walther@59945
|
1 |
(* Title: BaseDefinitions/model-pattern.sml
|
walther@59882
|
2 |
Author: Walther Neuper
|
walther@59882
|
3 |
(c) due to copyright terms
|
walther@59882
|
4 |
|
walther@60004
|
5 |
A \<open>Model_Pattern\<close> defines a -> \<open>Problem\<close>-type: its \<open>variables\<close> are to be instantiated
|
Walther@60654
|
6 |
by the values for particular \<open>Problem\<close>s in a \<open>Formalise.model\<close>.
|
walther@60004
|
7 |
The \<open>variables\<close> are used twice, in a model and as formal arguments in a \<open>Program\<close>.
|
walther@60004
|
8 |
The \<open>descriptor\<close>s are unique identifiers within one \<open>Model_Pattern\<close>.
|
walther@59945
|
9 |
*)
|
walther@59945
|
10 |
signature MODEL_PATTERN =
|
walther@59882
|
11 |
sig
|
walther@59945
|
12 |
type T
|
walther@59945
|
13 |
type single
|
Walther@60655
|
14 |
val to_string: Proof.context -> single list -> string
|
Walther@60710
|
15 |
val pat2str: Proof.context -> single -> string
|
Walther@60624
|
16 |
|
Walther@60624
|
17 |
type model_input_pos
|
Walther@60698
|
18 |
type empty_input
|
Walther@60602
|
19 |
type pre_model
|
Walther@60701
|
20 |
type pre_model'
|
Walther@60603
|
21 |
|
walther@59952
|
22 |
type m_field = string
|
walther@59952
|
23 |
type descriptor = term
|
Walther@60624
|
24 |
val parse_pos: Proof.context -> (m_field * (string * Position.T) list) list ->
|
Walther@60624
|
25 |
pre_model * (term * Position.T) list
|
Walther@60701
|
26 |
val parse_pos_empty: Proof.context -> (m_field * (string * Position.T) list) list ->
|
Walther@60701
|
27 |
pre_model' * (term * Position.T) list
|
walther@60004
|
28 |
|
walther@59987
|
29 |
val variables: T -> term list
|
walther@60004
|
30 |
val get_field: descriptor -> T -> m_field option
|
Walther@60697
|
31 |
datatype for = Problem | Method | Undef
|
Walther@60556
|
32 |
|
Walther@60556
|
33 |
val adapt_to_type: Proof.context -> single -> single
|
Walther@60698
|
34 |
(*from isac_test for Minisubpbl*)
|
Walther@60698
|
35 |
val split_descriptor: Proof.context -> m_field * term * Position.T ->
|
Walther@60698
|
36 |
(m_field * (descriptor * term) * Position.T)
|
Walther@60701
|
37 |
datatype pre_model_single' =
|
Walther@60698
|
38 |
Empty of (m_field * (descriptor * empty_input) * Position.T)
|
Walther@60698
|
39 |
| Proper of (m_field * (descriptor * term) * Position.T)
|
Walther@60698
|
40 |
val parse_pattern: Proof.context -> 'a * (string * Position.T) -> 'a * term * Position.T
|
Walther@60718
|
41 |
|
Walther@60721
|
42 |
val typ_of_element: descriptor -> typ
|
Walther@60719
|
43 |
val is_list_descr: descriptor -> bool
|
Walther@60718
|
44 |
val empty_for: descriptor -> empty_input
|
Walther@60698
|
45 |
val parse_term: Proof.context -> m_field * ((*TermC.as_*)string * Position.T) ->
|
Walther@60698
|
46 |
m_field * term * Position.T
|
Walther@60701
|
47 |
val parse_empty_input: Proof.context -> m_field * (string * Position.T) -> pre_model_single'
|
Walther@60700
|
48 |
val is_undefined: term -> bool
|
Walther@60556
|
49 |
|
wenzelm@60223
|
50 |
\<^isac_test>\<open>
|
Walther@60698
|
51 |
(**)
|
wenzelm@60223
|
52 |
\<close>
|
walther@59882
|
53 |
end
|
walther@59882
|
54 |
|
walther@59882
|
55 |
(**)
|
walther@59945
|
56 |
structure Model_Pattern(**): MODEL_PATTERN(**) =
|
walther@59882
|
57 |
struct
|
walther@59882
|
58 |
(**)
|
walther@59882
|
59 |
|
walther@59884
|
60 |
(* the pattern for an item of a problems model or a methods guard *)
|
walther@59945
|
61 |
type m_field = string;
|
walther@59952
|
62 |
type descriptor = term;
|
walther@59945
|
63 |
type single =
|
Walther@60722
|
64 |
(m_field * (* field Given, Find, Relate / Where in Pre_Conds *)
|
Walther@60722
|
65 |
(descriptor * (* for term *)
|
Walther@60722
|
66 |
term)) (* internal identifier for substitution *)
|
Walther@60722
|
67 |
(* does NOT contain Pre_Conds, because these have no \<open>descriptor\<close> *)
|
walther@59945
|
68 |
type T = single list;
|
walther@59945
|
69 |
|
Walther@60698
|
70 |
type model_input_pos = (* for internal use *)
|
Walther@60698
|
71 |
(m_field * (* "#Given", "#Find", "#Where", "#Relate" *)
|
Walther@60688
|
72 |
((*TermC.as_*)string * Position.T) list) (* list of items belonging to m_field *)
|
Walther@60698
|
73 |
list; (* list of "#Given" .. "#Relate" *)
|
Walther@60698
|
74 |
type empty_input = string
|
Walther@60720
|
75 |
datatype descr_type = List of typ | Single of typ
|
Walther@60718
|
76 |
fun descr_type (Type ("fun", [Type ("List.list", [typ]), _])) = List typ
|
Walther@60720
|
77 |
| descr_type (Type ("fun", [typ, _])) = Single typ
|
Walther@60720
|
78 |
| descr_type typ = raise TYPE ("Model_Pattern.descr_type", [typ], [])
|
Walther@60721
|
79 |
fun typ_of_element descr =
|
Walther@60721
|
80 |
case descr_type (type_of descr) of
|
Walther@60721
|
81 |
List typ => typ
|
Walther@60721
|
82 |
| Single typ => typ
|
Walther@60718
|
83 |
fun is_list_descr descr =
|
Walther@60718
|
84 |
case descr_type (type_of descr) of List _ => true | _ => false
|
Walther@60717
|
85 |
fun empty_for descr =
|
Walther@60717
|
86 |
case descr_type (type_of descr) of
|
Walther@60718
|
87 |
List typ => if typ = HOLogic.boolT then "[__=__, __=__]" else "[__, __]"
|
Walther@60720
|
88 |
| Single typ => if typ = HOLogic.boolT then "(__=__)" else "__"
|
Walther@60718
|
89 |
|
Walther@60624
|
90 |
type pre_model_single = (m_field * (descriptor * term) * Position.T)
|
Walther@60701
|
91 |
datatype pre_model_single' =
|
Walther@60698
|
92 |
Empty of (m_field * (descriptor * empty_input) * Position.T)
|
Walther@60698
|
93 |
| Proper of (m_field * (descriptor * term) * Position.T)
|
Walther@60698
|
94 |
type pre_model = pre_model_single list
|
Walther@60701
|
95 |
type pre_model' = pre_model_single' list
|
Walther@60602
|
96 |
|
Walther@60624
|
97 |
(*val split_descriptor: Proof.context -> m_field * term * Position.T ->
|
Walther@60624
|
98 |
m_field * (descriptor * term)(* * Position.T*)*)
|
Walther@60624
|
99 |
fun split_descriptor ctxt (m_field: string, dsc_tm, pos) =
|
Walther@60602
|
100 |
let
|
Walther@60624
|
101 |
val (m_field, (hd, arg)) = case strip_comb dsc_tm of
|
Walther@60602
|
102 |
(hd, [arg]) => (m_field, (hd, arg))
|
Walther@60675
|
103 |
| _ => error ("Wrong descriptor " ^ quote (UnparseC.term ctxt dsc_tm) ^ Position.here pos)
|
Walther@60624
|
104 |
in (m_field, (hd, arg), pos) end
|
Walther@60583
|
105 |
|
Walther@60604
|
106 |
(*val parse_term: Proof.context -> m_field * ((*TermC.as_*)string * Position.T) -> m_field * term*)
|
Walther@60604
|
107 |
fun parse_term ctxt (m_field, (str, pos)) =
|
Walther@60660
|
108 |
(m_field, ParseC.term_position ctxt (str, pos), pos)
|
Walther@60701
|
109 |
|
Walther@60701
|
110 |
fun is_undefined tm =
|
Walther@60701
|
111 |
if Term.exists_subterm (fn Const ("HOL.undefined", _) => true | _ => false) tm then true else false
|
Walther@60701
|
112 |
fun parse_empty_input ctxt (m_field, (str, pos)) =
|
Walther@60698
|
113 |
let
|
Walther@60699
|
114 |
val (m_field, term, pos) = parse_term ctxt (m_field, (str, pos))
|
Walther@60699
|
115 |
val (m_field, (descr, arg), pos) = split_descriptor ctxt (m_field, term, pos)
|
Walther@60698
|
116 |
in
|
Walther@60699
|
117 |
if is_undefined arg
|
Walther@60717
|
118 |
then Empty (m_field, (descr, descr |> empty_for), pos)
|
Walther@60699
|
119 |
else Proper (m_field, (descr, arg), pos)
|
Walther@60698
|
120 |
end
|
Walther@60698
|
121 |
|
Walther@60604
|
122 |
fun parse_pattern ctxt (m_field, (str, pos)) =
|
Walther@60660
|
123 |
(m_field, ParseC.pattern_position ctxt (str, pos), pos)
|
Walther@60624
|
124 |
|
Walther@60624
|
125 |
fun parse_pos ctxt model_input =
|
Walther@60602
|
126 |
let
|
Walther@60602
|
127 |
val items = model_input |> map (fn (m_field, items) => map (pair m_field) items) |> flat;
|
Walther@60602
|
128 |
val model = items
|
Walther@60602
|
129 |
|> filter_out ((fn f => (fn (f', _) => f = f')) "#Where")
|
Walther@60604
|
130 |
|> map (parse_term ctxt)
|
Walther@60624
|
131 |
|> map (split_descriptor ctxt)
|
Walther@60602
|
132 |
val where_ = items
|
Walther@60603
|
133 |
|> filter ((fn f => (fn (f', _) => f = f')) "#Where")
|
Walther@60604
|
134 |
|> map (parse_pattern ctxt)
|
Walther@60624
|
135 |
|> map (fn (_, a, b) => (a, b))
|
Walther@60602
|
136 |
in (model, where_) end
|
Walther@60701
|
137 |
fun parse_pos_empty ctxt model_input =
|
Walther@60698
|
138 |
let
|
Walther@60698
|
139 |
val items = model_input |> map (fn (m_field, items) => map (pair m_field) items) |> flat;
|
Walther@60698
|
140 |
val model = items
|
Walther@60699
|
141 |
|> filter_out ((fn f => (fn (f', _) => f = f')) "#Where")
|
Walther@60701
|
142 |
|> map (parse_empty_input ctxt)
|
Walther@60698
|
143 |
val where_ = items
|
Walther@60698
|
144 |
|> filter ((fn f => (fn (f', _) => f = f')) "#Where")
|
Walther@60698
|
145 |
|> map (parse_pattern ctxt)
|
Walther@60698
|
146 |
|> map (fn (_, a, b) => (a, b))
|
Walther@60698
|
147 |
in (model, where_) end
|
Walther@60583
|
148 |
|
Walther@60655
|
149 |
fun pat2str ctxt (field, (dsc, id)) =
|
Walther@60675
|
150 |
pair2str (field, pair2str (UnparseC.term ctxt dsc, UnparseC.term ctxt id));
|
Walther@60655
|
151 |
fun to_string ctxt pats = (strs2str o (map (pat2str ctxt))) pats;
|
Walther@60654
|
152 |
|
wenzelm@60223
|
153 |
\<^isac_test>\<open>
|
Walther@60655
|
154 |
(**)
|
wenzelm@60223
|
155 |
\<close>
|
walther@59882
|
156 |
|
walther@59987
|
157 |
(* get the variables out of a pbl_; FIXME.WN.0311: is_copy_named ...obscure!!! *)
|
walther@59987
|
158 |
fun variables pbl_ =
|
walther@59987
|
159 |
let
|
walther@59987
|
160 |
fun var_of_pbl_ (_, (_, t)) = t: term
|
walther@59987
|
161 |
in ((map var_of_pbl_)(* o (filter_out is_copy_named)*)) pbl_ end
|
walther@59987
|
162 |
|
walther@60004
|
163 |
fun get_field descriptor m_patt =
|
walther@60004
|
164 |
(filter ((curry (fn (desc, (_, (desc', _))) => desc = desc')) descriptor) m_patt
|
walther@60004
|
165 |
|> the_single
|
walther@60004
|
166 |
|> (fn (a, _) => SOME a))
|
walther@60004
|
167 |
handle List.Empty => NONE
|
Walther@60697
|
168 |
datatype for = Problem | Method | Undef
|
Walther@60697
|
169 |
|
walther@60004
|
170 |
|
Walther@60660
|
171 |
(* adapt type of terms with most general type to a more specific one *)
|
Walther@60556
|
172 |
fun adapt_to_type ctxt (field, (descr, term_as_string)) =
|
Walther@60660
|
173 |
(field, (ParseC.adapt_term_to_type ctxt descr, ParseC.adapt_term_to_type ctxt term_as_string))
|
Walther@60603
|
174 |
|
Walther@60603
|
175 |
(**)end(*struct*)
|