5 | module Search.Properties
8 | import Data.List.Lazy
9 | import Data.List.Lazy.Quantifiers
13 | import public Data.Stream
14 | import public Data.Colist
15 | import public Data.Colist1
17 | import public Search.Negation
18 | import public Search.HDecidable
19 | import public Search.Generator
21 | import Decidable.Equality
30 | Product : List Type -> Type
31 | Product = foldr Pair ()
38 | record Prop (cs : List Type) (a : Type) where
42 | runProp : Colist1 (Product cs) -> Fuel -> HDec a
51 | interface AProp (0 t : Type -> Type) where
52 | 0 Constraints : List Type
53 | toProp : t a -> Prop Constraints a
57 | AProp (Prop cs) where
65 | toProp = MkProp . const . const
71 | toProp = MkProp . (const . const . toHDec)
75 | check : (gen : Generator (Product cs)) => (f : Fuel) -> (p : Prop cs a) ->
76 | {auto pr : So (isTrue (runProp p (generate @{gen}) f))} -> a
77 | check @{gen} f p @{pr} = evidence (runProp p (generate @{gen}) f) pr
82 | exists : {0 p : a -> Type} -> (aPropt : AProp t) =>
83 | ((x : a) -> t (p x)) ->
84 | Prop (a :: Constraints @{aPropt}) (DPair a p)
85 | exists test = MkProp $
\ acs, fuel =>
86 | let candidates : LazyList a = take fuel (map fst acs) in
87 | let cs = map snd acs in
88 | let find = any candidates (\ x => runProp (toProp (test x)) cs fuel) in
96 | example : Prop ?
(DPair Nat (\ i => Not (i `LTE` 10)))
97 | example = exists (\ i => not (isLTE 11 i))
99 | lemma : DPair Nat (\ i => Not (i `LTE` 10))
100 | lemma = check (limit 1000) example
102 | namespace Pythagoras
105 | formula = DPair Nat $
\ m =>
108 | (0 `LT` m, 0 `LT` n, 0 `LT` p
109 | , (m * m + n * n) === (p * p))
111 | search : Prop ?
Pythagoras.formula
112 | search = exists $
\ m =>
115 | (isLT 0 m && isLT 0 n && isLT 0 p
116 | && decEq (m * m + n * n) (p * p))
120 | lemma : HDec Pythagoras.formula
121 | lemma = runProp search generate (limit 10)