49 nested_maps: thm list, |
49 nested_maps: thm list, |
50 nested_map_idents: thm list, |
50 nested_map_idents: thm list, |
51 nested_map_comps: thm list, |
51 nested_map_comps: thm list, |
52 ctr_specs: corec_ctr_spec list} |
52 ctr_specs: corec_ctr_spec list} |
53 |
53 |
54 val mk_conjs: term list -> term |
|
55 val mk_disjs: term list -> term |
|
56 val s_not: term -> term |
54 val s_not: term -> term |
57 val s_not_conj: term list -> term list |
55 val s_not_conj: term list -> term list |
|
56 val s_conjs: term list -> term |
|
57 val s_disjs: term list -> term |
|
58 val s_dnf: term list list -> term list |
58 |
59 |
59 val massage_indirect_rec_call: Proof.context -> (term -> bool) -> (typ -> typ -> term -> term) -> |
60 val massage_indirect_rec_call: Proof.context -> (term -> bool) -> (typ -> typ -> term -> term) -> |
60 typ list -> term -> term -> term -> term |
61 typ list -> term -> term -> term -> term |
61 val massage_direct_corec_call: Proof.context -> (term -> bool) -> (typ list -> term -> term) -> |
62 val massage_direct_corec_call: Proof.context -> (term -> bool) -> (typ list -> term -> term) -> |
62 typ list -> term -> term |
63 typ list -> term -> term |
158 | s_not (@{const disj} $ t $ u) = @{const conj} $ s_not t $ s_not u |
159 | s_not (@{const disj} $ t $ u) = @{const conj} $ s_not t $ s_not u |
159 | s_not (@{const implies} $ t $ u) = @{const conj} $ t $ s_not u |
160 | s_not (@{const implies} $ t $ u) = @{const conj} $ t $ s_not u |
160 | s_not t = @{const Not} $ t; |
161 | s_not t = @{const Not} $ t; |
161 |
162 |
162 val s_not_conj = conjuncts_s o s_not o mk_conjs; |
163 val s_not_conj = conjuncts_s o s_not o mk_conjs; |
|
164 |
|
165 fun s_conj c @{const True} = c |
|
166 | s_conj c d = HOLogic.mk_conj (c, d); |
|
167 |
|
168 fun propagate_unit_pos u cs = if member (op aconv) cs u then [@{const False}] else cs; |
|
169 |
|
170 fun propagate_unit_neg not_u cs = remove (op aconv) not_u cs; |
|
171 |
|
172 fun propagate_units css = |
|
173 (case List.partition (can the_single) css of |
|
174 ([], _) => css |
|
175 | ([u] :: uss, css') => |
|
176 [u] :: propagate_units (map (propagate_unit_neg (s_not u)) |
|
177 (map (propagate_unit_pos u) (uss @ css')))); |
|
178 |
|
179 fun s_conjs cs = |
|
180 if member (op aconv) cs @{const False} then @{const False} |
|
181 else mk_conjs (remove (op aconv) @{const True} cs); |
|
182 |
|
183 fun s_disjs ds = |
|
184 if member (op aconv) ds @{const True} then @{const True} |
|
185 else mk_disjs (remove (op aconv) @{const False} ds); |
|
186 |
|
187 fun s_dnf css0 = |
|
188 let val css = propagate_units css0 in |
|
189 if null css then |
|
190 [@{const False}] |
|
191 else if exists null css then |
|
192 [] |
|
193 else |
|
194 map (fn c :: cs => (c, cs)) css |
|
195 |> AList.coalesce (op =) |
|
196 |> map (fn (c, css) => c :: s_dnf css) |
|
197 |> (fn [cs] => cs | css => [s_disjs (map s_conjs css)]) |
|
198 end; |
163 |
199 |
164 fun factor_out_types ctxt massage destU U T = |
200 fun factor_out_types ctxt massage destU U T = |
165 (case try destU U of |
201 (case try destU U of |
166 SOME (U1, U2) => if U1 = T then massage T U2 else invalid_map ctxt |
202 SOME (U1, U2) => if U1 = T then massage T U2 else invalid_map ctxt |
167 | NONE => invalid_map ctxt); |
203 | NONE => invalid_map ctxt); |