src/HOL/Integ/presburger.ML
changeset 15570 8d8c70b41bab
parent 15531 08c8dad8e399
child 15574 b1d1b5bfc464
equal deleted inserted replaced
15569:1b3115d1a8df 15570:8d8c70b41bab
   146 fun getfuncs fm = case strip_comb fm of
   146 fun getfuncs fm = case strip_comb fm of
   147     (Free (_, T), ts as _ :: _) =>
   147     (Free (_, T), ts as _ :: _) =>
   148       if body_type T mem [iT, nT] 
   148       if body_type T mem [iT, nT] 
   149          andalso not (ts = []) andalso forall (null o loose_bnos) ts 
   149          andalso not (ts = []) andalso forall (null o loose_bnos) ts 
   150       then [fm]
   150       then [fm]
   151       else foldl op union ([], map getfuncs ts)
   151       else Library.foldl op union ([], map getfuncs ts)
   152   | (Var (_, T), ts as _ :: _) =>
   152   | (Var (_, T), ts as _ :: _) =>
   153       if body_type T mem [iT, nT] 
   153       if body_type T mem [iT, nT] 
   154          andalso not (ts = []) andalso forall (null o loose_bnos) ts then [fm]
   154          andalso not (ts = []) andalso forall (null o loose_bnos) ts then [fm]
   155       else foldl op union ([], map getfuncs ts)
   155       else Library.foldl op union ([], map getfuncs ts)
   156   | (Const (s, T), ts) =>
   156   | (Const (s, T), ts) =>
   157       if (s, T) mem allowed_consts orelse not (body_type T mem [iT, nT])
   157       if (s, T) mem allowed_consts orelse not (body_type T mem [iT, nT])
   158       then foldl op union ([], map getfuncs ts)
   158       then Library.foldl op union ([], map getfuncs ts)
   159       else [fm]
   159       else [fm]
   160   | (Abs (s, T, t), _) => getfuncs t
   160   | (Abs (s, T, t), _) => getfuncs t
   161   | _ => [];
   161   | _ => [];
   162 
   162 
   163 
   163 
   164 fun abstract_pres sg fm = 
   164 fun abstract_pres sg fm = 
   165   foldr (fn (t, u) =>
   165   Library.foldr (fn (t, u) =>
   166       let val T = fastype_of t
   166       let val T = fastype_of t
   167       in all T $ Abs ("x", T, abstract_over (t, u)) end)
   167       in all T $ Abs ("x", T, abstract_over (t, u)) end)
   168          (getfuncs fm, fm);
   168          (getfuncs fm, fm);
   169 
   169 
   170 
   170 
   196  variables. Whenever this function will be used, it will be ensured that t 
   196  variables. Whenever this function will be used, it will be ensured that t 
   197  will not contain subterms with function symbols that could have been 
   197  will not contain subterms with function symbols that could have been 
   198  abstracted over.*)
   198  abstracted over.*)
   199  
   199  
   200 fun relevant ps t = (term_typed_consts t) subset allowed_consts andalso 
   200 fun relevant ps t = (term_typed_consts t) subset allowed_consts andalso 
   201   map (fn i => snd (nth_elem (i, ps))) (loose_bnos t) @
   201   map (fn i => snd (List.nth (ps, i))) (loose_bnos t) @
   202   map (snd o dest_Free) (term_frees t) @ map (snd o dest_Var) (term_vars t)
   202   map (snd o dest_Free) (term_frees t) @ map (snd o dest_Var) (term_vars t)
   203   subset [iT, nT]
   203   subset [iT, nT]
   204   andalso not (has_free_funcs t);
   204   andalso not (has_free_funcs t);
   205 
   205 
   206 
   206 
   215     fun mk_all ((s, T), (P,n)) =
   215     fun mk_all ((s, T), (P,n)) =
   216       if 0 mem loose_bnos P then
   216       if 0 mem loose_bnos P then
   217         (HOLogic.all_const T $ Abs (s, T, P), n)
   217         (HOLogic.all_const T $ Abs (s, T, P), n)
   218       else (incr_boundvars ~1 P, n-1)
   218       else (incr_boundvars ~1 P, n-1)
   219     fun mk_all2 (v, t) = HOLogic.all_const (fastype_of v) $ lambda v t;
   219     fun mk_all2 (v, t) = HOLogic.all_const (fastype_of v) $ lambda v t;
   220     val (rhs,irhs) = partition (relevant (rev ps)) hs
   220     val (rhs,irhs) = List.partition (relevant (rev ps)) hs
   221     val np = length ps
   221     val np = length ps
   222     val (fm',np) =  foldr (fn ((x, T), (fm,n)) => mk_all ((x, T), (fm,n)))
   222     val (fm',np) =  Library.foldr (fn ((x, T), (fm,n)) => mk_all ((x, T), (fm,n)))
   223       (ps,(foldr HOLogic.mk_imp (rhs, c), np))
   223       (ps,(Library.foldr HOLogic.mk_imp (rhs, c), np))
   224     val (vs, _) = partition (fn t => q orelse (type_of t) = nT)
   224     val (vs, _) = List.partition (fn t => q orelse (type_of t) = nT)
   225       (term_frees fm' @ term_vars fm');
   225       (term_frees fm' @ term_vars fm');
   226     val fm2 = foldr mk_all2 (vs, fm')
   226     val fm2 = Library.foldr mk_all2 (vs, fm')
   227   in (fm2, np + length vs, length rhs) end;
   227   in (fm2, np + length vs, length rhs) end;
   228 
   228 
   229 (*Object quantifier to meta --*)
   229 (*Object quantifier to meta --*)
   230 fun spec_step n th = if (n=0) then th else (spec_step (n-1) th) RS spec ;
   230 fun spec_step n th = if (n=0) then th else (spec_step (n-1) th) RS spec ;
   231 
   231 
   298          Args.$$$ "no_quantify" >> K (apfst (K false))
   298          Args.$$$ "no_quantify" >> K (apfst (K false))
   299       || Args.$$$ "abs" >> K (apsnd (K true));
   299       || Args.$$$ "abs" >> K (apsnd (K true));
   300  in
   300  in
   301    Method.simple_args 
   301    Method.simple_args 
   302   (Scan.optional (Args.$$$ "(" |-- Scan.repeat1 parse_flag --| Args.$$$ ")") [] >>
   302   (Scan.optional (Args.$$$ "(" |-- Scan.repeat1 parse_flag --| Args.$$$ ")") [] >>
   303     curry (foldl op |>) (true, false))
   303     curry (Library.foldl op |>) (true, false))
   304     (fn (q,a) => fn _ => meth q a 1)
   304     (fn (q,a) => fn _ => meth q a 1)
   305   end;
   305   end;
   306 
   306 
   307 fun presburger_method q a i = Method.METHOD (fn facts =>
   307 fun presburger_method q a i = Method.METHOD (fn facts =>
   308   Method.insert_tac facts 1 THEN presburger_tac q a i)
   308   Method.insert_tac facts 1 THEN presburger_tac q a i)