1 (* Title: BaseDefinitions/model-pattern.sml
3 (c) due to copyright terms
5 A \<open>Model_Pattern\<close> defines a -> \<open>Problem\<close>-type: its \<open>variables\<close> are to be instantiated
6 by the values for particular \<open>Problem\<close>s in a \<open>Formalise.model\<close>.
7 The \<open>variables\<close> are used twice, in a model and as formal arguments in a \<open>Program\<close>.
8 The \<open>descriptor\<close>s are unique identifiers within one \<open>Model_Pattern\<close>.
10 signature MODEL_PATTERN =
14 val to_string: Proof.context -> single list -> string
15 val pat2str: Proof.context -> single -> string
23 type descriptor = term
24 val parse_pos: Proof.context -> (m_field * (string * Position.T) list) list ->
25 pre_model * (term * Position.T) list
26 val parse_pos_empty: Proof.context -> (m_field * (string * Position.T) list) list ->
27 pre_model' * (term * Position.T) list
29 val variables: T -> term list
30 val get_field: descriptor -> T -> m_field option
31 datatype for = Problem | Method | Undef
33 val adapt_to_type: Proof.context -> single -> single
34 (*from isac_test for Minisubpbl*)
35 val split_descriptor: Proof.context -> m_field * term * Position.T ->
36 (m_field * (descriptor * term) * Position.T)
37 datatype pre_model_single' =
38 Empty of (m_field * (descriptor * empty_input) * Position.T)
39 | Proper of (m_field * (descriptor * term) * Position.T)
40 val parse_pattern: Proof.context -> 'a * (string * Position.T) -> 'a * term * Position.T
42 val typ_of_element: descriptor -> typ
43 val is_list_descr: descriptor -> bool
44 val empty_for: descriptor -> empty_input
45 val parse_term: Proof.context -> m_field * ((*TermC.as_*)string * Position.T) ->
46 m_field * term * Position.T
47 val parse_empty_input: Proof.context -> m_field * (string * Position.T) -> pre_model_single'
48 val is_undefined: term -> bool
56 structure Model_Pattern(**): MODEL_PATTERN(**) =
60 (* the pattern for an item of a problems model or a methods guard *)
61 type m_field = string;
62 type descriptor = term;
64 (m_field * (* field Given, Find, Relate *)
65 (descriptor * (* for snd term *)
66 term)) (* id | arbitrary term *);
67 (* does NOT contain pre-conditions, because these have no \<open>descriptor\<close> *)
70 type model_input_pos = (* for internal use *)
71 (m_field * (* "#Given", "#Find", "#Where", "#Relate" *)
72 ((*TermC.as_*)string * Position.T) list) (* list of items belonging to m_field *)
73 list; (* list of "#Given" .. "#Relate" *)
74 type empty_input = string
75 datatype descr_type = List of typ | Single of typ
76 fun descr_type (Type ("fun", [Type ("List.list", [typ]), _])) = List typ
77 | descr_type (Type ("fun", [typ, _])) = Single typ
78 | descr_type typ = raise TYPE ("Model_Pattern.descr_type", [typ], [])
79 fun typ_of_element descr =
80 case descr_type (type_of descr) of
83 fun is_list_descr descr =
84 case descr_type (type_of descr) of List _ => true | _ => false
86 case descr_type (type_of descr) of
87 List typ => if typ = HOLogic.boolT then "[__=__, __=__]" else "[__, __]"
88 | Single typ => if typ = HOLogic.boolT then "(__=__)" else "__"
90 type pre_model_single = (m_field * (descriptor * term) * Position.T)
91 datatype pre_model_single' =
92 Empty of (m_field * (descriptor * empty_input) * Position.T)
93 | Proper of (m_field * (descriptor * term) * Position.T)
94 type pre_model = pre_model_single list
95 type pre_model' = pre_model_single' list
97 (*val split_descriptor: Proof.context -> m_field * term * Position.T ->
98 m_field * (descriptor * term)(* * Position.T*)*)
99 fun split_descriptor ctxt (m_field: string, dsc_tm, pos) =
101 val (m_field, (hd, arg)) = case strip_comb dsc_tm of
102 (hd, [arg]) => (m_field, (hd, arg))
103 | _ => error ("Wrong descriptor " ^ quote (UnparseC.term ctxt dsc_tm) ^ Position.here pos)
104 in (m_field, (hd, arg), pos) end
106 (*val parse_term: Proof.context -> m_field * ((*TermC.as_*)string * Position.T) -> m_field * term*)
107 fun parse_term ctxt (m_field, (str, pos)) =
108 (m_field, ParseC.term_position ctxt (str, pos), pos)
110 fun is_undefined tm =
111 if Term.exists_subterm (fn Const ("HOL.undefined", _) => true | _ => false) tm then true else false
112 fun parse_empty_input ctxt (m_field, (str, pos)) =
114 val (m_field, term, pos) = parse_term ctxt (m_field, (str, pos))
115 val (m_field, (descr, arg), pos) = split_descriptor ctxt (m_field, term, pos)
118 then Empty (m_field, (descr, descr |> empty_for), pos)
119 else Proper (m_field, (descr, arg), pos)
122 fun parse_pattern ctxt (m_field, (str, pos)) =
123 (m_field, ParseC.pattern_position ctxt (str, pos), pos)
125 fun parse_pos ctxt model_input =
127 val items = model_input |> map (fn (m_field, items) => map (pair m_field) items) |> flat;
129 |> filter_out ((fn f => (fn (f', _) => f = f')) "#Where")
130 |> map (parse_term ctxt)
131 |> map (split_descriptor ctxt)
133 |> filter ((fn f => (fn (f', _) => f = f')) "#Where")
134 |> map (parse_pattern ctxt)
135 |> map (fn (_, a, b) => (a, b))
136 in (model, where_) end
137 fun parse_pos_empty ctxt model_input =
139 val items = model_input |> map (fn (m_field, items) => map (pair m_field) items) |> flat;
141 |> filter_out ((fn f => (fn (f', _) => f = f')) "#Where")
142 |> map (parse_empty_input ctxt)
144 |> filter ((fn f => (fn (f', _) => f = f')) "#Where")
145 |> map (parse_pattern ctxt)
146 |> map (fn (_, a, b) => (a, b))
147 in (model, where_) end
149 fun pat2str ctxt (field, (dsc, id)) =
150 pair2str (field, pair2str (UnparseC.term ctxt dsc, UnparseC.term ctxt id));
151 fun to_string ctxt pats = (strs2str o (map (pat2str ctxt))) pats;
157 (* get the variables out of a pbl_; FIXME.WN.0311: is_copy_named ...obscure!!! *)
160 fun var_of_pbl_ (_, (_, t)) = t: term
161 in ((map var_of_pbl_)(* o (filter_out is_copy_named)*)) pbl_ end
163 fun get_field descriptor m_patt =
164 (filter ((curry (fn (desc, (_, (desc', _))) => desc = desc')) descriptor) m_patt
166 |> (fn (a, _) => SOME a))
167 handle List.Empty => NONE
168 datatype for = Problem | Method | Undef
171 (* adapt type of terms with most general type to a more specific one *)
172 fun adapt_to_type ctxt (field, (descr, term_as_string)) =
173 (field, (ParseC.adapt_term_to_type ctxt descr, ParseC.adapt_term_to_type ctxt term_as_string))