Theory Tree
theory Tree imports Main begin
subsection "Tree"
inductive_set
tree :: "['a => 'a set,'a] => (nat * 'a) set"
for subs :: "'a => 'a set" and gamma :: 'a
where
tree0: "(0,gamma) : tree subs gamma"
| tree1: "[| (n,delta) : tree subs gamma; sigma : subs delta |]
==> (Suc n,sigma) : tree subs gamma"
declare tree.cases [elim]
declare tree.intros [intro]
lemma tree0Eq: "(0,y) : tree subs gamma = (y = gamma)"
apply(rule iffI)
apply (erule tree.cases, auto)
done
lemma tree1Eq [rule_format]:
"∀Y. (Suc n,Y) ∈ tree subs gamma = (∃sigma ∈ subs gamma . (n,Y) ∈ tree subs sigma)"
by (induct n) (blast, force)
definition
incLevel :: "nat * 'a => nat * 'a" where
"incLevel = (% (n,a). (Suc n,a))"
lemma injIncLevel: "inj incLevel"
apply(simp add: incLevel_def)
apply(rule inj_onI)
apply auto
done
lemma treeEquation: "tree subs gamma = insert (0,gamma) (UN delta:subs gamma . incLevel ` tree subs delta)"
apply(rule set_eqI)
apply(simp add: split_paired_all)
apply(case_tac a)
apply(force simp add: tree0Eq incLevel_def)
apply(force simp add: tree1Eq incLevel_def)
done
definition
fans :: "['a => 'a set] => bool" where
"fans subs ⟷ (!x. finite (subs x))"
lemma fansD: "fans subs ==> finite (subs A)"
by(simp add: fans_def)
lemma fansI: "(!A. finite (subs A)) ==> fans subs"
by(simp add: fans_def)
subsection "Terminal"
definition
terminal :: "['a => 'a set,'a] => bool" where
"terminal subs delta ⟷ subs(delta) = {}"
lemma terminalD: "terminal subs Gamma ==> x ~: subs Gamma"
by(simp add: terminal_def)
lemma terminalI: "x ∈ subs Gamma ==> ~ terminal subs Gamma"
by(auto simp add: terminal_def)
subsection "Inherited"
definition
inherited :: "['a => 'a set,(nat * 'a) set => bool] => bool" where
"inherited subs P ⟷ (!A B. (P A & P B) = P (A Un B))
& (!A. P A = P (incLevel ` A))
& (!n Gamma A. ~(terminal subs Gamma) --> P A = P (insert (n,Gamma) A))
& (P {})"
lemma inheritedUn[rule_format]:"inherited subs P --> P A --> P B --> P (A Un B)"
by (auto simp add: inherited_def)
lemma inheritedIncLevel[rule_format]: "inherited subs P --> P A --> P (incLevel ` A)"
by (auto simp add: inherited_def)
lemma inheritedEmpty[rule_format]: "inherited subs P --> P {}"
by (auto simp add: inherited_def)
lemma inheritedInsert[rule_format]:
"inherited subs P --> ~(terminal subs Gamma) --> P A --> P (insert (n,Gamma) A)"
by (auto simp add: inherited_def)
lemma inheritedI[rule_format]: "[| ∀A B . (P A & P B) = P (A Un B);
∀A . P A = P (incLevel ` A);
∀n Gamma A . ~(terminal subs Gamma) --> P A = P (insert (n,Gamma) A);
P {} |] ==> inherited subs P"
by (simp add: inherited_def)
lemma inheritedUnEq[rule_format, symmetric]: "inherited subs P --> (P A & P B) = P (A Un B)"
by (auto simp add: inherited_def)
lemma inheritedIncLevelEq[rule_format, symmetric]: "inherited subs P --> P A = P (incLevel ` A)"
by (auto simp add: inherited_def)
lemma inheritedInsertEq[rule_format, symmetric]: "inherited subs P --> ~(terminal subs Gamma) --> P A = P (insert (n,Gamma) A)"
by (auto simp add: inherited_def)
lemmas inheritedUnD = iffD1[OF inheritedUnEq]
lemmas inheritedInsertD = inheritedInsertEq[THEN iffD1]
lemmas inheritedIncLevelD = inheritedIncLevelEq[THEN iffD1]
lemma inheritedUNEq[rule_format]:
"finite A --> inherited subs P --> (!x:A. P (B x)) = P (UN a:A. B a)"
apply(intro impI)
apply(erule finite_induct)
apply simp
apply(simp add: inheritedEmpty)
apply(force dest: inheritedUnEq)
done
lemmas inheritedUN = inheritedUNEq[THEN iffD1]
lemmas inheritedUND[rule_format] = inheritedUNEq[THEN iffD2]
lemma inheritedPropagateEq[rule_format]: assumes a: "inherited subs P"
and b: "fans subs"
and c: "~(terminal subs delta)"
shows "P(tree subs delta) = (!sigma:subs delta. P(tree subs sigma))"
apply(insert fansD[OF b])
apply(subst treeEquation [of _ delta])
using assms
apply(simp add: inheritedInsertEq inheritedUNEq[symmetric] inheritedIncLevelEq)
done
lemma inheritedPropagate:
"[| ~P(tree subs delta); inherited subs P; fans subs; ~(terminal subs delta)|]
==> ∃sigma ∈ subs delta . ~P(tree subs sigma)"
by(simp add: inheritedPropagateEq)
lemma inheritedViaSub: "[| inherited subs P; fans subs; P(tree subs delta); sigma ∈ subs delta |]
==> P(tree subs sigma)"
apply(frule_tac terminalI)
apply(simp add: inheritedPropagateEq)
done
lemma inheritedJoin[rule_format]:
"(inherited subs P & inherited subs Q) --> inherited subs (%x. P x & Q x)"
by(blast intro!: inheritedI
dest: inheritedUnEq inheritedIncLevelEq inheritedInsertEq inheritedEmpty)
lemma inheritedJoinI[rule_format]: "[| inherited subs P; inherited subs Q; R = ( % x . P x & Q x) |] ==> inherited subs R"
by(blast intro!:inheritedI dest: inheritedUnEq inheritedIncLevelEq inheritedInsertEq inheritedEmpty)
subsection "bounded, boundedBy"
definition
boundedBy :: "nat => (nat * 'a) set => bool" where
"boundedBy N A ⟷ (∀(n,delta) ∈ A. n < N)"
definition
bounded :: "(nat * 'a) set => bool" where
"bounded A ⟷ (∃N . boundedBy N A)"
lemma boundedByEmpty[simp]: "boundedBy N {}"
by(simp add: boundedBy_def)
lemma boundedByInsert: "boundedBy N (insert (n,delta) B) = (n < N & boundedBy N B)"
by(simp add: boundedBy_def)
lemma boundedByUn: "boundedBy N (A Un B) = (boundedBy N A & boundedBy N B)"
by(auto simp add: boundedBy_def)
lemma boundedByIncLevel': "boundedBy (Suc N) (incLevel ` A) = boundedBy N A"
by(auto simp add: incLevel_def boundedBy_def)
lemma boundedByAdd1: "boundedBy N B ⟹ boundedBy (N+M) B"
by(auto simp add: boundedBy_def)
lemma boundedByAdd2: "boundedBy M B ⟹ boundedBy (N+M) B"
by(auto simp add: boundedBy_def)
lemma boundedByMono: "boundedBy m B ⟹ m < M ⟹ boundedBy M B"
by(auto simp: boundedBy_def)
lemmas boundedByMonoD = boundedByMono
lemma boundedBy0: "boundedBy 0 A = (A = {})"
apply(simp add: boundedBy_def)
apply(auto simp add: boundedBy_def)
done
lemma boundedBySuc': "boundedBy N A ⟹ boundedBy (Suc N) A"
by (auto simp add: boundedBy_def)
lemma boundedByIncLevel: "boundedBy n (incLevel ` (tree subs gamma)) = ( ∃m . n = Suc m & boundedBy m (tree subs gamma))"
apply(cases n)
apply(force simp add: boundedBy0 tree0)
apply(force simp add: treeEquation [of _ gamma] incLevel_def boundedBy_def)
done
lemma boundedByUN: "boundedBy N (UN x:A. B x) = (!x:A. boundedBy N (B x))"
by(simp add: boundedBy_def)
lemma boundedBySuc[rule_format]: "sigma ∈ subs Gamma ⟹ boundedBy (Suc n) (tree subs Gamma) ⟶ boundedBy n (tree subs sigma)"
apply(subst treeEquation [of _ Gamma])
apply rule
apply(simp add: boundedByInsert)
apply(simp add: boundedByUN)
apply(drule_tac x=sigma in bspec) apply assumption
apply(simp add: boundedByIncLevel)
done
subsection "Inherited Properties- bounded"
lemma boundedEmpty: "bounded {}"
by(simp add: bounded_def)
lemma boundedUn: "bounded (A Un B) = (bounded A & bounded B)"
apply(auto simp add: bounded_def boundedByUn)
apply(rule_tac x="N+Na" in exI)
apply(blast intro: boundedByAdd1 boundedByAdd2)
done
lemma boundedIncLevel: "bounded (incLevel` A) = (bounded A)"
apply (simp add: bounded_def, rule)
apply(erule exE)
apply(rule_tac x=N in exI)
apply (simp add: boundedBy_def incLevel_def, force)
apply(erule exE)
apply(rule_tac x="Suc N" in exI)
apply (simp add: boundedBy_def incLevel_def, force)
done
lemma boundedInsert: "bounded (insert a B) = (bounded B)"
apply(case_tac a)
apply (simp add: bounded_def boundedByInsert, rule) apply blast
apply(erule exE)
apply(rule_tac x="Suc(aa+N)" in exI)
apply(force intro:boundedByMono)
done
lemma inheritedBounded: "inherited subs bounded"
by(blast intro!: inheritedI boundedUn[symmetric] boundedIncLevel[symmetric]
boundedInsert[symmetric] boundedEmpty)
subsection "founded"
definition
founded :: "['a => 'a set,'a => bool,(nat * 'a) set] => bool" where
"founded subs Pred = (%A. !(n,delta):A. terminal subs delta --> Pred delta)"
lemma foundedD: "founded subs P (tree subs delta) ==> terminal subs delta ==> P delta"
by(simp add: treeEquation [of _ delta] founded_def)
lemma foundedMono: "[| founded subs P A; ∀x. P x --> Q x |] ==> founded subs Q A"
by (auto simp: founded_def)
lemma foundedSubs: "founded subs P (tree subs Gamma) ⟹ sigma ∈ subs Gamma ⟹ founded subs P (tree subs sigma)"
apply(simp add: founded_def)
apply(intro ballI impI)
apply (case_tac x, simp, rule)
apply(drule_tac x="(Suc a, b)" in bspec)
apply(subst treeEquation)
apply (force simp: incLevel_def, simp)
done
subsection "Inherited Properties- founded"
lemma foundedInsert[rule_format]: "~ terminal subs delta --> founded subs P (insert (n,delta) B) = (founded subs P B)"
apply(simp add: terminal_def founded_def) done
lemma foundedUn: "(founded subs P (A Un B)) = (founded subs P A & founded subs P B)"
apply(simp add: founded_def) by force
lemma foundedIncLevel: "founded subs P (incLevel ` A) = (founded subs P A)"
apply (simp add: founded_def incLevel_def, auto) done
lemma foundedEmpty: "founded subs P {}"
by(auto simp add: founded_def)
lemma inheritedFounded: "inherited subs (founded subs P)"
by(blast intro!: inheritedI foundedUn[symmetric] foundedIncLevel[symmetric]
foundedInsert[symmetric] foundedEmpty)
subsection "Inherited Properties- finite"
lemmas finiteInsert = finite_insert
lemma finiteUn: "finite (A Un B) = (finite A & finite B)"
apply simp done
lemma finiteIncLevel: "finite (incLevel ` A) = finite A"
apply (insert injIncLevel, rule)
apply(frule finite_imageD)
apply (blast intro: subset_inj_on, assumption)
apply(rule finite_imageI)
by assumption
lemma finiteEmpty: "finite {}" by auto
lemma inheritedFinite: "inherited subs (%A. finite A)"
apply(blast intro!: inheritedI finiteUn[symmetric] finiteIncLevel[symmetric] finiteInsert[symmetric] finiteEmpty)
done
subsection "path: follows a failing inherited property through tree"
definition
failingSub :: "['a => 'a set,(nat * 'a) set => bool,'a] => 'a" where
"failingSub subs P gamma = (SOME sigma. (sigma:subs gamma & ~P(tree subs sigma)))"
lemma failingSubProps: "[| inherited subs P; ~P (tree subs gamma); ~(terminal subs gamma); fans subs |]
==> failingSub subs P gamma ∈ subs gamma & ~(P (tree subs (failingSub subs P gamma)))"
apply(simp add: failingSub_def)
apply(drule inheritedPropagate) apply(assumption+)
apply(erule bexE)
apply (rule someI2, auto)
done
lemma failingSubFailsI: "[| inherited subs P; ~P (tree subs gamma); ~(terminal subs gamma); fans subs |]
==> ~(P (tree subs (failingSub subs P gamma)))"
apply(rule conjunct2[OF failingSubProps]) .
lemmas failingSubFailsE = failingSubFailsI[THEN notE]
lemma failingSubSubs: "[| inherited subs P; ~P (tree subs gamma); ~(terminal subs gamma); fans subs |]
==> failingSub subs P gamma ∈ subs gamma"
apply(rule conjunct1[OF failingSubProps]) .
primrec path :: "['a => 'a set,'a,(nat * 'a) set => bool,nat] => 'a"
where
path0: "path subs gamma P 0 = gamma"
| pathSuc: "path subs gamma P (Suc n) = (if terminal subs (path subs gamma P n)
then path subs gamma P n
else failingSub subs P (path subs gamma P n))"
lemma pathFailsP: "[| inherited subs P; fans subs; ~P(tree subs gamma) |]
==> ~(P (tree subs (path subs gamma P n)))"
apply (induct_tac n, simp, simp)
apply rule
apply(rule failingSubFailsI) apply(assumption+)
done
lemmas PpathE = pathFailsP[THEN notE]
lemma pathTerminal[rule_format]: "[| inherited subs P; fans subs; terminal subs gamma |]
==> terminal subs (path subs gamma P n)"
apply (induct_tac n, simp_all) done
lemma pathStarts: "path subs gamma P 0 = gamma"
by simp
lemma pathSubs: "[| inherited subs P; fans subs; ~P(tree subs gamma); ~ (terminal subs (path subs gamma P n)) |]
==> path subs gamma P (Suc n) ∈ subs (path subs gamma P n)"
apply simp
apply (rule failingSubSubs, assumption)
apply(rule pathFailsP)
apply(assumption+)
done
lemma pathStops: "terminal subs (path subs gamma P n) ==> path subs gamma P (Suc n) = path subs gamma P n"
by simp
subsection "Branch"
definition
branch :: "['a => 'a set,'a,nat => 'a] => bool" where
"branch subs Gamma f ⟷ f 0 = Gamma
& (!n . terminal subs (f n) --> f (Suc n) = f n)
& (!n . ~ terminal subs (f n) --> f (Suc n) ∈ subs (f n))"
lemma branch0: "branch subs Gamma f ==> f 0 = Gamma"
by (simp add: branch_def)
lemma branchStops: "branch subs Gamma f ==> terminal subs (f n) ==> f (Suc n) = f n"
by (simp add: branch_def)
lemma branchSubs: "branch subs Gamma f ==> ~ terminal subs (f n) ==> f (Suc n) ∈ subs (f n)"
by (simp add: branch_def)
lemma branchI: "[| (f 0 = Gamma);
!n . terminal subs (f n) --> f (Suc n) = f n;
!n . ~ terminal subs (f n) --> f (Suc n) ∈ subs (f n) |] ==> branch subs Gamma f"
by (simp add: branch_def)
lemma branchTerminalPropagates: "branch subs Gamma f ==> terminal subs (f m) ==> terminal subs (f (m + n))"
apply (induct_tac n, simp)
by(simp add: branchStops)
lemma branchTerminalMono: "branch subs Gamma f ==> m < n ==> terminal subs (f m) ==> terminal subs (f n)"
apply(subgoal_tac "terminal subs (f (m+(n-m)))") apply force
apply(rule branchTerminalPropagates)
.
lemma branchPath:
"[| inherited subs P; fans subs; ~P(tree subs gamma) |]
==> branch subs gamma (path subs gamma P)"
by(auto intro!: branchI pathStarts pathSubs pathStops)
subsection "failing branch property: abstracts path defn"
lemma failingBranchExistence: "!!subs.
[| inherited subs P; fans subs; ~P(tree subs gamma) |]
==> ∃f . branch subs gamma f & (∀n . ~P(tree subs (f n)))"
apply(rule_tac x="path subs gamma P" in exI)
apply(rule conjI)
apply(force intro!: branchPath)
apply(intro allI)
apply(rule pathFailsP)
by auto
definition
infBranch :: "['a => 'a set,'a,nat => 'a] => bool" where
"infBranch subs Gamma f ⟷ f 0 = Gamma & (∀n. f (Suc n) ∈ subs (f n))"
lemma infBranchI: "[| (f 0 = Gamma); !n . f (Suc n) ∈ subs (f n) |] ==> infBranch subs Gamma f"
by (simp add: infBranch_def)
subsection "Tree induction principles"
lemma boundedTreeInduction':
"⟦ fans subs;
∀delta. ~ terminal subs delta --> (∀sigma ∈ subs delta. P sigma) --> P delta ⟧
⟹ ∀Gamma. boundedBy m (tree subs Gamma) ⟶ founded subs P (tree subs Gamma) ⟶ P Gamma"
apply(induct_tac m)
apply(intro impI allI)
apply(simp add: boundedBy0)
apply(subgoal_tac "(0,Gamma) ∈ tree subs Gamma") apply blast apply(rule tree0)
apply(intro impI allI)
apply(drule_tac x=Gamma in spec)
apply (case_tac "terminal subs Gamma", simp)
apply(drule_tac foundedD) apply assumption apply assumption
apply (erule impE, assumption)
apply (erule impE, rule)
apply(drule_tac x=sigma in spec)
apply(erule impE)
apply(rule boundedBySuc) apply assumption apply assumption
apply(erule impE)
apply(rule foundedSubs) apply assumption apply assumption
apply assumption
apply assumption
done
lemma boundedTreeInduction:
"⟦fans subs;
bounded (tree subs Gamma); founded subs P (tree subs Gamma);
∀delta. ~ terminal subs delta --> (∀sigma ∈ subs delta. P sigma) --> P delta
⟧ ⟹ P Gamma"
apply(unfold bounded_def)
apply(erule exE)
apply(frule_tac boundedTreeInduction') apply assumption
apply force
done
lemma boundedTreeInduction2':
"[| fans subs;
∀delta. (∀sigma ∈ subs delta. P sigma) --> P delta |]
==> ∀Gamma. boundedBy m (tree subs Gamma) ⟶ P Gamma"
apply(induct_tac m)
apply(intro impI allI)
apply(simp (no_asm_use) add: boundedBy0)
apply(subgoal_tac "(0,Gamma) ∈ tree subs Gamma") apply blast apply(rule tree0)
apply(intro impI allI)
apply(drule_tac x=Gamma in spec)
apply (erule impE, rule)
apply(drule_tac x=sigma in spec)
apply(erule impE)
apply(rule boundedBySuc) apply assumption apply assumption
apply assumption
apply assumption
done
lemma boundedTreeInduction2:
"[| fans subs; boundedBy m (tree subs Gamma);
∀delta. (∀sigma ∈ subs delta. P sigma) --> P delta |]
==> P Gamma"
by (frule_tac boundedTreeInduction2', assumption, blast)
end