cs4026 formal models of computation part ii the logic model lecture 5 – lists

24
CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

Upload: alexis-jacobs

Post on 28-Mar-2015

216 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

CS4026Formal Models of

ComputationPart II

The Logic ModelLecture 5 – Lists

Page 2: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 2

Lists• Data structure for non-numeric

programming.• A sequence of any number of items.• The items can be any Prolog term

(including nested lists!).• Useful when we don’t know in advance

how many items we are going to have.• Flexible and generic.• In Prolog, a list is represented as a

sequence of terms, separated by commas and within “[…]”:[123,hello,Var1,p(a,X),[1,2,3]]

Page 3: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 3

Types in lists: Haskell vs Prolog• In Haskell, for every type t there is a type [t]

for lists whose elements are of type t• In Haskell, every list must have type [t] (for

some t), and hence all its elements must be of the same type

• So you can’t for instance have a list, some of whose elements have type int and some of whose elements have type [int], e.g. [1,[2,3],4]

• Prolog places no restrictions on what elements of lists can be

• Less restrictive, but you lose the advantages of type checking

Page 4: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 4

Lists• Lists are ordinary Prolog terms.• The notation […] is just a shorthand:

[1,2,3] .(1,.(2,.(3,[]))) • Lists are thus represented internally as trees:• N.B.: the last element is always the empty list []

.

1

2

3 []

.

.

Page 5: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 5

Lists• Lists are recursively defined as:

– The empty list []; or– A term followed by a list.

• Lists can enter queries:

.

1

2

3 []

.

.

?- List = [1,2,3].List = [1,2,3]yes

?-

Page 6: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 6

Lists (Cont’d)• Prolog provides a notation for manipulating

lists.• The notation is [H|T], a shortand for .(H,T)

– H stands for the first element of the list.– T stands for the remaining elements of the list

and must be a list.• We can build and decompose lists with [H|T]:?- List = [1,2,3], List = [A|B].

A = 1,B = [2,3],List = [1,2,3]

?- List = [A|B], A = 1, B = [2,3].A = 1,B = [2,3],List = [1,2,3]

Page 7: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 7

Lists (Cont’d)• The [H|T] notation allows for variations:

– [E1,E2|T] (a list with at least 2 elements)– [1|[2,3|T]] (a list [1,2,3|T])

• [H|T] is also a term, hence a tree:

?- List = [A|B], A = 1, B = [2,3].A = 1,B = [2,3],List = [1,2,3]

List

A B

.

[]

2

.

3

.

1

Page 8: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 8

Haskell vs Prolog list notations

Haskell Prolog

[1,2,3] [1,2,3]

[] []

x:xs [X|Xs] or .(X,Xs)

1:2:xs [1,2|Xs]

Page 9: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 9

Operations on Lists• We can access elements from the front of a

list• We can add elements to the front of a list:

?- L = [2,3], NewL = [1|L]L

[]

2

.

3

. 1

.

NewL

Page 10: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 10

Programming with Lists• Because of their recursive definition, lists are

naturally manipulated with recursive programs.

• Let’s revisit our first loop program:– Enable it to build a list with values typed inloop(L):- % a loop to create a list L

L = [X|Xs], % List L has form [X|Xs]

read(X), % X is read from the standard Input (keyboard)

X \= end, % if input different from “end” then

loop(Xs). % build the tail recursively

loop([]). % if input is “end”, then List is empty.

?- loop(MyList).

|: a.

|: b.

|: end.

MyList = [a,b]

An argument is required to return the value of the list built

Page 11: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 11

Programming with Lists (Cont’d)• Its execution:

loop(L):-

L = [X|Xs],

read(X),

X \= end,

loop(Xs).

loop([]).

?- loop(MyList).

loop(L1):-

L1 = [X1|Xs1],

read(X1),

X1 \= end,

loop(Xs1).loop(L2):-

L2 = [X2|Xs2],

read(X2),

X2 \= end,

loop(Xs2).

a

L1

Xs1X1

.

b

L2

Xs2X2

.

loop(L3):-

L3 = [X3|Xs3],

read(X3),

X3 \= end,

loop(Xs3). end

L3

Xs3X3

.loop(L3):-

L3 = [X3|Xs3],

read(X3),

X3 \= end,

loop(Xs3).

?- loop(MyList).

|: a.

?- loop(MyList).

|: a.

|: b.

?- loop(MyList).

|: a.

|: b.

|: end.

Page 12: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 12

Programming with Lists (Cont’d)• Its execution:

loop(L):-

L = [X|Xs],

read(X),

X \= end,

loop(Xs).

loop([]).

loop(L1):-

L1 = [X1|Xs1],

read(X1),

X1 \= end,

loop(Xs1).loop(L2):-

L2 = [X2|Xs2],

read(X2),

X2 \= end,

loop(Xs2).

a

L1

Xs1X1

.

b

L2

Xs2X2

.

loop([]). []

?- loop(MyList).

|: a.

|: b.

|: end.

?- loop(MyList).

|: a.

|: b.

|: end.

MyList = [a,b]

Page 13: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 13

Programming with Lists (Cont’d)• To check if an element appears in a list:

– Check if element is the head;– Otherwise, check if element appears in tail

• This formulation is guaranteed to stop because lists are finite (!) and the process breaks list apart;

• In Prolog (first formulation):member(X,List):- % X is a member of List

List = [Y|Ys], % if List is of form [Y|Ys]

X = Y. % and X is equal to Y

member(X,List):- % otherwise (if not as above)

List = [Y|Ys], % break the list apart

member(X,Ys). % and check if X appears in Ys

Page 14: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 14

Programming with Lists (Cont’d)• Second formulation:

member(X,[Y|Ys]):- % X is a member of [Y|Ys]

X = Y. % if X is equal to Y

member(X,[Y|Ys]):- % otherwise (if not as above)

member(X,Ys). % check if X appears in Ys

Page 15: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 15

Programming with Lists (Cont’d)• Third (final) formulation:

• General point: Uses of the built-in predicate = can almost always be replaced more elegantly with pattern-matching in the head of a clause.

member(X,[X|_]). % X is member if it is head of list

member(X,[_|Ys]):- % otherwise (if not as above)

member(X,Ys). % check if X appears in Ys

Page 16: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 16

Prolog vs Haskell

• Cf Haskellmember :: a -> [a] -> Boolmember x [] = Falsemember x (y:ys) = (x==y) || (member x ys)

• Note: [] case

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

Page 17: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 17

Programming with Lists (Cont’d)• Let’s run the previous program:

member(X,[X|_]).

member(X,[_|Ys]):-

member(X,Ys).

?- member(3,[1,2,3]).

The query member(3,[1,2,3])does not match the 1st clause!!Prolog matches member(3,[1,2,3])with head of 2nd clause:

member(X1,[_|Ys1]):- member(X1,Ys1)

We thus get the values for the variables: {X1/3, Ys1/[2,3]}

Prolog now tries to prove member(X1,Ys1) that is

member(3,[2,3])The goal member(3,[2,3])does not match the 1st clause!!

Prolog matches member(3,[2,3])with head of 2nd clause:

member(X2,[_|Ys2]):- member(X2,Ys2)

We thus get the values for the variables: {X2/3, Ys2/[3]}

Prolog now tries to prove member(X2,Ys2) that is

member(3,[3])

The query member(3,[3])matches the 1st clause!!

?- member(3,[1,2,3]).

yes

?-

Page 18: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 18

Programming with Lists (Cont’d)• Member program can be run in two ways:

1. To check if an element occurs in a list;2. To obtain the elements of a list, one at a time

• It depends on the query – the program is exactly the same!!

• To obtain the elements of a list, we query:member(Elem,[1,2,3])

– We then get in Elem, the different elements

?- member(Elem,[1,2,3]).?- member(Elem,[1,2,3]).

Elem = 1 ?

?- member(Elem,[1,2,3]).

Elem = 1 ? ;

Elem = 2 ?

?- member(Elem,[1,2,3]).

Elem = 1 ? ;

Elem = 2 ? ;

Elem = 3 ?

?- member(Elem,[1,2,3]).

Elem = 1 ? ;

Elem = 2 ? ;

Elem = 3 ? ;

no

?-

Can you trace this query?

Page 19: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 19

Ys

[]

a

.

b

.

Xs

[]

1

.

2

.

Zs

Programming with Lists (Cont’d)• To concatenate two lists Xs and Ys:

– Create a 3rd list Zs by copying all elements of Xs,– When we get to the end of Xs, put Ys as the tail of

Zs• Diagrammatically:

1

2

.

.

Page 20: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 20

Programming with Lists (Cont’d)• We need a predicate with 3 arguments:

– 1st argument is the list Xs– 2nd argument is the list Ys– 3rd argument is the concatenation Xs.Ys (in this

order)• The first list Xs will control the loop • As the first list Xs is traversed, its elements

are copied onto the 3rd argument (the concatenation).

• When we get an empty list, we stop and make Ys the value of the 3rd argument

Page 21: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 21

Programming with Lists (Cont’d)• First attempt:

• A more compact format:

append([],Ys,Zs):- % if Xs is empty,

Zs = Ys. % then Zs is Ys

append([X|Xs],Ys,[Z|Zs]):- % otherwise

X = Z, % copy X onto 3rd argument

append(Xs,Ys,Zs). % carry on recursively

append([],Ys,Ys). % if Xs empty, then Zs is Ys

append([X|Xs],Ys,[X|Zs]):- % else copy X onto 3rd arg.

append(Xs,Ys,Zs). % carry on recursively

Page 22: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 22

Programming with Lists (Cont’d)• Execution:append([],Ys,Ys).

append([X|Xs],Ys,[X|Zs]):-

append(Xs,Ys,Zs).

?- append([1,2],[a,b],Res).

append([X1|Xs1],Ys1,[X1|Zs1]):-

append(Xs1,Ys1,Zs1).

append([X1|Xs1],Ys1,[X1|Zs1]):-

append(Xs1,Ys1,Zs1).

{X1/1,Xs1/[2],Ys1/[a,b]}

append([X1|Xs1],Ys1,[X1|Zs1]):-

append(Xs1,Ys1,Zs1).

{X1/1,Xs1/[2],Ys1/[a,b]}

append([X2|Xs2],Ys2,[X2|Zs2]):-

append(Xs2,Ys2,Zs2).

append([X2|Xs2],Ys2,[X2|Zs2]):-

append(Xs2,Ys2,Zs2).

{X2/2,Xs2/[],Ys2/[a,b]}

append([X2|Xs2],Ys2,[X2|Zs2]):-

append(Xs2,Ys2,Zs2).

{X2/2,Xs2/[],Ys2/[a,b]}

aliasing: Zs1/[X2|Zs2]

append([],Ys3,Ys3).append([],Ys3,Ys3).

{Ys3/[a,b]}

aliasing: Zs2/Ys3

?- append([1,2],[a,b],Res).

Res = [1,2,a,b] ?

yes

?-

aliasing: Res/[X1|Zs1]

Page 23: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 23

Programming with Lists (Cont’d)• Execution:append([],Ys,Ys).

append([X|Xs],Ys,[X|Zs]):-

append(Xs,Ys,Zs).

append([X2|Xs2],Ys2,[X2|Zs2]):-

append(Xs2,Ys2,Zs2).

{X2/2,Xs2/[],Ys2/[a,b]}

append([X1|Xs1],Ys1,[X1|Zs1]):-

append(Xs1,Ys1,Zs1).

{X1/1,Xs1/[2],Ys1/[a,b]}

append([],Ys3,Ys3).

{Ys3/[a,b]}

?- append([1,2],[a,b],Res).

Res = [1,2,a,b] ?

yes

?-

1

Res

Zs1X1

.

2

Zs2X2

.

a

.

b

.

[]

Page 24: CS4026 Formal Models of Computation Part II The Logic Model Lecture 5 – Lists

formal models of computation 24

“Reversible definitions” in Prolog• As with “member”, “append” can be used in

different ways, e.g.

?- append([a,b,c],[d],X).?- append(X,[a,b,l,e],[e,a,t,a,b,l,e]).?- append([e,a,t],X,[e,a,t,a,b,l,e]).?- append(X,Y,[e,a,t,a,b,l,e]).

• Each of these would require a different function/method definition in Haskell/Java…