ling 388: language and computers sandiway fong lecture 5: 9/8

24
LING 388: Language and Computers Sandiway Fong Lecture 5: 9/8

Upload: arielle-climo

Post on 14-Dec-2015

213 views

Category:

Documents


0 download

TRANSCRIPT

LING 388: Language and Computers

Sandiway Fong

Lecture 5: 9/8

2

Administrivia

• Homework 1– graded and returned by email– reviewed today

• Reminder– Homework 2 due tonight (by midnight)

• see the hint posted?

3

Homework 1 Review

• Use databasebird(robin). “robin is a bird”

bird(eagle). “eagle is a bird”

• (2pts) What do the following queries return as an answer?

• The queries?- \+ bird(Eagle).?- \+ \+ bird(robin).

• (6pts) Give the logical reasoning for each answer

Key observationcase of first letter matters in Prolog, Eagle is a variable

• ?- \+ bird(Eagle).• false.

• ?- trace.• true.

• [trace] ?- \+ bird(Eagle).• Call: (7) bird(_G334) ? • Exit: (7) bird(robin) ? • false.

4

Homework 1 Review

• Use databasebird(robin). “robin is a bird”

bird(eagle). “eagle is a bird”

• (2pts) What do the following queries return as an answer?

• The queries?- \+ bird(Eagle).?- \+ \+ bird(robin).

• (6pts) Give the logical reasoning for each answer

• ?- \+ \+ bird(robin).• true.[trace] ?- \+ \+ bird(robin). Call: (7) bird(robin) ? Exit: (7) bird(robin) ? true.

debugger gave only abbreviated information

• \+ \+ bird(robin) is true if• \+ bird(robin) is false if• bird(robin) is true• but bird(robin) is true since it’s in the

database• so \+ bird(robin) is false • and so \+ \+ bird(robin) is true • that’s why Prolog says true

5

Homework 1 Review

• (2pts) In Exercise 4, we stated:– has_feathers(Y) :-

bird(Y).– However, it is common

knowledge that, of all the animals in the world, all birds have feathers and only birds have feathers.

– What is missing from my Prolog rule?

– Submit the missing rule.

Key observation:Looking for some way to say “if and only if”e.g. has_feathers(Y) iff bird(Y).

has_feathers(Y) :- bird(Y).bird(Y):- has_feathers(Y).

Assert?- assert((bird(Y):- has_feathers(Y))).

Circularity in definition

6

Homework 1 Review

• (4pts) Although all birds have feathers, not all birds fly, e.g. penguins and ostriches– Add these two birds to the database– Make sure bird/1 and has_feathers/1 are true for them– Modify the can_fly rule to exclude them– hint: look up conjunction (comma symbol in Prolog)– Submit the completed database

% flightless birds

bird(penguin).bird(ostrich).has_feathers(Y) :- bird(Y).

Modifycan_fly(X) :- has_feathers(X).

Key observation:need to specify the fact that certain birds are flightless, and that those birds are excluded from can_fly/1

flightless(penguin).flightless(ostrich). can_fly(X) :- has_feathers(X), \+

flightless(X).

Homework 1 Review

• (4pts) Although all birds have feathers, not all birds fly, e.g. penguins and ostriches– Add these two birds to the database– Make sure bird/1 and has_feathers/1 are true for them– Modify the can_fly rule to exclude them– hint: look up conjunction (comma symbol in Prolog)– Submit the completed database

?- can_fly(X).X = robin ;X = eagle ;false.

?- can_fly(penguin).false.?- trace.true.[trace] ?- can_fly(penguin). Call: (6) can_fly(penguin) ? Call: (7) has_feathers(penguin) ? Call: (8) bird(penguin) ? Exit: (8) bird(penguin) ? Exit: (7) has_feathers(penguin) ? Call: (7) flightless(penguin) ? Exit: (7) flightless(penguin) ? Fail: (6) can_fly(penguin) ? false.

8

Today’s Topics

• More on recursion

• Last time– we defined lastinlist/2 and len/2 to pick the last

element of a list and compute the length of a list, respectively.

lastinlist([X],X). (base case) lastinlist([X|L],Y) :- lastinlist(L,Y). (recursive case)

len([],0). (base case)

len([X|L],N) :- len(L,M), N is M+1. (recursive case)

9

Today’s Topics

• More on recursion

– Look at taking apart and putting lists together– And symbols (atoms)

10

Building and Taking Atoms Apart

• Built-in predicate atom_chars/2 has two modes of usage– atom_chars(symbol,list)

1. takes names apart• ?- atom_chars(will,X).– X is the list of characters representing will

2. builds names from a list of characters• ?- atom_chars(X,[’J’,o,h,n]).

– use single quotes around capitalized J to avoid J being interpreted as a variable

• ?- atom_chars(X,[w,o,n,’’’’,t]).– ’’’’ denotes the single quote (or ’\’’)

11

Building and Taking Atoms Apart

more example queries• ?- atom_chars(has,[h,a,s]).

– Yes

• ?- atom_chars(will,[w,X,l,l]).– X = i

• ?- atom_chars(X,Y).

what happens here?

• ?- atom_chars(X,[J,o,h,n]).

12

Building and Taking Lists Apart

(This is about as complicated as it will get in this class)

13

Building and Taking Lists Apart

• append/3 is a built-in predicate in SWI-Prolog defined as follows:

– append(L1,L2,L3) is true– if list L3 is the linear concatenation

of lists L1 and L2 [1,2] append [3,4] = [1,2,3,4]

• Example– ?- append([1,2],[3,4],

[1,2,3,4]).• Note

– append/3 has multiple modes of usage

– i.e. it can be used to take apart as well as concatenate lists

• let’s run example queries– ?- append([1],[2,3],X).– ?- append(X,Y,[1,2]).– ?- append(_,[X],[1,2,3]).– ?- append(X,Y,Z).

• Note: – the underscore character ‘_’ is a variable

with no name– it’s a variable but we don’t care about its

final value– no binding will be reported by the

interpreter for underscores

14

Building and Taking Lists Apart

• append/3 can be defined recursively as follows:

– app([],L,L). Base case– app([X|L1],L2,[X|L3]) :- app(L1,L2,L3). Recursive case

• we use the predicate name app/3 here to avoid a naming clash• append/3 is already defined (built-in)

15

Building and Taking Lists Apart

app([],L,L). Base case

app([X|L1],L2,[X|L3]) :- app(L1,L2,L3). Recursive case

• Base case says:– if we concatenate [] with an arbitrary list L, we get L

• Recursive case says:– if I have a list headed by X and the tail is L1, i.e. [X|L1], and I want to

concatenate that to another list L2– the answer is going to be a list headed by X– the tail is some other list L3– where L3 is defined as– the concatenation of L1 and L2

Example

?- app([1,2,3],[4,5],L).L = [1|L3]

where L3 is given by

?- app([2,3],[4,5],L3).

16

Building and Taking Lists Apart

app([],L,L). Base case

app([X|L1],L2,[X|L3]) :- app(L1,L2,L3). Recursive case

• Base case says:– if we concatenate [] with an arbitrary list L, we get L

• Recursive case says:– if I have a list headed by X and the tail is L1, i.e. [X|L1], and I want to

concatenate that to another list L2– the answer is going to be a list headed by X– the tail is some other list L3– where L3 is defined as– the concatenation of L1 and L2

Example

?- app([1,2,3],[4,5],L).L = [1|L3] where L3 is given by

?- app([2,3],[4,5],L3).L3 = [2|L3’] where L3’ is given by

?- app([3],[4,5],L3’).

17

Building and Taking Lists Apart

app([],L,L). Base case

app([X|L1],L2,[X|L3]) :- app(L1,L2,L3). Recursive case

• Base case says:– if we concatenate [] with an arbitrary list L, we get L

• Recursive case says:– if I have a list headed by X and the tail is L1, i.e. [X|L1], and I want to

concatenate that to another list L2– the answer is going to be a list headed by X– the tail is some other list L3– where L3 is defined as– the concatenation of L1 and L2

Example

?- app([1,2,3],[4,5],L).L = [1|L3] where L3 is given by

?- app([2,3],[4,5],L3).L3 = [2|L3’] where L3’ is given by

?- app([3],[4,5],L3’).L3’ = [3|L3”] where L3” is given by

?- app([],[4,5],L3”).

18

Building and Taking Lists Apart

app([],L,L). Base case

app([X|L1],L2,[X|L3]) :- app(L1,L2,L3). Recursive case

• Base case says:– if we concatenate [] with an arbitrary list L, we get L

• Recursive case says:– if I have a list headed by X and the tail is L1, i.e. [X|L1], and I want to

concatenate that to another list L2– the answer is going to be a list headed by X– the tail is some other list L3– where L3 is defined as– the concatenation of L1 and L2

Example

?- app([1,2,3],[4,5],L).L = [1|L3] where L3 is given by

?- app([2,3],[4,5],L3).L3 = [2|L3’] where L3’ is given by

?- app([3],[4,5],L3’).L3’ = [3|L3”] where L3” is given by

?- app([],[4,5],L3”).L3” = [4,5] (Base case)

19

Building and Taking Lists Apart

app([],L,L). Base case

app([X|L1],L2,[X|L3]) :- app(L1,L2,L3). Recursive case

Example?- app(L1,L2,[1,2]).

matches

app([],L,L). Base caseL1 = [], L2 = [1,2]

1st answer

20

Building and Taking Lists Apart

app([],L,L). Base case

app([X|L1],L2,[X|L3]) :- app(L1,L2,L3). Recursive case

Example?- app(L1,L2,[1,2]).

matches

app([],L,L). Base caseL1 = [], L2 = [1,2]

head of recursive case

app([X|L1’],L2’,[X|L3’]) L1 = [1|L1’]L2 = L2’[1,2] = [X|L3’] L3’=[2]?- app(L1’,L2’,L3’).?- app(L1’,L2’,[2]).

21

Example?- app(L1,L2,[1,2]).

matches

app([],L,L). Base caseL1 = [], L2 = [1,2]

head of recursive case

app([X|L1’],L2’,[X|L3’]) L1 = [1|L1’]L2 = L2’[1,2] = [X|L3’] L3’=[2]?- app(L1’,L2’,L3’).?- app(L1’,L2’,[2]).

matches

app([],L,L). Base caseL1’ = []L2’ = L = [2]

Building and Taking Lists Apart

app([],L,L). Base case

app([X|L1],L2,[X|L3]) :- app(L1,L2,L3). Recursive case

2nd answerL1 = [1]L2 = [2]

22

Building and Taking Lists Apart

app([],L,L). Base case

app([X|L1],L2,[X|L3]) :- app(L1,L2,L3). Recursive case

Example?- app(L1,L2,[1,2]).

matches

app([],L,L). Base caseL1 = [], L2 = [1,2]

head of recursive case

app([X|L1’],L2’,[X|L3’]) L1 = [1|L1’]L2 = L2’[1,2] = [X|L3’] L3’=[2]?- app(L1’,L2’,L3’).?- app(L1’,L2’,[2]).

matches

app([],L,L). Base caseL1’ = []L2’ = L = [2]

Example contd.?- app(L1’,L2’,[2]).

matches

head of recursive case

app([X|L1”],L2”,[X|L3”]) L1’ = [2|L1”]L2’ = L2”[2] = [X|L3”] L3” =[]?- app(L1”,L2”,L3”).?- app(L1”,L2”,[]).

23

Building and Taking Lists Apart

app([],L,L). Base case

app([X|L1],L2,[X|L3]) :- app(L1,L2,L3). Recursive case

Example?- app(L1,L2,[1,2]).

matches

app([],L,L). Base caseL1 = [], L2 = [1,2]

head of recursive case

app([X|L1’],L2’,[X|L3’]) L1 = [1|L1’]L2 = L2’[1,2] = [X|L3’] L3’=[2]?- app(L1’,L2’,L3’).?- app(L1’,L2’,[2]).

matches

app([],L,L). Base caseL1’ = []L2’ = L = [2]

Example contd.?- app(L1’,L2’,[2]).

matches

head of recursive case

app([X|L1”],L2”,[X|L3”]) L1’ = [2|L1”]L2’ = L2”[2] = [X|L3”] L3” =[]?- app(L1”,L2”,L3”).?- app(L1”,L2”,[]).

matches

app([],L,L). Base caseL1” = [] L2”=L=[]

3rd answerL1 = [1,2]L2 = []

24

Building and Taking Lists Apart

app([],L,L). Base case

app([X|L1],L2,[X|L3]) :- app(L1,L2,L3). Recursive case

Example?- app(L1,L2,[1,2]).

has 3 answersL1 = [], L2 = [1,2]L1 = [1], L2 = [2]L1 = [1,2], L2 = []

in each case it is true that

L1 concatenated with L2 is [1,2]