(* Property from Case-Analysis for Rippling and Inductive Proof,
   Moa Johansson, Lucas Dixon and Alan Bundy, ITP 2010.
   This Isabelle theory is produced using the TIP tool offered at the following website:
     https://github.com/tip-org/tools
   This file was originally provided as part of TIP benchmark at the following website:
     https://github.com/tip-org/benchmarks
   Yutaka Nagashima at CIIRC, CTU changed the TIP output theory file slightly
   to make it compatible with Isabelle2017.*)
  theory TIP_prop_07
  imports "../../Test_Base"
begin

datatype Nat = Z | S "Nat"

fun t22 :: "Nat => Nat => Nat" where
  "t22 (Z) y = y"
| "t22 (S z) y = S (t22 z y)"

fun t2 :: "Nat => Nat => Nat" where
  "t2 (Z) y = Z"
| "t2 (S z) (Z) = S z"
| "t2 (S z) (S x2) = t2 z x2"

theorem property0 :
  "((t2 (t22 n m) n) = m)"
  oops

end


theory TS_To_XC_aux
  imports XC_Definition
begin

datatype 'a xc_element = V 'a | C "'a lit set" | L "'a lit" "'a lit set"

fun var :: "'a lit \<Rightarrow> 'a" where
"var (Neg a) = a" | "var (Pos a) = a"

fun vars :: "'a three_sat \<Rightarrow> 'a set" where
"vars [] = {}" |
"vars (x#xs) = (var ` x) \<union> vars xs"

lemma vars_correct:
"x \<in> vars F \<longleftrightarrow> x \<in> (var) ` \<Union> (set F)"
by (induction F) auto

fun comp_literals :: "'a three_sat \<Rightarrow> 'a xc_element set \<Rightarrow> 'a xc_element set" where
"comp_literals [] acc = acc" |
"comp_literals (x # xs) acc = comp_literals xs ({L a x | a. a \<in> x} \<union> acc)"

lemma sat_tail:
  "sat (x#xs) \<Longrightarrow> sat xs"
apply (induction xs)
apply (auto simp add: sat_def models_def)
done

lemma comp_literals_mono:
  "acc \<le> comp_literals F acc"
apply (induction F arbitrary: acc)
apply (auto simp add: three_cnf_sat_def sat_tail, force)
done

lemma comp_literals_correct[simp]:
  "comp_literals F acc = acc \<union> {L l c| l c. c \<in> set F \<and> l \<in> c}"
apply (induction F arbitrary: acc)
using comp_literals_mono
by fastforce+

section "splitting of the sat"

definition vars_of_sat :: "'a three_sat \<Rightarrow> 'a xc_element set" where
  "vars_of_sat F = {V v |v. v \<in> vars F}"

definition clauses_of_sat :: "'a three_sat \<Rightarrow> 'a xc_element set" where
  "clauses_of_sat F = {C c| c. c\<in> set F}"

lemma clauses_of_sat_correct[simp]:
  "c \<in> set F \<Longrightarrow> C c \<in> clauses_of_sat F"
unfolding clauses_of_sat_def
by blast

definition literals_of_sat :: "'a three_sat \<Rightarrow> 'a xc_element set" where
"literals_of_sat F = comp_literals F {}"

lemma literals_of_sat_correct[simp]:
  "\<lbrakk>c \<in> set F; l \<in> c\<rbrakk> \<Longrightarrow> L l c \<in> literals_of_sat F"
unfolding literals_of_sat_def
by simp

fun lift_xc_element :: "('a \<Rightarrow> bool) \<Rightarrow> 'a xc_element \<Rightarrow> bool" ("_\<Up>" 60) where
 "lift_xc_element \<sigma> (V v) = \<sigma> v" |
 "lift_xc_element \<sigma> (C c) \<longleftrightarrow> (\<exists> l\<in>c. (\<sigma>\<up>) l)" |
 "lift_xc_element \<sigma> (L x c) = (\<sigma>\<up>) x"

end