Author: Matthew Suderman
This work specifies a number of abstract data types (ADT) in VDM-SL. This includes single-linked lists, double-linked lists, queues, stacks and binary trees. In addition this work is initiating a translation from VDM-SL to Modula-2 so system addressing and dynamic memory handing is specified in VDM-SL. This work was done by Matthew Suderman when he was a student at Trinity Western University in the Spring Semester, 1997.
Properties | Values |
---|---|
Language Version: | classic |
Entry point : | DEFAULT`TestTrees() |
types
ADDRESS = nat;
values
NIL: ADDRESS = 0;
types
Nodes_Data = Data;
types
Nodes_SingleLink ::
data: Nodes_Data
next: Nodes_NodePtr;
Nodes_DoubleLink ::
data: Nodes_Data
next: Nodes_NodePtr
prev: Nodes_NodePtr;
Nodes_BinaryTree ::
data: Nodes_Data
right: Nodes_NodePtr
left: Nodes_NodePtr
parent: Nodes_NodePtr;
Nodes_Node = Nodes_SingleLink | Nodes_DoubleLink | Nodes_BinaryTree;
Nodes_NodePtr = ADDRESS;
functions
Nodes_MkSingleLink: Nodes_Data * Nodes_NodePtr -> Nodes_Node
Nodes_MkSingleLink(data, ptr) == mk_Nodes_SingleLink(data, ptr);
Nodes_MkDoubleLink: Nodes_Data * Nodes_NodePtr * Nodes_NodePtr -> Nodes_Node
Nodes_MkDoubleLink(data, next, prev) == mk_Nodes_DoubleLink(data, next, prev);
Nodes_MkBinaryTree: Nodes_Data * Nodes_NodePtr * Nodes_NodePtr * Nodes_NodePtr
-> Nodes_Node
Nodes_MkBinaryTree(data, right, left, parent) ==
mk_Nodes_BinaryTree(data, right, left, parent);
Nodes_GetData: Nodes_Node -> Nodes_Data
Nodes_GetData(node) ==
if is_Nodes_SingleLink(node) then
let mk_Nodes_SingleLink(data, -) = node in data
elseif is_Nodes_DoubleLink(node) then
let mk_Nodes_DoubleLink(data, -, -) = node in data
else
let mk_Nodes_BinaryTree(data, -, -, -) = node in data
pre is_Nodes_SingleLink(node)
or is_Nodes_DoubleLink(node)
or is_Nodes_BinaryTree(node);
Nodes_SetData: Nodes_Node * Nodes_Data -> Nodes_Node
Nodes_SetData(node, data) ==
if is_Nodes_SingleLink(node) then
let mk_Nodes_SingleLink(-, next) = node in
mk_Nodes_SingleLink(data, next)
elseif is_Nodes_DoubleLink(node) then
let mk_Nodes_DoubleLink(-, next, prev) = node in
mk_Nodes_DoubleLink(data, next, prev)
else
let mk_Nodes_BinaryTree(-, right, left, parent) = node in
mk_Nodes_BinaryTree(data, right, left, parent)
pre is_Nodes_SingleLink(node)
or is_Nodes_DoubleLink(node)
or is_Nodes_BinaryTree(node);
Nodes_GetNext: Nodes_Node -> Nodes_NodePtr
Nodes_GetNext(node) ==
if is_Nodes_SingleLink(node) then
let mk_Nodes_SingleLink(-, next) = node in next
else
let mk_Nodes_DoubleLink(-, next, -) = node in next
pre is_Nodes_SingleLink(node)
or is_Nodes_DoubleLink(node);
Nodes_SetNext: Nodes_Node * Nodes_NodePtr -> Nodes_Node
Nodes_SetNext(node, next) ==
if is_Nodes_SingleLink(node) then
let mk_Nodes_SingleLink(data, -) = node in
mk_Nodes_SingleLink(data, next)
else
let mk_Nodes_DoubleLink(data, -, prev) = node in
mk_Nodes_DoubleLink(data, next, prev)
pre is_Nodes_SingleLink(node)
or is_Nodes_DoubleLink(node);
Nodes_GetPrev: Nodes_Node -> Nodes_NodePtr
Nodes_GetPrev(node) ==
let mk_Nodes_DoubleLink(-, -, prev) = node in prev
pre is_Nodes_DoubleLink(node);
Nodes_SetPrev: Nodes_Node * Nodes_NodePtr -> Nodes_Node
Nodes_SetPrev(node, prev) ==
let mk_Nodes_DoubleLink(data, next, -) = node in
mk_Nodes_DoubleLink(data, next, prev)
pre is_Nodes_DoubleLink(node);
Nodes_GetRight: Nodes_Node -> Nodes_NodePtr
Nodes_GetRight(node) ==
let mk_Nodes_BinaryTree(-, right, -, -) = node in right
pre is_Nodes_BinaryTree(node);
Nodes_SetRight: Nodes_Node * Nodes_NodePtr -> Nodes_Node
Nodes_SetRight(node, right) ==
let mk_Nodes_BinaryTree(data, -, left, parent) = node in
mk_Nodes_BinaryTree(data, right, left, parent)
pre is_Nodes_BinaryTree(node);
Nodes_GetLeft: Nodes_Node -> Nodes_NodePtr
Nodes_GetLeft(node) ==
let mk_Nodes_BinaryTree(-, -, left, -) = node in left
pre is_Nodes_BinaryTree(node);
Nodes_SetLeft: Nodes_Node * Nodes_NodePtr -> Nodes_Node
Nodes_SetLeft(node, left) ==
let mk_Nodes_BinaryTree(data, right, -, parent) = node in
mk_Nodes_BinaryTree(data, right, left, parent)
pre is_Nodes_BinaryTree(node);
Nodes_GetParent: Nodes_Node -> Nodes_NodePtr
Nodes_GetParent(node) ==
let mk_Nodes_BinaryTree(-, -, -, parent) = node in parent
pre is_Nodes_BinaryTree(node);
Nodes_SetParent: Nodes_Node * Nodes_NodePtr -> Nodes_Node
Nodes_SetParent(node, parent) ==
let mk_Nodes_BinaryTree(data, right, left, -) = node in
mk_Nodes_BinaryTree(data, right, left, parent)
pre is_Nodes_BinaryTree(node);
types Heaps_Data = [Nodes_Node];
values Heaps_Size = 20;
types
Heaps_Location ::
data: [Heaps_Data]
allocated: bool
inv mk_Heaps_Location(d, a) == (a = true) <=> (d <> nil);
Heaps_Heap ::
storage: seq of Heaps_Location
inv mk_Heaps_Heap(s) == len s = Heaps_Size
functions
Heaps_InitSequence: nat1 -> seq of Heaps_Location
Heaps_InitSequence(length) ==
if length > 1 then
[mk_Heaps_Location(nil, false)]
^Heaps_InitSequence(length - 1)
else
[mk_Heaps_Location(nil, false)];
Heaps_Init: () -> Heaps_Heap
Heaps_Init() == mk_Heaps_Heap(Heaps_InitSequence(Heaps_Size));
Heaps_AmountUsed: Heaps_Heap -> nat
Heaps_AmountUsed(heap) ==
let store = heap.storage in
len [store(i) | i in set inds store
& store(i).allocated = true];
Heaps_Available: Heaps_Heap -> bool
Heaps_Available(heap) ==
Heaps_AmountUsed(heap) < len heap.storage;
Heaps_ModifyLoc: Heaps_Heap * ADDRESS * Heaps_Location -> Heaps_Heap
Heaps_ModifyLoc(heap, address, location) ==
mk_Heaps_Heap(heap.storage++{address|->location})
pre address in set inds heap.storage;
Heaps_Modify: Heaps_Heap * ADDRESS * Heaps_Data -> Heaps_Heap
Heaps_Modify(heap, address, data) ==
Heaps_ModifyLoc(heap, address, mk_Heaps_Location(data, true))
pre let store = heap.storage in
address in set inds store
and store(address).allocated = true;
Heaps_Retrieve: Heaps_Heap * ADDRESS -> [Heaps_Data]
Heaps_Retrieve(heap, address) ==
heap.storage(address).data
pre
let store = heap.storage in
address in set inds store
and store(address).allocated = true;
Heaps_UnallocatedAddresses: Heaps_Heap -> set of ADDRESS
Heaps_UnallocatedAddresses(heap) ==
let store = heap.storage in
{i|i in set inds store & store(i).allocated = false};
Heaps_UnallocatedAddress: Heaps_Heap -> ADDRESS
Heaps_UnallocatedAddress(heap) ==
iota new in set Heaps_UnallocatedAddresses(heap) &
(forall i in set Heaps_UnallocatedAddresses(heap) & new <= i)
pre Heaps_Available(heap);
operations
NEW: Heaps_Data ==> ADDRESS
NEW(data) ==
( def newAddress = Heaps_UnallocatedAddress(heap) in
def newLoc = mk_Heaps_Location(data, true) in
( heap := Heaps_ModifyLoc(heap, newAddress, newLoc);
return newAddress;
)
)
pre Heaps_Available(heap);
DISPOSE: ADDRESS ==> ()
DISPOSE(address) ==
heap := Heaps_ModifyLoc(heap, address, mk_Heaps_Location(nil, false))
pre pre_Heaps_ModifyLoc(heap, address, mk_Heaps_Location(nil, false));
SET_DATA: ADDRESS * Data ==> ()
SET_DATA(ptr, data) ==
heap := Heaps_Modify(heap, ptr,
Nodes_SetData(Heaps_Retrieve(heap, ptr), data));
SET_NEXT: ADDRESS * ADDRESS ==> ()
SET_NEXT(ptr, next) ==
heap := Heaps_Modify(heap, ptr,
Nodes_SetNext(Heaps_Retrieve(heap, ptr), next));
SET_LEFT: ADDRESS * ADDRESS ==> ()
SET_LEFT(ptr, left) ==
heap := Heaps_Modify(heap, ptr,
Nodes_SetLeft(Heaps_Retrieve(heap, ptr), left));
SET_RIGHT: ADDRESS * ADDRESS ==> ()
SET_RIGHT(ptr, right) ==
heap := Heaps_Modify(heap, ptr,
Nodes_SetRight(Heaps_Retrieve(heap, ptr), right));
SET_PREV: ADDRESS * ADDRESS ==> ()
SET_PREV(ptr, prev) ==
heap := Heaps_Modify(heap, ptr,
Nodes_SetPrev(Heaps_Retrieve(heap, ptr), prev));
SET_PARENT: ADDRESS * ADDRESS ==> ()
SET_PARENT(ptr, parent) ==
heap := Heaps_Modify(heap, ptr,
Nodes_SetParent(Heaps_Retrieve(heap, ptr), parent));
DATA: ADDRESS ==> Data
DATA(ptr) ==
return Nodes_GetData(Heaps_Retrieve(heap, ptr));
NEXT: ADDRESS ==> ADDRESS
NEXT(ptr) ==
return Nodes_GetNext(Heaps_Retrieve(heap, ptr));
LEFT: ADDRESS ==> ADDRESS
LEFT(ptr) ==
return Nodes_GetLeft(Heaps_Retrieve(heap, ptr));
RIGHT: ADDRESS ==> ADDRESS
RIGHT(ptr) ==
return Nodes_GetRight(Heaps_Retrieve(heap, ptr));
PARENT: ADDRESS ==> ADDRESS
PARENT(ptr) ==
return Nodes_GetParent(Heaps_Retrieve(heap, ptr));
types SList_Data = Data;
types SList_List = Nodes_NodePtr;
functions
SList_IsEmpty: SList_List -> bool
SList_IsEmpty(list) == list = NIL;
SList_Seq: Heaps_Heap * SList_List -> seq of SList_Data
SList_Seq(heap, list) ==
if not SList_IsEmpty(list) then
let node = Heaps_Retrieve(heap, list) in
let data = Nodes_GetData(node) in
let tail = Nodes_GetNext(node) in
[data]^SList_Seq(heap, tail)
else
[];
SList_Lengthf: Heaps_Heap * SList_List -> nat
SList_Lengthf(heap, list) ==
if not SList_IsEmpty(list) then
let tail = Nodes_GetNext(Heaps_Retrieve(heap, list)) in
1 + SList_Lengthf(heap, tail)
else
0
post RESULT = len SList_Seq(heap, list);
SList_PtrToNode: Heaps_Heap * SList_List * nat1 -> Nodes_NodePtr
SList_PtrToNode(heap, list, position) ==
let tail = Nodes_GetNext(Heaps_Retrieve(heap, list)) in
if position > 1 then
SList_PtrToNode(heap, tail, position - 1)
else list
pre position <= SList_Lengthf(heap, list)
post
let data = Nodes_GetData(Heaps_Retrieve(heap, RESULT)),
listSeq = SList_Seq(heap, list) in
data = listSeq(position);
SList_Init: () -> SList_List
SList_Init() == NIL;
operations
SList_InsertAtBeginning: SList_List * SList_Data ==> SList_List
SList_InsertAtBeginning(list, data) ==
return NEW(Nodes_MkSingleLink(data, list))
post [data]^SList_Seq(heap~, list) = SList_Seq(heap, RESULT);
SList_InsertAfter: SList_List * Nodes_NodePtr * SList_Data ==> SList_List
SList_InsertAfter(list, ptr, data) ==
( dcl new: Nodes_NodePtr := NEW(Nodes_MkSingleLink(data, NEXT(ptr)));
SET_NEXT(ptr, new);
return list;
)
post
let old = SList_Seq(heap~, ptr) in
[old(1)]^[data]^tl old = SList_Seq(heap, ptr);
SList_Insert: SList_List * SList_Data * nat1 ==> SList_List
SList_Insert(list, data, position) ==
if position = 1 then
return SList_InsertAtBeginning(list, data)
else
return SList_InsertAfter(list,
SList_PtrToNode(heap, list, position - 1), data)
pre position <= SList_Lengthf(heap, list) + 1 and Heaps_Available(heap)
post let new = SList_Seq(heap, RESULT) in
SList_Seq(heap~, list)
= [new(i) | i in set inds new & i <> position]
and new(position) = data
and Heaps_AmountUsed(heap~) + 1 = Heaps_AmountUsed(heap);
SList_Append: SList_List * SList_Data ==> SList_List
SList_Append(list, data) ==
( dcl ptr: Nodes_NodePtr := list;
if ptr = NIL then
return SList_InsertAtBeginning(list, data)
else
( while (NEXT(ptr) <> NIL) do ptr := NEXT(ptr);
return SList_InsertAfter(list, ptr, data);
)
)
pre Heaps_Available(heap)
post SList_Seq(heap~, list)^[data] = SList_Seq(heap, RESULT)
and Heaps_AmountUsed(heap~) + 1 = Heaps_AmountUsed(heap);
SList_Update: SList_List * SList_Data * nat1 ==> SList_List
SList_Update(list, data, position) ==
( dcl ptr: Nodes_NodePtr := SList_PtrToNode(heap, list, position);
SET_DATA(ptr, data);
return list;
)
pre position <= SList_Lengthf(heap, list)
post SList_Seq(heap~, list)++{position |-> data} = SList_Seq(heap, RESULT)
and Heaps_AmountUsed(heap~) = Heaps_AmountUsed(heap);
SList_DeleteAtBeginning: SList_List ==> SList_List
SList_DeleteAtBeginning(list) ==
( dcl temp: Nodes_NodePtr := list,
newlist: SList_List := NEXT(list);
DISPOSE(temp);
return newlist;
)
post tl SList_Seq(heap~, list) = SList_Seq(heap, RESULT);
SList_DeleteAfter: SList_List * Nodes_NodePtr ==> SList_List
SList_DeleteAfter(list, ptr) ==
( dcl temp: Nodes_NodePtr;
temp := NEXT(ptr);
SET_NEXT(ptr, NEXT(temp));
DISPOSE(temp);
return list;
)
post let old = SList_Seq(heap~, ptr) in
[old(1)]^tl (tl old) = SList_Seq(heap, ptr);
SList_Delete: SList_List * nat1 ==> SList_List
SList_Delete(list, position) ==
( if position = 1 then return SList_DeleteAtBeginning(list)
else
return SList_DeleteAfter(list,
SList_PtrToNode(heap, list, position - 1))
)
pre position <= SList_Lengthf(heap, list)
post let old = SList_Seq(heap~, list) in
[old(i) | i in set inds old & i <> position]
= SList_Seq(heap, RESULT)
and Heaps_AmountUsed(heap~) = Heaps_AmountUsed(heap) + 1;
SList_Traverse: SList_List * (SList_Data -> SList_Data) ==> SList_List
SList_Traverse(list, traversal) ==
( dcl ptr: Nodes_NodePtr := list;
while (ptr <> NIL) do
( SET_DATA(ptr, traversal(DATA(ptr)));
ptr := NEXT(ptr);
);
return list;
)
post
let old = SList_Seq(heap~, list) in
old <> [] => [traversal(old(i)) | i in set inds old]
= SList_Seq(heap, RESULT);
SList_Length: SList_List ==> nat
SList_Length(list) == return SList_Lengthf(heap, list);
SList_Empty: SList_List ==> bool
SList_Empty(list) == return SList_IsEmpty(list);
SList_Element: SList_List * nat1 ==> SList_Data
SList_Element(list, position) == DATA(SList_PtrToNode(heap, list, position));
types
DList_Data = Data;
types
DList_List = Nodes_NodePtr;
functions
DList_LastNode: Heaps_Heap * DList_List -> Nodes_NodePtr
DList_LastNode(heap, list) ==
let next = Nodes_GetNext(Heaps_Retrieve(heap, list)) in
if next <> NIL then
DList_LastNode(heap, next)
else list;
DList_Forward: Heaps_Heap * DList_List -> seq of DList_Data
DList_Forward(heap, list) == SList_Seq(heap, list);
DList_Backward: Heaps_Heap * DList_List -> seq of DList_Data
DList_Backward(heap, list) ==
if list <> NIL then
let prev = Nodes_GetPrev(Heaps_Retrieve(heap, list)) in
let data = Nodes_GetData(Heaps_Retrieve(heap, list)) in
DList_Backward(heap, prev)^[data]
else [];
DList_IsList: Heaps_Heap * DList_List -> bool
DList_IsList(heap, list) ==
if list <> NIL then
DList_Forward(heap, list)
= DList_Backward(heap, DList_LastNode(heap, list))
else true;
DList_Init: () -> DList_List
DList_Init() == NIL;
operations
DList_InsertAtBeginning: DList_List * DList_Data ==> DList_List
DList_InsertAtBeginning(list, data) ==
( dcl new: Nodes_NodePtr := NEW(Nodes_MkDoubleLink(data, list, NIL));
if list <> NIL then SET_PREV(list, new);
return new;
)
post [data]^SList_Seq(heap~, list) = SList_Seq(heap, RESULT);
DList_InsertAfter: DList_List * Nodes_NodePtr * DList_Data ==> DList_List
DList_InsertAfter(list, ptr, data) ==
( dcl new: Nodes_NodePtr := NEW(Nodes_MkDoubleLink(data, NEXT(ptr), ptr));
if NEXT(ptr) <> NIL then SET_PREV(NEXT(ptr), new);
SET_NEXT(ptr, new);
return list;
)
post
let old = SList_Seq(heap~, ptr) in
[old(1)]^[data]^tl old = SList_Seq(heap, ptr);
DList_Insert: DList_List * DList_Data * nat1 ==> DList_List
DList_Insert(list, data, position) ==
if position = 1 then
return DList_InsertAtBeginning(list, data)
else
return DList_InsertAfter(list,
SList_PtrToNode(heap, list, position - 1), data)
pre position <= SList_Lengthf(heap, list) + 1 and
Heaps_Available(heap) and DList_IsList(heap, list)
post DList_IsList(heap, RESULT) and
let new = SList_Seq(heap, RESULT) in
SList_Seq(heap~, list)
= [new(i) | i in set inds new & i <> position]
and new(position) = data;
DList_DeleteAtBeginning: DList_List ==> DList_List
DList_DeleteAtBeginning(list) ==
( dcl temp: Nodes_NodePtr := list,
newlist: DList_List := NEXT(list);
if newlist <> NIL then SET_PREV(newlist, NIL);
DISPOSE(temp);
return newlist;
)
post tl SList_Seq(heap~, list) = SList_Seq(heap, RESULT);
DList_DeleteAfter: DList_List * Nodes_NodePtr ==> DList_List
DList_DeleteAfter(list, ptr) ==
( dcl temp: Nodes_NodePtr, nextPtr: Nodes_NodePtr;
temp := NEXT(ptr);
nextPtr := NEXT(temp);
SET_NEXT(ptr, nextPtr);
if nextPtr <> NIL then SET_PREV(nextPtr, ptr);
DISPOSE(temp);
return list;
)
post let old = SList_Seq(heap~, ptr) in
[old(1)]^tl (tl old) = SList_Seq(heap, ptr);
DList_Delete: DList_List * nat1 ==> DList_List
DList_Delete(list, position) ==
( if position = 1 then return DList_DeleteAtBeginning(list)
else return DList_DeleteAfter(list,
SList_PtrToNode(heap, list, position - 1))
)
pre position <= SList_Lengthf(heap, list) and DList_IsList(heap, list)
post DList_IsList(heap, RESULT) and
let old = SList_Seq(heap~, list) in
[old(i) | i in set inds old & i <> position]
= SList_Seq(heap, RESULT)
and Heaps_AmountUsed(heap~) = Heaps_AmountUsed(heap) + 1;
DList_Append: DList_List * DList_Data ==> DList_List
DList_Append(list, data) ==
( dcl ptr: Nodes_NodePtr := list;
if ptr = NIL then
return DList_InsertAtBeginning(list, data)
else
( while (NEXT(ptr) <> NIL) do ptr := NEXT(ptr);
return DList_InsertAfter(list, ptr, data);
)
)
pre Heaps_Available(heap) and DList_IsList(heap, list)
post SList_Seq(heap~, list)^[data] = SList_Seq(heap, RESULT)
and Heaps_AmountUsed(heap~) + 1 = Heaps_AmountUsed(heap)
and DList_IsList(heap, RESULT);
DList_Empty: DList_List ==> bool
DList_Empty(list) == SList_Empty(list);
DList_Element: DList_List * nat1 ==> DList_Data
DList_Element(list, position) == SList_Element(list, position);
DList_Length: DList_List ==> nat
DList_Length(list) == SList_Length(list);
DList_Traverse: DList_List * (DList_Data -> DList_Data) ==> DList_List
DList_Traverse(list, traversal) == SList_Traverse(list, traversal);
DList_Update: DList_List * DList_Data * nat1 ==> DList_List
DList_Update(list, data, position) == SList_Update(list, data, position);
types Queues_Data = Data;
types Queues_Queue = SList_List;
functions
Queues_Init: () -> Queues_Queue
Queues_Init() == SList_Init();
operations
Queues_Enqueue: Queues_Queue * Queues_Data ==> Queues_Queue
Queues_Enqueue(queue, data) == return SList_Append(queue, data);
Queues_Dequeue: Queues_Queue ==> Queues_Queue * Queues_Data
Queues_Dequeue(queue) ==
( if not SList_Empty(queue) then
( dcl data: Queues_Data := Queues_Head(queue);
return mk_(SList_Delete(queue, 1), data);
)
else error;
);
Queues_Head: Queues_Queue ==> Queues_Data
Queues_Head(queue) ==
if not SList_Empty(queue) then SList_Element(queue, 1)
else error;
types Stacks_Data = Data;
types Stacks_Stack = SList_List;
functions
Stacks_Init: () -> Stacks_Stack
Stacks_Init() == SList_Init();
operations
Stacks_Push: Stacks_Stack * Stacks_Data ==> Stacks_Stack
Stacks_Push(stack, data) == return SList_Insert(stack, data, 1);
Stacks_Top: Stacks_Stack ==> Stacks_Data
Stacks_Top(stack) ==
if not SList_Empty(stack) then SList_Element(stack, 1)
else error;
Stacks_Pop: Stacks_Stack ==> Stacks_Stack * Stacks_Data
Stacks_Pop(stack) ==
( if not SList_Empty(stack) then
( dcl data: Stacks_Data := Stacks_Top(stack);
return mk_(SList_Delete(stack, 1), data);
)
else error
);
types
STrees_Data = Data;
types
STrees_Direction = <ToRoot> | <ToLeft> | <ToRight>
types
STrees_Node ::
data: STrees_Data
position: nat1;
STrees_Tree = set of STrees_Node
inv tree ==
(forall node in set tree &
not STrees_IsRoot(tree, node) <=> STrees_IsChild(tree, node)
and STrees_IsUnique(tree, node))
and (tree <> {} <=> exists1 node in set tree &
STrees_IsRoot(tree, node));
STrees_Info ::
tree: STrees_Tree
current: [STrees_Node]
inv mk_STrees_Info(t, c) ==
(c = nil <=> t = {}) and
(c <> nil <=> (c in set t and let r = STrees_Root(t) in r.position = 1));
functions
STrees_GetTree: STrees_Info -> STrees_Tree
STrees_GetTree(mk_STrees_Info(tree, -)) == tree;
STrees_MkNode: STrees_Data * nat1 -> STrees_Node
STrees_MkNode(data, position) ==
mk_STrees_Node(data, position);
STrees_MkTree: set of STrees_Node -> STrees_Tree
STrees_MkTree(tree) == tree
pre inv_STrees_Tree(tree);
STrees_MkInfo: STrees_Tree * STrees_Node -> STrees_Info
STrees_MkInfo(tree, current) ==
mk_STrees_Info(tree, current)
pre inv_STrees_Info(mk_STrees_Info(tree, current));
STrees_Init: () -> STrees_Info
STrees_Init() == mk_STrees_Info({}, nil);
STrees_IsRoot: set of STrees_Node * STrees_Node -> bool
STrees_IsRoot(tree, mk_STrees_Node(dr, pr)) ==
not STrees_IsChild(tree, mk_STrees_Node(dr, pr))
pre mk_STrees_Node(dr, pr) in set tree;
STrees_IsParent: STrees_Tree * STrees_Node -> bool
STrees_IsParent(tree, node) ==
exists child in set tree & STrees_IsParentOf(tree, node, child)
pre node in set tree;
STrees_IsChild: set of STrees_Node * STrees_Node -> bool
STrees_IsChild(tree, node) ==
(exists parent in set tree & STrees_IsParentOf(tree, parent, node))
and (exists1 parent in set tree & STrees_IsParentOf(tree, parent, node))
pre node in set tree;
STrees_IsUnique: set of STrees_Node * STrees_Node -> bool
STrees_IsUnique(tree, mk_STrees_Node(data, position)) ==
(mk_STrees_Node(data, position) in set tree) and
(exists1 node in set tree & node.position = position);
STrees_IsParentOf: set of STrees_Node * STrees_Node * STrees_Node -> bool
STrees_IsParentOf(tree, node1, node2) ==
STrees_IsRightChildOf(tree, node2, node1)
or STrees_IsLeftChildOf(tree, node2, node1)
pre node1 in set tree and node2 in set tree;
STrees_IsRightChildOf: set of STrees_Node * STrees_Node * STrees_Node -> bool
STrees_IsRightChildOf(tree, node1, node2) ==
let mk_STrees_Node(-, position1) = node1 in
let mk_STrees_Node(-, position2) = node2 in
(position1 = 2*position2 + 1)
pre node1 in set tree and node2 in set tree;
STrees_IsLeftChildOf: set of STrees_Node * STrees_Node * STrees_Node -> bool
STrees_IsLeftChildOf(tree, node1, node2) ==
let mk_STrees_Node(-, position1) = node1 in
let mk_STrees_Node(-, position2) = node2 in
(position1 = 2*position2)
pre node1 in set tree and node2 in set tree;
STrees_Insert: STrees_Info * STrees_Data * STrees_Direction -> STrees_Info
STrees_Insert(mk_STrees_Info(tree, current), data, direction) ==
cases mk_(current, direction):
mk_(nil, <ToRoot>) -> STrees_InsertRoot(data),
mk_(-, <ToLeft>) -> STrees_InsertLeft(tree, current, data),
mk_(-, <ToRight>) -> STrees_InsertRight(tree, current, data)
end
pre
(direction = <ToRoot> => tree = {}) and
(direction = <ToLeft> => not STrees_HasLeftChild(tree, current)) and
(direction = <ToRight> => not STrees_HasRightChild(tree, current))
post inv_STrees_Info(RESULT);
STrees_InsertRoot: STrees_Data -> STrees_Info
STrees_InsertRoot(data) ==
let root = mk_STrees_Node(data, 1) in
mk_STrees_Info({root}, root);
STrees_InsertLeft: STrees_Tree * STrees_Node * STrees_Data -> STrees_Info
STrees_InsertLeft(tree, current, data) ==
let mk_STrees_Node(-, position) = current in
let new = mk_STrees_Node(data, 2*position) in
mk_STrees_Info(tree union {new}, new)
pre not STrees_HasLeftChild(tree, current);
STrees_InsertRight: STrees_Tree * STrees_Node * STrees_Data -> STrees_Info
STrees_InsertRight(tree, current, data) ==
let mk_STrees_Node(-, position) = current in
let new = mk_STrees_Node(data, 2*position + 1) in
mk_STrees_Info(tree union {new}, new)
pre not STrees_HasRightChild(tree, current);
STrees_Traverse: STrees_Info * (STrees_Data -> STrees_Data) -> STrees_Info
STrees_Traverse(treeinfo, traversal) ==
let mk_STrees_Info(tree, current) = treeinfo in
if current <> nil then
let mk_STrees_Node(data, position) = current in
let newtree = {mk_STrees_Node(traversal(data), position) |
mk_STrees_Node(data, position) in set tree} in
mk_STrees_Info(newtree,
mk_STrees_Node(traversal(data), position))
else
treeinfo;
STrees_MoveInDir: STrees_Info * STrees_Direction -> STrees_Info
STrees_MoveInDir(mk_STrees_Info(tree, current), direction) ==
cases direction:
<ToRoot> -> mk_STrees_Info(tree, STrees_Root(tree)),
<ToLeft> -> mk_STrees_Info(tree, STrees_LeftChild(tree, current)),
<ToRight> -> mk_STrees_Info(tree, STrees_RightChild(tree, current))
end
pre STrees_ExistsDirection(mk_STrees_Info(tree, current), direction);
STrees_MoveToNode: STrees_Info * nat1 -> STrees_Info
STrees_MoveToNode(mk_STrees_Info(tree, current), position) ==
mk_STrees_Info(tree, STrees_GetNode(tree, position))
pre STrees_ExistsNode(mk_STrees_Info(tree, current), position);
STrees_MoveToParent: STrees_Info -> STrees_Info
STrees_MoveToParent(mk_STrees_Info(tree, current)) ==
mk_STrees_Info(tree, STrees_Parent(tree, current))
pre not STrees_IsRoot(tree, current);
STrees_MoveToAnscestor: STrees_Info * nat1 -> STrees_Info
STrees_MoveToAnscestor(treeinfo, pathlength) ==
if pathlength > 1
then STrees_MoveToAnscestor(STrees_MoveToParent(treeinfo), pathlength - 1)
else STrees_MoveToParent(treeinfo)
pre pre_STrees_MoveToParent(treeinfo);
STrees_Root: STrees_Tree -> STrees_Node
STrees_Root(tree) ==
iota root in set tree & STrees_IsRoot(tree, root)
pre tree <> {};
STrees_Parent: STrees_Tree * STrees_Node -> STrees_Node
STrees_Parent(tree, node) ==
iota parent in set tree
& STrees_IsParentOf(tree, parent, node)
pre node in set tree and not STrees_IsRoot(tree, node);
STrees_LeftChild: STrees_Tree * STrees_Node -> STrees_Node
STrees_LeftChild(tree, parent) ==
iota leftchild in set tree &
STrees_IsLeftChildOf(tree, leftchild, parent)
pre parent in set tree and STrees_HasLeftChild(tree, parent);
STrees_RightChild: STrees_Tree * STrees_Node -> STrees_Node
STrees_RightChild(tree, parent) ==
iota rightchild in set tree &
STrees_IsRightChildOf(tree, rightchild, parent)
pre parent in set tree and STrees_HasRightChild(tree, parent);
STrees_GetNode: STrees_Tree * nat1 -> STrees_Node
STrees_GetNode(tree, position) ==
iota node in set tree & node.position = position
pre exists node in set tree & node.position = position;
STrees_GetData: STrees_Info * nat1 -> STrees_Data
STrees_GetData(mk_STrees_Info(tree, current), position) ==
let mk_STrees_Node(data, -) = STrees_GetNode(tree, position) in
data
pre STrees_ExistsNode(mk_STrees_Info(tree, current), position);
STrees_StoreCurrentData: STrees_Info * STrees_Data -> STrees_Info
STrees_StoreCurrentData(mk_STrees_Info(tree, current), data) ==
let mk_STrees_Node(-, position) = current in
let newcurrent = mk_STrees_Node(data, position) in
mk_STrees_Info((tree\{current}) union {newcurrent}, newcurrent)
pre current <> nil;
STrees_GetCurrentData: STrees_Info -> STrees_Data
STrees_GetCurrentData(mk_STrees_Info(tree, mk_STrees_Node(data, -))) == data
pre tree <> {};
STrees_Size: STrees_Info -> nat
STrees_Size(mk_STrees_Info(tree, -)) == card tree;
STrees_GetCurrentNode: STrees_Info -> STrees_Node
STrees_GetCurrentNode(mk_STrees_Info(-, current)) == current;
STrees_SetCurrentNode: STrees_Info * STrees_Node -> STrees_Info
STrees_SetCurrentNode(mk_STrees_Info(tree, -), newcurrent) ==
mk_STrees_Info(tree, newcurrent)
pre newcurrent in set tree;
STrees_HasLeftChild: STrees_Tree * STrees_Node -> bool
STrees_HasLeftChild(tree, parent) ==
exists1 child in set tree
& STrees_IsLeftChildOf(tree, child, parent)
pre parent in set tree;
STrees_HasRightChild: STrees_Tree * STrees_Node -> bool
STrees_HasRightChild(tree, parent) ==
exists1 child in set tree
& STrees_IsRightChildOf(tree, child, parent)
pre parent in set tree;
STrees_InOrderPredecessor: STrees_Tree * STrees_Node -> STrees_Node
STrees_InOrderPredecessor(tree, node) ==
let leftchild = STrees_LeftChild(tree, node) in
let left = STrees_Subtree(tree, leftchild) in
let rightpath = {n | n in set left
& (exists p in set {0, ..., card left}
& n.position
= (leftchild.position + 1)*2**p - 1)} in
iota pred in set rightpath
& (forall n in set rightpath & n.position <= pred.position)
pre node in set tree and STrees_HasLeftChild(tree, node);
STrees_Delete: STrees_Info -> STrees_Info
STrees_Delete(mk_STrees_Info(tree, current)) ==
let old = STrees_Subtree(tree, current)
in
if STrees_HasRightChild(tree, current) and
STrees_HasLeftChild(tree, current)
then let leftchild = STrees_LeftChild(tree, current),
rightchild = STrees_RightChild(tree, current),
left = STrees_Subtree(old, leftchild),
mk_STrees_Node(-, position) =
STrees_InOrderPredecessor(old, current),
newright = STrees_MoveSubtree(old, rightchild,
2*position + 1),
newleft = left union newright,
new = STrees_MoveSubtree(newleft, STrees_Root(newleft),
current.position)
in
mk_STrees_Info((tree \ old) union new, STrees_Root(new))
elseif STrees_HasLeftChild(tree, current)
then let leftchild = STrees_LeftChild(tree, current),
new = STrees_MoveSubtree(old, leftchild, current.position)
in
mk_STrees_Info((tree \ old) union new, STrees_Root(new))
elseif STrees_HasRightChild(tree, current)
then let rightchild = STrees_RightChild(tree, current),
new = STrees_MoveSubtree(old, rightchild, current.position)
in
mk_STrees_Info((tree \ old) union new, STrees_Root(new))
else
mk_STrees_Info(tree \ {current}, STrees_Parent(tree, current))
pre current <> nil
post inv_STrees_Info(RESULT);
STrees_Subtree: STrees_Tree * STrees_Node -> STrees_Tree
STrees_Subtree(tree, mk_STrees_Node(rootdata, rootpos)) ==
{mk_STrees_Node(d, p) | mk_STrees_Node(d, p) in set tree
& (exists1 n in set {0, ..., card tree}
& p >= rootpos*2**n and p < (rootpos + 1)*2**n)}
pre mk_STrees_Node(rootdata, rootpos) in set tree;
STrees_MoveSubtree: STrees_Tree * STrees_Node * nat1 -> STrees_Tree
STrees_MoveSubtree(tree, subtreeRoot, newRootPos) ==
let subtree = STrees_Subtree(tree, subtreeRoot),
mk_STrees_Node(-, oldRootPos) = subtreeRoot in
{STrees_MoveNode(tree, node, oldRootPos, newRootPos)
| node in set subtree}
pre subtreeRoot in set tree;
STrees_MoveNode: STrees_Tree * STrees_Node * nat1 * nat1 -> STrees_Node
STrees_MoveNode(tree, mk_STrees_Node(d, p), oldRootPos, newRootPos) ==
let n = (iota n in set {0, ..., card tree}
& p >= oldRootPos*2**n and p < (oldRootPos + 1)*2**n) in
mk_STrees_Node(d, newRootPos*2**n + p - oldRootPos*2**n);
STrees_ExistsData: STrees_Info * STrees_Data -> bool
STrees_ExistsData(mk_STrees_Info(tree, -), data) ==
exists node in set tree & node.data = data;
STrees_ExistsNode: STrees_Info * nat1 -> bool
STrees_ExistsNode(mk_STrees_Info(tree, -), position) ==
exists node in set tree & node.position = position;
STrees_ExistsDirection: STrees_Info * STrees_Direction -> bool
STrees_ExistsDirection(mk_STrees_Info(tree, current), direction) ==
cases direction:
<ToRoot> -> (tree <> {}),
<ToLeft> ->
if current <> nil then
STrees_HasLeftChild(tree, current)
else false,
<ToRight> ->
if current <> nil then
STrees_HasRightChild(tree, current)
else false
end;
types Trees_Data = Data
types
Trees_Direction = STrees_Direction;
Trees_Tree ::
treePtr: Nodes_NodePtr
current: Nodes_NodePtr
functions
Trees_Position: Heaps_Heap * Nodes_NodePtr -> nat1
Trees_Position(heap, child) ==
let parent = Nodes_GetParent(Heaps_Retrieve(heap, child)) in
if parent = NIL then
1
elseif Trees_IsRightChildOf(heap, child, parent) then
2*Trees_Position(heap, parent) + 1
else
2*Trees_Position(heap, parent)
pre child <> NIL;
Trees_Set: Heaps_Heap * Trees_Tree -> STrees_Info
Trees_Set(heap, mk_Trees_Tree(treePtr, current)) ==
if treePtr <> NIL then
let treeset = STrees_MkTree(Trees_SubtreeToSet(heap, treePtr, 1)) in
let data = Nodes_GetData(Heaps_Retrieve(heap, current)) in
let position = Trees_Position(heap, current) in
let currentnode = STrees_MkNode(data, position) in
STrees_MkInfo(treeset, currentnode)
else STrees_Init();
Trees_SubtreeToSet: Heaps_Heap * Nodes_NodePtr * nat1 -> set of STrees_Node
Trees_SubtreeToSet(heap, subtree, position) ==
if subtree <> NIL
then {STrees_MkNode(Nodes_GetData(Heaps_Retrieve(heap, subtree)), position)}
union Trees_SubtreeToSet(heap,
Nodes_GetLeft(
Heaps_Retrieve(heap, subtree)), 2*position)
union Trees_SubtreeToSet(heap,
Nodes_GetRight(
Heaps_Retrieve(heap, subtree)), 2*position + 1)
else {};
Trees_HasLeftChild: Heaps_Heap * Nodes_NodePtr -> bool
Trees_HasLeftChild(heap, ptr) ==
if ptr <> NIL then
Nodes_GetLeft(Heaps_Retrieve(heap, ptr)) <> NIL
else false
pre ptr <> NIL => pre_Heaps_Retrieve(heap, ptr);
Trees_HasRightChild: Heaps_Heap * Nodes_NodePtr -> bool
Trees_HasRightChild(heap, ptr) ==
if ptr <> NIL then
Nodes_GetRight(Heaps_Retrieve(heap, ptr)) <> NIL
else false
pre ptr <> NIL => pre_Heaps_Retrieve(heap, ptr);
Trees_IsRightChildOf: Heaps_Heap * Nodes_NodePtr * Nodes_NodePtr -> bool
Trees_IsRightChildOf(heap, child, parent) ==
child = Nodes_GetRight(Heaps_Retrieve(heap, parent))
and parent = Nodes_GetParent(Heaps_Retrieve(heap, child))
pre pre_Heaps_Retrieve(heap, parent)
and pre_Heaps_Retrieve(heap, child);
Trees_IsLeftChildOf: Heaps_Heap * Nodes_NodePtr * Nodes_NodePtr -> bool
Trees_IsLeftChildOf(heap, child, parent) ==
child = Nodes_GetLeft(Heaps_Retrieve(heap, parent))
and parent = Nodes_GetParent(Heaps_Retrieve(heap, child))
pre pre_Heaps_Retrieve(heap, parent)
and pre_Heaps_Retrieve(heap, child);
Trees_IsRoot: Heaps_Heap * Nodes_NodePtr -> bool
Trees_IsRoot(heap, ptr) == Nodes_GetParent(Heaps_Retrieve(heap, ptr)) = NIL
pre ptr <> NIL;
Trees_Init: () -> Trees_Tree
Trees_Init() == mk_Trees_Tree(NIL, NIL);
operations
Trees_Insert: Trees_Tree * Trees_Data * Trees_Direction ==> Trees_Tree
Trees_Insert(tree, data, direction) ==
cases direction:
<ToRoot> -> return Trees_InsertRoot(data),
<ToLeft> -> return Trees_InsertLeft(tree, data),
<ToRight> -> return Trees_InsertRight(tree, data),
others -> error
end
pre Heaps_Available(heap) and
let mk_Trees_Tree(treePtr, current) = tree
in
(direction = <ToRoot> => treePtr = NIL) and
(direction = <ToRight> => not Trees_HasRightChild(heap, current)) and
(direction = <ToLeft> => not Trees_HasLeftChild(heap, current))
post Heaps_AmountUsed(heap~) + 1 = Heaps_AmountUsed(heap) and
let old = Trees_Set(heap~, tree) in
STrees_Insert(old, data, direction) = Trees_Set(heap, RESULT);
Trees_InsertRoot: Trees_Data ==> Trees_Tree
Trees_InsertRoot(data) ==
(dcl newTreePtr: Nodes_NodePtr := NEW(Nodes_MkBinaryTree(data, NIL, NIL, NIL));
return mk_Trees_Tree(newTreePtr, newTreePtr);
);
Trees_InsertLeft: Trees_Tree * Trees_Data ==> Trees_Tree
Trees_InsertLeft(mk_Trees_Tree(treePtr, current), data) ==
(dcl new: Nodes_NodePtr := NEW(Nodes_MkBinaryTree(data, NIL, NIL, current));
SET_LEFT(current, new);
return mk_Trees_Tree(treePtr, new);
);
Trees_InsertRight: Trees_Tree * Trees_Data ==> Trees_Tree
Trees_InsertRight(mk_Trees_Tree(treePtr, current), data) ==
(dcl new: Nodes_NodePtr := NEW(Nodes_MkBinaryTree(data, NIL, NIL, current));
SET_RIGHT(current, new);
return mk_Trees_Tree(treePtr, new);
);
Trees_InOrderPredecessor: Nodes_NodePtr ==> Nodes_NodePtr
Trees_InOrderPredecessor(ptr) ==
(dcl pred: Nodes_NodePtr := LEFT(ptr);
while Trees_HasRightChild(heap, pred) do
pred := RIGHT(pred);
return pred;
)
pre Trees_HasLeftChild(heap, ptr);
Trees_Delete: Trees_Tree ==> Trees_Tree
Trees_Delete(mk_Trees_Tree(treePtr, current)) ==
( dcl hasLeftChild: bool := Trees_HasLeftChild(heap, current),
hasRightChild: bool := Trees_HasRightChild(heap, current),
newcurrent: Nodes_NodePtr,
newtree: Nodes_NodePtr := treePtr,
parent: Nodes_NodePtr := PARENT(current),
newchild: Nodes_NodePtr;
if hasLeftChild or hasRightChild then
( if hasLeftChild then
( newcurrent := LEFT(current);
if hasRightChild then
( dcl right: Nodes_NodePtr := RIGHT(current),
pred :Nodes_NodePtr := Trees_InOrderPredecessor(current);
SET_PARENT(right, pred);
SET_RIGHT(pred, right);
);
)
else
newcurrent := RIGHT(current);
newchild := newcurrent;
SET_PARENT(newcurrent, parent);
)
else
( newcurrent := parent;
newchild := NIL;
);
if Trees_IsRoot(heap, current) then
newtree := newchild
elseif Trees_IsRightChildOf(heap, current, parent) then
SET_RIGHT(parent, newchild)
else
SET_LEFT(parent, newchild);
DISPOSE(current);
return mk_Trees_Tree(newtree, newcurrent);
)
pre treePtr <> NIL
post Heaps_AmountUsed(heap~) = Heaps_AmountUsed(heap) + 1 and
let old = Trees_Set(heap~, mk_Trees_Tree(treePtr, current)) in
STrees_Delete(old) = Trees_Set(heap, RESULT);
Trees_SearchSubtree: Nodes_NodePtr * Trees_Data ==> bool
Trees_SearchSubtree(subtree, dataToFind) ==
(
if subtree <> NIL then
( def data = DATA(subtree) in
if data = dataToFind then
return true
else
return Trees_SearchSubtree(RIGHT(subtree), dataToFind)
or Trees_SearchSubtree(LEFT(subtree), dataToFind)
)
else return false
);
Trees_ExistsData: Trees_Tree * Trees_Data ==> bool
Trees_ExistsData(tree, data) == Trees_SearchSubtree(tree.treePtr, data)
post STrees_ExistsData(Trees_Set(heap, tree), data) = RESULT;
Trees_ExistsDirection: Trees_Tree * Trees_Direction ==> bool
Trees_ExistsDirection(tree, direction) ==
cases direction:
<ToRoot> -> return tree.treePtr <> NIL,
<ToLeft> ->
return tree.current <> NIL
and Trees_HasLeftChild(heap, tree.current),
<ToRight> ->
return tree.current <> NIL
and Trees_HasRightChild(heap, tree.current),
others -> error
end
post STrees_ExistsDirection(Trees_Set(heap, tree), direction)
= RESULT;
Trees_GetCurrentData: Trees_Tree ==> Trees_Data
Trees_GetCurrentData(tree) == DATA(tree.current)
pre tree.treePtr <> NIL
post STrees_GetCurrentData(Trees_Set(heap, tree)) = RESULT;
Trees_StoreCurrentData: Trees_Tree * Trees_Data ==> Trees_Tree
Trees_StoreCurrentData(tree, data) ==
( SET_DATA(tree.current, data);
return tree;
)
pre tree.treePtr <> NIL
post STrees_StoreCurrentData(Trees_Set(heap~, tree), data)
= Trees_Set(heap, RESULT);
Trees_MoveInDir: Trees_Tree * Trees_Direction ==> Trees_Tree
Trees_MoveInDir(tree, direction) ==
cases direction:
<ToRoot> -> return mk_Trees_Tree(tree.treePtr, tree.treePtr),
<ToLeft> -> return mk_Trees_Tree(tree.treePtr, LEFT(tree.current)),
<ToRight> -> return mk_Trees_Tree(tree.treePtr, RIGHT(tree.current)),
others -> error
end
pre tree.treePtr <> NIL
and (direction = <ToLeft> => Trees_HasLeftChild(heap, tree.current))
and (direction = <ToRight> => Trees_HasRightChild(heap, tree.current))
post STrees_MoveInDir(Trees_Set(heap~, tree), direction)
= Trees_Set(heap, RESULT);
Trees_MoveToParent: Trees_Tree ==> Trees_Tree
Trees_MoveToParent(tree) ==
return mk_Trees_Tree(tree.treePtr, PARENT(tree.current))
pre not Trees_IsRoot(heap, tree.current)
post STrees_MoveToParent(Trees_Set(heap~, tree))
= Trees_Set(heap, RESULT);
Trees_Size: Trees_Tree ==> nat
Trees_Size(tree) == Trees_SubtreeSize(tree.treePtr)
post STrees_Size(Trees_Set(heap~, tree)) = RESULT;
Trees_SubtreeSize: Nodes_NodePtr ==> nat
Trees_SubtreeSize(subtree) ==
if subtree <> NIL then
return
1
+ Trees_SubtreeSize(RIGHT(subtree))
+ Trees_SubtreeSize(LEFT(subtree))
else return 0;
Trees_Traverse: Trees_Tree * (Trees_Data -> Trees_Data) ==> Trees_Tree
Trees_Traverse(tree, traversal) ==
( Trees_TraverseSubtree(tree.treePtr, traversal);
return tree;
)
post STrees_Traverse(Trees_Set(heap~, tree), traversal)
= Trees_Set(heap, RESULT);
Trees_TraverseSubtree: Nodes_NodePtr * (Trees_Data -> Trees_Data) ==> ()
Trees_TraverseSubtree(subtree, traversal) ==
if subtree <> NIL then
( SET_DATA(subtree, traversal(DATA(subtree)));
Trees_TraverseSubtree(LEFT(subtree), traversal);
Trees_TraverseSubtree(RIGHT(subtree), traversal);
);
state SystemState of
heap: Heaps_Heap
slist: SList_List
charQueue: Queues_Queue
charStack: Stacks_Stack
dlist: DList_List
charTree: Trees_Tree
stree: STrees_Info
init s == s = mk_SystemState(
Heaps_Init(),
SList_Init(),
Queues_Init(),
Stacks_Init(),
DList_Init(),
Trees_Init(),
STrees_Init())
end
types Data = char;
operations
TestSList: () ==> bool
TestSList() ==
(
slist := SList_Insert(slist, 'b', 1);
slist := SList_Update(slist, 'a', 1);
slist := SList_Delete(slist, 1);
slist := SList_Insert(slist, 'a', 1);
slist := SList_Insert(slist, 'b', 2);
slist := SList_Update(slist, 'c', 2);
slist := SList_Delete(slist, 2);
slist := SList_Insert(slist, 'b', 2);
slist := SList_Insert(slist, 'c', 3);
slist := SList_Update(slist, 'd', 2);
slist := SList_Update(slist, 'b', 3);
slist := SList_Delete(slist, 2);
slist := SList_Append(slist, 'c');
slist := SList_Delete(slist, 1);
slist := SList_Insert(slist, 'a', 1);
slist := SList_Insert(slist, 'f', 4);
slist := SList_Insert(slist, 'd', 4);
slist := SList_Append(slist, 'g');
slist := SList_Insert(slist, 'e', 5);
slist := SList_Append(slist, 'h');
slist := SList_Append(slist, 'i');
slist := SList_Append(slist, 'j');
slist := SList_Delete(slist, 10);
return [SList_Element(slist, i)| i in set {1, ..., 9}] = "abcdefghi";
);
TestDList: () ==> bool
TestDList() ==
(
dlist := DList_Insert(dlist, 'b', 1);
dlist := DList_Update(dlist, 'a', 1);
dlist := DList_Delete(dlist, 1);
dlist := DList_Insert(dlist, 'a', 1);
dlist := DList_Insert(dlist, 'b', 2);
dlist := DList_Update(dlist, 'c', 2);
dlist := DList_Delete(dlist, 2);
dlist := DList_Insert(dlist, 'b', 2);
dlist := DList_Insert(dlist, 'c', 3);
dlist := DList_Update(dlist, 'd', 2);
dlist := DList_Update(dlist, 'b', 3);
dlist := DList_Delete(dlist, 2);
dlist := DList_Append(dlist, 'c');
dlist := DList_Delete(dlist, 1);
dlist := DList_Insert(dlist, 'a', 1);
dlist := DList_Insert(dlist, 'f', 4);
dlist := DList_Insert(dlist, 'd', 4);
dlist := DList_Append(dlist, 'g');
dlist := DList_Insert(dlist, 'e', 5);
dlist := DList_Append(dlist, 'h');
dlist := DList_Append(dlist, 'i');
dlist := DList_Append(dlist, 'j');
dlist := DList_Delete(dlist, 10);
return [DList_Element(dlist, i)| i in set {1, ..., 9}] = "abcdefghi";
);
values
InsertResult = STrees_MkTree(
{
STrees_MkNode('a', 1),
STrees_MkNode('b', 2),
STrees_MkNode('c', 3),
STrees_MkNode('d', 4),
STrees_MkNode('e', 5),
STrees_MkNode('f', 6),
STrees_MkNode('g', 7),
STrees_MkNode('h', 8),
STrees_MkNode('i', 9),
STrees_MkNode('j', 10),
STrees_MkNode('k', 11),
STrees_MkNode('l', 12),
STrees_MkNode('m', 13),
STrees_MkNode('n', 14),
STrees_MkNode('o', 15),
STrees_MkNode('p', 16),
STrees_MkNode('q', 17),
STrees_MkNode('r', 18),
STrees_MkNode('s', 19),
STrees_MkNode('t', 20),
STrees_MkNode('u', 21),
STrees_MkNode('v', 22),
STrees_MkNode('w', 23),
STrees_MkNode('x', 24),
STrees_MkNode('y', 25),
STrees_MkNode('z', 26)
});
DeleteResult = STrees_MkTree(
{
STrees_MkNode('a', 1),
STrees_MkNode('d', 2),
STrees_MkNode('c', 3),
STrees_MkNode('h', 4),
STrees_MkNode('i', 5),
STrees_MkNode('f', 6),
STrees_MkNode('o', 7),
STrees_MkNode('p', 8),
STrees_MkNode('r', 10),
STrees_MkNode('s', 11),
STrees_MkNode('l', 12),
STrees_MkNode('z', 13),
STrees_MkNode('j', 23),
STrees_MkNode('x', 24),
STrees_MkNode('y', 25),
STrees_MkNode('t', 46),
STrees_MkNode('u', 47),
STrees_MkNode('k', 95),
STrees_MkNode('v', 190),
STrees_MkNode('w', 191)
});
TraverseResult = STrees_MkTree(
{
STrees_MkNode('a', 1),
STrees_MkNode('a', 2),
STrees_MkNode('a', 3),
STrees_MkNode('a', 4),
STrees_MkNode('a', 5),
STrees_MkNode('a', 6),
STrees_MkNode('b', 7),
STrees_MkNode('b', 8),
STrees_MkNode('b', 10),
STrees_MkNode('b', 11),
STrees_MkNode('b', 12),
STrees_MkNode('b', 13),
STrees_MkNode('a', 23),
STrees_MkNode('b', 24),
STrees_MkNode('b', 25),
STrees_MkNode('b', 46),
STrees_MkNode('b', 47),
STrees_MkNode('b', 95),
STrees_MkNode('b', 190),
STrees_MkNode('b', 191)
});
AlphabetSubset = {'a','b','c','d','e','f','g','h','i','j'};
functions
Traversal: char -> char
Traversal(ch) ==
if ch in set AlphabetSubset then 'a' else 'b';
operations
TestSTreesInsert: () ==> bool
TestSTreesInsert() ==
(
stree := STrees_Insert(stree, 'a', <ToRoot>);
stree := STrees_Insert(stree, 'b', <ToLeft>);
stree := STrees_MoveToParent(stree);
stree := STrees_Insert(stree, 'c', <ToRight>);
stree := STrees_MoveToParent(stree);
stree := STrees_MoveInDir(stree, <ToLeft>);
stree := STrees_Insert(stree, 'd', <ToLeft>);
stree := STrees_MoveToParent(stree);
stree := STrees_Insert(stree, 'e', <ToRight>);
stree := STrees_MoveInDir(stree, <ToRoot>);
stree := STrees_MoveInDir(stree, <ToRight>);
stree := STrees_Insert(stree, 'f', <ToLeft>);
stree := STrees_MoveToParent(stree);
stree := STrees_Insert(stree, 'g', <ToRight>);
stree := STrees_MoveInDir(stree, <ToRoot>);
stree := STrees_MoveInDir(stree, <ToLeft>);
stree := STrees_MoveInDir(stree, <ToLeft>);
stree := STrees_Insert(stree, 'h', <ToLeft>);
stree := STrees_MoveToParent(stree);
stree := STrees_Insert(stree, 'i', <ToRight>);
stree := STrees_MoveToAnscestor(stree, 2);
stree := STrees_MoveInDir(stree, <ToRight>);
stree := STrees_Insert(stree, 'j', <ToLeft>);
stree := STrees_MoveToParent(stree);
stree := STrees_Insert(stree, 'k', <ToRight>);
stree := STrees_MoveInDir(stree, <ToRoot>);
stree := STrees_MoveInDir(stree, <ToRight>);
stree := STrees_MoveInDir(stree, <ToLeft>);
stree := STrees_Insert(stree, 'l', <ToLeft>);
stree := STrees_MoveToParent(stree);
stree := STrees_Insert(stree, 'm', <ToRight>);
stree := STrees_MoveToAnscestor(stree, 2);
stree := STrees_MoveInDir(stree, <ToRight>);
stree := STrees_Insert(stree, 'n', <ToLeft>);
stree := STrees_MoveToParent(stree);
stree := STrees_Insert(stree, 'o', <ToRight>);
stree := STrees_MoveInDir(stree, <ToRoot>);
stree := STrees_MoveInDir(stree, <ToLeft>);
stree := STrees_MoveInDir(stree, <ToLeft>);
stree := STrees_MoveInDir(stree, <ToLeft>);
stree := STrees_Insert(stree, 'p', <ToLeft>);
stree := STrees_MoveToParent(stree);
stree := STrees_Insert(stree, 'q', <ToRight>);
stree := STrees_MoveToAnscestor(stree, 2);
stree := STrees_MoveInDir(stree, <ToRight>);
stree := STrees_Insert(stree, 'r', <ToLeft>);
stree := STrees_MoveToParent(stree);
stree := STrees_Insert(stree, 's', <ToRight>);
stree := STrees_MoveToAnscestor(stree, 3);
stree := STrees_MoveInDir(stree, <ToRight>);
stree := STrees_MoveInDir(stree, <ToLeft>);
stree := STrees_Insert(stree, 't', <ToLeft>);
stree := STrees_MoveToParent(stree);
stree := STrees_Insert(stree, 'u', <ToRight>);
stree := STrees_MoveToAnscestor(stree, 2);
stree := STrees_MoveInDir(stree, <ToRight>);
stree := STrees_Insert(stree, 'v', <ToLeft>);
stree := STrees_MoveToParent(stree);
stree := STrees_Insert(stree, 'w', <ToRight>);
stree := STrees_MoveInDir(stree, <ToRoot>);
stree := STrees_MoveInDir(stree, <ToRight>);
stree := STrees_MoveInDir(stree, <ToLeft>);
stree := STrees_MoveInDir(stree, <ToLeft>);
stree := STrees_Insert(stree, 'x', <ToLeft>);
stree := STrees_MoveToParent(stree);
stree := STrees_Insert(stree, 'y', <ToRight>);
stree := STrees_MoveToAnscestor(stree, 2);
stree := STrees_MoveInDir(stree, <ToRight>);
stree := STrees_Insert(stree, 'z', <ToLeft>);
return STrees_GetTree(stree) = InsertResult;
);
TestSTreesDelete: () ==> bool
TestSTreesDelete() ==
(
stree := STrees_MoveToNode(stree, 14);
stree := STrees_Delete(stree);
stree := STrees_MoveToNode(stree, 17);
stree := STrees_Delete(stree);
stree := STrees_MoveToNode(stree, 13);
stree := STrees_Delete(stree);
stree := STrees_MoveToNode(stree, 7);
stree := STrees_Delete(stree);
stree := STrees_MoveToNode(stree, 5);
stree := STrees_Delete(stree);
stree := STrees_MoveToNode(stree, 2);
stree := STrees_Delete(stree);
return STrees_GetTree(stree) = DeleteResult;
);
TestSTrees: () ==> bool
TestSTrees() ==
(
if STrees_ExistsDirection(stree, <ToLeft>) then return false;
if STrees_ExistsDirection(stree, <ToRight>) then return false;
if not TestSTreesInsert() then return false;
if not TestSTreesDelete() then return false;
if not STrees_ExistsData(stree, 'c') then return false;
if not STrees_ExistsNode(stree, 3) then return false;
stree := STrees_MoveToNode(stree, 3);
if not STrees_ExistsDirection(stree, <ToLeft>) then return false;
if not STrees_ExistsDirection(stree, <ToRight>) then return false;
if not STrees_ExistsDirection(stree, <ToRoot>) then return false;
if 'z' <> STrees_GetData(stree, 13) then return false;
stree := STrees_SetCurrentNode(stree, STrees_MkNode('z', 13));
if STrees_MkNode('z', 13) <> STrees_GetCurrentNode(stree)
then return false;
stree := STrees_StoreCurrentData(stree, 'Z');
if 'Z' <> STrees_GetCurrentData(stree) then return false;
if STrees_Size(stree) <> 20 then return false;
stree := STrees_Traverse(stree, Traversal);
return STrees_GetTree(stree) = TraverseResult;
);
operations
TestTreesInsert: () ==> ()
TestTreesInsert() ==
(
charTree := Trees_Insert(charTree, 'a', <ToRoot>);
charTree := Trees_Insert(charTree, 'b', <ToLeft>);
charTree := Trees_MoveToParent(charTree);
charTree := Trees_Insert(charTree, 'c', <ToRight>);
charTree := Trees_MoveToParent(charTree);
charTree := Trees_MoveInDir(charTree, <ToLeft>);
charTree := Trees_Insert(charTree, 'd', <ToLeft>);
charTree := Trees_MoveToParent(charTree);
charTree := Trees_Insert(charTree, 'e', <ToRight>);
charTree := Trees_MoveInDir(charTree, <ToRoot>);
charTree := Trees_MoveInDir(charTree, <ToRight>);
charTree := Trees_Insert(charTree, 'f', <ToLeft>);
charTree := Trees_MoveToParent(charTree);
charTree := Trees_Insert(charTree, 'g', <ToRight>);
charTree := Trees_MoveInDir(charTree, <ToRoot>);
charTree := Trees_MoveInDir(charTree, <ToLeft>);
charTree := Trees_MoveInDir(charTree, <ToLeft>);
charTree := Trees_Insert(charTree, 'h', <ToLeft>);
charTree := Trees_MoveToParent(charTree);
charTree := Trees_Insert(charTree, 'i', <ToRight>);
charTree := Trees_MoveToParent(charTree);
charTree := Trees_MoveToParent(charTree);
charTree := Trees_MoveInDir(charTree, <ToRight>);
charTree := Trees_Insert(charTree, 'j', <ToLeft>);
charTree := Trees_MoveToParent(charTree);
charTree := Trees_Insert(charTree, 'k', <ToRight>);
charTree := Trees_MoveInDir(charTree, <ToRoot>);
charTree := Trees_MoveInDir(charTree, <ToRight>);
charTree := Trees_MoveInDir(charTree, <ToLeft>);
charTree := Trees_Insert(charTree, 'l', <ToLeft>);
charTree := Trees_MoveToParent(charTree);
charTree := Trees_Insert(charTree, 'm', <ToRight>);
charTree := Trees_MoveToParent(charTree);
charTree := Trees_MoveToParent(charTree);
charTree := Trees_MoveInDir(charTree, <ToRight>);
charTree := Trees_Insert(charTree, 'n', <ToLeft>);
charTree := Trees_MoveToParent(charTree);
charTree := Trees_Insert(charTree, 'o', <ToRight>);
);
TestTreesDelete: () ==> ()
TestTreesDelete() ==
(
charTree := Trees_MoveInDir(charTree, <ToRoot>);
charTree := Trees_MoveInDir(charTree, <ToRight>);
charTree := Trees_MoveInDir(charTree, <ToRight>);
charTree := Trees_MoveInDir(charTree, <ToRight>);
charTree := Trees_Delete(charTree);
charTree := Trees_Delete(charTree);
charTree := Trees_MoveInDir(charTree, <ToRoot>);
charTree := Trees_MoveInDir(charTree, <ToLeft>);
charTree := Trees_MoveInDir(charTree, <ToLeft>);
charTree := Trees_MoveInDir(charTree, <ToLeft>);
charTree := Trees_Delete(charTree);
charTree := Trees_Delete(charTree);
charTree := Trees_MoveInDir(charTree, <ToRoot>);
charTree := Trees_MoveInDir(charTree, <ToLeft>);
charTree := Trees_Delete(charTree);
charTree := Trees_MoveInDir(charTree, <ToRoot>);
charTree := Trees_MoveInDir(charTree, <ToRight>);
charTree := Trees_Delete(charTree);
charTree := Trees_MoveInDir(charTree, <ToRoot>);
charTree := Trees_Delete(charTree);
);
TestTrees: () ==> bool
TestTrees() ==
(
if Trees_ExistsDirection(charTree, <ToLeft>) then return false;
if Trees_ExistsDirection(charTree, <ToRight>) then return false;
TestTreesInsert();
TestTreesDelete();
if not Trees_ExistsData(charTree, 'i') then return false;
if Trees_ExistsDirection(charTree, <ToLeft>) then return false;
if not Trees_ExistsDirection(charTree, <ToRight>) then return false;
if not Trees_ExistsDirection(charTree, <ToRoot>) then return false;
charTree := Trees_StoreCurrentData(charTree, 'Z');
if 'Z' <> Trees_GetCurrentData(charTree) then return false;
if Trees_Size(charTree) <> 8 then return false;
charTree := Trees_Traverse(charTree, Traversal);
return true;
);