161 (fn (n,ty) => n="List.nth" |
166 (fn (n,ty) => n="List.nth" |
162 andalso |
167 andalso |
163 AList.defined Type.could_unify (!bds) (domain_type ty)) rhs |
168 AList.defined Type.could_unify (!bds) (domain_type ty)) rhs |
164 andalso Type.could_unify (fastype_of rhs, tT) |
169 andalso Type.could_unify (fastype_of rhs, tT) |
165 end |
170 end |
166 fun get_nth t = |
171 fun get_nths t acc = |
167 case t of |
172 case t of |
168 Const("List.nth",_)$vs$n => (t,vs,n) |
173 Const("List.nth",_)$vs$n => insert (fn ((a,_),(b,_)) => a aconv b) (t,(vs,n)) acc |
169 | t1$t2 => (get_nth t1 handle REIF "get_nth" => get_nth t2) |
174 | t1$t2 => get_nths t1 (get_nths t2 acc) |
170 | Abs(_,_,t') => get_nth t' |
175 | Abs(_,_,t') => get_nths t' acc |
171 | _ => raise REIF "get_nth" |
176 | _ => acc |
172 val ([xn,vsn],ctxt') = Variable.variant_fixes ["x","vs"] ctxt |
177 |
173 val thy = ProofContext.theory_of ctxt' |
178 |
174 val cert = cterm_of thy |
179 fun tryeqs [] = error "Can not find the atoms equation" |
175 fun tryeqs [] = raise REIF "Can not find the atoms equation" |
|
176 | tryeqs (eq::eqs) = (( |
180 | tryeqs (eq::eqs) = (( |
177 let |
181 let |
178 val rhs = eq |> prop_of |> HOLogic.dest_Trueprop |
182 val rhs = eq |> prop_of |> HOLogic.dest_Trueprop |> HOLogic.dest_eq |> snd |
179 |> HOLogic.dest_eq |> snd |
183 val nths = get_nths rhs [] |
180 val (nt,vs,n) = get_nth rhs |
184 val (vss,ns) = fold_rev (fn (_,(vs,n)) => fn (vss,ns) => (insert (op aconv) vs vss, insert (op aconv) n ns)) nths ([],[]) |
181 val ntT = fastype_of nt |
185 val (vsns, ctxt') = Variable.variant_fixes (replicate (length vss) "vs") ctxt |
182 val ntlT = HOLogic.listT ntT |
186 val (xns, ctxt'') = Variable.variant_fixes (replicate (length nths) "x") ctxt' |
183 val (bsT,asT) = the (AList.lookup (op =) (!bds) ntlT) |
187 val thy = ProofContext.theory_of ctxt'' |
184 val x = Var ((xn,0),ntT) |
188 val cert = cterm_of thy |
185 val rhs_P = subst_free [(nt,x)] rhs |
189 val vsns_map = vss ~~ vsns |
186 val (_, tmenv) = Pattern.match |
190 val xns_map = (fst (split_list nths)) ~~ xns |
187 thy (rhs_P, t) |
191 val subst = map (fn (nt, xn) => (nt, Var ((xn,0), fastype_of nt))) xns_map |
188 (Envir.type_env (Envir.empty 0),Term.Vartab.empty) |
192 val rhs_P = subst_free subst rhs |
189 val tml = Vartab.dest tmenv |
193 val (_, tmenv) = Pattern.match |
190 val SOME (_,t') = AList.lookup (op =) tml (xn,0) |
194 thy (rhs_P, t) |
191 val cvs = |
195 (Envir.type_env (Envir.empty 0),Term.Vartab.empty) |
192 cert (fold_rev (fn x => fn xs => Const("List.list.Cons", ntT --> ntlT --> ntlT)$x$xs) |
196 val tml = Vartab.dest tmenv |
193 bsT (Free (vsn, ntlT))) |
197 val t's = map (fn xn => snd (valOf (AList.lookup (op =) tml (xn,0)))) xns |
|
198 val subst_ns = map (fn (Const _ $ vs $ n, Var (xn0,T)) => (cert n, snd (valOf (AList.lookup (op =) tml xn0)) |> (index_of #> IntInf.fromInt #> HOLogic.mk_nat #> cert))) subst |
|
199 val subst_vs = |
|
200 let |
|
201 fun h (Const _ $ (vs as Var (vsn,lT)) $ n, Var (xn0,T)) = |
|
202 let |
|
203 val (bsT,asT) = the (AList.lookup (op =) (!bds) lT) |
|
204 val vsn = valOf (AList.lookup (op =) vsns_map vs) |
|
205 val cvs = |
|
206 cert (fold_rev (fn x => fn xs => Const("List.list.Cons", T --> lT --> lT)$x$xs) bsT (Free (vsn, lT))) |
|
207 |
|
208 in (cert vs, cvs) end |
|
209 in map h subst end |
194 val cts = map (fn ((vn,vi),(tT,t)) => (cert(Var ((vn,vi),tT)), cert t)) |
210 val cts = map (fn ((vn,vi),(tT,t)) => (cert(Var ((vn,vi),tT)), cert t)) |
195 (AList.delete (op =) (xn,0) tml) |
211 (fold (AList.delete (fn (((a: string),_),(b,_)) => a = b)) (map (fn n => (n,0)) xns) tml) |
196 val th = (instantiate |
212 |
197 ([], |
213 val th = (instantiate ([],subst_ns@subst_vs@cts) eq) RS sym |
198 [(cert vs, cvs),(cert n, t' |> index_of |> IntInf.fromInt |> HOLogic.mk_nat |> cert)] |
214 in hd (Variable.export ctxt'' ctxt [th]) end) |
199 @cts) eq) RS sym |
|
200 in hd (Variable.export ctxt' ctxt [th]) |
|
201 end) |
|
202 handle MATCH => tryeqs eqs) |
215 handle MATCH => tryeqs eqs) |
203 in ([], fn _ => tryeqs (filter isat eqs)) |
216 in ([], fn _ => tryeqs (filter isat eqs)) |
204 end; |
217 end; |
205 |
218 |
206 (* |
|
207 fun mk_decompatom eqs (t,ctxt) = |
|
208 let |
|
209 val tT = fastype_of t |
|
210 val tlT = HOLogic.listT tT |
|
211 val (bsT,asT) = (the (AList.lookup (op =) (!bds) tlT) |
|
212 handle Option => error "mk_decompatom: Type not found in the env.") |
|
213 fun isateq (_$_$(Const("List.nth",_)$vs$_)) = (fastype_of vs = tlT) |
|
214 | isateq _ = false |
|
215 in case List.find (isateq o HOLogic.dest_Trueprop o prop_of) eqs of |
|
216 NONE => raise REIF "Can not find the atoms equation" |
|
217 | SOME th => |
|
218 ([], |
|
219 fn ths => |
|
220 let |
|
221 val ([x], ctxt') = Variable.variant_fixes ["vs"] ctxt |
|
222 val cert = cterm_of (ProofContext.theory_of ctxt') |
|
223 val (Const("List.nth",_)$(vs as Var((vsn,vsi),_))$n) = |
|
224 (snd o HOLogic.dest_eq o HOLogic.dest_Trueprop o prop_of) th |
|
225 val cvs = |
|
226 cert (foldr (fn (x,xs) => Const("List.list.Cons", tT --> tlT --> tlT)$x$xs) |
|
227 (Free(x,tlT)) bsT) |
|
228 val th' = (instantiate ([], |
|
229 [(cert vs, cvs), |
|
230 (cert n, cert (HOLogic.mk_nat(index_of t)))]) th) |
|
231 RS sym |
|
232 in hd (Variable.export ctxt' ctxt [th']) end) |
|
233 end; |
|
234 *) |
|
235 (* Generic reification procedure: *) |
219 (* Generic reification procedure: *) |
236 (* creates all needed cong rules and then just uses the theorem synthesis *) |
220 (* creates all needed cong rules and then just uses the theorem synthesis *) |
237 |
221 |
238 fun mk_congs ctxt raw_eqs = |
222 fun mk_congs ctxt raw_eqs = |
239 let |
223 let |