Theory Collections.PrioSpec
section ‹\isaheader{Specification of Priority Queues}›
theory PrioSpec
imports ICF_Spec_Base "HOL-Library.Multiset"
begin
text ‹
  We specify priority queues, that are abstracted to
  multisets of pairs of elements and priorities.
›
locale prio = 
  fixes α :: "'p ⇒ ('e × 'a::linorder) multiset" 
  fixes invar :: "'p ⇒ bool"                     
locale prio_no_invar = prio +
  assumes invar[simp, intro!]: "⋀s. invar s"
subsection "Basic Priority Queue Functions"
subsubsection "Empty Queue"
locale prio_empty = prio +
  constrains α :: "'p ⇒ ('e × 'a::linorder) multiset"
  fixes empty :: "unit ⇒ 'p"
  assumes empty_correct: 
  "invar (empty ())" 
  "α (empty ()) = {#}"
subsubsection "Emptiness Predicate"
locale prio_isEmpty = prio +
  constrains α :: "'p ⇒ ('e × 'a::linorder) multiset"
  fixes isEmpty :: "'p ⇒ bool"
  assumes isEmpty_correct: 
  "invar p ⟹ (isEmpty p) = (α p = {#})" 
subsubsection "Find Minimal Element"
locale prio_find = prio +
  constrains α :: "'p ⇒ ('e × 'a::linorder) multiset"
  fixes find :: "'p ⇒ ('e × 'a::linorder)"
  assumes find_correct: "⟦invar p; α p ≠ {#}⟧ ⟹ 
       (find p) ∈# (α p) ∧ (∀y ∈ set_mset (α p). snd (find p) ≤ snd y)"
subsubsection "Insert"
locale prio_insert = prio +
  constrains α :: "'p ⇒ ('e × 'a::linorder) multiset"
  fixes insert :: "'e ⇒ 'a ⇒ 'p ⇒ 'p"
  assumes insert_correct: 
  "invar p ⟹ invar (insert e a p)"
  "invar p ⟹ α (insert e a p) = (α p) + {#(e,a)#}" 
subsubsection "Meld Two Queues"
locale prio_meld = prio +
  constrains α :: "'p ⇒ ('e × 'a::linorder) multiset"
  fixes meld :: "'p ⇒ 'p ⇒ 'p"
  assumes meld_correct:
  "⟦invar p; invar p'⟧ ⟹ invar (meld p p')"
  "⟦invar p; invar p'⟧ ⟹ α (meld p p') = (α p) + (α p')"
subsubsection "Delete Minimal Element"
text ‹Delete the same element that find will return›
locale prio_delete = prio_find +
  constrains α :: "'p ⇒ ('e × 'a::linorder) multiset"
  fixes delete :: "'p ⇒ 'p"
  assumes delete_correct:
  "⟦invar p; α p ≠ {#}⟧ ⟹ invar (delete p)"
  "⟦invar p; α p ≠ {#}⟧ ⟹ α (delete p) = (α p) - {# (find p) #}"
subsection "Record based interface"