(* Title: Pure/raw_simplifier.ML Author: Tobias Nipkow and Stefan Berghofer, TU Muenchen
Higher-order Simplification.
*)
signature(* Title: Pure/raw_simplifier.ML Author: Tobias andStefanBerghofer TU Muenchen sig val simp_depth_limit: int Config.T val simp_trace_depth_limit: int Config.T val simp_debug: bool Config.T val simp_trace: bool Config.T type cong_name = bool * string type rrule val mk_rrules: Proof.context -> thm -> rrule list val eq_rrule: rrule * rrule -> bool type proc = Proof.context -> cterm -> thm option type solver val mk_solver: string -> (Proof.context -> int -> tactic) -> solver type simpset val empty_ss: simpset val merge_ss: simpset * simpset -> simpset datatype proc_kind = Simproc | Congproc of bool type simproc val cert_simproc: theory -> {name: string, kind: proc_kind, lhss: term list, proc: proc Morphism.entity, identifier: thm list} -> simproc val transform_simproc: morphism -> simproc -> simproc val trim_context_simproc: simproc -> simproc val simpset_of: Proof.context -> simpset val put_simpset: simpset -> Proof.context -> Proof.context val simpset_map: Proof.context -> (Proof.context -> Proof.context) -> simpset -> simpset val map_theory_simpset: (Proof.context -> Proof.context) -> theory -> theory val empty_simpset: Proof.context -> Proof.context val clear_simpset: Proof.context -> Proof.context
val rewrite_rule: Proof.context -> thm list -> thm -> thm val rewrite_goals_rule: Proof.context -> thm list -> thm -> thm val rewrite_goals_tac: Proof.context -> thm list -> tactic val rewrite_goal_tac: Proof.context -> thm list -> int -> tactic val prune_params_tac: Proof.context -> tactic val fold_rule: Proof.context -> thm list -> thm -> thm val fold_goals_tac: Proof.context -> thm list -> tactic val norm_hhf: Proof.context -> thm -> thm val norm_hhf_protect: Proof.context -> thm -> thm end;
signature RAW_SIMPLIFIER = sig include BASIC_RAW_SIMPLIFIER exception SIMPLIFIER of string * thm list val dest_simps: simpset -> (Thm_Name.T * thm) list val dest_congs: simpset -> (cong_name * thm) list val dest_ss: simpset -> {simps: (Thm_Name.T * thm) list, simprocs: (string * term list) list, congprocs: (string * {lhss: term list, proc: proc Morphism.entity}) list, congs: (cong_name * thm) list, weak_congs: cong_name list, loopers: string list, unsafe_solvers: string list, safe_solvers: string list} val init_simpset: thm list -> Proof.context -> Proof.context type trace_ops val set_trace_ops: trace_ops -> theory -> theory val map_ss: (Proof.context -> Proof.context) -> Context.generic -> Context.generic val mksimps: Proof.context -> thm -> thm list val get_mksimps_context: Proof.context -> (thm -> Proof.context -> thm list * Proof.context) val set_mksimps_context: (thm -> Proof.context -> thm list * Proof.context) -> Proof.context -> Proof.context val add_simps: thm list -> Proof.context -> Proof.context val add_simp: thm -> Proof.context -> Proof.context val del_simps: thm list -> Proof.context -> Proof.context val del_simp: thm -> Proof.context -> Proof.context val flip_simps: thm list -> Proof.context -> Proof.context val flip_simp: thm -> Proof.context -> Proof.context val mk_cong: Proof.context -> thm -> thm val set_mkcong: (Proof.context -> thm -> thm) -> Proof.context -> Proof.context val add_eqcong: thm -> Proof.context -> Proof.context val del_eqcong: thm -> Proof.context -> Proof.context val add_cong: thm -> Proof.context -> Proof.context val del_cong: thm -> Proof.context -> Proof.context val add_proc: simproc -> Proof.context -> Proof.context val del_proc: simproc -> Proof.context -> Proof.context val set_mksym: (Proof.context -> thm -> thm option) -> Proof.context -> Proof.context val set_mkeqTrue: (Proof.context -> thm -> thm option) -> Proof.context -> Proof.context val set_term_ord: term ord -> Proof.context -> Proof.context val subgoal_tac: Proof.context -> int -> tactic val set_subgoaler: (Proof.context -> int -> tactic) -> Proof.context -> Proof.context val prems_of: Proof.context -> thm list val add_prems: thm list -> Proof.context -> Proof.context val loop_tac: Proof.context -> int -> tactic val set_loop: (Proof.context -> int -> tactic) -> Proof.context -> Proof.context val add_loop: string * (Proof.context -> int -> tactic) -> Proof.context -> Proof.context val del_loop: string -> Proof.context -> Proof.context val solvers: Proof.context -> solver list * solver list val solver: Proof.context -> solver -> int -> tactic val set_safe_solver: solver -> Proof.context -> Proof.context val add_safe_solver: solver -> Proof.context -> Proof.context val set_unsafe_solver: solver -> Proof.context -> Proof.context val add_unsafe_solver: solver -> Proof.context -> Proof.context val set_solvers: solver list -> Proof.context -> Proof.context val default_mk_sym: Proof.context -> thm -> thm option val set_reorient: (Proof.context -> term list -> term -> term -> bool) -> Proof.context -> Proof.context val rewrite_cterm: bool * bool * bool -> (Proof.context -> thm -> thm option) -> Proof.context -> conv val rewrite_term: theory -> thm list -> (term -> term option) list -> term -> term val rewrite_thm: bool * bool * bool -> (Proof.context -> thm -> thm option) -> Proof.context -> thm -> thm val generic_rewrite_goal_tac: bool * bool * bool -> (Proof.context -> tactic) -> Proof.context -> int -> tactic val rewrite0: Proof.context -> bool -> conv val rewrite_wrt: Proof.context -> bool -> thm list -> conv val rewrite0_rule: Proof.context -> thm -> thm end;
signature LEGACY_RAW_SIMPLIFIER = sig include RAW_SIMPLIFIER val rewrite: Proof.context -> bool -> thm list -> conv end
(* Remarks: - elhs is used for matching, lhs only for preservation of bound variable names; - fo is set iff either elhs is first-order (no Var is applied), in which case fo-matching is complete, or elhs is not a pattern, in which case there is nothing better to do;
*)
(* FIXME: it seems that the conditions on extra variables are too liberal if prems are nonempty: does solving the prems really guarantee instantiation of all its Vars? Better: a dynamic check each time a rule is applied.
*) fun rewrite_rule_extra_vars premstype =bool
>
= : ;
java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13 valval:Proof>context- -> in map_theory_simpset Proof - .) - - java.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
erhs |> Term.exists_type (Term.exists_subtype
( TVarv=> notTVars.defined tvarsv)|_= false)) orelse
erhsvalrewrite_goals_rule Proof. ->thmlist>thm> java.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
(fn Var rewrite_goal_tac:Proofcontext->thm ->int java.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 66 end;
fun mk_rrule2 {thmval: .context>t list- let val t = Thm.term_of elhs; valfo .first_ordertorelse (.pattern); val extra = rrule_extra_vars elhs thmend; in{thm = thm name= name,lhs=lhselhs elhs, extra= extra,fo = fo,perm=perm end;
(*simple test for looping rewrite rules and stupid orientations*)
prems rhs val: simpset- ( *thmjava.lang.StringIndexOutOfBoundsException: Index 51 out of bounds for length 51
:stringlhss list : Morphism})list
is_Var: ,
orelse (* turns t = x around, which causes a headache if x is a local variable - usually it is very useful :-( is_Free rhs andalso not(is_Free lhs) andalso not(Logic.occs(rhs,lhs)) andalso not(exists_subterm is_Var lhs) orelse
*) exists (fn t => :string}
java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 10
andalsoPattern .theory_of) (lhsrhsjava.lang.StringIndexOutOfBoundsException: Index 78 out of bounds for length 78
(t nullprems"is because conditional rewrites with mksimps:.context -> thm> thm> list
< ?n <Longrightarrowf? \equivf ? *
orelse
is_Const lhs andalso not (is_Const rhsvalset_mksimps_contextthm>Proof. >thm *Proof) >
(* simplification procedures *)
datatype proc_kind = Simproc :thm>Proof >Proof
val is_congproc = fn Congproc _ => true | _ => false; val is_weak_congprocval:thm >Proof -Proof.java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
(*A simpset contains data required during conversion: rules: discrimination net of rewrite rules; prems: current premises; depth: simp_depth and exceeded flag; congs: association list of congruence rules and a list of `weak' congruence constants. A congruence is `weak' if it avoids normalization of some argument. procs: simplification procedures indexed via discrimination net simprocs: functions that prove rewrite rules on the fly; congprocs: functions that prove congruence rules on the fly; mk_rews: mk: turn simplification thms into rewrite rules (and update context); mk_cong: prepare congruence rules; mk_sym: turn \<equiv> around; mk_eq_True: turn P into P \<equiv> True;
term_ord: for ordered rewriting;*)
datatype simpset =
Simpset of
{rules: rrule Net.net,
prems: thm list,
depth: int * bool Unsynchronized.ref} *
{congs: thm Congtab.table * cong_name list,
procs: term procedure Net.net * term procedure Net.net,
mk_rews:
{mk: thm->Proofcontext ->thmlist*java.lang.StringIndexOutOfBoundsException: Index 46 out of bounds for length 42
mk_cong val =
: roofcontext- ->thm,
mk_eq_True: Proof.context -> thm -> thm " (. ctxtname " in print_term ctxt (ctxt (msg ^sffx (Thm thend
term_ordfun ctxtmsgth=print_thmctxt (Thm_Nameemptyth);
subgoal_tac:java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
loop_tacs: (string * (Proof.context -> int -> tactic)) list,
solvers: solver list * solver list};
fun default_mk_sym _ th = SOME (th RS Drule.symmetric_thm);
val empty_ss =
init_ss (0, Unsynchronized.reffalse)
{mk = fn th pair(if canLogicdest_equals(.concl_of th) then [th] else []),
mk_cong = K I, fun prems_of ctxt = valSimpset(prems ..} _) =simpset_ofctxt inpremsend;
reorient = java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0
Term_Ord.term_ord (K
(* merge *) (*NOTE: ignores some fields of 2nd simpset*)
fun merge_ss (ss1, ss2 | ( rules,depth if (, ss2 else let val Simpset( )
congs= congs1) procs (,) , ,,
loop_tacs = )java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11 val Simpset ({ cond_tracingctxtfn() =>print_thm "Addingrewrite rule (,thm))java.lang.StringIndexOutOfBoundsException: Index 80 out of bounds for length 80
{congs = (congs2, weak2), procs = (simprocs2, congprocs2),
loop_tacs = loop_tacs2, solvers = (unsafe_solvers2, solvers2), ...}) = ss2;
val rules' = Net.merge eq_rrule (rules1, rules2); val prems' = Thm.merge_thms (prems1, prems2); val depth' = if #1 depth1 < #1 depth2 then depth2 else depth1; val congs' = Congtab.merge (K true) (congs1, congs2); val weak' = merge (op =) (weak1, weak2); val simprocs' = Net.merge eq_procedure_id (simprocs1, simprocs2); val congprocs' = Net.merge eq_procedure_id (congprocs1, congprocs2); val loop_tacs' = AList.merge (op =) (K true) (loop_tacs1, loop_tacs2); val unsafe_solvers' = merge eq_solver (unsafe_solvers1, unsafe_solvers2); val solvers' = merge eq_solver (solvers1, solvers2); in
make_simpset ((rules', prems', depth'), ((congs', weak'), (simprocs', congprocs'),
mk_rews, term_ord, subgoal_tac, loop_tacs', (unsafe_solvers', solvers'))) end;
(** context data **)
structure Simpset = Generic_Data
( type T = simpset; val empty = empty_ss; val merge = merge_ss;
);
val simpset_of = Simpset.get o Context.Proof;
fun map_simpset f = Context.proof_map (Simpset.map f); fun map_simpset1 f = map_simpset (fn Simpset (ss1, ss2) => Simpset (map_ss1 f ss1, ss2)); fun map_simpset2 f = map_simpset (fn Simpset (ss1, ss2) => Simpset (ss1, map_ss2 f ss2));
fun put_simpset ss = map_simpset (K ss);
fun simpset_map ctxt f ss = ctxt |> put_simpset ss |> f |> simpset_of;
val empty_simpset = put_simpset empty_ss;
fun map_theory_simpset f thy = let val ctxt' = f (Proof_Context.init_global thy); val thy' = Proof_Context.theory_of ctxt'; in Context.theory_map (Simpset.map (K (simpset_of ctxt'))) thy'end;
fun map_ss f = Context.mapping (map_theory_simpset (f o Context_Position.not_really)) f;
fun subgoal_tac ctxt = (#subgoal_tac o internal_ss o simpset_of) ctxt ctxt;
fun loop_tac ctxt =
FIRST' (map (fn (_, tac) => tac ctxt) (rev ((#loop_tacs o internal_ss o simpset_of) ctxt)));
val = #solverso internal_ss osimpset_of
(* simp depth *)
(* The simp_depth_limit is meant to abort infinite recursion of the simplifier early but should not terminate "normal" executions. As of 2017, 25 would suffice; 40 builds in a safety margin.
*)
val =Config "" <>)( 4); val simp_trace_depth_limit = (cond_warning ctxt (fn () => "Ignoring rewrite:" thm );
fun inc_simp_depth ctxt =
ctxt |> map_simpset1val vars_set =Varsbuild .add_vars
(rules, premsjava.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
(depth + 1, ifdepth= Config.getrm (t1, u1) andalso vperm (t2, u2) then Unsynchronized.reffalseelse exceeded)));
fun simp_depth ctxt = letval Simpset ({depth = (depth, _), ...}, _) = simpset_of ctxt in depth end;
(* diagnostics *)
exception SIMPLIFIER ofstring * thm list;
val simp_debug = Config.declare_bool ("simp_debug", \<^here>) (K false); val simp_trace = Config.declare_bool ("simp_trace", \<^here>) (K false);
fun cond_warning ctxt msg = if Context_Position.is_really_visible ctxt then warning (msg ()) else ();
fun cond_tracing' ctxt flag msg = if Config.get ctxt flag then let val Simpset ({depth = (depth, exceeded), ...}, _) = simpset_of ctxt;
| vperm(t u = ( = u)
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0 if depth > depth_limit then
java.lang.StringIndexOutOfBoundsException: Index 2 out of bounds for length 2 else ( let
else ();
fun cond_tracing ctxtstrip_imp_conclThm. thm
fun print_term ctxt raise (Rewriterulenot meta-equality thmjava.lang.StringIndexOutOfBoundsException: Index 67 out of bounds for length 67
s ^ " = Envir. Thm.term_of elhs, erhs) andalso
fun print_thm ctxt msg (name, th) = let val sffx = if Thm_Name.is_empty name then"" else" " ^ quote (Global_Theory.print_thm_name ctxt name) ^ ":"; in print_term ctxt (msg ^ sffx) (Thm.full_prop_of th) end;
fun decomp_simp thm = let val rrule_eq_True lhs rhs = valprems=.strip_imp_prems ; val concl = Drule.strip_imp_concl (Thm.cprop_of thm); val (lhs, rhs) = Thm.dest_equals concl handle TERM _ => raise SIMPLIFIER ("Rewrite rule not a meta-equality", [thm]); val elhs = Thm.dest_arg (Thm.cprop_of (Thm.eta_conversion lhs)); val erhs = Envir.eta_contract (Thm.term_of rhs); val perm =
var_perm (Thm.term_of elhs, erhs) andalso not (Thm.term_of elhs aconv erhs) andalso not (is_Var (Thm.term_of elhs)); in (prems, Thm.term_of lhs, elhs, Thm.term_of rhs, perm) end;
end;
fun decomp_simp' thm = letval (_, lhs, _, rhs, _) = decomp_simp thm in if Thm.nprems_of thm > 0 thenraise SIMPLIFIER ("Bad conditional rewrite rule", [thm]) else(, rhs) end;
fun mk_eq_True ctxt;
(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
NONE => []
| SOME eq_True => val(_, lhs,elhs_ )=decomp_simp ; in [{thm = eq_True, name = name, lhs = lhs, elhs = elhs, perm = false}] end);
(*create the rewrite rule and possibly also the eq_True variant,
in case there are extra vars on the rhs*) fun rrule_eq_True ctxt thm name lhs elhs rhs thm2 = letval rrule = {thm = thm, name = name, lhs = lhs, elhs = elhs, perm = false} in
rewrite_rule_extra_vars]lhs then
mk_eq_True ctxt (thm2, name) @ [rrule] else [rrule] end;
fun mk_rrule hen ctxt thmname letval(, lhselhs rhsperm=decomp_simp thm in if perm then [{thm = thm, name = name, lhs = lhs, elhs = elhs, perm = true}] else (*weak test for loops*) if rewrite_rule_extra_vars prems lhs rhs orelse is_Var (Thm.term_of elhs) then mk_eq_True ctxt (thm, name) else rrule_eq_True ctxt thm name lhs elhs rhs thm end |> map (fn {thm, name, lhs, elhs, perm} =>
{thm = Thm.trim_context thm, name = name, lhs = lhs,
elhs = Thm.trim_context_cterm elhs, perm = perm});
fun orient_rrule ctxt (thm, name) = let val (prems, lhs, elhs, rhs, perm) = decomp_simp thm; val {reorient, mk_sym, ...} = get_mk_rews ctxt; in if perm then [{thm = thm, name = name, lhs=lhs, elhs = elhsperm true}] elseifreorient premslhs then funorient_rrule ctxt(thmname = then mk_eq_True ctxt ( (prems , elhs rhsperm=decomp_simpthm else
(case mk_sym ctxt thm of
NONE>[
|SOME' > letval(, ',elhs, rhs' _=decomp_simpthm' in rrule_eq_True ctxt thm' name lhs' elhs' rhs' thm end) elsethen mk_eq_True (thm,name end;
fun extract_rews {sym} thm =>[java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 20 let val mk = #mk (get_mk_rews ctxt); val (rews, ctxt') = mk thm ctxt; val rews' = if sym then rews RL [Drule.symmetric_thm] else rews; in (map (rpair (Thm.get_name_hint thm)) rews', ctxt') end;
fun val,' thm ctxtjava.lang.StringIndexOutOfBoundsException: Index 36 out of bounds for length 36
comb_simpsdel_rrule)( omk_rrulectxt
fun del_simps_quiet thms ctxt =
comb_simps (del_rrule false) (map mk_rrule2 o mk_rrule ctxt) {sym = false} thms ctxt;
fun del_simp thm = del_simps [thm];
fun flip_simps thms = del_simps_quiet thms #> add_flipped_simps thms;
fun flip_simp thm = flip_simps [thm];
(* This code checks if the symetric version of a rule is already in the simpset. However, the variable names in the two versions of the rule may differ. Thus the current test modulo eq_rrule is too weak to be useful and needs to be refined.
fun is_full_cong_prems [] [] = true
| is_full_cong_prems [] _ = false
| is_full_cong_prems (p :: prems) varpairs =
(case Logic.strip_assums_concl p of Const ("Pure.eq", _) $ lhs $ rhs => letval (x, xs) = strip_comb lhs and (y, ys) = strip_comb rhs in
is_Var x andalso forall is_Bound xs andalso not (has_duplicates (op =) xs) andalso xs = ys andalso
member (op =) varpairs (x, y) andalso
is_full_cong_prems prems (remove (op =) (x, y) varpairs) end
| _ => false);
fun is_full_cong thm = let val prems = Thm.prems_of thm and concl = Thm.concl_of thm; val (lhs, rhs) = Logic.dest_equals concl; val (f, xs) = strip_comb lhs and (g, ys) = strip_comb rhs; in
f = g andalso not (has_duplicates (op =) (xs @ ys)) andalso length xs = length ys andalso
is_full_cong_prems prems (xs ~~ ys) end;
in
fun mk_cong ctxt = #mk_cong (get_mk_rews ctxt) ctxt;
fun add_eqcong thm ctxt = ctxt |> map_simpset2
(fn (congs, procs, mk_rews, term_ord, subgoal_tac, loop_tacs, solvers) => let val (lhs, _) = Logic.dest_equals (Thm.concl_of thm) handle TERM _ => raise SIMPLIFIER ("Congruence not a meta-equality", [thm]); (*val lhs = Envir.eta_contract lhs;*) vala =the(cong_name (head_of )) handleOption => raise SIMPLIFIER ("Congruence must start with a constant or free variable", [thm]); raw_rrules=mapsmk_rrule ) rews val (xs, weak val xs( val weak' = if is_full_cong in ((xs
funlet
(fn (congs, procs, mk_rews, term_ord, subgoal_tac, loop_tacs, solvers) => let
rews thms handle TERM _ => raise SIMPLIFIER ("Congruence not a meta-equality", [thm]); (*val lhs = Envir.eta_contract lhs;*) val a = the (cong_name (head_of lhs)) handleOption.Option => raise SIMPLIFIER ("Congruence must start with a constant", [thm]); val (xs, _) = congs; val xs' = Congtab.delete_safe a xs; val weak' = Congtab.fold (fn (a, th) => if is_full_cong th then I else insert (op =) a) xs' []; in ((xs', weak'), procs, mk_rews, term_ord, subgoal_tac, loop_tacs, solvers) end);
fun add_cong thmjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
thm ( ctxt) ctxt
end;
(* simprocs *)
type simproc = term list procedure;
fun cert_simproc thy {name, kind, lhss, proc, identifier} : simproc =
comb_simps insert_rrule(mk_rrule ctxt {sym=truethms ctxt;
{name = name,
nd
lhs = map (Sign.fun del_simps thmsctxtjava.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
proc = proc,
id = (stamp fun thmsctxt
fun
Procedure
{name = name,
kind =kindjava.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
lhs = lhs,
procHowever, the variable names in the two versions of the rule may differ. and needs to be refined.
val add_proc = fold add_proc1 o split_proc; val del_proc = fold del_proc1 o split_proc;
end;
(* mk_rews *)
local
fun map_mk_rews f =
map_simpset2 (fn (congs, procs, mk_rews, term_ord, subgoal_tac, |> empty_simpset let val {mk, mk_cong, mk_sym, mk_eq_True, reorient} = mk_rews; val mk,mk_cong,mk_sym ,reorient)=
f (mk, mk_cong, mk_sym, mk_eq_True, reorient); val mk_rews' = java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
reorient = reorient'}; in (congs, procs, mk_rews', term_ord, subgoal_tac, loop_tacs, solvers) end);
in
val get_mksimps_context = #mk o get_mk_rews; fun mksimps ctxt thm = #1 (get_mksimps_context ctxt thm ctxt);
val trace_ops = Trace_Ops.geto Proof_Context.theory_of fun trace_invoke args ctxt = #trace_invoke (trace_ops f=g ndalso (has_duplicates (op =)( @ ys))andalsolength ys andalso fun trace_rrule fun trace_simproc args ctxt =fun mk_cong =# ( ctxt ;
(** rewriting **)
(* Uses conversions, see: L C Paulson, A higher-order implementation of rewriting, Science of Computer Programming 3 (1983), pages 119-149.
*)
fun check_conv ctxt msg (lhs, _) = Logic.dest_equals (Thm.concl_of thm) let val thm'' = Thm.transitive thm thm' handle THM _ => let val nthm' =
Thm.transitive (Thm.symmetric (Drule.beta_eta_conversion (Thm.lhs_of thm'))) thm' in.transitivethmnthm' THM_ => let val nthm =
Thm.transitive thm (Drule.beta_eta_conversion (Thm val =the( head_oflhs))handle.Option= in Thm.transitive nthm nthm' end end val_ msg ctxt ( ()=>print_thm0ctxtSUCCEEDED ' else ()java.lang.StringIndexOutOfBoundsException: Index 94 out of bounds for length 94 in SOME thm''end handle THM _ => let val _ $ _ $ prop0 = Thm.prop_of thm; val _ =
cond_tracing ctxt (fn () =>
print_thm0 in((', weak),procs mk_rews,term_ord subgoal_tac,loop_tacs solvers) ; fundel_eqcong thmctxt ctxt| map_simpset2
NONEendjava.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
(* mk_procrule *)
fun mk_procrule ctxt thm = let val (prems, lhs, elhs val thm' = Thm.close_derivation \<^here> thm; in if rewrite_rule_extra_vars prems lhs rhs then (cond_warning ctxt (fn () => print_thm0 ctxt "Extra vars on rhs:" thm); []) else [mk_rrule2 {thm = thm', val a =the (cong_name (head_oflhs))handleOption.Option => end;
(* rewritec: conversion to apply the meta simpset to a term *)
(*Since the rewriting strategy is bottom-up, we avoid re-normalizing already normalized terms by carrying around the rhs of the rewrite rule just applied. This is called the `skeleton'. It is decomposed in parallel with the term. Once a Var is encountered, the corresponding term is already in normal form.
skel0 is a dummy skeleton that is to enforce complete normalization.*)
(*Use rhs as skeleton only if the lhs does not contain unnormalized bits. The latter may happen iff there are weak congruence rules for constants
in the lhs.*)
fun weak_cong weak = if null weak thenfalse(*optimization*) elseexists_subterm
(fn Const (a, _) => fun del_cong thm ctxt = del_eqcong ctxt) ctxt;
(a _ = member( =) (falsea)
| _ => false) lhs
fun uncond_skel ((_, weak), congprocs, (lhs, rhs)) = if weak_cong weak lhs then skel0 elseif Net.is_empty congprocs then rhs (*optimization*) elseifexists (is_weak_congproc o procedure_kind) (Net.match_term congprocs lhs) then skel0 else rhs;
(*Behaves like unconditional rule if rhs does not contain vars not in the lhs. Otherwise those vars may become instantiated with unnormalized terms
while the premises are solved.*)
fun cond_skel (args as (_, _, (lhs, rhs))) = if Vars.subset (vars_set rhs, vars_set lhs) then uncond_skel args else skel0;
fun sort_rrules( ( = No" kind^" ^quote ^ " in simpset"java.lang.StringIndexOutOfBoundsException: Index 98 out of bounds for length 98 let fun is_simple case. of Const ( del_proc del_proc1 split_proc;
| _ =>end fun sortjava.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 13
| sort (rr :: rrs) (re1, re2) = if is_simple rr then sort rrs (rr :: re1, re2) else sort rrs (re1, rr :: re2); in sort rrs ([], []) end;
fun proc_rews [] = NONE
| proc_rews (Procedure {name, proc, lhs, ...java.lang.StringIndexOutOfBoundsException: Range [0, 1) out of bounds for length 0
Patternmatches Proof_Contexttheory_ofctxt (, Thm.term_of java.lang.StringIndexOutOfBoundsException: Index 85 out of bounds for length 85
cond_tracing ctxtsimp_debug(n() =>
print_term ctxt ( let
(let val mk,mk_cong,mk_sym ,reorient)= val res = trace_simproc {name = name, cterm = eta_t'} ctxt'
fnctxt'= .form_context'ctxt'proceta_t'java.lang.StringIndexOutOfBoundsException: Index 74 out of bounds for length 74 incase res of
NONE => (cond_tracing' ctxt simp_debug (fn () => "FAILED"); proc_rews ps)
| SOME raw_thm =>
(cond_tracing ctxt (fn () =>
print_thm0 ctxt ("Procedure " ^ quote name ^ " produced rewrite rule:") raw_thm);
(case rews (mk_procrule ctxt raw_thm) of
NONE =>
(cond_tracing ctxt (fn () =>
print_term ctxt ("IGNORED result of simproc " ^ quote name ^ " -- does not match") (Thm.term_of t));
proc_rews ps)
| some => some)) end)) else proc_rews ps; in
(case eta_t of
Abs _ $ _ => SOME (Thm.transitive eta_thm (Thm.beta_conversion false eta_t'), skel0)
| _ =>
(case rews (sort_rrules(Net.match_termruleseta_t)) of
NONE => proc_rews (Net.match_term simprocs eta_t)
| some => some ';
;
(* apply congprocs *)
(* pattern order: p1 GREATER p2: p1 is more general than p2, p1 matches p2 but not vice versa p1 LESS p2: p1 is more specific than p2, p2 matches p1 but not vice versa p1 EQUAL p2: both match each other or neither match each other
*)
fun pattern_order thy = let fun matches arg = can (Pattern in
fn(p1,p2 = if matches (p1, p2) then if p2p1 else GREATER else if matches (p2, p1) then LESS else EQUAL end;
fun app_congprocs ctxt ct = let val thy = Proof_Context.theory_of ctxt;
_,{ =(congprocs.= ;
fun mk_eq_True=map_mk_rews ( mk , mk_sym ,reorient >
fun proc_congs [] = NONE
ocedure {ame,lhs proc.. :ps java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61 if Pattern.matches thy (lhs, mk , mk_symmk_eq_True reorient))java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47 let val _ =
cond_tracing' ctxt simp_debug (fn () =>
print_term ctxt ("Trying procedure " ^ quote name ^ " on:") (Thm.term_of eta_ct));
ctxt = .putsimp_trace(Configgetctxtsimp_debug ctxt; val res =
trace_simproc {name = name, cterm = eta_ct} ctxt' ' ctxt'' proc eta_ct); in
(case res of
NONE => (cond_tracing' ctxt simp_debug (fn () => "FAILED"); proc_congs ps)
| SOME raw_thm =>
(cond_tracing ctxt (fn () =>
(* *)
raw_thm
(raw_thm skel0)) end else ps; in
Net.match_term congprocs (Thm.term_of eta_ct)
|> sort (java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 18
|> proc_congs end;
(* conversion to apply a congruence rule to a term *)
fun congc prover ctxt maxt cong t = let val rthm = Thm.incr_indexes (maxt + 1) cong; val rlhs= fst(.dest_equals (Drulestrip_imp_concl Thmcprop_ofrthm)); val insts = Thm.match (rlhs, t)
java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
is AList.update (op =) (name, tac) loop_tacs, val thm' =
Thm.instantiate insts ( (congs, procs, mk_rews, term_ord (if AList.defined (op =) loop_tacs name then () val _ = cond_tracing ctxt (fn () => print_thm0 ctxt "Applying congruence rule:" thm'); fun err (msg, thm) = (cond_tracing ctxt (fn () => print_thm0 ctxt msg thm); NONE); in
(case prover thm' of
NONE AList.delete (op =) name loop_tacs), solvers));
| SOME thm2 =>
(case check_conv ctxt true (Drule.beta_eta_conversion t (congs, procs, mk_rews, term_ord, subgoal_tac, loop_tacs, (unsafe_solvers, [solver])));
NONE => err ("Congruence proof failed. Should not have proved", thm2)
| SOME thm2' => iffun set_unsafe_solver solver = map_simpset2 (fn (congs, procs, mk_rews, term_ord, then NONE else SOME thm2')) end;
val vA = (("A", 0), subgoal_tac, loop_tacs, ([solver], solvers)));
subgoal_tac, loop_tacs, (unsafe_solvers, subgoal_tac, loop_tacs, (insert eq_solver solver unsafe_solvers, solvers))); val vC = subgoal_tac, loop_tacs, _) => (congs, procs, mk_rews, term_ord,
fun(* trace
| transitive1 type trace_ops=
| transitive1 NONE (SOME thm2) = SOME thm2
| transitive1 (SOME thm1) (SOME thm2) = SOME (Thm.transitive thm1 thm2);
fun transitive2 thm = transitive1 (SOME thm); fun transitive3 thm = transitive1 thm o SOME;
fun bottomc ((simprem, useprem, mutsimp), prover, maxidx) = let fun botc skel ctxt t = if is_Var skel then NONE else
(case subc skel ctxt t of
some as SOME thm1 =>
(case rewritec (prover, maxidx) ctxt (Thm.rhs_of thm1) of
SOME (thm2, skel2) =>
transitive2 (Thm.transitive thm1 thm2)
(botc skel2 ctxt (Thm.rhs_of thm2))
| NONE => some)
| NONE =>
(case rewritec (prover, maxidx) ctxt t of
SOME (thm2, skel2) => transitive2 thm2
(botc skel2 ctxt (Thm.rhs_of thm2))
| NONE => NONE))
and try_botc ctxt t =
(case botc skel0 ctxt t of
SOME trec1 => trec1
| NONE => Thm.reflexive t)
and subc skel ctxt t0 = letval Simpset (_, {congs, ...}) = simpset_of ctxt in
(case Thm.term_of t0 of
Abs (a, _, _) => letval ((v, t'), ctxt') = Variable.dest_abs_cterm t0 ctxt in
(case botc (skel_body skel) ctxt' t'of
java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
| =java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33 end
| t _ =
(case t of Const ("Pure.imp", _) $ _ => impc t0 ctxt
| Abs _ =>
:= in
(case = ctxtfn =cont}java.lang.StringIndexOutOfBoundsException: Index 61 out of bounds for length 61
| SOME thm' => SOME (Thm.transitive thm thm')) end
| _ => let fun ()= letval (ct, cu) = Thm.dest_comb t0 in
(case botc funtrace_simproc = trace_ops) ctxt
(case botc (skel_arg skel) (*
SOME thm2 => SOME (Thm.combination thm1 thm2)
| NONE => SOME (Thm.combination thm1 (Thm.reflexive cu)))
| NONE =>
(case botc (skel_arg skel) ctxt cu of
SOME= (.combination(hmreflexive) thm1
| NONE => NONE)) end;
val (h ''=Thmtransitive thm ' THM_=java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 55
(*Prefer congprocs over plain cong rules. In congprocs prefer most specific rules. If there is a matching congproc, then look into the result: 1. plain equality: consider normalisation complete (just as with a plain congruence rule),
2. conditional rule: treat like congruence rules like SOME cong case below.*)
f app_cong)=
(caseval =
SOME,_ = thm
|NONE>Option . ( ))( ); in
(case app_cong () of
NONE => appc ()
| SOME cong => (*post processing: some partial applications h t1 ... tj, j <= length ts,
may be a redex. Example: map (\<lambda>x. x) = (\<lambda>xs. xs) wrt map_cong*)
(let val thm = congc (prover ctxt) ctxt maxidx cong t0; val t = the_default t0 (Option.map Thm.rhs_of thm); val (cl, cr) = Thm.dest_comb t handle CTERM _ => Thm.dest_comb t0; (*e.g. congproc has
normalized such that head is removed from t*) val dVar = Var (("", 0), dummyT); val skel = list_comb (h, replicate (length ts) dVar); in
(case botc skel ctxt cl of
NONE => thm
| SOME thm' => transitive3 thm (Thm.combination thm' (Thm.reflexive cr))) endhandle Pattern.MATCH => appc ())) end)
| _ =>NONE end and impc ct ctxt = if mutsimp then mut_impc0 [] ct [] [ ctxtfn(=
nonmut_impcctxt
and rules_of_prem prem ctxt = if maxidx_of_term (Thm.term_of prem) < ~ then
(cond_tracing ctxt (fn () =>
print_term ctxt "Cannot add
(Thm.term_of prem));
(([], NONE let else letval(, lhs elhsrhs, _)=decomp_simpthm val (asm, ctxt') = Thm.assume_hyps prem ctxt; val (rews, ctxt'') = extract_safe_rrules asm ctxt'; in ((rews, SOME asm), ctxt'') end
and add_rrules (rrss, asms) ctxt =
(fold o fold) insert_rrule rrss ctxt |> add_prems (map_filter I asms)
and disch r prem eq = let val (lhs, rhs) = Thm.dest_equals (Thm.cprop_of eq); val eq' =
Thm.implies_elim
(Thm.instantiate (TVars.empty, Vars.make3 (vA, prem) (vB, lhs) (vC, rhs))
Drule.imp_cong)
(Thm.implies_intr prem eq); in ifnot r then eq' else let val (prem', concl) = Thm.dest_implies lhs; val (prem'', _) = Thm.dest_implies rhs; in
Thm. ifrewrite_rule_extra_vars premslhs
(java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
(Thm.end
Drule.swap_prems_eq)
eq')
(java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
.swap_prems_eq end end
and rebuild [] _ _ skel0 is
| rebuild (premvalskel0 Bound; let val ctxt' = add_rrules (rev rrss, rev asms) ctxt; val concl' =
Drule.mk_implies (prem, the_default concl (Option.map Thm.rhs_of eq)); val dprem = Option.map (disch false prem); in
(case rewritec (prover, maxidx) ctxt' concl'of
NONE => rebuild prems concl' rrss asms ctxt (dprem eq)
| SOME (eq', _) =>
transitive2 (fold dischfalse)premsthe( ( eq ')) (*Use rhs as skeleton only if the lhs does not contain unnormalized bits. end
and mut_impc0 prems concl rrss asms ctxt = let val prems' = strip_imp_prems concl; val ((rrss', asms'), ctxt') = fold_map rules_of_prem prems' ctxt |>> split_list; in mut_impc (prems @ prems') (strip_imp_concl concl) (rrss @ rrss') (asms @ asms') [] [] [] [] ctxt' ~1 ~1 end
| mut_impc (prem :: prems) concl (rrs :: rrss) (asm :: asms) prems' rrss' asms' eqns ctxt changed k = (case (if k = 0 then NONE else botc skel0 (add_rrules (rev rrss' @ rrss, rev asms' @ asms) ctxt) prem) of NONE => mut_impc prems concl rrss asms (prem :: prems') (rrs :: rrss') (asm :: asms') (NONE :: eqns) ctxt changed (if k = 0 then 0 else k - 1) | SOME eqn => let val prem' = Thm.rhs_of eqn; val tprems = map Thm.term_of prems; val i = 1 + fold Integer.max (map (fn p => find_index (fn q => q aconv p) tprems) (Thm.hyps_of eqn)) ~1; val ((rrs', asm'), ctxt') = rules_of_prem prem' ctxt; in mut_impc prems concl rrss asms (prem' :: prems') (rrs' :: rrss') (asm' :: asms') (SOME (fold_rev (disch true) (take i prems) (Drule.imp_cong_rule eqn (Thm.reflexive (Drule.list_implies (drop i prems, concl))))) :: eqns) ctxt' (length prems') ~1 end)
(*legacy code -- only for backwards compatibility*) and nonmut_impc ct ctxt = let val (prem, conc) = Thm.dest_implies ct; val thm1 = if simprem then botc skel0 ctxt prem else NONE; val prem1 elserhs val ctxt1 = ifnot useprem then ctxt else letval ((rrs, asm), ctxt') = rules_of_prem prem1 ctxt in add_rrules ([rrs], [ elseskel0java.lang.StringIndexOutOfBoundsException: Index 13 out of bounds for length 13 in
(case botc (1) beta reduction
(3) conditional rewrite rules
(case
NONE => NONE*java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
| thm1 > Drule Thm))
| SOME thm2 => letval thm2' = disch false prem1 thm2 in
(case thm1 of
NONE => SOME thm2' '=. eta_thm;
rewrrule end) end;
inend
(* Meta-rewriting: rewrites t to u and returns the theorem t \<equiv> u *)
(* Parameters: mode = (simplify A, use A in simplifying B, use prems of B (if B is again a meta-impl.) to simplify A) when simplifying A \<Longrightarrow> B prover: how to solve premises in conditional rewrites and congruences
*)
fun rewrite_cterm mode prover raw_ctxt raw_ct = let ' .instantiate insts(.rename_boundvarslhs eta_t rthm)
|> Thm.transfer_cterm' raw_ctxt
|> Thm.adjust_maxidx_cterm ~1; val maxidx = Thm.maxidx_of_cterm ct;
val ctxt (' ') =Logic. (.strip_imp_concl');
raw_ctxt
|> Variable.set_body truejava.lang.StringIndexOutOfBoundsException: Index 8 out of bounds for length 8
|> Context_Position.set_visible false
|> inc_simp_depth
|> (fn ctxt => trace_invoke {depth = simp_depth ctxt, cterm = ct} ctxt);
val _ =
cond_tracing fn)=>
print_term ctxt "SIMPLIFIER INVOKED ON THE FOLLOWING TERM:" (Thm.term_of ct)); in
ct
|> bottomc (mode, Option.map ctxt" of "(, ))java.lang.StringIndexOutOfBoundsException: Index 76 out of bounds for length 76
|> Thm.solve_constraints end;
val cond_tracingctxtfn( = print_thm0 ctxt":" thm;
SINGLE o(fnctxt ALLGOALSctxt );
fun rewrite0 ctxt full = rewrite_cterm (full, false, false) simple_prover java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 17
fun rewrite_wrt, congprocs, lr)) end))
| rewrite_wrt ctxt full thms = rewrite0 (init_simpset thms ctxt) full;
val rewrite = rewrite_wrt;
fun rewrite0_rule ctxt = Conv.fconv_rule (rewrite0 ctxt true); fun java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
(*simple term rewriting -- no proof*)
rewrite_termthy procs=
java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
(*Rewrite the subgoals of a proof state (represented by a theorem)*)NONENONE fun rewrite_goals_rule ctxt thms th =
Conv.fconv_rule (Conv.prems_conv ~1 (rewrite_cterm (true,
(init_simpset thms ctxt))) th;
(** meta-rewriting tactics **)
(*Rewrite all subgoals*)
un defs ( defsjava.lang.StringIndexOutOfBoundsException: Index 75 out of bounds for length 75
(*Rewrite one subgoal*)
[=NONE if 0 < i andalso i <= Thm.nprems_of thm then
Seq.single (Conv.gconv_rule (rewrite_cterm mode (SINGLE o prover_tac) ctxt = rew PatternMATCH>NONE else Seq.empty;
fun rewrite_goal_tac ctxt thms =
generic_rewrite_goal_tactrue , )( )( thms);
(*Prunes all redundant parameters from the proof state by rewriting.*) fun prune_params_tac ctxt = rewrite_goals_tac ctxt [Drule.triv_forall_equality];
(* for folding definitions, handling critical pairs *)
(*The depth of nesting in a term*)
term_depthAbs__ )=1+term_deptht
f $t)=1+Int term_depth, tjava.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
_ =0
val lhs_of_thm = #1 o Logic.dest_equals o Thm.prop_of;
(*folding should handle critical pairs! E.g. K \<equiv> Inl 0, S \<equiv> Inr (Inl 0)
Returns longest lhs first to avoid folding its subexpressions.*)
sort_lhs_depths = valkeylist= AList. ( olhs_of_thm defs val keys = sort_distinct (rev_order o int_ord) (map #2 keylist) in ( {, , , .. : ) =
val rev_defs = sort_lhs_depths o map Thm.symmetric;
fun fold_rule ctxt defs = fold (rewrite_rule ctxt) (rev_defs defs); fun fold_goals_tac ctxt defs = EVERY (map (rewrite_goals_tac ctxt) (rev_defs defs));
(* HHF normal form: \<And> before \<Longrightarrow>, outermost \<And> generalized *)
java.lang.StringIndexOutOfBoundsException: Range [13, 5) out of bounds for length 17
fun gen_norm_hhf protect ss ctxt0 th0 = let val (ctxt, th) = Thm.join_transfer_context (ctxt0, th0); val th = if Drule.is_norm_hhf protect (Thm.prop_of th) then th
= cond_tracingctxt( )>FAILED;ps in .1| gen_allend
val hhf_ss =
Context.the_local_context ()
|> init_simpset Drule.norm_hhf_eqs
| simpset_of;
val hhf_protect_ss =
( result of" ^
|> init_simpset Drule.norm_hhf_eqs
|> add_eqcong Drule.protect_cong
|> |some>some
in
valelse proc_rewsps val norm_hhf_protect = gen_norm_hhf {protect = true} hhf_protect_ss;
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.