src/HOL/ex/Reflected_Presburger.thy
changeset 21404 eb85850d3eb7
parent 21256 47195501ecf7
child 23274 f997514ad8f4
equal deleted inserted replaced
21403:dd58f13a8eb4 21404:eb85850d3eb7
   528 "islintn (n0, Cst i) = True"
   528 "islintn (n0, Cst i) = True"
   529 "islintn (n0, Add (Mult (Cst i) (Var n)) r) = (i \<noteq> 0 \<and> n0 \<le> n \<and> islintn (n+1,r))"
   529 "islintn (n0, Add (Mult (Cst i) (Var n)) r) = (i \<noteq> 0 \<and> n0 \<le> n \<and> islintn (n+1,r))"
   530 "islintn (n0, t) = False"
   530 "islintn (n0, t) = False"
   531 
   531 
   532 definition
   532 definition
   533   islint :: "intterm \<Rightarrow> bool"
   533   islint :: "intterm \<Rightarrow> bool" where
   534   "islint t = islintn(0,t)"
   534   "islint t = islintn(0,t)"
   535 
   535 
   536 (* And the equivalence to the first definition *)
   536 (* And the equivalence to the first definition *)
   537 lemma islinintterm_eq_islint: "islinintterm t = islint t"
   537 lemma islinintterm_eq_islint: "islinintterm t = islint t"
   538   using islint_def
   538   using islint_def
   728   "\<And> m. islintn(m,t) \<Longrightarrow> islintn(m,lin_mul(l,t))"
   728   "\<And> m. islintn(m,t) \<Longrightarrow> islintn(m,lin_mul(l,t))"
   729   by (induct l t rule: lin_mul.induct) simp_all
   729   by (induct l t rule: lin_mul.induct) simp_all
   730 
   730 
   731 (* lin_neg neagtes a linear term *)
   731 (* lin_neg neagtes a linear term *)
   732 definition
   732 definition
   733   lin_neg :: "intterm \<Rightarrow> intterm"
   733   lin_neg :: "intterm \<Rightarrow> intterm" where
   734   "lin_neg i = lin_mul ((-1::int),i)"
   734   "lin_neg i = lin_mul ((-1::int),i)"
   735 
   735 
   736 (* lin_neg has the semantics of Neg *)
   736 (* lin_neg has the semantics of Neg *)
   737 lemma lin_neg_corr:
   737 lemma lin_neg_corr:
   738   assumes lint: "islinintterm  t"
   738   assumes lint: "islinintterm  t"
  1623 using linform_isqfree linform_lin 
  1623 using linform_isqfree linform_lin 
  1624 by simp
  1624 by simp
  1625 
  1625 
  1626 (* Definitions and lemmas about gcd and lcm *)
  1626 (* Definitions and lemmas about gcd and lcm *)
  1627 definition
  1627 definition
  1628   lcm :: "nat \<times> nat \<Rightarrow> nat"
  1628   lcm :: "nat \<times> nat \<Rightarrow> nat" where
  1629   "lcm = (\<lambda>(m,n). m*n div gcd(m,n))"
  1629   "lcm = (\<lambda>(m,n). m*n div gcd(m,n))"
  1630 
  1630 
  1631 definition
  1631 definition
  1632   ilcm :: "int \<Rightarrow> int \<Rightarrow> int"
  1632   ilcm :: "int \<Rightarrow> int \<Rightarrow> int" where
  1633   "ilcm = (\<lambda>i.\<lambda>j. int (lcm(nat(abs i),nat(abs j))))"
  1633   "ilcm = (\<lambda>i.\<lambda>j. int (lcm(nat(abs i),nat(abs j))))"
  1634 
  1634 
  1635 (* ilcm_dvd12 are needed later *)
  1635 (* ilcm_dvd12 are needed later *)
  1636 lemma lcm_dvd1: 
  1636 lemma lcm_dvd1: 
  1637   assumes mpos: " m >0"
  1637   assumes mpos: " m >0"
  1877 "adjustcoeff (l,p) = p"
  1877 "adjustcoeff (l,p) = p"
  1878 
  1878 
  1879 
  1879 
  1880 (* unitycoeff expects a quantifier free formula an transforms it to an equivalent formula where the bound variable occurs only with coeffitient 1  or -1 *)
  1880 (* unitycoeff expects a quantifier free formula an transforms it to an equivalent formula where the bound variable occurs only with coeffitient 1  or -1 *)
  1881 definition
  1881 definition
  1882   unitycoeff :: "QF \<Rightarrow> QF"
  1882   unitycoeff :: "QF \<Rightarrow> QF" where
  1883   "unitycoeff p =
  1883   "unitycoeff p =
  1884   (let l = formlcm p;
  1884   (let l = formlcm p;
  1885        p' = adjustcoeff (l,p)
  1885        p' = adjustcoeff (l,p)
  1886    in (if l=1 then p' else 
  1886    in (if l=1 then p' else 
  1887       (And (Divides (Cst l) (Add (Mult (Cst 1) (Var 0)) (Cst 0))) p')))"
  1887       (And (Divides (Cst l) (Add (Mult (Cst 1) (Var 0)) (Cst 0))) p')))"
  5089 by (cases f, auto) (cases g, auto)+
  5089 by (cases f, auto) (cases g, auto)+
  5090 
  5090 
  5091 
  5091 
  5092 (* An implementation of sets trough lists *)
  5092 (* An implementation of sets trough lists *)
  5093 definition
  5093 definition
  5094   list_insert :: "'a \<Rightarrow> 'a list \<Rightarrow> 'a list"
  5094   list_insert :: "'a \<Rightarrow> 'a list \<Rightarrow> 'a list" where
  5095   "list_insert x xs = (if x mem xs then xs else x#xs)"
  5095   "list_insert x xs = (if x mem xs then xs else x#xs)"
  5096 
  5096 
  5097 lemma list_insert_set: "set (list_insert x xs) = set (x#xs)"
  5097 lemma list_insert_set: "set (list_insert x xs) = set (x#xs)"
  5098 by(induct xs) (auto simp add: list_insert_def)
  5098 by(induct xs) (auto simp add: list_insert_def)
  5099 
  5099 
  5366 qed
  5366 qed
  5367 
  5367 
  5368 (* An implementation of cooper's method for both plus/minus/infinity *)
  5368 (* An implementation of cooper's method for both plus/minus/infinity *)
  5369 
  5369 
  5370 (* unify the formula *)
  5370 (* unify the formula *)
  5371 definition unify:: "QF \<Rightarrow> (QF \<times> intterm list)"
  5371 definition unify:: "QF \<Rightarrow> (QF \<times> intterm list)" where
  5372   "unify p =
  5372   "unify p =
  5373   (let q = unitycoeff p;
  5373   (let q = unitycoeff p;
  5374        B = list_set(bset q);
  5374        B = list_set(bset q);
  5375        A = list_set (aset q)
  5375        A = list_set (aset q)
  5376   in
  5376   in
  5482   from explode_minf_corr2[OF unifq bst] unify_ex[OF linp] show ?thesis
  5482   from explode_minf_corr2[OF unifq bst] unify_ex[OF linp] show ?thesis
  5483     using qB_def by simp
  5483     using qB_def by simp
  5484 qed
  5484 qed
  5485 (* An implementation of cooper's method *)
  5485 (* An implementation of cooper's method *)
  5486 definition
  5486 definition
  5487   cooper:: "QF \<Rightarrow> QF option"
  5487   cooper:: "QF \<Rightarrow> QF option" where
  5488   "cooper p = lift_un (\<lambda>q. decrvars(explode_minf (unify q))) (linform (nnf p))"
  5488   "cooper p = lift_un (\<lambda>q. decrvars(explode_minf (unify q))) (linform (nnf p))"
  5489 
  5489 
  5490 (* cooper eliminates quantifiers *)
  5490 (* cooper eliminates quantifiers *)
  5491 lemma cooper_qfree: "(\<And> q q'. \<lbrakk>isqfree q ; cooper q = Some q'\<rbrakk> \<Longrightarrow>  isqfree q')"
  5491 lemma cooper_qfree: "(\<And> q q'. \<lbrakk>isqfree q ; cooper q = Some q'\<rbrakk> \<Longrightarrow>  isqfree q')"
  5492 proof-
  5492 proof-
  5536   show "?P ats (QEx q) = ?P ats q'" by simp
  5536   show "?P ats (QEx q) = ?P ats q'" by simp
  5537 qed  
  5537 qed  
  5538 
  5538 
  5539 (* A decision procedure for Presburger Arithmetics *)
  5539 (* A decision procedure for Presburger Arithmetics *)
  5540 definition
  5540 definition
  5541   pa:: "QF \<Rightarrow> QF option"
  5541   pa:: "QF \<Rightarrow> QF option" where
  5542   "pa p \<equiv> lift_un psimpl (qelim(cooper, p))"
  5542   "pa p \<equiv> lift_un psimpl (qelim(cooper, p))"
  5543 
  5543 
  5544 lemma psimpl_qfree: "isqfree p \<Longrightarrow> isqfree (psimpl p)"
  5544 lemma psimpl_qfree: "isqfree p \<Longrightarrow> isqfree (psimpl p)"
  5545 apply(induct p rule: isqfree.induct)
  5545 apply(induct p rule: isqfree.induct)
  5546 apply(auto simp add: Let_def)
  5546 apply(auto simp add: Let_def)