|
| 1 | +{-# OPTIONS --erasure #-} |
| 2 | + |
| 3 | +open import Haskell.Prelude |
| 4 | +open import Haskell.Control.Exception |
| 5 | +open import Haskell.Extra.Dec |
| 6 | +open import Haskell.Extra.Refinement |
| 7 | +open import Haskell.Law.Ord |
| 8 | + |
| 9 | +variable |
| 10 | + A A' B B' C C' : Set |
| 11 | + P P' Q Q' : A → Set |
| 12 | + |
| 13 | +it : {{A}} → A |
| 14 | +it {{x}} = x |
| 15 | + |
| 16 | +data _~_ : (A : Set) (B : Set) → Set₁ |
| 17 | +cast : A ~ B → A → B |
| 18 | +cast' : A ~ B → B → A |
| 19 | + |
| 20 | +data _~_ where |
| 21 | + refl : A ~ A |
| 22 | + |
| 23 | + assert-pre-left : ∀ {A : Set} {B : @0 A → Set} |
| 24 | + → {{Dec A}} |
| 25 | + → ({{@0 x : A}} → B x ~ B') |
| 26 | + → ({{@0 x : A}} → B x) ~ B' |
| 27 | + |
| 28 | + assert-pre-right : ∀ {A : Set} {B' : @0 A → Set} |
| 29 | + → {{Dec A}} |
| 30 | + → ({{@0 x : A}} → B ~ B' x) |
| 31 | + → B ~ ({{@0 x : A}} → B' x) |
| 32 | + |
| 33 | + assert-post-left : ∀ {A : Set} {@0 B : A → Set} |
| 34 | + → {{∀ {x} → Dec (B x)}} |
| 35 | + → A ~ A' |
| 36 | + → ∃ A B ~ A' |
| 37 | + |
| 38 | + assert-post-right : ∀ {A : Set} {@0 B' : A' → Set} |
| 39 | + → {{∀ {x'} → Dec (B' x')}} |
| 40 | + → A ~ A' |
| 41 | + → A ~ ∃ A' B' |
| 42 | + |
| 43 | + cong-pi : {B : @0 A → Set} {B' : @0 A' → Set} |
| 44 | + → (eA : A ~ A') → (eB : (x : A) (x' : A') → B x ~ B' x') |
| 45 | + → ((x : A) → B x) ~ ((x : A') → B' x) |
| 46 | + |
| 47 | +cast refl x = x |
| 48 | +cast (assert-pre-left {A = A} eB) x = assert A (cast eB x) |
| 49 | +cast (assert-pre-right eB) x = cast eB x |
| 50 | +cast (assert-post-left eA) (x ⟨ _ ⟩) = cast eA x |
| 51 | +cast (assert-post-right {B' = B'} eA) x = assert (B' x') (x' ⟨⟩) |
| 52 | + where x' = cast eA x |
| 53 | +cast (cong-pi {A = A} eA eB) f x' = cast (eB x x') (f x) |
| 54 | + where x = cast' eA x' |
| 55 | + |
| 56 | +cast' refl x' = x' |
| 57 | +cast' (assert-pre-left eB) x' = cast' eB x' |
| 58 | +cast' (assert-pre-right {A = A} eB) x' = assert A (cast' eB x') |
| 59 | +cast' (assert-post-left {B = B} eA) x' = assert (B x) (x ⟨⟩) |
| 60 | + where x = cast' eA x' |
| 61 | +cast' (assert-post-right eA) (x' ⟨ _ ⟩) = cast' eA x' |
| 62 | +cast' (cong-pi eA eB) f x = cast' (eB x x') (f x') |
| 63 | + where x' = cast eA x |
| 64 | + |
| 65 | +{-# COMPILE AGDA2HS cast inline #-} |
| 66 | +{-# COMPILE AGDA2HS cast' inline #-} |
| 67 | + |
| 68 | +module Sqrt where |
| 69 | + |
| 70 | + postulate |
| 71 | + mySqrt : (x : Double) → @0 {{IsTrue (x >= 0)}} → Double |
| 72 | + |
| 73 | + {-# COMPILE AGDA2HS mySqrt #-} |
| 74 | + |
| 75 | + eqr : ((x : Double) → @0 {{IsTrue (x >= 0)}} → Double) ~ |
| 76 | + ((x : Double) → ∃ Double (λ v → IsTrue (v >= 0) × IsTrue ((abs (x - v * v) <= 0.01)))) |
| 77 | + eqr = cong-pi refl (λ x x' → assert-pre-left (assert-post-right refl)) |
| 78 | + |
| 79 | + {-# COMPILE AGDA2HS eqr inline #-} |
| 80 | + |
| 81 | + checkedSqrt : (x : Double) → ∃ Double (λ y → IsTrue (y >= 0) × IsTrue (abs (x - y * y) <= 0.01)) |
| 82 | + checkedSqrt = cast eqr mySqrt |
| 83 | + |
| 84 | + {-# COMPILE AGDA2HS checkedSqrt #-} |
| 85 | + |
0 commit comments