66 val rel_expr_for_bound_var = foldl1 Product oooo vars_for_bound_var |
59 val rel_expr_for_bound_var = foldl1 Product oooo vars_for_bound_var |
67 fun decls_for R card Ts T = |
60 fun decls_for R card Ts T = |
68 map2 (curry DeclOne o pair 1) |
61 map2 (curry DeclOne o pair 1) |
69 (index_seq (index_for_bound_var card (T :: Ts) 0) |
62 (index_seq (index_for_bound_var card (T :: Ts) 0) |
70 (arity_of R card (nth (T :: Ts) 0))) |
63 (arity_of R card (nth (T :: Ts) 0))) |
71 (map (AtomSeq o rpair 0) (atom_schema_of R card T)) |
64 (atom_seqs_of R card T) |
72 |
65 |
73 val atom_product = foldl1 Product o map Atom |
66 val atom_product = foldl1 Product o map Atom |
74 |
67 |
75 val false_atom = Atom 0 |
68 val false_atom_num = 0 |
76 val true_atom = Atom 1 |
69 val true_atom_num = 1 |
77 |
70 val false_atom = Atom false_atom_num |
78 fun formula_from_atom r = RelEq (r, true_atom) |
71 val true_atom = Atom true_atom_num |
79 fun atom_from_formula f = RelIf (f, true_atom, false_atom) |
72 |
80 |
73 fun kodkod_formula_from_term ctxt total card complete concrete frees = |
81 fun kodkod_formula_from_term ctxt card frees = |
|
82 let |
74 let |
83 fun R_rep_from_S_rep (Type (@{type_name fun}, [T1, @{typ bool}])) r = |
75 fun F_from_S_rep (SOME false) r = Not (RelEq (r, false_atom)) |
84 let |
76 | F_from_S_rep _ r = RelEq (r, true_atom) |
85 val jss = atom_schema_of S_Rep card T1 |> map (rpair 0) |
77 fun S_rep_from_F NONE f = RelIf (f, true_atom, false_atom) |
86 |> all_combinations |
78 | S_rep_from_F (SOME true) f = RelIf (f, true_atom, None) |
87 in |
79 | S_rep_from_F (SOME false) f = RelIf (Not f, false_atom, None) |
88 map2 (fn i => fn js => |
80 fun R_rep_from_S_rep (Type (@{type_name fun}, [T1, T2])) r = |
89 RelIf (formula_from_atom (Project (r, [Num i])), |
81 if total andalso T2 = bool_T then |
90 atom_product js, empty_n_ary_rel (length js))) |
82 let |
91 (index_seq 0 (length jss)) jss |
83 val jss = atom_schema_of S_Rep card T1 |> map (rpair 0) |
92 |> foldl1 Union |
84 |> all_combinations |
93 end |
85 in |
94 | R_rep_from_S_rep (Type (@{type_name fun}, [T1, T2])) r = |
86 map2 (fn i => fn js => |
95 let |
87 (* |
96 val jss = atom_schema_of S_Rep card T1 |> map (rpair 0) |
88 RelIf (F_from_S_rep NONE (Project (r, [Num i])), |
97 |> all_combinations |
89 atom_product js, empty_n_ary_rel (length js)) |
98 val arity2 = arity_of S_Rep card T2 |
90 *) |
99 in |
91 Join (Project (r, [Num i]), |
100 map2 (fn i => fn js => |
92 atom_product (false_atom_num :: js)) |
101 Product (atom_product js, |
93 ) (index_seq 0 (length jss)) jss |
102 Project (r, num_seq (i * arity2) arity2) |
94 |> foldl1 Union |
103 |> R_rep_from_S_rep T2)) |
95 end |
104 (index_seq 0 (length jss)) jss |
96 else |
105 |> foldl1 Union |
97 let |
106 end |
98 val jss = atom_schema_of S_Rep card T1 |> map (rpair 0) |
|
99 |> all_combinations |
|
100 val arity2 = arity_of S_Rep card T2 |
|
101 in |
|
102 map2 (fn i => fn js => |
|
103 Product (atom_product js, |
|
104 Project (r, num_seq (i * arity2) arity2) |
|
105 |> R_rep_from_S_rep T2)) |
|
106 (index_seq 0 (length jss)) jss |
|
107 |> foldl1 Union |
|
108 end |
107 | R_rep_from_S_rep _ r = r |
109 | R_rep_from_S_rep _ r = r |
108 fun S_rep_from_R_rep Ts (T as Type (@{type_name fun}, _)) r = |
110 fun S_rep_from_R_rep Ts (T as Type (@{type_name fun}, _)) r = |
109 Comprehension (decls_for S_Rep card Ts T, |
111 Comprehension (decls_for S_Rep card Ts T, |
110 RelEq (R_rep_from_S_rep T |
112 RelEq (R_rep_from_S_rep T |
111 (rel_expr_for_bound_var card S_Rep (T :: Ts) 0), r)) |
113 (rel_expr_for_bound_var card S_Rep (T :: Ts) 0), r)) |
112 | S_rep_from_R_rep _ _ r = r |
114 | S_rep_from_R_rep _ _ r = r |
113 fun to_F Ts t = |
115 fun partial_eq pos Ts (Type (@{type_name fun}, [T1, T2])) t1 t2 = |
|
116 HOLogic.mk_all ("x", T1, |
|
117 HOLogic.eq_const T2 $ (incr_boundvars 1 t1 $ Bound 0) |
|
118 $ (incr_boundvars 1 t2 $ Bound 0)) |
|
119 |> to_F (SOME pos) Ts |
|
120 | partial_eq pos Ts T t1 t2 = |
|
121 if pos andalso not (concrete T) then |
|
122 False |
|
123 else |
|
124 (t1, t2) |> pairself (to_R_rep Ts) |
|
125 |> (if pos then Some o Intersect else Lone o Union) |
|
126 and to_F pos Ts t = |
114 (case t of |
127 (case t of |
115 @{const Not} $ t1 => Not (to_F Ts t1) |
128 @{const Not} $ t1 => Not (to_F (Option.map not pos) Ts t1) |
116 | @{const False} => False |
129 | @{const False} => False |
117 | @{const True} => True |
130 | @{const True} => True |
118 | Const (@{const_name All}, _) $ Abs (_, T, t') => |
131 | Const (@{const_name All}, _) $ Abs (_, T, t') => |
119 All (decls_for S_Rep card Ts T, to_F (T :: Ts) t') |
132 if pos = SOME true andalso not (complete T) then False |
|
133 else All (decls_for S_Rep card Ts T, to_F pos (T :: Ts) t') |
120 | (t0 as Const (@{const_name All}, _)) $ t1 => |
134 | (t0 as Const (@{const_name All}, _)) $ t1 => |
121 to_F Ts (t0 $ eta_expand Ts t1 1) |
135 to_F pos Ts (t0 $ eta_expand Ts t1 1) |
122 | Const (@{const_name Ex}, _) $ Abs (_, T, t') => |
136 | Const (@{const_name Ex}, _) $ Abs (_, T, t') => |
123 Exist (decls_for S_Rep card Ts T, to_F (T :: Ts) t') |
137 if pos = SOME false andalso not (complete T) then True |
|
138 else Exist (decls_for S_Rep card Ts T, to_F pos (T :: Ts) t') |
124 | (t0 as Const (@{const_name Ex}, _)) $ t1 => |
139 | (t0 as Const (@{const_name Ex}, _)) $ t1 => |
125 to_F Ts (t0 $ eta_expand Ts t1 1) |
140 to_F pos Ts (t0 $ eta_expand Ts t1 1) |
126 | Const (@{const_name HOL.eq}, _) $ t1 $ t2 => |
141 | Const (@{const_name HOL.eq}, Type (_, [T, _])) $ t1 $ t2 => |
127 RelEq (to_R_rep Ts t1, to_R_rep Ts t2) |
142 (case pos of |
|
143 NONE => RelEq (to_R_rep Ts t1, to_R_rep Ts t2) |
|
144 | SOME pos => partial_eq pos Ts T t1 t2) |
128 | Const (@{const_name ord_class.less_eq}, |
145 | Const (@{const_name ord_class.less_eq}, |
129 Type (@{type_name fun}, |
146 Type (@{type_name fun}, |
130 [Type (@{type_name fun}, [_, @{typ bool}]), _])) |
147 [Type (@{type_name fun}, [T', @{typ bool}]), _])) |
131 $ t1 $ t2 => |
148 $ t1 $ t2 => |
132 Subset (to_R_rep Ts t1, to_R_rep Ts t2) |
149 (case pos of |
133 | @{const HOL.conj} $ t1 $ t2 => And (to_F Ts t1, to_F Ts t2) |
150 NONE => Subset (to_R_rep Ts t1, to_R_rep Ts t2) |
134 | @{const HOL.disj} $ t1 $ t2 => Or (to_F Ts t1, to_F Ts t2) |
151 | SOME true => |
135 | @{const HOL.implies} $ t1 $ t2 => Implies (to_F Ts t1, to_F Ts t2) |
152 Subset (Difference (atom_seq_product_of S_Rep card T', |
136 | t1 $ t2 => Subset (to_S_rep Ts t2, to_R_rep Ts t1) |
153 Join (to_R_rep Ts t1, false_atom)), |
137 | Free _ => raise SAME () |
154 Join (to_R_rep Ts t2, true_atom)) |
138 | Term.Var _ => raise SAME () |
155 | SOME false => |
139 | Bound _ => raise SAME () |
156 Subset (Join (to_R_rep Ts t1, true_atom), |
140 | Const (s, _) => raise NOT_SUPPORTED ("constant " ^ quote s) |
157 Difference (atom_seq_product_of S_Rep card T', |
141 | _ => raise TERM ("Minipick.kodkod_formula_from_term.to_F", [t])) |
158 Join (to_R_rep Ts t2, false_atom)))) |
142 handle SAME () => formula_from_atom (to_R_rep Ts t) |
159 | @{const HOL.conj} $ t1 $ t2 => And (to_F pos Ts t1, to_F pos Ts t2) |
|
160 | @{const HOL.disj} $ t1 $ t2 => Or (to_F pos Ts t1, to_F pos Ts t2) |
|
161 | @{const HOL.implies} $ t1 $ t2 => |
|
162 Implies (to_F (Option.map not pos) Ts t1, to_F pos Ts t2) |
|
163 | t1 $ t2 => |
|
164 (case pos of |
|
165 NONE => Subset (to_S_rep Ts t2, to_R_rep Ts t1) |
|
166 | SOME pos => |
|
167 let |
|
168 val kt1 = to_R_rep Ts t1 |
|
169 val kt2 = to_S_rep Ts t2 |
|
170 val kT = atom_seq_product_of S_Rep card (fastype_of1 (Ts, t2)) |
|
171 in |
|
172 if pos then |
|
173 Not (Subset (kt2, Difference (kT, Join (kt1, true_atom)))) |
|
174 else |
|
175 Subset (kt2, Difference (kT, Join (kt1, false_atom))) |
|
176 end) |
|
177 | _ => raise SAME ()) |
|
178 handle SAME () => F_from_S_rep pos (to_R_rep Ts t) |
143 and to_S_rep Ts t = |
179 and to_S_rep Ts t = |
144 case t of |
180 case t of |
145 Const (@{const_name Pair}, _) $ t1 $ t2 => |
181 Const (@{const_name Pair}, _) $ t1 $ t2 => |
146 Product (to_S_rep Ts t1, to_S_rep Ts t2) |
182 Product (to_S_rep Ts t1, to_S_rep Ts t2) |
147 | Const (@{const_name Pair}, _) $ _ => to_S_rep Ts (eta_expand Ts t 1) |
183 | Const (@{const_name Pair}, _) $ _ => to_S_rep Ts (eta_expand Ts t 1) |
178 | @{const HOL.disj} $ _ => to_R_rep Ts (eta_expand Ts t 1) |
224 | @{const HOL.disj} $ _ => to_R_rep Ts (eta_expand Ts t 1) |
179 | @{const HOL.disj} => to_R_rep Ts (eta_expand Ts t 2) |
225 | @{const HOL.disj} => to_R_rep Ts (eta_expand Ts t 2) |
180 | @{const HOL.implies} $ _ => to_R_rep Ts (eta_expand Ts t 1) |
226 | @{const HOL.implies} $ _ => to_R_rep Ts (eta_expand Ts t 1) |
181 | @{const HOL.implies} => to_R_rep Ts (eta_expand Ts t 2) |
227 | @{const HOL.implies} => to_R_rep Ts (eta_expand Ts t 2) |
182 | Const (@{const_name bot_class.bot}, |
228 | Const (@{const_name bot_class.bot}, |
183 T as Type (@{type_name fun}, [_, @{typ bool}])) => |
229 T as Type (@{type_name fun}, [T', @{typ bool}])) => |
184 empty_n_ary_rel (arity_of R_Rep card T) |
230 if total then empty_n_ary_rel (arity_of (R_Rep total) card T) |
185 | Const (@{const_name insert}, _) $ t1 $ t2 => |
231 else Product (atom_seq_product_of (R_Rep total) card T', false_atom) |
186 Union (to_S_rep Ts t1, to_R_rep Ts t2) |
232 | Const (@{const_name top_class.top}, |
|
233 T as Type (@{type_name fun}, [T', @{typ bool}])) => |
|
234 if total then atom_seq_product_of (R_Rep total) card T |
|
235 else Product (atom_seq_product_of (R_Rep total) card T', true_atom) |
|
236 | Const (@{const_name insert}, Type (_, [T, _])) $ t1 $ t2 => |
|
237 if total then |
|
238 Union (to_S_rep Ts t1, to_R_rep Ts t2) |
|
239 else |
|
240 let |
|
241 val kt1 = to_S_rep Ts t1 |
|
242 val kt2 = to_R_rep Ts t2 |
|
243 in |
|
244 RelIf (Some kt1, |
|
245 if arity_of S_Rep card T = 1 then |
|
246 Override (kt2, Product (kt1, true_atom)) |
|
247 else |
|
248 Union (Difference (kt2, Product (kt1, false_atom)), |
|
249 Product (kt1, true_atom)), |
|
250 Difference (kt2, Product (atom_seq_product_of S_Rep card T, |
|
251 false_atom))) |
|
252 end |
187 | Const (@{const_name insert}, _) $ _ => to_R_rep Ts (eta_expand Ts t 1) |
253 | Const (@{const_name insert}, _) $ _ => to_R_rep Ts (eta_expand Ts t 1) |
188 | Const (@{const_name insert}, _) => to_R_rep Ts (eta_expand Ts t 2) |
254 | Const (@{const_name insert}, _) => to_R_rep Ts (eta_expand Ts t 2) |
189 | Const (@{const_name trancl}, _) $ t1 => |
255 | Const (@{const_name trancl}, |
190 if arity_of R_Rep card (fastype_of1 (Ts, t1)) = 2 then |
256 Type (_, [Type (_, [Type (_, [T', _]), _]), _])) $ t1 => |
191 Closure (to_R_rep Ts t1) |
257 if arity_of S_Rep card T' = 1 then |
|
258 if total then |
|
259 Closure (to_R_rep Ts t1) |
|
260 else |
|
261 let |
|
262 val kt1 = to_R_rep Ts t1 |
|
263 val true_core_kt = Closure (Join (kt1, true_atom)) |
|
264 val kTx = |
|
265 atom_seq_product_of S_Rep card (HOLogic.mk_prodT (`I T')) |
|
266 val false_mantle_kt = |
|
267 Difference (kTx, |
|
268 Closure (Difference (kTx, Join (kt1, false_atom)))) |
|
269 in |
|
270 Union (Product (Difference (false_mantle_kt, true_core_kt), |
|
271 false_atom), |
|
272 Product (true_core_kt, true_atom)) |
|
273 end |
192 else |
274 else |
193 raise NOT_SUPPORTED "transitive closure for function or pair type" |
275 raise NOT_SUPPORTED "transitive closure for function or pair type" |
194 | Const (@{const_name trancl}, _) => to_R_rep Ts (eta_expand Ts t 1) |
276 | Const (@{const_name trancl}, _) => to_R_rep Ts (eta_expand Ts t 1) |
195 | Const (@{const_name inf_class.inf}, |
277 | Const (@{const_name inf_class.inf}, |
196 Type (@{type_name fun}, |
278 Type (@{type_name fun}, |
197 [Type (@{type_name fun}, [_, @{typ bool}]), _])) |
279 [Type (@{type_name fun}, [_, @{typ bool}]), _])) |
198 $ t1 $ t2 => |
280 $ t1 $ t2 => |
199 Intersect (to_R_rep Ts t1, to_R_rep Ts t2) |
281 if total then Intersect (to_R_rep Ts t1, to_R_rep Ts t2) |
|
282 else partial_set_op true true Intersect Union Ts t1 t2 |
200 | Const (@{const_name inf_class.inf}, _) $ _ => |
283 | Const (@{const_name inf_class.inf}, _) $ _ => |
201 to_R_rep Ts (eta_expand Ts t 1) |
284 to_R_rep Ts (eta_expand Ts t 1) |
202 | Const (@{const_name inf_class.inf}, _) => |
285 | Const (@{const_name inf_class.inf}, _) => |
203 to_R_rep Ts (eta_expand Ts t 2) |
286 to_R_rep Ts (eta_expand Ts t 2) |
204 | Const (@{const_name sup_class.sup}, |
287 | Const (@{const_name sup_class.sup}, |
205 Type (@{type_name fun}, |
288 Type (@{type_name fun}, |
206 [Type (@{type_name fun}, [_, @{typ bool}]), _])) |
289 [Type (@{type_name fun}, [_, @{typ bool}]), _])) |
207 $ t1 $ t2 => |
290 $ t1 $ t2 => |
208 Union (to_R_rep Ts t1, to_R_rep Ts t2) |
291 if total then Union (to_R_rep Ts t1, to_R_rep Ts t2) |
|
292 else partial_set_op true true Union Intersect Ts t1 t2 |
209 | Const (@{const_name sup_class.sup}, _) $ _ => |
293 | Const (@{const_name sup_class.sup}, _) $ _ => |
210 to_R_rep Ts (eta_expand Ts t 1) |
294 to_R_rep Ts (eta_expand Ts t 1) |
211 | Const (@{const_name sup_class.sup}, _) => |
295 | Const (@{const_name sup_class.sup}, _) => |
212 to_R_rep Ts (eta_expand Ts t 2) |
296 to_R_rep Ts (eta_expand Ts t 2) |
213 | Const (@{const_name minus_class.minus}, |
297 | Const (@{const_name minus_class.minus}, |
214 Type (@{type_name fun}, |
298 Type (@{type_name fun}, |
215 [Type (@{type_name fun}, [_, @{typ bool}]), _])) |
299 [Type (@{type_name fun}, [_, @{typ bool}]), _])) |
216 $ t1 $ t2 => |
300 $ t1 $ t2 => |
217 Difference (to_R_rep Ts t1, to_R_rep Ts t2) |
301 if total then Difference (to_R_rep Ts t1, to_R_rep Ts t2) |
|
302 else partial_set_op true false Intersect Union Ts t1 t2 |
218 | Const (@{const_name minus_class.minus}, |
303 | Const (@{const_name minus_class.minus}, |
219 Type (@{type_name fun}, |
304 Type (@{type_name fun}, |
220 [Type (@{type_name fun}, [_, @{typ bool}]), _])) $ _ => |
305 [Type (@{type_name fun}, [_, @{typ bool}]), _])) $ _ => |
221 to_R_rep Ts (eta_expand Ts t 1) |
306 to_R_rep Ts (eta_expand Ts t 1) |
222 | Const (@{const_name minus_class.minus}, |
307 | Const (@{const_name minus_class.minus}, |
223 Type (@{type_name fun}, |
308 Type (@{type_name fun}, |
224 [Type (@{type_name fun}, [_, @{typ bool}]), _])) => |
309 [Type (@{type_name fun}, [_, @{typ bool}]), _])) => |
225 to_R_rep Ts (eta_expand Ts t 2) |
310 to_R_rep Ts (eta_expand Ts t 2) |
226 | Const (@{const_name Pair}, _) $ _ $ _ => raise SAME () |
311 | Const (@{const_name Pair}, _) $ _ $ _ => to_S_rep Ts t |
227 | Const (@{const_name Pair}, _) $ _ => raise SAME () |
312 | Const (@{const_name Pair}, _) $ _ => to_S_rep Ts t |
228 | Const (@{const_name Pair}, _) => raise SAME () |
313 | Const (@{const_name Pair}, _) => to_S_rep Ts t |
229 | Const (@{const_name fst}, _) $ _ => raise SAME () |
314 | Const (@{const_name fst}, _) $ _ => raise SAME () |
230 | Const (@{const_name fst}, _) => raise SAME () |
315 | Const (@{const_name fst}, _) => raise SAME () |
231 | Const (@{const_name snd}, _) $ _ => raise SAME () |
316 | Const (@{const_name snd}, _) $ _ => raise SAME () |
232 | Const (@{const_name snd}, _) => raise SAME () |
317 | Const (@{const_name snd}, _) => raise SAME () |
233 | Const (_, @{typ bool}) => atom_from_formula (to_F Ts t) |
318 | @{const False} => false_atom |
|
319 | @{const True} => true_atom |
234 | Free (x as (_, T)) => |
320 | Free (x as (_, T)) => |
235 Rel (arity_of R_Rep card T, find_index (curry (op =) x) frees) |
321 Rel (arity_of (R_Rep total) card T, find_index (curry (op =) x) frees) |
236 | Term.Var _ => raise NOT_SUPPORTED "schematic variables" |
322 | Term.Var _ => raise NOT_SUPPORTED "schematic variables" |
237 | Bound _ => raise SAME () |
323 | Bound _ => raise SAME () |
238 | Abs (_, T, t') => |
324 | Abs (_, T, t') => |
239 (case fastype_of1 (T :: Ts, t') of |
325 (case (total, fastype_of1 (T :: Ts, t')) of |
240 @{typ bool} => Comprehension (decls_for S_Rep card Ts T, |
326 (true, @{typ bool}) => |
241 to_F (T :: Ts) t') |
327 Comprehension (decls_for S_Rep card Ts T, to_F NONE (T :: Ts) t') |
242 | T' => Comprehension (decls_for S_Rep card Ts T @ |
328 | (_, T') => |
243 decls_for R_Rep card (T :: Ts) T', |
329 Comprehension (decls_for S_Rep card Ts T @ |
244 Subset (rel_expr_for_bound_var card R_Rep |
330 decls_for (R_Rep total) card (T :: Ts) T', |
245 (T' :: T :: Ts) 0, |
331 Subset (rel_expr_for_bound_var card (R_Rep total) |
246 to_R_rep (T :: Ts) t'))) |
332 (T' :: T :: Ts) 0, |
|
333 to_R_rep (T :: Ts) t'))) |
247 | t1 $ t2 => |
334 | t1 $ t2 => |
248 (case fastype_of1 (Ts, t) of |
335 (case fastype_of1 (Ts, t) of |
249 @{typ bool} => atom_from_formula (to_F Ts t) |
336 @{typ bool} => |
|
337 if total then |
|
338 S_rep_from_F NONE (to_F NONE Ts t) |
|
339 else |
|
340 RelIf (to_F (SOME true) Ts t, true_atom, |
|
341 RelIf (Not (to_F (SOME false) Ts t), false_atom, |
|
342 None)) |
250 | T => |
343 | T => |
251 let val T2 = fastype_of1 (Ts, t2) in |
344 let val T2 = fastype_of1 (Ts, t2) in |
252 case arity_of S_Rep card T2 of |
345 case arity_of S_Rep card T2 of |
253 1 => Join (to_S_rep Ts t2, to_R_rep Ts t1) |
346 1 => Join (to_S_rep Ts t2, to_R_rep Ts t1) |
254 | arity2 => |
347 | arity2 => |
255 let val res_arity = arity_of R_Rep card T in |
348 let val res_arity = arity_of (R_Rep total) card T in |
256 Project (Intersect |
349 Project (Intersect |
257 (Product (to_S_rep Ts t2, |
350 (Product (to_S_rep Ts t2, |
258 atom_schema_of R_Rep card T |
351 atom_seq_product_of (R_Rep total) card T), |
259 |> map (AtomSeq o rpair 0) |> foldl1 Product), |
|
260 to_R_rep Ts t1), |
352 to_R_rep Ts t1), |
261 num_seq arity2 res_arity) |
353 num_seq arity2 res_arity) |
262 end |
354 end |
263 end) |
355 end) |
264 | _ => raise NOT_SUPPORTED ("term " ^ |
356 | _ => raise NOT_SUPPORTED ("term " ^ |
265 quote (Syntax.string_of_term ctxt t))) |
357 quote (Syntax.string_of_term ctxt t))) |
266 handle SAME () => R_rep_from_S_rep (fastype_of1 (Ts, t)) (to_S_rep Ts t) |
358 handle SAME () => R_rep_from_S_rep (fastype_of1 (Ts, t)) (to_S_rep Ts t) |
267 in to_F [] end |
359 in to_F (if total then NONE else SOME true) [] end |
268 |
360 |
269 fun bound_for_free card i (s, T) = |
361 fun bound_for_free total card i (s, T) = |
270 let val js = atom_schema_of R_Rep card T in |
362 let val js = atom_schema_of (R_Rep total) card T in |
271 ([((length js, i), s)], |
363 ([((length js, i), s)], |
272 [TupleSet [], atom_schema_of R_Rep card T |> map (rpair 0) |
364 [TupleSet [], atom_schema_of (R_Rep total) card T |> map (rpair 0) |
273 |> tuple_set_from_atom_schema]) |
365 |> tuple_set_from_atom_schema]) |
274 end |
366 end |
275 |
367 |
276 fun declarative_axiom_for_rel_expr card Ts (Type (@{type_name fun}, [T1, T2])) |
368 fun declarative_axiom_for_rel_expr total card Ts |
277 r = |
369 (Type (@{type_name fun}, [T1, T2])) r = |
278 if body_type T2 = bool_T then |
370 if total andalso body_type T2 = bool_T then |
279 True |
371 True |
280 else |
372 else |
281 All (decls_for S_Rep card Ts T1, |
373 All (decls_for S_Rep card Ts T1, |
282 declarative_axiom_for_rel_expr card (T1 :: Ts) T2 |
374 declarative_axiom_for_rel_expr total card (T1 :: Ts) T2 |
283 (List.foldl Join r (vars_for_bound_var card S_Rep (T1 :: Ts) 0))) |
375 (List.foldl Join r (vars_for_bound_var card S_Rep (T1 :: Ts) 0))) |
284 | declarative_axiom_for_rel_expr _ _ _ r = One r |
376 | declarative_axiom_for_rel_expr total _ _ _ r = |
285 fun declarative_axiom_for_free card i (_, T) = |
377 (if total then One else Lone) r |
286 declarative_axiom_for_rel_expr card [] T (Rel (arity_of R_Rep card T, i)) |
378 fun declarative_axiom_for_free total card i (_, T) = |
287 |
379 declarative_axiom_for_rel_expr total card [] T |
288 fun kodkod_problem_from_term ctxt raw_card t = |
380 (Rel (arity_of (R_Rep total) card T, i)) |
|
381 |
|
382 fun kodkod_problem_from_term ctxt total raw_card raw_infinite t = |
289 let |
383 let |
290 val thy = ProofContext.theory_of ctxt |
384 val thy = ProofContext.theory_of ctxt |
291 fun card (Type (@{type_name fun}, [T1, T2])) = |
385 fun card (Type (@{type_name fun}, [T1, T2])) = |
292 reasonable_power (card T2) (card T1) |
386 reasonable_power (card T2) (card T1) |
293 | card (Type (@{type_name prod}, [T1, T2])) = card T1 * card T2 |
387 | card (Type (@{type_name prod}, [T1, T2])) = card T1 * card T2 |
294 | card @{typ bool} = 2 |
388 | card @{typ bool} = 2 |
295 | card T = Int.max (1, raw_card T) |
389 | card T = Int.max (1, raw_card T) |
|
390 fun complete (Type (@{type_name fun}, [T1, T2])) = |
|
391 concrete T1 andalso complete T2 |
|
392 | complete (Type (@{type_name prod}, Ts)) = forall complete Ts |
|
393 | complete T = not (raw_infinite T) |
|
394 and concrete (Type (@{type_name fun}, [T1, T2])) = |
|
395 complete T1 andalso concrete T2 |
|
396 | concrete (Type (@{type_name prod}, Ts)) = forall concrete Ts |
|
397 | concrete _ = true |
296 val neg_t = @{const Not} $ Object_Logic.atomize_term thy t |
398 val neg_t = @{const Not} $ Object_Logic.atomize_term thy t |
297 val _ = fold_types (K o check_type ctxt) neg_t () |
399 val _ = fold_types (K o check_type ctxt raw_infinite) neg_t () |
298 val frees = Term.add_frees neg_t [] |
400 val frees = Term.add_frees neg_t [] |
299 val bounds = map2 (bound_for_free card) (index_seq 0 (length frees)) frees |
401 val bounds = |
|
402 map2 (bound_for_free total card) (index_seq 0 (length frees)) frees |
300 val declarative_axioms = |
403 val declarative_axioms = |
301 map2 (declarative_axiom_for_free card) (index_seq 0 (length frees)) frees |
404 map2 (declarative_axiom_for_free total card) |
302 val formula = kodkod_formula_from_term ctxt card frees neg_t |
405 (index_seq 0 (length frees)) frees |
303 |> fold_rev (curry And) declarative_axioms |
406 val formula = |
|
407 neg_t |> kodkod_formula_from_term ctxt total card complete concrete frees |
|
408 |> fold_rev (curry And) declarative_axioms |
304 val univ_card = univ_card 0 0 0 bounds formula |
409 val univ_card = univ_card 0 0 0 bounds formula |
305 in |
410 in |
306 {comment = "", settings = [], univ_card = univ_card, tuple_assigns = [], |
411 {comment = "", settings = [], univ_card = univ_card, tuple_assigns = [], |
307 bounds = bounds, int_bounds = [], expr_assigns = [], formula = formula} |
412 bounds = bounds, int_bounds = [], expr_assigns = [], formula = formula} |
308 end |
413 end |