3 | import Data.Maybe.Upper
5 | import Data.Prim.String
6 | import Derive.Prelude
11 | public export %inline
12 | hill : Elem -> String
21 | 0 (<): Maybe String -> Maybe String -> Type
28 | 0 (<=): Maybe String -> Maybe String -> Type
29 | m1 <= m2 = Either (m1 < m2) (m1 === m2)
39 | data Repr : (ix : Maybe String) -> Type where
44 | -> {auto 0 prf : Just (hill $
fst p) < ix}
45 | -> {auto 0 nz : IsSucc (snd p)}
46 | -> Repr (Just $
hill $
fst p)
56 | record MergeRes (h1,h2 : Maybe String) where
58 | {0 hx : Maybe String}
60 | 0 prf : Either (h1 === hx) (h2 === hx)
62 | 0 trans_LT_EQ : {0 lt : _} -> Transitive a lt => lt x y -> y === z -> lt x z
63 | trans_LT_EQ w Refl = w
66 | prepLT : (p : (Elem,Nat))
67 | -> MergeRes h1 (Just k2)
68 | -> (0 prf1 : Just (hill $
fst p) < h1)
69 | => (0 prf2 : Just (hill $
fst p) < Just k2)
70 | => (0 nz : IsSucc (snd p))
71 | => MergeRes (Just $
hill $
fst p) (Just k2)
72 | prepLT p (MR ps prf) =
73 | let 0 lt = either (trans_LT_EQ prf1) (trans_LT_EQ prf2) prf
74 | in MR (p :: ps) (Left Refl)
77 | prepGT : (p : (Elem,Nat))
78 | -> MergeRes (Just k1) e2
79 | -> (0 prf1 : Just (hill $
fst p) < e2)
80 | => (0 prf2 : Just (hill $
fst p) < Just k1)
81 | => (0 nz : IsSucc (snd p))
82 | => MergeRes (Just k1) (Just $
hill $
fst p)
83 | prepGT p (MR ps prf) =
84 | let 0 lt = either (trans_LT_EQ prf2) (trans_LT_EQ prf1) prf
85 | in MR (p :: ps) (Right Refl)
88 | prepEQ : {0 x : Maybe String}
90 | -> (0 eq : hill (fst p) === k)
92 | -> (0 prf1 : Just (hill $
fst p) < h1)
93 | => (0 prf2 : Just k < h2)
94 | => (0 nz : IsSucc (snd p))
95 | => MergeRes (Just $
hill $
fst p) x
96 | prepEQ p eq (MR ps prf) =
97 | let 0 fstp_lt_m2 = rewrite eq in prf2
98 | 0 lt = either (trans_LT_EQ prf1) (trans_LT_EQ fstp_lt_m2) prf
99 | in MR (p :: ps) (Left Refl)
101 | 0 plusSucc : (m,n : Nat) -> (0 prf : IsSucc m) => IsSucc (m + n)
102 | plusSucc (S k) n = ItIsSucc
103 | plusSucc Z n impossible
109 | merge : Repr h1 -> Repr h2 -> MergeRes h1 h2
110 | merge xs@(p :: ps) ys@(q :: qs) = case comp (hill $
fst p) (hill $
fst q) of
111 | LT prf _ _ => prepLT p $
merge ps ys
113 | let 0 nz := plusSucc (snd p) (snd q)
114 | in prepEQ (fst p, snd p + snd q) prf $
merge ps qs
115 | GT _ _ prf => prepGT q $
merge xs qs
116 | merge y [] = MR y (Left Refl)
117 | merge [] y = MR y (Right Refl)
121 | pairs : Repr h1 -> List (Elem,Nat)
122 | pairs (h :: t) = h :: pairs t
131 | hcomp : Repr h1 -> Repr h2 -> Ordering
132 | hcomp (p :: ps) (q :: qs) = case compare (hill $
fst p) (hill $
fst q) of
133 | EQ => case compare (snd p) (snd q) of
143 | heq : Repr h1 -> Repr h2 -> Bool
144 | heq x y = hcomp x y == EQ
149 | contains_ : Repr h1 -> Repr h2 -> Bool
150 | contains_ (p :: ps) (q :: qs) = case compare (hill $
fst p) (hill $
fst q) of
151 | LT => contains_ ps (q :: qs)
152 | EQ => snd p >= snd q && contains_ ps qs
154 | contains_ _ [] = True
155 | contains_ [] _ = False
166 | record Formula where
168 | {0 mx : Maybe String}
171 | public export %inline
173 | F x == F y = heq x y
175 | public export %inline
177 | compare (F x) (F y) = hcomp x y
179 | showPair : (Elem,Nat) -> String
180 | showPair (e, 1) = symbol e
181 | showPair (e, n) = symbol e ++ show n
185 | show (F ps) = fastConcat $
map showPair (pairs ps)
188 | Interpolation Formula where
192 | Semigroup Formula where
193 | F x <+> F y = F (repr $
merge x y)
196 | Monoid Formula where
201 | singleton : Elem -> (n : Nat) -> Formula
202 | singleton e 0 = F []
203 | singleton e (S n) = F [(e,S n)]
209 | contains : Formula -> Formula -> Bool
210 | contains (F x) (F y) = contains_ x y
214 | insert : Elem -> Nat -> Formula -> Formula
216 | insert el n f = singleton el n <+> f
220 | insertElem : Elem -> Formula -> Formula
221 | insertElem el f = singleton el 1 <+> f
227 | 0 containsTest1 : contains (F [(C,2),(H,6), (O,1)]) (F [(H,2),(O,1)]) === True
228 | containsTest1 = Refl
230 | 0 containsTest2 : contains (F [(H,1),(F,1)]) (F [(H,2),(O,1)]) === False
231 | containsTest2 = Refl
233 | 0 containsTest3 : contains (F []) (F [(H,2)]) === False
234 | containsTest3 = Refl
236 | 0 containsTest4 : contains (F []) (F []) === True
237 | containsTest4 = Refl