------------------------------------------------------------------------------
-- The division program is correct
------------------------------------------------------------------------------
{-# OPTIONS --exact-split #-}
{-# OPTIONS --no-sized-types #-}
{-# OPTIONS --no-universe-polymorphism #-}
{-# OPTIONS --without-K #-}
-- N.B This module does not contain combined proofs, but it imports
-- modules which contain combined proofs.
-- This module proves the correctness of the division program using
-- repeated subtraction (Dybjer 1985).
module FOTC.Program.Division.CorrectnessProofATP where
open import FOTC.Base
open import FOTC.Data.Nat
open import FOTC.Data.Nat.Inequalities
open import FOTC.Data.Nat.Inequalities.PropertiesATP
open import FOTC.Data.Nat.PropertiesATP
import FOTC.Data.Nat.Induction.NonAcc.WF-ATP
open module WFInd = FOTC.Data.Nat.Induction.NonAcc.WF-ATP.WFInd
open import FOTC.Program.Division.Division
open import FOTC.Program.Division.ResultATP
open import FOTC.Program.Division.Specification
open import FOTC.Program.Division.TotalityATP
------------------------------------------------------------------------------
-- The division program is correct when the dividend is less than the
-- divisor.
div-x<y-correct : ∀ {i j} → N i → N j → i < j → divSpec i j (div i j)
div-x<y-correct Ni Nj i<j = div-x<y-N i<j , div-x<y-resultCorrect Ni Nj i<j
-- The division program is correct dividend is greater or equal than
-- the divisor.
div-x≮y-correct : ∀ {i j} → N i → N j →
(∀ {i'} → N i' → i' < i → divSpec i' j (div i' j)) →
j > zero →
i ≮ j →
divSpec i j (div i j)
div-x≮y-correct {i} {j} Ni Nj ah j>0 i≮j =
div-x≮y-N ih i≮j , div-x≮y-resultCorrect Ni Nj ih i≮j
where
-- The inductive hypothesis on i ∸ j.
ih : divSpec (i ∸ j) j (div (i ∸ j) j)
ih = ah {i ∸ j}
(∸-N Ni Nj)
(x≥y→y>0→x∸y<x Ni Nj (x≮y→x≥y Ni Nj i≮j) j>0)
------------------------------------------------------------------------------
-- The division program is correct.
-- We do the well-founded induction on i and we keep j fixed.
divCorrect : ∀ {i j} → N i → N j → j > zero → divSpec i j (div i j)
divCorrect {j = j} Ni Nj j>0 = <-wfind A ih Ni
where
A : D → Set
A d = divSpec d j (div d j)
-- The inductive step doesn't use the variable i (nor Ni). To make
-- this clear we write down the inductive step using the variables m
-- and n.
ih : ∀ {n} → N n → (∀ {m} → N m → m < n → A m) → A n
ih {n} Nn ah =
case (div-x<y-correct Nn Nj) (div-x≮y-correct Nn Nj ah j>0) (x<y∨x≮y Nn Nj)
------------------------------------------------------------------------------
-- References
--
-- Dybjer, Peter (1985). Program Verification in a Logical Theory of
-- Constructions. In: Functional Programming Languages and Computer
-- Architecture. Ed. by Jouannaud,
-- Jean-Pierre. Vol. 201. LNCS. Appears in revised form as Programming
-- Methodology Group Report 26, University of Gothenburg and Chalmers
-- University of Technology, June 1986. Springer, pp. 334–349.