signature PROPERTY = sig val is_property: term -> bool val add_property_field_const: term -> theory -> theory val is_property_field: theory -> term -> bool val strip_property_field: theory -> term -> term list val is_property_prem: theory -> term -> bool val get_property_name: term -> string val get_property_names: term list -> stringlist val get_property_arg: term -> term val get_property_arg_th: thm -> cterm
(* About the PropertyUpdateData table.*) val can_add_property_update: thm -> theory -> bool val add_property_update: thm -> theory -> theory val lookup_property_update: theory -> string -> thm list val lookup_property_update_fun: theory -> string -> thm list val instantiate_property_update: Proof.context -> term -> thm -> thm option end;
(* Rules deriving new properties of t from other properties of t. They areindexedunderthenamesofthepropertiesinthepremises.
*) structure UpdateData = Theory_Data ( type T = (thm list) Symtab.table; val empty = Symtab.empty; val merge = Symtab.merge_list Thm.eq_thm_prop
)
(* Rules for deriving properties of f x_1 ... x_n from properties of x_1,...x_n.Theyareindexedunderthenameoftheheadfunction f.
*) structure UpdateFunData = Theory_Data ( type T = (thm list) Symtab.table; val empty = Symtab.empty; val merge = Symtab.merge_list Thm.eq_thm_prop
)
(* Set of fields of a structure whose property can be considered as propertiesofthestructureitself.Relevantwhenchecking is_property_prem.
*) structure FieldData = Theory_Data ( type T = unit Symtab.table; val empty = Symtab.empty; val merge = Symtab.merge (K true)
)
(* Whether the term is a property predicate applied to a term. *) fun is_property t = let val _ = assert (fastype_of t = Basic_UtilBase.boolT) "is_property: wrong type" val (f, ts) = Term.strip_comb t in if length ts <> 1 orelse not (Term.is_Const f) thenfalseelse let val T = fastype_of (the_single ts) val (dT, _) = Term.strip_type T in
length dT = 0 andalso T <> Basic_UtilBase.boolT end end
(* Insert the following constant as a property field. *) fun add_property_field_const t thy = case Term.head_of t of Const (c, T) => let val (pTs, _) = Term.strip_type T val _ = if length pTs = 1then () else error "Add property field: input should be a field." val _ = writeln ("Add field " ^ c ^ " as property field.") in
thy |> FieldData.map (Symtab.update_new (c, ())) end
| _ => error "Add property field: input should be a constant."
(* Whether the term is zero or more property field constants applied toaVarterm.
*) fun is_property_field thy t = case t of
Var _ => true
| Const (c, _) $ t' =>
Symtab.defined (FieldData.get thy) c andalso is_property_field thy t'
| _ => false
(* Given a term t, return all possible ways to strip property field constantsfromt.Forexample,iftisoftheformf1(f2(x)),where f1andf2arepropertyconstants,thentheresultis[f1(f2(x)), f2(x),x].
*) fun strip_property_field thy t = case t of Const (c, _) $ t' => if Symtab.defined (FieldData.get thy) c then
t :: strip_property_field thy t' else [t]
| _ => [t]
(* Stricter condition than is_property: the argument must be a schematicvariable(uptopropertyfields).
*) fun is_property_prem thy t =
is_property t andalso is_property_field thy (dest_arg t)
(* Return the argument of the property. *) fun get_property_arg t =
dest_arg t handle Fail "dest_arg" => raise Fail "get_property_arg: t in wrong form."
(* Return the argument of the property theorem as a cterm. *) fun get_property_arg_th th =
Thm.dest_arg (UtilLogic.cprop_of' th) handle CTERM _ => raise Fail "get_property_carg"
| Fail "dest_Trueprop" => raise Fail "get_property_carg"
(* Add the given rule as a property update. The requirements on th is asfollows:
-Eachpremisemustbeapropertyconstanton?x(inthefirst case)oroneof?x1...?xn(inthesecondcase).Theargumentof thepropertyintheconclusionmustcontainallschematic variablesofthetheorem.
*) fun can_add_property_update th thy = let val (prems, concl) = UtilLogic.strip_horn' th in if is_property concl andalso forall (is_property_prem thy) prems thenlet val concl_arg = get_property_arg concl val all_vars = map Var (Term.add_vars (Thm.prop_of th) []) in if is_Var concl_arg then (* First case: check that concl_arg is the only schematic Var. *)
length all_vars = 1 else (* Second case: concl_arg is of the form f ?x1 ... ?xn. *) let val args = Util.dest_args concl_arg in
forall is_Var args andalso subset (op aconv) (all_vars, args) end end elsefalse end
(* Add the given theorem as a property update rule. Choose which table toaddtheruleto.
*) fun add_property_update th thy = let val (prems, concl) = UtilLogic.strip_horn' th val _ = assert (is_property concl) "add_property_update: concl must be a property constant." val _ = assert (forall (is_property_prem thy) prems) "add_property_update: prem must be a property premise." val concl_arg = get_property_arg concl val all_vars = map Var (Term.add_vars (Thm.prop_of th) []) in if is_Var concl_arg then (* First case. Each premise must also be about ?x. Add to UpdateDatatableunderthenamesofthepredicates.
*) let val _ = assert (length all_vars = 1) "add_property_update: extraneous Vars in th." val names = get_property_names prems val _ = writeln ("Add property rule for " ^
(Util.string_of_list I names)) in
thy |> UpdateData.map (
fold (Symtab.update_list Thm.eq_thm_prop) (map (rpair th) names)) end else (* Second case. concl_arg in the form f ?x1 ... ?xn. Add to UpdateFunDatatableunderf.
*) let val (f, args) = Term.strip_comb concl_arg val c = case f of Const (c, _) => c
| _ => raise Fail "add_property_update: f is not constant." val _ = assert (forall is_Var args) "add_property_update: all args of concl must be Vars." val _ = assert (subset (op aconv) (all_vars, args)) "add_property_update: extraneous Vars in th." val _ = writeln ("Add property rule for function " ^ c) in
thy |> UpdateFunData.map (Symtab.update_list Thm.eq_thm_prop (c, th)) end end
(* Find update rules of the form P1 x ==> ... ==> Pn x ==> P x, where cisoneofP1,...Pn.
*) fun lookup_property_update thy c =
Symtab.lookup_list (UpdateData.get thy) c
(* Find update rules of the form A1 ==> ... ==> An ==> P(f(x1,...,xn)),whereeachA_iisapropertyononeofx_j.Herec isthenameoff.
*) fun lookup_property_update_fun thy c =
Symtab.lookup_list (UpdateFunData.get thy) c
(* Instantiate th by matching t with the argument of the conclusion of th.ReturnNONEifinstantiationisunsuccessful(becausetypedoes notmatch).
*) fun instantiate_property_update ctxt t th = let val (_, concl) = UtilLogic.strip_horn' th val concl_arg = get_property_arg concl val thy = Proof_Context.theory_of ctxt in if Sign.typ_instance thy (fastype_of t, fastype_of concl_arg) then let val err_str = "instantiate_property_update: cannot match with t." val inst = Pattern.first_order_match thy (concl_arg, t) fo_init handle Pattern.MATCH => raise Fail err_str in
SOME (Util.subst_thm ctxt inst th) end else NONE end
end(* structure Property. *)
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.9 Sekunden
(vorverarbeitet am 2026-06-10)
¤
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 und die Messung sind noch experimentell.