(* Title: HOL/Tools/reification.ML Author: Amine Chaieb, TU Muenchen
A trial for automatical reification.
*)
signature REIFICATION = sig val conv: Proof.context -> thm list -> conv val tac: Proof.context -> thm list -> term option -> int -> tactic val lift_conv: Proof.context -> conv -> term option -> int -> tactic val dereify: Proof.context -> thm list -> conv end;
structure Reification : REIFICATION = struct
fun dest_listT (Type (\<^type_name>\<open>list\<close>, [T])) = T;
val pure_subst = @{lemma "x == y ==> PROP P y ==> PROP P x" by simp}
fun lift_conv ctxt conv some_t = Subgoal.FOCUS (fn {context = ctxt', concl, ...} => let val ct =
(case some_t of
NONE => Thm.dest_arg concl
| SOME t => Thm.cterm_of ctxt' t) val thm = conv ct; in if Thm.is_reflexive thm then no_tac else ALLGOALS (resolve_tac ctxt [pure_subst OF [thm]]) end) ctxt;
(* Make a congruence rule out of a defining equation for the interpretation
th is one defining equation of f, i.e. th is "f (Cp ?t1 ... ?tn) = P(f ?t1, .., f ?tn)" Cp is a constructor pattern and P is a pattern
The result is: [|?A1 = f ?t1 ; .. ; ?An= f ?tn |] ==> P (?A1, .., ?An) = f (Cp ?t1 .. ?tn)
+ the a list of names of the A1 .. An, Those are fresh in the ctxt *)
fun mk_congeq ctxt fs th = let valConst (fN, _) = th |> Thm.prop_of |> HOLogic.dest_Trueprop |> HOLogic.dest_eq
|> fst |> strip_comb |> fst; val ((_, [th']), ctxt') = Variable.import true [th] ctxt; val (lhs, rhs) = HOLogic.dest_eq (HOLogic.dest_Trueprop (Thm.prop_of th')); fun add_fterms (t as t1 $ t2) = ifexists (fn f => Term.could_unify (t |> strip_comb |> fst, f)) fs then insert (op aconv) t else add_fterms t1 #> add_fterms t2
| add_fterms (t as Abs _) = if exists_Const (fn (c, _) => c = fN) t then K [t] else K []
| add_fterms _ = I; val fterms = add_fterms rhs []; val (xs, ctxt'') = Variable.variant_fixes (replicate (length fterms) "x") ctxt'; val tys = map fastype_of fterms; val vs = map Free (xs ~~ tys); val env = fterms ~~ vs; (*FIXME*) fun replace_fterms (t as t1 $ t2) =
(case AList.lookup (op aconv) env t of
SOME v => v
| NONE => replace_fterms t1 $ replace_fterms t2)
| replace_fterms t =
(case AList.lookup (op aconv) env t of
SOME v => v
| NONE => t); fun mk_def (Abs (x, xT, t), v) =
HOLogic.mk_Trueprop (HOLogic.all_const xT $ Abs (x, xT, HOLogic.mk_eq (v $ Bound 0, t)))
| mk_def (t, v) = HOLogic.mk_Trueprop (HOLogic.mk_eq (v, t)); fun tryext x =
(x RS @{lemma "(\x. f x = g x) \ f = g" by blast} handle THM _ => x); val cong =
(Goal.prove ctxt'' [] (map mk_def env)
(HOLogic.mk_Trueprop (HOLogic.mk_eq (lhs, replace_fterms rhs)))
(fn {context, prems, ...} =>
Local_Defs.unfold0_tac context (map tryext prems) THEN resolve_tac ctxt'' [th'] 1)) RS sym; val (cong' :: vars') =
Variable.export ctxt'' ctxt (cong :: map (Drule.mk_term o Thm.cterm_of ctxt'') vs); val vs' = map (fst o fst o Term.dest_Var o Thm.term_of o Drule.dest_term) vars';
in (vs', cong') end;
(* congs is a list of pairs (P,th) where th is a theorem for
[| f p1 = A1; ...; f pn = An|] ==> f (C p1 .. pn) = P *)
fun rearrange congs = let fun P (_, th) = letval \<^term>\<open>Trueprop\<close> $ (Const (\<^const_name>\<open>HOL.eq\<close>, _) $ l $ _) = Thm.concl_of th in can dest_Var l end; val (yes, no) = List.partition P congs; in no @ yes end;
fun index_of t bds = let val tt = HOLogic.listT (fastype_of t); in
(case AList.lookup Type.could_unify bds tt of
NONE => error "index_of: type not found in environements!"
| SOME (tbs, tats) => let val i = find_index (fn t' => t' = t) tats; val j = find_index (fn t' => t' = t) tbs; in if j = ~1 then if i = ~1 then (length tbs + length tats, AList.update Type.could_unify (tt, (tbs, tats @ [t])) bds) else (i, bds) else (j, bds) end) end;
(* Generic decomp for reification : matches the actual term with the rhs of one cong rule. The result of the matching guides the proof synthesis: The matches of the introduced Variables A1 .. An are processed recursively
The rest is instantiated in the cong rule,i.e. no reification is needed *)
(* da is the decomposition for atoms, ie. it returns ([],g) where g returns the right instance f (AtC n) = t , where AtC is the Atoms
constructor and n is the number of the atom corresponding to t *) fun decomp_reify da cgns (ct, ctxt) bds = let val thy = Proof_Context.theory_of ctxt; fun tryabsdecomp (ct, ctxt) bds =
(case Thm.term_of ct of
Abs (_, xT, _) => let val ((cx, cta), ctxt') = Variable.dest_abs_cterm ct ctxt; val x = Thm.term_of cx; val bds = (case AList.lookup Type.could_unify bds (HOLogic.listT xT) of
NONE => error "tryabsdecomp: Type not found in the Environement"
| SOME (bsT, atsT) => AList.update Type.could_unify (HOLogic.listT xT,
(x :: bsT, atsT)) bds); in (([(cta, ctxt')],
fn ([th], bds) =>
(hd (Variable.export ctxt' ctxt [(Thm.forall_intr cx th) COMP allI]), let val (bsT, asT) = the (AList.lookup Type.could_unify bds (HOLogic.listT xT)); in
AList.update Type.could_unify (HOLogic.listT xT, (tl bsT, asT)) bds end)),
bds) end
| _ => da (ct, ctxt) bds) in
(case cgns of
[] => tryabsdecomp (ct, ctxt) bds
| ((vns, cong) :: congs) =>
(let val (tyenv, tmenv) =
Pattern.match thy
((fst o HOLogic.dest_eq o HOLogic.dest_Trueprop) (Thm.concl_of cong), Thm.term_of ct)
(Vartab.empty, Vartab.empty); val (fnvs, invs) = List.partition (fn ((vn, _),_) => member (op =) vns vn) (Vartab.dest tmenv); val (fts, its) =
(map (snd o snd) fnvs, map (fn ((vn, vi), (tT, t)) => (((vn, vi), tT), Thm.cterm_of ctxt t)) invs); val ctyenv = map (fn ((vn, vi), (s, ty)) => (((vn, vi), s), Thm.ctyp_of ctxt ty))
(Vartab.dest tyenv); in
((map (Thm.cterm_of ctxt) fts ~~ replicate (length fts) ctxt,
apfst (FWD (Drule.instantiate_normalize (TVars.make ctyenv, Vars.make its) cong))), bds) endhandle Pattern.MATCH => decomp_reify da congs (ct, ctxt) bds)) end;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.