open import Data.Nat.DivMod
open import Data.Nat
open import Data.Nat.Properties
open import Relation.Binary.PropositionalEquality
open import Function
open import Relation.Binary
open import Data.Product
open import Relation.Unary
open import Relation.Nullary
open import Data.Empty
module RefinementExample where
open import Refinement
open import Data.Sum renaming (inj₁ to l ; inj₂ to r)
_≈₂_ : _
_≈₂_ = _≡_ on _div 5
eq≈₂ : IsEquivalence _≈₂_
eq≈₂ = record { refl = refl ; sym = sym ; trans = trans }
_≺₂_ : _
_≺₂_ = _<_ on _div 5
irr≺₂≈₂ : Irreflexive _≈₂_ _≺₂_
irr≺₂≈₂ {x} {y} with x div 5 | y div 5
irr≺₂≈₂ | suc _ | suc _ = <-irrefl
resp≺₂≈₂ : _≺₂_ Respects₂ _≈₂_
resp≺₂≈₂ = (λ { {x} {y} {z} → aux₁ {x} {y} {z}}) ,
λ { {x} {y} {z} → aux₂ {x} {y} {z}}
where
aux₁ : ∀ {x y z} → y ≈₂ z → x ≺₂ y → x ≺₂ z
aux₁ {x} {y} {z} with x div 5 | y div 5 | z div 5
aux₁ | _ | _ | _ = proj₁ (resp₂ _<_)
aux₂ : ∀ {x y z} → y ≈₂ z → y ≺₂ x → z ≺₂ x
aux₂ {x} {y} {z} with x div 5 | y div 5 | z div 5
aux₂ | _ | _ | _ = proj₂ (resp₂ _<_)
ispo≈₂≺₂ : IsStrictPartialOrder _≈₂_ _≺₂_
ispo≈₂≺₂ = record {
isEquivalence = eq≈₂ ;
irrefl = λ { {x} {y} → irr≺₂≈₂ {x} {y}} ;
trans = <-trans ;
<-resp-≈ = resp≺₂≈₂ }
_≈₁_ : Rel ℕ _
a ≈₁ b = (a / 5) ≡ (b / 5) × (a % 5 ≡ b % 5 ⊎ a % 5 + b % 5 ≡ 1)
sym≈₁ : Symmetric _≈₁_
sym≈₁ {a} {b} (fst , snd) with a / 5 | b / 5 | a % 5 | b % 5
sym≈₁ {a} {b} (fst , l x) | _ | _ | _ | _ = (sym fst) , l (sym x)
sym≈₁ {a} {b} (fst , r y) | _ | _ | w | w₁ =
(sym fst) , r (trans (+-comm w₁ w) y)
trans≈₁ : Transitive _≈₁_
trans≈₁ {a} {b} {c} _ _ with a / 5 | b / 5 | c / 5 | a % 5 | b % 5 | c % 5
trans≈₁ (refl , l refl) (refl , l refl) | _ | _ | _ | _ | _ | _ = refl , l refl
trans≈₁ (refl , l refl) (refl , r y) | _ | _ | _ | _ | _ | _ = refl , r y
trans≈₁ (refl , r y) (refl , l refl) | _ | _ | _ | _ | _ | _ = refl , r y
trans≈₁ (refl , r refl) (refl , r refl) | _ | _ | _ | zero | .1 | .0 = refl , l refl
trans≈₁ (refl , r refl) (refl , r refl) | _ | _ | _ | suc zero | .0 | .1 = refl , l refl
eq≈₁ : IsEquivalence _≈₁_
eq≈₁ = record {
refl = refl , l refl ;
sym = λ { {a} {b} → sym≈₁ {a} {b}};
trans = λ { {a} {b} {c} → trans≈₁ {a} {b} {c} }}
_≺₁_ : Rel ℕ _
a ≺₁ b = a / 5 < b / 5 ⊎ (a / 5 ≡ b / 5 × a % 5 < b % 5 × ¬ b % 5 ≡ 1)
trans≺₁ : Transitive _≺₁_
trans≺₁ {a} {b} {c} _ _ with a / 5 | b / 5 | c / 5 | a % 5 | b % 5 | c % 5
trans≺₁ (l x) (l x₁) | _ | _ | _ | _ | _ | _ = l (<-trans x x₁)
trans≺₁ (l x) (r (refl , _)) | _ | _ | _ | _ | _ | _ = l x
trans≺₁ (r (refl , _)) (l x) | _ | _ | _ | _ | _ | _ = l x
trans≺₁ (r (refl , u , _)) (r (refl , w , x)) | _ | _ | _ | _ | _ | _ =
r (refl , (<-trans u w , x))
irr≈₁≺₁ : Irreflexive _≈₁_ _≺₁_
irr≈₁≺₁ {a} {b} _ _ with a / 5 | b / 5 | a % 5 | b % 5
irr≈₁≺₁ (refl , snd) (l (s≤s x)) | _ | _ | _ | _ = <-irrefl refl x
irr≈₁≺₁ (refl , l refl) (r (refl , fst , _)) | _ | _ | _ | _ = <-irrefl refl fst
irr≈₁≺₁ (refl , r y₁) (r (refl , _ , snd)) | _ | _ | zero | _ = snd y₁
irr≈₁≺₁ (refl , r refl) (r (refl , () , snd)) | _ | _ | suc zero | _
resp≺≈₁ᵣ : _≺₁_ Respectsʳ _≈₁_
resp≺≈₁ᵣ {a} {b} {c} _ _ with a / 5 | b / 5 | c / 5 | a % 5 | b % 5 | c % 5
resp≺≈₁ᵣ (refl , _) (l x) | _ | _ | _ | _ | _ | _ = l x
resp≺≈₁ᵣ (refl , l refl) (r y) | _ | _ | _ | _ | _ | _ = r y
resp≺≈₁ᵣ (refl , r refl) (r (refl , _ , snd)) | _ | _ | _ | _ | suc zero | .0 =
⊥-elim (snd refl)
resp≺≈₁ₗ : _≺₁_ Respectsˡ _≈₁_
resp≺≈₁ₗ {a} {b} {c} _ _ with a / 5 | b / 5 | c / 5 | a % 5 | b % 5 | c % 5
resp≺≈₁ₗ (refl , _) (l x) | _ | _ | _ | _ | _ | _ = l x
resp≺≈₁ₗ (refl , l refl) (r y) | _ | _ | _ | _ | _ | _ = r y
resp≺≈₁ₗ (refl , r refl) (r (refl , fst , snd)) | _ | _ | _ | suc _ | zero | .1 =
r (refl , ≤∧≢⇒< fst (snd ∘ sym) , snd)
resp≺≈₁ₗ (refl , r refl) (r (refl , _ , snd)) | _ | _ | _ | suc _ | suc zero | _ =
r (refl , s≤s z≤n , snd)
resp≺₁≈₁ : _≺₁_ Respects₂ _≈₁_
resp≺₁≈₁ =
(λ { {x} {y} {z} → resp≺≈₁ᵣ {x} {y} {z}}) ,
λ { {x} {y} {z} → resp≺≈₁ₗ {x} {y} {z}}
ispo≈₁≺₁ : IsStrictPartialOrder _≈₁_ _≺₁_
ispo≈₁≺₁ = record {
isEquivalence = eq≈₁ ;
irrefl = λ { {x} {y} → irr≈₁≺₁ {x} {y}} ;
trans = λ { {x} {y} {z} → trans≺₁ {x} {y} {z}} ;
<-resp-≈ = resp≺₁≈₁ }
aux₁ : ∀ {a b} → a ≺₁ b → a ≺₂ b ⊎ a ≈₂ b
aux₁ {a} {b} _ with a / 5 | b / 5 | a % 5 | b % 5
aux₁ (l x) | _ | _ | _ | _ = l x
aux₁ (r (refl , _)) | _ | _ | _ | _ = r refl
aux₂ : ∀ {a b} → a ≈₂ b → a ≈₁ b ⊎ a ≺₁ b ⊎ b ≺₁ a
aux₂ {a} {b} _ with a / 5 | b / 5 | a % 5 | b % 5
aux₂ refl | _ | _ | zero | zero = l (refl , l refl)
aux₂ refl | _ | _ | zero | suc zero = l (refl , r refl)
aux₂ refl | _ | _ | zero | suc (suc _) = r (l (r (refl , s≤s z≤n , (λ ()))))
aux₂ refl | _ | _ | suc zero | zero = l (refl , r refl)
aux₂ refl | _ | _ | suc (suc _) | zero = r (r (r (refl , s≤s z≤n , (λ ()))))
aux₂ refl | _ | _ | suc zero | suc zero = l (refl , l refl)
aux₂ refl | _ | _ | suc zero | suc (suc _) =
r (l (r (refl , s≤s (s≤s z≤n) , (λ ()))))
aux₂ refl | _ | _ | suc (suc w) | suc zero =
r (r (r (refl , s≤s (s≤s z≤n) , (λ ()))))
aux₂ refl | _ | _ | suc (suc w) | suc (suc w₁) with <-cmp w w₁
aux₂ refl | _ | _ | suc (suc _) | suc (suc _) | tri< a _ _ =
r (l (r (refl , s≤s (s≤s a) , (λ ()))))
aux₂ refl | _ | _ | suc (suc _) | suc (suc ._) | tri≈ _ refl _ =
l (refl , l refl)
aux₂ refl | _ | _ | suc (suc _) | suc (suc _) | tri> _ _ c =
r (r (r (refl , s≤s (s≤s c) , (λ ()))))
refines : (_≈₁_ , _≺₁_) ≺≈ (_≈₂_ , _≺₂_)
refines = record {
≈₁→₂ = proj₁ ;
≈₂→₁ = λ { {a} {b} → aux₂ {a} {b}} ;
≺₁→₂ = λ { {a} {b} → aux₁ {a} {b}} ;
≺₂→₁ = l }