166 |
166 |
167 |
167 |
168 (** eta-expand quantifiers, let expressions and built-ins *) |
168 (** eta-expand quantifiers, let expressions and built-ins *) |
169 |
169 |
170 local |
170 local |
171 fun eta T t = Abs (Name.uu, T, Term.incr_boundvars 1 t $ Bound 0) |
171 fun eta f T t = Abs (Name.uu, T, f (Term.incr_boundvars 1 t $ Bound 0)) |
172 |
172 |
173 fun exp T = eta (Term.domain_type (Term.domain_type T)) |
173 fun exp f T = eta f (Term.domain_type (Term.domain_type T)) |
174 |
174 |
175 fun exp2 T q = |
175 fun exp2 T q = |
176 let val U = Term.domain_type T |
176 let val U = Term.domain_type T |
177 in Abs (Name.uu, U, q $ eta (Term.domain_type U) (Bound 0)) end |
177 in Abs (Name.uu, U, q $ eta I (Term.domain_type U) (Bound 0)) end |
178 |
178 |
179 fun exp2' T l = |
179 fun exp2' T l = |
180 let val (U1, U2) = Term.dest_funT T ||> Term.domain_type |
180 let val (U1, U2) = Term.dest_funT T ||> Term.domain_type |
181 in Abs (Name.uu, U1, eta U2 (l $ Bound 0)) end |
181 in Abs (Name.uu, U1, eta I U2 (l $ Bound 0)) end |
182 |
182 |
183 fun expf k i T t = |
183 fun expf k i T t = |
184 let val Ts = drop i (fst (SMT_Utils.dest_funT k T)) |
184 let val Ts = drop i (fst (SMT_Utils.dest_funT k T)) |
185 in |
185 in |
186 Term.incr_boundvars (length Ts) t |
186 Term.incr_boundvars (length Ts) t |
187 |> fold_index (fn (i, _) => fn u => u $ Bound i) Ts |
187 |> fold_index (fn (i, _) => fn u => u $ Bound i) Ts |
188 |> fold_rev (fn T => fn u => Abs (Name.uu, T, u)) Ts |
188 |> fold_rev (fn T => fn u => Abs (Name.uu, T, u)) Ts |
189 end |
189 end |
190 in |
190 in |
191 |
191 |
192 fun eta_expand ctxt funcs = |
192 fun eta_expand ctxt is_fol funcs = |
193 let |
193 let |
194 fun exp_func t T ts = |
194 fun exp_func t T ts = |
195 (case Termtab.lookup funcs t of |
195 (case Termtab.lookup funcs t of |
196 SOME k => |
196 SOME k => |
197 Term.list_comb (t, ts) |
197 Term.list_comb (t, ts) |
198 |> k <> length ts ? expf k (length ts) T |
198 |> k <> length ts ? expf k (length ts) T |
199 | NONE => Term.list_comb (t, ts)) |
199 | NONE => Term.list_comb (t, ts)) |
200 |
200 |
201 fun expand ((q as Const (@{const_name All}, _)) $ Abs a) = q $ abs_expand a |
201 fun expand ((q as Const (@{const_name All}, _)) $ Abs a) = q $ abs_expand a |
202 | expand ((q as Const (@{const_name All}, T)) $ t) = q $ exp T t |
202 | expand ((q as Const (@{const_name All}, T)) $ t) = q $ exp expand T t |
203 | expand (q as Const (@{const_name All}, T)) = exp2 T q |
203 | expand (q as Const (@{const_name All}, T)) = exp2 T q |
204 | expand ((q as Const (@{const_name Ex}, _)) $ Abs a) = q $ abs_expand a |
204 | expand ((q as Const (@{const_name Ex}, _)) $ Abs a) = q $ abs_expand a |
205 | expand ((q as Const (@{const_name Ex}, T)) $ t) = q $ exp T t |
205 | expand ((q as Const (@{const_name Ex}, T)) $ t) = q $ exp expand T t |
206 | expand (q as Const (@{const_name Ex}, T)) = exp2 T q |
206 | expand (q as Const (@{const_name Ex}, T)) = exp2 T q |
207 | expand ((l as Const (@{const_name Let}, _)) $ t $ Abs a) = |
207 | expand ((l as Const (@{const_name Let}, _)) $ t $ Abs a) = |
208 l $ expand t $ abs_expand a |
208 if is_fol then expand (Term.betapply (Abs a, t)) |
|
209 else l $ expand t $ abs_expand a |
209 | expand ((l as Const (@{const_name Let}, T)) $ t $ u) = |
210 | expand ((l as Const (@{const_name Let}, T)) $ t $ u) = |
210 l $ expand t $ exp (Term.range_type T) u |
211 if is_fol then expand (u $ t) |
|
212 else l $ expand t $ exp expand (Term.range_type T) u |
211 | expand ((l as Const (@{const_name Let}, T)) $ t) = |
213 | expand ((l as Const (@{const_name Let}, T)) $ t) = |
212 exp2 T (l $ expand t) |
214 if is_fol then |
213 | expand (l as Const (@{const_name Let}, T)) = exp2' T l |
215 let val U = Term.domain_type (Term.range_type T) |
|
216 in Abs (Name.uu, U, Bound 0 $ Term.incr_boundvars 1 t) end |
|
217 else exp2 T (l $ expand t) |
|
218 | expand (l as Const (@{const_name Let}, T)) = |
|
219 if is_fol then |
|
220 let val U = Term.domain_type (Term.range_type T) |
|
221 in |
|
222 Abs (Name.uu, Term.domain_type T, Abs (Name.uu, U, |
|
223 Bound 0 $ Bound 1)) |
|
224 end |
|
225 else exp2' T l |
214 | expand t = |
226 | expand t = |
215 (case Term.strip_comb t of |
227 (case Term.strip_comb t of |
216 (u as Const (c as (_, T)), ts) => |
228 (u as Const (c as (_, T)), ts) => |
217 (case SMT_Builtin.dest_builtin ctxt c ts of |
229 (case SMT_Builtin.dest_builtin ctxt c ts of |
218 SOME (_, k, us, mk) => |
230 SOME (_, k, us, mk) => |
361 mk_meta_eq @{thm SMT.term_true_def}, |
373 mk_meta_eq @{thm SMT.term_true_def}, |
362 mk_meta_eq @{thm SMT.term_false_def}, |
374 mk_meta_eq @{thm SMT.term_false_def}, |
363 @{lemma "P = True == P" by (rule eq_reflection) simp}, |
375 @{lemma "P = True == P" by (rule eq_reflection) simp}, |
364 @{lemma "if P then True else False == P" by (rule eq_reflection) simp}] |
376 @{lemma "if P then True else False == P" by (rule eq_reflection) simp}] |
365 |
377 |
366 fun reduce_let (Const (@{const_name Let}, _) $ t $ u) = |
|
367 reduce_let (Term.betapply (u, t)) |
|
368 | reduce_let (t $ u) = reduce_let t $ reduce_let u |
|
369 | reduce_let (Abs (n, T, t)) = Abs (n, T, reduce_let t) |
|
370 | reduce_let t = t |
|
371 |
|
372 fun as_term t = @{const HOL.eq (bool)} $ t $ @{const SMT.term_true} |
378 fun as_term t = @{const HOL.eq (bool)} $ t $ @{const SMT.term_true} |
373 |
379 |
374 fun wrap_in_if t = |
380 fun wrap_in_if t = |
375 @{const If (bool)} $ t $ @{const SMT.term_true} $ @{const SMT.term_false} |
381 @{const If (bool)} $ t $ @{const SMT.term_true} $ @{const SMT.term_false} |
376 |
382 |