Você está na página 1de 14

Prolog: tutorial 6

Barbara Morawska

April 1, 2019
Lists in Prolog
Examples:
I list of characters: [a, b, c]
I list of numbers: [17, 13, 11, 7, 5, 3, 2]
I list of strings (repetitions) [orange, orange, apple, banana]
I list with elements not of the same type [X , f (A), hello, 3, −9.4]
I list containing lists [a, [a, a], [a, [a, a]], a]
I list with the empty list [the, [], has, nothing , in, it]

List constructor
[Head | Tail]
where Head is the first element of the list and Tail is the rest of the list
The query: ?-[Head | Tail] = [a,b,c]
returns: Head = a, Tail = [b,c]
Construct a list: ?- A = a, B = [b, c], C = [A|B].
List exercise
Try the following goals:
?- [a] = [H|T].
?- [ ] = [H|T].
What happens?
String in double quotes
String in double quotes: ”abcd” is treated as a list of ASCII characters.
Try queries:
?- "abcd"=X. X = ”abcd”
?- "abcd" = [97, 98, 99, 100]. false
?- "abcd" = [H|T]. false
?- "X*(Y+Z)" = [H|T] false

String without quotes


String without double quotes is a constant. Try queries:
?- abcd = X.
?- abcd = [H|T]. false
?- a+b = X. X =a+b
?- ‘a+b’ = X. X =0 a + b 0
?- ‘a+b’ = [H|T]. false
Changing constants to lists or vice versa
Try the following goals:
?- name(abc, X).
?- name(X, [97, 98, 99]).
?- name(abc, [97, 98, 99]).
?- name(a+b, X). error
?- name(’a+b’,X).
Predicate for even number of a’s

p([]).
p([a,a|X]) :- p(X).

I Test the predicate on different lists


I Trace it on p([a,a]).
I Generate all terms for which p is true by backtracking.
I Define a predicate true only of lists that consist of odd number of b’s
Defining sets in Prolog
Example:
p(a, b).
p(a, c).
p(b, d).
p(c, e).
We want to define a set:
S = {x | ∃y p(x, y )}

This is done by using predicate setof :

setof(X, Y^p(X, Y), S).

Notice that existential quantifier is expressed:

Y^p(X,Y)
which is equal to ∃Y p(X , Y ).

What is S?
Defining sets in Prolog
I Define set S = {x | p(a, x)} in Prolog.
I setof(X,p(a,X),S).
I What is S now?
I Define a set of grandparent relations:
S = {g (X , Y ) | ∃Z (p(X , Z ) ∧ p(Z , Y ))}
I setof(g(X,Y), Z^(p(X,Z), p(Z,Y)),S)
Bags (multisets) in Prolog
A bag (multiset) is a set in which repetitions are allowed.
Example
Define a bag of first elements of the parent relation.

bagof(X, Y^p(X,Y), S).

I what is S now?
I Compare it with setof predicate.

Instead of using bagof we can use findall predicate:

findall(X, p(X,Y), S).

Notice we don’t use any quantifier inside findall, since it contains


universal quantifier anyway.
Sets and bags exercises
I Define set of children:
C = {y | ∃x p(x, y )}
I Define child relation:

R = {(x, y ) | p(y , x)}


I Compare the queries. What are differences?
?- setof(X, Y^p(X, Y), S).

?- setof(X, p(X, Y), S).

?- setof(X, p(X, _), S).


I setof predicate does not return empty set, only ”false”. For example
define: {x | p(a, x)} and check.
I Define newsetof predicate that returns empty list [ ] instead. (It
should use setof in its definition)
Checking membership in a list
Prolog has a predefined member predicate. We can define it in the
following way:

member(H, [H|_]).

member(X, [_|T]) :- member(X, T).

I Try it: ?- member(a, [b, a, c, b]).


I Use backtracking to list all members of a list.

Subset
Using member predicate we can define subset predicate
subset([ ], _).

subset([H|T], X) :- member(H, X), subset(T, X).

Using subset define equal predicate for sets.


Union, intersection of sets
Using the property:

S = A ∪ B = {x | x ∈ A ∨ x ∈ B}

And using the member predicate we can define union:

union(A,B,S) :- setof(X, (member(X,A); member(X,B)), S).

Notice ”or” in the condition of setof predicate.


What should be the base case (?) for this definition?

Define intersection of two sets, using the following property:

S = A ∩ B = {x | x ∈ A ∧ x ∈ B}

What should be base case (?) in this case?


Exercises
I Define predicate minus that is a relative complement of a set B in A
(A \ B)
I Define predicate symdiff i.e. symmetric difference of two sets using
the following property:

S = A −̇ B = (A \ B) ∪ (B \ A)

I Define another predicate symdiff 2 of symmetric difference using the


following property:

S = A −̇ B = (A ∪ B) \ (A ∩ B)

I What backtracking on the following query shows:


?- member(A, S).
I What backtracking on the following query shows:
?- member(a, S).
Exercises
I Define another subset predicate basing your definition on the
following property: A ⊆ B iff A ∩ B = A
I Define another subset predicate basing your definition on the
following property: A ⊆ B iff A ∪ B = B
I Define a predicate my length that computes recursively the length
of a list. (length is one of the predefined predicates in Prolog). The
head of the main clause in the definition should be:

my_length([Head | Tail], L) :- . . .
I Define predicate concatenate for two lists, that computes their
concatenation:
concatenate([h,e], [l,l,o], A)
should yield A = [h, e, l, l, o]
Do not use the predefined predicate append that does it.
I Define predicate last, that finds the last element of a nonempty list.
I Define predicate pairs that finds the list of pairs of the elements of
two lists of the same length. Given two lists: [a, b, c] and [1, 2, 3] it
returns [[a, 1], [b, 2], [c, 3]]
Exercises
I Define a predicate pairs1 that given an element and a list creates
pairs with this element. Given an element a and a list [1, 2, 3] it
creates [[a, 1], [a, 2], [a, 3]].
I Define a predicate prod that given two lists created the Cartesian
product of them.
I Define a predicate replace that given a list will replace one element
by another. For example:
replace(a, o, [b, a, n, a, n, a], X).
Should yield: X = [b, o, n, o, n, o]
I Define a predicate powerset that given a list, will construct a list
containing all subsets of the elements in the list. For example:
?- powerset([a, b], X).
should yield: X = [[], [a], [b], [a, b]]

Você também pode gostar