Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  Treap.thy

  Sprache: Isabelle
 

(*
  File:      Treap.thy
  Authors:   Tobias Nipkow, Max Haslbeck
*)

section Treaps
theory Treap
imports
  "HOL-Library.Tree"
begin

definition treap :: "('k::linorder * 'p::linorder) tree ==> bool" where
"treap t = (bst (map_tree fst t) heap (map_tree snd t))"

abbreviation "keys t set_tree (map_tree fst t)"
abbreviation "prios t set_tree (map_tree snd t)"

function treap_of :: "('k::linorder * 'p::linorder) set ==> ('k * 'p) tree" where
"treap_of KP = (if infinite KP KP = {} then Leaf else
  let m = arg_min_on snd KP;
      L = {p KP. fst p < fst m};
      R = {p KP. fst p > fst m}
  in Node (treap_of L) m (treap_of R))"
by pat_completeness auto
termination
proof (relation "measure card")
  show "wf (measure card)"  by simp
next
  fix KP :: "('a × 'b) set" and m L
  assume KP: "¬ (infinite KP KP = {})"
  and m: "m = arg_min_on snd KP"
  and L: "L = {p KP. fst p < fst m}"
  have "m KP" using KP arg_min_if_finite(1) m by blast
  thus  "(L, KP) measure card" using KP L by(auto intro!: psubset_card_mono)
next
  fix KP :: "('a × 'b) set" and m R
  assume KP: "¬ (infinite KP KP = {})"
  and m: "m = arg_min_on snd KP"
  and R: "R = {p KP. fst m < fst p}"
  have "m KP" using KP arg_min_if_finite(1) m by blast
  thus  "(R, KP) measure card" using KP R by(auto intro!: psubset_card_mono)
qed

declare treap_of.simps [simp del]

lemma treap_of_unique:
  "[ treap t; inj_on snd (set_tree t) ]
  ==> treap_of (set_tree t) = t"
proof(induction "set_tree t" arbitrary: t rule: treap_of.induct)
  case (1 t)
  show ?case
  proof (cases "infinite (set_tree t) set_tree t = {}")
    case True
    thus ?thesis by(simp add: treap_of.simps)
  next
    case False
    let ?m = "arg_min_on snd (set_tree t)"
    let ?L = "{p set_tree t. fst p < fst ?m}"
    let ?R = "{p set_tree t. fst p > fst ?m}"
    obtain l a r where t: "t = Node l a r"
      using False by (cases t) auto
    have "kp set_tree t. snd a snd kp"
      using "1.prems"(1)
      by(auto simp add: t treap_def ball_Un)
        (metis image_eqI snd_conv tree.set_map)+
    hence "a = ?m"
      by (metis "1.prems"(2) False arg_min_if_finite(1) arg_min_if_finite(2) inj_on_def 
          le_neq_trans t tree.set_intros(2))
    have "treap l" "treap r" using "1.prems"(1by(auto simp: treap_def t)
    have l: "set_tree l = {p set_tree t. fst p < fst a}"
      using "1.prems"(1by(auto simp add: treap_def t ball_Un tree.set_map)
    have r: "set_tree r = {p set_tree t. fst p > fst a}"
      using "1.prems"(1by(auto simp add: treap_def t ball_Un tree.set_map)
    have "l = treap_of ?L"
      using "1.hyps"(1)[OF False a = ?m l r treap l]
        l a = ?m "1.prems"(2)
      by (fastforce simp add: inj_on_def)
    have "r = treap_of ?R"
      using "1.hyps"(2)[OF False a = ?m l r treap r]
        r a = ?m "1.prems"(2)
      by (fastforce simp add: inj_on_def)
    have "t = Node (treap_of ?L) ?m (treap_of ?R)"
      using a = ?m l = treap_of ?L r = treap_of ?R by(subst t) simp
    thus ?thesis using False
      by (subst treap_of.simps) simp
  qed
qed

lemma treap_unique:
  "[ treap t1; treap t2; set_tree t1 = set_tree t2; inj_on snd (set_tree t1) ]
  ==> t1 = t2"
  for t1 t2 :: "('k::linorder * 'p::linorder) tree"
by (metis treap_of_unique)

fun ins :: "'k::linorder ==> 'p::linorder ==> ('k × 'p) tree ==> ('k × 'p) tree" where
"ins k p Leaf = Leaf, (k,p), Leaf" |
"ins k p l, (k1,p1), r =
  (if k < k1 then
     (case ins k p l of
       l2, (k2,p2), r2 ==>
         if p1 p2 then l2, (k2,p2), r2, (k1,p1), r
         else l2, (k2,p2), r2, (k1,p1), r)
   else
   if k > k1 then
     (case ins k p r of
       l2, (k2,p2), r2 ==>
         if p1 p2 then l, (k1,p1), l2, (k2,p2), r2
         else l, (k1,p1), l2, (k2,p2), r2)
   else l, (k1,p1), r)"

lemma ins_neq_Leaf: "ins k p t "
  by (induction t rule: ins.induct) (auto split: tree.split)

lemma keys_ins: "keys (ins k p t) = Set.insert k (keys t)"
proof (induction t rule: ins.induct)
  case 2
  then show ?case
    by (simp add: ins_neq_Leaf split: tree.split prod.split) (safe; fastforce)
qed (simp)

lemma prios_ins: "prios (ins k p t) {p} prios t"
apply(induction t rule: ins.induct)
 apply simp
  apply (simp add: ins_neq_Leaf split: tree.split prod.split)
  by (safe; fastforce)

lemma prios_ins': "k keys t ==> prios (ins k p t) = {p} prios t"
apply(induction t rule: ins.induct)
 apply simp
  apply (simp add: ins_neq_Leaf split: tree.split prod.split)
  by (safe; fastforce)

lemma set_tree_ins: "set_tree (ins k p t) {(k,p)} set_tree t"
  by (induction t rule: ins.induct) (auto simp add: ins_neq_Leaf split: tree.split prod.split)
    
lemma set_tree_ins': "k keys t ==> {(k,p)} set_tree t set_tree (ins k p t)"
  by (induction t rule: ins.induct) (auto simp add: ins_neq_Leaf split: tree.split prod.split)

lemma set_tree_ins_eq: "k keys t ==> set_tree (ins k p t) = {(k,p)} set_tree t"
  using set_tree_ins set_tree_ins' by blast

lemma prios_ins_special:
  "[ ins k p t = Node l (k',p') r; p' = p; p prios r prios l ]
  ==> p prios t"
  by (induction k p t arbitrary: l k' p' r rule: ins.induct)
     (fastforce simp add: ins_neq_Leaf split: tree.splits prod.splits if_splits)+

lemma treap_NodeI:
  "[ treap l; treap r;
     k' keys l. k' < k; k' keys r. k < k';
     p' prios l. p p'; p' prios r. p p' ]
  ==> treap (Node l (k,p) r)"
 by (auto simp: treap_def)

lemma treap_rotate1:
  assumes "treap l2" "treap r2" "treap r" "¬ p1 p2" "k < k1" and
  ins: "ins k p l = Node l2 (k2,p2) r2" and treap_ins: "treap (ins k p l)"
  and treap: "treap l, (k1, p1), r"
  shows "treap (Node l2 (k2,p2) (Node r2 (k1,p1) r))"
proof(rule treap_NodeI[OF treap l2 treap_NodeI[OF treap r2 treap r]])
  from keys_ins[of k p l] have 1"keys r2 {k} keys l" by(auto simp: ins)
  from treap have 2"k'keys l. k' < k1" by (simp add: treap_def)
  show "k'keys r2. k' < k1" using 1 2 k < k1 by blast
next
  from treap have 2"p'prios l. p1 p'" by (simp add: treap_def)
  show "p'prios r2. p1 p'"
  proof
    fix p' assume "p' prios r2"
    hence "p' = p p' prios l" using prios_ins[of k p l] ins by auto
    thus "p1 p'"
    proof
      assume [simp]: "p' = p"
      have "p2 = p p2 prios l" using prios_ins[of k p l] ins by simp
      thus "p1 p'"
      proof
        assume "p2 = p"
        thus "p1 p'"
          using prios_ins_special[OF ins] p' prios r2 2 by auto
      next
        assume "p2 prios l"
        thus "p1 p'" using 2 ¬ p1 p2 by blast
      qed
    next
      assume "p' prios l"
      thus "p1 p'" using 2 by blast
    qed
  qed
next
  have "k2 = k k2 keys l" using keys_ins[of k p l] ins by (auto)
  hence 1"k2 < k1"
  proof
    assume "k2 = k" thus "k2 < k1" using k < k1 by simp
  next
    assume "k2 keys l"
    thus "k2 < k1" using treap by (auto simp: treap_def)
  qed
  have 2"k'keys r2. k2 < k'"
    using treap_ins by(simp add: ins treap_def)
  have 3"k'keys r. k2 < k'"
    using 1 treap by(auto simp: treap_def)
  show "k'keys r2, (k1, p1), r. k2 < k'" using 1 2 3 by auto
next
  show "p'prios r2, (k1, p1), r. p2 p'"
    using ins treap_ins treap ¬ p1 p2 by (auto simp: treap_def ball_Un)
qed (use ins treap_ins treap in auto simp: treap_def ball_Un)


lemma treap_rotate2:
  assumes "treap l" "treap l2" "treap r2" "¬ p1 p2" "k1 < k" and
  ins: "ins k p r = Node l2 (k2,p2) r2" and treap_ins: "treap (ins k p r)"
  and treap: "treap l, (k1, p1), r"
  shows "treap (Node (Node l (k1,p1) l2) (k2,p2) r2)"
proof(rule treap_NodeI[OF treap_NodeI[OF treap l treap l2treap r2])
  from keys_ins[of k p r] have 1"keys l2 {k} keys r" by(auto simp: ins)
  from treap have 2"k'keys r. k1 < k'" by (simp add: treap_def)
  show "k'keys l2. k1 < k'" using 1 2 k1 < k by blast
next
  from treap have 2"p'prios r. p1 p'" by (simp add: treap_def)
  show "p'prios l2. p1 p'"
  proof
    fix p' assume "p' prios l2"
    hence "p' = p p' prios r" using prios_ins[of k p r] ins by auto
    thus "p1 p'"
    proof
      assume [simp]: "p' = p"
      have "p2 = p p2 prios r" using prios_ins[of k p r] ins by simp
      thus "p1 p'"
      proof
        assume "p2 = p"
        thus "p1 p'"
          using prios_ins_special[OF ins] p' prios l2 2 by auto
      next
        assume "p2 prios r"
        thus "p1 p'" using 2 ¬ p1 p2 by blast
      qed
    next
      assume "p' prios r"
      thus "p1 p'" using 2 by blast
    qed
  qed
next
  have "k2 = k k2 keys r" using keys_ins[of k p r] ins by (auto)
  hence 1"k1 < k2"
  proof
    assume "k2 = k" thus "k1 < k2" using k1 < k by simp
  next
    assume "k2 keys r"
    thus "k1 < k2" using treap by (auto simp: treap_def)
  qed
  have 2"k'keys l. k' < k2" using 1 treap by(auto simp: treap_def)
  have 3"k'keys l2. k' < k2"
    using treap_ins by(auto simp: ins treap_def)
  show "k'keys l, (k1, p1), l2. k' < k2" using 1 2 3 by auto
next
  show "p'prios l, (k1, p1), l2. p2 p'"
    using ins treap_ins treap ¬ p1 p2 by (auto simp: treap_def ball_Un)
qed (use ins treap_ins treap in auto simp: treap_def ball_Un)

lemma treap_ins: "treap t ==> treap (ins k p t)"
proof(induction t rule: ins.induct)
  case 1 thus ?case by (simp add: treap_def)
next
  case (2 k p l k1 p1 r)
  have "treap l" "treap r"
    using "2.prems" by(auto simp: treap_def tree.set_map)
  show ?case
  proof cases
    assume "k < k1"
    obtain l2 k2 p2 r2 where ins: "ins k p l = Node l2 (k2,p2) r2"
      by (metis ins_neq_Leaf neq_Leaf_iff prod.collapse)
    note treap_ins = "2.IH"(1)[OF k < k1 treap l]
    hence "treap l2" "treap r2" using ins by (auto simp add: treap_def)
    show ?thesis
    proof cases
      assume "p1 p2"
      have "treap (Node (Node l2 (k2,p2) r2) (k1,p1) r)"
        apply(rule treap_NodeI[OF treap_ins[unfolded ins] treap r])
        using ins treap_ins k < k1 "2.prems" keys_ins[of k p l]
        by (auto simp add: treap_def ball_Un order_trans[OF p1 p2])
      thus ?thesis using k < k1 ins p1 p2 by simp
    next
      assume "¬ p1 p2"
      have "treap (Node l2 (k2,p2) (Node r2 (k1,p1) r))"
        by(rule treap_rotate1[OF treap l2 treap r2  treap r ¬ p1 p2
            k < k1 ins treap_ins "2.prems"])
      thus ?thesis using k < k1 ins ¬ p1 p2 by simp
    qed
  next
    assume "¬ k < k1"
    show ?thesis
    proof cases
    assume "k > k1"
    obtain l2 k2 p2 r2 where ins: "ins k p r = Node l2 (k2,p2) r2"
      by (metis ins_neq_Leaf neq_Leaf_iff prod.collapse)
    note treap_ins = "2.IH"(2)[OF ¬ k < k1 k > k1 treap r]
    hence "treap l2" "treap r2" using ins by (auto simp add: treap_def)
    have fst: "k' set_tree (map_tree fst (ins k p r)).
                 k' = k k' set_tree (map_tree fst r)"
      by(simp add: keys_ins)
    show ?thesis
    proof cases
      assume "p1 p2"
      have "treap (Node l (k1,p1) (ins k p r))"
        apply(rule treap_NodeI[OF treap l treap_ins])
        using ins treap_ins k > k1 "2.prems" keys_ins[of k p r]
        by (auto simp: treap_def ball_Un order_trans[OF p1 p2])
      thus ?thesis using ¬ k < k1 k > k1 ins p1 p2 by simp
    next
      assume "¬ p1 p2"
      have "treap (Node (Node l (k1,p1) l2) (k2,p2) r2)"
        by(rule treap_rotate2[OF treap l treap l2 treap r2 ¬ p1 p2
             k1 < k ins treap_ins "2.prems"])
      thus ?thesis using ¬ k < k1  k > k1 ins ¬ p1 p2 by simp
    qed
    next
      assume "¬ k > k1"
      hence "k = k1" using ¬ k < k1 by auto
      thus ?thesis using "2.prems" by(simp)
    qed
  qed  
qed

lemma treap_of_set_tree_unique:
  "[ finite A; inj_on fst A; inj_on snd A ]
  ==> set_tree (treap_of A) = A"  
proof(induction "A" rule: treap_of.induct)
  case (1 A)
  note IH = 1
  show ?case
  proof (cases "infinite A A = {}")
    assume "infinite A A = {}"
    with IH show ?thesis by (simp add: treap_of.simps)
  next
    assume not_inf_or_empty: "¬ (infinite A A = {})"
    let ?m = "arg_min_on snd A"
    let ?L = "{p A. fst p < fst ?m}"
    let ?R = "{p A. fst p > fst ?m}"
    obtain l a r where t: "treap_of A = Node l a r"
      using not_inf_or_empty
      by (cases "treap_of A") (auto simp: Let_def elim!: treap_of.elims split: if_splits)
    have [simp]: "inj_on fst {p A. fst p < fst (arg_min_on snd A)}"
                 "inj_on snd {p A. fst p < fst (arg_min_on snd A)}"
                 "inj_on fst {p A. fst (arg_min_on snd A) < fst p}"
                 "inj_on snd {p A. fst (arg_min_on snd A) < fst p}"
      using IH by (auto intro: inj_on_subset)
    have lr: "l = treap_of ?L" "r = treap_of ?R"
      using t by (auto simp: Let_def elim: treap_of.elims split: if_splits)
    then have l: "set_tree l = ?L"
       using not_inf_or_empty IH by auto
     have "r = treap_of ?R"
       using t by (auto simp: Let_def elim: treap_of.elims split: if_splits)
    then have r: "set_tree r = ?R"
      using not_inf_or_empty IH(2by (auto)
    have a: "a = ?m"
      using t by (elim treap_of.elims) (simp add: Let_def split: if_splits)
    have "a fst (arg_min_on snd A)" if "(a,b) A" "(a, b) arg_min_on snd A" for a b
      using IH(4,5) that not_inf_or_empty arg_min_if_finite(1) inj_on_eq_iff by fastforce
    then have "a < fst (arg_min_on snd A)" 
       if "(a,b) A" "(a, b) arg_min_on snd A" "fst (arg_min_on snd A) a" for a b
      using le_neq_trans that by auto
    moreover have "arg_min_on snd A A"
      using not_inf_or_empty arg_min_if_finite by auto
    ultimately have A: "A = {?m} ?L ?R"
      by auto
    show ?thesis using l r a A t by force
  qed
qed

lemma treap_of_subset: "set_tree (treap_of A) A"
proof(induction "A" rule: treap_of.induct)
  case (1 A)
  note IH = 1
  show ?case
  proof (cases "infinite A A = {}")
    assume "infinite A A = {}"
    with IH show ?thesis by (simp add: treap_of.simps)
  next
    assume not_inf_or_empty: "¬ (infinite A A = {})"
    let ?m = "arg_min_on snd A"
    let ?L = "{p A. fst p < fst ?m}"
    let ?R = "{p A. fst p > fst ?m}"
    obtain l a r where t: "treap_of A = Node l a r"
      using not_inf_or_empty by (cases "treap_of A")
                                (auto simp add: Let_def  elim!: treap_of.elims split: if_splits)
    have "l = treap_of ?L" "r = treap_of ?R"
      using t by (auto simp: Let_def elim: treap_of.elims split: if_splits)
    have "set_tree l ?L" "set_tree r ?R"
    proof -
      have "set_tree (treap_of {p A. fst p < fst (arg_min_on snd A)})
             {p A. fst p < fst (arg_min_on snd A)}"
        by (rule IH) (use not_inf_or_empty in auto)
      then show "set_tree l ?L"
        using l = treap_of ?L by auto
    next
      have "set_tree (treap_of {p A. fst (arg_min_on snd A) < fst p})
             {p A. fst (arg_min_on snd A) < fst p}"
        by (rule IH) (use not_inf_or_empty in auto)
      then show "set_tree r ?R"
        using r = treap_of ?R by auto
    qed
    moreover have "a = ?m"
      using t by (auto elim!: treap_of.elims simp add: Let_def split: if_splits)
    moreover have "{?m} ?L ?R A"
      using not_inf_or_empty arg_min_if_finite by auto
    ultimately show ?thesis by (auto simp add: t)
  qed
qed

lemma treap_treap_of:
  "treap (treap_of A)"
proof(induction "A" rule: treap_of.induct)
  case (1 A)
  show ?case
  proof (cases "infinite A A = {}")
    case True
    with 1 show ?thesis by (simp add: treap_of.simps treap_def)
  next
    case False
    let ?m = "arg_min_on snd A"
    let ?L = "{p A. fst p < fst ?m}"
    let ?R = "{p A. fst p > fst ?m}"
    obtain l a r where t: "treap_of A = Node l a r"
      using False by (cases "treap_of A") (auto simp: Let_def elim!: treap_of.elims split: if_splits)
    have l: "l = treap_of ?L"
      using t by (auto simp: Let_def elim: treap_of.elims split: if_splits)
    then have treap_l: "treap l"
      using False by (auto intro: 1
    from l have keys_l: "keys l fst ` ?L"
      by (auto simp add: tree.set_map intro!: image_mono treap_of_subset)
    have r: "r = treap_of ?R"
      using t by (auto simp: Let_def elim: treap_of.elims split: if_splits)
    then have treap_r: "treap r"
      using False by (auto intro: 1
    from r have keys_r: "keys r fst ` ?R"
      by (auto simp add: tree.set_map intro!: image_mono treap_of_subset)
    have prios: "prios l snd ` A" "prios r snd ` A"
      using l r treap_of_subset image_mono by (auto simp add: tree.set_map)
    have a: "a = ?m"
      using t by(auto simp: Let_def elim: treap_of.elims split: if_splits)
    have prios_l: "x. x prios l ==> snd a x"
      by (drule rev_subsetD[OF _ prios(1)]) (use arg_min_least a False in fast)
    have prios_r: "x. x prios r ==> snd a x"
      by (drule rev_subsetD[OF _ prios(2)]) (use arg_min_least a False in fast)
    show ?thesis
      using prios_r prios_l treap_l treap_r keys_l keys_r a 
      by (auto simp add: t treap_def dest: rev_subsetD[OF _ keys_l] rev_subsetD[OF _ keys_r])
    qed
qed

lemma treap_Leaf: "treap "
  by (simp add: treap_def)

lemma foldl_ins_treap: "treap t ==> treap (foldl (λt' (x, p). ins x p t') t xs)"
  using treap_ins by (induction xs arbitrary: t) auto

lemma foldl_ins_set_tree: 
  assumes "inj_on fst (set ys)" "inj_on snd (set ys)" "distinct ys" "fst ` (set ys) keys t = {}"
  shows "set_tree (foldl (λt' (x, p). ins x p t') t ys) = set ys set_tree t"
  using assms
  by (induction ys arbitrary: t) (auto simp add: case_prod_beta' set_tree_ins_eq keys_ins)

lemma foldl_ins_treap_of:
  assumes "distinct ys" "inj_on fst (set ys)" "inj_on snd (set ys)"
 shows "(foldl (λt' (x, p). ins x p t') Leaf ys) = treap_of (set ys)"
  using assms by (intro treap_unique) (auto simp: treap_Leaf foldl_ins_treap foldl_ins_set_tree 
                                                  treap_treap_of treap_of_set_tree_unique)

end

Messung V0.5 in Prozent
C=91 H=97 G=93

¤ Dauer der Verarbeitung: 0.13 Sekunden  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge