Add documentation
This commit is contained in:
@@ -15,6 +15,24 @@
|
||||
* *
|
||||
*************************************************************************/
|
||||
|
||||
/**
|
||||
* @file splay.yap
|
||||
* @author Vijay Saraswat
|
||||
* @date Wed Nov 18 01:12:49 2015
|
||||
*
|
||||
* @brief "Self-adjusting Binary Search Trees
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
:- module(splay,[
|
||||
splay_access/5,
|
||||
splay_insert/4,
|
||||
splay_del/3,
|
||||
splay_init/1,
|
||||
splay_join/3,
|
||||
splay_split/5]).
|
||||
|
||||
/** @defgroup Splay_Trees Splay Trees
|
||||
@ingroup library
|
||||
@{
|
||||
@@ -24,15 +42,93 @@ Trees", by D.D. Sleator and R.E. Tarjan, JACM, vol. 32, No.3, July 1985,
|
||||
p. 668. They are designed to support fast insertions, deletions and
|
||||
removals in binary search trees without the complexity of traditional
|
||||
balanced trees. The key idea is to allow the tree to become
|
||||
unbalanced. To make up for this, whenever we find a node, we move it up
|
||||
unbalanced. To make up for this, whenever we \ find a node, we move it up
|
||||
to the top. We use code by Vijay Saraswat originally posted to the Prolog
|
||||
mailing-list.
|
||||
|
||||
Date: Sun 22 Mar 87 03:40:22-EST
|
||||
>From: vijay <Vijay.Saraswat@C.CS.CMU.EDU>
|
||||
Subject: Splay trees in LP languages.
|
||||
|
||||
There have hardly been any interesting programs in this Digest for a
|
||||
long while now. Here is something which may stir the slothful among
|
||||
you! I present Prolog programs for implementing self-adjusting binary
|
||||
search trees, using splaying. These programs should be among the most
|
||||
efficient Prolog programs for maintaining binary search trees, with
|
||||
dynamic insertion and deletion.
|
||||
|
||||
The algorithm is taken from: "Self-adjusting Binary Search Trees",
|
||||
D.D. Sleator and R.E. Tarjan, JACM, vol. 32, No.3, July 1985, p. 668.
|
||||
(See Tarjan's Turing Award lecture in this month's CACM for a more
|
||||
informal introduction).
|
||||
-----------------------------------------
|
||||
|
||||
The operations provided by the program are:
|
||||
|
||||
1. access(i,t): (implemented by the call access(V, I, T, New))
|
||||
"If item i is in tree t, return a pointer to its location;
|
||||
otherwise return a pointer to the null node."
|
||||
In our implementation, in the call access(V, I, T, New),
|
||||
V is unifies with `null' if the item is not there, else
|
||||
with `true' if it is there, in which case I is also
|
||||
unified with that item.
|
||||
|
||||
2. insert(i,t): (implemented by the call insert(I, T, New))
|
||||
"Insert item i in tree t, assuming that it is not there already."
|
||||
(In our implementation, i is not inserted if it is already
|
||||
there: rather it is unified with the item already in the tree.)
|
||||
|
||||
3. delete(i,t): (implemented by the call del(I, T, New))
|
||||
"Delete item i from tree t, assuming that it is present."
|
||||
(In our implementation, the call fails if the item is not in
|
||||
the tree.)
|
||||
|
||||
4. join(t1,t2): (Implemented by the call join(T1, T2, New))
|
||||
"Combine trees t1 and t2 into a single tree containing
|
||||
all items from both trees, and return the resulting
|
||||
tree. This operation assumes that all items in t1 are
|
||||
less than all those in t2 and destroys both t1 and t2."
|
||||
|
||||
5. split(i,t): (implemented by the call split(I, T, Left, Right))
|
||||
"Construct and return two trees t1 and t2, where t1
|
||||
contains all items in t less than i, and t2 contains all
|
||||
items in t greater than i. This operations destroys t."
|
||||
|
||||
The basic workhorse is the routine bst(Op, Item, Tree, NewTree), which
|
||||
returns in NewTree a binary search tree obtained by searching for Item
|
||||
in< Tree and splaying. OP controls what must happen if Item is not
|
||||
found in the Tree. If Op = access(V), then V is unified with null if
|
||||
the item is not found in the tree, and with true if it is; in the
|
||||
latter case Item is also unified with the item found in the tree. In
|
||||
% the first case, splaying is done at the node at which the discovery
|
||||
% was made that Item was not in the tree, and in the second case
|
||||
% splaying is done at the node at which Item is found. If Op=insert,
|
||||
% then Item is inserted in the tree if it is not found, and splaying is
|
||||
% done at the new node; if the item is found, then splaying is done at
|
||||
% the node at which it is found.
|
||||
|
||||
% A node is simply an n/3 structure: n(NodeValue, LeftSon, RightSon).
|
||||
% NodeValue could be as simple as an integer, or it could be a (Key,
|
||||
% Value) pair.
|
||||
|
||||
|
||||
% A node is simply an n/3 structure: n(NodeValue, LeftSon, RightSon).
|
||||
% NodeValue could be as simple as an integer, or it could be a (Key,
|
||||
% Value) pair.
|
||||
|
||||
% Here are the top-level axioms. The algorithm for del/3 is the first
|
||||
% algorithm mentioned in the JACM paper: namely, first access the
|
||||
% element to be deleted, thus bringing it to the root, and then join its
|
||||
% sons. (join/4 is discussed later.)
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
/*
|
||||
@pred splay_access(- _Return_,+ _Key_,? _Val_,+ _Tree_,- _NewTree_)
|
||||
|
||||
|
||||
v
|
||||
If item _Key_ is in tree _Tree_, return its _Val_ and
|
||||
unify _Return_ with `true`. Otherwise unify _Return_ with
|
||||
`null`. The variable _NewTree_ unifies with the new tree.
|
||||
@@ -86,93 +182,10 @@ Construct and return two trees _LeftTree_ and _RightTree_,
|
||||
where _LeftTree_ contains all items in _Tree_ less than
|
||||
_Key_, and _RightTree_ contains all items in _Tree_
|
||||
greater than _Key_. This operations destroys _Tree_.
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
*/
|
||||
:- module(splay,[
|
||||
splay_access/5,
|
||||
splay_insert/4,
|
||||
splay_del/3,
|
||||
splay_init/1,
|
||||
splay_join/3,
|
||||
splay_split/5]).
|
||||
|
||||
% Date: Sun 22 Mar 87 03:40:22-EST
|
||||
% >From: vijay <Vijay.Saraswat@C.CS.CMU.EDU>
|
||||
% Subject: Splay trees in LP languages.
|
||||
|
||||
% There have hardly been any interesting programs in this Digest for a
|
||||
% long while now. Here is something which may stir the slothful among
|
||||
% you! I present Prolog programs for implementing self-adjusting binary
|
||||
% search trees, using splaying. These programs should be among the most
|
||||
% efficient Prolog programs for maintaining binary search trees, with
|
||||
% dynamic insertion and deletion.
|
||||
|
||||
% The algorithm is taken from: "Self-adjusting Binary Search Trees",
|
||||
% D.D. Sleator and R.E. Tarjan, JACM, vol. 32, No.3, July 1985, p. 668.
|
||||
% (See Tarjan's Turing Award lecture in this month's CACM for a more
|
||||
% informal introduction).
|
||||
% -----------------------------------------
|
||||
|
||||
% The operations provided by the program are:
|
||||
|
||||
% 1. access(i,t): (implemented by the call access(V, I, T, New))
|
||||
% "If item i is in tree t, return a pointer to its location;
|
||||
% otherwise return a pointer to the null node."
|
||||
% In our implementation, in the call access(V, I, T, New),
|
||||
% V is unifies with `null' if the item is not there, else
|
||||
% with `true' if it is there, in which case I is also
|
||||
% unified with that item.
|
||||
|
||||
% 2. insert(i,t): (implemented by the call insert(I, T, New))
|
||||
% "Insert item i in tree t, assuming that it is not there already."
|
||||
% (In our implementation, i is not inserted if it is already
|
||||
% there: rather it is unified with the item already in the tree.)
|
||||
|
||||
% 3. delete(i,t): (implemented by the call del(I, T, New))
|
||||
% "Delete item i from tree t, assuming that it is present."
|
||||
% (In our implementation, the call fails if the item is not in
|
||||
% the tree.)
|
||||
|
||||
% 4. join(t1,t2): (Implemented by the call join(T1, T2, New))
|
||||
% "Combine trees t1 and t2 into a single tree containing
|
||||
% all items from both trees, and return the resulting
|
||||
% tree. This operation assumes that all items in t1 are
|
||||
% less than all those in t2 and destroys both t1 and t2."
|
||||
|
||||
% 5. split(i,t): (implemented by the call split(I, T, Left, Right))
|
||||
% "Construct and return two trees t1 and t2, where t1
|
||||
% contains all items in t less than i, and t2 contains all
|
||||
% items in t greater than i. This operations destroys t."
|
||||
|
||||
% The basic workhorse is the routine bst(Op, Item, Tree, NewTree), which
|
||||
% returns in NewTree a binary search tree obtained by searching for Item
|
||||
% in< Tree and splaying. OP controls what must happen if Item is not
|
||||
% found in the Tree. If Op = access(V), then V is unified with null if
|
||||
% the item is not found in the tree, and with true if it is; in the
|
||||
% latter case Item is also unified with the item found in the tree. In
|
||||
% the first case, splaying is done at the node at which the discovery
|
||||
% was made that Item was not in the tree, and in the second case
|
||||
% splaying is done at the node at which Item is found. If Op=insert,
|
||||
% then Item is inserted in the tree if it is not found, and splaying is
|
||||
% done at the new node; if the item is found, then splaying is done at
|
||||
% the node at which it is found.
|
||||
|
||||
% A node is simply an n/3 structure: n(NodeValue, LeftSon, RightSon).
|
||||
% NodeValue could be as simple as an integer, or it could be a (Key,
|
||||
% Value) pair.
|
||||
|
||||
|
||||
% A node is simply an n/3 structure: n(NodeValue, LeftSon, RightSon).
|
||||
% NodeValue could be as simple as an integer, or it could be a (Key,
|
||||
% Value) pair.
|
||||
|
||||
% Here are the top-level axioms. The algorithm for del/3 is the first
|
||||
% algorithm mentioned in the JACM paper: namely, first access the
|
||||
% element to be deleted, thus bringing it to the root, and then join its
|
||||
% sons. (join/4 is discussed later.)
|
||||
|
||||
splay_access(V, Item, Val, Tree, NewTree):-
|
||||
bst(access(V), Item, Val, Tree, NewTree).
|
||||
|
Reference in New Issue
Block a user