<#2#><#2#> <#4#>Prolog - next 2 weeks<#4#> <#19#><#19#> <#21#>Prolog<#21#> <#38#>gramming in ic<#38#> <#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#>

<#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#>
  1. father(john,sue).
  2. ancestor(odin,X).
  3. parent(X,Y) :- mother(X,Y).
  4. 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#>

  1. father(john,sue)
  2. #tex2html_wrap_inline2356# X . ancestor(odin,X)
  3. #tex2html_wrap_inline2358# X, Y . mother(X,Y) #tex2html_wrap_inline2360# parent(X,Y)
  4. #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#> <#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

  1. #tex2html_wrap_inline2712# = <#751#>success<#751#>
  2. #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:

  1. #tex2html_wrap_inline2844#] #tex2html_wrap_inline2846# (<#840#>list<#840#> #tex2html_wrap_inline2848#)
  2. #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:

  1. <#868#>X<#868#> is a member of any list of which it is the first element.
  2. 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#>
  1. 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.
  1. 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#>
  1. <#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#>
  1. verbatim32 Procedural: Try 43.
    If that fails, try44.
  2. <#2189#> verbatim33 Call <#2123#>p(a)<#2123#>. Assign Y=b then fails.
    Reassign Y=c then succeeds.
    Can tell Prolog to find another proof.
    Reassign Y=d then succeeds.
    Try again #tex2html_wrap_inline3110# failure. <#2189#>
<#2127#><#2127#>
  1. (in principle)
    We can execute a goal in more than one way. verbatim34 Which body will be executed?
    (Prolog's use of DFS makes this deterministic.)

  2. <#2190#>
    • variables can be given values proc.\ call or proc.\ call
    • variables need not have or be given values at all, but can simply be with respect to other variables via unification.
    • can about particular values that variables must have as long as possible
      #tex2html_wrap_inline3112# major strength of Prolog.
    <#2190#>