Programming with Lists

CS314

Review

Previously

  • Prolog Basics

This lecture

  • Programming with Lists
  • And many concepts in the process
    • Arithmetic
    • Last call optimisation
    • Backtracking & Choice points.

Support for lists in Prolog

  • Notated with square brackets [1,2,3,4].
  • The empty list is [].
  • List pattern matching is [H | T], where H is a list element and T is a list.
    • Can also match [1,2,3 | T].

Finding the last element of a list

In [1]:
last([H],H).
last([_ | T], V) :- last(T, V).
Added 2 clauses(s).
In [2]:
?- last([1,2],X). 
X = 2 .

Quiz

The last element of a list:

last([H],H).
last([_ | T], V) :- last(T, V).

What happens if I ask for last([],X)?

A. pattern match exception.
B. Prolog says false.
C. Prolog says true, X = [].
D. Prolog says true, X = ???.

Quiz

The last element of a list:

last([H],H).
last([_ | T], V) :- last(T, V).

What happens if I ask for last([],X)?

A. pattern match exception
B. Prolog says false.
C. Prolog says true, X = [].
D. Prolog says true, X = ???.

Arithmetic

  • How do we compute the length of the list?
    • We need support for arithmetic.
  • Arithmetic is quite natural in imperative and functional paradigms.
    • Since computation is deduction in logic programming (unification), arithmetic is quite special.

Arithmetic equality != Unification

= operator is used up by unification.

In [3]:
?- A = 1+2.
A = +(1, 2) .
In [4]:
?- 1+2 = 3.
false.
In [5]:
?- A = money+power.
A = +(money, power) .

Use the is operator

The “is” operator tells prolog to evaluate the righthand expression numerically and unify with the left.

In [6]:
?- X is 1, A is X+2, X is 2.
false.
In [7]:
?- A is money+power.
ERROR: Caused by: '  A is money+power'. Returned: 'error(type_error(evaluable, /(power, 0)), context(:(system, /(is, 2)), _1670))'.

Restriction on is operator

The RHS must be a ground term (no variables).

In [8]:
?- A is B+2.
ERROR: Caused by: '  A is B+2'. Returned: 'error(instantiation_error, context(:(system, /(is, 2)), _1764))'.
In [9]:
?- 3 is B+2.
ERROR: Caused by: '  3 is B+2'. Returned: 'error(instantiation_error, context(:(system, /(is, 2)), _1846))'.

Quiz

What is the result of A is *(3,+(1,2))?

  1. Error
  2. 9
  3. 8
  4. 6

Quiz

What is the result of A is *(3,+(1,2))?

  1. Error
  2. 9
  3. 8
  4. 6

Arithmetic

There is support for +,*, /, <, =<, >, >=,etc.

In [10]:
?- X is 20/20.
X = 1 .

Length of list

Compute the length of a list.

In [11]:
len([],0).
len([H | T], N) :- len(T,M), N is M+1.
Added 2 clauses(s).
In [12]:
?- len([1,2,3],X).
X = 3 .

Backtracking

The way prolog produces results for the given query is through Backtracking.

Choice Points

  • Choice points are locations in the search where we could take another option.
  • If there are no choice points left then Prolog doesn't offer the user any more answers

Quiz

len([],0).
len([H | T], N) :- len(T,M), N is M+1.

?- len([1,2],X).
X = 2 .

What is the first result of query len(A,2)?

  1. Error due uninstantiated arithmetic expression.
  2. A = [h1,h2]
  3. Query runs forever
  4. Error due to invalid arguments

Quiz

What is the first result of query len(A,2)?

  1. Error due uninstantiated arithmetic expression.
  2. A = [h1,h2]
  3. Query runs forever
  4. Error due to invalid arguments

Quiz

len([],0).
len([H | T], N) :- len(T,M), N is M+1.

?- len(A,2).
A = [h1,h2] ;
...

What is the second result of query len(A,2)?

  1. Error due uninstantiated arithmetic expression.
  2. A = [h1,h2]
  3. Query runs forever
  4. Error due to invalid arguments

Quiz

What is the second result of query len(A,2)?

  1. Error due uninstantiated arithmetic expression.
  2. A = [h1,h2]
  3. Query runs forever
  4. Error due to invalid arguments

Limiting the number of results

len([],0).
len([H | T], N) :- len(T,M), N is M+1.

?- len(A,2).
In [13]:
?- len(A,2) {1}.
A = [ _1888, _1894 ] .

Last call optimization

  • len uses O(N) stack space.

Tail recursive length

  • Define a function len2(List, Acc, Len) such that len2(List, Acc, Len) is true if the sum of the length of List and Acc is euivalent to Len.
In [14]:
len2([],Acc,Acc).
len2([H|T],Acc,N) :- M is Acc+1, len2(T,M,N).
Added 2 clauses(s).
In [15]:
?- len2([1,2],0,X).
X = 2 .

Predicate Overloading

len2([],Acc,Acc).
len2([H|T],Acc,N) :- M is Acc+1, len2(T,M,N).
In [16]:
len3(L,X) :- len2(L,0,X).
Added 1 clauses(s).
In [17]:
?- len3([1,2,3],X).
X = 3 .

Last Call Optimization

  • This technique is applied by the prolog interpreter
  • We can only do this if the rule is determinate up to a choice point
    • No further choices for the rule

List append

e.g. append([1,2], [3,4], [1,2,3,4])

In [18]:
append([],Q,Q).
append([H | P], Q, [H | R]) :- append(P, Q, R).
Added 2 clauses(s).
In [19]:
?- append(Y,X,[1,2,3,4]).
Y = [  ], X = [ 1, 2, 3, 4 ] ;
Y = [ 1 ], X = [ 2, 3, 4 ] ;
Y = [ 1, 2 ], X = [ 3, 4 ] ;
Y = [ 1, 2, 3 ], X = [ 4 ] ;
Y = [ 1, 2, 3, 4 ], X = [  ] .

Backtracking

The way prolog fetches multiple results for the given query is through Backtracking.

Choice Points

  • Choice points are locations in the search where we could take another option.
  • If there are no choice points left then Prolog doesn't offer the user any more answers

List Sum

Compute the sum of the list. This is the example we saw in the first Prolog lecture.

In [20]:
sum([],0).
sum([H | T], N) :- sum(T,M), N is M+H.
Added 2 clauses(s).
In [21]:
?- sum([1,2,3],X).
X = 6 .
In [22]:
?- sum(X,0) {1}.
X = [  ] .

Prefix and Suffix

<-------X-------->
+-------------------------------+
|      |    S    |              |  
+-------------------------------+
<--------------Z---------------->
  • prefix X of Z.
  • suffix S of X.

Prefix and Suffix of list can be defined using append.

In [23]:
prefix(X,Z) :- append(X,Y,Z).
suffix(Y,Z) :- append(X,Y,Z).
Added 2 clauses(s).

Prefix and Suffix

In [24]:
?- prefix(X,[1,2,3]).
X = [  ] ;
X = [ 1 ] ;
X = [ 1, 2 ] ;
X = [ 1, 2, 3 ] .
In [25]:
?- suffix(X,[1,2,3]).
X = [ 1, 2, 3 ] ;
X = [ 2, 3 ] ;
X = [ 3 ] ;
X = [  ] .