Theory CertLin

(*  Author:     Tobias Nipkow, 2007

A simple certificate checker for q-free linear arithmetic:
is linear combination of atoms and certificate contradictory?
*)

theory CertLin
imports LinArith
begin

declare list_add_assoc [simp]

instantiation atom :: monoid_add
begin

fun plus_atom :: "atom  atom  atom" where
  "(Eq r1 cs1) + (Eq r2 cs2) = Eq (r1+r2) (cs1+cs2)" |
  "(Eq r1 cs1) + (Less r2 cs2) = Less (r1+r2) (cs1+cs2)" |
  "(Less r1 cs1) + (Eq r2 cs2) = Less (r1+r2) (cs1+cs2)" |
  "(Less r1 cs1) + (Less r2 cs2) = Less (r1+r2) (cs1+cs2)"

definition
  "0 = Eq 0 []"

instance
apply intro_classes
apply(simp_all add: zero_atom_def)
apply(case_tac a)
apply(case_tac b)
apply(case_tac c)
apply simp_all
apply(case_tac c)
apply simp_all
apply(case_tac b)
apply(case_tac c)
apply simp_all
apply(case_tac c)
apply simp_all
apply(case_tac a)
apply simp_all
apply(case_tac a)
apply simp_all
done

end

lemma I_R_additive: "IR a xs  IR b xs  IR(a+b) xs"
apply(case_tac a)
apply(case_tac b)
apply (simp_all add:iprod_left_add_distrib)
apply(case_tac b)
apply (simp_all add:iprod_left_add_distrib)
done

fun mult_atom :: "real  atom  atom" (infix "*a" 70) where
"c *a Eq r cs = Eq (c*r) (c *s cs)" |
"c *a Less r cs = (if c=0 then Eq 0 [] else Less (c*r) (c *s cs))"

definition iprod_a :: "real list  atom list  atom" (infix "a" 70)
where "cs a as = ((c,a)  zip cs as. c *a a)"

lemma iprod_a_Nil2[simp]: "cs a [] = 0"
by(simp add:iprod_a_def)

lemma [simp]: "(c#cs) a (a#as) = (c *a a) + cs a as"
by(simp add:iprod_a_def)

definition contradict :: "atom list  real list  bool" where
"contradict as cs  size cs = size as  (cset cs. c0) 
  (case cs a as of Eq r cs  r  0  (cset cs. c=0)
                  | Less r cs  r  0  (cset cs. c=0))"

definition
"contradict_dnf ass = (css. list_all2 contradict ass css)"

lemma refute_I:
  "¬ Logic.interpret h (Neg f) e  Logic.interpret h f e"
by simp

lemma I_R_mult_atom: "c  0  IR a xs  IR (c *a a) xs"
apply(cases a)
 apply(clarsimp)
apply(simp)
done

lemma I_R_iprod_a:
 "size cs = size as  (c,a)  set(zip cs as). IR (c *a a) xs
  IR (cs a as) xs"
apply(induct cs as rule:list_induct2)
 apply (simp add:zero_atom_def)
apply(simp add:I_R_additive)
done

lemma contradictD:
 "contradict as cs  aset as. ¬ IR a xs"
proof -
  assume "contradict as cs"
  have "¬ IR (cs a as) xs"
  proof (cases "cs a as")
    case Less thus ?thesis using contradict as cs
      by(simp add:contradict_def iprod0_if_coeffs0)
  next
    case Eq thus ?thesis using contradict as cs
      by(simp add:contradict_def iprod0_if_coeffs0)
  qed
  thus ?thesis using contradict as cs
    by(force simp add:contradict_def intro: I_R_iprod_a I_R_mult_atom
             elim:in_set_zipE)
qed

lemma cyclic_dnfD: "qfree f  contradict_dnf (dnf(R.nnf f))  ¬R.I f xs"
apply(subst R.I_nnf[symmetric])
apply(subst R.I_dnf[symmetric])
apply(erule R.nqfree_nnf)
apply(auto simp add:contradict_dnf_def list_all2_iff in_set_conv_nth)
apply(drule_tac x="(dnf(R.nnf f) ! i, css!i)" in bspec)
apply (auto simp:set_zip)
apply(drule_tac xs=xs in contradictD)
apply auto
done

end