Theory FRE

(*  Author:     Tobias Nipkow, 2007  *)

theory FRE
imports LinArith
begin

subsection‹Ferrante-Rackoff \label{sec:FRE}›

text‹This section formalizes a slight variant of Ferrante and
Rackoff's algorithm~cite"FerranteR-SIAM75". We consider equalities
separately, which improves performance.›

fun between :: "real * real list  real * real list  real * real list"
where "between (r,cs) (s,ds) = ((r+s)/2, (1/2) *s (cs+ds))"

definition FR1 :: "atom fm  atom fm" where
"FR1 φ =
(let as = R.atoms0 φ; lbs = lbounds as; ubs = ubounds as; ebs = ebounds as;
     intrs = [subst φ (between l u) . l  lbs, u  ubs]
 in list_disj (inf- φ # inf+ φ # intrs @ map (subst φ) ebs))"


lemma dense_interval:
assumes "finite L" "finite U" "l  L" "u  U" "l < x" "x < u" "P(x::real)"
and dense: "y l u.  y{l<..<x}. y  L;  y{x<..<u}. y  U;
                       l<x;x<u; l<y;y<u   P y"
shows "lL.uU. l<u  (y. l<y  y<u  P y)"
proof -
  let ?L = "{l:L. l < x}" let ?U = "{u:U. x < u}"
  let ?ll = "Max ?L" let ?uu = "Min ?U"
  have "?L  {}" using l  L l<x by (blast intro:order_less_imp_le)
  moreover have "?U  {}" using u:U x<u by (blast intro:order_less_imp_le)
  ultimately have "y. ?ll<y  y<x  y  L" "y. x<y  y<?uu  y  U"
    using finite L finite U by force+
  moreover have "?ll  L"
  proof
    show "?ll  ?L" using finite L Max_in[OF _ ?L  {}] by simp
    show "?L  L" by blast
  qed
  moreover have "?uu  U"
  proof
    show "?uu  ?U" using finite U Min_in[OF _ ?U  {}] by simp
    show "?U  U" by blast
  qed
  moreover have "?ll < x" using finite L ?L  {} by simp
  moreover have "x < ?uu" using finite U ?U  {} by simp
  moreover have "?ll < ?uu" using ?ll<x x<?uu by arith
  ultimately show ?thesis using l < x x < u ?L  {} ?U  {}
    by(blast intro!:dense greaterThanLessThan_iff[THEN iffD1])
qed

lemma dense:
  " nqfree f; y{l<..<x}. y  LB f xs; y{x<..<u}. y  UB f xs;
     l < x; x < u; x  EQ f xs;  R.I f (x#xs); l < y; y < u
    R.I f (y#xs)"
proof(induct f)
  case (Atom a)
  show ?case
  proof (cases a)
    case (Less r cs)
    show ?thesis
    proof (cases cs)
      case Nil thus ?thesis using Atom Less by (simp add:dependsR_def)
    next
      case (Cons c cs)
      hence "r < c*x + cs,xs" using Atom Less by simp
      { assume "c=0" hence ?thesis using Atom Less Cons by simp }
      moreover
      { assume "c<0"
        hence "x < (r - cs,xs)/c" (is "_ < ?u") using r < c*x + cs,xs
          by (simp add: field_simps)
        have ?thesis
        proof (rule ccontr)
          assume "¬ R.I (Atom a) (y#xs)"
          hence "?u  y" using Atom Less Cons c<0
            by (auto simp add: field_simps)
          hence "?u < u" using y<u by simp
          with x<?u show False using Atom Less Cons c<0
            by(auto simp:dependsR_def)
        qed } moreover
      { assume "c>0"
        hence "x > (r - cs,xs)/c" (is "_ > ?l") using r < c*x + cs,xs
          by (simp add: field_simps)
        have ?thesis
        proof (rule ccontr)
          assume "¬ R.I (Atom a) (y#xs)"
          hence "?l  y" using Atom Less Cons c>0
            by (auto simp add: field_simps)
          hence "?l > l" using y>l by simp
          with ?l<x show False using Atom Less Cons c>0
            by (auto simp:dependsR_def)
        qed }
      ultimately show ?thesis by force
    qed
  next
    case (Eq r cs)
    show ?thesis
    proof (cases cs)
      case Nil thus ?thesis using Atom Eq by (simp add:dependsR_def)
    next
      case (Cons c cs)
      hence "r = c*x + cs,xs" using Atom Eq by simp
      { assume "c=0" hence ?thesis using Atom Eq Cons by simp }
      moreover
      { assume "c0"
        hence ?thesis using r = c*x + cs,xs Atom Eq Cons l<y y<u
          by (auto simp: dependsR_def split: if_splits) }
      ultimately show ?thesis by force
    qed
  qed
next
  case (And f1 f2) thus ?case
    by auto (metis (no_types, opaque_lifting))+
next
  case (Or f1 f2) thus ?case
    by auto (metis (no_types, opaque_lifting))+
qed fastforce+

theorem I_FR1:
assumes "nqfree φ" shows "R.I (FR1 φ) xs = (x. R.I φ (x#xs))"
  (is "?FR = ?EX")
proof
  assume ?FR
  { assume "R.I (inf- φ) xs"
    hence ?EX using ?FR min_inf[OF nqfree φ, where xs=xs]
      by(auto simp add:FR1_def)
  } moreover
  { assume "R.I (inf+ φ) xs"
    hence ?EX using ?FR plus_inf[OF nqfree φ, where xs=xs]
      by(auto simp add:FR1_def)
  } moreover
  { assume "x  EQ φ xs. R.I φ (x#xs)"
    hence ?EX using ?FR by(auto simp add:FR1_def)
  } moreover
  { assume "¬R.I (inf- φ) xs  ¬R.I (inf+ φ) xs 
            (xEQ φ xs. ¬R.I φ (x#xs))"
    with ?FR obtain r cs s ds
      where "R.I (subst φ (between (r,cs) (s,ds))) xs"
      by(auto simp: FR1_def eval_def
        diff_divide_distrib set_ebounds I_subst nqfree φ) blast
    hence "R.I φ (eval (between (r,cs) (s,ds)) xs # xs)"
      by(simp add:I_subst nqfree φ)
    hence ?EX .. }
  ultimately show ?EX by blast
next
  assume ?EX
  then obtain x where x: "R.I φ (x#xs)" ..
  { assume "R.I (inf- φ) xs  R.I (inf+ φ) xs"
    hence ?FR by(auto simp:FR1_def)
  } moreover
  { assume "x  EQ φ xs"
    then obtain r cs
      where "(r,cs)  set(ebounds(R.atoms0 φ))  x = r + cs,xs"
      by(force simp:set_ebounds field_simps)
    moreover hence "R.I (subst φ (r,cs)) xs" using x
      by(auto simp: I_subst nqfree φ eval_def)
    ultimately have ?FR by(force simp:FR1_def) } moreover
  { assume "¬ R.I (inf- φ) xs" and "¬ R.I (inf+ φ) xs" and "x  EQ φ xs"
    obtain l where "l  LB φ xs" "l < x"
      using LBex[OF nqfree φ x ¬ R.I (inf- φ) xs x  EQ φ xs] ..
    obtain u where "u  UB φ xs" "x < u"
      using UBex[OF nqfree φ x ¬ R.I (inf+ φ) xs x  EQ φ xs] ..
    have "lLB φ xs. uUB φ xs. l<u  (y. l < y  y < u  R.I φ (y#xs))"
      using dense_interval[where P = "λx. R.I φ (x#xs)", OF finite_LB finite_UB l:LB φ xs u:UB φ xs l<x x<u x] x dense[OF nqfree φ _ _ _ _ x  EQ φ xs] by simp
    then obtain r c cs s d ds
      where "Less r (c # cs)  set (R.atoms0 φ)" "Less s (d # ds)  set (R.atoms0 φ)"
          "y. (r - cs,xs) / c < y  y < (s - ds,xs) / d  R.I φ (y # xs)"
        and *: "c > 0" "d < 0" "(r - cs,xs) / c < (s - ds,xs) / d"
      by blast
    moreover
      have "(r - cs,xs) / c < eval (between (r / c, (-1 / c) *s cs) (s / d, (-1 / d) *s ds)) xs" (is ?P)
        and "eval (between (r / c, (-1 / c) *s cs) (s / d, (-1 / d) *s ds)) xs < (s - ds,xs) / d" (is ?Q)
    proof -
      from * have [simp]: "c * (c * (d * (d * 4))) > 0"
        by (simp add: algebra_split_simps)
      from * have "c * s + d * cs,xs < d * r + c * ds,xs"
        by (simp add: field_simps)
      with * have "(2 * c * c * d) * (d * r + c * ds,xs)
        < (2 * c * c * d) * (c * s + d * cs,xs)"
        and "(2 * c * d * d) * (c * s + d * cs,xs)
        < (2 * c * d * d) * (d * r + c * ds,xs)" by simp_all
      with * show ?P and ?Q by (auto simp add: field_simps eval_def iprod_left_add_distrib)
    qed
    ultimately have ?FR
      by (fastforce simp: FR1_def bex_Un set_lbounds set_ubounds set_ebounds I_subst nqfree φ)
  } ultimately show ?FR by blast
qed


definition "FR = R.lift_nnf_qe FR1"


lemma qfree_FR1: "nqfree φ  qfree (FR1 φ)"
apply(simp add:FR1_def)
apply(rule qfree_list_disj)
apply(auto simp:qfree_min_inf qfree_plus_inf set_ubounds set_lbounds set_ebounds image_def qfree_map_fm)
done

theorem I_FR: "R.I (FR φ) xs = R.I φ xs"
by(simp add:I_FR1 FR_def R.I_lift_nnf_qe qfree_FR1)

theorem qfree_FR: "qfree (FR φ)"
by(simp add:FR_def R.qfree_lift_nnf_qe qfree_FR1)

end