[isabelle-dev] Normalise theorem wrt an environment
Kevin Kappelmann
kevin.kappelmann at tum.de
Tue Sep 28 12:19:25 CEST 2021
Dear list,
I see that there are functions to normalise a type (Envir.norm_type) and
a term (Envir.norm_term) wrt an environment. Is there also a function to
normalise a theorem wrt an environment? If not, I think doing such a
normalisation is very common and should be added to Isabelle/Pure.
Attached, find my proposal for such a function (norm_thm) and some
examples why a simpler alternative (that is akin to the function
described in the Isabelle/ML cookbook [1, page 57]) does not work. The
file compiles using the current Isabelle development version.
Happy to hear your feedback. Best wishes,
Kevin
[1] https://nms.kcl.ac.uk/christian.urban/Cookbook/
-------------- next part --------------
theory Scratch
imports
Pure
begin
ML \<open>
(*collect and normalise TVars of a term*)
fun collect_norm_types ctxt tyenv t =
let
val norm_type = Envir.norm_type tyenv
fun prep_type_entry x = (x, Thm.ctyp_of ctxt (norm_type (TVar x)))
in
fold_types (fold_atyps (fn (TVar v) => TVars.add (prep_type_entry v) | _ => I)) t
|> TVars.build
end
(*collect and normalise Vars of a term*)
fun collect_norm_terms ctxt (env as Envir.Envir {tyenv,...}) t =
let
val norm_type = Envir.norm_type tyenv
val norm_term = Envir.norm_term env
fun prep_term_entry (x as (n, T)) = ((n, norm_type T), Thm.cterm_of ctxt (norm_term (Var x)))
in
fold_aterms (fn (Var v) => Vars.add (prep_term_entry v) | _ => I) t
|> Vars.build
end
(*normalise types of a theorem*)
fun norm_thm_types ctxt tyenv thm =
let
val prop = Thm.prop_of thm
val type_inst = collect_norm_types ctxt tyenv prop
val inst = (type_inst, Vars.empty)
in Thm.instantiate inst thm end
(*normalise a theorem*)
fun norm_thm ctxt (env as Envir.Envir {tyenv,...}) thm =
let
val prop = Thm.prop_of thm
val type_inst = collect_norm_types ctxt tyenv prop
val term_inst = collect_norm_terms ctxt env prop
val inst = (type_inst, term_inst)
in Thm.instantiate inst thm end
(*wrong normalisation of a theorem; this does not work, for example with environments in triangular
form or environments where type variables of a term are substituted*)
fun norm_thm_wrong ctxt (Envir.Envir {tyenv, tenv,...}) thm =
let
fun add_type_entry (n, (S, T)) = TVars.add ((n, S), Thm.ctyp_of ctxt T)
fun add_term_entry (n, (T, t)) = Vars.add ((n, T), Thm.cterm_of ctxt t)
val type_inst = Vartab.fold add_type_entry tyenv |> TVars.build
val term_inst = Vartab.fold add_term_entry tenv |> Vars.build
val inst = (type_inst, term_inst)
in Thm.instantiate inst thm end
\<close>
ML \<open>
(*just some auxiliary definitions, you can ignore this*)
(* pretty-printing *)
local
val pretty_term = Syntax.pretty_term
val pretty_type = Syntax.pretty_typ
fun pretty_env_aux show_entry =
Vartab.dest
#> map show_entry
#> Pretty.list "[" "]"
fun pretty_env_entry show (s, t) = Pretty.enum " := " "" "" (map show [s, t])
in
fun pretty_tyenv ctxt =
let
val show_entry = pretty_env_entry (pretty_type ctxt)
fun get_typs (v, (s, T)) = (TVar (v, s), T)
in pretty_env_aux (show_entry o get_typs) end
fun pretty_tenv ctxt =
let
val show_entry = pretty_env_entry (pretty_term ctxt)
fun get_trms (v, (T, t)) = (Var (v, T), t)
in pretty_env_aux (show_entry o get_trms) end
end
fun pretty_env ctxt env = Pretty.enum "," "(" ")" [
pretty_tyenv ctxt (Envir.type_env env),
pretty_tenv ctxt (Envir.term_env env)
]
(* schematic variables in antiquotation *)
val _ = Theory.setup (
ML_Antiquotation.inline_embedded \<^binding>\<open>term_pat\<close>
(Args.term_pattern >> (ML_Syntax.atomic o ML_Syntax.print_term)))
\<close>
declare [[show_types]]
ML \<open>
val s = @{term_pat "\<lambda> (x :: ?'Y). (?z :: ?'Y \<Rightarrow> ?'R) x"}
val t = @{term_pat "\<lambda> (x :: ?'X). (c :: ?'X \<Rightarrow> ?'R) x"}
(*another example that would fail for a diffferent reason*)
(*val s = @{term_pat "f (\<lambda> (x :: ?'Y). ?z :: ?'X)"}*)
(*val t = @{term_pat "f (\<lambda> (x :: ?'X). (c :: ?'V))"}*)
val ctxt = @{context}
val env = Pattern.unify (Context.Proof ctxt) (s, t) (Envir.empty 0)
|> tap (pretty_env ctxt #> Pretty.writeln)
val thm = norm_thm @{context} env (Thm.reflexive (Thm.cterm_of ctxt s))
(*this call fails*)
(*val thm' = norm_thm_wrong @{context} env (Thm.reflexive (Thm.cterm_of ctxt s))*)
\<close>
end
More information about the isabelle-dev
mailing list