Louisiana State University
LSU Digital Commons
LSU Historical Dissertations and Theses
Graduate School
1989
A Framework for Efficient Execution of Logic
Programs.
Sudharsan R. Iyengar
Louisiana State University and Agricultural & Mechanical College
Follow this and additional works at: https://digitalcommons.lsu.edu/gradschool_disstheses
Recommended Citation
Iyengar, Sudharsan R., "A Framework for Efficient Execution of Logic Programs." (1989). LSU Historical Dissertations and Theses. 4783.
https://digitalcommons.lsu.edu/gradschool_disstheses/4783
This Dissertation is brought to you for free and open access by the Graduate School at LSU Digital Commons. It has been accepted for inclusion in
LSU Historical Dissertations and Theses by an authorized administrator of LSU Digital Commons. For more information, please contact
[email protected].
INFORMATION TO USERS
The m ost advanced technology has been used to photo
graph and reproduce th is m anuscript from th e microfilm
m aster. UMI film s th e te x t d irec tly from th e o rig in a l or
copy subm itted. Thus, some thesis and dissertation copies
are in typew riter face, w hile others may be from any type
of com puter printer.
The q u a lity of th is reproduction is d ep en d en t upon th e
quality of th e copy subm itted. Broken or indistinct p rin t,
colored or poor q u a lity illu s tra tio n s an d photographs,
print bleedthrough, su b stan d ard m argins, and im proper
alignm ent can adversely affect reproduction.
In th e unlikely event th a t th e author did not send UMI a
complete m anuscript and th ere are m issing pages, these
will be noted. Also, if u n au th o riz ed copyright m a te ria l
had to be removed, a note will indicate the deletion.
Oversize m aterials (e.g., maps, draw ings, charts) are re
produced by sectio n in g th e o rig in al, b e g in n in g a t th e
upper left-hand corner and continuing from left to rig h t in
equal sections w ith sm all overlaps. Each original is also
photographed in one exposure and is included in reduced
form at the back of th e book. These are also available as
one exposure on a stan d ard 35mm slide or as a 17" x 23"
black an d w h ite p h o to g ra p h ic p r in t for an a d d itio n a l
charge.
P hotographs included in th e o rig in al m a n u sc rip t have
been reproduced x ero g rap h ic ally in th is copy. H ig h e r
q u ality 6" x 9" black an d w h ite photographic p rin ts are
available for any photographs or illustrations appearing
in th is copy for an additional charge. Contact UMI directly
to order.
University Microfilms In ter national
A Bel t & H o w e l l I n f o r m a t i o n C o m p a n y
3 0 0 N o r t h Z e e b R o a d A n n A r b o r Ml 4 8 1 0 b 1 3 4 6 U S A
3 1 3 761 4 7 0 0
8 0 0 621 0 6 0 0
Order Number
A fra m ew o rk for efficien t e x e c u tio n o f logic p ro g ra m s
Iyengar, Sudharsan R., Ph.D .
T h e L o u is ia n a S ta te U n iv e rs ity a n d A g ric u ltu ra l a n d M e c h a n ic a l C o l., 1989
UMI
300 N. Zccb Rd.
Ann Arbor, Ml 48106
9017267
A Framework for Efficient Execution of Logic Programs
A Dissertation
Submitted to the Graduate Faculty of the
Louisiana State University and
Agricultural and Mechanical College
in partial fulfillment of the
requirements for the degree of
Doctor of Philosophy
in
The Department of Computer Science
by
Sudharsan R. Iyengar
B.E., Electrical Engineering, Regional Engineering College, Durgapur, India, 19S4
M.S., Systems Science, Louisiana State University, Baton Rouge, 1987
M.S., Electrical Engineering, Louisiana State University, Baton Rouge, 1987
August, 1989
Acknowledgem ents
I am indebted to my major professors S. Sitarama Iyengar and Dr. Andijez Hoppe
for their encouragement, support and guidance. More importantly, I am grateful for their
enormous amount of time spent in discussing and writing this dissertation. I thank my
committee members Prof. Donald H. Kraft, Dr. Doris Carver and Prof. El-Amawy.
I acknowledge the assistance of Dr. Sukhamay Kundu in this project
This work would not have been fruitful but for the relentless encouragement and
motivation provided by my dear uncle. Prof. A. Raman, and his family. My parents and
my sisters deserve special credit for the continuous love and affection, poured to me
through the distance from India.
Memories will always remain of my friends Lalitha Krishnamurthy, Krishna Prasad,
Mohan B. Sharma, Ananta Prasad, Guja (Rajanarayan), and scores of others who all pro
vided me with a nourishing environment throughout my Ph.D. work.
I also acknowledge the Department of Computer Science, in particular Dr. Kraft, for
the financial support.
ii
List of Tables
Table I
Trace of Naive Prolog E x e c u tio n ...................................................................... 32
Table n
Comparison of Results in L ite ra tu re ..................................................................60
Table III
Trace o f Execution by Intelligent B acktracking.............................................101
Table IV
Trace of Execution by Intelligent Forward E x ecu tio n ................. ..........
Table V
Trace of Execution by Forward Jumping and IntelligentBacktracking . . 133
Table VI
Trace of Execution by Intelligent Backtracking, Intelligent Forward . . . 155
Execution and Forward Jumping
iii
115
List of Symbols
symbol
«
meaning
and
V
or
-
not
<—
if
V
for all
3
there exists
1
such that
iff
if and only if
□
success
■
failure
A
solution of a goal
£
belongs to
U
set union
n
set intersection
0
empty set
0, o
state of computation
A
goal tree
S
search method
Iv
List of Figures
Figure 1.
Standard Goal-Search-Tree by P ro lo g ..........................................................................31
Figure 2.
Execution of Prolog on a linear stack ........................................................................ 36
Figure 3.1.
Recursive Execution Model, o f Pereira and P o r t o .....................................................41
Figure 3.2.
Dependency Tag representation, of Pereira and P o rto ................................................41
Figure 4.1.
Minimal Deduction Subtree that is consistent, o f B ru n o o g h ee............................... 43
Figure 4.2.
Maximal Deduction Subtree that is consistent, of C o x ............................................ 43
Figure 5.1.
Type I backtracking based on SDDA, of Chang and D cSpain...................................46
Figure 5.2.
Type II backtracking based on SDDA, of Chang and D esp ain ................................. 47
Figure 5.3.
Type III backtracking based on SDDA, of Chang and D espain ................................ 47
Figure 6.
Backtracking based on B-list, of Conery and K ib le r................................................ 50
Figure 7.
Backtracking based on dynamic B-list, of Vipin Kumar, e ta l ................................. 52
Figure 8.
Variable Based Backtracking, of Rajasekhar, e ta l. ................................................. 5 4
Figure 9.
Local-stack used by WAM, of Warren
Figure 10.
Identification of Failure-Bindings when a predicate is defined by facts..................6 9
Figure 11.
Identification of Failure-Bindings when a predicate has facts and rules..................7 1
Figure 12.1.
E ntriestoF B T ................................................................................................................75
Figure 12.2.
Maximal tuples in FBT
Figure 13.
Unification with facts and Bit-vector manipulation
Figure 14.
Bit-vector manipulation with application of rules
Figure 15.
Identification of Failure-binding in the presence of facts and r u l e s ........................ 94
Figure 16.
Incompleteness o f identification of Failure-bindings by r u l e s ................................ 97
Figure 17.
Incompleteness of identification of Failure-bindings by u n ification ......................9 8
Figure 18.
Goal-search tree explored by Intelligent Backtracking based on failure-bindings 100
Figure 19.
Goal-search tree explored by Intelligent Forward Execution..................................... 114
Figure 20.1.
Possible values of redo(2,9) for example in Figure 1.
Figure 20.2.
Possible values of redo(2, 11) for example in Figure 1 . .............................................I 26
...................................................................... 5 8
................................................................................................77
v
................................................. 92
................................................... 93
125
Figure 21.
Goal-search tree explored by Intelligent Backtracking and Forward lumping . . 1 3 2
Figure 22.
Execution of logic programs on Segmented S t a c k ................................................. 146
Figure 23.
Execution Model Implementing Intelligent Backtracking, Intelligent
Forward Execution and Forward Jumping................................................................. 153
Figure 24
Goal-search tree by Intelligent Backtracking, Intelligent Forward
Execution and Forward Ju m p in g ................................................................................154
vi
T able of C ontents
A c k n o w le d g e m e n ts ..................................................................................................................................i i
List o f T a b l e s .......................................................................................................................................... i i i
List o f Sym bols
....................................................................................................................................... *v
List o f Figures .............................................................................................................................................v
A bstract
........................................................................................................................................................ x
1. Introduction
.......................................................................................................................................... 1
1.1. O v e r v i e w .................................................................................................................................... 1
1.2. Logic Program m ing as a Tool for A rtificial Intelligence
.............................................. 3
1.3. Prolog as a L ogic Program m ing L anguage ...................................................................... 6
1.4. D isadvantages o f E x h au stiv e S earch b y P r o l o g ...................
10
1.5. M otivation for Efficient E x e c u tio n ...................................................................................
1.6. C ontribution o f the D issertation
.........................................................................................1 5
1.7 O utline o f the D is s e r ta tio n ................................................................................................
2. Introduction to Logic Program m ing
2.1. Logic Program s
17 *
.............................................................................................19
..................................................................................................................
2.2. R easoning by R e s o lu tio n .....................................................................................................22
2.3. U nification ..............................................................................................................................26
2.4. Procedural I n te rp r e ta tio n .....................................................................................................2 8
2.5. Interpreter
..............................................................................................................................33
2.6. Im plem entation I s s u e s .......................................................................................................... 3 7
3. L iterature R eview
...............................................................................................................................38
3.1. In tro d u c tio n .............................................................................................................................. 38
3.2. Selective B acktracking Based on U nification M apping In f o rm a tio n .....................3 9
3.3. R un-tim e Intelligent B a c k tra c k in g ....................................................................................4 2
3.4. S em i-Intelligent B acktracking Based on Static D ata D ependency A nalysis. . . . 4 4
3.5. G enerator-C onsum er A p p r o a c h ......................................................................................... 4 8
vii
3.6. Modified B-list Approach .............................................................................................51
3.7. Variable Based Intelligent Backtracking
...................................................................53
3.8 Warren Abstract M achine............................................................................................. 55
3.9. Discussion......................................................................................................................... 59
4. Intelligent Backtracking Based on Failure-B indings............................................................. 61
4.1. Introduction .................................................................................................................... 61
4.2. F ailure-B inding............................................................................................................... 63
4.3. Failure-Binding-Table
* * .............................................................................................75
4.4. Forward Execution Based on Failure-Binding
4.5. Generators and Consumers
........................................................ 78
.......................................................................................... 81
4.6. Backward Execution Based on Failure-Bindings ......................................................87
4.7. Bit-vector Implementation to Identify Failure-Bindings
.........................................90
4.8. Incompleteness of the Identification of F ailure-B indings.........................................9 ^
4.9.
Soundness and Completeness of < ; .........................................................................
5. Intelligent Forward Execution Based on Failure-Solutions.................................................105
5.1. Introduction
..................................................................................................................1 0 5
5.2. F ailu re-S o lu tio n s..........................................................................................................1 0 7
5.3. Failure-Solution-Table
............................................................................................... 109
5.4. Intelligent Forward Execution Based on Failure-Solution...................................... 1 1 0
5.5. Backward Execution Based on F ailure-S olution......................................................1 1 2
5.6. Soundness and Completeness o f t ; '............................................................................. 110
5.7. Difficulty in Implementation o ft;' ............................................................................. 110
6. Intelligent Forward Jumping
6.1. Introduction
.................................................................................................. 119
........................................................................................
119
6.2. Dependencies among subgoals.....................................................................................122
viit
6.3. Redo-list
....................................................................................................... 12 3
6.4. Forward J u m p in g ....................................................................................................... .1 3 0
6.3. Soundness and Completeness of ("Range Convergence for Forward Jump- . . . 134
ing
6.6. Difficulty in Implementation of (" ......................................................................... 1 3 5
7. Segmented Environment S ta c k .............................................................................................. 1 3 6
7.1. Introduction
.................................................................................................................13 ®
7.2. Inapplicability of Linear Stack to Implement (* and ( ” ........................................... 138
7.3. Segmented S t a c k ..................
.....1 3 9
7.4. Forward Execution on a Segmented S ta c k ................................................................ 3 * 3
7.5. Backward Execution on a Segmented S ta c k ............................................................. 3 * ^
7.6. Space Complexity o f Segmented S ta c k ....................................................................
8. Effects of Non-logical Operators
8.1. Introduction
......................................................................................... 148
..................................................................................................................1 4 8
8.2. Effect of Cut and F a i l . ..................................................................................................1 4 9
8.3. Effect of Assert and R e tr a c t ........................................................................................1 5 0
9. Summary ................................................................................................................................... 151
9.1. C on clu sio n s.................................................................................................................... 151
9.2. Future Directions .......................................................................................................... 158
R e fe re n c e s ..................................................................................................................................... 159
Vita ................................................................................................................................................ 1 6 6
lx
Abstract
The focus o f this dissertation is to develop an efficient framework for sequential
execution of logic programs. Within this framework the logic programs are executed by
pruning the goal-search tree whenever applicable.
Three new concepts for pruning o f computation during execution of logic programs
are introduced.
Fallure*binding
A Failure-binding for a literal is a binding which when applied to the literal
fails the goal obtained from the literal. Failure-bindings for a literal are
identified by analyzing the goal-trec o f a goal which is obtained from the
literal. The failure-bindings for a literal are used for intelligent backtracking
based on the generator-consumer approach. Intelligent backtracking based on
failure-bindings prune the computation of search space which lead to late
detection of failure.
Failure-aolution
A Failure-solution of a goal is unacceptable to some other subgoal in the for
ward execution. Failure-solutions o f a goal are identified by analyzing the his
tory of computation, during execution. Failure-soludons of the goals are used
for intelligent forward execution. Intelligent forward execution prunes the
computation of search space which leads to repeated failure resulting from
repeated successes of a goal.
Forward Jumping
Forward jumping is a method to avoid reexecution of some subgoals after
backtracking (instead of naive forward execution after backtracking). Forward
jumping is based on the dynamic subgoal dependencies in a rule. Such jum p
ing prunes the computation of the search spaces which leads to the same
sequences of successes of subgoals after backtracking.
x
To facilitate the implementation o f these concepts a new data structure, called
segm ented-stack, is defined. The space complexity o f a segmented stack is linear in the
number o f nodes in the stack. Depth-first search as well as breadth-first search are very
easily implemented on a segmented-stack during execution of logic programs. Execution
of logic programs on a segmented-stack allows association o f the search space, as well as
the solutions, of a goal with the frame of the goal. This enables implementation of intel
ligent backtracking, intelligent forward execution and forward jumping.
The search based on each of these paradigms is proved to be sound and complete. It
is also shown that the implementation of these paradigms preserves the order of results
obtained by Prolog. The effects of the non-logical operators, in Prolog, on the paradigms
are studied. The search based on these paradigms is compared individually, and collec
tively, with the standard search by Prolog.
Keywords: logic program m ing, failure-binding, intelligent backtracking,
failure-solution, intelligent forward execution,
forward jum ping, segm ented stack.
xi
Chapter 1
Introduction
1.1. Overview
Artificial Intelligence (AI), or computer intelligence, combines the automated
computing power o f computers to implement effective intelligent techniques.
Research in A1 has focused on the finding newer paradigms for automating intelligent
behavior. Recent attempts to develop comprehensive and adaptable intelligent sys
tems which obtain specific solutions to specific problems have proven beneficial in
areas such as medical diagnosis, legal affairs, weather forecasting, testing and safe
guarding of nuclear equipments, intelligent database and knowledge based systems,
robotics [55, 58], language processing, effective and relevant information retrieval,
and image processing.
Research in AI is being directed towards the development of systems which not
only obtain solutions for a given problem [5] but also refines their own process
dynamically so as to perform more accurately and efficiently. Such techniques use
some kind of a learning process, constraint-based efficient search methods, informa
tion refinement and enhancement techniques, and self correcting principles.
Over the past two decades, there has been a growing interest in the design and
development of AI languages useful in building intelligent systems which ate not only
efficient and easy to program, but which provide a framework for implementing learn
ing. Fifth Generation projects, by ICOT in Japan [42], concentrate on developing
languages and efficient frameworks for programming and executing knowledge based
decision support systems. Automated deduction is central to the aim of achieving
artificial intelligence.
l
2
H ie A! requirements of a language include provisions for
1) automatic deduction,
2) early and effective constraint realization and propagation,
3) ability to intermix procedures and data,
4) goal directed behavior,
5) knowledge structuring and learning,
6) metalevel programming and control structures, [57].
Three types o f languages for programming and developing such intelligent sys
tems are under consideration.
1.
Functional languages, like Lisp, are used in developing expert and produc
tion systems and for implementing constraint based computational models.
2.
Relational or Logic languages, like Prolog [4], are used in developing
advanced database and knowledge-base engineering and decision support
systems. Logic languages are basically rule based languages.
3.
Object oriented languages, like Smalltalk, are used for simulation, testing
and performance analysis of real problems.
O f these three types of languages, logic programming languages are most popular,
mainly because of their expressive capacity and simplicity.
The main focus of this dissertation is to obtain a general framework that provides
efficient execution process o f logic programs. In spirit, we attempt to present new
computational paradigms for efficient execution of logic programs using new charac
terizations and a new data structure.
3
1.2. Logic Programming as a Tool for Artificial Intelligence
Almost all AI problems are solved based on different types o f constraints which
need to be globally satisfied. This requires extensive search to effect constraint gen
eration, propagation and satisfiability. In logic programs the constraints are values for
variables - see section 2.2. Logic programming enables specification of constraint
propagation its execution performs the required search on these constraints.
Logic programming began in the early 1970's as a direct outgrowth o f earlier
work in automatic theorem proving and predicate logic. Earlier work by Herbrand,
Prawitz, Gilmore, Davis, Putnam [4] and others culminated in 1965 with the publica
tion o f the landmark paper by Robinson [ 1 - 6 ] which introduced the resolution princi
ple - an inference rule well suited to automation on a computer.
Kowalski [7 - 10] showed that an algorithm consists o f two disjoint components the logic and the control - the what and how part of a problem to be solved, respec
tively. Logic is used to express the what part. Thus, an algorithm is converted to
symbolic manipulation.
Logic is an effective symbolic framework for theorem proving. Theorem prov
ing is an automated deduction procedure, a procedure to derive newer information
from a given information base. Resolution theorem proving is an effective tool for
developing automated inference engine on a symbolic framework.
A symbolic system is developed to express knowledge in the form of proposi
tions, expressions which have only a True or False value, and the relationships
between these propositions. The statements, or rules, about these propositions also
express how one can validly infer newer propositions from those that are given. More
complicated propositions can be expressed in terms of simple propositions by the use
of the connectives (e.g.
a
, v , - i,
*—) between them.
4
The programmer needs to specify only the logic component of the problem in the
form o f propositions and rules about the propositions. The control during execution,
which is independent of the problem description, provides an answer to the query
requested by using standard deduction procedures on the propositions and rules
specified by the programmer.
Piopositional logic is a sound framework for symbolic computation. The argu
ments for propositional logic can be extended to predicate logic, where propositions
are expressed in terms of predicates, a predicate name followed by n-tuple arguments.
Predicate logic is a more general framework, because it allows more generalized
expressions in terms o f variables and ground terms. Variables can assume different
values at different times. The programmer can then specify general information about
a predicate using variables. First order predicate logic (FOPL), a restricted form of
predicate logic, see section 2.1, provides methods for deducing newer theorems of a
theory as logical consequences o f the axioms and the theorem which are provided. A
logic program consists of a set of procedures, or axioms, and a goal statem ent
Again the programmer needs to specify only the logic component of the problem
which is information about predicates. The execution, or the control part, provides
answer to the goal by using standard deduction procedures.
Predicate logic has two aspects: the syntactic and the semantic aspects. The syn
tactic aspect is concerned with syntactic constructs of the symbolic system. The
semantics is concerned with the meanings attached to the statements in the syntactic
constructs.
A clause is a disjunction of literals, which are propositions in the form of predi
cates. Ground unit clauses are facts, Le. a single literal with a fixed true or false value,
and rules are generalized clauses. A logic program with only ground unit clauses, i.e.
facts, is a relational database.
5
Theorem proving is an automated procedure to derive new information from a
given information base. Resolution theorem proving is an effective tool for develop
ing a automated deduction system. All logic programming systems are based on reso
lution theorem proving.
The problems in artificial intelligence can be converted into symbolic manipula
tion by proper knowledge representation, manipulation and inferencing problems.
Logic programs together with automatic deduction rules are based on the resolution
principle and form a powerful framework for developing AI systems. Most logic pro
gramming systems are resolution theorem provers.
The credit for the introduction of logic programming goes mainly to Kowalski
and Colmerauer [7 -10] who introduced in 1972 the fundamental idea that logic can be
used as a programming language. A programming language for implementing logic
programs is Prolog. The next section gives a brief introduction to Prolog.
6
1.3. Prolog as a Logic Programming Language
Prolog (PROgramming in LOGic) is a programming language to describe logic
programs. The first Prolog interpreter was implemented in Algol by Roussel in Mar
seille in 1972 [4].
Prolog is based on Robinson’s Resolution Principle with specific top-down leftto-right control. The programmer describes his problem in a symbolic framework
which he develops. Users can now test a goal on the logic program to obtain newer
information. The goal is also a symbolic expression. The goal is mapped onto the
program and the theorem proving technique is applied to see if the goal is satisfied by
the theorems provided in the program in the form of program clauses - facts and rules.
Programming in Prolog, with its well defined syntax, facilitates generalized
specification o f information and their inter-relationships. It essentially implements a
theorem prover for the programmer. The term "logic programs" has now become
analogous to Prolog programs.
Prolog systems employ the computation rule which always selects the leftmost
goal in a sequence o f goals called the goal-list for execution. It also employs Linear
Resolution with a Selector Function, a selection mechanism which uses the order of
the program clauses, to select clauses during execution. The execution mechanism is
independent of the program specification. Prolog employs deterministic top-down
resolution which results in depth-first search to satisfy a goal.
Success is reported if the goal unifies (see section 2.3) with a clause and the
clause is true. The goal-list is modified during the execution o f a logic program. The
search rule is implemented on a linear stack of goals, called the local-stack. An
instance o f the goal stack represents the branch of the goal-search tree that is currently
being investigated.
The computation then essentially becomes an interleaved
sequence of pushes and pops on this stack [see section 2.5].
7
The resulting search is a depth-first search of the goal-tree. Depth first rules can
be very efficiently implemented on a stack. For a system that searches depth-first, the
search rule reduces to an ordering rule which specifies the order in which the program
clauses are to be tried. Prolog systems use the order of clauses in a program as the
fixed order in which they are to be tried. This is implemented in a very simple and
efficient way.
The positive features of Prolog can be enumerated as follows.
• As any other programming language, it has well defined syntax.
• It is closer to a declarative language than are logic programs (see section 2.1).
The procedural interpretation of Prolog helps the programmer to follow Prolog
programs more clearly.
• The answers to the query are accurate within the domain o f the program lead
ing to answers within the closed world (CW) of the program.
• Not is implemented as a negation by failure - that is the negation of a goal is
true if the goal cannot be satisfied by the program. This is sufficient within the
CW o f the program.
• The selection rule is fixed; hence, the behavior of the program is explicit to the
programmer.
• The input/output indirection as a result of the unification substitution mechan
ism (see section 2.3) is a powerful characteristic. This removes the necessity
of mode specification in the programs. Thus programs can be used to test for
satisfiability of goals or to generate solutions for which the query is true,
• Prolog interpreters are usually interactive in nature and hence encourage
man-machine interaction.
• Failure of a goal implies that the goal cannot be satisfied with the given con
8
straints applied to the goal. Consequently, the detection o f a success or failure
of a goal is also sound.
• Backtracking is used to get also another set of constraints for a failed goal.
The actions taken by the interpreter to effect backtracking are elementary in
nature.
• Alternatives are selected top to bottom and failure is reported if and only if
there are no more alternatives for a goal. Thus, all possible paths to satisfying
a goal are explored. Consequently, every solution to a goal is reported. Since
the search is exhaustive, it is complete within the CW of the program, as long
as the search does not get trapped in an infinite loop.
• Many non-logical operators like +, -, is, nl, write, cut, assert and retract, are
provided to make Prolog useful for different applications.
■ Identical solutions for the predicates may be obtained via different search
paths in the goal-search tree. There is no restriction on the type or size of the
terms used and the number of solutions for a goal.1
• The control operates on a goal-list and a linear stack of activation records.
The implementation of this control is very simple and efficient - translating
itself into operations similar to the implementation of a Push Down Auto
mata.
Since Prolog implements depth first search with fixed ordering, the resulting
search is naive and exhaustive. Each call to a definition tries the clauses in the
definition in exactly the same order every time a program is executed. Even though it
employs goal-oriented search, it does not effect selective and relevant search.
t It is precisely due to this generality that the search process gets trapped into an infinite loop.
9
For an infinite search tree, depth-first search is not fair. Breadth-first search
would be fair (avoid infinite search tree), but is less compatible with efficient imple
mentations. The depth-first search method results in incompleteness o f Prolog resolu
tion, because it does not guarantee finding the success branch - even if one exists because the search may get trapped in an infinite branch. Hence, Prolog systems,
though sound, are partially incomplete.
Exhaustive search is not always necessary, and the search process can be pruned
without losing the soundness and completeness properties of Prolog. The disadvan
tages o f the present implementation of Prolog is presented in the next section.
10
1.4. Pisadvantages of Exhaustive Search by Prolog
Query processing should base its decisions on the entire search, i.e, the search
space with all the permutations of the constraints. It is also true that only a select set
o f permutations o f constraints satisfy the query. All sets o f permutations are tried by
employing backtracking when a failure is encountered during the execution of logic
programs. The set o f constraints and the resulting search space that is explored is
rather large.
The use o f traditional backtracking to explore a search space in a top-down,
depth-first scheme starts with the initial state with the query goal as the current state.
For each forward derivation step, one of the goals yet untried in the current state is
used to derive a new current state. Success is reported when the set o f untried goals
applicable in the current state is empty. Failure is reported when an untried goal in
the current state cannot be solved. Forward execution is repeated until a success state,
Q is reached, or a failed stated, ■ , is reached. In the □ state, the goal-list is empty
and the local-stack contains the path to the successful state. In the ■ state, the localstack is empty and the goal-state contains the query goal.
After reaching ■ , the system returns to a previous state. This process is called
backtracking. Forward execution is repeated for this state to derive newer states. If
backtracking returns to the state prior to ■ , then this is naive backtracking. A failure
is cured only when the cause of the failed state is undone. Retracting to the previous
state on reaching ■ may not be able to cure the failure. Unfortunately, there is no way
to identify the cause of failure. The result of naive backtracking could be unusual
trashing, unnecessary backtracking and forward execution.
Due to the depth-first search a subgoal may be tried more than once during dif
ferent stages o f computation.
Consider a state, f, in which failure is reported and also assume that backtracking
11
takes us to state b.
1. Backtracking to b, after the failure at f, and subsequent return to f, without any
change to the constraints applied in ft (this could be due to backtracking to b,
and subsequent return, without changing the constraints applied in f, or due to
applying the same set of constraints to the goal that failed in f)
2. Backtracking to b, after the failure in f, and subsequent return to f without cur
ing the cause of failure of the subgoal in f, (this could be due to backtracking
to b and solving a subgoal in b whose new solution does not cure the failure of
the subgoal that failed in f).
3. Multiple appearance o f the same subgoal in different states during the search
due to the appearance o f the same subgoal in different rules.
In particular, repeated computation of a subgoal may occur both for the case
when a subgoal succeeds (generating the same solutions) and for the case when a
subgoal fails (generating the same failure).
The specific deficiencies which result due to the exhaustive depth-first search
implemented by Prolog can be enumerated as:
•
Naive backtracking (backtracking without any basis) to the immediately
previous state results in an exhaustive search. This could result in inconse
quential exploration of some of the search space.
•
There are dependencies among the subgoals in the rule which imply seman
tic relationships among the subgoals. Naive backtracking does not use these
semantic relationships among the subgoals to identify a better state for
backtracking. Again, this could result in inconsequential exploration of
some of the search space.
The causes of failure of a subgoal in a state is not analyzed. This analysis
could lead to identification of specific causes of failure which could be used
for relevant exploration o f search-space.
When a goal fails in a state f, the dependency directed backtracking [5]
assumes the cause of failure of a goal as the set of all constraints applied to
the subgoal that failed in f. The backtracking is based on the dependencies
among the subgoals of the rule and the system selects the latest state that
generated any constraint for backtracking to ensure completeness of search.
The selection of the state for backtracking is not based on the causes of
failure of the subgoal in f. H ie resulting search by dependency-directed
backtracking may not cure the failure of the subgoal in f. The cause of
failure will eventually be corrected. This amounts to late detection, and
correction, o f the cause of failure. This results in futile exploration of some
of the search space.
The history of computation is not used during different stages of computa
tion. Repeated failures could occur due to the result of repeated identical
solutions, constraints, generated by certain other goals. This results in
repeatedly exploring in vain search spaces which contain no solutions. This
is a direct consequence of not maintaining the information from the history
of computation. Such dynamic learning is not employed by Prolog.
Computations continue blindly after backtracking. Some of the computa
tions that are performed after backtracking may be independent of the
corrective action taken by backtracking. Consequently, identical search
spaces which lead to success, which are independent o f the reason of back
tracking, may be repeated. These computations need not be repeated. Pro
log does not employ any technique to avoid the repetition of such computa-
13
dons.
•
Search spaces o f different subgoals in a rule are not maintained separately.
Prolog execution on a linear stack demands that computations be performed
in a systematic manner where even independent computations are stacked
on top of one another. This allows accessing different records in the chro
nological order of execution. H u s rules out independent access to the
search space o f different goals in a rule. Importantly, the information about
the solutions of a goal cannot be associated with the goal.
The area of efficient execution of logic programs have been addressed by many
researchers. The next section presents the motivation for intelligent execution of logic
programs.
14
1.5. Motivation tor Intelligent Execution
Efficient backtracking methods [1-7], which are essentially variants of depen
dency directed backtracking [9], have been proposed for eliminating certain inconse
quential computations. An intelligent search mechanism employs a search rule which
is directed by the information provided to it by the programmer. If no information is
provided to determine the search rule (the order of search), then certain information
derived during execution is used to effect selective and relevant search space explora
tion. These intelligent search methods use one or more of the following:
unification mapping information [11] (see section 3.2)
dynamic data-dependency [12, 13, 14, 15, 16] (see section 3.2)
static data-dependency [17,18] (see section 3.4)
variable binding informations [27] (see section 3.7)
generator-consumer lists of variables [19 - 26] (see sections 3.5 and 3.6)
selective page retainment in the main memory [28, 35.40]
elimination of tail-recursion [29 - 32] (see section 3.8)
The major deficiencies of the exhaustive search employed Prolog, presented in
section 1.3, have not been addressed by any of the existing solutions, for sequential
Prolog, in the literature. The information content of the program is static in that there
is no learning involved from the computations that are performed during execution.
An intelligent search rule should utilize the semantics prescribed by the rules in the
logic program together with a learning process and effective search techniques. The
focus o f this dissertation is to develop and present paradigms to eliminate all inconse
quential search space exploration during execution.
15
1.6. Contributions of the Dissertation
We present newly developed paradigms applicable to logic programs. A frame
work base for efficient execution
of
logic programs is developed based
chi
these para
digms and a new data structure for implementing these paradigms. The major contri
butions being made by this dissertation to the field of logic programs are as follows.
i)
An exact analysis of the failure o f a goal in logic programs is done to iden
tify definite causes of failure o f a goal. This gives global informations
about predicates which is associated with the predicates for future use, thus
effecting a learning process.
ii) A systematic evaluation method for identifying the causes of failure of the
current goal, in Prolog, is presented. This analysis does not demand exces
sive dynamic time and space. An algorithm to identify the causes of failure
is also presented.
iii) An intelligent backtracking scheme based on the identified exact causes of
failure of a goal is proposed. The resulting search resulting from intelligent
backtracking, based on exact causes of failure, is proved to be sound and
complete.
iv)
An intelligent forward execution algorithm to identify and eliminate
repeated computations which result in failure during forward execution is
presented. The intelligent forward execution is based on the notion of a
failure-solution of a goal. The failure solutions of a goal are identified from
the history of the execution. The resulting search based on intelligent for
ward execution based on failure solutions of a goal is proved to be complete
and sound.
v) Forward jumping algorithm to eliminate repetition of computation during
forward execution after backtracking is presented. Forward jumping is
16
based on subgoal dependencies in a rule. The forward jumping algorithm,
which further prunes redundant computations so as to result in successes, is
proved to be complete and sound.
vi)
A new data structure, a segmented stack, for implementing the above algo
rithms is defined. Execution of logic programs on a segmented stack facili
tates associating search spaces and solutions with a goal.
vii) Execution of logic programs based on the paradigms enumerated above is
shown to preserve the order of results as obtained by Prolog.
viii) The search space explored by the use o f the paradigms enumerated above is
compared to the search space explored by standard Prolog.
ix)
A framework which employs all the proposed paradigms is detailed.
17
1.7. Outline o f the Dissertation
Chapter 2 presents a formal introduction to logic programs describing in detail
the resolution principle and the implementation o f Prolog as a programming language.
The important implementation issues of a Prolog interpreter are analyzed in detail.
Chapter 3 reviews the literature pertaining to efficient execution of logic pro
grams and presents the significant contribution to intelligent sequential execution of
logic programs. Some o f the contributions of parallel execution models which are
applicable to sequential execution are exemplified.
Chapter 4 introduces the concept of a failure-binding of a goal after presenting a
discourse on the causes of failure of a goal. A modified unification algorithm which
enables the identification of failure-bindings is also presented. The selection of the
backtrack literal, backtracking and subsequent forward execution is illustrated. The
resulting search space explored is related to the search space explored by Prolog. It is
proved that the identification of failure-binding is sound. The causes of incomplete
ness o f the identification o f failure-binding is scrutinized. A method to use the
identified failure-bindings as global information about a predicate is described. This
information is associated with the predicates and are used during subsequent search.
The intelligent backtracking method based on failure-bindings is proved to be correct.
The forward and backward execution algorithms based on failure-bindings are
presented, and proved to preserve the soundness and completeness property of Prolog.
Chapter 5 introduces the notion of a failure-solution of a goal. A method to use
the dynamically identified failure solutions from the history of computation for intelli
gent forward execution is proposed. H ie intelligent forward execution algorithm is
presented. The correctness of this algorithm and the soundness and completeness pro
perties o f the resulting search are proved.
Hie concept o f forward-jumping during sequential execution of logic programs
18
is introduced in chapter 6. An algorithm to obtain to redo-list (see section 6.3), which
contains the subgoals which are independent o f the corrective action taken by the the
backtracking process, is presented. Different instances o f forward-jumping are illus
trated. Forward jumping for recursive backtracking is also detailed. The resulting
search is proved to be complete and sound. The search space explored by forward
jumping is compared to the standard search space explored by ftolog.
Chapter 7 introduces the new data structure, a segmented stack, for implement
ing the paradigms and algorithms developed in chapters 3, 4 and 5. The segmented
stack, together with its operations, is defined. The use o f a segmented stack as a local
stack for executing logic programs is illustrated.
Chapter 8 considers the effects o f non-logical operators on the paradigms intro
duced in chapters 3 ,4 , and 5.
Chapter 9 presents a brief sum m ary of the contributions of the dissertation. The
flow-diagram of the framework which implements the concepts developed in this
dissertation is given. A note for future research concludes the chapter.
Chapter 2
2. Introduction to Logic Programming
2.1. Logic P ro g ram s
Logic programming differs fundamentally from other conventional programming
in that it requires the programmer to describe the logical structure of a problem. The
primitive symbol in logic programs is a proposition (sec section 1.2). A proposition
can have only one of the two values - True or False. Other primitive symbols are the
connectives, viz
a, v,
—i , and
.
A sentence is made o f propositions with connectives
over such propositions. The knowledge that can be represented by a proposition is the
relationship among the propositions. AU queries are answered using logical infer
ences.
A logic program describing a problem consists of sentences, which are proposi
tions, and which are predicates, expressing knowledge relevant to the problem. The
formulation of this knowledge makes use of two basic concepts: the existence of
discrete objects and the existence of relations between them. Objects are terms made
up of constants and variables. The principal constituents of a logic program are
objects, variables, propositions and connectives. Both objects and relations are given
names - this creates symbolic models. Sentences express the relations or logical pro
perties of the names.
A predicate is a predicate name with an n-tuple of arguments. Each of the argu
ments of a proposition is a term. Logic relations are named by predicate symbols and
knowledge is expressed as sentences, formulas, constructed from predicates. A for
mula is defined as follows:
1)
any predicate is a formula
2)
if FI and F2 are formulas, then so are (FI), FI
19
a
F2, FI
v
F2, FI <— F2, and
20
—.F I .
The use o f variables in the arguments of predicates allows the writing o f general
ized sentences. The role of the variables in a sentence is governed by their mode of
quantification (existential or universal).
The set of all sentences constructed with rules 1 - 4 given below constitutes the
language of first order logic.
1)
A term is a constant or a variable or an n-tuple of terms prefixed by a func
tor.
2)
A predicate is a n-tuple o f terms prefixed by a predicate symbol.
3)
A formula is either a predicate or several predicates with connectives, with
a quantifier for the variables appearing in the formula.
4)
A sentence is a formula in which every occurrence o f a variable is within
the scope of the quantifier for that variable.
Consider the following logic program:
1. fatherijohn, bob).
2. fatherCgeorge, john).
3. fatherCgeorge, donald).
4. motherCmary, bob).
5. motherCmary, jenniffer).
6. motherCchristina, donald).
7. V (parent(X, Y) <—mother(X, Y) v father(X, Y))
8. V (sibling(X, Y)
parent(Z, X)
a
parent(Z, Y))
The first six propositions in the logic program are facts. For example, the first
fact, fatheiCjohn, bob), expresses the father relationship between the objects john and
bob. Similarly, the fourth fact, motherCmary, bob), expresses the mother relationship
21
between the objects mary and bob.
The father and mother relationship arc both 2-tuple predicates. H ie proposition
father(john, bob) can represent the information that john is the father o f bob, i.e., the
object which is the first argument is the father o f the object that is the second argu
ment.
The 7th and 8th propositions in the logic program given above are formulas, or
rules. The knowledge represented by the formula V parent(X, Y) <— mother(X, Y) v
fathcr<X, Y) is that,
for all X and Y, X is a parent of Y if X is the mother o f Y or if X is the father of
Y.
This is expressed by the {Repositions which appear on the right hand side of the impli
cation in the rule. Knowledge represented in the statements of logic programs are
used during inferencing newer facts, or theorems.
22
2 2 . Reasoning by Resolution
It is necessary to have a proof procedure that carries out the variety o f processes
involved in reasoning with statements in predicate logic. Resolution is such a pro
cedure. The resolution proof procedure gains its efficiency from the fact that it
operates on statements that have been converted to a very convenient standard form.
The convenient standard form is the clausal form.
A literal is an instance o f a predicate. A clause is a disjunction of literals. The
convenient clausal form is obtained from a general logic program by applying the fol
lowing steps.
1.
Convert all the formulae to conjunctive normal fo rm • for example ((a
v c) is converted to ((a v c)
2.
Converting all implications,
a
a
b)
(b v c)).
, from formulas using the fact that (a <— b) is
equivalent to (—i a v b).
3.
The scope of the negation is reduced to the next literal
(-<a
4.
a
b)) is equivalent to (-i a v
using the fact that
b).
Normalize all quantifiers by moving all quantifiers to the left of theformula.
This formula is said to be in prenex normal form .
3.
Eliminating all existential quantifiers (3) by using assertions, i.e., facts. The
resulting formula is said to be in skolem normal form .
6.
The universal quantifiers are dropped as they are now implicit.
A clause which contains at most one negation is called a Horn clauses. A Prolog pro
gram is a set of Horn clauses.
Resolution produces proofs by refutation. In other words, to prove a statement
resolution attempts to show that the negation of the statement produces a contradic
tion, unsatisfiability, with the known statements. The resolution procedure is a simple
iterative process. At each step two clauses, called the parent clauses, are compared
23
(resolved) yielding a new clause, called the resolvent, that has been inferred from
them.
Given two clauses ( i v b v - i c ) and
c), since either of a or
-1
a is true and (b v
( - 1
- 1
av bv
- 1
c) the resolvent of it is (b v —<
c) is common to both the clauses. If (b v
—» c) is true, giving an interpretation, then both parent clauses are true with this
interpretation.
The resolvent represents ways that the two parent clauses interact with e n.ch
other. If the resolvent is satisfiable then both parent clauses can be satisfiable simul
taneously. An interpretation of a formula is the truth set, i.e., the set of values for the
variables in the formula, which makes the formula true. An interpretation of the resol
vent is an interpretation of the parent clauses. If resolution produces an empty clause,
then the parent clauses cannot be satisfied simultaneously.
When resolution of clauses yields an empty clause, Bf, then there exists a con
tradiction among the clauses. There may not be any contradiction among the clauses
when the proof procedure is complete, in which case the clauses are said to be
satisfiable. That is, when an empty clause is not derivable by the resolution proof pro
cedure, then the clauses are said to be satisfiable. The resolution proof procedure is
exhaustive.
An interpretation which satisfies a set of clauses is said to be its model. Resolu
tion tests for satisfiability for all clauses with all combinations of interpretations avail
able to find a model.
An interpretation over some domain D is said to satisfy a sentence iff (if and
only if) it makes that statement to evaluate as true. It satisfies a set of sentences, S, iff
t
This is similar to a state in which failure occurs in Prolog Hence, the use of identical symbols.
24
it satisfies each sentence in S. S logically implies some sentence s iff for all possible
domains every interpretation which satisfies S also satisfies s.
Sentences are of three types - denials, assertions or implications - o f the form
(“ ■(Al
A j, .. A j ) ,
A, o r ( A
B„
B j,
B j,
respectively. A is the consequent and
( B ,t
, Bn) are antecedants o f the implication.
If propositions are predicates, then we must consider all combination o f values
for variables, i.e., bindings, to complete the proof procedure. The fundamental notion
underlying the reasoning process which explores the logical consequences of the
knowledge is the logical implication.
A substitution is an assignment of a set of terms to variables. A unifying substi
tution when applied to A and B, makes A = B. A most-general-unifier (mgu) is a most
general substitution which makes A » B .
All computational problems can be formulated using only denials, assertions or
implications. All solvable problems can be solved by using general depth-first resolu
tion.
Resolution possesses the soundness and completeness properties That is, every
theorem derivable by S is a valid formula and every valid formula is derivable by S,
respectively. Sentences consisting only of denials, assertions and implications form a
subclass o f the clausal form and are called Horn clauses.
The resolution method is a good tool for testing the consistency of a set of Horn
clauses, i.e., Prolog programs, provided an adequate selection strategy is used. Algo
rithmic properties of a function can be represented in a suitable set of clauses. The
values o f that function can then be obtained by the resolution method.
Negation is implemented as "negation by failure", i.e. the negation of an expres
sion is true if the expression is not true within the framework of the program (closed
world assumption). This means that when the negation of a goal is true, then the goal
25
is false, within the framework o f the program.
The closed world assumption gives partial incompleteness. What this means is
that the resolution proof procedure is accurate within the framework o f the program the assertions and implications supplied in the program.
The proof by refutation procedure uses the proof by negation principle, i.e., if a
set o f sentences is unsatisfiable, then each of the sentences is true. W hen a goal, C , is
tested with a logic program, P, then the clauses P u G i s tested for satisfiability. If the
clauses in P u G are satisfiable then, G is false, because each clause in P is known to
be true. If P u G is unsatisfiable, then G is also true.
If the left hand side of an implication is a single literal, then we can convert this
implication into conjunctive normal form using the rule that (B <—A) is equivalent to
(—i B v A). The proof procedure becomes very simple in this case, because a goal
which is identical to B is unsatisfiable if A is unsatisfiable. In B «—A, B is called the
head and A is called the body of the implication or rule. If the goal G is identical to
the head of the clauses C l, C2,
Cn and the body of each of the clauses are false,
then G is unsatisfiable. A Prolog program applies this principle during query process ing.
Unification and substitution form the basic activities for resolution theorem prov
ing in first order predicate logic. The first activity during the proof procedure is to
identify if the goal G is identical to the head, H, of a clause, C. This is achieved by
unification of G with H.
26
2 3 . Unification
The unification of two expressions can be described as follows
i)
If either expression is a variable occurring in the other, then the the expres
sions do not unify. (Occur check is done for assignments of the type X :=
f(X) unification, which is an unreasonable event)
ii)
If either expression is a variable not occurring in the other, then unification
succeeds and the latter to the former is the unification substitution. (A vari
able ’X ’ unifies with another variable *Y\ The substitution is X/Y. A vari
able *X’ unifies with a constant ’a ’, then X takes a value *a*; the substitution
X «— V or X/a)
iii) If either expression is a constant and the other is either a different constant
or a structured, term then the expressions do not unify. (A constant ’a ’ fails
to unify with a constant ’b ’ or a structured term ’[X a]'.)
iv)
If the expressions are structured terms having different principal functors,
then the expressions do not unify. If the expressions are structured terms
having identical functors, then the expressions unify, if each of the argu
ments unify. If any of the arguments fail to unify then the expressions fail
to unify. All the substitutions which are applied during the unification of
the arguments are recorded by the unification process to give the unification
substitutions between the expressions.
A predicate name is a functor name. The arguments of the predicate are the
arguments of the function. Variables and constants form the n-tuple arguments o f a
predicate functor.
The unification procedure in Prolog is essentially a pattern matching and substi
tution algorithm. The pattern matching proceeds matching the goal pattern G and the
pattern H, which is the head of a clause C, from left to right. If the functors of G and
27
H are not identical, then G fails to unify with H. If the functors of G and H are identi
cal then each argument o f G is unified with the corresponding argument o f H.
Unification fails even if one o f the arguments of G fails to unify with the correspond
ing argument of H. The left to right pattern matching and substitution quits at the first
failure to unify.
Exam ple
H
7 Unity
Substitution
p(X, Y, a).
p(H, y , R).
Yes
X <- P. Y 4 - Q; R <- a
q(X, Y).
q([a, b], c).
Yes
X <- (a, bj; Y <- c
r(Xt Y( Y).
r(a, a, a).
Yes
X <—a; Y <- a
r(X, Y, Y).
r(a, b, c).
Fail
0
s(a, b, c).
s(a, c, d).
Fail
0
71--------------
If G unifies with H, then G is substituted by the body of C, with the unification
substitutions applied to the subgoals in the body of C. G is true if the body of C is
true. An interpretation of the body of C is an interpretation for G. Note that the body
o f C can contain more than one subgoal. Each of these goals is processed in the same
way G was processed.
28
2.4. Procedural Interpretation
There are no factors to determine a precise course of execution of logic pro
grams. The call selection rule is more casually called the computation rule. The stan
dard computation rule always selects, in each step, the first call in the goal-lisL The
selected subgoal is resolved with the clauses. Since the clauses are implications, on
unification with the rule-head, the subgoal is replaced by the rule-body. Then, to
solve the subgoal the rule-body is solved. The standard search rule chooses clause for
unification in the order of appearances in the program tex t
A logic program can be executed as any declarative program. This is done by
considering the goal as a procedure, the procedure name is the predicate name and the
parameters are the arguments o f the predicate. The procedures are defined as the
clauses. The head of a clause is the header of the procedure and the subgoals in the
body of the clause form the body of the procedure. The subgoals in a clause are exe
cuted when a procedure is executed. Note that there can be more than one clause for
any predicate. Each of these clauses uniquely defines one procedure.
A Prolog program is farmed by a set o f instructions that can also be interpreted
as productions of a definite clause grammar. The Prolog language uses resolution as
an elementary execution mechanism. The choice of sequence o f instructions to be
executed in the course of program execution is determined from the text of the pro
gram. Each production is a two level process. When the goal matches with a rulehead, the goal is replaced by the rule-body and then the rule-body is executed instead
o f the goal.
The procedural interpretation [48] views the execution goals as a set of pro
cedure calls. Each one is processed by calling an appropriate procedure. A goal-list
[A ,
A j
is a collection of procedures,
A „ A 2, .., A ,.
The procedure is the name of
the predicate and its arguments are parameters. For any given program, the total com-
29
putadon space is the set of all computations derivable from it using standard pro
cedures calling operations.
The unification procedure draws upon a very important aspect of logic programs.
The unification procedure finds a substitution which makes two literals identical.
Using the procedural interpretation to execute a goal and using unification procedure
to execute a call to the appropriate procedure leads to a property called I/O indirec
tion. This means that the calling statement need not have all its arguments instan
tiated. The calling statement contributes some instantiation to the called procedure
and the unification with the head o f the called procedure and its execution contributes
some instantiation to the calling statem ent
It is understood that when this call becomes replaced by the invoked procedure
body, the textual order of the latter’s calls is not altered. An application of a rule
confines computation to a selected subspace defined by the subspace of the computa
tion o f the subgoals in the rule. The total computation space is the computation tree
whose root is the initial goal and whose paths from that node represent various com
putation. A program is said to be unsolvable when its subspace contains no successful
computation.
The computation o f a goal can be depicted as a goal-search tree. Every node in
the tree represents the execution of a subgoal in the path to solving the goal. The sub
stitutions applied to a node are indicated on the path from the root to the node and the
instantiations generated by the successful execution o f the goal corresponding to a
node is indicated on the branches from the node. The number of branches from a
node equals the number of alternative clauses that are applicable to a goal correspond
ing to a node. Failure of a goal is shown as "F" next to the node. Consider the rule’
and the predicate relation given below. Figure 1 shows pan of the standard goalt
This rule is take from Kundu, [34],
search-tree by Prolog, for this rule, until the first success is encountered. Table I gives
the corresponding trace of execution, using the notations developed in section 4.1.
pO(X, Y)
pI(Y, 2), p2(X), p3(Z), p4<X, Y. U), p5(Z. X. U, W),
p6(V). p7(X, V), p8(Y). p9(X, U, V), plO(Y, U), p i 1(X, Z).
pl(bl, cl).
p l(b l,c l).
pl(b2, c2).
p2(a1).
p2(a2).
p3(cl).
p3(c2),
p4(i2. b l.d l).
p4(a2. b2. dl).
p5(c2, « 2 ,d l,e l).
pS(c2,a2,dl,el).
p6(fl).
p6(f2).
p7(«2, fl).
p7(«2, f2).
p8(b2).
p9(«2,dl,f2).
pl0(b2.dl).
pll(a2.c2).
31
Y/b2; Z/c2
Y/ bl ; Z/cl
Z/C 1
Y/bl
X/q
X/Q
X/a
X/ a
X/a2
X/a
U/d
v/f
plO
pll
Success!!
Figure 1.
Standard Goal-Search-Tree by Prolog
32
goal
tpl(Y,Z), ())
(p2(X), {})
(p3(Z), {Z/cl})
<p4(X,Y.U). (X/al, Y/bl})
(p3CZ). {Z/cl»
<p2(X),{))
(p3(Z). (ZA=H)
tp4(X,Y,U), {X/i2, Y/blJ)
<p5(Z, X, U. W), (Z/cl,X/a2, U /dl))
(p4(X, Y, U), (X/a2, Y /bl))
(p3(Z), (Z/cl))
<p2(X).{))
(plCY.Z).{J)
(p2(X), (})
(p3(Z), (Z/cl))
(p4(X, Y, U), {X/al, Y/bl})
(p3(Z), {Z/cl))
<p2(X), {))
(p3(Z), (Z/cl))
<p4(X.Y.U), (X/a2. Y/bl))
(p5(Z, X. U. W). {Z/c 1.X/a2, U/dl})
(p4CX, Y, U), (X/a2, Y/bl})
(p3(Z), {Z/cl})
(P2CX), {})
(pl(Y, Z), {))
(p2(X), {})
(p3{Z), {Z/c2})
(p4(X, Y, U), {X/al, Y/b2))
(p3(Z), (Z/c2J)
(p2(X), {))
(p3(Z), {Z/c2})
(p4(X. Y, U), {X/a2, Y/b2})
(p5(Z, X, U, W), (Z/c2, X/a2, U/dl ])
(P6CV).{}>
<p7(X, V), {X/a2, V/fl})
(p8(Y). (Y/b2))
(p9(X, U, V). {X/a2,U/dl. V/fl))
(p8(Y), {Y/b2))
(p7(X,V), (X/a2, V /fl})
(p6CV),{))
(p7(X, V), (X/a2, V/f2))
(p8(Y), (Y/b2))
(p9(X. U, V). {X/a2,U/dl, V/T2})
{plO(Y.U), (Y/b2,U/dl})
(pllCX.Z), {X/a2,Z/c2})
success/fail
success
success
success
fail
fail
success
success
success
fail
fail
fail
fail
success
success
success
fail
fail
success
success
success
fail
fail
fail
fail
success
success
success
fail
fail
success
success
fail
success
success
success
success
fail
fail
fail
success
success
success
success
success
success
backtrack literal
-
binding
Y/bl; 7jc\
X/al
-
-
P3
p2
-
X/a2
-
-
U/dl
-
P*
p3
-
Y/bl; Z/cl
X/al
X/a2
U/dl
Y/b2; Z/c2
X/al
X/a2
Wfcl
V/fl
-
-
V/f2
*■
*
Tabic I: Trace of Standard Prolog Execution
P10
-
*
P3
p2
-
P3
pl
P3
P2
P3
*
p8
P7
p6
-
33
2 i . In te rp re te r
The interpreter that executes a logic program has to remember what data has
been assigned so far to the variables. It needs to r emember how the locus of control
evolved to its current state. This is needed to deal with the return operation after
every successful procedure exit and the need to deal with backtracking, since that
operation has to recall previously discovered opportunities still open for exploration.
Program execution accesses two important data areas. The first one contains
some suitable compacted and codified facsimile of the input logic program and is
static. The second area is highly dynamic and is used by the interpreter to record the
history o f its own actions. This is generally in the input heap and the execution stack.
The stack represents both the execution control state and the data state.
The interpreter changes its attention from one control to another, and it traces out
a path called the locus of control. Consider the following rules:
P: A if Plt P2
P4
P„.
Q: B if Qj.Q*
Assume that some of the subgoals in body of P, Ph ..., PM, have been solved. The
subgoal ^ is tried next. If P, matches with B then the procedure Q is executed. After
Q
Q, is solved, control goes back to procedure P to execute Phi- If any Q is
unsolvable, then control goes back to P to try another candidate clause which are
applicable for Pi. (This is shallow backtracking). If there are no untried candidate
clauses applicable for P., then control goes back to P_,. (This is deep backtracking.)
The complete computation space is explored before computation stops.
Exploration of computation is achieved by creating and storing a frame for each
procedure call on a linear stack called the local-stack. The procedure entered and not
exited is called active. The frame is maintained as long as the procedure is active.
34
The frame can contain variable cells to know the variable values. But, the output
assignments of a frame have to be undone on backtracking. If the frames contain cells
for variables, then discarding the frame is enough to achieve backtracking. Havings
cells for variables in a frame leads to excessive use of space, since duplication is ram
pant. One can use another area called the trail which contains the values for the active
variables. A cell with trail pointer is created in every frame. On deleting a frame, all
assignments from the trail-pointer to the top of the trail are undone for effective back
tracking.
A two stack representation has a local-stack and a global-stack. the local-stack
contains the frames of the procedure calls. The global stack contains variables that
are global to the called procedure. A cell for the global frame pointer is every frame.
In order to search the complete computation space, a goal-list is maintained. The
goal-list contains all the goal that have to be solved before the primary goal is
announced as a success or failure. Every procedure call modifies the goal-list and the
local-stack as follows:
1.
H ie first literal in the goal-list is chosen for execution.
2.
A frame is created for this goal and is added to the top o f the activation
stack.
3.
A procedure to solve this goal is selected.
4.
If no procedure is available to solve this goal, then the goal is announced as
a failure and backtracking is invoked.
5.
If the procedure selected to solve the goal is an assertion, i.e., a fact, then
the unification substitution that makes the procedure selectable is applied to
the goal-list.
6.
If the procedure selected to solve the goal is a rule, then the goal-list is the
35
resultant of appending the goal-list with the rule-body.
7.
The above steps are repeated until the goal-list is empty - when a result to
the primary goal is available.
If the stack is empty, then announce failure; else announce success and pro
nounce the substitution applicable to the primary goal as a result of the success.
A push occurs when the goal at the top of the goal-list is selected for execution.
If the goal at the top o f the stack unifies with a program clause, then the resolvent is
added to the head of the goal-list. A pop occurs when there are no program clauses
whose head matches the goal at the top of the stack. The goal at the top o f the stack is
added to the head of the goal-list If the goal-list contains the body o f a program
clause, then this body is removed from the goal-list. The next choice of matching
clause for the new top of stack is investigated. Computation continues in this manner
until the goal-list is empty. This is the state U and success is reported. If the localstack is empty then, the state ■ is reached and failure is reported. Figure 2 illustrates
the execution of a Prolog program on a linear stack for two instances (marked "#")
Figure 1.
The execution of a logic program is carried out by the interpreter. There are
numerous issues pertaining to the implementation of interpreters for logic programs.
These are described briefly in the next section.
30
p9
p8
— r-
P7
— r
p6
ZH
p5
—
1~
p4
~ ~ l~
p3
P2
—r~
Pi
pO
Figure 2. E xecution o f Prolog on a linear stack.
37
2.6. Implementation Issues
Many implementation issues pertaining to implementation of an interpreter for
Prolog have been addressed by researchers. Some of the key issues that are addressed
are the data structures that are to be used and efficient management o f dynamic data
during execution.
Efficient memory management [28, 33] and backtracking [11 - 23] schemes can
be used to avoid unnecessary computations and prudent searches. Last call optimiza
tion is a technique which deletes a frame from the activation stack, once the last call
for a procedure has been activated.
One of the most recent result is based on the locality of reference in the execu
tion o f Prolog programs (the locality being the top of the stack). All but the page
which contains the top o f the stack is kept in the main memory. Hashing, indexing
and special techniques for coding the programs are developed for efficient selection of
clause for executing a goal [28,33].
Warren [29, 31, 32] has developed a stack-based method of executing compiled
Prolog clauses. The method employed by the Warren Abstract Machine (WAM)
eliminates tail-recursion. WAM maintains certain information in registers to effect
speedy selection o f the backtrack literal on the stack, and resetting of the local-stack,
trail and heap.
The significant results pertaining to efficient sequential execution of logic pro
grams are described in the next chapter. These results are based on selective back
tracking for re-exploration of the search space.
Chapter 3
3. Literature Review
3.1. Introduction
Research in the area o f efficient execution of logic programs is exemplified by
the Japanese Fifth Generation Computer Project, started in the 1980’s. Towards this
objective, researchers have been focusing on efficient implementation of logic pro
grams, which would be useful in knowledge processing systems. Prolog has proved to
be a successful programming language. In this chapter we describe in detail the
results obtained by other researchers in their attempts to develop a model to efficiently
execute logic programs.
The basic computational mechanism of Prolog is pattern matching on terms of
logic. The matching expands the computation into a proof tree, until terms are shown
to be true or false. In sequential execution, the proof tree is expanded in a depth-first
manner. The goals o f a clause are executed left to right and the goals of the most
recent clause entry are executed first The unification creates a binding of variables to
terms and other variables, which affects further unification attempts. If, at any time
the system fails to find a match for a goal, it backtracks, rejecting the most recently
activated clauses and undoing any bindings made by the matches with their clause
heads.
An obvious and simple technique in efficient execution of logic programs is
identifying and backtracking to a better backtrack literal when a failure occurs during
execution.
38
39
3.2. Selective B acktracking Baaed on Unification M apping Inform ation
The unification substitution mappings employed during goal search brings in
dependencies among the different goals. Pereira and Porto [11] developed a model to
use this information that is generated at runtime to select a better backtrack literal
when a failure occurs during goal search.
In their model a goal execution is represented as a box with four ports, DO,
DONE, REDO and UNDONE. The DO port o f a goal is entered when the goal is first
activated. The DONE port of a goal is exited on a successful execution of the goal.
On backtracking to a goal, the control re-enters the goal execution box through the
REDO port. Control exits through the UNDONE port of a goal on unsuccessful exe
cution of a goal. Every goal execution box decomposes itself into similar boxes for
the subgoals in a rule on unification of the goal to the bead o f the rule. Figure 3.1
shows the execution model developed by Pereira and Porto.
The main idea of selective backtracking is to select, at each failed goal, a single
goal to backtrack to, not necessarily the previous goal as in standard backtracking in
Prolog. Consequently, entry into the REDO port of G is allowed, only if G has been
selected as the backtrack goal for the last failed goal; otherwise, control flows directly
to the UNDONE port of G.
At the UNDONE port of a goal, in a rule, selection of the backtrack goal takes
place. Deselection of the backtrack goal is done when backtracking to the goal
occurs.
The backtrack goal is selected from among:
Ancestors of G
The goals whose alternative clauses avoid a reactivation of G (essentially
the parent of G)
40
Modifying goals of G
The goals whose match if undone will undo failure (the goals on which G is
dependent)
Legacy set of G
The set of candidate backtrack goals inherited from the failed goals that
selected the backtrack goal
A dependency tag list representation is used to maintain all the dependencies
generated
at runtime,
in a dependency-graph.
After every
unification this
dependency-graph is modified. This graph maintains all the information required to
do optimal backtracking.
The modifying goals of a failing goal, G, is constructed whenever G fails and the
backtracking goal is selected. The overhead incurred in modifying and maintaining
the dependency-graph, with every unification, is rather large and complex. Analyzing
unification failures to construct the modifying goals is also expensive. Figure 3.2
shows the dependency tag representation and the modifying goals for two instances
(marked "#") from Figure 1.
41
DONE
DO
S e le c t
backtrac <
Clause
Head
M atch
UNDONE
D e se le c
Body
Executic n
select'
REDO
Fig u r e 3.1. R e c u r s i u e E x e c u t i o n M o d e l
bi
Y —- 1 —- Z — - c l
2
-X
- al
b2 —- Y
-
1 — Z
c2
2
a2
- X
4 .... u —- dl
5 .... w —- el
6 —- V —- fl
Figure 3 .2 D ep en dency Graph rep resen tation
Figure 3. B acktracking based on U nification inform ation. (Pereira et al.)
42
3.3. R un-tim e Intelligent B acktracking
The selection o f the appropriate backtrack goal without maintaining the
dependency-graph can be done using runtime information [12 - 16]. As execution of
goal search proceeds, a deduction tree is b uilt A naive interpreter always considers
the whole proof tree as a failing tree when a failure occurs. A smaller deduction sub
tree can be identified as the cause of failure. This could lead to pruning of redundant
search space. Cox and Pietrzykowski [12, 13] and Bruynooghee and Matwin [14 - 16]
describe methods to find a minimal deduction subtree in which unification is impossi
ble, i.e., which holds no solution, and maximal deduction subtree in which unification
is possible, Le. could contain solutions.
W henever a goal fails, the whole deduction tree becomes inconsistent. A
minimal failing deduction tree can be constructed by analyzing the variable bindings,
[16]. The clause choice, i.e., the program clause currently applied, to one of the leaf
nodes of one of the minimal failing trees is changed and computation proceeds as
usual. Alternatively, a maximal subtree that is consistent can be constructed by
analyzing the variable bindings, and then a clause choice of one o f the leaf nodes not
in that subtree is changed and computation is continued as usual, [12,13].
Bruynooghee [15] also presents a backtracking scheme in which dependencies of
a goal P are constructed when P is unified with various clause heads. Subsequently, a
scheme to generate and maintain the modifying goals of P is developed in the same
paper.
A lot of information about runtime dependency and bindings has to be main
tained to implement intelligent backtracking. Figures 4.1 and 4.2 show the minimal
and maximal deduction subtrees described by Bruynooghee and Cox, et al., respec
tively.
43
,
Unification substitutions
X /a 2
Y /b l
z /c l
U /d l
at
2
at 1
at 1
at 4
1 and 3 do not
share substitutions
Minimal consistent
deduction subtree
Figure 4.1. Minimal Deduction Subtree th at is consistent, of Brunooghce.
Maximal inconsistent
deduction subtree
On failure o f p5 modify either p i or p3.
Figure 4.2. Maximal Deduction Subtree that is inconsistent, Cox.
44
3.4. Sem i-Intelligent B acktracking Based on Static D ata Dependency Analysis
(SDDA)
In general, there are two kinds of backtracking: shallow backtracking and deep
backtracking. Shallow backtracking is backtracking to alternative candidate clauses,
when the head of the current candidate clause cannot unify with the calling literal.
Deep backtracking occurs when there are no untried candidate clauses for the current
procedure call, so backtracking occurs to any previously invoked procedure.
Dependencies among the subgoals in a rule are used for deep backtracking. A
static-data-dependency-graph which represents the static dependencies of the subgoals
in a rule, can be generated using the textual information about the rule. The SDDA of
a rule is a directed acyclic graph and is independent of the runtime unification substi
tution information. Literals in the SDDA which are equidistant from the root are said
to be in one layer.
Chang and Despain [17, 18] propose a method to select the backtrack literal from
the SDDA, when a failure occurs. They construct an SDDA for each clause at com
pile time. They assume that if two literals do not share any unbound variables, then
they are independent, because the dependence among literals which do not share a
variable (static information) is generated at runtime. They define three types of back
tracking.
Type I
The parent of a literal, in the SDDA of a rule, is chosen as a backtrack
literal when a literal fails during forward execution, i.e., without producing
any solutions.
Type II
The next left brother sibling in the same layer of the SDDA of a rule is
selected as the backtrack literal when a literal fails after producing solutions
45
in its forward execution. What this means is that the literal succeeded, but
its solutions were not accepted by some successor o f the literal in the
SDDA of the rule.
Type HI
Backtracking within a clause defaults to naive backtracking, as in Prolog, if
the clauses succeeded.
The SDDA is used during type I and type n backtracking. Intelligent back
tracking based on the SDDA is local to a procedure (rule). This reduces the
number of redundant steps and its effect is inter-procedural.
Literals in the same layer of an SDDA of a clause (rule) are assumed to be
independent during the forward execution. The literals in a layer may not be
independent if any literal in the next layer has been executed.
The backtracking based on SDDA does not always give the best selection of
a backtrack literal, but avoids excessive runtime overhead. Hence, this method
o f backtracking is called semi-intelligent backtracking. Also, many SDDAs can
be constructed from a given rule. There is no systematic way of identifying the
best SDDA.
Figure 5.1, 5.2, and 5.3 show the use of SDDA for Type I, Type II and Type
HI backtracking, Chang and Despain [17 -18], for two instances (marked "#")
from Figure 1.
Static Data Dependency Graph (SDDA)
4
On failure at 6 backtrack to 0.
5.1. Type I backtracking based on SDDA
47
Backtracking after Forward Execution. On failure at 6 after
failure at 9 backtrack to 4.
5.2. Type 11 b ack track in g based on SDDA
Backtracking after succeeding by a rule.
On failure at 9 backtrack to 8.
5.3.
Type III b ack track in g based on SDDA
F ig u r e 5 .
Semi-Intelligent Backtracking based on SDDA. (Chang et.al.)
48
3.5. Generator-Consumer Approach
The generator-consumer relationship among the literals in a rule is based on
the dependencies that are caused by sharing variables by the literals. This rela
tionship gives information similar to the information obtained by the data-flow
analysis o f the literals in a rule. Conery and Kibler [19 - 23] use the generatorconsumer information in a rule to select a backtrack literal. This scheme incurs
small overhead and yet can eliminate redundant backtracking in many problems.
The generator-consumer relationship can be described as follows. One of
the literals sharing a variable X is considered the generator of X. the other literals
which use the variable X are considered as consumers of X. The generatorconsumer relation can be depicted as a data dependency graph D, which is a
directed graph, in which a literal L is the parent of another literal M, if for some
variable X, M is the generator of X and L is a consumer of X.
Whenever a goal P„ fails the backtrack point is chosen from the set of goals
that have generated the values of the variables X, ... , X, that occur in the argu
ments of
To enable the construction o f this set of goals, some extra informa
tion is maintained with each variable - namely, the generator o f the binding of
the variable. The backtrack goal selection using the generators of the variables
o f the failing goal is not precise, but runtime overhead is small.
Whenever unification of a goal P with some clause head results in assign
ment of a value to a variable, X, a tag P is attached to the variable X, indicating
that the value to the variable X was generated at the goal P. This assignment is
undone when backtracking takes to P, or to the left of P. This tag is unique at
any moment due to the single assignment property of logic programs - there can
be only one assignment to a variable at a time.
When a goal P fails, then the modifying goals of P are the generators of the
49
variables used by P and the parent of P - the goal that unified with the head of the
clause containing P. The B-list with a literal P is the order list o f the modifying
goals of P. Backtracking takes the first element of B -list H u s method leads to
backtracking to any point in the proof tree rather than to the clause containing
the failed goal. This is because the generator/consumer relationship that tran
scends clause boundaries is also maintained. Figure 6 illustrates the use of Blist, by Conery and Kibler, for backtracking for two example from Figure 1.
The scheme developed by Conery and Kibler misses solutions under situa
tions similar to the type n [17 - 18]. This was cured, independendy, by Kumar
[24 - 25] and Woo and Choc [26], independendy.
50
goal
B-list
1
[OJ
2
[01
3
[2]
On failure at 9 backtrack to 6
4
[ 2 ,1 ]
On failure at 6 backtrack to 0
3
[4, 2, 1]
6
[01
7
[6, 2]
8
[I]
9
[6. 4, 2]
10
[4. 11
11
[2 .
1]
Figure 6. B acktracking based on B -list., o f C onery and Kibler.
51
3.6. Modified B-list Approach
The approach by Kumar [24 - 25] and Woo and Choe [26] is as follows.
When a literal Q is selected as the backtrack goal, when a goal P fails, Q
being the most recent goal in modifying(P), Q is also passed the (modifying(P) {Q) >. When Q, fails the latest goal from (modifying(Q) u [modifying(P) {Q ) }) is selected as the backtrack goal. The major difference here is the use of
dynamic B-lists. The backtracking method based on dynamic B-lists is shown to
be complete. Figure 7 illustrates the modified B-list, approach by Vipin Kumar,
for two instances (marked
of Figure 1.
52
goal
B-list
goal
B-list
1
10]
1
10]
2
[0]
2
10]
3
12]
3
12]
4
[2. 1]
4
12. 1]
5
[4. 2, 1]
5
[4. 2. 1]
6
10]
6
14. 2]
7
16. 2]
8
11]
9
16. 4, 2]
Backtrack literal Is the
B-list after backtracking from 9.
elem ent in the B-list with a literal.
Figure 7. B acktracking b ased on dynam ic B -list ,
ofVipin Kumar, et a l
53
3.7. Variable Baaed Intelligent Backtracking
An approach based on variables, rather than the predicates, is presented by
Rajasekhar and Narasimha Murthy [27]. The variables used by the goal is used
for identifying the backtrack literal. These results developed are comparable to
those of Kumar in terms of complexity, but could lead to the elimination of a lot
of redundant backtracking. A tag with every variable is maintained. This tag
indicates where the variable got its binding, its present instantiation. On failure
of a goal, the tags o f the variables used by the goal is examined in order to select
the backtrack literal. The modifying goals are maintained similarly as with
Kum ar's method. This scheme is not very easily implemented on a linear stack.
Figure 8 illustrates the use o f variable tags for backtracking for two
instances (marked "#") of Figure 1.
5'1
1
Y- 1
1
Z- 1
i
X 2
w
Z
-
X
Y
U -4
W-5
V -6
Backtrack based on the variables used by the failing literal.
Figure 8. Variable B ased Backtracking, o f Rajasekhar, e t al.
55
3.8. Warren Abstract Machine
Prolog requires a stack, called the local-stack, to hold frames for each
active procedure. The local-stack contains all the bookkeeping information
together with the value cells for local variables. A frame is reclaimed only on
backtracking.
The Warren Abstract Machine (WAM) [29 - 32] is the most efficient
method for executing Prolog programs by elimination of tail recursion. In
WAM, the local-stack contains only the records o f the goals in the current path
which have pending untried alternatives. A frame is reclaimed when its last
alternative is used up. Maintaining the most recent choice-points in a register
and employing structure sharing rather than structure copying leads to further
efficiency [28].
The code for the clauses reside on a heap and execution unfolds on local,
global and trail stacks. The local-stack contains the variables o f the clause, along
with the environment pointer to manage code and data. The global-stack holds
complex structures and the trail keeps pointers indicating the unification substitu
tions created by the goals. The global-stack bolds complex structures, such as
lists, and the trail keeps pointers to variables which are not local to the current
clause and are assigned during unification, in order to undo their bindings during
backtracking. As each goal is called for unification, an activation record is
created on the local stack for its variables. New structures created by the goal
are placed on the global-stack.
Activations on the local-stack can be deallocated after a goal returns and
has no alternate clauses to try (called success popping) or when backtracking
occurs. Global locations are kept until backtracking occurs. Stack allocation
and deallocation of the stacks eases storage reclamation substantially, reducing
56
runtime storage needs.
On the local-stack, there can be several goals with alternatives yet to be
tried. These goals are called choice-points. When unification fails, the most
recent goal, which is called the choice-point is selected for backtracking. The
last-choice register maintains this choice-point and helps in this selection. Each
activation maintains the last-choice pointer, which is loaded to the register when
this goal is executed. Each activation also maintains a fail point pointing to its
next alternate, yet to be tried. The trail is unwound after backtracking by looking
at the choice-point register, in order to undo some of the unification substitution.
Thus, when a goal fails, the processor need only look at the choice-point
register to find the correct environment to restore. The trail is unwound back to
the beginning of that choice-point goal by popping each address and tagging the
location as undefined. Shallow backtracking needs only transfer of control to the
fail point, but deep backtracking needs to clear the local- and global- stack and
reload stack pointers from the choice-point activation and then transfer control to
the fail point of the choice-point goal.
Figure 9 illustrates the information on the WAM local-stack for two
instances (marked "#") o f Figure 1.
57
The departure from the conventional Prolog execution in WAM is that
instead of passing the information about the caller to the procedure, it is now
given a pointer to the actual goal to be executed next cm backtracking, called the
choice-point. The choice-point points to the most recent ancestor with further
alternatives left to execute.
The execution is efficient in space and time by elimination of unnecessary
activations on the stack and by prior knowledge of alternatives in the form of
choicc-points.
58
p3
pO
Figure 9. L ocal-stack u sed b y WAM, o f Warren,
59
3.9. Discussion
The techniques described in sections 3.1 - 3.6 have significant inherent
drawbacks in effective implementation for savings in sequential implementation
of Prolog. These drawbacks arise due to excessive run-time time and space
requirements for
runtime maintenance of unification substitution information, and
maintenance of dynamic data dependency graph.
Severe difficulties in implementations of these results also arise due to the imple
mentation of Prolog on a linear stack.
The runtime cost is measured in terms of the amount of work done during
execution and the amount of dynamic space that is required. A method is sound
if every solution obtained by the method is valid (correct). A method is com
plete if every solution to a problem (valid or invalid) is obtained by the method.
The following table compares the various results for their time and space com
plexity together with the savings in computation.
60
Authors
Runtime cost
Execution
Linear Stack
Sound/Complete
Pereira & Porto
Prohibitive
No
Yes/Yes
Cox & Piertowzski
Prohibitive
No
Yes/Yes
Bruynooghee & Matwin
Prohibitive
No
Yes/Yes
Conery & Kibler
Pair
No
Yes/No
Vipin Kumar
Fair
No
Yes/Yes
Rajasckar
Linear
No
Yes/Yes
WAM
Best
Yes
Yes/Yes
"
Table II: Comparison of Results in Literature
Parallel execution models and parallel logic programming languages are
being developed for faster execution of logic programs [36 - 54]. Table II com
pares the performance of the existing results in literature. These methods do not
address the central issues for intelligent search, described in section 2.4. This
dissertation addresses these issues, leading to intelligent search; it proposes and
presents efficient implementable algorithms.
Chapter 4
+
4. Intelligent B acktracking Baaed on F ailure Bindings
4.1. Introduction
When a goal fails, the conventional assumption is that the cause o f failure
o f the goal is the set o f all bindings applied in obtaining the goal. In this chapter
the notion of a failure-binding for a literal' is defined. This definition is extended
to predicates. A failure-bin ding for a literal is a precise cause o f failure of the
goal which is obtained from the literal.1 This precise cause is a member of the set
containing the bindings applied to obtain the goal. There can be zero or more
failure-bindings for a literal identified when a goal fails. This depends on the
information content of the logic program.
A method which uses a bit-vector to identify the failure-bindings of a literal
is presented. Intelligent backtracking based on failure-bindings o f the currently
failed literal is presented. The savings in redundant backtracking by intelligent
backtracking based on the failure-bindings o f a literal is illustrated.
The search based on failure-bindings,
is shown to satisfy the complete
ness and soundness properties of Prolog, g also obtains the results of a goal in
the same order as obtained by Prolog. Forward and Backward Execution Algo
rithms for ^ are given.
Consider the example in Figure 1. When the failure o f p5(Z, X, U, W) with
s e e 159].
A literal is an instance of a predicate. The arguments of the predicate arc substituted by terms
made up of constants and w iables to give a literal.
A more general definition of failure binding can be found in [34],
62
the bindings 77c!, X/a2, U /dl is detected, then the backtrack literal selected by
dependency directed backtracking is the latest of the generators of Z, X and U.
This is the generator of U, Le. p4. Hence, dependency directed backtracking
selects p4 as the backtrack literal. On analysis o f the predicate relation of p5, it
can be seen that p5 can never succeed with Z /cl. p5 will never succeed, unless
the binding Z/c 1 is changed.
W e show that such precise individual causes of failure of a goal can be
identified and used effectively for pruning goal search tree. The premise to such
identification is that every failure is due to failure during unification, which is a
pattern matching process, and a failure occurs only after exploring the whole
goal search tree of a goal.
The gain in efficiency derived by employing intelligent backtracking based
on failure-bindings is, however, not without a co st Additional work is required
in identifying and maintaining the causes of failure during the search. The
amount of work done in identifying and maintaining the causes of failure is
overshadowed by the savings derived by their use, as is described in the later sec
tions.
63
4.2. Failure-B inding
When a goal G fails, the causes of failure of G is not known. In fact, the
cause of failure is attributed to die set of bindings applied to obtain G. Intelli
gent backtracking methods described in [5 - 13] perform relevant search. These
methods still suffer in performance due to insufficient information about the
cause of failure o f a goal.
In a logic program a variable can be in either of the three states: Free,
Ground or Partially-instantiated. In a Ground state the variable is instantiated to
a ground value. For example, X/a means X is in the Ground state with a ground
value ’a*. In a Free state the variable is completely uninstantiated. In the
Partially-instantiated state, pan of the variable is in the Ground state and pan of
it is in the Free state. If X/[Y, Z] with Y/b and Z in the Free state indicates, then
X is said to be in the Partially-instantiated state.
64
E xam ple
state
Variable
instantiation
X-
X/a
Ground
X
none
Free
X
X /[Y ,a]
Partially Instantiated
A Prolog literal is an instance of a predicate with many variables that form
its arguments. There are no restrictions on the state o f these variables that form
the arguments o f the goal (i.e., there are no mode restrictions). A consequence of
a mode free program is the VO indirection of Logic Programs. During execu
tion, a set of bindings is applied to a prolog literal to obtain a goal. The success
of a goal may generate zero or more newer bindings to the variables which were
in the Free state at the time o f the call of the goal. A goal fails if there is no solu
tion to the predicate with the bindings applied to obtain the goal. The goal can
never succeed with this set of bindings. A different set of bindings is necessary
to satisfy the predicate.
Definition 4.1.: A prolog goal g for a predicate p is a pair g = (p't a ) where
1. p ' is an instance of p.f
2. a is a set o f instantiations applied to all variables in p'.
Alternately we represent the goal g with the argument tuple of p ' with the substi
tutions from a applied to all the variables in p'.*
t
An instance of p is a literal of p. with its arguments substituted by terms.
5
A Prolog goal g » (p'. a ) is also an instance of the predicate p
N otation suggested by K undu, (331.
65
Definition 4 2 .: Let g be a prolog goal, g « (p \ a ). The Variable-set of g, denoted
v B, is the set of all the Free variables in g. The Constant-set of g, denoted C, is
the set of all the constants in g.1
Exam ple
argument tuple
predicate
goal
p(argl, arg2, arg3, arg4).
(p(X, Y ,d ,Z ), (X/aJ)
p(a, Y, d, Z).
q(argl, arg2, arg3).
(q(P,Q , R), (R/[a, b]))
q(P, Q, [a, b]).
r(argl, arg2).
(r(a, b), {))
r(a, b).
s(argl, arg2, arg3).
<s(P, Q, d), (})
s(P, Q, d).
representation
Exam ple
instance ot
Vanable-set
(Jonstant-set
predicate
of instance
of instance
pCa, Y, d, Z)
lY .Z j
(a, d]
q(P, Q, R)
{P. Q .R}
{)
rfa, b)
(}
(a ,b )
s(P, Q, d)
(P .Q )
Id}
The successful execution of a goal g generates a set of new instantiations for the
variables in Vg. Due to the single assignment rule, a successful execution of a goal
can assign values only to variables whose instantiations are not defined in a . We
1
g uniquely defines Vf and Cg.
66
denote this set of newer instantiations generated when g succeeds by &, or simply A.
A can possibly be empty. When g fails, A is necessarily empty.
A goal g - (p \ a ) fails if every alternative applicable to the predicate p, of which
p ' is an instance, fails to solve p". p" fails if
1) g fails to unify with any fact of p,
2)
g fails to unify with the rule-heads of some rules for p, and
3) every rule for p, p
pjj, p ^ ,.., pM , 1 £ j £ k, which is applicable to g (there
are k rules applicable to p") fails to solve g.
The classical assumption is that the cause of failure of p ', which gave g, is a,
since p ' will always fail with this particular combination of bindings in a . The fol
lowing definition is used for identifying precise cause of failure for p'.
Definition 4.3.: If the goal p" * (p', {X/v}) fails, then X/v is a failure-binding for
p'. Similarly, if p" ■ (p', {)) with the constant-set of p ' Cr- - {c) is false, then c is
a failure binding for p'.
It can be observed from the definition of a failure-binding of p ' that if X/v is a
failure-binding for p', then any goal g' obtained by applying X/v to p' and any other
values for other variables in Vp. is also false. In general there can be more than one
failure-binding fo rp '.
The failure-bindings for p ' are identified by combining the causes of failure for p'
from the failure of a general goal g = (p', a ) by each alternative of p.
When a goal g = (p', a ) fails, the causes of failure for p ' with respect to each of
the alternatives are identified. The cause of failure for p* by an alternative is obtained
from the facts:*
*
Pemonal com m unication, Kundu (33).
67
Fact 1:
A binding X/v e a is a cause of failure for p ' due to a fact of p if v fails to
unify for X in the fac t
Fact 2:
A constant c e O’ is a cause o f failure for p ' due to a fact of p if c fails to
unify in the fact.
Fact 3:
A binding X/v € a is a cause of failure for p ' due to an alternative o f p
which is a rule if
a) v fails to unify for X in the rule-head of the rule or
b) part of v is a failure-binding o f some subgoal in the rule-body of the
rule. The unified version o f the rule, r”, obtained after g unifies with
the rule head of the rule r
r : p :* p i, p2, p 3 ,.... pm.
is
r p , p "* p i i p2 ,
J i
_ M
_ «
,
_ i » i
_ A « i
pm .
_ _ « i
X/v € a is a cause of failure for p ' by the rule r if there exists some
X '/v', v ' is a pan of v, obtained via unification o f g to the rule-head of
the rule, and X '/v' is a failure-binding of some subgoal pj" in the rule.
Fact 4:
A binding (c e Cp ) is a cause of failure for p' due to an alternative of p
which is a rule if
a) c fails to unify in the rule-head of the rule or
b) part of c is a failure-binding o f some subgoal in the rule-body of the
rule. The unified version o f the rule, r", obtained after g unifies with
the rule head of the rule r
r :p
p i, p2, p3
pm.
68
is
r p ,p
_ * l
_ * t1
•" p i *pZ * <ti pm *
,
_ *
M
- O
"
n
1 ^ 1 11
c is a cause of failure for p ' by the rule r if there exists some c', which
is a part o f c, obtained via unification of g to the rule-head of the rule
c ' is a failure-binding of some subgoal pj" in the rule.
Fact 5:
If there are no rules or facts of p, then every
memberof a and every
member o f Cy is a cause of failure for p'.
A failure binding for p ' can be obtained from the complete goal-search-tree of gf
= (p \ a ), which is known when the failure of g is detected.
(1) If the goal-tree of g is o f height zero, i.e., there are no facts or rules of p,
then every X/v e a and every c e
is a failure-binding for p'. (Fact 5)
(2) If the goal-search-tree of g is of height one, i.e., there are only facts of p but
no rules, then a binding X/v
e
a (or a constant c € Cp.) is a failure-binding
for p ' if X/v (c) is a cause of failure for p ' with all the facts o f p, by Fact 1
(Fact 2).
(3) If the goal-tree of g has height 2 2, i.e., there are facts and rules of p, a bind
ing X/v
(a)
e
a (c e Cy) is a failure-binding for p ' iff
X/v (c) is a cause of failure for p', according to Fact 1 (Fact 2) with
respect to each o f the facts of p and
(b)
X/v (c) is a cause of failure for p', according to Fact 3with respect to
each rule of p, by Fact 3 (Fact 4).
Exam ple
t
Wc only consider goai-trees which *re finilc, i.e., there is no infinite branch.
*
IW i definition la my rewording of note* from Knndu [33).
69
For the goal p" - (p(X, b, Z), (X /al, Z/c2}) with no facts and rules for p the
failure-bindings for p{X, b, Z) are b, X /al and Z/c2.
Exam ple
Consider that the predicate q is defined only by the facts given below*
Facts ot q
q(a2, b2, c l, d3).
q(a3,b2, c 2 ,d l).
q(a2, b3, c3, d2).
The failure-bindings for diffierent instances of q according to (2) above is shown
in Figure 10.
goal
taiiure-bindings
reason
(q(P, Q, R, d l), (P/a2, Q /b l})
Q /bl
b l fails to unify for Q
(q (a l,S , T, d l), (t/c 2 J)
al
al fails to unify
(q (al, Y, 2, W), [ Y /bl, Z /c3J)
a l; Y/bl
a l fails to unify
b l fails to unify for Y
(q(X, Y, Z, d l), [X/a2, Z/c3J)
none
no common cause o f failure
Figure 10. Identification of Failure-Bindings when a predicate is defined by facts.
Consider the goal (q(P, Q, R, d l), {Q /b l}) in Figure 10. The value bl fails to
unify, for Q, in each of the facts for q. Hence, Q /bl is a failure-binding for q(P, Q,
d l). Consider another goal (q(al, S, T, d l), (T/c2J). The value a l fails to unify in
each of the facts for p. Hence, al is a failure-binding in q (al, S, T, d l). Two failure-
t
From discussions with Kundu, [331.
70
bindings for q (al, Y, Z, W) can be identified when the goal (q(al, Y, Z, W), (Y /bl,
Z/c3}) fails, because a l does not unify in each o f the facts for p and b l does not unify
for Y in each o f the facts for p. No failure-bindings for q(X, Y, Z, d l) can be
identified when the goal (q(X, Y, Z, d l), {X/a2, Z/c3}) fails, because none of a2, c3,
or d l fails to unify in each of the facts for p.
71
Exam ple
Figure 11. shows the identification of failure-binding for r(X, Y) using the facts
and rules of r.f
Consider the following facts and rules for the predicate r and the goal r" = (r(X,
Y), {X/al, Y /bl}).
1 .r(a l,b 2 ) .------------------------------2. r l l<al ).
3. rl2(b2).
4. r21(al, c l).
5. r22(cl, b2).
6. r(X, Y) :-rll(X ),rl2 (Y ).
7. r(X, Y)
alternative
r21 (X, Z), i22(Z, Y).
cause ot failure
o f r(X, Y)
1
Y /bl
6
Y/bl
7
Y /bl
Figure 11. Failure-binding in the presence of facts and rules.
The facts of r, listed above, suggest that Y /bl is a failure-binding for r(X, Y).
The first rule of r fails to solve r(a l, b l), because pl2(Y ) fails and Y /bl is a failure
binding o f rl2(Y ). This suggests that Y /bl is a failure-binding for r(X, Y). The
second rule proceeds with the computation of r21(X, Z), which succeeds with a solu
tion Z /cl. The goal r22(Z, Y) fails and Y /bl is a failure-binding for r22(Z, Y). The
t
This example was given by Kiindu, [33].
72
suggestion that Y /bl is a failure binding in r(X, Y) still holds. There are no more
alternatives for r. H ius, the suggestion that Y /bl is a failure-binding for r(X , Y) is
substantiated by all the facts and rules of r. Note that Y /bl is still the failure-binding
for r(X, Y), even if the fact p21(al, c l) is removed.1 In general, removal of any fact or
rule cannot eliminate or invalidate any failure-bindings in that if X/v is a failurebinding in g then on removing any fact or rule it will still be true that X/v is a failurebinding in p". Alternatively, the addition of a fact or a rule can easily eliminate or
invalidate a failure-binding for g.
It is interestion to note that a failure-binding which is identified by analyzing the
goal-tree of a goal, g - (p', a ), is applicable to any other goal, g ' « (p', o'). What this
means is that every goal which is obtained from p \ by applying a failure-binding for
p', will fail. If the arguments of an instance are either variables or constants, but no
generalized terms, then a failure-binding for p ' is applicable for any instance of the
predicate p, i.e. any goal g" - (p’\ a ") will fail if either Cy or a ', or both, contain one
or more failure-bindings for any instance p ' of p. The substitution of these failurebindings in p" should correspond to those in p'.
T heorem 4.1.: If X/v € a (c e Cy)) is a cause of failure for p \ obtained by
analyzing the goal-tree of g * (p \ a ) which fails, due to every alternative, then
X/v (c) is a failure-binding for p'.*
Proof. By definition, if there are no alternatives for p, then every X/v e a and
every c e Cy is a failure-binding for p'. If X/v (c) is a cause of failure for p ' by
each alternative, then either v failed to unify for X (c failed to unify) in each of
t
Developed in conjunction with Kundu, [33].
%
A more general definition of failure-binding, and its use, is considered by Kundu [33 - 34}.
73
the facts of p, and in some rule-heads of p, or part of v (c) is a failure-binding of
some subgoal in every rule that is applicable to g. Effectively, this says that X/v
(c) individually would cause failure of g with each alternative o f p. This will
then be true if a contained only X/v (Cy contained only c). Hence, every alterna
tive o f p will fail a goal p" = (p', (X /v)) (p" - (p', {)), Cy * {c}), leading to
failure o f p". Thus X/v (c) is a failure-binding for p'.
T heorem 4.2.: If X/v e a (c e Cy) is a failure-binding for p', then X'/v e a ', or
v e C y, (c € C y, or X'/c
e
a ) is a failure-binding for p* if X', or v, in p"
corresponds to X in p ' (c, or X', in p" corresponds to c) in p'.
Proof: Since X/v is a failure-binding for p ' we can say that v (c) fails to unify for
X in the facts of p and in some rule-heads of the rules o f p and either v (c) or
parts of v (c) are failure-bindings of some subgoal in each of the the rules o f p.
The same facts and rules are applicable for p". Since X', or v, in pMcorresponds
to X in p ' (c, or X', in p" corresponds to c) in pO the same cause of failures for p'
are applicable to p". Hence, X/v (c) is a failure-binding for p”.
The definition of a failure-binding can be generalized for the case of a compound
goal containing several ANDed goals (such as a rule body). In this case, we say that a
binding X/v (constant c) is a failure-binding for the compound goal if it is a failurebinding for at least one of the literals in the compound goal.1
Consider the facts and rules of r in Figure 11, without the fact r21(al, c l). There
are two failure-bindings for the compound goal "p21(X, Z), p22(Z, Y)", namely, X/al
(from p21(X, Z)) and Y /bl (from p22(Z, Y)).
S
Persona] communications, Kundu [33 • 34],
74
The definition of a failure-binding for a literal can also be generalized from the
case o f a single binding of X/v, to the case o f a case of a set of bindings (X ,/v„ X /v 2,
.... X ./V .),
a set o f constants (c„ c* ... O * or a set o f bindings and constants, which
together cause a failure of the literal. W e call such a composite set o f bindings that
makes the literal false a composite failure-binding for the literal.* The conventional
assumption that when a goal g = (p', a ) fails, the cause of failure is a u C^-. This
gives us a composite failure-binding.
E xam ple
In Figure 10, we have (X/a3, Z/c3) as a composite failure-binding for q ' = q(X,
Y, Z, W ), because the goal (q(X, Y, Z, d l), (X/a3, Z/c3)) fails.*
The advantage of using the composite failure-bindings is that these may be
encountered more often than the single variable failure-bindings. Put in another way,
the composite failure-binding is a weaker notion than the single variable failurebinding. The generalization from singular failure-bindings to composite failurebindings is straightforward. The problem, however, is that the composite failurebindings can be numerous. Their identification and maintenance is much more com
plex and expensive than identification o f singleton failure-bindings.
t
Personal communications, Kundu [33 - 34],
t
Personal communications, Kundu [33 - 34j.
75
4.3. F ailure Binding Table
There is a failure binding table FBT(p) for each predicate p. H ie tuples of
FBT(p) represent a failure-binding applicable to p. Every tuple of FBT(p) represents
one failure-binding applicable to p. The tuples of FBT(p) are obtained as follows.*
1.
Let X/v (c) be a failure-binding for p'.
2.
We obtain p“ from p ' by substituting every constant in Cy by a dummy vari
able # (obtain p“ from p ' by substituting every constant in Cy, other than c,
by a dummy variable #). The dummy variable # always unifies.
3.
The argument tuple o f (p“, (X /v)) (the argument tuple o f (p“, ())) is added
to FBT(p).
E xam ple The entries to the FBT(q) from Figure 10 is shown below.
FBT(q)
"IT T
p
bl
al
S
T
al
Y
Z
#
bl
z
#
w
w
Entries to FBT from Figure 10.
If a predicate p has only facts then FBT(p) can be computed by knowing the
domain o f the program. The entries in FBT(p) could then be numerous.
t
Notation and concept of FBT developed in conjunction with Kundu, [33]. The use of subsump
tion to keep the size of FBT small is due to Kundu, [33,34]. Kundu, [34], uses
instead of
76
If there are rules of p, then no part of FBT(p) can be computed at compile time
because no negative facts are allowed in Prolog. FBT(p) is initialized to be the empty
table.
All entries to FBT(p) are generated during execution.* As the execution
proceeds, more and more failure-bindings for the various predicates are identified and
they in turn are used to optimize the subsequent search process. The FBT(p) is void
when the program is modified (externally or using the Prolog assert clause).
If s = sl(S|, a ,..... i*) and t ■ tl(i„ tj
O are two argument tuples, then s is said
to subsume (i.e., be more general than) t if s unifies with t with the substitutions going
from s to t, i.e., substitutions are made in s to make s identical to t.f
Exam ple
The tuple s - (al, bl, Z) subsumes the tuple t - (al, b l , c l) , because by substitut
ing Z /cl, s can be made identical to t. However, s does not subsume the tuple q = (X,
b l, cl).
The tuples in each FBT(p) are maintained as maximal (most general) in the sense
that tuple t is added to FBT(p) only if it is not subsumed by an existing tuple in
FBT(p). Furthermore, when a tuple t is added to FBT(p), all the existing tuples s e
FBT(p) which are subsumed by t are deleted.
$
Personal communications, Kundu [33],
t
This subsianption definition corresponds to conventional definition of subsumption in database
theory and other related fields of computer science.
77
Exam ple
The maximal tuples in FBT(q) from Figure 10 are shown in Figure 12.
al
#
" 5 " "5"
bl
z
nr
w
Figure 12.2.: Maximal tuples in FBT
78
4 .4 . Forward Execution Based on Fallure-Bindings
Forward execution is modified when there are failure-bindings for a literal which
is used to obtain the current goal. The forward execution algorithm based on failurebindings is given in Algorithm A l.
The failure-bindings of a literal are used for intelligent backtracking based on the
generator-consumer approach. The generators and consumers of a variable in a rule
dynamically change. The next section describes the maintenance of the generators
and consumers in a rule in detail.
79
Phase I:
Let g = (p't a ) be a new current goal.
If (goal-list = em pty)
then
Report Success.
Apply Algorithm B 1 (see section 4.6)
elseif (g is subsumed by FBT(p)) or (no more alternatives o f p)
then
Report failure /* g fails */
Apply Algorithm B 1 (see section 4.6)
else
Phase D:
Let i be the next alternative for p.
If (no more alternative of p)
then
Report failure /* g fails */
Apply Algorithm B l
If (alternative i is a fact and if g unifies with i)
then
Apply Algorithm A 1 at Phase I
elseif (alternative i is a rule)
then
if (g fails to unify with the rule-head of i)
then
80
Apply Algorithm A l at Phase II
else
let i" be the body o f the unified version of rule i.
if (the a subgoal q*' in i” is subsumed by a tuple in FBT(q))
then
Apply Algorithm A l at Phase II
else
Apply Algorithm A l at Phase I
A lgorithm A I: F o rw ard Execution A lgorithm based on Failure-bindings.
4.5. Generators and Consumers
Consider a rule r, The head of r is denoted head(r) and its body is denoted
body(r). The generator-consumer list (in short, the gc-list) of a variable X in r is
defined as the ordered list of subgoals in body(r) which contain the variable X in
their arguments.1 The gc-list of a variable X in rule r is denoted gc(r, X). It is
assumed that no rule in the program has alternate paths.1 If c is a constant in
body(r), then we let gc(r, c) = head(r). This is done to indicate the fact that the
presence of c is due to the rule itself.
An instance o f a predicate may appear more than once in r. Hence, a con
venient way to represent gc(r, X) is by a list o f the indices of the subgoals in
body(r), where the subgoals are successively assigned the indices 1, 2, ... ,in
left-right order ’ The indices imply the order of literals in the rule. The index 0
goes to head(r) and for a constant c, the assignment gc(r, c) = [0] is done to indi
cate that c in r is explicit. The gc-lists for a rule r are easily determined by a sin
gle left to right scan of the rule-body. An application t ' of a rule r is obtained
from the set of unification substitutions applied to head(r), when a goal, g, unifies
with head(r). The gc-lists of the variables in the unified form r' of r can be con
structed from the gc-lists for r as follows.
1.
Let (X, 4— e,} denote the unification mappings from g to head(r). X,
This section on generators and consumers is largely taken from Kundu, [33 - 34], with adaptation
to atomic constants and variables.
For example the rule-body
gl. g2, (g3; g4), g5." has two alternate paths, namely "gl. g2, g3,
g5." and "gl,g2, g4,g5.".
The index i 2 0 refers to a subgoal or the head of rule r which has the index i.
82
occurs in head(r) and t, is an expression made up of constants and vari
ables, Yj’s, in g,
2.
For each variable construct
e(Xi) - {Xk | Xfc occurs in head(r) and body(r) and 3 Y, which
appears in e* and in e*}.
3.
Construct the gc-list o f the variables in / from e(X') as follows:
gcfr', XO = ( u gc-list(r, X j | Xk e e(X,))
4.
The gc-lists of r* are ordered appropriately with duplicate occurrences
of indices, if any, removed.
Note that e(Xj * 0 if x* is substituted by a constant in r'. Consequently, gc(r',
x j = [0]. If c is a constant in bodyfr'), then we let gc(r', c) - [0]. A simpler notation,
gc(X), for gc(r, X), is used when the rule application is understood.
Example
Consider the rule r, from Figure 1.:
r : pO(X, Y ) :-
pl(Y , Z). p2(X), p3(Z), p4(X, Y. U), p5(Z, W). p6(V),
p7(X, V), p8(Y), p9(X, U, V), pl(XY, U). pi 1(X, Z).
The gc-lists of r axe
gc(r, X) = [2, 4 ,7 , 9, 11 ]
gc(r, U) = [4, 9, 10]
gc(r, Y) = [1, 4, 8, 10]
gc(r, V) = [6, 7,9]
gc(r, Z) = [1, 3 ,5 , 11]
gc(r, W) = [5]
Now, consider an application r' of r obtained by the unification of the goal g =
(pO(X\ X '), O ) to the head(r). The unification mapping from g to r is given by
{ X < - X ',Y 4 - X '} .
83
e(X) - (X, Y) and e(Y) - {X, Y)
Therefore, the gc-lists of r ' are
& ( /, X) « gc(r, X) u gc(r, Y) - [ 1 .2 ,4 ,7 , 8 ,9 , 10, 11]
gcCr', Y) - gc(r, X) u gc(r, Y) - [ 1 ,2 ,4 ,7 ,8 ,9 ,1 0 .1 1 ]
For the (dummy) variables Z, U, V, and W which appear only in the body of rule
r (and hence only in the body of r0. their gc-lists remain unaltered, e.g., gc(r, Z) =
gc(r/, Z).
Consider r", which is an application of r for the goal gH■ (pO(X”, Y”), {Y/yO}).
The unification mappings are
{X «—X, Y «—yOJ.
e (X )« (XJ and e(Y) - 0 .
Therefore, the gc-lists of r" are
gc(r", X )* g c (r, X)
gc(r’\ Y) ** [0]
The other gc-lists remain the same as before.
The gc-lists of r"" which is an application of r for the goal
(p(X""t Y""), {X""/[x0, yO]))
are
gc(r"H, X) = [0]
gc(r’"’, Y) = gc(r, Y).
The gc-lists give an abstract representation of the rule r in that these lists are not
affected by certain changes in permutations and composition of the arguments of a
literal in r. For example, if the literal p4(X, Y, U) in the above example were replaced
by p4(Y, X, U), or by any other literal which uses the variables X, Y and U, the gclists would remain unchanged.
84
The importance of the gc-lists comes from the fact that they contain all the
relevant information about the structure o f the rule r for determining intelligent back
tracking operations as explained in subsequent sections (and forward jumping, as
explained in chapter 7).
A state of computation, 0, in a Prolog execution corresponds to a node in the
goal-seaich tree, or more precisely, the path from the root to that node. The path
describes the sequence of successive rule-applicadons and their associated unification
substitutions. Thus, the state of computation gives the current goal, the active set of
variables and their instantiations. If the same rule r is used more than once along a
path, then they are distinguished by their order of occurrence in the path.
The notion of a generator for a variable X in a particular application r' of rule r
and in a computation state 6, the path from die root to a node in the goal-search-tree,
is defined as follows:
I
Let the subgoals j £ 1 in r' be the subgoal that is being investigated in the
state 6. The subgoals 1 £ i < j in r ' have been satisfied in states prior to 6.
n
If, for some i, 1 £ i < j and i £ g c(r\ X), X is assigned a value in course of
satisfying the subgoal i in r', then i is called the generator of X for r' in the
state 0 and we write gen(r', 0, X) * i*
The subgoals m £ gc(r", X) and m > gen(r', 6, X) are called the consumers of X
§
The assignments of die form X «—c, where c is a constant value (atomic or structured constant)
indicates that X is assigned a value. The discussion for the assignments of the form X «- e can
be easily extended to the case when e is a general expression. The expression e could contain
new variables which were not in r'. Hence, newer gc-lists appear and compulation proceeds
described.
as
85
denoted by confr', 8, X). If c is a constant in body(rO, then gentr', 8, c) - 0 and con(i/
, 0, c) = 0 for all applicable states 0 in r'.
In general, only some of the variables o f r ' will have their generators defined in a
state 0. A simple method for updating the values of gen(r\ X) as the search for the
successive subgoals of r ' is continued is as follows.
1.
Initially, for each variable X and constant in body(O gen(r', X) = 0.
2.
When a subgoal i of r ' succeeds, we let genCr', X) - i for each variable X,
which is assigned a constant value by i.
3.
If i is the gen(r', X), then this is not modified unless backtracking goes to a
subgoal j £ i.
Simpler notations like gen(X) or gen(r', X) for gen(r', 0, X) and con(X) or con(r',
X) for con(r', 0, X) can be used when an application o f a rule and the state o f compu
tation is understood.
Example:
Consider an application r ' of the rule r, shown in Figure 1, for an application of a
goal g = (pO(X', Y'),{Y7y0}).
r*: pO(X, y O ) p l ( y 0 , Z), p2(X), p3(Z), p4(X, yO, U), P5(Z, W), p6(V),
P?(X, V), P8(y0), p9(X, U, V), P 10(y0, U), p i 1(X, Z).
The gc-lists of f arc
g c(r\ X) = gc(r, X)
gc(r', Y) = [0],
The gc-lists of other variables appearing only in body(r') remain the same as the
gc-lists of the rule r, as in the earlier example. The generators of all the variables and
constants in r ' are set to 0.
86
Consider the computation state 6 where the first eight subgoals in b o d y (0 have
succeeded and the computation o f the subgoal p9(X, U, V) is not yet complete. More
specifically, assume that the state 0 was reached as follows:
1.
The subgoal pl(yO, Z) succeeded, without generating a value for Z.
2.
p2(X) succeeded, with an output assignment X/xO, modifying gen(X) = 2.
3.
p3(Z) has succeeded, generating Z /zl and modifying gen(Z) = 3.
4.
p4(x0, yO, U) succeeded, generating U/uO and modifying gen(U) = 4.
5.
p 5 (z l, W) succeeded, without assigning a value to W.
6.
p6(V) succeeded, generating V/vO and modifying gen(V) *= 6
7.
p7(x0, vO) succeeded, without any output assignments.
8.
p8(y0) succeeded, without any output assignments.
The search for the subgoal p9(x0, uO, vO) is assumed to be incomplete. Here, j =
9. The associated generators and consumers for r' in the state 0 are given by
gen(X)
=
2
con(X)
= [4 ,7 .9 . 11]
gen(yO)
-0
con(y0)
=
gen(Z)
* 3
con(Z)
- [ 5 ,1 1 ]
gen(U)
=4
con(U)
-1 9 , 10]
gen(V)
=
6
con(V)
= [7. 10]
gen(W)
= undefined
con(W)
= undefined.
0
87
4.6. Backward Execution Based on Failure-binding
When a subgoal f reports failure in state 6 during execution then backtracking is
applied. A previous state, 8 ', in which a goal b is executed, is selected for backtrack
ing. Any subgoal £ (f-1) may be selected for backtracking. Forward execution is
started in the state b and is executed.
The intelligent backtracking schemes described in chapter 3 are based on identi
fying the most recently generated binding that could cure the failure of a goal g, when
g fails without any solution. However, a better backtrack point can be selected if the
failure-bindings of literal f that failed in the state 8, are known. It is shown that the
earliest o f the generators o f the failure-bindings can be selected as the backtrack
literal/ This is based on the observation that every failure-binding of f has to be
rectified before f can succeed.
t
The selection of backtrack literal was developed in conjunction with Dr. Kundu. 133. 34]
88
Example
Consider a goal g = ((q(X, Y, Z, d l), {X/al, Y /bl, Z/c3)) that fails with the
failuie-bindings X /al and Y/bl for q(X, Y, Z, d l). Also assume that gen(X) = 3,
gen(Y) * 1 and gen(Z) - 4. Dependency directed backtracking will select the latest of
the generators whose solutions were applied to g. Hence the backtrack literal selected
would be 4.
However, since both X /al and Y /bl have to be rectified to solve g we have to
redo literals 3 and 1. Hence, the backtrack literal selection that is based on failurebindings would select 1 as the backtrack literal. This literal is the closer to the root of
the goal-tree than those selected by other methods.
B ackw ard Execution Algorithm
If the argument tuple of a goal g * (p \ a ) is subsumed by any tuple in FBT(p),
then g will fail because a failure-binding is applied to p ' to obtain g. The tuples that
subsume g give failure-bindings of p'. This is because every tuple in FBT corresponds
to one failure-binding of the predicate. Algorithm B 1 gives the Backward Execution
algorithm based on failure-bindings.
Example
Consider the goal g = (q(X, Y, Z, d l), (X /al, Y /a l}). This gives the argument
tuple of g as q (al, b l, Z, d l). Let the tuples si = q (al, S, T, #), s2 = q(X, b l, Z, W) in
FBT(q) subsume p (al, b l, Z, d l). The tuple si represents X/al as a failure-binding of
p and the tuple s2 represents Y/a2 as a failure-binding of p. Hence, X /al and Y/a2 are
identified as the failure-bindings for q(X, Y, Z, dl).
89
Let g = (p \ a ) be the cunent goal that failed.
If (g is subsumed by FBT(p))
then
identify the failure bindings o f p' from FBT(p).
else f* g is not subsumed by FBT(p) */
Identify failure-bindings for p ' from the alternatives of p
Update FBT(p) for every failure-binding in p"
If (there are no failure-bindings in p H)
then
Backtrack literal is selected according to Kumar
else f* there are failure-bindings of p” */
if (c e Cp is a failure-binding for pO
then
backtrack literal = 0
else
backtrack literal * min{gen(X) | X/v is failure-binding for
p'J
Backtrack
Update bit-vector if backtrack literal « 0 (See section 5.7)
Continue Forward Execution.
Algorithm B l: Backward Execution Algorithm Based on Fallure-Bindings.
90
4.7. Bit-vector Implementation to Identify Failure Bindings
The following discussion for identifying the failure-bindings is limited to Prolog
program with only two modes for the arguments o f the predicates, the Ground state
and the Free state. In essence, it is limited to programs without structured terms,
though structured constants arc allowed. Structured terms lead to nested structures,
and the unification process and identification o f cause of failure becomes dependent
on this process.
Failure-binding can be identified in a fairly straight forward manner as Prolog
backtracks from a failure o f a subgoal to its parent (** the head of the rule which gave
rise to the subgoal), by simply translating die failure-binding (if any) o f the subgoals
in the rule as causes of failure for the goal using the unification substitution mapping
in the reverse direction, and by combining the latter with the current tentative failurebindings at the parent
The failure-bindings o f all the predicates can be identified by analyzing the pro
gram. This is not always necessary. The objective is to prune computation during
execution. In other words, the objective is to explore the search space efficiently
while being relevant to the query. Hence, it would be ideal to identify the failurebindings, if any, during the computation, without incurring excessive runtime over
head. An important observation to be kept in mind is that a goal fails only after an
attempt to explore the entire search space of the predicate of which the goal is an
instance.
For every goal executed, the failure-bindings can be identified by identifying the
causes o f failure by each of the alternatives from Facts 1, 2, 3, 4 and 5. (see section
4.2)
Consider a goal g = (p't a ). The failure-bindings for p ' are identified as follows.
1.
A bit-vector is maintained with g. The length of this bit-vector is | Cp- u a |,
i.e., there is a bit for every constant in p ' and every binding in a .
2.
Every bit in this bit-vector is initialized to ’ 1*. Thus each member o f C u a
is a potential failure-bindings for p'.
3.
The causes o f failure for p ' by every alternative of p are identified. The
suggestion o f failure-bindings for p ' is maintained incrementally, i.e., the
common causes of failure for p ' by all the alternatives that have been tried
so far are suggested as potential failure-bindings for p', when the alternative
m is tried.
For each alternative, the bit corresponding to a binding X/v (c) in the bit-
vector with g is ANDed with ’ 1’ if X /v (c) is a cause of failure for p ' due to the
alternative. Otherwise, the bit is ANDed with a ’0*.
4.
The common causes of failure for p ' after exhaustion of all the alternatives
of p are identified as the failure-bindings for p'.
The final bit-vector with g, after exhausting all the alternatives of p, is used
to identify the failure-bindings for p \ if any. There is a one-to-one correspon
dence between every bit in the bit-vector of g and the elements ofC^ u a
Every
bit which is ’ 1’ in the final bit-vector with p" gives the corresponding element in
C u a a s a failure-binding in p". This is obtained from the bits which are ’1* in
the bit-vector after all the alternatives are exhausted.
The unification algorithm, which is essentially a pattern matching algorithm in
Prolog, quits after the first mismatch. This pattern matching algorithm is modified to
identify all the mismatches over the whole argument tuple of the goal g. Each
mismatch then gives one cause of failure of g.
It is to be noted that the extension of the unification algorithm to scan the whole
argument tuple of the goal does not hurt the complexity of the unification process, but
92
can potentially perform more than the standard unification algorithm. In the bargain,
more causes o f failures of p ' arc identified.
Exam ple
Consider the bit-vector modification with unification with facts.
g = t(al, b l, c l).
facts
causes of failure
bit-vector
before unification
t(a2, b l, c2).
a l; c l
[1 ,1 ,1 ]
[1 ,0 ,1 ]
t(a2, b2, c4).
a l; b l; c l
[1 ,0 ,1 ]
[1 ,0 ,1 ]
t(a2, b3. c l).
a l; bl
[1 ,0 ,1 ]
[1 ,0 ,0 ]
Figure 13. Unification with facts and Bit-vector manipulation
Figure 13 illustrates the identification of the causes of failure of g obtained by
unification and the refinement o f the bit-vector with g.
During backtracking from a subgoal j in a rule, r, if the selected backtrack literal
is 0, then the failure-bindings of j together with the unification mapping applied to the
subgoal 0, head(r), in the reverse direction is used to identify the causes of failure of
the goal by the rule.
Example:
Consider the goal g - (p(X, Y, Z), {X/[al, a2], Y /[bl, b2], ZJ[c l, c2]}) and the
rules
p(X, Y, Z ) p i IOC). pl2(Y ), pl3(Z).
P([P. S], [Q, T |, rR, U])
p(M, N, O)
p21(P, S), P22(Q, T), p23(R, U), p24(S, T, U).
p31(M, N), p32(N, O), p33(0, M).
The causes of failure of g by the rules and the corresponding modification to the bitvector with g are shown in Figure 14.
bit-vector
failure-binding
before rule execution
subgoals in rule
[1 .1 . 1J
—X /[al, a2] f o rp ll(X )
[1 ,0 ,0 ]
S/al for p24(S, T, U)
[1 ,0 , 0]
M /[al, a2] for p33(OpM)
Figure 14. Bit-vector manipulation with application of rules
Example
Consider the goal (query(X. Y), IX /al, Y /b l)) and the following program. The
identification of the failure-bindings o f query(X, Y) by the facts and rules of the pro
gram is shown in Figure 15.
q l(a l).
q2(b2).
q2(b3).
q3(al, c l).
q3(a2, c l).
q 4 (cl, b2).
query(al, b2).
query(X, Y) ql(X ),q2(Y ),
query(X, Y ) q 3 ( X . Z), q4(Z. Y).
94
initial tut vector resultant bit vector
applicable fact or rule
auerWaT UV
11.1]
query(X, Y ) q l ( x ) , q2(Y).
to .il
1 o rn
ql(al).
[0]
ID
all facts and rules indicate
[1]
dl
failure due lo to Y/bl.
(Intelligent backtracking takes
so coal beinc tried.)
query (a 1, bl).
query(X, Y):- q3(A, Z), q4(Z, V).
10.1]
[0,1]
[0,0]
q3(al,cl).
q3(al, Z).
[1.0]
q4<cl, bl).
all alternatives fail
ro, ij
[1.1]
for q4 indicating Y/bl as the
the cause of failure.
(Intelligent backtracking
takes us the coal beinc tried)
[0, 1]
auery(al. bl).
no more alternatives
[0.1]
Figure IS. Identification of Failure-binding in the presence of facts and rules.
coal
queryfal, bl).
query(al. bl).
ql(*l)
q2(bl).
In Figure IS computation starts with a search for a solution of to the goal
query(al, bl) with the initialized bit-veccor [1, 1]. The first fact indicates that Y/bl is
a cause of failure for query(al. bl), modifying the bit-vector [0,1]. On application of
the next rule q l(a l) succeeds and q2(bl) foils. The failure of q2(bl) identifies Y/bl as
a failure-binding far q2(Y). This eliminates all computation within the first rule appli
cable to the query, Le., ql(X) is not tried any more, and backtracking goes to the ini
tial goal, the query<al, bl). using the gc-list of Y. The bit-vector at the que^rtal, bl)
is modified to [0,1). The next applicable rule translates itself into q3(al, Z) and q4(Z,
bl). q3(al. Z) aucceeds with a banding Z/cl. q4<cl, bl) fails, identifying Y/bl,
during unification a> the rale-head, as a failure-binding for q4(Z, Y). This
suggests Y/bl as a cause of failure for qneryfal, b l) by this rule. The bit-vector of
query(al, bl) is modified [0,1]. There are no more alternatives for query(al, bl), so
the final bit-vector {0,1), which indicates Y/bl as a failure-binding for queryOX, Y).
95
4.8. Incompleteness o f the Identification of Fallure-Blndlngs
An interesting point to be noted here is that if we focus our attention only on the
part o f the goal-tree for the goal g which is visited by Prolog, then we may miss iden
tifying some failure bindings. The identification o f failure-bindings by Prolog, using
the bit-vector implementation, is not complete, i.e., every failure-binding o f a goal is
not identified when the goal fails. The reasons for the incompleteness are two fold.
They are
1.
Left to right control of execution o f subgoals in a rule. This is due to
incomplete gathering of information about the causes o f failure for the goal
by the applicable rules for the goal. The failure o f a subgoal may invalidate
the application o f a rule. Subsequent subgoals are not tried. The subse
quent subgoals may indicate additional causes of failure for the goal.
2.
Even with an extended unification algorithm, some failure-bindings can be
missed by the bit-vector implementation algorithm. This happens if the
unification fails and does not identify any cause o f failure. This is illustrated
in Figure 16.*
The following is true using the Prolog control structure. Every alternative can
indicate many bindings as causes of failure by the alternative. As a rule body is exe
cuted left-to-right, all the failure-bindings o f all the failing subgoals in the rule may
not identified. The first subgoal that fails and leads to backtracking to the parent, i.e.,
head o f the rule, leads to preventing further execution of the body of the role. This
results in incomplete information about the causes of failure by the role, because the
failure-bindings o f the subgoals that are not executed may identify causes of failure of
t
The failure of unification without identifying a cause of failure was singularly pointed out by
Kundu. [33]
96
the goal by the alternative. Since, no assumption can be made about the causes of
failure of the goal by the alternative, only the identified causes o f failure are used to
identify failure-bindings.
What this means is that if we compute the failure-bindings only cm the basis of
the searches performed by Prolog, then certain failure-bindings may be missed,
though no erroneous failure-bindings will be reported. This will partially reduce the
effectiveness o f the new backtracking method, in that it will be reduced more often
than necessary to ordinary intelligent backtracking.
Bits in the bit-vector are ANDed with ’1* only if the corresponding binding, or
constant, is a cause of failure. Otherwise they are ANDed with 'O’. The incomplete
information by an application of a rule could result in the improper ANDing of ’O' to
some o f the potential causes of failure. This could result in not identifying possible
failure-bindings, as shown in Figure 16.
Example
In Figure 11 we cannot identify Y/bl as the failure-binding for r22(Z, Y) if the
fact r21(al, c l) is removed. The first fact for r identifies Y /bl as the cause of failure
for r(X, Y). The first rule for r identifies Y /bl as a cause of failure of r ”. The left-toright processing of subgoals in a rule-body of the second rule by Prolog causes r21(X,
Z) to fail, reporting X /al to be the failure-binding for r21(X, Z), which in turn
translates to X /al a cause of failure for rfX, Y). This is not supported by the first fact
or the first rule for r. The goal r22(Z, Y) is never tried, and hence Y /bl which is a
failure binding for r22(Z, Y) is never identified, to identify Y /bl as a a cause of failure
for r(X, Y). The second rule does not support Y /bl as a cause of failure of r". One
then erroneously concludes that r(X, Y, Z) does not have a failure-binding.
97
Example
Consider the goal (query(X, Y), (X/a2, Y /bl}) and the program in Figure 15.
Figure 16 shows the incompleteness of the identification of failure-bindings.
applicable fact or rule
initial bit vector resultant bit vector
queryf u , bl).
[1. 11
querycx, Y) ql(X), q2(Y).
U.O]
n . ij
X/a2 is failure-binding for ql(X)
[1]
i ll
backtrack to query(a2. b l)
query(a2. bl).
10. OJ
query(X, Y ):- q3(X, Z), q4(Z, Y).
[I* 0]
q3(a2, Z).
q3(al,cl).
[0.0]
[1.0]
q4(cl, bl).
Y/bl is failure-binding for q4(Z, Y)
[0.1]
[1.1]
backtrack to auery(a2. bl)
[0 . 1]
query(a2, bl).
[0.0]
no more alternatives
_& 0]
Figure 16. Incompleteness of Identification of Failure-bindings by rales.
goal
query(a2, bl).
query(a2, bl).
ql(a2).
Figure 16 shows the bit-vector method to identify the failure-bindings of
(queiyCX, Y), (X/a2, Y/bl J). Computation of the goal queiy(al. bl) proceeds as fol
lows:
1. The first fact modifies the bit-vector to be (1.1]
i
2. The first rale is applied, and ql(a2) is tried first ql(a2) fails and indicates
X/a2 as a failure-binding far ql(X). The first rule application fails, the goal
q2(bl) is not executed. The bit corresponding to Y/bl in the bit-vector with
the query<a2, bl) is ANDed with *0', because Y/bl is not identified as a
cause of failure by the first rale. The resulting bit-vector with the goal is [ 1,
0] (the bit corresponding to X/a2 is ANDed with '1').
3.
The next applicable rale translates itself into q3(a2. Z) and q4{Z, bl). q3(X,
Z) succeeds generating the binding Z/cl. q4(cl, bl) fails and identifies
Y/bl as a failure binding for q4(Z, Y). This modifies the bit-vector with the
query(a2, bl) to [0. 0], ANDing the bit corresponding to Y/bl with *1* and
the others with '0 ’s.
98
4.
There are no more alternatives applicable to the query. The query(a2, b l)
fails and no failure-binding for query(X, Y) is identified.
According to Theorem 4.2 and Figure IS, Y /bl is a failure-binding for queryfX,
Y). The information that Y /bl is a cause of failure of query(a2, b l) is not substan
tiated by the first rule during the execution, because the subgoal q2(Y) was not exe
cuted when the subgoal q l(X ) fails. Hence, the incompleteness prevails in the
identification of failure-bindings.
Exam ple
The incompleteness of identification of failure-binding is also due to unification
failure without identifying any cause of failure. Consider the goal (p(X, Y, Y), (X/a,
Y/b}). Figure 17 shows the unification with the facts for p.
tacts
initial bit-vector
hnai bit-vector
p (al, b l, b2).
U, 1J
[1.1]
p(a, b l, b2).
[1.1]
[0,1]
p (al, b, b).
[0,1]
[0,0]
Figure 17. Incompleteness o f identification of failure-binding by unification.
Consider that the goal (p(X, Y, Y), (X/a, Y/b}) as defined only by the facts in
Figure 17. The unification process and the subsequent bit-vector does not identify any
failure-binding for p(X, Y, Y). It is easy to observe that the goal (p(X, Y, Y), (X, Y },
{}, (X /a)) fails and, as per the Definition 1, X/a is a failure-binding of p(X, Y, Y).
The unification algorithm identifies mismatches as causes o f failure. In the
above example, the failure in unification in the different facts are due to different
bindings. The failure-binding in the goal (p(X, Y, Y), {X/a}) is due to the interaction
o f X and Y in different facts. The unification algorithm is oblivious to such situations.
99
Exam ple
The following example illustrates recursive intelligent backtracking based on
failure-bindings across clauses.
query(X, Y) q l(X . Y). q2(Yt Z). q3(Xt Z).
ql(X , Y ) .....
q2(Y, Z ) ....
q3(X, Y) q31 (X, Z), q32(Z, Y), q33(X. Y).
q31(X, Y ) ....
q32(X, Y ) ....
q33(X, Y) q331(X, Z), q332(Y, Z). q333(X, Y).
q331(X, Y ) : - ....
q332(X, Y) ....
q333(X, Y) q3331(X, Y). q3332(X, Y).
Suppose, the goal (queryCX, Y), {X, Y}, {}, {X /al}) is tried. Also, assume that
the literals, obtained after unification and substitution, q l, q2, q3, q31, q32, q33, q331,
q332, q333, q3331, q3332 have succeeded and the literal q333 fails with X /al as a
failure-binding. Also, assume that the literals q333, q33 and q3 have exhausted their
alternatives. Then, gen(X) in the rules "q33(..)
and ”query(..)
...." , ”q33(..)
..." , "q3(..>
....”
..." would be 0. Hence, backtracking is recursively applied from
q333 to q33 to q3 to query, since q333, q33 and q3 have exhausted their alternatives.
Applying the techniques used in WAM, it is easy to implement intelligent backtrack
ing based on failure-bindings and can backtrack across clauses.
Figure 18. shows the complete goal search tree explored by intelligent backtrack
ing based on failure-bindings, for the example in Figure 1. Table m gives the trace of
execution by intelligent backtracking based on failure-bindings for the example in
Figure 1.
100
Y/b1
X/o
x/q
fb - X /al
EZl
<E>
F
lb - Z /c l
| Z /cl
X/a
X/a 2
X /o 1
u/q
F
lb - Z /cl
V/fl
lb * fall urc-bln ding
lb - V/fl
Figure 18*
Goal-tree by Intelligent Backtracking based on failure-bindings
101
goal
(pl(Y , Z ) , {))
(p2CX), {))
<p3(Z), {Z/cl})
(p4(X, Y, U), {X/al, Y /bl))
(p2(X), {])
(p3(Z). {Z/cl})
(p4(X. Y, U), (X/h2t Y/bl))
(p5(Z, X.U.W ). (Z/cl, X/a2, U/dl))
(pl(Y.Z), ())
(p2(X), {})
(p3(Z), {Z/cl})
(p4(X, Y. U), {X/al, Y/bl})
(P2(X), {})
(p3(Z), {Z/cl})
(p4(X, Y, U), (X/a2,Y/bl))
(p5(Z, X.U .W ). (Z/cl.X/a2.U/dl})
(PKY.Z), ())
(p2(X). [})
(p3(Z), {Z/c2})
(p4(X, Y.U), (X/al, Y/b2))
(P2(X). ())
(p3(Z), (Z/c2)>
(p4(X, Y.U), {X/a2,Y/b2})
(p5(Z, X. U. W). Z/c2. X/a2, U /dl})
(P6(V). {))
(p7(X, V), (X/a2, V/fl))
(p8(Y). {Y/b2})
(p9(X, U, V). {X/a2, U/d 1. v / n })
(P6(V),{))
(p7(X. V). (X/a2, V/f2))
(p8(Y). (Y/b2J)
(p9(X, U. V), {X/a2. U/dl. V/C})
(plOCY.U), {Y/b2,U/dl})
(pll(X ,Z ), (X/a2,Z/c2))
t
success/fail
success
success
success
fail
success
success
success
fail
success
success
success
fail
success
success
success
fail
success
success
success
fail
success
success
success
success
success
success
success
fail
success
success
success
success
success
success
failure-binding
binding
Y/bl: Z/cl
backtrack literal
-
-
X/al
-
-
-
-
-
X/h2
-
U/dl
Y/bl; Z/cl
X/al
-
X/al
Z/cl
pi
-
-
p2
•
-
-
-
-
-
-
X/al
p2
-
-
X/a2
-
-
-
U/dl
-
-
Z/cl
Pi
-
YA>2; Z/c2
X/al
-
X/a2
-
U/dl
W/el
V/fl
-
-
-
-
X/al (t)
P2
-
-
-
-
-
-
-
•
-
-
-
-
-
-
-
-
-
V/T2
V/fl
p6
-
-
-
-
-
-
-
-
-
-
-
-
“
Table Ql: Trace of Execution by Intelligent Backtracking baaed on failure-bindings
Identified from FBT(p4) search.
102
T heorem 4.3.: H ie computation of a failure-binding by the bit-vector implemen
tation method is sound.
Proof. On failure o f a goal by an alternative, a bit in its bit-vector is ANDed with
a ’ 1*, if the binding, or constant, corresponding to the bit is identified as a cause
o f failure by the alternative. The alternative will not satisfy any goal with this
cause of failure in the argument of the goal. Thus, a bit in the bit-vector is *1 ’ if
and only if the binding corresponding to the bit has been identified as a cause of
failure by every alternative that has been tried so far. Consequently, if a bit is ’ 1’
after exhausting each of the alternatives then the binding corresponding to the bit
has been a cause o f failure by all alternatives, and, hence, is a failure-binding. A
binding or a constant is identified as a failure-binding, iff the binding or the con
stant is identified as a cause of failure by each alternative.
If a binding, or constant, is not identified as a cause of failure by an alterna
tive, then the bit corresponding to the binding (constant) is ANDed with a ’O'.
Consequently, if a bit is ’0 ’ after exhausting all the alternatives, then the binding
corresponding to the bit is not a cause of failure for each of the alternatives, and,
hence, is not identified as a failure-binding for the goal.
Due to the fact that ’ 1’ AND *0’ « *0’ once a bit is ANDed with a ’O’, it
remains *0’. Thus, the binding corresponding to this bit is not identified as a
failure-binding. Hence, the identification of failure-binding by the bit-vector
implementation is sound.
103
4.9. Soundness and Completeness o f c
In this section we prove that the search based on failure-bindings,
is sound,
complete and that it preserves the order o f the solutions obtained by Prolog.
A method is sound if every answer that is derived by a method is a valid (correct)
one. A method is complete if the method derives every solution. No solution, valid or
invalid, should go underived.
The basic execution mechanism is the same as in Prolog, Intelligent backtracking
is a special case o f backtracking based on failure-bindings of the current literal.
T heorem 4.4.: The algorithm for selection of backtrack literal is optimal.
Proof: If there are no failure-bindings for the failed literal, then common
dependency-directed backtracking is applied, according to [17 - 27]. If there are
failure-bindings for the failed literal then the earliest o f the generators of the
failure-bindings is selected as the backtrack literal. Every failure-binding is a
definite cause of failure for the literal, which needs to be rectified. If a literal
which is not the earliest of the generators of the failure-bindings for the failed
literal is selected as the backtrack literal then the computation would arrive, after
backtracking and forward execution, at the failed literal with at least one of its
unrectified failure-binding. Hence, this literal will fail again. This will occur
until all the failure-bindings o f the failed literal are corrected, called late detec
tion of failure. Hence, backtracking to any other literal which is not the earliest
o f the generators of failure-bindings for a failed literal would not be of any
consequence to the failed literal. Thus, the selection of the earliest o f the genera
tors of the failure-bindings of the failed as the backtrack literal is most efficient
and hence optimal.
104
T heorem 4 i . : <; is sound.
Proof: A solution to a goal is reported if the goal unifies with a fact, in which
case the goal is true, or if all the subgoals in a rule applicable to the goal are true,
implying that the goal is true. No other solution o f a goal is reported. Hence <; is
sound.
T heorem 4.6.: ; is complete.
Proof. The search defaults to ordinary dependency-directed backtracking when
there are no failure-bindings of a goal. Intelligent backtracking is applied when
there are failure-bindings for the current literal that failed. Backtracking to an
intermediate literal, b, is equivalent to jumping to b in the goal-search-tree which
generated a failure-binding. Resuming computation at b continues search in the
next right subtree at b, discarding the subtree of b which uses a failure binding of
the currently failed literal. This subtree does not contain any solution to the ini
tial query. Hence, discarding further search in this subtree does not miss any
solution.
Since the identification of failure-bindings is sound, and since the selection
of a backtrack literal based on failure-bindings is correct, no subtree which could
possibly contain a solution is pruned. Thus no solution that could be derived by
Prolog is missed. Hence, <; is complete, within the closed world assumption.
T heorem 4.7.: The order of solution derived by <; is the same as those obtained
by Prolog.
Proof. The proof is trivial for naive backtracking, as in standard Prolog, and
dependency-directed backtracking. The control mechanism is identical to that by
Prolog and £ is sound and complete. Hence, <; preserves the order of the results.
C hapters
5. Intelligent Forward Execution Based on Failure-Solutions
5.1. Introduction
The notion o f a failure-solution of a goal is introduced in this chapter. A simple
method to identify the failure-solutions of a goal is presented. A systematic method to
associate the failure-solutions of a goal in a a failure solution table (FST) is illustrated.
Intelligent forward execution is based on the failure-solutions of a goal. 'Hie savings
in computation by intelligent forward execution is compared to the standard search by
Prolog. The completeness and soundness properties o f the search method based on
failure-solutions,
is proved. It is also proved that <? preserves the order of solutions
obtained by Prolog
Exhaustive and thorough search of the goal-tree by Prolog has a shortcoming in
that computations of the same successes and same failures can be repeated. One of
the reason why standard, dependency-directed or intelligent backtracking may not be
able to cure a failure is that the backtrack literal can have many repeated identical
solutions which could result in repeated failures.
Consider the execution of the body of a rule
...., p(X, Y)
q(X, Y ) , T h e
bindings generated by p(X, Y) must satisfy q(X, Y). Let us assume that a solution, A,
of p(X, Y) does not satisfy q(X, Y). This also means that A fails to satisfy the goal
that unified with the rule-head of the rule in which p(X, Y) and q(X, Y) appear,
because the rule-application will not succeed with the solution A of p(X, Y). If A' is
another solution of p(X, Y) and A' = A, or if A' is weaker than A (A subsumes A ')/
t
The weakness property based on subsumption definition was developed in conjunction with Rundu, [33], Kundu also suggested maintaining a table of successes for each predicate p (similar to
FBT(p)>. This can be used to avoid search success-tree of a subgoal if it had been executed be-
105
106
then the rule application will fail again. However, the computation encountered in an
intelligent forward execution from p(X, Y) onwards with A' can be safely avoided.
fore, perhaps in a diffeitnl rule, than the current rule.
107
5.2. Failure-Solutions
Semantically, a goal g * (p't a ) is true (that is, satisfiable, or logically follows
from the program) if and only if there is a clause instance I of o f a clause C, in the
program, such that the head of I is identical to p" and all the goals in the body of 1 are
true. By the procedural interpretation of a logic program, a goal g is true if and only if
a)
there is a fact F that unifies with p" or
b)
there is a rule H ;- B l, B 2 ,... Bn. such that p" unifies with H and B l, B 2 ,...
, Bn are true.
The subgoals in a rule are executed left-to-right. The bindings that are applica
ble at a node in the goal-tree of g are the solutions of all the subgoals which are above
it in the goal-tree of g.
Prolog execution has two phases.
1)
During forward execution, goals are unified with facts or rule-heads. The
goal is true when it unifies with a fact. When the goal unifies with a rule
head, the goal is replaced by the unified version of the rule-body. The goal
is true when all the subgoals in this rule-body are true. The subgoals are
executed left-to-righL Alternatives that are applicable to a goal are selected
top-to-bottom from the textual description of the program.
2)
When a goal fails, a backtrack literal is selected by the backward execution
algorithm and execution at this literal starts again for additional solutions.
Let g be the primary goal. Along the path to the solution of g many subgoals are
tried. Let n = (q', P) be a subgoal in the current path to a solution to g. Let n be exe
cuted in the state o. The successful computation of n gives a set of newer bindings, A,
as its solution. The state of computation is modified from a to o '. A can possibly be
empty; and n may fail in the state o, in which case A is necessarily empty. Note that
the computation of n in the state o, can have other solutions, i.e., A '’s with A' = A or
108
A' * A.
The computation o f n in the state a is denoted by
The goal-tree of g is
denoted A*. The subtree o f A* which is below the computation o f the subgoal ^
is
denoted A*^
Definition 1: Hie solution „nAis a failure-solution of n for g if there is no solu
tion for g in the subtree Aj^.
Exam ple
Refer to In Figure 1 there is no solution for pO(X, Y) in the subtree under pl(Y ,
Z) with the solution (Y /bl; Z /c l). Hence, {Y/bl, Z /c l} is a failure solution of pl(Y ,
Z).
Forward execution will fail to find any solution o f g if a new solution, A', of
subgoal n is identical or weaker than a previously detected failure-solution. A, of n for
g. It is then proper to skip the redundant search represented by the search space
a^
.
A different solution of n is required for solving g.
Exam ple
In Figure 1, on backtracking to pl(Y , Z) a new solution {Y/bl, Z /c l} is obtained.
This solution is identical to an earlier solution which failed to produce a solution for
pO(X, Y). Obviously, this solution will fail during forward execution, as can be
observed from the goal-search tree that has been explored earlier.
109
S 3 . F ailure Solution T able
Definition 2 : A Failure Solution Table (FST) o f q" - (q', a ) which is executed in
the state o and which is denoted FST(q”, a ), is a table containing the failuresolutions o f q" in the state o. Every tuple in the FST(q", a ) is the set of argu
ment tuples of the goal (q", a vj A), where A is a failure-solution of q" in the
state o.
The operations that are required to maintain the FST(q", o ) are:
1.
create(FST(q", o » - creates an empty table
2.
flnd(FST(q", a ), A) - finds if A is identical or subsumed by a tuple in
FST(q", o)
3.
add(FST(q", o), A) - adds the argument tuple (q', a u A) to FST(q", a )
4.
destroy(FST(q", <y)) - deletes FST(q", o).
An FST is associated with every node in the current path in the goal-tree of g, the
primary goal. As newer subgoals are invoked, their FST’s are created. FST 's are ini
tialized empty at the first call to a subgoal. When a subgoal exhausts its solutions or
backtracking takes to a node above the subgoal in the goal-search-tree, the FST of the
subgoal is destroyed. When a subgoal is selected as the backtrack literal by the back
tracking algorithm .then the subgoal may a d d a tuple to its FST. if the latest solution
o f the subgoal is a failure-solution. When a solution A to a subgoal q*' is obtained, the
FST(q”, o) is searched to find, if the tuple (q', a u A) is subsumed by the existing
tuples in FST(q", a ). The entries in FST(q", o ) are not applicable for q" executed in
another state & # o. Therefore, on backtracking to the left of q ” the FST(q", a ) is
made void (destroyed).
110
5.4. Intelligent Forward Execution Baaed on Fallure-Solution
FST(q", o) is used in intelligent forward execution from q". When q" succeeds
with a solution A, then find(FST(q", <j), A) is done to find if A is a previously
identified failure-solution. If A is identical or weaker than any tuple in FST(q", o),
then forward execution from q" is aborted and a new solution for q” is requested. Oth
erwise, forward execution continues as usual.
If the argument tuple of the goal (q', a u A), is subsumed by any existing tuple
in FST(q", a ) then forward execution from q” is aborted and q" is further executed to
find more solutions of q". A flag is maintained with every goal that is active. This
flag is initialized to False when the goal is first invoked. Algorithm A2 gives the for
ward execution algorithm based on failure-solutions.
lil
Let q" - (q', a ) be the current goal, executed in state cr.
Phase 1
FST(q", o) = 0 ;
flag(q". o ) * false;
Phase 2:
solved = exec(q"); /* exec is a function to execute a goal */
if (solved = tru e)
then
found = find(FST(q", o), A); /* A is the new solution of q" */
if (found = true)
then
Apply Algorithm A2 at Phase 2 to q".
Else
next-goal = fetches(goaMist) f* fetches a goal from goal-list */
If (next-goal = 0 ) f* goal-list is empty */
then
report success
flag(q", a) * true;
Apply Algorithm A2 at Phase 2 to q".
else
Apply Algorithm B2 at Phase 1 to next-goal.
else
Apply Algorithm B2 toq".
Algorithm A2: Forward Execution Algorithm based on Failure-Solutions.
112
5 i . B ackw ard Execution Baaed on Failure-Solutlon
On backtracking to q" from r", the flag with r" is returned to q". The value of the
flag returned identifies the failure-solution of the q". If no solution for the primary
goal g is found in the interim of forward execution from q" and backtracking to q",
then an addition corresponding to A is done to FST(q”, o). H ie absence or presence
o f a solution of g with the present solution of q", A, is determined by the flag returned
by the backtracking algorithm. If the flag returned to q” is True, then the flag(q", o ) is
set to true. If the flag returned to q" is False then A is a failure solution of q" and the
tuple corresponding to q" is added to FST(q", a). On backtracking from q", to b"» the
flag(q", c ) is returned, to b". Algorithm B2 gives the backward execution algorithm
based on Failure Solutions.
Let q" be the current goal that failed.
Let b” - (b \ o ') be the selected backtrack literal.
if (flag(q", a ) = False)
then
FST(b”, o ') - add(FST(b", o '), A') /* A' is the previous soln. of bH*/
else
flag(bH, o ') =■T rue;
Backtrack to b”;
Apply Algorithm A2 at Phase 2 to b".
A lgorithm B2: B ackw ard Execution A lgorithm based on Failure-Solutions
Data structures optimal for searching and insertion are ideal for maintaining
FST’s. Data structures such as AVL-trees or B-trees are quite efficient for add and
find operations.
113
The go&l-tree for the execution of the example of Figure 1 by intelligent forward
execution is shown in Figure 19. The trace o f execution based on use o f FST is given
in Table IV.
1 14
failure-solution
Y/bl.
Z/cl
Ibl.rll
V/b2, Z/c2
W /r fl
Search pruned by u se of FST
Success!!
Figure 19. Goal-search tree explored by Intelligent Forward Execution
115
goal
(pl(Y, 2). {})
tp2(X), {))
<p3(Z), {Z/cl})
(p4(X, Y ,U ).{X /slt Y /bl])
(p3(Z), (Z/cl))
(P2(X).{J)
(p3(Z), (Z/cl))
(p4(X, Y,U), {Xfr2,Y/bl})
(p5(z, x . u . w ). tsyci. x a 2, u / a i })
<p4(X,Y,U), {X/a2,Y/bl})
(p3(Z), (Z/cl))
(P2(X), ())
<pl(Y,Z). ())
<pl(Y,Z), (})
<p2(X), 0 )
<p3(Z), (Z/c2J)
(p4(X, Y,U), {X/al.Y/b2})
(p3(Z), (Z/c2))
(p2(X), ())
(p3(Z). (Z/c2|)
(p4(X, Y, U), (X/a2,Y/b2)>
(p5(Z. X, U. W). (Z/c2, X/a2, U /dl))
<p6(V). ())
(p7(X, V), (X/a2, V /fl))
<p8(Y). (Y/b2))
(p9(X, U, V), {X/b2, U/dl, VA1})
(p8(Y), (Y/b2J)
(p?(X, V), (X/a2, V /fl))
< P6(V ). { ))
(p7(X.V), (X/a2, V/f2))
<p8(Y). (Y/b2}>
(p9(X, U, V), {X/i2.U/dl.V/f2})
(plOCY.U).(Y/b2.U/dl))
(pllfX .Z ), (X/a2, Z/c2)>
success/fail
success
fail
fail
success
success
success
fail
faU
fail
fail
f U f f f jd
success
success
success
fail
fail
success
s u c c e ss
fail
success
success
success
fail
fail
fail
success
success
success
success
success
success
binding
Y/bl; Z/cl
Xyfcl
-
X/a2
-
e
-
-
U/dl
-
-
-
*
-
Y/bl; Z/cl
Y/b2; Z/c2
X /il
-
X/a2
-
W/el
V/fl
-
V/12
*
FST 77
-
yes
-
backtrack literal
-
p3
p2
-
P*
p3
-
Pi
-
p3
p2
-
p3
-
p8
P?
p6
-
;
*
Table IV: Trace of Execution by Intelligent Forward Execution
“
116
5.6. Soundness and Completeness of
It is proved that the search based on failurr-solutions,
shown that
is sound. It is also
preserves the order o f solutions obtained by Prolog
T heorem 5.1.:
is sound.
Proof. A solution to a goal g is reported if g unifies with a fact o r if all the
subgoals in a rule applicable to g is true. Hence.
Theorem 5.2.:
is sound.
is complete.
P ro of If a solution A of a subgoal, n, executed in state a , is subsumed by a in
FST(n. o). then forward execution from n is avoided. This indicates that A is
identical to or weaker than a previously determined failure-solution of n. It can
then safely be said that the subtree A*,, does not have a solution for g. Hence,
pruning the search of subtree A^ does not mis any solution. The search o f a sub
tree of the goal-tice g is pruned, by aborting forward execution, if and only if the
subtree does not have a solution for g. This ensures the completeness of search,
bye'
T heorem 5.3.: <? preserves the order of results as obtained by Prolog.
Proof. No solution is missed and every solution obtained by Prolog is obtained.
The control is the same as in Prolog, i.e., left-to-right within a rule and top-tobottom selection of alternatives. Hence, <;' preserves the order of the result.
T heorem S.4.: No two states in the goal-tree by s ' of a goal g which fails are
identical.
Proof: A state in a goal-tree corresponds to the path in the goal-search tree.
Thus, every node in a goal-search tree corresponds to a state. Consider a goal g
executed in the state a. Let A be a solution of g. Also assume that A is a
failure-solution of g. If another solution of g, A' = A, is obtained, then forward
117
execution from g is aborted. This is done for all failure-solutions of g. This
means that computation from g onwards does not encounter two identical states
which lead to failure. If g does not have any solution then this is applicable to
the whole goal-tree of g. As a corollary to Theorem 5.4. it can be stated that
"there are no two identical paths in the goal-tree by
of a goal g which fail".
118
5.7. Difficulty in Implementation of c*
It should be noted that association of FST(q", o) with q" is not possible on a
linear stack of goals - because of the stacking of records in the chronological order of
execution. A goal can be solved by a rule whose subgoals may be solved by different
rule applications and so on. This leads to the record q" being buried deep in the
local-stack. Due to the simplicity of implementation o f stack, the address of this
record is not know. Hence, the search space and solution o f a goal cannot be associ
ated with it. A new data structure which is introduced in chapter 7 is needed to effect
intelligent forward execution.
Chapter 6
6. Intelligent Forward Jumping
6.1. Introduction
The notion of forward jumping for sequential execution of Prolog is addressed
and a scheme to avoid computation of subgoals independent of the corrective actions
taken by backtracking is presented/ These independent subgoals fall in the range of
the failed subgoal, f, and the backtrack subgoal, b, in a rule. The goals are identified
from the subgoal dependencies in a rule together with the generators and consumers of
the variables in the rule. The resulting search based on forward jumping,
is related
to the goal-tree o f Prolog, and the savings in computation is illustrated. It is proved
that
satisfies the completeness and soundness properties of Prolog and that it
preserves the order of solutions obtained by Prolog.
The notion of intelligent forward jumping is based on the observation that when
backtracking occurs, say, from the subgoal position f to the subgoal position 1 £ b < f
within the body o f a rule, then only some of the subgoals in the range b £ i £ f (in
short, [b..f]) need to be re-evaluated. The inequalities
S between the literals
indicate the order of appearance of the literals in a rule. The set of subgoals that have
to be re-evaluated to ensure completeness of search is denoted by redo(b, f). The rea
son that we are able to avoid re-evaluation of the other subgoals in the range fb .f] is
that the re-execution of these subgoals would proceed exactly in the same way as
before, through the same series of successes, failures, and backtrackings and generat
ing the same intermediate variable bindings, if any, on the way [33, 34],
t
A separate representation scheme and method for forward jumping is being independently
developed by Dr. Kundu. [33 - 34]
119
120
The forward jumping scheme avoids computation of successful subgoals which
are independent of the corrective action taken to cure the failure o f the currently failed
subgoal. The list of subgoals that can potentially affect the cause of failure of the
most recently failed subgoal is identified from the gc-lists o f the variables in the rule.
After backtracking, only those subgoals that are in the redo-list are recomputed, thus
effecting forward jumping over subgoals that are not in this list.
Consider the rule
r" : p(X, Y)
i(X), s(Y), t(X, Z), u(Z, M), v(Y, T).
Execution of p(X, Y) may proceed in the following manner *
1.
r(X) succeeds, generating the binding X/a
2.
s(Y) succeeds, generating the binding Y/bl
3.
t(a, Z) succeeds, generating the binding Z/c
4.
u(c, M) succeeds, generating the binding M/d
5.
v (b l,T ) fails.
Backtracking would take to s(Y), for a new binding for Y. In the process the
search space of t(a, Z) and u(c, M) is deleted. After s(Y) succeeds, with a new bind
ing for Y, the goals t(a, Y) and u(c, M) start from their first alternative Let the recom
putation continue as follow:
6.
s(Y) succeeds, generating the binding Y/bl
7.
t(a, Z) succeeds, generating the binding Z/c
8.
u(c, M) succeeds, generating the binding M/d
Now, v(b2, T) is tried for solutions. Note that when s(Y) succeeds with a new
binding Y/b2, t(a, Z) succeeds with the binding Z/c, and u(c, M), succeeds with the
binding M/d. These recomputations of successful subgoals encountered in the previ
ous computations need not be repeated. The execution of the goals t(X. Z) and ufZ.
* These observations were developed Jointly with Kundu, [33J.
121
M) are independent of the new solution of s(Y). Forward jumping is a scheme to
avoid such unnecessary successful recomputation.
122
6.2. Dependencies among subgoals
The gc-list o f the variables which appear on the RHS of a rule is the list of the
literals which appear on the RHS of a rule and whose declaration has the variable X, as
its argument or part of its argum ent Note that since the declaration o f the literal
differs throughout the program, the gc-lists are pertinent only to the rule; it is valid as
long as the rule is not modified. (Refer Chapter 4)
Consider a rule
" q u e r y ( ...) 1,2, 3.......n."
where the literals are replaced by their corresponding indices. Consider two literals i
and j in the rule.
Definition 6.1.: A literals b is said to be exclusive of the literal f, and vice versa,
if b and f do not share any variables. In other words, there is no gc-list which
contains both b and f.
Definition 62.: A literal b is said to be related to the literal f, and vice versa, if b
is not exclusive of f. Note that every literal is related to itself.
Definition 6J.: A literal f is dependent on a literal b, f £ b, if it is related to i or if
there exists a literal k, b £ k £ f, which is dependent on b. Every literal is depen
dent on itself.
Definition 6.4.: In a range of literals [b..f], a literal p is parallel to a literal b, b <
m £ f, if p is not dependent on b and if there exists a literal k, p < k £ f, which is
dependent on b.
Definition 65.: In a range of literals [b..f| if a literal o > i is neither dependent on
the literal b, nor is parallel to the literal b in the range [b..f], then the literal o is
said to be orthogonal to the literal b in the range [b..f].
123
When two goals are exclusive o f one another, they are semantically independent
o f one another. W hen two goals are related to one another, they are semantically
dependent on one another. If goal b appears before the goal f and if the goals b and f
are related to one another, then the solution of b affects the solution o f f. If literal f is
dependent on b, then the solution of f is directly or indirectly affected by the solution
of b. If a literal p is parallel to literal b in the range [b..f|, then the state o f computa
tion in which f is executed is affected by p as well as by b. If a literal o is orthogonal
to b in the range [b..f], then it implies that the computation of b does not affect the
computation of o and the computation of o does not affect the state in which f is exe
cuted.
6.3. Redo-list
Consider the situation when a rule r is executed and a subgoal f fails. Also,
assume that the backtrack literal selected is b, which is executed in the state o.
Definition 6.6.: The set redo(r, b, f, o) is the set of goals which are affected by
the recomputation of b and whose solutions affect the state in which f is exe
cuted.
The use of the redo-list is inter-procedural (i.e., applicable within a rule). When
the rule application is understood we represent redo(r, b, f, o ) by redo(b, f). The com
putation of the redo-list for a range [b..f] is done to find the subgoals in this range
which need to be re-executed for completeness of the search.
Exam ple
Refer to In Figure 1 consider the case when p4(al, b l, U) fails. The selected
backtrack literal is p2(X). Thus, f = 4 and b = 2. The re-execution of p2(X) may gen
erate a new binding for X. It is clear that no matter what the new binding of X may
be, there is no need to re-evaluate p3(Z).
124
Wc denote by redo(b, f, o) the list of the subgoals i, b £ i £ f, whose reexecution
after backtracking to b is necessary to assure that no potential solution to the rule head
is missed. The computation of redo(b, f, o ) in / can be done using the gc-lists of the
variables of f'.
The redo-list, redo(b, f). can be recursively defined as*
1.
b and f belong to redo(b, f).
2.
If j e redo(b, 0 and j e con(r', X), then gc(r', X) <\ [b..f] belongs
to redo(b, f, o).
Basically, redo(b, 0 consists o f all subgoals in the range [b..f] whose re-execution can
potentially affect the continuation of the computation from the subgoal b through the
subgoal f.
Example
Consider the following rule and its gc-lists.1
r : pO(X, Y ) p l ( Y , Z), p2(X), p3(Z), p4(X, Y, U), p5(Z, W), p6(V),
p7(X, V), p8(Y), p9(X, U. V), plO(Y, U), p i 1(X, Z).
gc(X) « [2,4, 7 ,9 , 11]
gc(U) = [4, 9, 10]
gc(Y) - [ 1 . 4 , 8. 10]
gc(V) - [6, 7,9]
gc(Z) = [1, 3, 5, 11]
gc(W) = [5]
Figure 20 illustrates the possible values of redo(2, 9) and redo(2, 11) based on the
various consumer lists.
t
The definition of rcdo(b, f) which dynamically changes with different stales was developed in
conjunction with Kundu, [33 - 34].
5
Kundu. [34],
125
Uurrent gc-lists in state o on backtracking to I
con(o, X) « [2,4, 7 ,9 ,1 1 ], con(a,
» [4 ,9 ,1 0 ]
redocz, 9, a )
[2,4,6,7, If, 9 T
con«j, Y) - [4 .8 .1 0 ], con(o, V) - [6 ,7 ,9 ]
con«r, 2 ) * [3 ,5 ,1 1 ], con(a, W) - [5]
con(o, X) = [2 ,4 ,7 ,9 , 11], con(a, U) « [4, 9, 10]
[2,4,6,7,9]
con(o, Y <—yO) = 0 , con(o, V) = [6, 7, 9]
con (a, Z) = [3 ,5 ,1 1 ], con(a, W) = [5]
con(C, X) = [2, 4, 7 ,9 ,1 1 ], con(flf, U) = [4, 9, 10]
[2, 4, 6 ,7 , 8,9]
con (a, Y) - [4, 8, 10], con (o, V) * [6 ,7 ,9 ]
con(Z, Z <— zO) « 0 , con(o, W) = [5]
con(o, X) = [2, 4, 7 ,9 , 11], con«J, U) = 14,9, 10]
[2,4,6,7,9]
con(o, Y «—yO) = 0 , con(o, V) * [6, 7, 9]
con (a, Z «— zO) = 0 , con(o, W) = [5]
Figure 20 (i). Possible values of redo(2,9) for different consumer lists.
126
Uurrent gc-Usts m state o on backtracking to 2
re d o (2 ,11, o)
con(CT, X) * [ 2 ,4 ,7 ,9 ,1 1 ] , con(o, U) » [4 ,9 ,1 0 ]
[2, 3 ,4 ,5 ,6 ,7 , 8 ,9 , 10, 11]
con(o, Y) « [4 ,8 ,1 0 ], con(o, V) - [6 ,7 ,9 ]
con(o, Z) » [3 ,5 ,1 1 ], con(o, W) » [5 ]
con(a, X) = [2, 4, 7 ,9 , 11], con(o, U) « [4, 9, 10]
[2, 3, 4 ,5 ,6 , 7, 9, 10, 11]
con(a, Y <— yO) * 0 , con(a, V) ■ [6, 7, 9]
con (a, Z) = [3 ,5 ,1 1 ], con(a, W) = [5]
con(o, X) » [2,4, 7 ,9 , 11], con(o, U) ■ [4, 9, 10]
[2, 4, 6, 7, 8, 9, 10, 11]
con(o, Y) = (4, 8, 10], con(o, V) ■ [6 ,7 ,9 ]
con(L, Z <— zO) = 0 , con(o, W) « [5]
con(o, X) * [2, 4, 7 ,9 , 11], con(o, U) - [4 ,9 , 10]
[2,4, 6, 7, 9, 10, 11]
con(a, Y <— yO) = 0 , con(a, V) « [ 6 ,7 ,9 ]
con(o, Z «- rO) * 0 , con(a, W) « [5]
Figure 20 (ii) Possible values of redo(2, 11) for different consumer lists.
Note that if a literal o is orthogonal to b and in the range [b..f], then o is orthogo
nal to b for any range [b...fl], f l £ f, The orthogonality is to be recomputed for any
other range.
The states in which the dependent goals o f b are executed are directly affected by
the execution of the goal b. The states in which the goals which are parallel to b are
executed are not affected by the execution of b. The solutions of the goals dependent
on b and the goals that are parallel to b are contributory to the state in which f is exe
cuted.
The states in which the goals that are orthogonal to b are executed are not
affected by the execution o f b. The solutions of the goals that are orthogonal to b in
the range [b..f] do not affect the state in which f is executed.
127
In the context o f sequential Prolog execution, f is the failed goal, b is the goal
backtracked to, and dependent and parallel goals form the redo-list. The recomputa
tion o f the orthogonal goals is redundant. The relationship between the subgoals in a
rule is dynamic during execution.
Consider an application / of a rule r. W hen substitution of the form X <— a is
applied to head(r), the relationships among the subgoals in r which are based on the
variable X are affected. This is because g c f/, X) * [0]. Also, consider a situation
where the subgoals [l..j] have succeeded. Also assume that the subgoal i, 0 £ i 5 j,
has generated a binding for a variable X. In this case, all members in gc(r', X) use the
binding for X. by X. Hence, any subgoal g > i, g e g c(r\ X), is dependent on i. For a
subgoal g \ i < g ' £ g and g ' € gc(r/, X), we can also say that the subgoal g is depen
dent on g'. But this dependence relation is of no consequence, due to the single
assignment property of logic programs. Dynamic dependence relations are used in
finding redofb, 0Consider an execution state in which the goals [l..fl have succeeded. Also
assume that a subgoal p, 1 £ p £ f, is orthogonal to a subgoal b in die range [b..f]- As
execution proceeds, a subgoal f 1 > f, which is related to b, as well as p, may succeed.
Now p is parallel to b in the range [b..fk], fk
f l. Thus the relationship between two
subgoals in a rule may dynamically change from being orthogonal to parallel to
orthogonal, and so on. As described earlier, only the dynamic parallel and orthogo
nal relationships, based on the dynamic dependence relationship are used in finding
redo(b, f>The literals in the body of the rule are denoted by the corresponding indices.
Algorithm R1 is the redo-list generation list algorithm, which uses the dynamic rela
tionships among the subgoals in a rule. The dynamic relationships can be known from
the generators and consumers of the variables in the rule.
128
Let f be the failed subgoal and b be the selected backtrack literal.
redo-set« {b, f};
temp-set = (b, f J;
var-set = {);
temp-var-set = var-set;
repeat
repeat
G = remove(temp-set); f* get an element from temp-set */
temp-var-set « (X | G e con(X)J
until (temp-set) - 0 ) ;
If ((temp-var-set - var-set) - 0 ) then break;
var-set * var-set u temp-var-set;
repeat
X ■ remove(temp-var-set);
If (b S gen(X) S f)
then
temp-set = temp-set u (con(var) n [b..fj);
until (temp-var-set = 0 or temp-set = [b..f]);
if ((temp-set - redo-set) *= 0 ) then break;
redo-set = redo-set u temp-set;
if (redo-set = [b..f]) then break;
until;
redo-list = order(remove-duplicates(redo-set));
Algorithm R l: An algorithm to generate dynamic redo(b, 0-
129
Algorithm R1 is finite and terminates, the termination conditions being i) 4 when
the redo-list contains all the subgoals in the range [b..f], ii) 4 when there are no more
new goals to be added to redo(b, f) iii) 4 when there are no more new variables that
are affected by the re-execution o f b.
130
6.4. F o rw ard Ju m p in g
The redo(b, f) is used for recomputation of intermediate subgoals during the
forward-jump phase. Once this list is exhausted, the forward-execution algorithm, as
described previously, is employed. After backtracking to b from f, the goals in
rcdo(b, f) are re-executed. The goal b is executed for further solutions, and the rest of
the goals in redofb, f) are executed from their first alternative. This is effected as fol
lows: after selecting b and finding redofb, f), the search spaces of the goals in [b..f] redo(b, f) are saved. After the re-execution of b, the execution continues by executing
the goals in redofb, f) and interleaving the search spaces, bringing back the saved
search space, of the goals in [b..f] - redo(b, f) in the order of their appearance in the
rule.
Exam ple
Consider red 0 (0 , 2, 11) of Figure 20. (ii). After backtracking to 2, computation
continues as follows.
compute/overlay
Continue Computation of 2
Interleave the search space of 3
Compute 4
Interleave the search space of 5
Compute 6
Compute 7
Interleave the search space of 8
Compute 9
Compute 10
Compute 11
13J
In the event of a failure o f a goal f € redo(b, f), b S f £ f, select a backtrack goal
b'. The backtrack procedure takes us to b'. The net result of backtracking from f has
resulted in backtracking to b'. Compute iedofb', f)- Discard the search space of the
subgoals that belongs to redofb', f). Then continue forward execution at b'.
Figure 21 shows the search tree based on from intelligent backtracking and for
ward jumping. Table V shows the trace o f execution from intelligent backtracking
and forward jumping.
132
fb = X /
fb = X / a l
fb = Z / c l
|
fb = X /a
fb » Z /c J
j Pruned Search epeee by Intelligent
1 b a c k track in g
F
fb = V/ f ]
P ru n e d S earch apace by Forward Ju m p in g
Success)'
Figure 2 1 . Goal-search tree explored by Intelligent Backtracking
and Forwaxd Jumpfag.
133
<pl(Y. Z>.()>
(p2fX). (J)
(pXZ), (Z*l))
(p4(X. Y.U). (U l.Y A D )
(p2(XU)>
(p*(X. Y.UMX*2,YAl)>
(p5(Z, X. U, W), {ZAl. X « , \m %))
(pl(Y .Z),(J)
(pvz). tjycii)
<p*z. X, U. W). {Z/cl. XA2. UM1))
<pl(Y, Z). U)
<p*Z). (Zfc3))
(p5<Z, X, U. W), (Z/c2. XA2, IW1))
(P*™ . (J)
0
'o.txAiv/nj)
(P^ . (YA2))
(p9(X.U, V). [X*2,UA».V/n))
0*00,0)
(p7(X, V). {XA2, V/!2)>
(p9(X. U. V). {XA2. UMl. V/OJ)
(plO(Y.UX, (YA2.U/J1))
(pllfX.Z). (XA2.ZA3))
t
YAl;Z/cl
X*>
XA2
UM1
YA1; Z/cl
YA2.ZAJ
XA1
Z/cl
pl.p3.p31
Z/cl
pl.p3.pS )
v /n
p6. pY, pA)
W/el
v /n
v /o
Tbbte V: Tncs r f E i n r i n by bMUigca Bacfcncbiag aid f a w j ) m f b |
Idm tiM bon FBT(p4) M«ch
134
6.5. Soundness and Com pleteness of C*
H ie search based on forward jumping.
will be proved to be sound and com
plete. It is also shown that the order of solutions obtained by
is the same as
obtained by Prolog.
T heorem 6.1.: <;" is sound.
Proof. Solutions are obtained only if a goal unifies with a fact or all the subgoals
in a rule applicable to the goal are true. Hence, every solution obtained by
is
sound.
T heorem 6.2.:
is complete.
Proof. In the default case, where redo(bt f) —[b..f], the search is complete. The
recomputation of the goals in the redo(bt f) (other than b) from their first alterna
tive is necessary, because the solutions of these goals can potentially affect the
state in which f is executed. As observed, the computation of the goals that are
not in the redo-list are independent of the corrective actions taken to cure the
failure of f. This ensures that no unique search path which would succeed, or
fail, is missed. Hence,
is complete.
T heorem 6.3.: <; preserves the order of results obtained.
Proof. H ie default case when redo(b, f) = [b..f], yields the same results as those
obtained by Prolog. Otherwise, the solutions of the different subgoals are inter
leaved during forward execution in the order o f their appearance in the rule.
Since the selection of control is still the same as in Prolog, the order of solutions
obtained by
is unaffected.
135
6.6. Difficulty in Implementation o f c”
The search space of a subgoal cannot be associated with a subgoal during execu
tion due to the nature of the linear local stack. It is not possible to isolate and store the
search space o f intermediate goals while backtracking and to interleave them during
the forward jumping process. The next chapter on the Segmented Stack presents a
data structure that facilitates association of search spaces with goals. This can help
forward jumping during sequential execution.
Chapter 7
7. Execution of Logic Programs on a Segmented Stack
7.1. Introduction
A new data structure, called the segmented stack, for execution of logic pro
grams is introduced. The segmented stack can be maintained as a right-threaded tree
with a heap pointer. A detailed illustration o f the segmented stack environment is
presented. It can be used as the data structure for the local-stack used by Prolog. The
use o f a segmented stack as the data structure to maintain the local-stack enables asso
ciation o f search spaces and solutions with goals. This in turn results in implementsJ
tion o f ^ ^ and <;". Forward and backward execution algorithms are given. The space
and time complexity analysis of the segmented stack is analyzed.
Prolog programs are evaluated on a linear stack of activation records, called the
local-stack or the environment-stack, together with the goal-list. The goal-list is a list
of goals which remain to be solved in older to to solve the initial query. It attempts to
unify with the goal, t, at the top of the local-stack with its alternatives. If t unifies
with a fact, then t succeeds. If t unifies with a rule-head of a rule r, then the body(r) is
inserted at the head of the goal-list. If the local-stack is empty or if the goal at the top
o f the local-stack succeeds, then the goal at the head of the goal-list, h, is selected for
solving. This modifies the goal-list in that h is removed from the goal-list. A record
o f h is stacked on top of the local stack of activation records. The goal h is tried for
unification with its first alternative. If h unifies with a fact, then h succeeds. If h
unifies with a rule-head of the rule r, then the body(r) is inserted at the head of the
goal-list. The local-stack is initialized empty. The local-stack grows with the invoca
tion of goals by forward execution. It contains the activation records of all the goals
that are active. The records on the local-stack constitute the current path in the goalsearch tree that is being tried to solve the initial query. The goal-list is initialized with
136
137
the query goal. It is empty on successful completion of the query. When the query
goal succeeds, the local-stack contains the goals falling in the current path that is
being tried for a solution. Thus, forward execution modifies the goal-list and the
local-stack.
A goal f fails when no more alternatives are left for unification. Backward exe
cution is as follows:
The goal f is inserted at the head of the goal-list.
A backtrack literal is selected.
Coals are popped off the local-stack, their alternatives reset, and inserted at
the head of the goal-list -the unification substitution created by this goal is
undone - till the backtrack literal is encountered at the top of the stack.
All the subgoals in body(r), of the rule r which unified with a goal g, and
which are in the goal-list are removed from the goal-list when the goal g is
encountered at the top of the local-stack.
The local-stack shrinks during backtracking.
The goal-fist grows and
shrinks during computation. Forward execution is resumed with the goal at the
top of the local-stack. When the query goal fails, the goal-list contains the query
goal and the local-stack is empty. Operations on the local-stack and the goal-list
occur hand-in-hand in order to implement, and execute, exhaustive search for
Prolog programs. A record on the local stack contains all necessary information
to implement, correctly, backtracking and continuation of search. A goal is
active as long as its activation record is present on the local-stack.
138
7,2. Inapplicability o f Linear Stack to Implement c' and c"
A goal may be solved by way of unification with a fact or by a rule which
succeeds. The rules that are applicable for a goal, in general, have more than one
subgoal, and one or more of these subgoals may be solved by using the rules
applicable to them. Hence, in general, the successful search path of one goal
contains more than one record on the local-stack.
The search paths of different subgoals are stacked on top of one another.
While backtracking, the records are popped off the stack until the backtrack
point is reached. The records o f the different subgoals in a rule are not readily
accessible without a linear popping o f the records from the local-stack. Con
tinuation of search of an intermediate subgoal going back to where die system
left off, cannot be implemented on a linear stack. Also, the information on a
linear stack is popped off during backtracking, the search space . Subsequently,
these popped records are not retrievable.
A solution to a goal is obtained only when the rule succeeds. The record of
the goal which succeeds is embedded deep in the stack. The solution of a goal
cannot be associated with the record of the goal. Hence, it is not possible to
associate FST’s with a goal. Independent search spaces cannot be saved and
interleaved in a straight forward fashion. Hence, <? and
cannot be imple
mented on a linear stack o f records as data the structure for the local-stack.
139
73. Segmented Stack
A linear stack structure for the local-stack does not facilitate maintenance
of FST’s with goals or for saving and interleaving search spaces for forwardjumping over subgoals. A data structure facilitating depth-first search, as well as
breadth-first search, is required. A new data structure, the segmented-stack, for
the local-stack is proposed in order to enable both depth-first search and
breadth-first search during execution of Prolog programs. Depth-first search is
employed when unification succeeds and during forward execution, and
breadth-first search is employed during intelligent backward execution, intelli
gent forward execution and forward jumping.
Definition of a Segm ented Stack:
A node in a segmented stack, SS, has three fields. These are
1) a rule-pointer,
2) a heap-pointer and
3) data.
The rules defining a segmented stack are,
1)
A segmented-stack, SS, of zero nodes is an empty segmented-stack.
2)
A segmented stack, SS, with a single node, which is the root of SS, is a
segmented-stack.
3)
A node, which is the root, together with its rule-pointer, pointing to a
list o f segmented-stacks, which form the body, is a segmented-stack.
140
A segmented-stack, SSg can be used as a local-stack for execution of a goal g as
follows:
1.
A node for g is created when g is executed.
2.
If g unifies with a fact, then the rule-pointer in the node for g is null, the tree
of SS( is empty and the heap-pointer in the node for g points to itself.
3.
If g unifies with a rule r, then each subgoal,
in body(r) is solved on a
separate segmented-stack, SS,. All such segmented-stacks, SS„ 1 £ i £ n,
where n is the number of subgoals in body(r) which has been solved, form
the tree o f the segmented-stack rooted at g. The rule-pointer in the node for
g points to the list (SS„ SS* .... SS.}. The heap-pointer points to the node
pointed to by the heap-pointer of SS.. The list of segmented-stacks together
with the root g is the segmented-stack SSr Thus the heap-pointer points to
the last record formed on the segmented-stack.
In the context o f Prolog execution, this corresponds to a goal unifying with
head(r) o f a rule r. The subgoals in body(r) are solved over the segmented-stacks
pointed to by the list, pointed to by the rule-pointer.
A node is an activation record of a goal. The list implementation of the
segmented-stacks for different subgoals in a rule enables operation on any of these
subgoals. Hence, the search space of any of the subgoals in body(r) can be deleted.
Also, the heap-pointer of the segmented stack o f a subgoal can be used to continue
execution of the subgoal. Thus, a subgoal in a rule solved on a segmented-stack can
be deleted or continued for further solutions without affecting the search space of
other subgoals in the rule. The logical connectivity among the subgoals in a rule is
maintained by the list of segmented-stacks over which the subgoals are solved. The
logical connectivity between a goal and the body(r) of the rule r applied to solve the
goal is maintained by the rule-pointer of the record o f the goal.
141
Example
Consider the facts and rules in Figure 11 and a goal r(a l, bl). A node for r ( a lt
b l) is created. The rule-pointer and heap-pointer are undefined. When r(a l, b l)
unifies with the first rule of r the rule-pointer points to a list o f two segmented stack.
r l l ( a l ) is executed on the first segmented stack and rl2 (b l) on the second, r l l ( a l )
unifies with a fact and so the corresponding segmented stack is a single node pointing
to itself.
The segmented-stack needs to hold all the information that would be held in the
equivalent local-stack during the execution of logic programs. Since there is a record
for every goal that is active, this information would be consistent with that of a linear
stack implementation of the local-stack.
A segmented-stack is active as long as its root is present. An active segmentedstack can be in either of the two states: Open or Closed. If the heap-pointer of an
active segmented-stack, SS,, is null, then it is said to be Open. Otherwise it is said to
be Closed.
In the context of Prolog execution
1.
An open
segmented-stack
with a single node corresponds to the
segmented-stack for a goal whose unification is in progress.
2.
A closed segmented-stack with a single node corresponds to a segmentedstack for a goal which has succeeded by unification with a fact.
3.
An open segmented-stack with multiple nodes corresponds to a segmentedstack for a goal for which a rule application has not yet terminated.
4.
A closed segmented-stack with multiple nodes corresponds to a segmentedstack for a goal which has succeeded by a rule application.
142
The operations on a segmented-stack are:
m k seg
Segmented-stacks are created by the mk_seg() procedure. This procedure opens
a segmented-stack by creating a node for the goal to be executed on this
segmented-stack.
close_seg
Segmented-stacks are closed by the close_segO procedure. This procedure
closes a segmented-stack by recording the heap-pointer at the of the segmentedstack.
get-top(arg)
Segmented-stacks are accessed by the get-top(arg) procedure. This procedure
goes to the top of the segmented-stack referred to by the argument via the heappointer of the segmented-stack, referred to by arg.
m k_null(arg)
A segmented-stack is deleted by the mk-null(arg) procedure. This procedure
deletes the tree of the segmented-stack referred to by arg. It also undefines,
makes null, the rule-pointer and the heap-pointer at the root of this segmentedstack..
A segmented-stack is active during the interim of the mk_segO which created it
and the mk-null(arg) call referring to its parent. The above procedures are sufficient
to create and maintain a segmented-stack.
7.4. Forward Execution on a Segmented Stack
The two main data-structures other than the goal-list and the segmented-stack are
the heap and trail. The heap maintains the address o f the choice-points [32] and the
trail maintains the unification substitution informations. The goal-list contains the
goals to be computed to solve the primary goal, and the segmented-stack contains the
nodes for the goals that have been computed, partially or fully, constituting the path
from root to the present node in the goal-seaich-tree. Algorithm A3 gives the Forward
Execution Algorithm on a segmented stack.
1.
A segmented-stack is created when a goal, G, is first tried for solution.
2.
If G unifies with a fact, then the segmented-stack corresponding to this goal
is closed using the address of the node of G itself for the heap-pointer of G.
3.
If G unifies with a rule, then a list of segmented-stacks are created to solve
each of the subgoals in the rule-body. When each of these segmentedstacks that solve these subgoals are closed, then the segmented-stack of G is
closed by updating the heap-pointer of the segmented-stack o f G with the
heap-pointer of the last segmented-stack which solved the last goal in the
rule.
Algorithm A3 is used to build the segmented-stack as the forward execution
proceeds. If any o f the subgoals fail, then backward execution is applied.
Phase I
if (goal*list - 0 )
then
report success
Apply Algorithm B3
else
t_goal = get(goal-list); f* get first element from goal-list */
if t_goal = Y
then
close_segO; /** record the pointer to the top of the stack **/
else
mk_segO
/** create a new segmented stack and record the
pointer of its root **/
Phase II
t__list - unify(t_goal)
if (t_list = fail)
then
report failure
Apply Algorithm B3
else
cons(t_list* goaMist);
Apply Algorithm A3 at Phase I
Phase
in
t-goal = get-top(b);
Apply Forward Execution at Phase I
A lgorithm A3: F orw ard Execution A lgorithm on Segm ented-stack.
145
7.5. Backward Execution on a Segmented Stack
Backward execution allows search for other alternate solutions. During back
ward execution, many subgoals in a rule are to be redone. After the detection of the
cause o f failure of a subgoal, and subsequent detection of the backtrack-literal and the
redo-list, the segmented-stack is updated to perform backtracking and forward jum p
ing.
When the backward execution algorithm is invoked, a backtrack literal, b, is
selected together with the redo-list. The search space on the segmented-stack of the
goals in the redo-list are deleted, the tree of the corresponding segmentcd-stack is
deleted, and the rule-pointer and heap-pointer set to null. Forward execution is
resumed, at Phase Q, at b. If b fails, then backward execution is applied. If b
succeeds, then the forward-jumping algorithm is applied. Algorithm B3 gives the
backward execution algorithm for the segmented-stack.
Let f be the failed literal,
b = select(backtrack-literal)
generate redo(b, f)
for (i e redo-list) do
mk-null(i);
backtrack (b);
modify (FST(b));
rep eat
Apply Algorithm A3 Phase II to b
until (result is not subsumed in FST(b))
if (result = failure) then
report failure
Apply Algorithm B3
146
else
for (i e rcdo(b, 0 ) do
Apply Algorithm A3 Phase n to i as t_goal.
Algorithm B3: Backward Execution Algorithm on a Segmented-stack.
The segmented-stack representation of the local-stack for two instances from
Figure 1. arc shown in Figure 22. It shows the state where pO has unified with the
rule-head and when the execution of the subgoals p i, p2, p3, p4 and p5 have suc
ceeded. Note that until all the subgoals in the rule succeed, the heap-pointer with the
node for pO will remain dangling, i.e., undefined.
ru le -p o in te r
Dangling heap pointer
heap
pointe
Figure 22. Execution o f Logic program* on a segm ented stack,
a c u e from Figure 1.
147
7.6. Space Complexity of Segmented Stack
There is an additional usage of space in implementing the segmented stack in the
form of two additional fields in each frame. These are used for maintaining the rulepointer and the segment pointer. The space complexity o f the local-stack is unaltered.
With m inim al overhead in space, significant efficiency in execution can be obtained.
The maintenance of the segmented stack is simple and efficient.
In implementing forward jumping, there is a dynamic overhead in space. This
overhead in the form of saving the search subspace of the successful subgoals that do
not fall in the redo-list, while backtracking and forward jumping are taking place.
This dynamic overhead in the use of space is directly proportional to the savings in
computations derived by forward jumping.
Also, since a subgoal is computed on a separate segmented stack, the solutions of
the subgoal can be associated with i t This facilitates association of FST’s with a goal,
so we can implement intelligent forward execution.
When space is at premium, forward jumping can be avoided by simply back
tracking to the appropriate goal and performing the normal operations of popping the
stack and only implementing
Chapter 8
8. Effects of Non-logical Operators
8.1. Introduction
Non-logical operators in Prolog, such as =, >, <, assert, write, cut, fail, facilitate
programming. These operators have side-effects while performing mathematical
operations, while avoiding search using control operations like cut and fail, and while
performing input/output operations. These operators are built on top of the systematic
control facility of the Prolog interpreter. It is essential that every new paradigm for
Prolog, or logic programming, incorporates these facilities in a transparent manner.
The operators +,
*, /, =, <, >, write and read do not have any effect on the para
digms developed in chapters 4, 5, and 6. The operator "consult" modifies the program
and hence all the identified failure-bindings, failure-solutions and gc-lists stand void
The effects of other non-logical operators on the different paradigms and data struc
tures is described below.
148
149
8.2. Effect of C ut and Fail
The cut is a control facility provided to the programmer to help prune certain
searches. The predicate cut always succeeds. When forward execution encounters the
predicate cut, all subsequent searches of the subgoals to the left of the cut in the rule,
and subsequent alternatives that are applicable to the goal that unified with the head,
are avoided.
The effect of the cut on the identification of failure-bindings is contributory to its
incompleteness. This is because not all the alternatives of a goal are tried when any of
the alternative applicable to the goal execute a cut. Hence, no failure-bindings can be
identified.
There is no effect o f the cut on identification of failure-solutions. Similarly, the
forward jumping procedure is unaltered if any of the subgoals in a rule applied to a
goal contains a cut. The use of the segmented stack as a data structure for the local
stack does not hinder the control implemented by the cut.
The control operator ''fail” does not have any effect on the paradigms developed
in the earlier chapters.
ISO
8*3. Effect o f Assert and Retract
Retract removes information from the database and hence does not affect either
the identified failure-bindings or failure-solutions, though it could lead to not identify
ing some failure-bindings during later execution. Assert, however, adds to the infor
mation content of the database. This voids all identified failure-bindings and failuresolutions. Hence, FBT*s and FST’s of all predicates and goals are made void.
Chapter 9
9. Summary
9.1. Conclusions
W e have presented three paradigms and a new data structure for implementing
these paradigms. The frame woric implementing these paradigms on the new data
structure leads to very efficient execution o f logic programs.
1.
The identification and use o f failure-bindings during execution leads to
alleviation o f extensive oscillation o f computation between backtracking
and forward execution. Although the identification o f failure-bindings is
not complete, the late detection of failure is cured to a great extent by the
bit-vector implementation and the use of failure-binding-tables. The time
and space incurred in the identification o f failure-bindings of a goal is ident
ical to the nodes in the goal-search tree o f a goal.
2.
T he identification and use o f failure-solutions dining execution leads to
elimination o f retracing of identical paths in the goal-search o f the primary
goal. In other words, the states encountered by the use o f failure-solutions
are unique. Thus, the resulting search is deterministic in nature. The time
and space incurred in identifying a failure-solunon o f a goal equals the
num ber of nodes in the goal-search tree o f the initial query which is under a
subgoal.
3.
The use o f forward jumping leads to further pruning o f the goal-search tree.
Forward jumping leads to elimination of computations with combinations
o f bindings which have been identified to cause failure. The time and space
incurred in determining redo-list for forward jumping equals N^, * NrAr, lt.
where Nw is the maximum number of variables used in a rule and
151
n _^|
... is
152
the number of goals in the rule.
4.
As described in chapter 7, the additional space and time incurred in execut
ing logic programs on a segmented-stack, as the data structure for the
local-stack, equals two additional fields in each frame and their updating.
Thus, additional savings in computation can be found by implementing the
techniques described in this dissertation.
5.
The effect of non-logical operators is straightforward so that these operators
can be implemented properly in the context of efficient search.
Figure 23 presents a flow chart of the execution box of a goal for the framework
which would implement intelligent backtracking based on failure-bindings
identified by the bit-vector method, intelligent forward execution based on
failure-solutions, and forward jumping.
Figure 24 shows the goal-tree which uses all the three paradigms for the example
in Figure
1. Table VI gives the trace of execution forthe example in Figure
on the use
of all the three paradigms.
1 based
153
no
| p r tm iy S
fetch redo
list
I
Fetch f<
yes
Report SUCCESS
no
ifa ilu rrv
yes
no
A O t U t I O * ——
until'
succe*
no
no
b -0
R eport FAILURE
b >0
Figure 23. Execution Box of a goal implementing Intelligent
Backtracking, Intelligent Forward Execution and
Forward Juiqping
154
b l.c l
(bl.
Y/bl; Z/c l
c u Y' b 2 - V r t
X /0 2 t
F
ib * X /al
fb = X / a
U/
fb = Z / c l
Pruned Search space based on
Intelligent backtracking
fb = V / f l
Pruned Search sp ace by Forward Ju m p in g
Pruned S earch ap ace by Failure S o lu tio n
Success!!
Figure 2 4 . G oal-tree by In telligen t B acktracking. In tellig en t Forward
Execution and Forward Jum ping
155
goal
(pl(Y, Z). (Y .Z ). {},{})
(p2(X), {))
<p3(Z). {Z/cl}>
<p4(X. Y,U), (X/al, Y /bl])
(p2(X). {})
(p4(X. Y, U)( {X/a2, Y /bl))
<p5(Z, X. U. W). {Z/cl. X W , U /dl))
(pl(Y, Z),{})
(p5(Z, X. U. W). {Z/cl. X/h2. U /dl))
(pl(Y. Z). {))
<p3(Z), (Z/c2J)
(p5(Z, X. U, W). {Z/c2, X/a2. U /dl))
(P6(V), {))
(p7(X. V). {X/a2, V/fl J)
<p8(Y). {Y/b2})
<p9fX, U. V). {X/a2. U/dl. V /fl})
<P6(V}, {))
(p7(X,V), (X/a2, V/f2))
(p9(X, U. V). {X/a2, U/dl. V/E2))
(plOCY.U). {Y/b2,U/dl|)
(pll(X . Z). {X/a2. Z/c2))
success/fail
success
success
success
fiul
ruccess
success
fail
success
fail
success
success
success
success
success
success
fail
success
success
success
success
success
binding
Y/bl; Z/cl
X/sl
X/»2
U/dl
Y/bl; Z/cl
Y/b2; Z/c2
W/el
v/n
V/T2
*
"
fb
X/al
Z/cl
Z/cl
V/fl
”
e PSTW
yes
*
-
b
ta
pi
*
pi
p6
-
redo-list
(p2J
(p l,p 3 |
{pl,p3|
(P6. p7}
*
"
Table VI: Trace of Execution by Intelligent Backtracking. Intelligent Forward Execution and Forward Jumping
t
Identified from FBT(p4) search, fb and b in the header row is an acronym for failure-binding and
backtrack literal, respectively.
156
Each of these paradigms is defined and systematic evaluation of these methods is
presented in detail. Forward- and backward* execution algorithms that implement
these paradigms are given. It is proved that the application of these paradigms is
sound and complete in that the resulting execution based on these paradigms are
sound and complete. Also, the application of these paradigms preserves the order of
results obtained by Prolog. The properties of the use o f these paradigms and data
structure are:
Failure Binding (Chapter 4)
Precise cause of failure.
State independent. Intelligent backtracking farthest to the left than has been pre
viously possible.
Global learning of information about predicates.
Failure Solution (Ch. 5)
Use of history of computation.
State dependent.
Intelligent forward execution eliminates repetition of unsuccessful search.
Local learning about the solutions of goals.
Forward Jumping (Ch. 6)
Use of generator consumer approach.
State dependent.
Eliminates repetition of successful search after backtracking.
Segmented Stack (Ch. 7)
Facilitates association of information about a goal with the goal.
Keeps space and time complexity identical to that of linear stack.
Used for interleaved depth-first and breadth-first search.
A simple comparison of the number of steps performed by the application of different
157
paradigms and that by Prolog, for the example in Figure 1, from the Tables I,
n, in,
IV and V is given below.
Standard
C
<
5"
Prolog
45
Unified
framework
34
34
22
21
This project was started in conjunction with Kundu, [33] and [59]. The concepts
in Kundu, [34], differ in that the failure-bindings described in this dissertation are pre
cise causes of failure and that by Kundu are composite faiure-bindings. The use of
FBT is similar, if not identical. The representation schemes for the dependencies
among the literals in a rule are different The generation of redo-list is based on the
representation schemes.
An implementation of an interpreter based on the paradigms described in this
chapter was undertaken by Mr. Pramod Korwar, under the direction of Kundu. This
interpreter implemented a prototype of the segmented stack and the bit-vector method
for identification of "precise" failure-binding, as described in chapter 4 For more
details on this implementation contact Kundu, [33].
158
9.2. Future Directions
The area o f efficient execution of logic programs needs to be further explored.
Some o f the open issues that can be stated are as follows:
a)
Extension of the paradigms introduced in this dissertation to logic programs
which contain generalized terms containing lists$. sup t$
b)
Is it possible to find a method which is complete in identifying failurebindings of a goal?
c)
Can the identification of failure-bindings lead further pruning than has been
described in this dissertation?
d)
How to make the FST and FBT table look up procedures more efficient?
e)
A method to identify failure-bindings of a negated goal.
f)
A user friendly, declarative style to control paradigm to specify control of
search.
g)
A formal and accurate time and complexity analysis model for comparing
the execution models for logic programs.
t
The application of failure-bindings to (he case of logic programs with generalized terms is being
investigated independently Kundu, [33 -34],
References
1
Hogger, C. J., Introduction to Logic Programming, APIC Studies in Data
Processing, No. 21, Academic Press, Inc., New York, 1984.
2
Lloyd, J. W „ Mathematical foundations o f logic programming, Research
Monograph, Dept, of Computer Science, Univ. of Melbourne, Australia,
1983.
3
Clark, K. L., Tamlund, S. A., Logic Programming, editors, APIC studies in
data processing, Vol. 16, Academic Press, London.
4
Clocks in, W. F., Mellish, C. S., Programming in Prolog, Springer-Verlag,
Berlin, 1981.
5
Stallman, R. M. and Sussman, G. J., Forward Reasoning and dependency
directed backtracking in a system for computer aided circuit analysis,
Artificial Intelligence, 9(1977).
6
Apt, K. R., van Emden, M. H., Contributions to the theory of logic pro
gramming, JACM 29(3), pp. 841-862.
7
Kowalski, R. A., Predicate logic as a programming language, Proc. of
IFIP-74 North Holland Publ., Amsterdam, pp. 569-574.
8
Kowalski, R. A., Prolog as a logic programming language, Proc. of AICA
congress, Pavia, Italy, September, 1981, 23-25.
9
Kowalski, R. A., The history of logic programming.
10 Kowalski, R., in, Logic for Problem Solving, Elsevier, North Holland, New
159
160
York, NY, 1979.
11
Pereira, L. M., Porto, A., Selective Backtracking, Logic Programming, ed.
K. L. Clark and S. A. Tamlund, Academic Press, 1982, pp. 107-114.
12 Cox, P. T., Finding Backtrack Points for Intelligent Backtracking, Imple
mentations of Prolog, ed. J. A. Campbell, Ellis Horwood Limited, 1984, pp.
216-233.
13
Cox, P., Pietrzylowsld, T., Deduction Plans: A basis for Intelligent Back
tracking, IEEE Transactions on Pattern Analysis and Machine Intelligence,
P A M I-3 ,1981.
14
Bruynooghe, M., Analysis of Dependencies to Improve the Behaviour of
Logic Programs, Conference on Automated Deduction, 1980, pp. 293-305.
15
Bruynooghe, M., Intelligent Backtracking for an Interpreter of Horn C ause
Logic Programs, Mathematical Logic in Computer Science, Salgotaijan,
Hungary, ColJoquia Mathematics Societatis Janos Bolyai, 1978.
16
Bruynooghe, M., Pereira, L. M., Deduction Revision by Intelligent Back
tracking, in Implementations of Prolog, ed. J. A. Campbell, Ellis Horwood
Limited, 1984, pp. 194-215.
17
Chang, J. H., Despain, A. M., DeGroot, D., AND-Parallelism of Logic Pro
grams Based on a Static Data Dependency Analysis, IEEE Spring CompCon, 1985, pp. 218-225.
18
Chang, J. H., Despain, A. M., Semi-Intelligent Backtracking of Prolog
Based on a Static Data Dependency Analysis, Proceedings of IEEE Sympo
sium on Logic Programming, August, 1985, pp. 10-21.
19
Concry, J. S., Implementing Backward Execution in Nondeterministic
AND-Parallel Systems, Fourth International Conference on Logic Program
ming, MIT Press, 1987.
20
Conery, J. S., The And/Or Process Model for Parallel Interpretation of
Logic Programs, PhD Thesis, University of California, Irvine, CA, June
1983.
21
Conery, J. S., Kibler, D. F., And-Parallelism and Non-Determinism in
Logic Programs, New Generation Computing, 3,1985, pp. 43-70.
22
Conery, J. S., Backward Execution in Non-Deterministic And-Parallel Sys
tems, Proceedings of Fourth International Conference on Logic Program
ming, May 1987.
23
Conery, J. S., Kibler, D. F., Parallel Interpretation of Logic Programs,
Proceedings of the ACM Conference on Functional Languages and Com
puter Architecture, October 1981, pp. 163-170.
24
Kumar, V., Lin, Y. J., A Framework for Intelligent Backtracking in Logic
Programs, Proceedings of the Sixth Conference on Foundations of Software
Technology and Theoretical Computer Science, New Delhi, India, pp. ???,
Springer-Verlag lecture notes #241, December 1986,
25
Kumar, V., Lin, Y. J., An Intelligent Backtracking Scheme for Prolog,
IEEE Symposium on Logic Programming, San Francisco. 1987,406-114.
26
Woo, N., Choc, K., Selecting the Backtrack Literal in the AND/OR Process
162
Model, Symposium on Logic Programming, Salt Lake City, 1986, pp. 200209.
27
Rajasekhar, S, Narasimha Murthy, Variable Based Backtrcldng Method,
Conference on
28
The memory management of Prolog implementations, Clark and Tamlund.
29
Warren, D. H. D., An Abstract Prolog Instruction Set, Technical Note 309,
SRI International, Menlo Park, CA, October 1983.
30 Warren, D. H. D., Or-Parallel Execution Models of Prolog, Technical Note,
Dept, o f Computer Science, University of Manchester, December 1986.
31
Warren, D. H. D., Implementing Prolog - compiling predicate logic pro
grams, Research reports No. 39 and 40, Dept, of AI, Univ. of Edinburgh,
Scotland, 1977.
32
Warren, D. H. D .t An improved Prolog implementation which optimizes tail
recursion, Workshop on LP, 1980.
33
Kundu, S., private communications and different versions of reports
exchanged, October, 1987 through March, 1989.
34 Kundu, S., paper under preparation pertaining to generalized failurebindings and their use for backtracking and forward jumping.
35 Mellish, C. S., An alternative to structure sharing in the implementation of
Prolog interpreter, Clark and Tamlund.
36
Clark, K., Gregory, S., PARLOG: Parallel Programming in Logic, Research
Report DOC 84/4, D ept of Computing, Imperial College of Science and
Tech., London, 1984.
37
Gregory, S., Design, Application and Implementation o f a Parallel Logic
Programming Language, PhD Thesis, Imperial College o f Science and
Tech., London, 1985.
38
Hermenegildo, M. V„ Nasr, R. I., Efficient Management o f Backtracking in
AND-Parallelism, Third International Conference on Logic Programming,
Springer-Verlag, Lecture Notes in Computer Science, Vol. 225,1986.
39
Disz, T., Lusk, E., Overbeek, R., Efficient Management o f Backtracking in
Or-Parallel Logic Programs, Proceedings of Fourth International Confer
ence on Logic Programming, May 1987.
40
Kale, L. V., Warren, D. S., A Class of Architectures for Prolog Machine,
Proc. of the Conference on Logic Programming, Uppasala, Sweden, July
1984, pp. 171-182.
41
Kale, L. V., Parallel Execution of Logic Programs: The Redtice-Or Process
Model, Proceedings of Fourth International Conference on Logic Program
ming, May 1987.
42
Hausmen, B., Ciepielewski, A., Haridi, S., Or-Parallel Prolog Made
Efficient on Shared Memory Multiprocessors, IEEE Symposium on Logic
Programming, San Francisco, 1987, pp. 69-79.
43
Degroot, D., Restricted And-Parallelism and Side-Effects, IEEE Sympo
sium on Logic Programming, San Francisco, 1987, pp. 80-91.
44
DeGroot, D., Restricted And-Parallelism, ICOT International Conference
164
on Fifth Generation Computer Systems, 1984, pp. 471-478.
45
Kale, L. V., Completeness and Full Parallelism of Parallel Logic Program
ming Schemes, IP.BF. Symposium on Logic Programming, San Francisco,
1987, pp. 125-133.
46
Wisboiough, W., Semantically Transparent Selective Reset for AND Paral
lel Interpreters Based on Origin of Failures, IEEE Symposium on Logic
Programming, San Francisco, 1987, pp. 134-153.
47 Ali, K. A. M., A Method for Implementing Cut in Parallel Execution of
Prolog, IEEE Symposium on Logic Programming, San Francisco, 1987, pp.
449-45.
48
Ueda, K., Making Exhaustive Search Programs Deterministic, Proc. Third
International Conference on Logic Programming (Lecture Notes in Com
puter Science, Vol. 225), Springer-Verlag, 1986, pp. 270-282.
49 Ueda, K., Guarded Horn Clauses, in Proc. Logic Programming ’85, E.
Wada (ed.), Lecture Notes in Computer Science, 221, Springer-Verlag, pp.
168-179,
50
Byrd, L,, Understanding the control flow of Prolog programs. Logic pro
gramming workshop 1980.
51
Ciepielewski, A., Haridi, S., A Formal Model for Or-Parallel Execution of
Logic Programs, in Information Processing, R. E. A. Mason (ed.) Elsevier
Science Publishers. 1983, pp. 299-305.
52
Li, P. P., Martin, A. J., The Sync Model: A Parallel Execution Method for
Logic Programming, in Proceedings of the Third Symposium on Logic Pro
gramming, Salt Lake City. September, 1986.
53 Wise, M. J„ A Parallel Prolog: The Construction o f a Data Driven Model,
Proceedings of the 1982 Conference on Lisp and Functional Programming,
1982, pp. 56-66.
54 Kasif, S., Minker, J., The Intelligent Channel: A Scheme for Result Sharing
in Logic Programs, Proceedings o f the 9th UCA1, Los Angeles, August
1985, pp. 29-31..
55
Monteiro, L., A proposal for distributed programming in Logic, in Imple
mentations of Prolog, Ed. Campbell, Ellis Horwood 1984.
56 Borgwaidt, P., Rea, D., Distributed Semi-Intelligent Backtracking for a
Stack-based AND-parallel Prolog, Proceedings of the 1986 Symposium on
Logic Programming, IEEE Computer Society, 1986, pp. 211-222.
57
Kumar, A., Parameswaran, N., and Iyengar, S. S., Meta-level Control in
Prolog Interpretation, submitted to CACM, May 1989.
58
Iyengar, S. S., and Kashyap, R. L „ Intelligent Autonomous Machines, IEEE
Computer, June 1989, pp. 14.
59
Iyengar, Sudharsan, and Kundu, S., two reports on the ideas of failurebinding, forward jumping, intelligent forward execution and segmented
stack, independent study report, March 1988.
Vita
Sudharsan R. Iyengar w as bom to Pankajam and R engasw am y A ravam udhan on
First o f N ovem ber, 1961, in the tow n o f S rirangam , M adras, India. A fter finishing
Secondary
S c h o o l C ertificate at Fatim a H igh School, B om bay, and H igher S econ
dary C ertificate, at C H M C , Bom bay, he w ent on to study for the B achelor in
E ngineering D egree, at R egional E ngineering college, D urgapur. A fter obtaining the
B.E. in E lectrical E ngineering, in M ay 1984, he w ent on to pursue higher education at
L ouisiana State U niversity, Baton R ouge. H e got his M .S. in S ystem s Science and
M .S. in E lectrical E ngineering in M ay 1987. H e is currently a can d id ate fo r his Ph.D.
degree in the D epartm ent o f C om puter Science, at LSU , B aton Rouge.
166
DOCTORAL EXAMINATION AND DISSERTATION REPORT
C a n d id a te :
Sudharsan R. Iyengar
(first)
(last)
Major Field:
COMPUTER SCIENCE
Title of Dissertation
A Framework for Efficient Execution of Logic Programs,
Approved:
Major Professor and Chairman
Dean of the Graduate
EXAM INING
Date of Examination:
6/ 2 9 / 8 9
C O M M ITTEE