Theory Prefix_Tree_Refined
section ‹Refined Code Generation for Prefix Trees›
text ‹This theory provides alternative code equations for selected functions on prefix trees.
Currently only Mapping via RBT is supported.›
theory Prefix_Tree_Refined
imports Prefix_Tree Containers.Containers
begin
declare [[code drop: Prefix_Tree.combine]]
lemma combine_refined[code] :
fixes m1 :: "('a :: ccompare, 'a prefix_tree) mapping_rbt"
shows "Prefix_Tree.combine (MPT (RBT_Mapping m1)) (MPT (RBT_Mapping m2))
= (case ID CCOMPARE('a) of
None ⇒ Code.abort (STR ''combine_MPT_RBT_Mapping: ccompare = None'') (λ_. Prefix_Tree.combine (MPT (RBT_Mapping m1)) (MPT (RBT_Mapping m2)))
| Some _ ⇒ MPT (RBT_Mapping (RBT_Mapping2.join (λ a t1 t2 . Prefix_Tree.combine t1 t2) m1 m2)))"
(is "?PT1 = ?PT2")
proof (cases "ID CCOMPARE('a)")
case None
then show ?thesis by simp
next
case (Some a)
then have *: "?PT2 = MPT (RBT_Mapping (RBT_Mapping2.join (λ a t1 t2 . Prefix_Tree.combine t1 t2) m1 m2))"
by auto
have "ID CCOMPARE('a) ≠ None"
using Some by auto
have "Mapping.lookup (Mapping.combine Prefix_Tree.combine (RBT_Mapping m1) (RBT_Mapping m2)) = Mapping.lookup (RBT_Mapping (RBT_Mapping2.join (λ a b c . Prefix_Tree.combine b c) m1 m2))"
proof
fix x
show "Mapping.lookup (Mapping.combine Prefix_Tree.combine (RBT_Mapping m1) (RBT_Mapping m2)) x =
Mapping.lookup (RBT_Mapping (RBT_Mapping2.join (λa. Prefix_Tree.combine) m1 m2)) x"
(is "?M1 = ?M2")
proof (cases "RBT_Mapping2.lookup m1 x")
case None
show ?thesis proof (cases "RBT_Mapping2.lookup m2 x")
case None
have "?M1 = None"
using ‹RBT_Mapping2.lookup m1 x = None› None
by (metis combine_options_simps(1) lookup_Mapping_code(2) lookup_combine)
moreover have "?M2 = None"
using ‹RBT_Mapping2.lookup m1 x = None› None
by (simp add: Mapping.lookup.abs_eq ‹ID ccompare ≠ None› lookup_join)
ultimately show ?thesis
by simp
next
case (Some a)
have "?M1 = Some a"
using ‹RBT_Mapping2.lookup m1 x = None› Some
by (metis combine_options_simps(1) lookup_Mapping_code(2) lookup_combine)
moreover have "?M2 = Some a"
using ‹RBT_Mapping2.lookup m1 x = None› Some
by (simp add: Mapping.lookup.abs_eq ‹ID ccompare ≠ None› lookup_join)
ultimately show ?thesis
by simp
qed
next
case (Some a)
show ?thesis proof (cases "RBT_Mapping2.lookup m2 x")
case None
have "?M1 = Some a"
using None Some
by (metis combine_options_simps(2) lookup_Mapping_code(2) lookup_combine)
moreover have "?M2 = Some a"
using None Some
by (simp add: Mapping.lookup.abs_eq ‹ID ccompare ≠ None› lookup_join)
ultimately show ?thesis
by simp
next
case (Some b)
have "?M1 = Some (Prefix_Tree.combine a b)"
using ‹RBT_Mapping2.lookup m1 x = Some a› Some
by (metis combine_options_simps(3) lookup_Mapping_code(2) lookup_combine)
moreover have "?M2 = Some (Prefix_Tree.combine a b)"
using ‹RBT_Mapping2.lookup m1 x = Some a› Some
by (simp add: Mapping.lookup.abs_eq ‹ID ccompare ≠ None› lookup_join)
ultimately show ?thesis
by simp
qed
qed
qed
then have "(Mapping.combine Prefix_Tree.combine (RBT_Mapping m1) (RBT_Mapping m2)) = (RBT_Mapping (RBT_Mapping2.join (λ a b c . Prefix_Tree.combine b c) m1 m2))"
by (metis Mapping.lookup.rep_eq rep_inverse)
then show ?thesis
unfolding * unfolding combine_MPT by simp
qed
declare [[code drop: Prefix_Tree.is_leaf]]
lemma is_leaf_refined[code] :
fixes m :: "('a :: ccompare, 'a prefix_tree) mapping_rbt"
shows "Prefix_Tree.is_leaf (MPT (RBT_Mapping m))
= (case ID CCOMPARE('a) of
None ⇒ Code.abort (STR ''is_leaf_MPT_RBT_Mapping: ccompare = None'') (λ_. Prefix_Tree.is_leaf (MPT (RBT_Mapping m)))
| Some _ ⇒ RBT_Mapping2.is_empty m)"
(is "?PT1 = ?PT2")
proof (cases "ID CCOMPARE('a)")
case None
then show ?thesis by simp
next
case (Some a)
then have *: "?PT2 = RBT_Mapping2.is_empty m"
by auto
show ?thesis
unfolding *
by (metis (no_types, opaque_lifting) MPT_def Mapping.is_empty_empty RBT_Mapping2.is_empty_empty Some is_leaf.elims(2) is_leaf_MPT lookup_Mapping_code(2) lookup_empty_empty mapping_empty_code(4) mapping_empty_def option.distinct(1) prefix_tree.inject)
qed
end