src/HOL/Decision_Procs/Cooper.thy
changeset 55981 66739f41d5b2
parent 55964 acdde1a5faa0
child 55999 6477fc70cfa0
equal deleted inserted replaced
55980:36fd4981c119 55981:66739f41d5b2
    60 lemma fmsize_pos: "fmsize p > 0"
    60 lemma fmsize_pos: "fmsize p > 0"
    61   by (induct p rule: fmsize.induct) simp_all
    61   by (induct p rule: fmsize.induct) simp_all
    62 
    62 
    63 primrec Ifm :: "bool list \<Rightarrow> int list \<Rightarrow> fm \<Rightarrow> bool"  -- {* Semantics of formulae (fm) *}
    63 primrec Ifm :: "bool list \<Rightarrow> int list \<Rightarrow> fm \<Rightarrow> bool"  -- {* Semantics of formulae (fm) *}
    64 where
    64 where
    65   "Ifm bbs bs T = True"
    65   "Ifm bbs bs T \<longleftrightarrow> True"
    66 | "Ifm bbs bs F = False"
    66 | "Ifm bbs bs F \<longleftrightarrow> False"
    67 | "Ifm bbs bs (Lt a) = (Inum bs a < 0)"
    67 | "Ifm bbs bs (Lt a) \<longleftrightarrow> Inum bs a < 0"
    68 | "Ifm bbs bs (Gt a) = (Inum bs a > 0)"
    68 | "Ifm bbs bs (Gt a) \<longleftrightarrow> Inum bs a > 0"
    69 | "Ifm bbs bs (Le a) = (Inum bs a \<le> 0)"
    69 | "Ifm bbs bs (Le a) \<longleftrightarrow> Inum bs a \<le> 0"
    70 | "Ifm bbs bs (Ge a) = (Inum bs a \<ge> 0)"
    70 | "Ifm bbs bs (Ge a) \<longleftrightarrow> Inum bs a \<ge> 0"
    71 | "Ifm bbs bs (Eq a) = (Inum bs a = 0)"
    71 | "Ifm bbs bs (Eq a) \<longleftrightarrow> Inum bs a = 0"
    72 | "Ifm bbs bs (NEq a) = (Inum bs a \<noteq> 0)"
    72 | "Ifm bbs bs (NEq a) \<longleftrightarrow> Inum bs a \<noteq> 0"
    73 | "Ifm bbs bs (Dvd i b) = (i dvd Inum bs b)"
    73 | "Ifm bbs bs (Dvd i b) \<longleftrightarrow> i dvd Inum bs b"
    74 | "Ifm bbs bs (NDvd i b) = (\<not>(i dvd Inum bs b))"
    74 | "Ifm bbs bs (NDvd i b) \<longleftrightarrow> \<not> i dvd Inum bs b"
    75 | "Ifm bbs bs (NOT p) = (\<not> (Ifm bbs bs p))"
    75 | "Ifm bbs bs (NOT p) \<longleftrightarrow> \<not> Ifm bbs bs p"
    76 | "Ifm bbs bs (And p q) = (Ifm bbs bs p \<and> Ifm bbs bs q)"
    76 | "Ifm bbs bs (And p q) \<longleftrightarrow> Ifm bbs bs p \<and> Ifm bbs bs q"
    77 | "Ifm bbs bs (Or p q) = (Ifm bbs bs p \<or> Ifm bbs bs q)"
    77 | "Ifm bbs bs (Or p q) \<longleftrightarrow> Ifm bbs bs p \<or> Ifm bbs bs q"
    78 | "Ifm bbs bs (Imp p q) = ((Ifm bbs bs p) \<longrightarrow> (Ifm bbs bs q))"
    78 | "Ifm bbs bs (Imp p q) \<longleftrightarrow> (Ifm bbs bs p \<longrightarrow> Ifm bbs bs q)"
    79 | "Ifm bbs bs (Iff p q) = (Ifm bbs bs p = Ifm bbs bs q)"
    79 | "Ifm bbs bs (Iff p q) \<longleftrightarrow> Ifm bbs bs p = Ifm bbs bs q"
    80 | "Ifm bbs bs (E p) = (\<exists>x. Ifm bbs (x#bs) p)"
    80 | "Ifm bbs bs (E p) \<longleftrightarrow> (\<exists>x. Ifm bbs (x # bs) p)"
    81 | "Ifm bbs bs (A p) = (\<forall>x. Ifm bbs (x#bs) p)"
    81 | "Ifm bbs bs (A p) \<longleftrightarrow> (\<forall>x. Ifm bbs (x # bs) p)"
    82 | "Ifm bbs bs (Closed n) = bbs!n"
    82 | "Ifm bbs bs (Closed n) \<longleftrightarrow> bbs!n"
    83 | "Ifm bbs bs (NClosed n) = (\<not> bbs!n)"
    83 | "Ifm bbs bs (NClosed n) \<longleftrightarrow> \<not> bbs!n"
    84 
    84 
    85 consts prep :: "fm \<Rightarrow> fm"
    85 consts prep :: "fm \<Rightarrow> fm"
    86 recdef prep "measure fmsize"
    86 recdef prep "measure fmsize"
    87   "prep (E T) = T"
    87   "prep (E T) = T"
    88   "prep (E F) = F"
    88   "prep (E F) = F"
   127 
   127 
   128 text {* Boundedness and substitution *}
   128 text {* Boundedness and substitution *}
   129 
   129 
   130 primrec numbound0 :: "num \<Rightarrow> bool"  -- {* a num is INDEPENDENT of Bound 0 *}
   130 primrec numbound0 :: "num \<Rightarrow> bool"  -- {* a num is INDEPENDENT of Bound 0 *}
   131 where
   131 where
   132   "numbound0 (C c) = True"
   132   "numbound0 (C c) \<longleftrightarrow> True"
   133 | "numbound0 (Bound n) = (n>0)"
   133 | "numbound0 (Bound n) \<longleftrightarrow> n > 0"
   134 | "numbound0 (CN n i a) = (n >0 \<and> numbound0 a)"
   134 | "numbound0 (CN n i a) \<longleftrightarrow> n > 0 \<and> numbound0 a"
   135 | "numbound0 (Neg a) = numbound0 a"
   135 | "numbound0 (Neg a) \<longleftrightarrow> numbound0 a"
   136 | "numbound0 (Add a b) = (numbound0 a \<and> numbound0 b)"
   136 | "numbound0 (Add a b) \<longleftrightarrow> numbound0 a \<and> numbound0 b"
   137 | "numbound0 (Sub a b) = (numbound0 a \<and> numbound0 b)"
   137 | "numbound0 (Sub a b) \<longleftrightarrow> numbound0 a \<and> numbound0 b"
   138 | "numbound0 (Mul i a) = numbound0 a"
   138 | "numbound0 (Mul i a) \<longleftrightarrow> numbound0 a"
   139 
   139 
   140 lemma numbound0_I:
   140 lemma numbound0_I:
   141   assumes nb: "numbound0 a"
   141   assumes nb: "numbound0 a"
   142   shows "Inum (b#bs) a = Inum (b'#bs) a"
   142   shows "Inum (b # bs) a = Inum (b' # bs) a"
   143   using nb by (induct a rule: num.induct) (auto simp add: gr0_conv_Suc)
   143   using nb by (induct a rule: num.induct) (auto simp add: gr0_conv_Suc)
   144 
   144 
   145 primrec bound0 :: "fm \<Rightarrow> bool" -- {* A Formula is independent of Bound 0 *}
   145 primrec bound0 :: "fm \<Rightarrow> bool" -- {* A Formula is independent of Bound 0 *}
   146 where
   146 where
   147   "bound0 T = True"
   147   "bound0 T \<longleftrightarrow> True"
   148 | "bound0 F = True"
   148 | "bound0 F \<longleftrightarrow> True"
   149 | "bound0 (Lt a) = numbound0 a"
   149 | "bound0 (Lt a) \<longleftrightarrow> numbound0 a"
   150 | "bound0 (Le a) = numbound0 a"
   150 | "bound0 (Le a) \<longleftrightarrow> numbound0 a"
   151 | "bound0 (Gt a) = numbound0 a"
   151 | "bound0 (Gt a) \<longleftrightarrow> numbound0 a"
   152 | "bound0 (Ge a) = numbound0 a"
   152 | "bound0 (Ge a) \<longleftrightarrow> numbound0 a"
   153 | "bound0 (Eq a) = numbound0 a"
   153 | "bound0 (Eq a) \<longleftrightarrow> numbound0 a"
   154 | "bound0 (NEq a) = numbound0 a"
   154 | "bound0 (NEq a) \<longleftrightarrow> numbound0 a"
   155 | "bound0 (Dvd i a) = numbound0 a"
   155 | "bound0 (Dvd i a) \<longleftrightarrow> numbound0 a"
   156 | "bound0 (NDvd i a) = numbound0 a"
   156 | "bound0 (NDvd i a) \<longleftrightarrow> numbound0 a"
   157 | "bound0 (NOT p) = bound0 p"
   157 | "bound0 (NOT p) \<longleftrightarrow> bound0 p"
   158 | "bound0 (And p q) = (bound0 p \<and> bound0 q)"
   158 | "bound0 (And p q) \<longleftrightarrow> bound0 p \<and> bound0 q"
   159 | "bound0 (Or p q) = (bound0 p \<and> bound0 q)"
   159 | "bound0 (Or p q) \<longleftrightarrow> bound0 p \<and> bound0 q"
   160 | "bound0 (Imp p q) = ((bound0 p) \<and> (bound0 q))"
   160 | "bound0 (Imp p q) \<longleftrightarrow> bound0 p \<and> bound0 q"
   161 | "bound0 (Iff p q) = (bound0 p \<and> bound0 q)"
   161 | "bound0 (Iff p q) \<longleftrightarrow> bound0 p \<and> bound0 q"
   162 | "bound0 (E p) = False"
   162 | "bound0 (E p) \<longleftrightarrow> False"
   163 | "bound0 (A p) = False"
   163 | "bound0 (A p) \<longleftrightarrow> False"
   164 | "bound0 (Closed P) = True"
   164 | "bound0 (Closed P) \<longleftrightarrow> True"
   165 | "bound0 (NClosed P) = True"
   165 | "bound0 (NClosed P) \<longleftrightarrow> True"
   166 
   166 
   167 lemma bound0_I:
   167 lemma bound0_I:
   168   assumes bp: "bound0 p"
   168   assumes bp: "bound0 p"
   169   shows "Ifm bbs (b#bs) p = Ifm bbs (b'#bs) p"
   169   shows "Ifm bbs (b # bs) p = Ifm bbs (b' # bs) p"
   170   using bp numbound0_I[where b="b" and bs="bs" and b'="b'"]
   170   using bp numbound0_I[where b="b" and bs="bs" and b'="b'"]
   171   by (induct p rule: fm.induct) (auto simp add: gr0_conv_Suc)
   171   by (induct p rule: fm.induct) (auto simp add: gr0_conv_Suc)
   172 
   172 
   173 fun numsubst0 :: "num \<Rightarrow> num \<Rightarrow> num"
   173 fun numsubst0 :: "num \<Rightarrow> num \<Rightarrow> num"
   174 where
   174 where
   254 lemma decr_qf: "bound0 p \<Longrightarrow> qfree (decr p)"
   254 lemma decr_qf: "bound0 p \<Longrightarrow> qfree (decr p)"
   255   by (induct p) simp_all
   255   by (induct p) simp_all
   256 
   256 
   257 fun isatom :: "fm \<Rightarrow> bool"  -- {* test for atomicity *}
   257 fun isatom :: "fm \<Rightarrow> bool"  -- {* test for atomicity *}
   258 where
   258 where
   259   "isatom T = True"
   259   "isatom T \<longleftrightarrow> True"
   260 | "isatom F = True"
   260 | "isatom F \<longleftrightarrow> True"
   261 | "isatom (Lt a) = True"
   261 | "isatom (Lt a) \<longleftrightarrow> True"
   262 | "isatom (Le a) = True"
   262 | "isatom (Le a) \<longleftrightarrow> True"
   263 | "isatom (Gt a) = True"
   263 | "isatom (Gt a) \<longleftrightarrow> True"
   264 | "isatom (Ge a) = True"
   264 | "isatom (Ge a) \<longleftrightarrow> True"
   265 | "isatom (Eq a) = True"
   265 | "isatom (Eq a) \<longleftrightarrow> True"
   266 | "isatom (NEq a) = True"
   266 | "isatom (NEq a) \<longleftrightarrow> True"
   267 | "isatom (Dvd i b) = True"
   267 | "isatom (Dvd i b) \<longleftrightarrow> True"
   268 | "isatom (NDvd i b) = True"
   268 | "isatom (NDvd i b) \<longleftrightarrow> True"
   269 | "isatom (Closed P) = True"
   269 | "isatom (Closed P) \<longleftrightarrow> True"
   270 | "isatom (NClosed P) = True"
   270 | "isatom (NClosed P) \<longleftrightarrow> True"
   271 | "isatom p = False"
   271 | "isatom p \<longleftrightarrow> False"
   272 
   272 
   273 lemma numsubst0_numbound0:
   273 lemma numsubst0_numbound0:
   274   assumes "numbound0 t"
   274   assumes "numbound0 t"
   275   shows "numbound0 (numsubst0 t a)"
   275   shows "numbound0 (numsubst0 t a)"
   276   using assms
   276   using assms
   421 definition lex_bnd :: "num \<Rightarrow> num \<Rightarrow> bool"
   421 definition lex_bnd :: "num \<Rightarrow> num \<Rightarrow> bool"
   422   where "lex_bnd t s = lex_ns (bnds t) (bnds s)"
   422   where "lex_bnd t s = lex_ns (bnds t) (bnds s)"
   423 
   423 
   424 consts numadd:: "num \<times> num \<Rightarrow> num"
   424 consts numadd:: "num \<times> num \<Rightarrow> num"
   425 recdef numadd "measure (\<lambda>(t, s). num_size t + num_size s)"
   425 recdef numadd "measure (\<lambda>(t, s). num_size t + num_size s)"
   426   "numadd (CN n1 c1 r1 ,CN n2 c2 r2) =
   426   "numadd (CN n1 c1 r1, CN n2 c2 r2) =
   427     (if n1 = n2 then
   427     (if n1 = n2 then
   428       (let c = c1 + c2
   428        let c = c1 + c2
   429        in if c = 0 then numadd (r1, r2) else CN n1 c (numadd (r1, r2)))
   429        in if c = 0 then numadd (r1, r2) else CN n1 c (numadd (r1, r2))
   430      else if n1 \<le> n2 then CN n1 c1 (numadd (r1, Add (Mul c2 (Bound n2)) r2))
   430      else if n1 \<le> n2 then CN n1 c1 (numadd (r1, Add (Mul c2 (Bound n2)) r2))
   431      else CN n2 c2 (numadd (Add (Mul c1 (Bound n1)) r1, r2)))"
   431      else CN n2 c2 (numadd (Add (Mul c1 (Bound n1)) r1, r2)))"
   432   "numadd (CN n1 c1 r1, t) = CN n1 c1 (numadd (r1, t))"
   432   "numadd (CN n1 c1 r1, t) = CN n1 c1 (numadd (r1, t))"
   433   "numadd (t, CN n2 c2 r2) = CN n2 c2 (numadd (t, r2))"
   433   "numadd (t, CN n2 c2 r2) = CN n2 c2 (numadd (t, r2))"
   434   "numadd (C b1, C b2) = C (b1 + b2)"
   434   "numadd (C b1, C b2) = C (b1 + b2)"
  1106   "zlfm (NOT (NClosed P)) = Closed P"
  1106   "zlfm (NOT (NClosed P)) = Closed P"
  1107   "zlfm p = p" (hints simp add: fmsize_pos)
  1107   "zlfm p = p" (hints simp add: fmsize_pos)
  1108 
  1108 
  1109 lemma zlfm_I:
  1109 lemma zlfm_I:
  1110   assumes qfp: "qfree p"
  1110   assumes qfp: "qfree p"
  1111   shows "(Ifm bbs (i # bs) (zlfm p) = Ifm bbs (i # bs) p) \<and> iszlfm (zlfm p)"
  1111   shows "Ifm bbs (i # bs) (zlfm p) = Ifm bbs (i # bs) p \<and> iszlfm (zlfm p)"
  1112   (is "(?I (?l p) = ?I p) \<and> ?L (?l p)")
  1112   (is "?I (?l p) = ?I p \<and> ?L (?l p)")
  1113   using qfp
  1113   using qfp
  1114 proof (induct p rule: zlfm.induct)
  1114 proof (induct p rule: zlfm.induct)
  1115   case (5 a)
  1115   case (5 a)
  1116   let ?c = "fst (zsplit0 a)"
  1116   let ?c = "fst (zsplit0 a)"
  1117   let ?r = "snd (zsplit0 a)"
  1117   let ?r = "snd (zsplit0 a)"
  2202     \<Longrightarrow> \<forall>x. \<not>(\<exists>(j::int) \<in> {1..D}. \<exists>(b::int) \<in> B. P (b + j)) \<longrightarrow> P x \<longrightarrow> P (x - D)
  2202     \<Longrightarrow> \<forall>x. \<not>(\<exists>(j::int) \<in> {1..D}. \<exists>(b::int) \<in> B. P (b + j)) \<longrightarrow> P x \<longrightarrow> P (x - D)
  2203     \<Longrightarrow> (\<forall>(x::int). \<forall>(k::int). P1 x = (P1 (x - k * D)))
  2203     \<Longrightarrow> (\<forall>(x::int). \<forall>(k::int). P1 x = (P1 (x - k * D)))
  2204     \<Longrightarrow> (\<exists>(x::int). P x) = ((\<exists>(j::int) \<in> {1..D}. P1 j) \<or> (\<exists>(j::int) \<in> {1..D}. \<exists>(b::int) \<in> B. P (b + j)))"
  2204     \<Longrightarrow> (\<exists>(x::int). P x) = ((\<exists>(j::int) \<in> {1..D}. P1 j) \<or> (\<exists>(j::int) \<in> {1..D}. \<exists>(b::int) \<in> B. P (b + j)))"
  2205   apply(rule iffI)
  2205   apply(rule iffI)
  2206   prefer 2
  2206   prefer 2
  2207   apply(drule minusinfinity)
  2207   apply (drule minusinfinity)
  2208   apply assumption+
  2208   apply assumption+
  2209   apply(fastforce)
  2209   apply fastforce
  2210   apply clarsimp
  2210   apply clarsimp
  2211   apply(subgoal_tac "!!k. 0<=k \<Longrightarrow> !x. P x \<longrightarrow> P (x - k*D)")
  2211   apply (subgoal_tac "\<And>k. 0 \<le> k \<Longrightarrow> \<forall>x. P x \<longrightarrow> P (x - k * D)")
  2212   apply(frule_tac x = x and z=z in decr_lemma)
  2212   apply (frule_tac x = x and z=z in decr_lemma)
  2213   apply(subgoal_tac "P1(x - (\<bar>x - z\<bar> + 1) * D)")
  2213   apply (subgoal_tac "P1 (x - (\<bar>x - z\<bar> + 1) * D)")
  2214   prefer 2
  2214   prefer 2
  2215   apply(subgoal_tac "0 <= (\<bar>x - z\<bar> + 1)")
  2215   apply (subgoal_tac "0 \<le> \<bar>x - z\<bar> + 1")
  2216   prefer 2 apply arith
  2216   prefer 2 apply arith
  2217    apply fastforce
  2217    apply fastforce
  2218   apply(drule (1)  periodic_finite_ex)
  2218   apply (drule (1)  periodic_finite_ex)
  2219   apply blast
  2219   apply blast
  2220   apply(blast dest:decr_mult_lemma)
  2220   apply (blast dest: decr_mult_lemma)
  2221   done
  2221   done
  2222 
  2222 
  2223 theorem cp_thm:
  2223 theorem cp_thm:
  2224   assumes lp: "iszlfm p"
  2224   assumes lp: "iszlfm p"
  2225     and u: "d_\<beta> p 1"
  2225     and u: "d_\<beta> p 1"
  2295     (Inum (i # bs)) ` set B = (Inum (i # bs)) ` set (\<beta> q) \<and> d_\<beta> q 1 \<and> d_\<delta> q d \<and> d > 0 \<and>
  2295     (Inum (i # bs)) ` set B = (Inum (i # bs)) ` set (\<beta> q) \<and> d_\<beta> q 1 \<and> d_\<delta> q d \<and> d > 0 \<and>
  2296     iszlfm q \<and> (\<forall>b\<in> set B. numbound0 b)"
  2296     iszlfm q \<and> (\<forall>b\<in> set B. numbound0 b)"
  2297 proof -
  2297 proof -
  2298   fix q B d
  2298   fix q B d
  2299   assume qBd: "unit p = (q,B,d)"
  2299   assume qBd: "unit p = (q,B,d)"
  2300   let ?thes = "((\<exists>x. Ifm bbs (x#bs) p) = (\<exists>x. Ifm bbs (x#bs) q)) \<and>
  2300   let ?thes = "((\<exists>x. Ifm bbs (x#bs) p) \<longleftrightarrow> (\<exists>x. Ifm bbs (x#bs) q)) \<and>
  2301     Inum (i#bs) ` set B = Inum (i#bs) ` set (\<beta> q) \<and>
  2301     Inum (i#bs) ` set B = Inum (i#bs) ` set (\<beta> q) \<and>
  2302     d_\<beta> q 1 \<and> d_\<delta> q d \<and> 0 < d \<and> iszlfm q \<and> (\<forall>b\<in> set B. numbound0 b)"
  2302     d_\<beta> q 1 \<and> d_\<delta> q d \<and> 0 < d \<and> iszlfm q \<and> (\<forall>b\<in> set B. numbound0 b)"
  2303   let ?I = "\<lambda>x p. Ifm bbs (x#bs) p"
  2303   let ?I = "\<lambda>x p. Ifm bbs (x#bs) p"
  2304   let ?p' = "zlfm p"
  2304   let ?p' = "zlfm p"
  2305   let ?l = "\<zeta> ?p'"
  2305   let ?l = "\<zeta> ?p'"
  2317   from a_\<beta>_ex[where p="?p'" and l="?l" and bs="bs", OF lp' dl lp] pp'
  2317   from a_\<beta>_ex[where p="?p'" and l="?l" and bs="bs", OF lp' dl lp] pp'
  2318   have pq_ex:"(\<exists>(x::int). ?I x p) = (\<exists>x. ?I x ?q)" by simp
  2318   have pq_ex:"(\<exists>(x::int). ?I x p) = (\<exists>x. ?I x ?q)" by simp
  2319   from lp' lp a_\<beta>[OF lp' dl lp] have lq:"iszlfm ?q" and uq: "d_\<beta> ?q 1"  by auto
  2319   from lp' lp a_\<beta>[OF lp' dl lp] have lq:"iszlfm ?q" and uq: "d_\<beta> ?q 1"  by auto
  2320   from \<delta>[OF lq] have dp:"?d >0" and dd: "d_\<delta> ?q ?d" by blast+
  2320   from \<delta>[OF lq] have dp:"?d >0" and dd: "d_\<delta> ?q ?d" by blast+
  2321   let ?N = "\<lambda>t. Inum (i#bs) t"
  2321   let ?N = "\<lambda>t. Inum (i#bs) t"
  2322   have "?N ` set ?B' = ((?N o simpnum) ` ?B)" by auto
  2322   have "?N ` set ?B' = ((?N \<circ> simpnum) ` ?B)"
  2323   also have "\<dots> = ?N ` ?B" using simpnum_ci[where bs="i#bs"] by auto
  2323     by auto
       
  2324   also have "\<dots> = ?N ` ?B"
       
  2325     using simpnum_ci[where bs="i#bs"] by auto
  2324   finally have BB': "?N ` set ?B' = ?N ` ?B" .
  2326   finally have BB': "?N ` set ?B' = ?N ` ?B" .
  2325   have "?N ` set ?A' = ((?N o simpnum) ` ?A)" by auto
  2327   have "?N ` set ?A' = ((?N \<circ> simpnum) ` ?A)"
  2326   also have "\<dots> = ?N ` ?A" using simpnum_ci[where bs="i#bs"] by auto
  2328     by auto
       
  2329   also have "\<dots> = ?N ` ?A"
       
  2330     using simpnum_ci[where bs="i#bs"] by auto
  2327   finally have AA': "?N ` set ?A' = ?N ` ?A" .
  2331   finally have AA': "?N ` set ?A' = ?N ` ?A" .
  2328   from \<beta>_numbound0[OF lq] have B_nb:"\<forall>b\<in> set ?B'. numbound0 b"
  2332   from \<beta>_numbound0[OF lq] have B_nb:"\<forall>b\<in> set ?B'. numbound0 b"
  2329     by (simp add: simpnum_numbound0)
  2333     by (simp add: simpnum_numbound0)
  2330   from \<alpha>_l[OF lq] have A_nb: "\<forall>b\<in> set ?A'. numbound0 b"
  2334   from \<alpha>_l[OF lq] have A_nb: "\<forall>b\<in> set ?A'. numbound0 b"
  2331     by (simp add: simpnum_numbound0)
  2335     by (simp add: simpnum_numbound0)
  2332     {assume "length ?B' \<le> length ?A'"
  2336   {
  2333     then have q:"q=?q" and "B = ?B'" and d:"d = ?d"
  2337     assume "length ?B' \<le> length ?A'"
       
  2338     then have q: "q = ?q" and "B = ?B'" and d: "d = ?d"
  2334       using qBd by (auto simp add: Let_def unit_def)
  2339       using qBd by (auto simp add: Let_def unit_def)
  2335     with BB' B_nb have b: "?N ` (set B) = ?N ` set (\<beta> q)"
  2340     with BB' B_nb
  2336       and bn: "\<forall>b\<in> set B. numbound0 b" by simp_all
  2341     have b: "?N ` (set B) = ?N ` set (\<beta> q)" and bn: "\<forall>b\<in> set B. numbound0 b"
  2337   with pq_ex dp uq dd lq q d have ?thes by simp}
  2342       by simp_all
       
  2343     with pq_ex dp uq dd lq q d have ?thes
       
  2344       by simp
       
  2345   }
  2338   moreover
  2346   moreover
  2339   {assume "\<not> (length ?B' \<le> length ?A')"
  2347   {
       
  2348     assume "\<not> (length ?B' \<le> length ?A')"
  2340     then have q:"q=mirror ?q" and "B = ?A'" and d:"d = ?d"
  2349     then have q:"q=mirror ?q" and "B = ?A'" and d:"d = ?d"
  2341       using qBd by (auto simp add: Let_def unit_def)
  2350       using qBd by (auto simp add: Let_def unit_def)
  2342     with AA' mirror_\<alpha>_\<beta>[OF lq] A_nb have b:"?N ` (set B) = ?N ` set (\<beta> q)"
  2351     with AA' mirror_\<alpha>_\<beta>[OF lq] A_nb have b:"?N ` (set B) = ?N ` set (\<beta> q)"
  2343       and bn: "\<forall>b\<in> set B. numbound0 b" by simp_all
  2352       and bn: "\<forall>b\<in> set B. numbound0 b" by simp_all
  2344     from mirror_ex[OF lq] pq_ex q
  2353     from mirror_ex[OF lq] pq_ex q
  2345     have pqm_eq:"(\<exists>(x::int). ?I x p) = (\<exists>(x::int). ?I x q)" by simp
  2354     have pqm_eq:"(\<exists>(x::int). ?I x p) = (\<exists>(x::int). ?I x q)"
       
  2355       by simp
  2346     from lq uq q mirror_l[where p="?q"]
  2356     from lq uq q mirror_l[where p="?q"]
  2347     have lq': "iszlfm q" and uq: "d_\<beta> q 1" by auto
  2357     have lq': "iszlfm q" and uq: "d_\<beta> q 1"
  2348     from \<delta>[OF lq'] mirror_\<delta>[OF lq] q d have dq:"d_\<delta> q d " by auto
  2358       by auto
  2349     from pqm_eq b bn uq lq' dp dq q dp d have ?thes by simp
  2359     from \<delta>[OF lq'] mirror_\<delta>[OF lq] q d have dq: "d_\<delta> q d"
       
  2360       by auto
       
  2361     from pqm_eq b bn uq lq' dp dq q dp d have ?thes
       
  2362       by simp
  2350   }
  2363   }
  2351   ultimately show ?thes by blast
  2364   ultimately show ?thes by blast
  2352 qed
  2365 qed
  2353 
  2366 
  2354 
  2367 
  2355 text {* Cooper's Algorithm *}
  2368 text {* Cooper's Algorithm *}
  2356 
  2369 
  2357 definition cooper :: "fm \<Rightarrow> fm" where
  2370 definition cooper :: "fm \<Rightarrow> fm"
       
  2371 where
  2358   "cooper p =
  2372   "cooper p =
  2359     (let
  2373     (let
  2360       (q, B, d) = unit p;
  2374       (q, B, d) = unit p;
  2361       js = [1..d];
  2375       js = [1..d];
  2362       mq = simpfm (minusinf q);
  2376       mq = simpfm (minusinf q);
  2384   fix i
  2398   fix i
  2385   let ?N = "\<lambda>t. Inum (i#bs) t"
  2399   let ?N = "\<lambda>t. Inum (i#bs) t"
  2386   let ?Bjs = "[(b,j). b\<leftarrow>?B,j\<leftarrow>?js]"
  2400   let ?Bjs = "[(b,j). b\<leftarrow>?B,j\<leftarrow>?js]"
  2387   let ?qd = "evaldjf (\<lambda>(b,j). simpfm (subst0 (Add b (C j)) ?q)) ?Bjs"
  2401   let ?qd = "evaldjf (\<lambda>(b,j). simpfm (subst0 (Add b (C j)) ?q)) ?Bjs"
  2388   have qbf:"unit p = (?q,?B,?d)" by simp
  2402   have qbf:"unit p = (?q,?B,?d)" by simp
  2389   from unit[OF qf qbf] have pq_ex: "(\<exists>(x::int). ?I x p) = (\<exists>(x::int). ?I x ?q)" and
  2403   from unit[OF qf qbf]
  2390     B:"?N ` set ?B = ?N ` set (\<beta> ?q)" and
  2404   have pq_ex: "(\<exists>(x::int). ?I x p) \<longleftrightarrow> (\<exists>(x::int). ?I x ?q)"
  2391     uq:"d_\<beta> ?q 1" and dd: "d_\<delta> ?q ?d" and dp: "?d > 0" and
  2405     and B: "?N ` set ?B = ?N ` set (\<beta> ?q)"
  2392     lq: "iszlfm ?q" and
  2406     and uq: "d_\<beta> ?q 1"
  2393     Bn: "\<forall>b\<in> set ?B. numbound0 b" by auto
  2407     and dd: "d_\<delta> ?q ?d"
       
  2408     and dp: "?d > 0"
       
  2409     and lq: "iszlfm ?q"
       
  2410     and Bn: "\<forall>b\<in> set ?B. numbound0 b"
       
  2411     by auto
  2394   from zlin_qfree[OF lq] have qfq: "qfree ?q" .
  2412   from zlin_qfree[OF lq] have qfq: "qfree ?q" .
  2395   from simpfm_qf[OF minusinf_qfree[OF qfq]] have qfmq: "qfree ?smq" .
  2413   from simpfm_qf[OF minusinf_qfree[OF qfq]] have qfmq: "qfree ?smq" .
  2396   have jsnb: "\<forall>j \<in> set ?js. numbound0 (C j)" by simp
  2414   have jsnb: "\<forall>j \<in> set ?js. numbound0 (C j)"
       
  2415     by simp
  2397   then have "\<forall>j\<in> set ?js. bound0 (subst0 (C j) ?smq)"
  2416   then have "\<forall>j\<in> set ?js. bound0 (subst0 (C j) ?smq)"
  2398     by (auto simp only: subst0_bound0[OF qfmq])
  2417     by (auto simp only: subst0_bound0[OF qfmq])
  2399   then have th: "\<forall>j\<in> set ?js. bound0 (simpfm (subst0 (C j) ?smq))"
  2418   then have th: "\<forall>j\<in> set ?js. bound0 (simpfm (subst0 (C j) ?smq))"
  2400     by (auto simp add: simpfm_bound0)
  2419     by (auto simp add: simpfm_bound0)
  2401   from evaldjf_bound0[OF th] have mdb: "bound0 ?md" by simp
  2420   from evaldjf_bound0[OF th] have mdb: "bound0 ?md"
       
  2421     by simp
  2402   from Bn jsnb have "\<forall>(b,j) \<in> set ?Bjs. numbound0 (Add b (C j))"
  2422   from Bn jsnb have "\<forall>(b,j) \<in> set ?Bjs. numbound0 (Add b (C j))"
  2403     by simp
  2423     by simp
  2404   then have "\<forall>(b,j) \<in> set ?Bjs. bound0 (subst0 (Add b (C j)) ?q)"
  2424   then have "\<forall>(b,j) \<in> set ?Bjs. bound0 (subst0 (Add b (C j)) ?q)"
  2405     using subst0_bound0[OF qfq] by blast
  2425     using subst0_bound0[OF qfq] by blast
  2406   then have "\<forall>(b,j) \<in> set ?Bjs. bound0 (simpfm (subst0 (Add b (C j)) ?q))"
  2426   then have "\<forall>(b,j) \<in> set ?Bjs. bound0 (simpfm (subst0 (Add b (C j)) ?q))"
  2407     using simpfm_bound0  by blast
  2427     using simpfm_bound0 by blast
  2408   then have th': "\<forall>x \<in> set ?Bjs. bound0 ((\<lambda>(b,j). simpfm (subst0 (Add b (C j)) ?q)) x)"
  2428   then have th': "\<forall>x \<in> set ?Bjs. bound0 ((\<lambda>(b,j). simpfm (subst0 (Add b (C j)) ?q)) x)"
  2409     by auto
  2429     by auto
  2410   from evaldjf_bound0 [OF th'] have qdb: "bound0 ?qd" by simp
  2430   from evaldjf_bound0 [OF th'] have qdb: "bound0 ?qd"
  2411   from mdb qdb
  2431     by simp
  2412   have mdqdb: "bound0 (disj ?md ?qd)"
  2432   from mdb qdb have mdqdb: "bound0 (disj ?md ?qd)"
  2413     unfolding disj_def by (cases "?md=T \<or> ?qd=T") simp_all
  2433     unfolding disj_def by (cases "?md = T \<or> ?qd = T") simp_all
  2414   from trans [OF pq_ex cp_thm'[OF lq uq dd dp,where i="i"]] B
  2434   from trans [OF pq_ex cp_thm'[OF lq uq dd dp,where i="i"]] B
  2415   have "?lhs = (\<exists>j\<in> {1.. ?d}. ?I j ?mq \<or> (\<exists>b\<in> ?N ` set ?B. Ifm bbs ((b+ j)#bs) ?q))"
  2435   have "?lhs \<longleftrightarrow> (\<exists>j \<in> {1.. ?d}. ?I j ?mq \<or> (\<exists>b \<in> ?N ` set ?B. Ifm bbs ((b + j) # bs) ?q))"
  2416     by auto
  2436     by auto
  2417   also have "\<dots> = (\<exists>j\<in> {1.. ?d}. ?I j ?mq \<or> (\<exists>b\<in> set ?B. Ifm bbs ((?N b+ j)#bs) ?q))"
  2437   also have "\<dots> \<longleftrightarrow> (\<exists>j \<in> {1.. ?d}. ?I j ?mq \<or> (\<exists>b \<in> set ?B. Ifm bbs ((?N b + j) # bs) ?q))"
  2418     by simp
  2438     by simp
  2419   also have "\<dots> = ((\<exists>j\<in> {1.. ?d}. ?I j ?mq ) \<or>
  2439   also have "\<dots> \<longleftrightarrow> (\<exists>j \<in> {1.. ?d}. ?I j ?mq ) \<or>
  2420       (\<exists>j\<in> {1.. ?d}. \<exists>b\<in> set ?B. Ifm bbs ((?N (Add b (C j)))#bs) ?q))"
  2440       (\<exists>j\<in> {1.. ?d}. \<exists>b \<in> set ?B. Ifm bbs ((?N (Add b (C j))) # bs) ?q)"
  2421     by (simp only: Inum.simps) blast
  2441     by (simp only: Inum.simps) blast
  2422   also have "\<dots> = ((\<exists>j\<in> {1.. ?d}. ?I j ?smq ) \<or>
  2442   also have "\<dots> \<longleftrightarrow> (\<exists>j \<in> {1.. ?d}. ?I j ?smq) \<or>
  2423       (\<exists>j\<in> {1.. ?d}. \<exists>b\<in> set ?B. Ifm bbs ((?N (Add b (C j)))#bs) ?q))"
  2443       (\<exists>j \<in> {1.. ?d}. \<exists>b \<in> set ?B. Ifm bbs ((?N (Add b (C j))) # bs) ?q)"
  2424     by (simp add: simpfm)
  2444     by (simp add: simpfm)
  2425   also have "\<dots> = ((\<exists>j\<in> set ?js. (\<lambda>j. ?I i (simpfm (subst0 (C j) ?smq))) j) \<or>
  2445   also have "\<dots> \<longleftrightarrow> (\<exists>j\<in> set ?js. (\<lambda>j. ?I i (simpfm (subst0 (C j) ?smq))) j) \<or>
  2426       (\<exists>j\<in> set ?js. \<exists>b\<in> set ?B. Ifm bbs ((?N (Add b (C j)))#bs) ?q))"
  2446       (\<exists>j\<in> set ?js. \<exists>b\<in> set ?B. Ifm bbs ((?N (Add b (C j)))#bs) ?q)"
  2427     by (simp only: simpfm subst0_I[OF qfmq] set_upto) auto
  2447     by (simp only: simpfm subst0_I[OF qfmq] set_upto) auto
  2428   also have "\<dots> = (?I i (evaldjf (\<lambda>j. simpfm (subst0 (C j) ?smq)) ?js) \<or>
  2448   also have "\<dots> \<longleftrightarrow> ?I i (evaldjf (\<lambda>j. simpfm (subst0 (C j) ?smq)) ?js) \<or>
  2429       (\<exists>j\<in> set ?js. \<exists>b\<in> set ?B. ?I i (subst0 (Add b (C j)) ?q)))"
  2449       (\<exists>j\<in> set ?js. \<exists>b\<in> set ?B. ?I i (subst0 (Add b (C j)) ?q))"
  2430     by (simp only: evaldjf_ex subst0_I[OF qfq])
  2450     by (simp only: evaldjf_ex subst0_I[OF qfq])
  2431   also have "\<dots>= (?I i ?md \<or> (\<exists>(b,j) \<in> set ?Bjs. (\<lambda>(b,j). ?I i (simpfm (subst0 (Add b (C j)) ?q))) (b,j)))"
  2451   also have "\<dots> \<longleftrightarrow> ?I i ?md \<or>
       
  2452       (\<exists>(b,j) \<in> set ?Bjs. (\<lambda>(b,j). ?I i (simpfm (subst0 (Add b (C j)) ?q))) (b,j))"
  2432     by (simp only: simpfm set_concat set_map concat_map_singleton UN_simps) blast
  2453     by (simp only: simpfm set_concat set_map concat_map_singleton UN_simps) blast
  2433   also have "\<dots> = (?I i ?md \<or> (?I i (evaldjf (\<lambda>(b,j). simpfm (subst0 (Add b (C j)) ?q)) ?Bjs)))"
  2454   also have "\<dots> \<longleftrightarrow> ?I i ?md \<or> ?I i (evaldjf (\<lambda>(b,j). simpfm (subst0 (Add b (C j)) ?q)) ?Bjs)"
  2434     by (simp only: evaldjf_ex[where bs="i#bs" and f="\<lambda>(b,j). simpfm (subst0 (Add b (C j)) ?q)" and ps="?Bjs"])
  2455     by (simp only: evaldjf_ex[where bs="i#bs" and f="\<lambda>(b,j). simpfm (subst0 (Add b (C j)) ?q)" and ps="?Bjs"])
  2435       (auto simp add: split_def)
  2456       (auto simp add: split_def)
  2436   finally have mdqd: "?lhs = (?I i ?md \<or> ?I i ?qd)"
  2457   finally have mdqd: "?lhs \<longleftrightarrow> ?I i ?md \<or> ?I i ?qd"
  2437     by simp
  2458     by simp
  2438   also have "\<dots> = (?I i (disj ?md ?qd))"
  2459   also have "\<dots> \<longleftrightarrow> ?I i (disj ?md ?qd)"
  2439     by (simp add: disj)
  2460     by (simp add: disj)
  2440   also have "\<dots> = (Ifm bbs bs (decr (disj ?md ?qd)))"
  2461   also have "\<dots> \<longleftrightarrow> Ifm bbs bs (decr (disj ?md ?qd))"
  2441     by (simp only: decr [OF mdqdb])
  2462     by (simp only: decr [OF mdqdb])
  2442   finally have mdqd2: "?lhs = (Ifm bbs bs (decr (disj ?md ?qd)))" .
  2463   finally have mdqd2: "?lhs \<longleftrightarrow> Ifm bbs bs (decr (disj ?md ?qd))" .
  2443   {
  2464   {
  2444     assume mdT: "?md = T"
  2465     assume mdT: "?md = T"
  2445     then have cT: "cooper p = T"
  2466     then have cT: "cooper p = T"
  2446       by (simp only: cooper_def unit_def split_def Let_def if_True) simp
  2467       by (simp only: cooper_def unit_def split_def Let_def if_True) simp
  2447     from mdT have lhs: "?lhs"
  2468     from mdT have lhs: "?lhs"
  2448       using mdqd by simp
  2469       using mdqd by simp
  2449     from mdT have "?rhs"
  2470     from mdT have "?rhs"
  2450       by (simp add: cooper_def unit_def split_def)
  2471       by (simp add: cooper_def unit_def split_def)
  2451     with lhs cT have ?thesis by simp
  2472     with lhs cT have ?thesis
       
  2473       by simp
  2452   }
  2474   }
  2453   moreover
  2475   moreover
  2454   {
  2476   {
  2455     assume mdT: "?md \<noteq> T"
  2477     assume mdT: "?md \<noteq> T"
  2456     then have "cooper p = decr (disj ?md ?qd)"
  2478     then have "cooper p = decr (disj ?md ?qd)"