(* Title: BDD
Author: Veronika Ortner and Norbert Schirmer, 2004
Maintainer: Norbert Schirmer, norbert.schirmer at web de
License: LGPL
*)
(*
BinDag.thy
Copyright (C) 2004-2008 Veronika Ortner and Norbert Schirmer
Some rights reserved, TU Muenchen
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as
published by the Free Software Foundation; either version 2.1 of the
License, or (at your option) any later version.
This library is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
USA
*)
section ‹BDD Abstractions›
theory BinDag
imports Simpl.Simpl_Heap
begin
datatype dag = Tip | Node dag ref dag
lemma [simp]: "Node lt a rt ≠ lt"
by (induct lt) auto
lemma [simp]: "lt ≠ Node lt a rt"
by (induct lt) auto
lemma [simp]: "Node lt a rt ≠ rt"
by (induct rt) auto
lemma [simp]: "rt ≠ Node lt a rt"
by (induct rt) auto
primrec set_of:: "dag → ref set" where
set_of_Tip: "set_of Tip = {}"
| set_of_Node: "set_of (Node lt a rt) = {a} ∪ set_of lt ∪ set_of rt"
primrec DAG:: "dag → bool" where
"DAG Tip = True"
| "DAG (Node l a r) = (a ∉ set_of l ∧ a ∉ set_of r ∧ DAG l ∧ DAG r)"
primrec subdag:: "dag → dag → bool" where
"subdag Tip t = False"
| "subdag (Node l a r) t = (t=l ∨ t=r ∨ subdag l t ∨ subdag r t)"
lemma subdag_size: "subdag t s ==> size s < size t"
by (induct t) auto
lemma subdag_neq: "subdag t s ==> t≠s"
by (induct t) (auto dest: subdag_size)
lemma subdag_trans [trans]: "subdag t s ==> subdag s r ==> subdag t r"
by (induct t) auto
lemma subdag_NodeD:
"subdag t (Node lt a rt) ==> subdag t lt ∧ subdag t rt"
by (induct t) auto
lemma subdag_not_sym: "∧t. [subdag s t; subdag t s] ==> P"
by (induct s) (auto dest: subdag_NodeD)
instantiation dag :: order
begin
definition
less_dag_def: "s < (t::dag) ⟷ subdag t s"
definition
le_dag_def: "s ≤ (t::dag) ⟷ s=t ∨ s < t"
lemma le_dag_refl: "(x::dag) ≤ x"
by (simp add: le_dag_def)
lemma le_dag_trans:
fixes x::dag and y and z
assumes x_y: "x ≤ y" and y_z: "y ≤ z"
shows "x ≤ z"
proof (cases "x=y")
case True with y_z show ?thesis by simp
next
case False
note x_neq_y = this
with x_y have x_less_y: "x < y" by (simp add: le_dag_def)
show ?thesis
proof (cases "y=z")
case True
with x_y show ?thesis by simp
next
case False
with y_z have "y < z" by (simp add: le_dag_def)
with x_less_y have "x < z"
by (auto simp add: less_dag_def intro: subdag_trans)
thus ?thesis
by (simp add: le_dag_def)
qed
qed
lemma le_dag_antisym:
fixes x::dag and y
assumes x_y: "x ≤ y" and y_x: "y ≤ x"
shows "x = y"
proof (cases "x=y")
case True thus ?thesis .
next
case False
with x_y y_x show ?thesis
by (auto simp add: less_dag_def le_dag_def intro: subdag_not_sym)
qed
lemma dag_less_le:
fixes x::dag and y
shows "(x < y) = (x ≤ y ∧ x ≠ y)"
by (auto simp add: less_dag_def le_dag_def dest: subdag_neq)
instance
by standard (auto simp add: dag_less_le le_dag_refl intro: le_dag_trans dest: le_dag_antisym)
end
lemma less_dag_Tip [simp]: "¬ (x < Tip)"
by (simp add: less_dag_def)
lemma less_dag_Node: "x < (Node l a r) =
(x ≤ l ∨ x ≤ r)"
by (auto simp add: order_le_less less_dag_def)
lemma less_dag_Node': "x < (Node l a r) =
(x=l ∨ x=r ∨ x < l ∨ x < r)"
by (simp add: less_dag_def)
lemma less_Node_dag: "(Node l a r) < x ==> l < x ∧ r < x"
by (auto simp add: less_dag_def dest: subdag_NodeD)
lemma less_dag_set_of: "x < y ==> set_of x ⊆ set_of y"
by (unfold less_dag_def, induct y, auto)
lemma le_dag_set_of: "x ≤ y ==> set_of x ⊆ set_of y"
apply (unfold le_dag_def)
apply (erule disjE)
apply simp
apply (erule less_dag_set_of)
done
lemma DAG_less: "DAG y ==> x < y ==> DAG x"
by (induct y) (auto simp add: less_dag_Node')
lemma less_DAG_set_of:
assumes x_less_y: "x < y"
assumes DAG_y: "DAG y"
shows "set_of x ⊂ set_of y"
proof (cases y)
case Tip with x_less_y show ?thesis by simp
next
case (Node l a r)
with DAG_y obtain a: "a ∉ set_of l" "a ∉ set_of r"
by simp
from Node obtain l_less_y: "l < y" and r_less_y: "r < y"
by (simp add: less_dag_Node)
from Node a obtain
l_subset_y: "set_of l ⊂ set_of y" and
r_subset_y: "set_of r ⊂ set_of y"
by auto
from Node x_less_y have "x=l ∨ x=r ∨ x < l ∨ x < r"
by (simp add: less_dag_Node')
thus ?thesis
proof (elim disjE)
assume "x=l"
with l_subset_y show ?thesis by simp
next
assume "x=r"
with r_subset_y show ?thesis by simp
next
assume "x < l"
hence "set_of x ⊆ set_of l"
by (rule less_dag_set_of)
also note l_subset_y
finally show ?thesis .
next
assume "x < r"
hence "set_of x ⊆ set_of r"
by (rule less_dag_set_of)
also note r_subset_y
finally show ?thesis .
qed
qed
lemma in_set_of_decomp:
"p ∈ set_of t = (∃l r. t=(Node l p r) ∨ subdag t (Node l p r))"
(is "?A = ?B")
proof
assume "?A" thus "?B"
by (induct t) auto
next
assume "?B" thus "?A"
by (induct t) auto
qed
primrec Dag:: "ref → (ref → ref) → (ref → ref) → dag → bool"
where
"Dag p l r Tip = (p = Null)" |
"Dag p l r (Node lt a rt) = (p = a ∧ p ≠ Null ∧
Dag (l p) l r lt ∧ Dag (r p) l r rt)"
lemma Dag_Null [simp]: "Dag Null l r t = (t = Tip)"
by (cases t) simp_all
lemma Dag_Ref [simp]:
"p≠Null ==> Dag p l r t = (∃lt rt. t=Node lt p rt ∧
Dag (l p) l r lt ∧ Dag (r p) l r rt)"
by (cases t) auto
lemma Null_notin_Dag [simp, intro]: "∧p l r. Dag p l r t ==> Null ∉ set_of t"
by (induct t) auto
theorem notin_Dag_update_l [simp]:
"∧ p. q ∉ set_of t ==> Dag p (l(q := y)) r t = Dag p l r t"
by (induct t) auto
theorem notin_Dag_update_r [simp]:
"∧ p. q ∉ set_of t ==> Dag p l (r(q := y)) t = Dag p l r t"
by (induct t) auto
lemma Dag_upd_same_l_lemma: "∧p. p≠Null ==> ¬ Dag p (l(p:=p)) r t"
apply (induct t)
apply simp
apply (simp (no_asm_simp) del: fun_upd_apply)
apply (simp (no_asm_simp) only: fun_upd_apply refl if_True)
apply blast
done
lemma Dag_upd_same_l [simp]: "Dag p (l(p:=p)) r t = (p=Null ∧ t=Tip)"
apply (cases "p=Null")
apply simp
apply (fast dest: Dag_upd_same_l_lemma)
done
text ‹@{thm[source] Dag_upd_same_l} prevents
{term "p≠Null ==> Dag p (l(p:=p)) r t = X"} from looping, because of
{thm[source] Dag_Ref} and @{thm[source] fun_upd_apply}.
›
lemma Dag_upd_same_r_lemma: "∧p. p≠Null ==> ¬ Dag p l (r(p:=p)) t"
apply (induct t)
apply simp
apply (simp (no_asm_simp) del: fun_upd_apply)
apply (simp (no_asm_simp) only: fun_upd_apply refl if_True)
apply blast
done
lemma Dag_upd_same_r [simp]: "Dag p l (r(p:=p)) t = (p=Null ∧ t=Tip)"
apply (cases "p=Null")
apply simp
apply (fast dest: Dag_upd_same_r_lemma)
done
lemma Dag_update_l_new [simp]: "[set_of t ⊆ set alloc]
==> Dag p (l(new (set alloc) := x)) r t = Dag p l r t"
by (rule notin_Dag_update_l) fastforce
lemma Dag_update_r_new [simp]: "[set_of t ⊆ set alloc]
==> Dag p l (r(new (set alloc) := x)) t = Dag p l r t"
by (rule notin_Dag_update_r) fastforce
lemma Dag_update_lI [intro]:
"[Dag p l r t; q ∉ set_of t] ==> Dag p (l(q := y)) r t"
by simp
lemma Dag_update_rI [intro]:
"[Dag p l r t; q ∉ set_of t] ==> Dag p l (r(q := y)) t"
by simp
lemma Dag_unique: "∧ p t2. Dag p l r t1 ==> Dag p l r t2 ==> t1=t2"
by (induct t1) auto
lemma Dag_unique1: "Dag p l r t ==> ∃!t. Dag p l r t"
by (blast intro: Dag_unique)
lemma Dag_subdag: "∧ p. Dag p l r t ==> subdag t s ==> ∃ q. Dag q l r s"
by (induct t) auto
lemma Dag_root_not_in_subdag_l [simp,intro]:
assumes "Dag (l p) l r t"
shows "p ∉ set_of t"
proof -
{
fix lt rt
assume t: "t = Node lt p rt"
from assms have "Dag (l p) l r lt"
by (clarsimp simp only: t Dag.simps)
with assms have "t=lt"
by (rule Dag_unique)
with t have False
by simp
}
moreover
{
fix lt rt
assume subdag: "subdag t (Node lt p rt)"
with assms obtain q where "Dag q l r (Node lt p rt)"
by (rule Dag_subdag [elim_format]) iprover
hence "Dag (l p) l r lt"
by auto
with assms have "t=lt"
by (rule Dag_unique)
moreover
have "subdag t lt"
proof -
note subdag
also have "subdag (Node lt p rt) lt" by simp
finally show ?thesis .
qed
ultimately have False
by (simp add: subdag_neq)
}
ultimately show ?thesis
by (auto simp add: in_set_of_decomp)
qed
lemma Dag_root_not_in_subdag_r [simp, intro]:
assumes "Dag (r p) l r t"
shows "p ∉ set_of t"
proof -
{
fix lt rt
assume t: "t = Node lt p rt"
from assms have "Dag (r p) l r rt"
by (clarsimp simp only: t Dag.simps)
with assms have "t=rt"
by (rule Dag_unique)
with t have False
by simp
}
moreover
{
fix lt rt
assume subdag: "subdag t (Node lt p rt)"
with assms obtain q where "Dag q l r (Node lt p rt)"
by (rule Dag_subdag [elim_format]) iprover
hence "Dag (r p) l r rt"
by auto
with assms have "t=rt"
by (rule Dag_unique)
moreover
have "subdag t rt"
proof -
note subdag
also have "subdag (Node lt p rt) rt" by simp
finally show ?thesis .
qed
ultimately have False
by (simp add: subdag_neq)
}
ultimately show ?thesis
by (auto simp add: in_set_of_decomp)
qed
lemma Dag_is_DAG: "∧p l r. Dag p l r t ==> DAG t"
by (induct t) auto
lemma heaps_eq_Dag_eq:
"∧p. ∀x ∈ set_of t. l x = l' x ∧ r x = r' x
==> Dag p l r t = Dag p l' r' t"
by (induct t) auto
lemma heaps_eq_DagI1:
"[Dag p l r t; ∀x∈set_of t. l x = l' x ∧ r x = r' x]
==> Dag p l' r' t"
by (rule heaps_eq_Dag_eq [THEN iffD1])
lemma heaps_eq_DagI2:
"[Dag p l' r' t; ∀x∈set_of t. l x = l' x ∧ r x = r' x]
==> Dag p l r t"
by (rule heaps_eq_Dag_eq [THEN iffD2]) auto
lemma Dag_unique_all_impl_simp [simp]:
"Dag p l r t ==> (∀t. Dag p l r t ⟶ P t) = P t"
by (auto dest: Dag_unique)
lemma Dag_unique_ex_conj_simp [simp]:
"Dag p l r t ==> (∃t. Dag p l r t ∧ P t) = P t"
by (auto dest: Dag_unique)
lemma Dags_eq_hp_eq:
"∧p p'. [Dag p l r t; Dag p' l' r' t] ==>
p'=p ∧ (∀no ∈ set_of t. l' no = l no ∧ r' no = r no)"
by (induct t) auto
definition isDag :: "ref → (ref → ref) → (ref → ref) → bool"
where "isDag p l r = (∃t. Dag p l r t)"
definition dag :: "ref → (ref → ref) → (ref → ref) → dag"
where "dag p l r = (THE t. Dag p l r t)"
lemma Dag_conv_isDag_dag: "Dag p l r t = (isDag p l r ∧ t=dag p l r)"
apply (simp add: isDag_def dag_def)
apply (rule iffI)
apply (rule conjI)
apply blast
apply (subst the1_equality)
apply (erule Dag_unique1)
apply assumption
apply (rule refl)
apply clarify
apply (rule theI)
apply assumption
apply (erule (1) Dag_unique)
done
lemma Dag_dag: "Dag p l r t ==> dag p l r = t"
by (simp add: Dag_conv_isDag_dag)
end
¤ Dauer der Verarbeitung: 0.6 Sekunden
¤
*© Formatika GbR, Deutschland