File ‹ETTS_Algorithm.ML›
signature ETTS_ALGORITHM =
sig
val mk_local_typedef_ex : (string * sort) * term -> term
val dest_local_typedef_ex : term -> typ * term
datatype etts_output_type = default | verbose | active
val etts_output_type_of_string : string -> etts_output_type
val string_of_etts_output_type : etts_output_type -> string
val is_verbose : etts_output_type -> bool
val is_active : etts_output_type -> bool
val is_default : etts_output_type -> bool
val etts_algorithm :
Proof.context ->
etts_output_type ->
int list ->
(indexname * term) list ->
(term * term) list ->
(Facts.ref * Token.src list) option ->
(Facts.ref * Token.src list) list ->
(term list * (Proof.context -> tactic)) option ->
Token.src list ->
thm ->
(thm * int list) * Proof.context
val etts_fact :
Proof.context ->
etts_output_type ->
int list ->
(indexname * term) list ->
(term * term) list ->
(Facts.ref * Token.src list) option ->
(Facts.ref * Token.src list) list ->
(term list * (Proof.context -> tactic)) option ->
Token.src list ->
thm list ->
(thm list * int list) * Proof.context
end;
structure ETTS_Algorithm : ETTS_ALGORITHM =
struct
open UD_With;
open ETTS_Utilities;
open ETTS_RI;
open ETTS_Substitution;
fun mk_local_typedef_ex (rcd_spec, rissett) =
let
val T = TFree rcd_spec
val risset_ftv = rissett
|> type_of
|> (fn T => Term.add_tfreesT T [])
|> the_single
|> TFree
in
HOLogic.mk_exists
(
"rep",
T --> risset_ftv,
HOLogic.mk_exists
(
"abs",
risset_ftv --> T,
HOLogic.mk_type_definition_pred T risset_ftv $ Bound 1 $ Bound 0 $ rissett
)
)
end;
fun dest_local_typedef_ex t =
let
val (_, T', t') = HOLogic.dest_exists t
handle TERM ("dest_exists", _) =>
raise TERM ("dest_local_typedef_ex", single t)
val (_, _, t'') = HOLogic.dest_exists t'
handle TERM ("dest_exists", _) =>
raise TERM ("dest_local_typedef_ex", single t)
val (T''', _) = dest_funT T'
val t''' = t'' |> HOLogic.dest_type_definition |> #3
in (T''', t''') end;
datatype etts_output_type = default | verbose | active;
fun etts_output_type_of_string "" = default
| etts_output_type_of_string "!" = verbose
| etts_output_type_of_string "?" = active
| etts_output_type_of_string _ =
error "etts_output_type_of_string: invalid input";
fun string_of_etts_output_type default = "default"
| string_of_etts_output_type verbose = "verbose"
| string_of_etts_output_type active = "active";
fun is_verbose verbose = true
| is_verbose _ = false;
fun is_active active = true
| is_active _ = false;
fun is_default default = true
| is_default _ = false;
fun verbose_writer_prem etts_output_type writer c =
if is_verbose etts_output_type
then ETTS_Writer.write_action c writer
else writer
fun verbose_writer_concl_thms etts_output_type ctxt thms =
if is_verbose etts_output_type
then map (Thm.string_of_thm ctxt #> writeln) thms
else single ();
fun verbose_writer_concl_types etts_output_type ctxt Ts =
if is_verbose etts_output_type
then map (Syntax.string_of_typ ctxt #> writeln) Ts
else single ();
fun cancel_type_definition_repeat n thm =
let
fun apply_cancel_type_definition 0 thm = thm
| apply_cancel_type_definition n thm = thm
|> Local_Typedef.cancel_type_definition
|> rotate_prems 1
|> apply_cancel_type_definition (n - 1)
in
thm
|> apply_cancel_type_definition n
|> rotate_prems (~n)
end;
local
val risset_tthms =
[@{thm type_definition_Domainp}, @{thm type_definition_Domainp'}];
val sc_tthms =
[
@{thm typedef_bi_unique},
@{thm typedef_right_total},
@{thm typedef_left_unique},
@{thm typedef_right_unique}
];
fun get_riT rit = rit
|> type_of
|> (fn T => (T |> binder_types |> the_single, body_type T));
fun mk_cr_rhst rept =
let
val (isoT, domT) = get_riT rept
val rhst =
Abs
(
"r",
domT,
Abs
(
"a",
isoT,
Const (\<^const_name>‹HOL.eq›, domT --> domT --> HOLogic.boolT) $
Bound 1 $
(rept $ Bound 0)
)
)
in rhst end;
fun etts_rlt_ctxt_intialize rispec = length rispec;
fun etts_rlt_ctxt_mk_fresh_ris ctxt rispec = rispec
|> map #2
|> map (fn t => Term.add_frees t [])
|> flat
|> dup
||> map #1
||> Variable.fix_new_vars ctxt
|>> map Free
|-> fold_rev Variable.declare_term;
fun etts_rlt_ctxt_mk_fresh_risstv ctxt etts_output_type writer nds rispec =
let
val writer' = verbose_writer_prem
etts_output_type writer "types associated with the RIs..."
val (rispec', ctxt') = ctxt
|> (\<^sort>‹HOL.type› |> replicate nds |> Variable.invent_types)
|>> curry (swap #> op~~) rispec
val _ = verbose_writer_concl_types
etts_output_type ctxt' (map (#1 #> TFree) rispec')
in ((writer', rispec'), ctxt') end;
fun etts_rlt_ctxt_mk_ltd_assms ctxt etts_output_type writer rispec =
let
val writer' = verbose_writer_prem
etts_output_type writer "assumptions for the local typedef..."
val (ltd_assms, ctxt') = rispec
|>
(
apsnd #2
#> mk_local_typedef_ex
#> HOLogic.mk_Trueprop
#> Thm.cterm_of ctxt
|> map
)
|> (fn ltdts => Assumption.add_assumes ltdts ctxt)
val _ = verbose_writer_concl_thms etts_output_type ctxt' ltd_assms
in ((writer', ltd_assms), ctxt') end;
local
fun mk_ex_crt rept =
let
val (isoT, domainT) = get_riT rept
val crT = domainT --> isoT --> HOLogic.boolT
val rhst = mk_cr_rhst rept
val t = HOLogic.mk_exists
(
"cr",
crT,
Const (\<^const_name>‹HOL.eq›, crT --> crT --> HOLogic.boolT) $
Bound 0 $
rhst
)
in t end;
in
fun etts_rlt_ctxt_mk_crs ctxt etts_output_type writer nds ltd_assms =
let
val writer' = verbose_writer_prem etts_output_type writer "crs..."
val ((ra_var_specs, ra_thms), ctxt') = ctxt
|> Obtain.result
(K (REPEAT (eresolve_tac ctxt (single @{thm exE}) 1))) ltd_assms
val repts = ra_var_specs
|> map (#2 #> Thm.term_of)
|> chop nds
|> #1
val ex_cr_thms =
let
val hol_ex_cr_tac = resolve_tac ctxt' (single @{thm ex_eq}) 1
fun hol_cr_prover thm =
Goal.prove ctxt' [] [] thm (K (hol_ex_cr_tac))
in map (mk_ex_crt #> HOLogic.mk_Trueprop #> hol_cr_prover) repts end
val ((crts, hol_cr_thms), ctxt'') = ctxt'
|> Obtain.result
(K (REPEAT (eresolve_tac ctxt' (single @{thm exE}) 1))) ex_cr_thms
|>> (fn x => x |>> map #2 |>> map Thm.term_of)
val pure_cr_thms =
let
val pure_crts = map Logic.mk_equals (crts ~~ (map mk_cr_rhst repts))
fun pure_cr_tac thm _ =
Object_Logic.full_atomize_tac ctxt'' 1
THEN resolve_tac ctxt'' (single thm) 1
fun pure_cr_prover (goal, tac_thm) =
Goal.prove ctxt'' [] [] goal (pure_cr_tac tac_thm)
in map pure_cr_prover (pure_crts ~~ hol_cr_thms) end
val _ = verbose_writer_concl_thms etts_output_type ctxt'' pure_cr_thms
in ((writer', ra_thms, crts, pure_cr_thms), ctxt'') end;
end;
fun etts_rlt_ctxt_mk_ri_tr ctxt etts_output_type writer ra_thms pure_cr_thms =
let
val writer' =
verbose_writer_prem etts_output_type writer "main transfer rules..."
val (risset_transfer_thms, sc_transfer_thms) =
let
val OFthms = map list_of_pair (ra_thms ~~ pure_cr_thms)
val apply_OFthms =
map (fn thm => map ((curry op OF) thm) OFthms) #> flat
in (risset_tthms, sc_tthms) |>> apply_OFthms ||> apply_OFthms end
val _ = verbose_writer_concl_thms
etts_output_type ctxt (risset_transfer_thms @ sc_transfer_thms)
in (writer', risset_transfer_thms, sc_transfer_thms) end;
local
fun get_sc_ex_rissets risset_transfer_thms sc_transfer_thms =
let val nds = (length risset_transfer_thms) div (length risset_tthms)
in
(risset_transfer_thms, sc_transfer_thms)
|>> take nds
||> chop nds
||> (nds |> chop #> #1 |> apsnd)
||> op ~~
|> op ~~
end;
in
fun etts_rlt_ctxt_mk_sbt_tr
ctxt
etts_output_type
writer
risset_transfer_thms
sc_transfer_thms
rispec
sbtspec =
let
val writer' = verbose_writer_prem
etts_output_type writer "transfer rules for the sbts..."
val ((sbtspec_specs, pp_thms), ctxt') =
let
val sc_ex_rissets = get_sc_ex_rissets risset_transfer_thms sc_transfer_thms
val scthms_of_ftv =
let
val scthms_ftv =
(
map (#1 #> #2 #> #2 #> type_of #> dest_rissetT) rispec ~~
map reroute_sp_triple sc_ex_rissets
)
in AList.lookup op= scthms_ftv end
fun thm_prem_ftvs thm = thm
|> Thm.prems_of
|> map (fn t => Term.add_tfrees t [])
|> flat
|> distinct op=
fun get_sc_ftv_specs (thm_ftv_specs, rvt_ftv_specs) = rvt_ftv_specs
|> subtract op= (rvt_ftv_specs |> subtract op= thm_ftv_specs)
fun obtain_prs ctxt ex_pr_thms = case ex_pr_thms of
[] => (([], []), ctxt)
| _ => Obtain.result
(K (REPEAT (eresolve_tac ctxt (single @{thm exE}) 1)))
ex_pr_thms
ctxt
in
sbtspec
|>
(
(Thm.cterm_of ctxt #> (sbt_data_of ctxt #> the) |> apdupl)
#> swap
|> apsnd
#> reroute_sp_ps
|> map
)
|> map (reroute_ps_sp #> apsnd swap)
|>
(
(fn (thm, t) => (thm, (thm, t)))
#>
(
(apfst thm_prem_ftvs)
#> (type_of #> (fn t => Term.add_tfreesT t []) |> apsnd)
#> get_sc_ftv_specs
#>
(
Option.compose (list_of_triple, scthms_of_ftv)
#>
(
fn xs_opt => case xs_opt of
SOME xs_opt => xs_opt
| NONE => []
)
|> map
#> flat
)
|> apsnd
)
#> op OF
|> apsnd
|> map
)
|> split_list
||> obtain_prs ctxt
|> reroute_sp_ps
|>> reroute_sp_ps
|>> apfst op~~
|>> (#2 |> apsnd |> map |> apfst)
|>> apsnd Transfer.mk_transfer_rels
end
val _ = verbose_writer_concl_thms etts_output_type ctxt' pp_thms
in ((writer', pp_thms, sbtspec_specs), ctxt') end;
end;
fun etts_rlt_ctxt_mk_transfer risset_transfer_thms sc_transfer_thms pp_thms =
risset_transfer_thms @ sc_transfer_thms @ pp_thms;
fun etts_rlt_ctxt_mk_rispec rispec =
map (#1 #> swap #> apfst #1) rispec;
fun etts_rlt_ctxt_mk_sbtspec sbtspec_specs =
let
val sbtspec_var_specs = sbtspec_specs
|> filter (apfst is_Var #> #1)
|> map (apfst dest_Var)
val sbtspec_const_specs = sbtspec_specs
|> filter (apfst is_Const #> #1)
|> map (apfst dest_Const)
in (sbtspec_var_specs, sbtspec_const_specs) end;
in
fun init_rlt_ctxt ctxt etts_output_type writer rispec sbtspec =
let
val nds = etts_rlt_ctxt_intialize rispec
val ctxt' = etts_rlt_ctxt_mk_fresh_ris ctxt rispec
val ((writer', rispec'), ctxt'') = etts_rlt_ctxt_mk_fresh_risstv
ctxt' etts_output_type writer nds rispec
val ((writer'', ltd_assms), ctxt''') = etts_rlt_ctxt_mk_ltd_assms
ctxt'' etts_output_type writer' rispec'
val ((writer''', ra_thms, crts, pure_cr_thms), ctxt'''') =
etts_rlt_ctxt_mk_crs ctxt''' etts_output_type writer'' nds ltd_assms
val rispec'' = rispec' ~~ crts
val (writer'''', risset_transfer_thms, sc_transfer_thms) = etts_rlt_ctxt_mk_ri_tr
ctxt'''' etts_output_type writer''' ra_thms pure_cr_thms
val ((writer''''', pp_thms, sbtspec_specs), ctxt''''') =
etts_rlt_ctxt_mk_sbt_tr
ctxt''''
etts_output_type
writer''''
risset_transfer_thms
sc_transfer_thms
rispec''
sbtspec
val transfer_thms = etts_rlt_ctxt_mk_transfer
risset_transfer_thms sc_transfer_thms pp_thms
val rispec''' = etts_rlt_ctxt_mk_rispec rispec''
val (sbtspec_var_specs, sbtspec_const_specs) =
etts_rlt_ctxt_mk_sbtspec sbtspec_specs
in
(
ctxt,
ctxt''''',
writer''''',
rispec''',
sbtspec_var_specs,
sbtspec_const_specs,
transfer_thms
)
end;
end;
local
fun etts_algorithm_fresh_stv
ctxt
writer
rispec
sbtspec_var_specs
sbtspec_const_specs
thm =
let
val stvs = thm |> Thm.full_prop_of |> (fn t => Term.add_tvars t [])
val rispec' = rispec
|> filter (fn (v, _) => member op= (map fst stvs) v)
|> map (apfst (apdupr ((AList.lookup op= stvs #> the))))
val thm_stvs =
let val cs = rispec' |> map fst |> map fst |> map fst
in stvs |> filter (fn (v, _) => fst v |> member op= cs |> not) end
val cs =
let
fun folder c (cs, nctxt) =
let val out = Name.variant c nctxt
in (fst out::cs, snd out) end
val cs = rispec' |> map snd |> map fst
val nctxt = fold Name.declare cs (Variable.names_of ctxt)
in fold folder (thm_stvs |> map fst |> map fst) ([], nctxt) |> fst end
val rhsTs = cs ~~ map (reroute_ps_sp #> snd) thm_stvs
|> map reroute_sp_ps
|> map TVar
val thm' =
let val rhs_cT = map (Thm.ctyp_of ctxt) rhsTs
in
Drule.instantiate_normalize
(TVars.make (thm_stvs ~~ rhs_cT), Vars.empty) thm
end
fun thm_stvs_map (v, T) =
case AList.lookup op= (thm_stvs ~~ rhsTs) (v, T) of
SOME T => T
| NONE => TVar (v, T)
val sbtspec_var_specs = sbtspec_var_specs
|> map (fn ((v, T), x) => ((v, map_type_tvar thm_stvs_map T), x))
val sbtspec_const_specs = sbtspec_const_specs
|> map (fn ((c, T), x) => ((c, map_type_tvar thm_stvs_map T), x))
val thm_stvs = thm' |> Thm.full_prop_of |> (fn t => Term.add_tvars t [])
val thm_stvs_map = map_type_tvar
(fn (v, _) => TVar (v, (AList.lookup op= thm_stvs #> the) v))
val sbtspec_const_specs = sbtspec_const_specs
|> map (fn ((c, T), x) => ((c, thm_stvs_map T), x))
in ((writer, rispec', sbtspec_var_specs, sbtspec_const_specs), thm') end;
fun etts_algorithm_unfold_ud_with
ctxt''
etts_output_type
writer
sbtspec_var_specs
sbtspec_const_specs
thm =
let
val writer' = verbose_writer_prem etts_output_type writer "unfold ud_with..."
val ud_with_thms = ctxt''
|> UDWithData.get
|> map (Local_Defs.meta_rewrite_rule ctxt'')
val thm' = Local_Defs.unfold ctxt'' ud_with_thms thm
val stvs = thm' |> Thm.full_prop_of |> (fn t => Term.add_vars t [])
val consts = thm' |> Thm.full_prop_of |> (fn t => Term.add_consts t [])
val sbtspec_var_specs = sbtspec_var_specs
|> filter (fn ((v, T), _) => member op= stvs (v, T))
val sbtspec_const_specs = sbtspec_const_specs
|> filter (fn (const, _) => member op= consts const)
val sbtspec_specs =
(
(map (apfst Var) sbtspec_var_specs) @
(map (apfst Const) sbtspec_const_specs)
)
val _ = verbose_writer_concl_thms etts_output_type ctxt'' (single thm')
in ((writer', sbtspec_specs), thm') end;
fun etts_algorithm_unoverload_types
ctxt' etts_output_type writer rispec sbtspec_specs thm =
let
val writer' =
verbose_writer_prem etts_output_type writer "unoverload types..."
val thm' = Unoverload_Type.unoverload_type
(Context.Proof ctxt') (rispec |> map (#1 #> #1) |> rev) thm
val t = Thm.full_prop_of thm
val n = Logic.count_prems t
val out_t = Thm.full_prop_of thm'
val out_n = Logic.count_prems out_t
val out_prem_ts = out_t |> Logic.strip_imp_prems |> drop (out_n - n)
val out_t' = Logic.list_implies (out_prem_ts, Logic.strip_imp_concl out_t)
val (mapT, mapt) = (Thm.cterm_of ctxt' out_t', Thm.cprop_of thm)
|> Thm.match
|>> TVars.map (K Thm.typ_of)
||> Vars.map (K Thm.term_of)
|>> TVars.dest
||> Vars.dest
|>> map (apfst TVar)
||> map (apfst Var)
|>> map swap
||> map swap
val rispec' = rispec
|> map (apfst TVar)
|> map (apfst (map_atyps (AList.lookup op= mapT #> the)))
|> map (apfst dest_TVar)
val sbtspec_specs' = sbtspec_specs
|> map (apfst (map_aterms (AList.lookup op= mapt #> the)))
|> map (apfst dest_Var)
|> map (apfst (apsnd (map_atyps (AList.lookup op= mapT #> the))))
val _ = verbose_writer_concl_thms etts_output_type ctxt' (single thm')
in ((writer', rispec', sbtspec_specs'), thm') end;
fun etts_algorithm_subst_type ctxt' etts_output_type writer rispec thm =
let
val writer' = verbose_writer_prem
etts_output_type writer "substitution of type variables..."
val thm' = Drule.instantiate_normalize
(
rispec
|> map (apsnd TFree)
|> map (apsnd (Thm.ctyp_of ctxt'))
|> TVars.make,
Vars.empty
)
thm
val _ = verbose_writer_concl_thms etts_output_type ctxt' (single thm')
in (writer', thm') end;
fun etts_algorithm_subst_var ctxt' etts_output_type writer sbtspec_specs thm =
let
val writer' = verbose_writer_prem
etts_output_type writer "substitution of variables..."
val thm' = sbtspec_specs
|> (Var #> (ctxt' |> Thm.cterm_of) |> apfst |> map)
|> map Thm.first_order_match
|> fold Drule.instantiate_normalize
|> curry op|> thm
val _ = verbose_writer_concl_thms etts_output_type ctxt' (single thm')
in (writer', thm') end;
fun etts_algorithm_untransfer ctxt' etts_output_type writer transfer_thms thm =
let
val writer' = verbose_writer_prem etts_output_type writer "untransfer..."
val (thm', context) = Thm.apply_attribute
(Transfer.untransferred_attribute transfer_thms)
thm
(Context.Proof ctxt')
val _ = verbose_writer_concl_thms etts_output_type ctxt' (single thm')
in (context, writer', thm') end;
fun etts_algorithm_export context ctxt etts_output_type writer thm =
let
val writer' = verbose_writer_prem etts_output_type writer "export..."
val thy' = Context.theory_of context
val ctxt' = Context.proof_of context
val ctxt'' = Proof_Context.transfer thy' ctxt
val thm' = singleton (Proof_Context.export ctxt' ctxt'') thm
val _ = verbose_writer_concl_thms etts_output_type ctxt'' (single thm')
in ((writer', thm'), ctxt'') end;
fun etts_algorithm_ctd ctxt etts_output_type writer rispec thm =
let
val writer' =
verbose_writer_prem etts_output_type writer "cancel type definition..."
val thm' = (rispec |> length |> cancel_type_definition_repeat) thm
val _ = verbose_writer_concl_thms etts_output_type ctxt (single thm')
in ((writer', thm'), ctxt) end;
in
fun etts_kera
ctxt
ctxt'
etts_output_type
writer
rispec
sbtspec_var_specs
sbtspec_const_specs
transfer_thms
thm =
let
val ((writer', rispec, sbtspec_var_specs, sbtspec_const_specs), thm') =
etts_algorithm_fresh_stv
ctxt'
writer
rispec
sbtspec_var_specs
sbtspec_const_specs
thm
val ((writer'', sbtspec_specs), thm'') =
etts_algorithm_unfold_ud_with
ctxt'
etts_output_type
writer'
sbtspec_var_specs
sbtspec_const_specs
thm'
val ((writer''', rispec, sbtspec_specs'), thm''') =
etts_algorithm_unoverload_types
ctxt' etts_output_type writer'' rispec sbtspec_specs thm''
val (writer'''', thm'''') = etts_algorithm_subst_type
ctxt' etts_output_type writer''' rispec thm'''
val (writer''''', thm''''') = etts_algorithm_subst_var
ctxt' etts_output_type writer'''' sbtspec_specs' thm''''
val (context, writer'''''', thm'''''') = etts_algorithm_untransfer
ctxt' etts_output_type writer''''' transfer_thms thm'''''
val ((writer''''''', thm'''''''), ctxt'') = etts_algorithm_export
context ctxt etts_output_type writer'''''' thm''''''
val ((writer'''''''', thm''''''''), ctxt''') = etts_algorithm_ctd
ctxt'' etts_output_type writer''''''' rispec thm'''''''
in ((thm'''''''', writer''''''''), ctxt''') end;
end;
local
fun etts_algorithm_simplification ctxt etts_output_type writer sbrr_opt thm =
let
val writer = verbose_writer_prem etts_output_type writer "simplification..."
val out_thm = More_Simplifier.rewrite_simp_opt' ctxt sbrr_opt thm
val _ = verbose_writer_concl_thms etts_output_type ctxt (single out_thm)
in (writer, out_thm) end;
local
fun term_equiv_st (t, u) =
let
fun term_equiv_st ((Const (a, T)), (Const (b, U))) =
a = b andalso Type.could_match (T, U)
| term_equiv_st ((Free (_, T)), (Free (_, U))) = Type.could_match (T, U)
| term_equiv_st ((Var (_, T)), (Var (_, U))) = Type.could_match (T, U)
| term_equiv_st ((Free (_, T)), (Var (_, U))) = Type.could_match (T, U)
| term_equiv_st ((Var (_, T)), (Free (_, U))) = Type.could_match (T, U)
| term_equiv_st ((Const (_, T)), (Free (_, U))) = Type.could_match (T, U)
| term_equiv_st ((Free (_, T)), (Const (_, U))) = Type.could_match (T, U)
| term_equiv_st ((Const (_, T)), (Var (_, U))) = Type.could_match (T, U)
| term_equiv_st ((Var (_, T)), (Const (_, U))) = Type.could_match (T, U)
| term_equiv_st ((Bound n), (Bound m)) = (n = m)
| term_equiv_st ((Abs (_, T, t)), (Abs (_, U, u))) =
Type.could_match (T, U) andalso term_equiv_st (t, u)
| term_equiv_st ((tl $ tr), (ul $ ur)) =
term_equiv_st (tl, ul) andalso term_equiv_st (tr, ur)
| term_equiv_st ((Var (_, T)), (ul $ ur)) =
Type.could_match (T, type_of (ul $ ur))
| term_equiv_st ((Var (_, T)), (Abs (c, U, u))) =
Type.could_match (T, type_of (Abs (c, U, u)))
| term_equiv_st (_, _) = false;
in
if
(Term.add_frees t [] |> null |> not)
andalso (Term.add_frees u [] |> null |> not)
then term_equiv_st (t, u)
else false
end;
in
fun etts_algorithm_subst_prems ctxt etts_output_type writer subst_thms thm =
let
val writer' = verbose_writer_prem
etts_output_type writer "substitute known premises..."
val thm' =
let
val subst_thms = Attrib.eval_thms ctxt subst_thms
val subst_thmst = map Thm.full_prop_of subst_thms
fun option_thm thm_opt = case thm_opt of
SOME thm => thm
| _ => @{thm _}
fun mk_OFthms ts = ts
|>
(
(subst_thmst ~~ subst_thms)
|> AList.lookup term_equiv_st
|> map
)
|> map option_thm
fun subst_premises_repeat thm =
let
val premsts = thm |> Thm.full_prop_of |> Logic.strip_imp_prems
val out_thm = thm OF (mk_OFthms premsts)
in
if Thm.nprems_of thm = Thm.nprems_of out_thm
then out_thm
else subst_premises_repeat out_thm
end
in subst_premises_repeat thm end
val _ = verbose_writer_concl_thms etts_output_type ctxt (single thm')
in (writer', thm') end;
end;
fun etts_algorithm_premred ctxt etts_output_type writer mpespc_opt thm =
let
val writer' =
verbose_writer_prem etts_output_type writer "elimination of premises..."
val thm' = case mpespc_opt of
SOME m_spec =>
let
val (out_thm, ctxt') = Thm.unvarify_local_thm ctxt thm
val out_thm = out_thm
|> ETTS_Tactics.prem_red ctxt' m_spec
|> singleton (Proof_Context.export ctxt' ctxt)
in out_thm end
| NONE => thm
val _ = verbose_writer_concl_thms etts_output_type ctxt (single thm')
in (writer', thm') end;
fun etts_algorithm_app_attrb ctxt etts_output_type writer attrbs thm =
let
val writer' = verbose_writer_prem etts_output_type writer
"application of the attributes for the set-based theorem..."
val (thm', ctxt') =
let
val attrbs =
map (Attrib.check_src ctxt #> Attrib.attribute ctxt) attrbs
in Thm.proof_attributes attrbs thm ctxt end
val _ = verbose_writer_concl_thms etts_output_type ctxt' (single thm')
in (writer', thm') end;
in
fun etts_algorithm_pp
ctxt etts_output_type writer sbrr_opt subst_thms mpespc_opt attrbs thm =
let
val (writer', thm') = etts_algorithm_simplification
ctxt etts_output_type writer sbrr_opt thm
val (writer'', thm'') = etts_algorithm_subst_prems
ctxt etts_output_type writer' subst_thms thm'
val (writer''', thm''') = etts_algorithm_premred
ctxt etts_output_type writer'' mpespc_opt thm''
val (writer'''', thm'''') = etts_algorithm_app_attrb
ctxt etts_output_type writer''' attrbs thm'''
in ((thm'''', writer''''), ctxt) end;
end;
local
fun mk_msg_etts_algorithm msg = "tts_algorithm: " ^ msg;
fun etts_algorithm_input rispec thm =
let
val msg_etts_context = mk_msg_etts_algorithm
"ERA can only be invoked from an appropriately parameterized tts context"
val msg_ftvs = mk_msg_etts_algorithm
"fixed type variables must not occur in the type-based theorems"
val msg_fvs = mk_msg_etts_algorithm
"fixed variables must not occur in the type-based theorems"
val msg_not_risstv_subset = mk_msg_etts_algorithm
"risstv must be a subset of the schematic type " ^
"variables that occur in the type-based theorems"
val _ = not (null rispec) orelse error msg_etts_context
val t = Thm.full_prop_of thm
val _ = t
|> (fn t => Term.add_tfrees t [])
|> null
orelse error msg_ftvs
val _ = t
|> (fn t => Term.add_frees t [])
|> null
orelse error msg_fvs
val stvs = t
|> (fn t => Term.add_tvars t [])
|> map #1
|> distinct op=
val risstv = map #1 rispec
val _ = subset op= (risstv, stvs) orelse error msg_not_risstv_subset
in () end;
in
fun etts_algorithm
ctxt
etts_output_type
writer
rispec
sbtspec
sbrr_opt
subst_thms
mpespc_opt
attrbs
thm =
let
val _ = etts_algorithm_input rispec thm
val
(
ctxt,
ctxt',
writer,
rispec,
sbtspec_var_specs,
sbtspec_const_specs,
transfer_thms
) = init_rlt_ctxt ctxt etts_output_type writer rispec sbtspec
val writer' = ETTS_Writer.increment_index 2 writer
val ((thm', writer'), ctxt'') = etts_kera
ctxt
ctxt'
etts_output_type
writer'
rispec
sbtspec_var_specs
sbtspec_const_specs
transfer_thms
thm
val writer'' = ETTS_Writer.increment_index 2 writer'
val ((thm'', writer'''), ctxt''') = etts_algorithm_pp
ctxt'' etts_output_type writer'' sbrr_opt subst_thms mpespc_opt attrbs thm'
in ((thm'', writer'''), ctxt''') end;
end;
fun etts_fact
ctxt
etts_output_type
writer
rispec
sbtspec
sbrr_opt
subst_thms
mpespc_opt
attrbs
thms =
let
fun folder thm ((thms, writer), ctxt) =
etts_algorithm
ctxt
etts_output_type
writer
rispec
sbtspec
sbrr_opt
subst_thms
mpespc_opt
attrbs
thm
|>> apsnd (ETTS_Writer.increment_index 1)
|>> apfst (curry (swap #> op::) thms)
in fold_rev folder thms (([], writer), ctxt) end;
end;