#2#><#2#>
<#4#>Prolog - next 2 weeks<#4#>
- Overview
- Prolog and Predicate Calculus
- Substitution and Unification
- Prolog Technique
- Goals and Subgoals
- List Processing
- Recursion
- Miscellaneous Functions
- Examples
- Conclusion
<#19#><#19#>
<#21#>Prolog<#21#>
<#38#>gramming in ic<#38#>
- idea emerged in early 1970's;
most work done at Univ.\ of Edinburgh - based on a subset of first-order logic
- feed it theorems and pose queries,
system does the rest
- main uses:
- originally, mainly an AI language
esp.\ expert systems - now finding uses in database systems and even rapid
prototyping systems of industrial software
<#33#><#33#>
<#35#>Logic Programming Framework<#35#>
= cmr10 scaled 2
= cmr10 scaled 3
= cmti10 scaled 2
`@=11
graph@4@unt
graphtemp
`@=12
=<#295#>to0pt<#294#><#293#>=.6ex by 5.95in
<#284#>to 0pt<#269#><#40#>Answer: <#40#><#269#><#284#>=.6ex by 0.34in
<#285#>to 0pt<#270#><#41#>Query: <#41#><#270#><#285#>=.6ex by 2.295in
<#286#>to 0pt<#271#><#89#>Programming Environment <#89#><#271#><#286#>=.6ex by 0.638in
<#287#>to 0pt<#272#><#117#>Is q(X1, ... ,XN) true? <#117#><#272#><#287#>=.6ex by 6.205in
<#288#>to 0pt<#273#><#118#>``Yes/No'' <#118#><#273#><#288#>=.6ex by 6.418in
<#289#>to 0pt<#274#><#119#>& variable bindings <#119#><#274#><#289#>=.6ex by 2.805in
<#290#>to 0pt<#275#><#128#>Knowledge Base: <#128#><#275#><#290#>=.6ex by 3.91in
<#291#>to 0pt<#276#><#129#>Proof Procedure <#129#><#276#><#291#>=.6ex by 3.103in
<#292#>to 0pt<#277#><#130#>Facts & Rules <#130#><#277#><#292#><#293#><#294#><#295#>
<#145#><#145#>
<#147#>Logic and Prolog<#147#>
- Syntax:
--- Horn clauses of <#150#>terms<#150#>
- Proof process: \
- <#153#>unification<#153#> + <#154#>substitution<#154#>:
pattern matching between terms +
binding unresolved variables as needed. - <#155#>automatic backtracking<#155#>:
if one attempt fails, try again until all search paths exhausted.
<#160#><#160#>
<#162#>Prolog Terms<#162#>
BNF:
<#278#>
#tabular164#
<#278#>
Examples:
#tabular174#
<#182#>DEFN:<#182#> \ a is a term with no
variables.
#tabular185#
<#190#><#190#>
<#192#>How Prolog Does Proofs<#192#>
#tabular194#
<#201#><#201#>
<#203#>Prolog's Syntax<#203#>
We would like to have full first-order logic (#tex2html_wrap_inline2312#), but we settle for a subset:
#tex2html_wrap_inline2314# positive Horn clauses.
<#279#>
#tex2html_wrap_inline2316# Horn clause #tex2html_wrap_inline2318# ::= ¯#tex2html_wrap_inline2322# term #tex2html_wrap_inline2324#<#207#>.<#207#>
| #tex2html_wrap_inline2328# term #tex2html_wrap_inline2330# :- #tex2html_wrap_inline2334# term #tex2html_wrap_inline2336# {<#208#>,<#208#>
#tex2html_wrap_inline2338# term #tex2html_wrap_inline2340# }<#209#>.<#209#>
<#279#>
Examples:
<#280#>
- father(john,sue).
- ancestor(odin,X).
- parent(X,Y) :- mother(X,Y).
- grandparent(X,Y) :- parent(X,Z), parent(Z,Y).
<#280#>
<#217#><#217#>
<#281#>Reading Prolog as
Predicate Calculus<#281#>
#tabular221#
Variables are assumed to be quantified by <#230#>#tex2html_wrap_inline2354#<#230#>.
Interpretations of examples:
<#282#>
- father(john,sue)
- #tex2html_wrap_inline2356# X . ancestor(odin,X)
- #tex2html_wrap_inline2358# X, Y . mother(X,Y) #tex2html_wrap_inline2360# parent(X,Y)
- #tex2html_wrap_inline2362# X, Y, Z . ( parent(X,Z) #tex2html_wrap_inline2364# parent(Z,Y) )
#tex2html_wrap_inline2366# grandparent(X,Y)
<#282#>
<#239#><#239#>
<#241#>Horn Clauses vs.\ Predicate Calculus<#241#>
- <#244#>FACT:<#244#> any PC formula can be rewritten in
<#283#><#283#> using only #tex2html_wrap_inline2368# and
#tex2html_wrap_inline2370#.
<#247#>e.g.<#247#>\ <#248#>A #tex2html_wrap_inline2372# B<#248#> equiv.\ to <#249#>#tex2html_wrap_inline2374#<#249#>- <#250#>FACT:<#250#> any clausal form formula can be rewritten into
(Conjunctive Normal Form).
<#253#>e.g.<#253#>\ #tex2html_wrap_inline2376#- are CNF formulas with
exactly one positive literal.
#tabular256#
<#264#><#264#>
<#266#>An Example<#266#>
= cmr10 scaled 2
= cmbx10 scaled 2
`@=11
graph@4@unt
graphtemp
`@=12
=<#479#>to0pt<#478#><#477#>=.6ex by 3.91in
<#452#>to 0pt<#426#><#335#>above(b5,b6) <#335#><#426#><#452#>=.6ex by 1.105in
<#453#>to 0pt<#427#><#374#>(4) \ above(X,Y) :- on(X,Z), above(Z,Y). <#374#><#427#><#453#>=.6ex by 1.148in
<#454#>to 0pt<#428#><#375#>b6 <#375#><#428#><#454#>=.6ex by 0.68in
<#455#>to 0pt<#429#><#376#>b5 <#376#><#429#><#455#>=.6ex by 0.213in
<#456#>to 0pt<#430#><#377#>b4 <#377#><#430#><#456#>=.6ex by 0.595in
<#457#>to 0pt<#431#><#398#>(2) \ on(b5,b6). <#398#><#431#><#457#>=.6ex by 0.34in
<#458#>to 0pt<#432#><#399#>(1) \ on(b4, b5). <#399#><#432#><#458#>=.6ex by 0.468in
<#459#>to 0pt<#433#><#400#>KB: <#400#><#433#><#459#>=.6ex by 2.21in
<#460#>to 0pt<#434#><#401#>Query: <#401#><#434#><#460#>=.6ex by 2.21in
<#461#>to 0pt<#435#><#402#>above(b4,b6) <#402#><#435#><#461#>=.6ex by 3.06in
<#462#>to 0pt<#436#><#403#>on(b4,b6) <#403#><#436#><#462#>=.6ex by 3.91in
<#463#>to 0pt<#437#><#404#>failure <#404#><#437#><#463#>=.6ex by 3.06in
<#464#>to 0pt<#438#><#405#>on(b4,X), above(X,b6) <#405#><#438#><#464#>=.6ex by 4.76in
<#465#>to 0pt<#439#><#406#>on(b5,Y), above(Y,b6) <#406#><#439#><#465#>=.6ex by 4.76in
<#466#>to 0pt<#440#><#407#>on(b5,b6) <#407#><#440#><#466#>=.6ex by 5.61in
<#467#>to 0pt<#441#><#408#>success <#408#><#441#><#467#>=.6ex by 6.035in
<#468#>to 0pt<#442#><#409#>failure <#409#><#442#><#468#>=.6ex by 6.29in
<#469#>to 0pt<#443#><#410#>(eventually) <#410#><#443#><#469#>=.6ex by 2.635in
<#470#>to 0pt<#444#><#411#>(3) <#411#><#444#><#470#>=.6ex by 2.465in
<#471#>to 0pt<#445#><#412#>(4) <#412#><#445#><#471#>=.6ex by 3.4in
<#472#>to 0pt<#446#><#413#>X = b5 <#413#><#446#><#472#>=.6ex by 4.165in
<#473#>to 0pt<#447#><#414#>(4) <#414#><#447#><#473#>=.6ex by 4.25in
<#474#>to 0pt<#448#><#415#>(3) <#415#><#448#><#474#>=.6ex by 5.185in
<#475#>to 0pt<#449#><#416#>(2) <#416#><#449#><#475#>=.6ex by 0.85in
<#476#>to 0pt<#450#><#417#>(3) \ above(X,Y) :- on(X,Y). <#417#><#450#><#476#><#477#><#478#><#479#>
<#421#><#421#>
<#451#><#423#>Example<#423#> (cont'd)<#451#>
Can also have variables in the proof:
= cmr10 scaled 3
`@=11
graph@4@unt
graphtemp
`@=12
=<#952#>to0pt<#951#><#950#>=.6ex by 1.87in
<#945#>to 0pt<#924#><#481#>W = b6 <#481#><#924#><#945#>=.6ex by 0.595in
<#946#>to 0pt<#925#><#482#>(3) <#482#><#925#><#946#>=.6ex by 1.275in
<#947#>to 0pt<#926#><#503#>on(b5,W) <#503#><#926#><#947#>=.6ex by 2.55in
<#948#>to 0pt<#927#><#504#>success <#504#><#927#><#948#>=.6ex
<#949#>to 0pt<#928#><#505#>above(b5,W) <#505#><#928#><#949#><#950#><#951#><#952#>
<#509#><#509#>
<#511#>An Example Prolog Session<#511#>
<#513#>
verbatim1
<#513#>
<#516#><#516#>
<#518#>Substitution<#518#>
A substitution is a set
{#tex2html_wrap_inline2396#}
#tabular524#
Positive Examples:
{#tex2html_wrap_inline2406#}
{#tex2html_wrap_inline2408#}
Negative Examples:
{#tex2html_wrap_inline2410#}
{#tex2html_wrap_inline2412#}
{#tex2html_wrap_inline2414#}
{#tex2html_wrap_inline2416#}
<#538#><#538#>
<#540#>Applying a Substitution<#540#>
#tabular542#
then #tex2html_wrap_inline2422# is the term resulting from performing the substitution
#tex2html_wrap_inline2424# on t.
Examples:
#tabular550#
Let t = f(a,h(Y,b),X)
#tabular555#
Note:
#tex2html_wrap_inline2458# #tex2html_wrap_inline2460# need not include all variables in t.
#tex2html_wrap_inline2464# #tex2html_wrap_inline2466# can include variables not in t.
<#565#><#565#>
<#567#>Composing Substitutions<#567#>
We can compose substitutions
(barring variable name clashes).
If #tex2html_wrap_inline2470# and #tex2html_wrap_inline2472# are substitutions, then so is #tex2html_wrap_inline2474#.
<#569#>DEFN:<#569#> \ For any term t, #tex2html_wrap_inline2478#.
For example,
#tabular573#
Also,
#tabular580#
<#585#><#585#>
<#587#>Unifiers<#587#>
<#589#>DEFN:<#589#> #tex2html_wrap_inline2512# and #tex2html_wrap_inline2514# are by substitution
#tex2html_wrap_inline2516#
iff #tex2html_wrap_inline2518#.
If so, #tex2html_wrap_inline2520# is called a ,
and #tex2html_wrap_inline2522# and #tex2html_wrap_inline2524# are said to be unifiable.
Examples:
<#929#>
#tabular597#
<#929#>
<#623#><#623#>
<#625#>Multiple Unifiers<#625#>
Assume \ \ #tex2html_wrap_inline2536# \ \ and \ \ #tex2html_wrap_inline2538#.
#tabular627#
<#930#><#638#>Q:<#638#> \ Is there a ``best'' unifier?<#930#>
Wish list:
- no irrelevant constants
<#642#>{Y #tex2html_wrap_inline2566# X} preferred over {X #tex2html_wrap_inline2568# a, \ Y #tex2html_wrap_inline2570# a}<#642#>- no irrelevant bindings
<#644#>{Y #tex2html_wrap_inline2572# X} preferred over {Y #tex2html_wrap_inline2574# X, \ W #tex2html_wrap_inline2576# h(q,Z)}<#644#>
<#648#><#648#>
<#650#>In Search of the
``Best'' Unifier<#650#>
Assume #tex2html_wrap_inline2578# and #tex2html_wrap_inline2580# are both unifiers for some pair of terms.
- Suppose #tex2html_wrap_inline2582# has a constant <#654#>where #tex2html_wrap_inline2584# has a<#654#>
variable. Then #tex2html_wrap_inline2586# subst.\ #tex2html_wrap_inline2588# such
that <#655#>#tex2html_wrap_inline2590#<#655#>
<#931#>
<#656#>e.g.<#656#> #tex2html_wrap_inline2592#
then #tex2html_wrap_inline2594#
and #tex2html_wrap_inline2596#
<#931#>
- Suppose #tex2html_wrap_inline2598# has an extra binding over #tex2html_wrap_inline2600#. Then
#tex2html_wrap_inline2602# subst.\ #tex2html_wrap_inline2604# such that <#660#>#tex2html_wrap_inline2606#<#660#>
<#932#>
<#661#>e.g.<#661#> #tex2html_wrap_inline2608#
then #tex2html_wrap_inline2610#
and #tex2html_wrap_inline2612#
<#932#>
<#671#>Moral:<#671#>\+
inferior unifier = better unifier composed
with another subst.
<#675#><#675#>
<#677#>``Most General Unifier'' (MGU)<#677#>
<#679#>DEFN:<#679#> \ #tex2html_wrap_inline2618# is an for #tex2html_wrap_inline2620# and #tex2html_wrap_inline2622# iff
(1) #tex2html_wrap_inline2624# unifies both #tex2html_wrap_inline2626# and #tex2html_wrap_inline2628#, and
(2) #tex2html_wrap_inline2630# subst. #tex2html_wrap_inline2632# that unify #tex2html_wrap_inline2634# and #tex2html_wrap_inline2636#,
#tex2html_wrap_inline2638# subst.\ #tex2html_wrap_inline2640# such that #tex2html_wrap_inline2642#.
<#686#>i.e.<#686#> #tex2html_wrap_inline2644#
and #tex2html_wrap_inline2646#.
Basic idea: \ An mgu has
- no unnec./irrelevant constants
(uses constants only when necessary) - no extraneous bindings
<#694#><#694#>
<#696#>An Example<#696#>
#tex2html_wrap3114#
then #tex2html_wrap_inline2650# is an mgu.
Why?
Consider #tex2html_wrap_inline2652#, another unifier for #tex2html_wrap_inline2654# and #tex2html_wrap_inline2656#.
Then #tex2html_wrap_inline2658# #tex2html_wrap_inline2660# such that #tex2html_wrap_inline2662#.
Note also that #tex2html_wrap_inline2664# and #tex2html_wrap_inline2666# are also mgus for
#tex2html_wrap_inline2668# and #tex2html_wrap_inline2670#.
<#701#><#701#>
<#703#>Another Example<#703#>
#tex2html_wrap_inline2672#
#tex2html_wrap_inline2674#
#tabular711#
so mgu #tex2html_wrap_inline2694# =
<#717#><#717#>
<#719#>More MGU Examples<#719#>
<#933#>
#tabular721#
<#933#>
<#733#><#733#>
<#735#>Prolog's Proof Process<#735#>
<#737#>DEFN:<#737#> A is either a sequence of terms or the
special goal <#739#>success<#739#>.
#tabular740#
<#747#>DEFN:<#747#> #tex2html_wrap_inline2708# is a of #tex2html_wrap_inline2710#
(given a set of true Horn clauses/axioms) iff
- #tex2html_wrap_inline2712# = <#751#>success<#751#>
- #tex2html_wrap_inline2716# is a of #tex2html_wrap_inline2718#, #tex2html_wrap_inline2720#
according to either (I) or (II) below.
<#758#><#758#>
<#760#>Subgoals<#760#>
Given goal <#762#>G<#762#> #tex2html_wrap_inline2722# (#tex2html_wrap_inline2724#s are terms)
- (I)
- If there is an axiom t where t and #tex2html_wrap_inline2730#
have mgu #tex2html_wrap_inline2732#, then
<#934#>#tex2html_wrap_inline2734#<#934#>
is a subgoal of <#769#>G<#769#>.
- (II)
- If there is a rule axiom t :- #tex2html_wrap_inline2740# where t and
#tex2html_wrap_inline2744# have mgu #tex2html_wrap_inline2746#, then
<#935#>#tex2html_wrap_inline2748#<#935#>
is a subgoal of <#773#>G<#773#>.
Restriction: variables of axioms must be <#775#>distinct<#775#> from variables
of subgoals. Must rename if necessary.
This is a lot simpler than it sounds.
<#778#><#778#>
<#780#>Example<#780#>
#tabular782#
Goal: <#791#>above(A,B).<#791#>
Possible subgoals:
- <#793#>on(A,B)<#793#> \ \ #tex2html_wrap_inline2754# = #tex2html_wrap_inline2758#
using rule II, axiom (3)- <#794#>on(A,Z),above(Z,B)<#794#> \ \ #tex2html_wrap_inline2760# = #tex2html_wrap_inline2764#
using rule II, axiom (4)- <#795#>success<#795#> \ \ #tex2html_wrap_inline2766# = #tex2html_wrap_inline2770#
using rule I, axiom (5)
<#799#><#799#>
<#936#>Possible subgoals of
<#802#>on(A,#tex2html_wrap_inline2772#), above(#tex2html_wrap_inline2774#,B)<#802#>:<#936#>
#tex2html_wrap_inline2776# <#805#>on(#tex2html_wrap_inline2778#,B), on(A,#tex2html_wrap_inline2780#)<#805#>12¯¯
#tex2html_wrap_inline2782# <#806#>above(b5,B)<#806#> #tex2html_wrap_inline2784# = #tex2html_wrap_inline2788#
using rule I, axiom (1)
#tex2html_wrap_inline2790# <#808#>above(b6,B)<#808#> #tex2html_wrap_inline2792# = #tex2html_wrap_inline2796#
using rule I, axiom (2)
#tex2html_wrap_inline2798# <#810#>on(A,c1)<#810#> #tex2html_wrap_inline2800# = #tex2html_wrap_inline2804#
using rule I, axiom (5)
#tex2html_wrap_inline2806# <#812#>on(#tex2html_wrap_inline2808#,B), on(A,#tex2html_wrap_inline2810#)<#812#> #tex2html_wrap_inline2812# = #tex2html_wrap_inline2816#
using rule II, axiom (3)
#tex2html_wrap_inline2818# <#814#>on(#tex2html_wrap_inline2820#,Z), above(Z,B), on(A,#tex2html_wrap_inline2822#)<#814#>
#tex2html_wrap_inline2824# = #tex2html_wrap_inline2828#
using rule II, axiom (4)
<#820#><#820#>
<#822#>Lists in Prolog<#822#>
#tabular824#
#tabular829#
Prolog shorthand:
- #tex2html_wrap_inline2844#] #tex2html_wrap_inline2846# (<#840#>list<#840#> #tex2html_wrap_inline2848#)
- #tex2html_wrap_inline2850# | <#841#>L<#841#>] #tex2html_wrap_inline2854# (<#842#>cons<#842#> #tex2html_wrap_inline2856# \ (<#843#>cons<#843#>
#tex2html_wrap_inline2858#
(<#845#>cons #tex2html_wrap_inline2860# L<#845#>) #tex2html_wrap_inline2862#)
<#938#>
#tabular849#
<#938#>
<#855#><#855#>
<#857#>List Membership<#857#>
Prolog uses , not functions. Want to define a
two-place predicate
<#861#>member(X,Y)<#861#>
that holds iff <#862#>X<#862#> is a member of list <#863#>Y<#863#>.
Solution:
verbatim2
Interpretation: - <#868#>X<#868#> is a member of any list of which it is the first element.
- If <#870#>X<#870#> is a member of list <#871#>Y<#871#>, then <#872#>X<#872#> is a member
of any list that has <#873#>Y<#873#> as its <#874#>cdr.<#874#>
<#878#><#878#>
<#880#>An Example<#880#>
verbatim3
<#884#><#884#>
<#886#>
Inductive Reasoning
<#886#>
- <#889#>Identify Base Cases
Handled directly as facts
Simple solution, e.g null<#889#> - <#890#>Identify Decomposition
Reduce General Case to simpler
sub cases<#890#> - <#891#>Identify Composition
Compose solution of Subcases to
solution of original general case<#891#>
<#895#><#895#>
<#897#>
Example - member
<#897#>
- <#939#>Desired, <#900#>member( X , Y ) <#900#>
succeeds if X is a member of list Y<#939#> - <#940#>Base case:
X is at head of list Y
Tmember( X , [X,Y] ).<#940#>- <#941#>Induction case:
X is member of rest of Y except head
Tmember( X, [Z,Y] ) :- member( X, Y).<#941#>- <#903#>Order of axioms matters.<#903#>
<#907#><#907#>
<#909#>
Example - Append
<#909#>
- <#942#>Desired: <#912#>append(X,Y,Z)<#912#>
Z is result of appending X onto Y<#942#> - <#943#>Base case:
Append empty list onto Y
Tappend( [], Y, Y ).<#943#>- <#914#>Decomposition:
Process head of X
Process rest of X
Reduce length of X<#914#> - <#915#>Composition:
Add to head of Z<#915#> - <#944#>Solution:
Tappend([E|X],Y,[E|Z]):-append(X,Y,Z).<#944#>
<#920#><#920#>
<#922#>An Example<#922#>
= cmr10 scaled 2
= cmr10 scaled 4
`@=11
graph@4@unt
graphtemp
`@=12
=<#1054#>to0pt<#1053#><#1052#>=.6ex by 4.048in
<#1035#>to 0pt<#1017#><#954#>append([ ],[c,d],#tex2html_wrap_inline2876#) <#954#><#1017#><#1035#>=.6ex by 5.023in
<#1036#>to 0pt<#1018#><#955#>(1) <#955#><#1018#><#1036#>=.6ex
<#1037#>to 0pt<#1019#><#956#>append([a,b],[c,d],V) <#956#><#1019#><#1037#>=.6ex by 2.699in
<#1038#>to 0pt<#1020#><#968#>#tex2html_wrap_inline2878# <#968#><#1020#><#1038#>=.6ex by 3.374in
<#1039#>to 0pt<#1021#><#969#>#tex2html_wrap_inline2880# <#969#><#1021#><#1039#>=.6ex by 2.699in
<#1040#>to 0pt<#1022#><#970#>#tex2html_wrap_inline2882# <#970#><#1022#><#1040#>=.6ex by 3.374in
<#1041#>to 0pt<#1023#><#971#>#tex2html_wrap_inline2884# <#971#><#1023#><#1041#>=.6ex by 2.924in
<#1042#>to 0pt<#1024#><#972#>(2) <#972#><#1024#><#1042#>=.6ex by 1.949in
<#1043#>to 0pt<#1025#><#973#>append([b],[c,d],#tex2html_wrap_inline2886#) <#973#><#1025#><#1043#>=.6ex by 5.323in
<#1044#>to 0pt<#1026#><#985#>#tex2html_wrap_inline2888# <#985#><#1026#><#1044#>=.6ex by 4.873in
<#1045#>to 0pt<#1027#><#986#>#tex2html_wrap_inline2890# <#986#><#1027#><#1045#>=.6ex by 5.923in
<#1046#>to 0pt<#1028#><#998#>success <#998#><#1028#><#1046#>=.6ex by 1.125in
<#1047#>to 0pt<#1029#><#999#>#tex2html_wrap_inline2892# <#999#><#1029#><#1047#>=.6ex by 1.125in
<#1048#>to 0pt<#1030#><#1000#>#tex2html_wrap_inline2894# <#1000#><#1030#><#1048#>=.6ex by 0.675in
<#1049#>to 0pt<#1031#><#1001#>#tex2html_wrap_inline2896# <#1001#><#1031#><#1049#>=.6ex by 0.675in
<#1050#>to 0pt<#1032#><#1002#>#tex2html_wrap_inline2898# <#1002#><#1032#><#1050#>=.6ex by 0.9in
<#1051#>to 0pt<#1033#><#1003#>(2) <#1003#><#1033#><#1051#><#1052#><#1053#><#1054#>
<#1034#>
#tabular1007#
<#1034#>
<#1012#><#1012#>
<#1014#>More Examples<#1014#>
= cmr10 scaled 2
= cmr10 scaled 3
= cmr10 scaled 4
`@=11
graph@4@unt
graphtemp
`@=12
=<#1141#>to0pt<#1140#><#1139#>=.6ex by 1.125in
<#1124#>to 0pt<#1109#><#1056#>#tex2html_wrap_inline2918# <#1056#><#1109#><#1124#>=.6ex by 3.374in
<#1125#>to 0pt<#1110#><#1057#>#tex2html_wrap_inline2920# <#1057#><#1110#><#1125#>=.6ex by 2.699in
<#1126#>to 0pt<#1111#><#1058#>#tex2html_wrap_inline2922# <#1058#><#1111#><#1126#>=.6ex by 3.374in
<#1127#>to 0pt<#1112#><#1059#>#tex2html_wrap_inline2924# <#1059#><#1112#><#1127#>=.6ex by 1.125in
<#1128#>to 0pt<#1113#><#1060#>#tex2html_wrap_inline2926# <#1060#><#1113#><#1128#>=.6ex by 0.675in
<#1129#>to 0pt<#1114#><#1061#>#tex2html_wrap_inline2928# <#1061#><#1114#><#1129#>=.6ex by 5.923in
<#1130#>to 0pt<#1115#><#1062#>failure <#1062#><#1115#><#1130#>=.6ex by 5.098in
<#1131#>to 0pt<#1116#><#1063#>No possible unification. <#1063#><#1116#><#1131#>=.6ex by 4.049in
<#1132#>to 0pt<#1117#><#1064#>append([ ],[c],[c,d]) <#1064#><#1117#><#1132#>=.6ex by 1.949in
<#1133#>to 0pt<#1118#><#1065#>append([b],[c],[b,c,d]) <#1065#><#1118#><#1133#>=.6ex
<#1134#>to 0pt<#1119#><#1066#>append([a,b],[c],[a,b,c,d]) <#1066#><#1119#><#1134#>=.6ex by 0.9in
<#1135#>to 0pt<#1120#><#1067#>(2) <#1067#><#1120#><#1135#>=.6ex by 0.675in
<#1136#>to 0pt<#1121#><#1068#>#tex2html_wrap_inline2930# <#1068#><#1121#><#1136#>=.6ex by 2.924in
<#1137#>to 0pt<#1122#><#1089#>(2) <#1089#><#1122#><#1137#>=.6ex by 2.699in
<#1138#>to 0pt<#1123#><#1090#>#tex2html_wrap_inline2932# <#1090#><#1123#><#1138#><#1139#><#1140#><#1141#>
<#1104#><#1104#>
<#1106#>More Examples<#1106#>
= cmr10 scaled 2
= cmr10 scaled 4
`@=11
graph@4@unt
graphtemp
`@=12
=<#1338#>to0pt<#1337#><#1336#>=.6ex by 4.723in
<#1324#>to 0pt<#1305#><#1143#>#tex2html_wrap_inline2934# <#1143#><#1305#><#1324#>=.6ex by 1.2in
<#1325#>to 0pt<#1306#><#1144#>#tex2html_wrap_inline2936# <#1144#><#1306#><#1325#>=.6ex by 0.6in
<#1326#>to 0pt<#1307#><#1145#>#tex2html_wrap_inline2938# <#1145#><#1307#><#1326#>=.6ex by 1.2in
<#1327#>to 0pt<#1308#><#1146#>#tex2html_wrap_inline2940# <#1146#><#1308#><#1327#>=.6ex by 0.6in
<#1328#>to 0pt<#1309#><#1147#>#tex2html_wrap_inline2942# <#1147#><#1309#><#1328#>=.6ex by 2.924in
<#1329#>to 0pt<#1310#><#1148#>#tex2html_wrap_inline2944# <#1148#><#1310#><#1329#>=.6ex by 2.924in
<#1330#>to 0pt<#1311#><#1149#>(1) <#1149#><#1311#><#1330#>=.6ex by 3.974in
<#1331#>to 0pt<#1312#><#1150#>success <#1150#><#1312#><#1331#>=.6ex by 4.049in
<#1332#>to 0pt<#1313#><#1151#><#1151#><#1313#><#1332#>=.6ex by 1.949in
<#1333#>to 0pt<#1314#><#1152#>append([ ],#tex2html_wrap_inline2946#,[b,c]) <#1152#><#1314#><#1333#>=.6ex
<#1334#>to 0pt<#1315#><#1153#>append([a,b],W,[a,b,c]) <#1153#><#1315#><#1334#>=.6ex by 0.9in
<#1335#>to 0pt<#1316#><#1174#>(2) <#1174#><#1316#><#1335#><#1336#><#1337#><#1338#>
Similarly,
<#1180#>append(D,[c,d],[a,b,c,d])<#1180#>
succeeds with <#1182#>D = [a,b]<#1182#>.
<#1185#><#1185#>
<#1187#>
Example - Reverse a List
<#1187#>
- <#1317#>Desired <#1190#>rev( L , M )<#1190#>
where the list M is the result of reversing the order of
the list L<#1317#> - <#1191#>Solution without helping functions<#1191#>
- <#1318#>Base case:
Reverse empty list
Trev( [], [] ).<#1318#>- <#1319#>Induction case:
Append head of L to tail of output
Trev([H,T],M) :- rev(T,Z),append(Z,[H],M).<#1319#>
<#1197#><#1197#>
<#1199#>
Using Helping Functions
<#1199#>
- <#1320#>One common technique is to design <#1202#>helping functions<#1202#>
that do the real work of generating the desired results.<#1320#>
- <#1203#>Use extra parameters to helping functions to hold intermediate
values or partial results.<#1203#>
- <#1204#>Use extra parameters to preserve original input for subesquent
processing or second pass.<#1204#>
- <#1321#>Example:
Tdoit(X,Y) :- realDoIt(X,Y,Y,[]).<#1321#>
<#1209#><#1209#>
<#1211#>
Example - Reverse a List
<#1211#>
- <#1214#>Use helping function to hold partial result<#1214#>
- <#1322#>Base case:
Start with empty output list
Trev2(L1,L2) :- revzap(L1,[],L2).<#1322#>- <#1323#>Induction case:
Accumulate results so far in 2nd arg
of revzap
Trevzap([],L,L).
Trevzap([X,L],L2,L3):-revzap(L,[X,L2],L3).<#1323#>
<#1221#><#1221#>
<#1223#>Equality in Lists<#1223#>
The predicate for equality of lists is trivial:
<#1226#>equal(X,X).<#1226#>
Unification does all the work!
Note that <#1227#>equal(#tex2html_wrap_inline2950#)<#1227#> succeeds if #tex2html_wrap_inline2952# and #tex2html_wrap_inline2954# are merely
unifiable:
1 \ \ #tex2html_wrap_inline2956# \ \ success + 2
<#1231#><#1231#>
<#1233#>List Membership<#1233#>
Recall:
verbatim4
We can rewrite this as:
verbatim5
``_'' is a special Prolog term that will unify with .
We use ``_'' instead of a more normal variable name to emphasize that we
don't care what it unifies with.
Each occurrence may unify to something <#1236#>different!<#1236#>
<#1239#><#1239#>
<#1241#>Negation as Failure<#1241#>
Consider the intersection predicate for lists:
verbatim6
Problem: How to define <#1248#>nonmember<#1248#>.
#tex2html_wrap_inline2960# need negation.
verbatim7
<#1250#>not<#1250#> is a special function symbol:
#displaymath2232#
Example: \ \ 3
will succeed with 4.
<#1271#><#1271#>
<#1273#>An Extended Example<#1273#>
We will represent the natural numbers as
Prolog terms:
#tabular1275#
#tabular1280#
[Prolog have numbers, but we ignore them for now.]
<#1289#><#1289#>
<#1291#>Addition Predicate<#1291#>
Want to define <#1293#>sum<#1293#>:
<#1295#>sum(X,Y,Z)<#1295#> holds iff <#1296#>X + Y = Z<#1296#>.
Solution:
verbatim8
<#1300#><#1300#>
<#1302#>An Example<#1302#>
= cmr10 scaled
= cmr10 scaled 2
= cmr10 scaled 4
`@=11
graph@4@unt
graphtemp
`@=12
=<#1434#>to0pt<#1433#><#1432#>=.6ex by 4.158in
<#1417#>to 0pt<#1401#><#1340#>#tex2html_wrap_inline2974# <#1340#><#1401#><#1417#>=.6ex by 5.782in
<#1418#>to 0pt<#1402#><#1341#>#tex2html_wrap_inline2976# Total = s(s(s(s(s(0))))) <#1341#><#1402#><#1418#>=.6ex by 2.988in
<#1419#>to 0pt<#1403#><#1342#>#tex2html_wrap_inline2980# <#1342#><#1403#><#1419#>=.6ex by 2.209in
<#1420#>to 0pt<#1404#><#1343#>#tex2html_wrap_inline2982# <#1343#><#1404#><#1420#>=.6ex by 3.443in
<#1421#>to 0pt<#1405#><#1344#>sum(0,s(s(s(0))),#tex2html_wrap_inline2984#) <#1344#><#1405#><#1421#>=.6ex by 1.689in
<#1422#>to 0pt<#1406#><#1345#>sum(s(0),s(s(s(0))),Z) <#1345#><#1406#><#1422#>=.6ex
<#1423#>to 0pt<#1407#><#1346#>sum(s(s(0)),s(s(s(0))),Total) <#1346#><#1407#><#1423#>=.6ex by 0.78in
<#1424#>to 0pt<#1408#><#1347#>(2) <#1347#><#1408#><#1424#>=.6ex by 5.132in
<#1425#>to 0pt<#1409#><#1348#>success <#1348#><#1409#><#1425#>=.6ex by 2.534in
<#1426#>to 0pt<#1410#><#1369#>(2) <#1369#><#1410#><#1426#>=.6ex by 4.353in
<#1427#>to 0pt<#1411#><#1381#>(1) <#1381#><#1411#><#1427#>=.6ex by 2.599in
<#1428#>to 0pt<#1412#><#1382#>#tex2html_wrap_inline2986# <#1382#><#1412#><#1428#>=.6ex by 1.169in
<#1429#>to 0pt<#1413#><#1383#>Y = s(s(s(0))) <#1383#><#1413#><#1429#>=.6ex by 0.39in
<#1430#>to 0pt<#1414#><#1384#>Total = s(Z) <#1384#><#1414#><#1430#>=.6ex by 0.78in
<#1431#>to 0pt<#1415#><#1385#>X = s(0) <#1385#><#1415#><#1431#><#1432#><#1433#><#1434#>
<#1389#><#1389#>
<#1391#>Another Example<#1391#>
Notation: #tex2html_wrap_inline2994# #tex2html_wrap_inline2996# #tex2html_wrap_inline2998#
= cmr10 scaled
= cmr10 scaled 4
`@=11
graph@4@unt
graphtemp
`@=12
=<#1527#>to0pt<#1526#><#1525#>=.6ex by 4.158in
<#1504#>to 0pt<#1490#><#1436#>No unification possible. <#1436#><#1490#><#1504#>=.6ex by 2.209in
<#1505#>to 0pt<#1491#><#1437#>#tex2html_wrap_inline3000# <#1437#><#1491#><#1505#>=.6ex by 2.989in
<#1518#>to 0pt<#1506#><#1492#>#tex2html_wrap_inline3002# <#1492#><#1506#><#1518#>=.6ex by 2.599in
<#1519#>to 0pt<#1507#><#1493#>#tex2html_wrap_inline3004# <#1493#><#1507#><#1519#>=.6ex by 0.39in
<#1520#>to 0pt<#1508#><#1494#>#tex2html_wrap_inline3006# <#1494#><#1508#><#1520#>=.6ex by 1.169in
<#1521#>to 0pt<#1509#><#1495#>#tex2html_wrap_inline3008# <#1495#><#1509#><#1521#>=.6ex by 5.782in
<#1524#>to 0pt<#1522#><#1510#>#tex2html_wrap_inline3010# <#1496#>sum(#tex2html_wrap_inline3012#)<#1496#> fails <#1510#><#1522#><#1524#>=.6ex by 0.78in
<#1523#>to 0pt<#1511#><#1497#>#tex2html_wrap_inline3014# <#1497#><#1511#><#1523#>=.6ex by 5.133in
<#1512#>to 0pt<#1498#><#1446#>failure <#1446#><#1498#><#1512#>=.6ex by 3.443in
<#1513#>to 0pt<#1499#><#1447#>sum(0,s(s(s(0))),s(s(0))) <#1447#><#1499#><#1513#>=.6ex by 1.689in
<#1514#>to 0pt<#1500#><#1448#>sum(s(0),s(s(s(0))),s(s(s(0)))) <#1448#><#1500#><#1514#>=.6ex
<#1515#>to 0pt<#1501#><#1449#>sum(s(s(0)),s(s(s(0))),s(s(s(s(0))))) <#1449#><#1501#><#1515#>=.6ex by 2.534in
<#1516#>to 0pt<#1502#><#1461#>(2) <#1461#><#1502#><#1516#>=.6ex by 0.78in
<#1517#>to 0pt<#1503#><#1482#>(2) <#1482#><#1503#><#1517#><#1525#><#1526#><#1527#>
<#1486#><#1486#>
<#1488#>Addition as Subtraction<#1488#>
= cmr10 scaled
= cmr10 scaled 4
`@=11
graph@4@unt
graphtemp
`@=12
=<#1604#>to0pt<#1603#><#1602#>=.6ex by 0.78in
<#1586#>to 0pt<#1575#><#1529#>Y = W <#1529#><#1575#><#1586#>=.6ex by 3.508in
<#1601#>to 0pt<#1596#><#1587#>#tex2html_wrap_inline3018# <#1576#>W = #tex2html_wrap_inline3020#<#1576#> <#1587#><#1596#><#1601#>=.6ex by 1.689in
<#1597#>to 0pt<#1588#><#1577#>sum(#tex2html_wrap_inline3022#) <#1577#><#1588#><#1597#>=.6ex
<#1598#>to 0pt<#1589#><#1578#>sum(#tex2html_wrap_inline3024#) <#1578#><#1589#><#1598#>=.6ex by 2.534in
<#1590#>to 0pt<#1579#><#1535#>(1) <#1535#><#1579#><#1590#>=.6ex by 3.508in
<#1591#>to 0pt<#1580#><#1536#>success <#1536#><#1580#><#1591#>=.6ex by 2.599in
<#1599#>to 0pt<#1592#><#1581#>#tex2html_wrap_inline3026# <#1581#><#1592#><#1599#>=.6ex by 1.169in
<#1600#>to 0pt<#1593#><#1582#>#tex2html_wrap_inline3028# <#1582#><#1593#><#1600#>=.6ex by 0.39in
<#1594#>to 0pt<#1583#><#1539#>X = 0 <#1539#><#1583#><#1594#>=.6ex by 0.78in
<#1595#>to 0pt<#1584#><#1560#>(2) <#1560#><#1584#><#1595#><#1602#><#1603#><#1604#>
Similarly, <#1585#>sum(D,#tex2html_wrap_inline3032# \ D =
#tex2html_wrap_inline3036#<#1585#>
#tex2html_wrap_inline3038# can define subtraction via one axiom:
5
<#1568#>diff(X,Y,Z)<#1568#> holds iff X-Y=Z.
<#1571#><#1571#>
<#1573#>Creative Use of Variables<#1573#>
= cmr10
= cmr10 scaled 2
= cmr10 scaled 3
= cmti10 scaled 2
`@=11
graph@4@unt
graphtemp
`@=12
=<#2229#>to0pt<#2228#><#2227#>=.6ex by 3.3in
<#2191#>to 0pt<#2143#><#1606#>#tex2html_wrap_inline3042# <#1606#><#2143#><#2191#>=.6ex by 4.08in
<#2192#>to 0pt<#2144#><#1607#>#tex2html_wrap_inline3044# <#1607#><#2144#><#2192#>=.6ex by 0.3in
<#2193#>to 0pt<#2145#><#1608#>A = s(X) <#1608#><#2145#><#2193#>=.6ex by 1.02in
<#2219#>to 0pt<#2194#><#2146#>#tex2html_wrap_inline3048# <#2146#><#2194#><#2219#>=.6ex by 0.84in
<#2220#>to 0pt<#2195#><#2147#>#tex2html_wrap_inline3050# <#2147#><#2195#><#2220#>=.6ex by 1.5in
<#2196#>to 0pt<#2148#><#1621#>success <#1621#><#2148#><#2196#>=.6ex by 1.74in
<#2221#>to 0pt<#2197#><#2149#>#tex2html_wrap_inline3052# <#2149#><#2197#><#2221#>=.6ex by 2.16in
<#2198#>to 0pt<#2150#><#1623#>X = 0 <#1623#><#2150#><#2198#>=.6ex by 2.4in
<#2222#>to 0pt<#2199#><#2151#>#tex2html_wrap_inline3056# <#2151#><#2199#><#2222#>=.6ex by 3.72in
<#2200#>to 0pt<#2152#><#1626#>#tex2html_wrap_inline3058# <#1626#><#2152#><#2200#>=.6ex by 2.58in
<#2201#>to 0pt<#2153#><#1627#>Z = 0 <#1627#><#2153#><#2201#>=.6ex by 1.86in
<#2202#>to 0pt<#2154#><#1628#>#tex2html_wrap_inline3062# <#1628#><#2154#><#2202#>=.6ex by 0.48in
<#2203#>to 0pt<#2155#><#1630#>(1) <#1630#><#2155#><#2203#>=.6ex by 2.22in
<#2204#>to 0pt<#2156#><#1631#>(2) <#1631#><#2156#><#2204#>=.6ex by 2.22in
<#2205#>to 0pt<#2157#><#1633#>#tex2html_wrap_inline3064# <#1633#><#2157#><#2205#>=.6ex by 1.92in
<#2206#>to 0pt<#2158#><#1635#>(1) <#1635#><#2158#><#2206#>=.6ex by 0.66in
<#2207#>to 0pt<#2159#><#1636#>(2) <#1636#><#2159#><#2207#>=.6ex by 0.66in
<#2208#>to 0pt<#2160#><#1638#>B = Y <#1638#><#2160#><#2208#>=.6ex by 3.3in
<#2223#>to 0pt<#2209#><#2161#>#tex2html_wrap_inline3068# <#2161#><#2209#><#2223#>=.6ex by 2.94in
<#2210#>to 0pt<#2162#><#1669#>success <#1669#><#2162#><#2210#>=.6ex by 3in
<#2211#>to 0pt<#2163#><#1670#>sum(#tex2html_wrap_inline3070#) <#1670#><#2163#><#2211#>=.6ex by 3.9in
<#2212#>to 0pt<#2164#><#1671#>(1) <#1671#><#2164#><#2212#>=.6ex by 4.44in
<#2213#>to 0pt<#2165#><#1672#>success <#1672#><#2165#><#2213#>=.6ex by 4.8in
<#2224#>to 0pt<#2214#><#2166#>#tex2html_wrap_inline3072# <#2166#><#2214#><#2224#>=.6ex
<#2225#>to 0pt<#2215#><#2167#>sum(A,B,#tex2html_wrap_inline3074#) <#2167#><#2215#><#2225#>=.6ex by 1.5in
<#2226#>to 0pt<#2216#><#2168#>sum(X,Y,#tex2html_wrap_inline3076#) <#2168#><#2216#><#2226#><#2227#><#2228#><#2229#>
Similarly, <#2169#>sum(A,B,#tex2html_wrap_inline3078#)<#2169#> succeeds with
#tabular1691#
<#1701#><#1701#>
<#1703#>
Assignment and Arithmetic
<#1703#>
#tabular1705#
<#1710#><#1710#>
<#1712#>
Arithmetic Compare
<#1712#>
Arithmetic Comparisons apply to <#1714#>numbers<#1714#> only.
Use arithmetic comparisons as goals in terms.
#tabular1715#
<#1720#><#1720#>
<#1722#>
Term Comparisons in Prolg<#1722#>
- <#2171#>Term comparisons in Prolog are used to compare and
order <#1725#>terms<#1725#>. Comparisons do not cause variables to
be instantiated.<#2171#>
- <#1726#>Comparison predicates succeeed or fail. No side effects,
substitutions or error conditions.<#1726#>
- <#1727#>Don't use predicates described below when you want
arithmetic comparison or unification.<#1727#>
<#1731#><#1731#>
<#1733#>
Comparison Predicates
<#1733#>
#tabular1735#
<#1740#><#1740#>
<#1742#>
compare predicate
<#1742#>
- <#2172#>compare( <#1746#>Op<#1746#> , <#1747#>T1<#1747#>, <#1748#>T2<#1748#> )<#2172#>
- <#2173#>Succeeds if the result of comparing <#1754#>T1<#1754#> and <#1755#>T2<#1755#> is
<#1756#>Op<#1756#><#2173#>
- <#2174#><#1757#>Op<#1757#> is one of 25<#2174#>
<#1761#><#1761#>
<#1763#>Special Tool: The Cut Symbol ``!''<#1763#>
In general,verbatim9
May have to try <#1766#>Q<#1766#> twice.
Solution: The cut symbol ``!''
verbatim10
Behaviour:- if <#1772#>Q<#1772#> succeeds, then <#1773#>P<#1773#> succeeds if
<#1775#>R<#1775#> and <#1776#>S<#1776#> succeed. <#1777#>T<#1777#> and <#1778#>U<#1778#> will never be
attempted even if <#1779#>R<#1779#> or <#1780#>S<#1780#> cannot be satisfied.
- if <#1782#>Q<#1782#> fails, only then will <#1783#>R<#1783#> and <#1784#>S<#1784#> be
attempted.
<#1788#><#1788#>
<#1790#>More on the Cut<#1790#>
- ``!'' always succeeds; it has the side-effect of committing Prolog to
the current rule and the current set of choices for variable
values. Effectively, the cut creates a that the
system is not allowed to back up beyond.
- <#1794#>e.g.<#1794#>\ 26
Prolog can backtrack as much as its likes in attempting to satisfy
<#1795#>B, C<#1795#> and <#1796#>D<#1796#>, but once <#1797#>D<#1797#> has been satisfied, it may
backtrack beyond the cut. However, it
backtrack over <#1800#>E, F<#1800#> and <#1801#>G<#1801#> as much as it
likes in attempting to satisfy them.
<#1805#><#1805#>
- effectively, the ``!'' indicates that if you get this far, then
you've made the only correct choice, and you succeed or fail with
that choice. You may not back up in this rule, or use any other
rule for the same goal.
- Thus,
verbatim11
behaves like 27 <#1807#>if<#1807#> 28 <#1808#>then<#1808#> 29 <#1809#>else<#1809#> 30
<#1813#><#1813#>
<#1815#>Examples<#1815#>
- The cut is often used with the special term <#1818#>fail<#1818#> (that always
fails) to indicate that a goal cannot be satisfied.
<#1819#>e.g.<#1819#>\ can define <#1820#>not<#1820#> ourselves:verbatim12If <#1823#>G<#1823#> succeeds, the commit to failure;
otherwise succeed.
-
verbatim13
if the first clause succeeds, then on <#1832#>failure<#1832#> (later on),
we know we don't have to <#1833#>examine<#1833#> the rest of the list.
List membership is <#1834#>decided<#1834#> once and for all if we satisfy
the first rule.
<#1838#><#1838#>
<#1840#>Examples<#1840#>
- <#1845#>``Everyone has two parents, except Adam and Eve who have none.''<#1845#>
First attempt:
<#1847#>
verbatim14
<#1847#>
What happened? The last query unified with (3), but not (2) so the cut was
not encountered.
<#1851#><#1851#>
Better Solution:
verbatim15
Note that the order is important: cannot
interchange (1) and (3).
<#1852#>Moral:<#1852#>\ be careful how you use cuts.
verbatim16
Exercise: Rewrite axioms so that it also
returns 31.
<#1858#><#1858#>
<#1860#>Assert, Retract and Abolish<#1860#>
These are special Prolog predicates with side-effect --- they allow clauses
to be added and deleted from the current KB.
- <#1863#>assert(C), asserta(C), assertz(C)<#1863#>
the clause <#1864#>C<#1864#> is added somewhere / at the beginning / at the
end of the KB. - <#1865#>retract C<#1865#>
the first clause in the KB that unifies with <#1866#>C<#1866#> is deleted. - <#1867#>abolish(C,N)<#1867#>
remove all instances of clause <#1868#>C<#1868#> with <#2175#>arity <#1869#>N<#1869#><#2175#>.
<#1870#>abolish<#1870#> is often used to wipe out all
instances of a
temporary variable.
<#1874#><#1874#>
<#1876#>Examples<#1876#>
<#1879#>
verbatim17
<#1879#>
<#2218#>
- 32 wipes out (4), (5).
33 wipes out (1), (2), (3).
<#1884#>[Assuming all axioms are still there:]<#1884#>
- 34 wipes out (1) on the first call, (2) on the
second and (3) on the third.
- 35 wipes out (5).
- 36 wipes out (6) on the first call
and returns <#1886#>Z<#1886#> = <#1887#>harry<#1887#> and <#1888#>Y<#1888#> = <#1889#>true<#1889#>.
On the second call it wipes out (7) and returns
<#1890#>Z<#1890#> = <#1891#>_23<#1891#> and
<#1892#>Y<#1892#> = <#2176#><#1893#>player(_12), player(_6), player(_9)<#1893#>.<#2176#>
<#2218#>
<#1897#><#1897#>
<#1899#>Another Example<#1899#>
<#1901#>
verbatim18
<#1901#>
Note that <#1903#>big(fred)<#1903#> can be satisfied in 6 ways!
So we introduce:
<#1905#>bigamist(X) :- big(X), not(injail(X)),<#1905#>
<#1908#>assert(injail(X)).<#1908#>
<#1909#>
verbatim19
<#1909#>
<#1912#><#1912#>
<#1914#>
Clause
<#1914#>
- <#1918#>clause ( LHS , RHS )<#1918#>
- <#2177#><#1924#>clause<#1924#> searches the Prolog Knowledge Base for
a clause of the form:
\
LHS :- RHS<#2177#> - <#1925#>Relation symbol of LHS must be a constant, but it can contain
other variables (which may get instantiated).<#1925#>
<#1929#><#1929#>
<#1931#>
Clause Example
<#1931#>
verbatim20
<#1935#><#1935#>
<#1937#>
Executing Data
<#1937#>
- <#2178#><#1941#>Term<#1941#> 37 [ <#1942#>Functor<#1942#> 38 <#1943#>Arglist<#1943#> ] <#2178#>
- <#2179#>The 39 operator (pronounced ;SPMquot;univ;SPMquot;) transforms a list into a
<#1949#>functor<#1949#><#2179#>
- <#2180#><#1950#>Term<#1950#> is any prolog term.
<#1951#>Functor<#1951#> is its functor, and
<#1952#>Arglist<#1952#> is its argument list
<#2180#> - <#1953#>40 fails if operands are not properly instantiated<#1953#>
<#1957#><#1957#>
<#1959#>
41 Example<#1959#>
verbatim21
<#1963#><#1963#>
<#1965#>
Improving Efficiency by Helping Functions
<#1965#>
- <#2181#>Compute Fibonacci numbers
Fib(1) <#1968#>=<#1968#> 1
Fib(2) <#1969#>=<#1969#> 1
Fib(N) <#1970#>=<#1970#> Fib(N-1) + Fib(N-2)<#2181#> - <#1971#>Naive Algorithm using Definition<#1971#>
verbatim22
<#1975#><#1975#>
<#1977#>
Naive Fibonnaci Analysis
<#1977#>
- <#1980#>Naive solution wastes effort by repeating
parts of the computation<#1980#>
<#1985#><#1985#>
<#2182#>
Use <#1987#>assert<#1987#> to Save Effort
<#2182#>
- <#1990#>When each Fibonnaci Number is
computed add it as a fact to the knowledge base.<#1990#>
verbatim23
<#1994#><#1994#>
<#2183#>
Using <#1996#>assert<#1996#> to Save Effort
<#2183#>
- <#1999#>For a call of fib(N,F) all Fibonnaci numbers
upto N will become facts in the knowledge base.<#1999#>
- <#2000#>The second recursive call in the definition will
always succeed imediately because its results has been
asserted in the knowledge base by the first recursive call.<#2000#>
<#2005#><#2005#>
<#2007#>
Use Helping Function for Efficiency
<#2007#>
- <#2010#>Avoid recursive computation by computing
Fibonnaci numbers in the forward direction.<#2010#>
verbatim24
<#2015#><#2015#>
<#2017#>A Bigger Example: Sorting<#2017#>
Declarative approach:
42
<#2021#>i.e.<#2021#> <#2022#>Y<#2022#> is the sorted version of <#2023#>X<#2023#> if <#2024#>Y<#2024#> is a
permutation of <#2025#>X<#2025#> and <#2026#>Y<#2026#> is ordered.
<#2027#>permute<#2027#> and <#2028#>ordered<#2028#> are not difficult to
define, but <#2029#>ordered<#2029#> will depend of the type
list element.
However, this is a terrible way to sort.
A list with n elements has n! permutations, and each of them will be
tried until one is found to be ordered.
<#2032#><#2032#>
<#2034#>
Sorting Lists
<#2034#>
- <#2037#>Common Operation for Organizing Data<#2037#>
- <#2038#>Could use builtin list sorting primitives in
Prolog. We'll look at how to do it directly.<#2038#>
- <#2184#>Assume that there is an ordering relation:
Tgt(X,Y)
for whatever data type we want to sort.
Also assume non-empty lists.<#2184#>- <#2040#>Look at several alternatives:
bubble sort
insertion sort
quick sort
<#2040#>
<#2044#><#2044#>
<#2046#>
Basic Bubble Sort
<#2046#>
Algorithm: swap adjacent elements in the list until
all items are in order
verbatim25
<#2050#><#2050#>
<#2052#>
Insertion Sort
<#2052#>
- <#2185#>To sort a non-empty list <#2055#>L = [X|T]<#2055#>
- <#2057#>Sort the tail T of L<#2057#>
- <#2058#>Insert the head X into the sorted tail such that
the resulting list is sorted<#2058#>
<#2185#>
verbatim26
<#2063#><#2063#>
<#2065#>
Quicksort
<#2065#>
To sort a non-empty list L:
- <#2186#>Select some element X from L as a <#2069#>pivot<#2069#><#2186#>
- <#2070#>Split the rest of L into two lists (Small and Big)
such that all elements of L greater than X are in Big and
all the rest are in Small<#2070#>
- <#2071#>Sort Small to obtain SortedSmall
Sort Big to obtain SortedBig<#2071#> - <#2187#>The whole sorted list is the concatenation of
SortedSmall
and <#2072#>[ X | SortedBig ]<#2072#><#2187#>
<#2076#><#2076#>
<#2078#>
Quicksort Algorithm
<#2078#>
verbatim27
<#2082#><#2082#>
<#2084#>
More Efficient List Concatenation
<#2084#>
- <#2087#>Naive list concatenation:
verbatim28
<#2087#>- <#2088#>This is very inefficient when first list is long.
Recurs down first list until it is empty.
Could do better if we could efficiently find end of
first list.<#2088#> - <#2188#>Change representation of lists to represent a list as
a pair of lists.
A <#2089#>Difference List<#2089#> represents a list L and a
difference of two lists L1 and L2, written as L1-L2<#2188#>
<#2093#><#2093#>
<#2095#>
Difference List Example
<#2095#>
verbatim29
<#2099#><#2099#>
<#2101#>
Concatentation of Difference Lists
<#2101#>
verbatim30
<#2105#><#2105#>
<#2107#>
More Efficient Quicksort
Using Difference Lists
<#2107#>
verbatim31
<#2111#><#2111#>
<#2113#>Prolog vs.\ ``Standard'' Procedures<#2113#>
-