------------------------------------------------------------------------------
-- Conversion rules for the division
------------------------------------------------------------------------------
{-# OPTIONS --exact-split #-}
{-# OPTIONS --no-sized-types #-}
{-# OPTIONS --no-universe-polymorphism #-}
{-# OPTIONS --without-K #-}
module FOTC.Program.Division.ConversionRulesI where
open import Common.FOL.Relation.Binary.EqReasoning
open import FOTC.Base
open import FOTC.Data.Nat
open import FOTC.Data.Nat.Inequalities
open import FOTC.Program.Division.Division
------------------------------------------------------------------------------
-- Division properties
private
-- Before to prove some properties for div it is convenient
-- to have a proof for each possible execution step.
-- Initially, we define the possible states (div-s₁, div-s₂, ...)
-- and after that, we write down the proof for the execution step
-- from the state p to the state q, e.g.
--
-- proof₂₋₃ : ∀ i j → div-s₂ i j ≡ div-s₃ i j.
-- Initially, the conversion rule div-eq is applied.
div-s₁ : D → D → D
div-s₁ i j = if (lt i j) then zero else succ₁ (div (i ∸ j) j)
-- lt i j ≡ true.
div-s₂ : D → D → D
div-s₂ i j = if true
then zero
else succ₁ (div (i ∸ j) j)
-- lt i j ≡ false.
div-s₃ : D → D → D
div-s₃ i j = if false
then zero
else succ₁ (div (i ∸ j) j)
-- The conditional is true.
div-s₄ : D
div-s₄ = zero
-- The conditional is false.
div-s₅ : D → D → D
div-s₅ i j = succ₁ (div (i ∸ j) j)
{-
To prove the execution steps, e.g.
proof₃₋₄ : ∀ i j → div-s₃ i j → divh_s₄ i j,
we usually need to prove that
... m ... ≡ ... n ... (1)
given that
m ≡ n, (2)
where (2) is a conversion rule usually.
We prove (1) using
subst : ∀ {x y} (A : D → Set) → x ≡ y → A x → A y
where
• P is given by \m → ... m ... ≡ ... n ...,
• x ≡ y is given n ≡ m (actually, we use ≡-sym (m ≡ n)) and
• P x is given by ... n ... ≡ ... n ... (i.e. ≡-refl)
-}
-- From div i j to div-s₁ using the equation div-eq.
proof₀₋₁ : ∀ i j → div i j ≡ div-s₁ i j
proof₀₋₁ i j = div-eq i j
-- From div-s₁ to div-s₂ using the proof i<j.
proof₁₋₂ : ∀ i j → i < j → div-s₁ i j ≡ div-s₂ i j
proof₁₋₂ i j i<j =
subst (λ t → (if t
then zero
else succ₁ (div (i ∸ j) j))
≡
(if true
then zero
else succ₁ (div (i ∸ j) j))
)
(sym i<j)
refl
-- From div-s₁ to div-s₃ using the proof i≮j.
proof₁₋₃ : ∀ i j → i ≮ j → div-s₁ i j ≡ div-s₃ i j
proof₁₋₃ i j i≮j =
subst (λ t → (if t
then zero
else succ₁ (div (i ∸ j) j))
≡
(if false
then zero
else succ₁ (div (i ∸ j) j))
)
(sym i≮j)
refl
-- From div-s₂ to div-s₄ using the conversion rule if-true.
proof₂₋₄ : ∀ i j → div-s₂ i j ≡ div-s₄
proof₂₋₄ i j = if-true zero
-- From div-s₃ to div-s₅ using the conversion rule if-false.
proof₃₋₅ : ∀ i j → div-s₃ i j ≡ div-s₅ i j
proof₃₋₅ i j = if-false (succ₁ (div (i ∸ j) j))
----------------------------------------------------------------------
-- The division result when the dividend is minor than the
-- the divisor.
div-x<y : ∀ {i j} → i < j → div i j ≡ zero
div-x<y {i} {j} i<j =
div i j ≡⟨ proof₀₋₁ i j ⟩
div-s₁ i j ≡⟨ proof₁₋₂ i j i<j ⟩
div-s₂ i j ≡⟨ proof₂₋₄ i j ⟩
div-s₄ ∎
----------------------------------------------------------------------
-- The division result when the dividend is greater or equal than the
-- the divisor.
div-x≮y : ∀ {i j} → i ≮ j → div i j ≡ succ₁ (div (i ∸ j) j)
div-x≮y {i} {j} i≮j =
div i j ≡⟨ proof₀₋₁ i j ⟩
div-s₁ i j ≡⟨ proof₁₋₃ i j i≮j ⟩
div-s₃ i j ≡⟨ proof₃₋₅ i j ⟩
div-s₅ i j ∎