Theory Trail
section‹Trail datatype definition and its properties›
theory Trail
imports MoreList
begin
text‹Trail is a list in which some elements can be marked.›
type_synonym 'a Trail = "('a*bool) list"
abbreviation
element :: "('a*bool) ⇒ 'a"
where "element x == fst x"
abbreviation
marked :: "('a*bool) ⇒ bool"
where "marked x == snd x"
subsection‹Trail elements›
text‹Elements of the trail with marks removed›
primrec
elements :: "'a Trail ⇒ 'a list"
where
"elements [] = []"
| "elements (h#t) = (element h) # (elements t)"
lemma
"elements t = map fst t"
by (induct t) auto
lemma eitherMarkedOrNotMarkedElement:
shows "a = (element a, True) ∨ a = (element a, False)"
by (cases a) auto
lemma eitherMarkedOrNotMarked:
assumes "e ∈ set (elements M)"
shows "(e, True) ∈ set M ∨ (e, False) ∈ set M"
using assms
proof (induct M)
case (Cons m M')
thus ?case
proof (cases "e = element m")
case True
thus ?thesis
using eitherMarkedOrNotMarkedElement [of "m"]
by auto
next
case False
with Cons
show ?thesis
by auto
qed
qed simp
lemma elementMemElements [simp]:
assumes "x ∈ set M"
shows "element x ∈ set (elements M)"
using assms
by (induct M) (auto split: if_split_asm)
lemma elementsAppend [simp]:
shows "elements (a @ b) = elements a @ elements b"
by (induct a) auto
lemma elementsEmptyIffTrailEmpty [simp]:
shows "(elements list = []) = (list = [])"
by (induct list) auto
lemma elementsButlastTrailIsButlastElementsTrail [simp]:
shows "elements (butlast M) = butlast (elements M)"
by (induct M) auto
lemma elementLastTrailIsLastElementsTrail [simp]:
assumes "M ≠ []"
shows "element (last M) = last (elements M)"
using assms
by (induct M) auto
lemma isPrefixElements:
assumes "isPrefix a b"
shows "isPrefix (elements a) (elements b)"
using assms
unfolding isPrefix_def
by auto
lemma prefixElementsAreTrailElements:
assumes
"isPrefix p M"
shows
"set (elements p) ⊆ set (elements M)"
using assms
unfolding isPrefix_def
by auto
lemma uniqElementsTrailImpliesUniqElementsPrefix:
assumes
"isPrefix p M" and "uniq (elements M)"
shows
"uniq (elements p)"
proof-
from ‹isPrefix p M›
obtain s
where "M = p @ s"
unfolding isPrefix_def
by auto
with ‹uniq (elements M)›
show ?thesis
using uniqAppend[of "elements p" "elements s"]
by simp
qed
lemma [simp]:
assumes "(e, d) ∈ set M"
shows "e ∈ set (elements M)"
using assms
by (induct M) auto
lemma uniqImpliesExclusiveTrueOrFalse:
assumes
"(e, d) ∈ set M" and "uniq (elements M)"
shows
"¬ (e, ¬ d) ∈ set M"
using assms
proof (induct M)
case (Cons m M')
{
assume "(e, d) = m"
hence "(e, ¬ d) ≠ m"
by auto
from ‹(e, d) = m› ‹uniq (elements (m # M'))›
have "¬ (e, d) ∈ set M'"
by (auto simp add: uniqAppendIff)
with Cons
have ?case
by (auto split: if_split_asm)
}
moreover
{
assume "(e, ¬ d) = m"
hence "(e, d) ≠ m"
by auto
from ‹(e, ¬ d) = m› ‹uniq (elements (m # M'))›
have "¬ (e, ¬ d) ∈ set M'"
by (auto simp add: uniqAppendIff)
with Cons
have ?case
by (auto split: if_split_asm)
}
moreover
{
assume "(e, d) ≠ m" "(e, ¬ d) ≠ m"
from ‹(e, d) ≠ m› ‹(e, d) ∈ set (m # M')› have
"(e, d) ∈ set M'"
by simp
with ‹uniq (elements (m # M'))› Cons(1)
have "¬ (e, ¬ d) ∈ set M'"
by simp
with ‹(e, ¬ d) ≠ m›
have ?case
by simp
}
moreover
{
have "(e, d) = m ∨ (e, ¬ d) = m ∨ (e, d) ≠ m ∧ (e, ¬ d) ≠ m"
by auto
}
ultimately
show ?case
by auto
qed simp
subsection‹Marked trail elements›
primrec
markedElements :: "'a Trail ⇒ 'a list"
where
"markedElements [] = []"
| "markedElements (h#t) = (if (marked h) then (element h) # (markedElements t) else (markedElements t))"
lemma
"markedElements t = (elements (filter snd t))"
by (induct t) auto
lemma markedElementIsMarkedTrue:
shows "(m ∈ set (markedElements M)) = ((m, True) ∈ set M)"
by (induct M) (auto split: if_split_asm)
lemma markedElementsAppend:
shows "markedElements (M1 @ M2) = markedElements M1 @ markedElements M2"
by (induct M1) auto
lemma markedElementsAreElements:
assumes "m ∈ set (markedElements M)"
shows "m ∈ set (elements M)"
using assms markedElementIsMarkedTrue[of "m" "M"]
by auto
lemma markedAndMemberImpliesIsMarkedElement:
assumes "marked m" "m ∈ set M"
shows "(element m) ∈ set (markedElements M)"
proof-
have "m = (element m, marked m)"
by auto
with ‹marked m›
have "m = (element m, True)"
by simp
with ‹m ∈ set M› have
"(element m, True) ∈ set M"
by simp
thus ?thesis
using markedElementIsMarkedTrue [of "element m" "M"]
by simp
qed
lemma :
assumes "isPrefix p M" "m ∈ set (markedElements p)"
shows "m ∈ set (markedElements M)"
proof-
from ‹m ∈ set (markedElements p)›
have "(m, True) ∈ set p"
by (simp add: markedElementIsMarkedTrue)
with ‹isPrefix p M›
have "(m, True) ∈ set M"
using prefixIsSubset[of "p" "M"]
by auto
thus ?thesis
by (simp add: markedElementIsMarkedTrue)
qed
lemma :
assumes
"uniq (elements M)" and
"isPrefix p M" and
"m ∈ set (elements p)" and
"m ∈ set (markedElements M)"
shows
"m ∈ set (markedElements p)"
proof-
from ‹m ∈ set (markedElements M)› have "(m, True) ∈ set M"
by (simp add: markedElementIsMarkedTrue)
with ‹uniq (elements M)› ‹m ∈ set (elements p)›
have "(m, True) ∈ set p"
proof-
{
assume "(m, False) ∈ set p"
with ‹isPrefix p M›
have "(m, False) ∈ set M"
using prefixIsSubset[of "p" "M"]
by auto
with ‹(m, True) ∈ set M› ‹uniq (elements M)›
have False
using uniqImpliesExclusiveTrueOrFalse[of "m" "True" "M"]
by simp
}
with ‹m ∈ set (elements p)›
show ?thesis
using eitherMarkedOrNotMarked[of "m" "p"]
by auto
qed
thus ?thesis
using markedElementIsMarkedTrue[of "m" "p"]
by simp
qed
subsection‹Prefix before/upto a trail element›
text‹Elements of the trail before the first occurrence of a given element - not incuding it›
primrec
prefixBeforeElement :: "'a ⇒ 'a Trail ⇒ 'a Trail"
where
"prefixBeforeElement e [] = []"
| "prefixBeforeElement e (h#t) =
(if (element h) = e then
[]
else
(h # (prefixBeforeElement e t))
)"
lemma "prefixBeforeElement e t = takeWhile (λ e'. element e' ≠ e) t"
by (induct t) auto
lemma "prefixBeforeElement e t = take (firstPos e (elements t)) t"
by (induct t) auto
text‹Elements of the trail before the first occurrence of a given element - incuding it›
primrec
prefixToElement :: "'a ⇒ 'a Trail ⇒ 'a Trail"
where
"prefixToElement e [] = []"
| "prefixToElement e (h#t) =
(if (element h) = e then
[h]
else
(h # (prefixToElement e t))
)"
lemma "prefixToElement e t = take ((firstPos e (elements t)) + 1) t"
by (induct t) auto
lemma isPrefixPrefixToElement:
shows "isPrefix (prefixToElement e t) t"
unfolding isPrefix_def
by (induct t) auto
lemma isPrefixPrefixBeforeElement:
shows "isPrefix (prefixBeforeElement e t) t"
unfolding isPrefix_def
by (induct t) auto
lemma prefixToElementContainsTrailElement:
assumes "e ∈ set (elements M)"
shows "e ∈ set (elements (prefixToElement e M))"
using assms
by (induct M) auto
lemma prefixBeforeElementDoesNotContainTrailElement:
assumes "e ∈ set (elements M)"
shows "e ∉ set (elements (prefixBeforeElement e M))"
using assms
by (induct M) auto
lemma prefixToElementAppend:
shows "prefixToElement e (M1 @ M2) =
(if e ∈ set (elements M1) then
prefixToElement e M1
else
M1 @ prefixToElement e M2
)"
by (induct M1) auto
lemma prefixToElementToPrefixElement:
assumes
"isPrefix p M" and "e ∈ set (elements p)"
shows
"prefixToElement e M = prefixToElement e p"
using assms
unfolding isPrefix_def
proof (induct p arbitrary: M)
case (Cons a p')
then obtain s
where "(a # p') @ s = M"
by auto
show ?case
proof (cases "(element a) = e")
case True
from True ‹(a # p') @ s = M› have "prefixToElement e M = [a]"
by auto
moreover
from True have "prefixToElement e (a # p') = [a]"
by auto
ultimately
show ?thesis
by simp
next
case False
from False ‹(a # p') @ s = M› have "prefixToElement e M = a # prefixToElement e (p' @ s)"
by auto
moreover
from False have "prefixToElement e (a # p') = a # prefixToElement e p'"
by simp
moreover
from False ‹e ∈ set (elements (a # p'))› have "e ∈ set (elements p')"
by simp
have "? s . (p' @ s = p' @ s)"
by simp
from ‹e ∈ set (elements p')› ‹? s. (p' @ s = p' @ s)›
have "prefixToElement e (p' @ s) = prefixToElement e p'"
using Cons(1) [of "p' @ s"]
by simp
ultimately show ?thesis
by simp
qed
qed simp
subsection‹Marked elements upto a given trail element›
text‹Marked elements of the trail upto the given element (which is also included if it is marked)›
definition
markedElementsTo :: "'a ⇒ 'a Trail ⇒ 'a list"
where
"markedElementsTo e t = markedElements (prefixToElement e t)"
lemma markedElementsToArePrefixOfMarkedElements:
shows "isPrefix (markedElementsTo e M) (markedElements M)"
unfolding isPrefix_def
unfolding markedElementsTo_def
by (induct M) auto
lemma :
assumes "m ∈ set (markedElementsTo e M)"
shows "m ∈ set (markedElements M)"
using assms
using markedElementsToArePrefixOfMarkedElements[of "e" "M"]
using prefixIsSubset
by auto
lemma markedElementsToNonMemberAreAllMarkedElements:
assumes "e ∉ set (elements M)"
shows "markedElementsTo e M = markedElements M"
using assms
unfolding markedElementsTo_def
by (induct M) auto
lemma markedElementsToAppend:
shows "markedElementsTo e (M1 @ M2) =
(if e ∈ set (elements M1) then
markedElementsTo e M1
else
markedElements M1 @ markedElementsTo e M2
)"
unfolding markedElementsTo_def
by (auto simp add: prefixToElementAppend markedElementsAppend)
lemma markedElementsEmptyImpliesMarkedElementsToEmpty:
assumes "markedElements M = []"
shows "markedElementsTo e M = []"
using assms
using markedElementsToArePrefixOfMarkedElements [of "e" "M"]
unfolding isPrefix_def
by auto
lemma markedElementIsMemberOfItsMarkedElementsTo:
assumes
"uniq (elements M)" and "marked e" and "e ∈ set M"
shows
"element e ∈ set (markedElementsTo (element e) M)"
using assms
unfolding markedElementsTo_def
by (induct M) (auto split: if_split_asm)
lemma markedElementsToPrefixElement:
assumes "isPrefix p M" and "e ∈ set (elements p)"
shows "markedElementsTo e M = markedElementsTo e p"
unfolding markedElementsTo_def
using assms
by (simp add: prefixToElementToPrefixElement)
subsection‹Last marked element in a trail›
definition
lastMarked :: "'a Trail ⇒ 'a"
where
"lastMarked t = last (markedElements t)"
lemma lastMarkedIsMarkedElement:
assumes "markedElements M ≠ []"
shows "lastMarked M ∈ set (markedElements M)"
using assms
unfolding lastMarked_def
by simp
lemma removeLastMarkedFromMarkedElementsToLastMarkedAreAllMarkedElementsInPrefixLastMarked:
assumes
"markedElements M ≠ []"
shows
"removeAll (lastMarked M) (markedElementsTo (lastMarked M) M) = markedElements (prefixBeforeElement (lastMarked M) M)"
using assms
unfolding lastMarked_def
unfolding markedElementsTo_def
by (induct M) auto
lemma markedElementsToLastMarkedAreAllMarkedElements:
assumes
"uniq (elements M)" and "markedElements M ≠ []"
shows
"markedElementsTo (lastMarked M) M = markedElements M"
using assms
unfolding lastMarked_def
unfolding markedElementsTo_def
by (induct M) (auto simp add: markedElementsAreElements)
lemma lastTrailElementMarkedImpliesMarkedElementsToLastElementAreAllMarkedElements:
assumes
"marked (last M)" and "last (elements M) ∉ set (butlast (elements M))"
shows
"markedElementsTo (last (elements M)) M = markedElements M"
using assms
unfolding markedElementsTo_def
by (induct M) auto
lemma lastMarkedIsMemberOfItsMarkedElementsTo:
assumes
"uniq (elements M)" and "markedElements M ≠ []"
shows
"lastMarked M ∈ set (markedElementsTo (lastMarked M) M)"
using assms
using markedElementsToLastMarkedAreAllMarkedElements [of "M"]
using lastMarkedIsMarkedElement [of "M"]
by auto
lemma :
assumes "¬ marked (last M)"
shows "markedElementsTo e M = markedElementsTo e (butlast M)"
using assms
unfolding markedElementsTo_def
by (induct M) auto
subsection‹Level of a trail element›
text‹Level of an element is the number of marked elements that precede it›
definition
elementLevel :: "'a ⇒ 'a Trail ⇒ nat"
where
"elementLevel e t = length (markedElementsTo e t)"
lemma elementLevelMarkedGeq1:
assumes
"uniq (elements M)" and "e ∈ set (markedElements M)"
shows
"elementLevel e M >= 1"
proof-
from ‹e ∈ set (markedElements M)› have "(e, True) ∈ set M"
by (simp add: markedElementIsMarkedTrue)
with ‹uniq (elements M)› have "e ∈ set (markedElementsTo e M)"
using markedElementIsMemberOfItsMarkedElementsTo[of "M" "(e, True)"]
by simp
hence "markedElementsTo e M ≠ []"
by auto
thus ?thesis
unfolding elementLevel_def
using length_greater_0_conv[of "markedElementsTo e M"]
by arith
qed
lemma elementLevelAppend:
assumes "a ∈ set (elements M)"
shows "elementLevel a M = elementLevel a (M @ M')"
using assms
unfolding elementLevel_def
by (simp add: markedElementsToAppend)
lemma elementLevelPrecedesLeq:
assumes
"precedes a b (elements M)"
shows
"elementLevel a M ≤ elementLevel b M"
using assms
proof (induct M)
case (Cons m M')
{
assume "a = element m"
hence ?case
unfolding elementLevel_def
unfolding markedElementsTo_def
by simp
}
moreover
{
assume "b = element m"
{
assume "a ≠ b"
hence "¬ precedes a b (b # (elements M'))"
by (rule noElementsPrecedesFirstElement)
with ‹b = element m› ‹precedes a b (elements (m # M'))›
have False
by simp
}
hence "a = b"
by auto
hence ?case
by simp
}
moreover
{
assume "a ≠ element m" "b ≠ element m"
moreover
from ‹precedes a b (elements (m # M'))›
have "a ∈ set (elements (m # M'))" "b ∈ set (elements (m # M'))"
unfolding precedes_def
by (auto split: if_split_asm)
from ‹a ≠ element m› ‹a ∈ set (elements (m # M'))›
have "a ∈ set (elements M')"
by simp
moreover
from ‹b ≠ element m› ‹b ∈ set (elements (m # M'))›
have "b ∈ set (elements M')"
by simp
ultimately
have "elementLevel a M' ≤ elementLevel b M'"
using Cons
unfolding precedes_def
by auto
hence ?case
using ‹a ≠ element m› ‹b ≠ element m›
unfolding elementLevel_def
unfolding markedElementsTo_def
by auto
}
ultimately
show ?case
by auto
next
case Nil
thus ?case
unfolding precedes_def
by simp
qed
lemma elementLevelPrecedesMarkedElementLt:
assumes
"uniq (elements M)" and
"e ≠ d" and
"d ∈ set (markedElements M)" and
"precedes e d (elements M)"
shows
"elementLevel e M < elementLevel d M"
using assms
proof (induct M)
case (Cons m M')
{
assume "e = element m"
moreover
with ‹e ≠ d› have "d ≠ element m"
by simp
moreover
from ‹uniq (elements (m # M'))› ‹d ∈ set (markedElements (m # M'))›
have "1 ≤ elementLevel d (m # M')"
using elementLevelMarkedGeq1[of "m # M'" "d"]
by auto
moreover
from ‹d ≠ element m› ‹d ∈ set (markedElements (m # M'))›
have "d ∈ set (markedElements M')"
by (simp split: if_split_asm)
from ‹uniq (elements (m # M'))› ‹d ∈ set (markedElements M')›
have "1 ≤ elementLevel d M'"
using elementLevelMarkedGeq1[of "M'" "d"]
by auto
ultimately
have ?case
unfolding elementLevel_def
unfolding markedElementsTo_def
by (auto split: if_split_asm)
}
moreover
{
assume "d = element m"
from ‹e ≠ d› have "¬ precedes e d (d # (elements M'))"
using noElementsPrecedesFirstElement[of "e" "d" "elements M'"]
by simp
with ‹d = element m› ‹precedes e d (elements (m # M'))›
have False
by simp
hence ?case
by simp
}
moreover
{
assume "e ≠ element m" "d ≠ element m"
moreover
from ‹precedes e d (elements (m # M'))›
have "e ∈ set (elements (m # M'))" "d ∈ set (elements (m # M'))"
unfolding precedes_def
by (auto split: if_split_asm)
from ‹e ≠ element m› ‹e ∈ set (elements (m # M'))›
have "e ∈ set (elements M')"
by simp
moreover
from ‹d ≠ element m› ‹d ∈ set (elements (m # M'))›
have "d ∈ set (elements M')"
by simp
moreover
from ‹d ≠ element m› ‹d ∈ set (markedElements (m # M'))›
have "d ∈ set (markedElements M')"
by (simp split: if_split_asm)
ultimately
have "elementLevel e M' < elementLevel d M'"
using ‹uniq (elements (m # M'))› Cons
unfolding precedes_def
by auto
hence ?case
using ‹e ≠ element m› ‹d ≠ element m›
unfolding elementLevel_def
unfolding markedElementsTo_def
by auto
}
ultimately
show ?case
by auto
qed simp
lemma differentMarkedElementsHaveDifferentLevels:
assumes
"uniq (elements M)" and
"a ∈ set (markedElements M)" and
"b ∈ set (markedElements M)" and
"a ≠ b"
shows "elementLevel a M ≠ elementLevel b M"
proof-
from ‹a ∈ set (markedElements M)›
have "a ∈ set (elements M)"
by (simp add: markedElementsAreElements)
moreover
from ‹b ∈ set (markedElements M)›
have "b ∈ set (elements M)"
by (simp add: markedElementsAreElements)
ultimately
have "precedes a b (elements M) ∨ precedes b a (elements M)"
using ‹a ≠ b›
using precedesTotalOrder[of "a" "elements M" "b"]
by simp
moreover
{
assume "precedes a b (elements M)"
with assms
have ?thesis
using elementLevelPrecedesMarkedElementLt[of "M" "a" "b"]
by auto
}
moreover
{
assume "precedes b a (elements M)"
with assms
have ?thesis
using elementLevelPrecedesMarkedElementLt[of "M" "b" "a"]
by auto
}
ultimately
show ?thesis
by auto
qed
subsection‹Current trail level›
text‹Current level is the number of marked elements in the trail›
definition
currentLevel :: "'a Trail ⇒ nat"
where
"currentLevel t = length (markedElements t)"
lemma currentLevelNonMarked:
shows "currentLevel M = currentLevel (M @ [(l, False)])"
by (auto simp add:currentLevel_def markedElementsAppend)
lemma currentLevelPrefix:
assumes "isPrefix a b"
shows "currentLevel a <= currentLevel b"
using assms
unfolding isPrefix_def
unfolding currentLevel_def
by (auto simp add: markedElementsAppend)
lemma elementLevelLeqCurrentLevel:
shows "elementLevel a M ≤ currentLevel M"
proof-
have "isPrefix (prefixToElement a M) M"
using isPrefixPrefixToElement[of "a" "M"]
.
then obtain s
where "prefixToElement a M @ s = M"
unfolding isPrefix_def
by auto
hence "M = prefixToElement a M @ s"
by (rule sym)
hence "currentLevel M = currentLevel (prefixToElement a M @ s)"
by simp
hence "currentLevel M = length (markedElements (prefixToElement a M)) + length (markedElements s)"
unfolding currentLevel_def
by (simp add: markedElementsAppend)
thus ?thesis
unfolding elementLevel_def
unfolding markedElementsTo_def
by simp
qed
lemma elementOnCurrentLevel:
assumes "a ∉ set (elements M)"
shows "elementLevel a (M @ [(a, d)]) = currentLevel (M @ [(a, d)])"
using assms
unfolding currentLevel_def
unfolding elementLevel_def
unfolding markedElementsTo_def
by (auto simp add: prefixToElementAppend)
subsection‹Prefix to a given trail level›
text‹Prefix is made or elements of the trail up to a given element level›
primrec
prefixToLevel_aux :: "'a Trail ⇒ nat ⇒ nat ⇒ 'a Trail"
where
"(prefixToLevel_aux [] l cl) = []"
| "(prefixToLevel_aux (h#t) l cl) =
(if (marked h) then
(if (cl >= l) then [] else (h # (prefixToLevel_aux t l (cl+1))))
else
(h # (prefixToLevel_aux t l cl))
)"
definition
prefixToLevel :: "nat ⇒ 'a Trail ⇒ 'a Trail"
where
prefixToLevel_def: "(prefixToLevel l t) == (prefixToLevel_aux t l 0)"
lemma isPrefixPrefixToLevel_aux:
shows "∃ s. prefixToLevel_aux t l i @ s = t"
by (induct t arbitrary: i) auto
lemma isPrefixPrefixToLevel:
shows "(isPrefix (prefixToLevel l t) t)"
using isPrefixPrefixToLevel_aux[of "t" "l"]
unfolding isPrefix_def
unfolding prefixToLevel_def
by simp
lemma currentLevelPrefixToLevel_aux:
assumes "l ≥ i"
shows "currentLevel (prefixToLevel_aux M l i) <= l - i"
using assms
proof (induct M arbitrary: i)
case (Cons m M')
{
assume "marked m" "i = l"
hence ?case
unfolding currentLevel_def
by simp
}
moreover
{
assume "marked m" "i < l"
hence ?case
using Cons(1) [of "i+1"]
unfolding currentLevel_def
by simp
}
moreover
{
assume "¬ marked m"
hence ?case
using Cons
unfolding currentLevel_def
by simp
}
ultimately
show ?case
using ‹i <= l›
by auto
next
case Nil
thus ?case
unfolding currentLevel_def
by simp
qed
lemma currentLevelPrefixToLevel:
shows "currentLevel (prefixToLevel level M) ≤ level"
using currentLevelPrefixToLevel_aux[of "0" "level" "M"]
unfolding prefixToLevel_def
by simp
lemma currentLevelPrefixToLevelEq_aux:
assumes "l ≥ i" "currentLevel M >= l - i"
shows "currentLevel (prefixToLevel_aux M l i) = l - i"
using assms
proof (induct M arbitrary: i)
case (Cons m M')
{
assume "marked m" "i = l"
hence ?case
unfolding currentLevel_def
by simp
}
moreover
{
assume "marked m" "i < l"
hence ?case
using Cons(1) [of "i+1"]
using Cons(3)
unfolding currentLevel_def
by simp
}
moreover
{
assume "¬ marked m"
hence ?case
using Cons
unfolding currentLevel_def
by simp
}
ultimately
show ?case
using ‹i <= l›
by auto
next
case Nil
thus ?case
unfolding currentLevel_def
by simp
qed
lemma currentLevelPrefixToLevelEq:
assumes
"level ≤ currentLevel M"
shows
"currentLevel (prefixToLevel level M) = level"
using assms
unfolding prefixToLevel_def
using currentLevelPrefixToLevelEq_aux[of "0" "level" "M"]
by simp
lemma prefixToLevel_auxIncreaseAuxilaryCounter:
assumes "k ≥ i"
shows "prefixToLevel_aux M l i = prefixToLevel_aux M (l + (k - i)) k"
using assms
proof (induct M arbitrary: i k)
case (Cons m M')
{
assume "¬ marked m"
hence ?case
using Cons(1)[of "i" "k"] Cons(2)
by simp
}
moreover
{
assume "i ≥ l" "marked m"
hence ?case
using ‹k ≥ i›
by simp
}
moreover
{
assume "i < l" "marked m"
hence ?case
using Cons(1)[of "i+1" "k+1"] Cons(2)
by simp
}
ultimately
show ?case
by (auto split: if_split_asm)
qed simp
lemma isPrefixPrefixToLevel_auxLowerLevel:
assumes "i ≤ j"
shows "isPrefix (prefixToLevel_aux M i k) (prefixToLevel_aux M j k)"
using assms
by (induct M arbitrary: k) (auto simp add:isPrefix_def)
lemma isPrefixPrefixToLevelLowerLevel:
assumes "level < level'"
shows "isPrefix (prefixToLevel level M) (prefixToLevel level' M)"
using assms
unfolding prefixToLevel_def
using isPrefixPrefixToLevel_auxLowerLevel[of "level" "level'" "M" "0"]
by simp
lemma prefixToLevel_auxPrefixToLevel_auxHigherLevel:
assumes "i ≤ j"
shows "prefixToLevel_aux a i k = prefixToLevel_aux (prefixToLevel_aux a j k) i k"
using assms
by (induct a arbitrary: k) auto
lemma prefixToLevelPrefixToLevelHigherLevel:
assumes "level ≤ level'"
shows "prefixToLevel level M = prefixToLevel level (prefixToLevel level' M)"
using assms
unfolding prefixToLevel_def
using prefixToLevel_auxPrefixToLevel_auxHigherLevel[of "level" "level'" "M" "0"]
by simp
lemma prefixToLevelAppend_aux1:
assumes
"l ≥ i" and "l - i < currentLevel a"
shows
"prefixToLevel_aux (a @ b) l i = prefixToLevel_aux a l i"
using assms
proof (induct a arbitrary: i)
case (Cons a a')
{
assume "¬ marked a"
hence ?case
using Cons(1)[of "i"] ‹i ≤ l› ‹l - i < currentLevel (a # a')›
unfolding currentLevel_def
by simp
}
moreover
{
assume "marked a" "l = i"
hence ?case
by simp
}
moreover
{
assume "marked a" "l > i"
hence ?case
using Cons(1)[of "i + 1"] ‹i ≤ l› ‹l - i < currentLevel (a # a')›
unfolding currentLevel_def
by simp
}
ultimately
show ?case
using ‹i ≤ l›
by auto
next
case Nil
thus ?case
unfolding currentLevel_def
by simp
qed
lemma prefixToLevelAppend_aux2:
assumes
"i ≤ l" and "currentLevel a + i ≤ l"
shows "prefixToLevel_aux (a @ b) l i = a @ prefixToLevel_aux b l (i + (currentLevel a))"
using assms
proof (induct a arbitrary: i)
case (Cons a a')
{
assume "¬ marked a"
hence ?case
using Cons
unfolding currentLevel_def
by simp
}
moreover
{
assume "marked a" "l = i"
hence ?case
using ‹(currentLevel (a # a')) + i ≤ l›
unfolding currentLevel_def
by simp
}
moreover
{
assume "marked a" "l > i"
hence "prefixToLevel_aux (a' @ b) l (i + 1) = a' @ prefixToLevel_aux b l (i + 1 + currentLevel a')"
using Cons(1) [of "i + 1"] ‹(currentLevel (a # a')) + i ≤ l›
unfolding currentLevel_def
by simp
moreover
have "i + 1 + length (markedElements a') = i + (1 + length (markedElements a'))"
by simp
ultimately
have ?case
using ‹marked a› ‹l > i›
unfolding currentLevel_def
by simp
}
ultimately
show ?case
using ‹l ≥ i›
by auto
next
case Nil
thus ?case
unfolding currentLevel_def
by simp
qed
lemma prefixToLevelAppend:
shows "prefixToLevel level (a @ b) =
(if level < currentLevel a then
prefixToLevel level a
else
a @ prefixToLevel_aux b level (currentLevel a)
)"
proof (cases "level < currentLevel a")
case True
thus ?thesis
unfolding prefixToLevel_def
using prefixToLevelAppend_aux1[of "0" "level" "a"]
by simp
next
case False
thus ?thesis
unfolding prefixToLevel_def
using prefixToLevelAppend_aux2[of "0" "level" "a"]
by simp
qed
lemma isProperPrefixPrefixToLevel:
assumes "level < currentLevel t"
shows "∃ s. (prefixToLevel level t) @ s = t ∧ s ≠ [] ∧ (marked (hd s))"
proof-
have "isPrefix (prefixToLevel level t) t"
by (simp add:isPrefixPrefixToLevel)
then obtain s::"'a Trail"
where "(prefixToLevel level t) @ s = t"
unfolding isPrefix_def
by auto
moreover
have "s ≠ []"
proof-
{
assume "s = []"
with ‹(prefixToLevel level t) @ s = t›
have "prefixToLevel level t = t"
by simp
hence "currentLevel (prefixToLevel level t) ≤ level"
using currentLevelPrefixToLevel[of "level" "t"]
by simp
with ‹prefixToLevel level t = t› have "currentLevel t ≤ level"
by simp
with ‹level < currentLevel t› have False
by simp
}
thus ?thesis
by auto
qed
moreover
have "marked (hd s)"
proof-
{
assume "¬ marked (hd s)"
have "currentLevel (prefixToLevel level t) ≤ level"
by (simp add:currentLevelPrefixToLevel)
from ‹s ≠ []› have "s = [hd s] @ (tl s)"
by simp
with ‹(prefixToLevel level t) @ s = t› have
"t = (prefixToLevel level t) @ [hd s] @ (tl s)"
by simp
hence "(prefixToLevel level t) = (prefixToLevel level ((prefixToLevel level t) @ [hd s] @ (tl s)))"
by simp
also
with ‹currentLevel (prefixToLevel level t) ≤ level›
have "… = ((prefixToLevel level t) @ (prefixToLevel_aux ([hd s] @ (tl s)) level (currentLevel (prefixToLevel level t))))"
by (auto simp add: prefixToLevelAppend)
also
have "… =
((prefixToLevel level t) @ (hd s) # prefixToLevel_aux (tl s) level (currentLevel (prefixToLevel level t)))"
proof-
from ‹currentLevel (prefixToLevel level t) <= level› ‹¬ marked (hd s)›
have "prefixToLevel_aux ([hd s] @ (tl s)) level (currentLevel (prefixToLevel level t)) =
(hd s) # prefixToLevel_aux (tl s) level (currentLevel (prefixToLevel level t))"
by simp
thus ?thesis
by simp
qed
ultimately
have "(prefixToLevel level t) = (prefixToLevel level t) @ (hd s) # prefixToLevel_aux (tl s) level (currentLevel (prefixToLevel level t))"
by simp
hence "False"
by auto
}
thus ?thesis
by auto
qed
ultimately
show ?thesis
by auto
qed
lemma prefixToLevelElementsElementLevel:
assumes
"e ∈ set (elements (prefixToLevel level M))"
shows
"elementLevel e M ≤ level"
proof -
have "elementLevel e (prefixToLevel level M) ≤ currentLevel (prefixToLevel level M)"
by (simp add: elementLevelLeqCurrentLevel)
moreover
hence "currentLevel (prefixToLevel level M) ≤ level"
using currentLevelPrefixToLevel[of "level" "M"]
by simp
ultimately have "elementLevel e (prefixToLevel level M) ≤ level"
by simp
moreover
have "isPrefix (prefixToLevel level M) M"
by (simp add:isPrefixPrefixToLevel)
then obtain s
where "(prefixToLevel level M) @ s = M"
unfolding isPrefix_def
by auto
with ‹e ∈ set (elements (prefixToLevel level M))›
have "elementLevel e (prefixToLevel level M) = elementLevel e M"
using elementLevelAppend [of "e" "prefixToLevel level M" "s"]
by simp
ultimately
show ?thesis
by simp
qed
lemma elementLevelLtLevelImpliesMemberPrefixToLevel_aux:
assumes
"e ∈ set(elements M)" and
"elementLevel e M + i ≤ level" and
"i ≤ level"
shows
"e ∈ set (elements (prefixToLevel_aux M level i))"
using assms
proof (induct M arbitrary: i)
case (Cons m M')
thus ?case
proof (cases "e = element m")
case True
thus ?thesis
using ‹elementLevel e (m # M') + i ≤ level›
unfolding prefixToLevel_def
unfolding elementLevel_def
unfolding markedElementsTo_def
by (simp split: if_split_asm)
next
case False
with ‹e ∈ set (elements (m # M'))›
have "e ∈ set (elements M')"
by simp
show ?thesis
proof (cases "marked m")
case True
with Cons ‹e ≠ element m›
have "(elementLevel e M') + i + 1 ≤ level"
unfolding elementLevel_def
unfolding markedElementsTo_def
by (simp split: if_split_asm)
moreover
have "elementLevel e M' ≥ 0"
by auto
ultimately
have "i + 1 ≤ level"
by simp
with ‹e ∈ set (elements M')› ‹(elementLevel e M') + i + 1 ≤ level› Cons(1)[of "i+1"]
have "e ∈ set (elements (prefixToLevel_aux M' level (i + 1)))"
by simp
with ‹e ≠ element m› ‹i + 1 ≤ level› True
show ?thesis
by simp
next
case False
with ‹e ≠ element m› ‹elementLevel e (m # M') + i ≤ level› have "elementLevel e M' + i ≤ level"
unfolding elementLevel_def
unfolding markedElementsTo_def
by (simp split: if_split_asm)
with ‹e ∈ set (elements M')› have "e ∈ set (elements (prefixToLevel_aux M' level i))"
using Cons
by (auto split: if_split_asm)
with ‹e ≠ element m› False show ?thesis
by simp
qed
qed
qed simp
lemma elementLevelLtLevelImpliesMemberPrefixToLevel:
assumes
"e ∈ set (elements M)" and
"elementLevel e M ≤ level"
shows
"e ∈ set (elements (prefixToLevel level M))"
using assms
using elementLevelLtLevelImpliesMemberPrefixToLevel_aux[of "e" "M" "0" "level"]
unfolding prefixToLevel_def
by simp
lemma literalNotInEarlierLevelsThanItsLevel:
assumes
"level < elementLevel e M"
shows
"e ∉ set (elements (prefixToLevel level M))"
proof-
{
assume "¬ ?thesis"
hence "level ≥ elementLevel e M"
by (simp add: prefixToLevelElementsElementLevel)
with ‹level < elementLevel e M›
have False
by simp
}
thus ?thesis
by auto
qed
lemma elementLevelPrefixElement:
assumes "e ∈ set (elements (prefixToLevel level M))"
shows "elementLevel e (prefixToLevel level M) = elementLevel e M"
using assms
proof-
have "isPrefix (prefixToLevel level M) M"
by (simp add: isPrefixPrefixToLevel)
then obtain s where "(prefixToLevel level M) @ s = M"
unfolding isPrefix_def
by auto
with assms show ?thesis
using elementLevelAppend[of "e" "prefixToLevel level M" "s"]
by auto
qed
lemma currentLevelZeroTrailEqualsItsPrefixToLevelZero:
assumes "currentLevel M = 0"
shows "M = prefixToLevel 0 M"
using assms
proof (induct M)
case (Cons a M')
show ?case
proof-
from Cons
have "currentLevel M' = 0" and "markedElements M' = []" and "¬ marked a"
unfolding currentLevel_def
by (auto split: if_split_asm)
thus ?thesis
using Cons
unfolding prefixToLevel_def
by auto
qed
next
case Nil
thus ?case
unfolding currentLevel_def
unfolding prefixToLevel_def
by simp
qed
subsection‹Number of literals of every trail level›
primrec
levelsCounter_aux :: "'a Trail ⇒ nat list ⇒ nat list"
where
"levelsCounter_aux [] l = l"
| "levelsCounter_aux (h # t) l =
(if (marked h) then
levelsCounter_aux t (l @ [1])
else
levelsCounter_aux t (butlast l @ [Suc (last l)])
)"
definition
levelsCounter :: "'a Trail ⇒ nat list"
where
"levelsCounter t = levelsCounter_aux t [0]"
lemma levelsCounter_aux_startIrellevant:
"∀ y. y ≠ [] ⟶ levelsCounter_aux a (x @ y) = (x @ levelsCounter_aux a y)"
by (induct a) (auto simp add: butlastAppend)
lemma levelsCounter_auxSuffixContinues: "∀ l. levelsCounter_aux (a @ b) l = levelsCounter_aux b (levelsCounter_aux a l)"
by (induct a) auto
lemma levelsCounter_auxNotEmpty: "∀ l. l ≠ [] ⟶ levelsCounter_aux a l ≠ []"
by (induct a) auto
lemma levelsCounter_auxIncreasesFirst:
"∀ m n l1 l2. levelsCounter_aux a (m # l1) = n # l2 ⟶ m <= n"
proof (induct "a")
case Nil
{
fix m::nat and n::nat and l1::"nat list" and l2::"nat list"
assume "levelsCounter_aux [] (m # l1) = n # l2"
hence "m = n"
by simp
}
thus ?case
by simp
next
case (Cons a list)
{
fix m::nat and n::nat and l1::"nat list" and l2::"nat list"
assume "levelsCounter_aux (a # list) (m # l1) = n # l2"
have "m <= n"
proof (cases "marked a")
case True
with ‹levelsCounter_aux (a # list) (m # l1) = n # l2›
have "levelsCounter_aux list (m # l1 @ [Suc 0]) = n # l2"
by simp
with Cons
show ?thesis
by auto
next
case False
show ?thesis
proof (cases "l1 = []")
case True
with ‹¬ marked a› ‹levelsCounter_aux (a # list) (m # l1) = n # l2›
have "levelsCounter_aux list [Suc m] = n # l2"
by simp
with Cons
have "Suc m <= n"
by auto
thus ?thesis
by simp
next
case False
with ‹¬ marked a› ‹levelsCounter_aux (a # list) (m # l1) = n # l2›
have "levelsCounter_aux list (m # butlast l1 @ [Suc (last l1)]) = n # l2"
by simp
with Cons
show ?thesis
by auto
qed
qed
}
thus ?case
by simp
qed
lemma levelsCounterPrefix:
assumes "(isPrefix p a)"
shows "? rest. rest ≠ [] ∧ levelsCounter a = butlast (levelsCounter p) @ rest ∧ last (levelsCounter p) ≤ hd rest"
proof-
from assms
obtain s :: "'a Trail" where "p @ s = a"
unfolding isPrefix_def
by auto
from ‹p @ s = a› have "levelsCounter a = levelsCounter (p @ s)"
by simp
show ?thesis
proof (cases "s = []")
case True
have "(levelsCounter a) = (butlast (levelsCounter p)) @ [last (levelsCounter p)] ∧
(last (levelsCounter p)) <= hd [last (levelsCounter p)]"
using ‹p @ s = a› ‹s = []›
unfolding levelsCounter_def
using levelsCounter_auxNotEmpty[of "p"]
by auto
thus ?thesis
by auto
next
case False
show ?thesis
proof (cases "marked (hd s)")
case True
from ‹p @ s = a› have "levelsCounter a = levelsCounter (p @ s)"
by simp
also
have "… = levelsCounter_aux s (levelsCounter_aux p [0])"
unfolding levelsCounter_def
by (simp add: levelsCounter_auxSuffixContinues)
also
have "… = levelsCounter_aux (tl s) ((levelsCounter_aux p [0]) @ [1])"
proof-
from ‹s ≠ []› have "s = hd s # tl s"
by simp
then have "levelsCounter_aux s (levelsCounter_aux p [0]) = levelsCounter_aux (hd s # tl s) (levelsCounter_aux p [0])"
by simp
with ‹marked (hd s)› show ?thesis
by simp
qed
also
have "… = levelsCounter_aux p [0] @ (levelsCounter_aux (tl s) [1])"
by (simp add: levelsCounter_aux_startIrellevant)
finally
have "levelsCounter a = levelsCounter p @ (levelsCounter_aux (tl s) [1])"
unfolding levelsCounter_def
by simp
hence "(levelsCounter a) = (butlast (levelsCounter p)) @ ([last (levelsCounter p)] @ (levelsCounter_aux (tl s) [1])) ∧
(last (levelsCounter p)) <= hd ([last (levelsCounter p)] @ (levelsCounter_aux (tl s) [1]))"
unfolding levelsCounter_def
using levelsCounter_auxNotEmpty[of "p"]
by auto
thus ?thesis
by auto
next
case False
from ‹p @ s = a› have "levelsCounter a = levelsCounter (p @ s)"
by simp
also
have "… = levelsCounter_aux s (levelsCounter_aux p [0])"
unfolding levelsCounter_def
by (simp add: levelsCounter_auxSuffixContinues)
also
have "… = levelsCounter_aux (tl s) ((butlast (levelsCounter_aux p [0])) @ [Suc (last (levelsCounter_aux p [0]))])"
proof-
from ‹s ≠ []› have "s = hd s # tl s"
by simp
then have "levelsCounter_aux s (levelsCounter_aux p [0]) = levelsCounter_aux (hd s # tl s) (levelsCounter_aux p [0])"
by simp
with ‹~marked (hd s)› show ?thesis
by simp
qed
also
have "… = butlast (levelsCounter_aux p [0]) @ (levelsCounter_aux (tl s) [Suc (last (levelsCounter_aux p [0]))])"
by (simp add: levelsCounter_aux_startIrellevant)
finally
have "levelsCounter a = butlast (levelsCounter_aux p [0]) @ (levelsCounter_aux (tl s) [Suc (last (levelsCounter_aux p [0]))])"
unfolding levelsCounter_def
by simp
moreover
have "hd (levelsCounter_aux (tl s) [Suc (last (levelsCounter_aux p [0]))]) >= Suc (last (levelsCounter_aux p [0]))"
proof-
have "(levelsCounter_aux (tl s) [Suc (last (levelsCounter_aux p [0]))]) ≠ []"
using levelsCounter_auxNotEmpty[of "tl s"]
by simp
then obtain h t where "(levelsCounter_aux (tl s) [Suc (last (levelsCounter_aux p [0]))]) = h # t"
using neq_Nil_conv[of "(levelsCounter_aux (tl s) [Suc (last (levelsCounter_aux p [0]))])"]
by auto
hence "h ≥ Suc (last (levelsCounter_aux p [0]))"
using levelsCounter_auxIncreasesFirst[of "tl s"]
by auto
with ‹(levelsCounter_aux (tl s) [Suc (last (levelsCounter_aux p [0]))]) = h # t›
show ?thesis
by simp
qed
ultimately
have "levelsCounter a = butlast (levelsCounter p) @ (levelsCounter_aux (tl s) [Suc (last (levelsCounter_aux p [0]))]) ∧
last (levelsCounter p) ≤ hd (levelsCounter_aux (tl s) [Suc (last (levelsCounter_aux p [0]))])"
unfolding levelsCounter_def
by simp
thus ?thesis
using levelsCounter_auxNotEmpty[of "tl s"]
by auto
qed
qed
qed
lemma levelsCounterPrefixToLevel:
assumes "p = prefixToLevel level a" "level ≥ 0" "level < currentLevel a"
shows "? rest . rest ≠ [] ∧ (levelsCounter a) = (levelsCounter p) @ rest"
proof-
from assms
obtain s :: "'a Trail" where "p @ s = a" "s ≠ []" "marked (hd s)"
using isProperPrefixPrefixToLevel[of "level" "a"]
by auto
from ‹p @ s = a› have "levelsCounter a = levelsCounter (p @ s)"
by simp
also
have "… = levelsCounter_aux s (levelsCounter_aux p [0])"
unfolding levelsCounter_def
by (simp add: levelsCounter_auxSuffixContinues)
also
have "… = levelsCounter_aux (tl s) ((levelsCounter_aux p [0]) @ [1])"
proof-
from ‹s ≠ []› have "s = hd s # tl s"
by simp
then have "levelsCounter_aux s (levelsCounter_aux p [0]) = levelsCounter_aux (hd s # tl s) (levelsCounter_aux p [0])"
by simp
with ‹marked (hd s)› show ?thesis
by simp
qed
also
have "… = levelsCounter_aux p [0] @ (levelsCounter_aux (tl s) [1])"
by (simp add: levelsCounter_aux_startIrellevant)
finally
have "levelsCounter a = levelsCounter p @ (levelsCounter_aux (tl s) [1])"
unfolding levelsCounter_def
by simp
moreover
have "levelsCounter_aux (tl s) [1] ≠ []"
by (simp add: levelsCounter_auxNotEmpty)
ultimately
show ?thesis
by simp
qed
subsection‹Prefix before last marked element›
primrec
prefixBeforeLastMarked :: "'a Trail ⇒ 'a Trail"
where
"prefixBeforeLastMarked [] = []"
| "prefixBeforeLastMarked (h#t) = (if (marked h) ∧ (markedElements t) = [] then [] else (h#(prefixBeforeLastMarked t)))"
lemma prefixBeforeLastMarkedIsPrefixBeforeLastLevel:
assumes "markedElements M ≠ []"
shows "prefixBeforeLastMarked M = prefixToLevel ((currentLevel M) - 1) M"
using assms
proof (induct M)
case Nil
thus ?case
by simp
next
case (Cons a M')
thus ?case
proof (cases "marked a")
case True
hence "currentLevel (a # M') ≥ 1"
unfolding currentLevel_def
by simp
with True Cons show ?thesis
using prefixToLevel_auxIncreaseAuxilaryCounter[of "0" "1" "M'" "currentLevel M' - 1"]
unfolding prefixToLevel_def
unfolding currentLevel_def
by auto
next
case False
with Cons show ?thesis
unfolding prefixToLevel_def
unfolding currentLevel_def
by auto
qed
qed
lemma isPrefixPrefixBeforeLastMarked:
shows "isPrefix (prefixBeforeLastMarked M) M"
unfolding isPrefix_def
by (induct M) auto
lemma lastMarkedNotInPrefixBeforeLastMarked:
assumes "uniq (elements M)" and "markedElements M ≠ []"
shows "¬ (lastMarked M) ∈ set (elements (prefixBeforeLastMarked M))"
using assms
unfolding lastMarked_def
by (induct M) (auto split: if_split_asm simp add: markedElementsAreElements)
lemma uniqImpliesPrefixBeforeLastMarkedIsPrefixBeforeLastMarked:
assumes "markedElements M ≠ []" and "(lastMarked M) ∉ set (elements M)"
shows "prefixBeforeLastMarked M = prefixBeforeElement (lastMarked M) M"
using assms
unfolding lastMarked_def
proof (induct M)
case Nil
thus ?case
by auto
next
case (Cons a M')
show ?case
proof (cases "marked a ∧ (markedElements M') = []")
case True
thus ?thesis
unfolding lastMarked_def
by auto
next
case False
hence "last (markedElements (a # M')) = last (markedElements M')"
by auto
thus ?thesis
using Cons
by (auto split: if_split_asm simp add: markedElementsAreElements)
qed
qed
lemma markedElementsAreElementsBeforeLastDecisionAndLastDecision:
assumes "markedElements M ≠ []"
shows "(markedElements M) = (markedElements (prefixBeforeLastMarked M)) @ [lastMarked M]"
using assms
unfolding lastMarked_def
by (induct M) (auto split: if_split_asm)
end