2 | import Language.Reflection.Util
11 | conIndexName : Named a => a -> Name
12 | conIndexName v = funName v "conIndex"
16 | conIndexTypes : Nat -> (Bits32 -> TTImp, TTImp)
18 | let f := primVal . PrT
19 | in if n < 256 then (primVal . B8 . cast, f Bits8Type)
20 | else if n < 0x20000 then (primVal . B16 . cast, f Bits16Type)
21 | else (primVal . B32, f Bits32Type)
26 | conIndexClauses : Named a => Name -> List a -> List Clause
27 | conIndexClauses n ns = go 0 (fst $
conIndexTypes $
length ns) ns
30 | go : Bits32 -> (Bits32 -> TTImp) -> List a -> List Clause
33 | patClause(var n `app` bindAny c) (f ix) :: go (ix + 1) f cs
38 | conIndexClaim : Visibility -> (fun : Name) -> (t : TypeInfo) -> Decl
39 | conIndexClaim vis fun t =
40 | let tpe := snd (conIndexTypes $
length t.cons)
42 | in simpleClaim vis fun $
piAll `(~(arg) -> ~(tpe)) (t.implicits)
47 | conIndexDef : (fun : Name) -> TypeInfo -> Decl
48 | conIndexDef fun t = def fun $
conIndexClauses fun t.cons
74 | ConIndexVis : Visibility -> List Name -> ParamTypeInfo -> Res (List TopLevel)
75 | ConIndexVis vis _ t =
76 | let fun := conIndexName t
77 | in Right [ TL (conIndexClaim vis fun t.info) (conIndexDef fun t.info) ]
81 | ConIndex : List Name -> ParamTypeInfo -> Res (List TopLevel)
82 | ConIndex = ConIndexVis Public
91 | eqClaim : Visibility -> (fun : Name) -> (p : ParamTypeInfo) -> Decl
93 | let arg := p.applied
94 | tpe := piAll `(~(arg) -> ~(arg) -> Bool
) (allImplicits p "Eq")
95 | in simpleClaim vis fun tpe
100 | eqImplClaim : Visibility -> (impl : Name) -> (p : ParamTypeInfo) -> Decl
101 | eqImplClaim vis impl p = implClaimVis vis impl (implType "Eq" p)
107 | eqImplDef : (fun, impl : Name) -> Decl
108 | eqImplDef fun impl = def impl [patClause (var impl) (var "mkEq" `app` var fun)]
110 | eqEnumDef : (impl, ci : Name) -> Decl
112 | def i [patClause (var i) `(mkEq $
\x,y => ~(var c) x ==
~(var c) y
)]
116 | catchAll : (fun : Name) -> TypeInfo -> List Clause
118 | if length ti.cons > 1
119 | then [patClause `(~(var fun) _ _) `(False
)]
123 | rhs : SnocList TTImp -> TTImp
125 | rhs (sx :< x) = foldr (\e,acc => `(~(e) &&
~(acc))) x sx
127 | parameters (nms : List Name)
128 | arg : BoundArg 2 Regular -> TTImp
129 | arg (BA g [x,y] _) = assertIfRec nms g.type `(~(var x) ==
~(var y))
136 | eqClauses : (fun : Name) -> TypeInfo -> List Clause
137 | eqClauses fun ti = map clause ti.cons ++ catchAll fun ti
140 | clause : Con ti.arty ti.args -> Clause
141 | clause = accumArgs2 regular (\x,y => `(~(var fun) ~(x) ~(y))) rhs arg
146 | eqDef : Name -> TypeInfo -> Decl
147 | eqDef fun ti = def fun (eqClauses fun ti)
158 | deriveEq : Elab (Eq f)
161 | | Nothing => fail "Can't infer goal"
162 | let Just (resTpe, nm) := extractResult tpe
163 | | Nothing => fail "Invalid goal type: \{show tpe}"
167 | lam (lambdaArg {a = Name} "x") $
168 | lam (lambdaArg {a = Name} "y") $
169 | iCase `(MkPair x y
) implicitFalse (eqClauses [ti.name] "MkPair" ti)
171 | logMsg "derive.definitions" 1 $
show impl
172 | check $
var "mkEq" `app` impl
176 | EqVis : Visibility -> List Name -> ParamTypeInfo -> Res (List TopLevel)
177 | EqVis vis nms p = case isEnum p.info of
179 | let impl := implName p "Eq"
180 | ci := conIndexName p
182 | [ ConIndexVis vis nms p
183 | , Right [ TL (eqImplClaim vis impl p) (eqEnumDef impl ci) ]
186 | let fun := funName p "eq"
187 | impl := implName p "Eq"
189 | [ TL (eqClaim vis fun p) (eqDef nms fun p.info)
190 | , TL (eqImplClaim vis impl p) (eqImplDef fun impl)
195 | Eq : List Name -> ParamTypeInfo -> Res (List TopLevel)