1 (* Title: BaseDefinitions/substitution.sml
3 (c) due to copyright terms
5 The variety of substitutions is required by various presentations to the front end;
6 this shall be simplified during the shift to Isabelle/PIDE.
8 Two different formats shall remain, probably:
9 # type input: is what the user sees (pairs of terms)
10 # type as_eqs: a format useful for handling results of equation solving
12 signature SUBSTITUTION =
14 type T = LibraryC.subst;
15 val to_string: T -> string
17 type as_eqs = term list (* for Tactic.Substitute: [@{term "bdv = x"}, ...] *)
18 type program = term (* in programs: @{term "[(''bdv_1'', x::real), ..]} *)
19 type input = TermC.as_string list (* by student: ["(''bdv'', x)", ..] *)
20 val input_empty: input
22 type as_string_eqs (* for Tactic.Substitute ["bdv_1 = x", ...] *)
23 val string_eqs_to_string: as_string_eqs -> string
25 val T_to_string_eqs: T -> as_string_eqs
26 val T_to_input: T -> input
27 val T_from_string_eqs: theory -> as_string_eqs -> T
28 val T_from_input: Proof.context -> input -> T
30 val input_to_terms: Proof.context -> input -> as_eqs
31 val eqs_to_input: as_eqs -> as_string_eqs
32 val program_to_input: program -> input
33 val for_bdv: program -> T -> input option * T
35 val string_eqs_empty: as_string_eqs
36 val T_from_program: program -> T
41 structure Subst(**): SUBSTITUTION(**) =
45 type T = LibraryC.subst;
49 linefeed o pair2str o (apsnd UnparseC.term) o (apfst UnparseC.term)))) s;
51 type input = TermC.as_string list;
54 type as_string_eqs = TermC.as_string list;
56 val string_eqs_empty = []: TermC.as_string list;
58 fun string_eqs_to_string s = strs2str s;
60 type as_eqs = term list;
63 fun T_to_string_eqs subst = map UnparseC.term (map HOLogic.mk_eq subst)
64 fun T_to_input subst_rew = (subst_rew
65 |> map (apsnd UnparseC.term)
66 |> map (apfst UnparseC.term)
67 |> map (apfst (enclose "''" "''")))
69 handle TERM _ => raise TERM ("T_to_input: wrong argument " ^ to_string subst_rew, [])
71 fun T_from_string_eqs thy s = map (TermC.dest_equals o (TermC.parse_patt thy)) s;
72 (*TODO: input requires parse _: _ -> _ option*)
73 fun T_from_input ctxt input = (input
74 |> map (TermC.parse_patt (Proof_Context.theory_of ctxt))
75 |> map TermC.isapair2pair
76 |> map (apfst HOLogic.dest_string)
77 |> map (apfst (fn str => (TermC.mk_Free (str, HOLogic.realT)))))
78 handle TERM _ => raise TERM ("T_from_input: wrong argument " ^ strs2str' input, [])
80 val eqs_to_input = map UnparseC.term;
82 (* TermC.parse ctxt fails with "c_2 = 0" \<longrightarrow> \<open>c_2 = (0 :: 'a)\<close> and thus requires adapt_to_type *)
83 fun input_to_terms ctxt strs = strs
84 |> map (TermC.parse ctxt)
85 |> map (Model_Pattern.adapt_term_to_type ctxt)
87 fun program_to_input sub = (sub
89 |> map HOLogic.dest_prod
90 |> map (fn (e1, e2) => (HOLogic.dest_string e1, UnparseC.term e2))
91 |> map (fn (e1, e2) => "(''" ^ e1 ^ "'', " ^ e2 ^ ")"): TermC.as_string list)
92 handle TERM _ => raise TERM ("program_to_input: wrong argument ", [sub])
94 fun T_from_program t = (t
96 |> map HOLogic.dest_prod
97 |> map (apfst HOLogic.dest_string))
98 |> map (apfst (fn e1 => (TermC.mk_Free (e1, HOLogic.realT))))
99 handle TERM _ => raise TERM ("T_from_program: wrong argument ", [t])
101 (* get a substitution for "bdv*" from the current program and environment.
102 returns a substitution: as_string_eqs for tac, subst for tac_, i.e. for rewriting *)
103 fun for_bdv prog env =
105 fun scan (Const _) = NONE
106 | scan (Free _) = NONE
107 | scan (Var _) = NONE
108 | scan (Bound _) = NONE
109 | scan (t as Const (\<^const_name>\<open>Cons\<close>, _) $ (Const (\<^const_name>\<open>Pair\<close>, _) $ _ $ _) $ _) =
110 if TermC.is_bdv_subst t then SOME t else NONE
111 | scan (Abs (_, _, body)) = scan body
112 | scan (t1 $ t2) = case scan t1 of NONE => scan t2 | SOME subst => SOME subst
115 NONE => (NONE: input option, []: subst)
117 let val subst = subst_atomic env tm
118 in (SOME (program_to_input subst), T_from_program subst) end