Weakness of logic Programming

Post on 17-Mar-2016

47 views 0 download

Tags:

description

Weakness of logic Programming. Horn clause cannot cover all logics “ every living thing is an animal or a plant animal(X) V plant(X)  living(X) So we must have the following definition in Prolog animal(X):- living(X), not plant(X). plant(X):- living(X), not animal(X). - PowerPoint PPT Presentation

transcript

Weakness of logic Programming

• Horn clause cannot cover all logics• “every living thing is an animal or a plant• animal(X) V plant(X) living(X)

• So we must have the following definition in Prologanimal(X):- living(X), not plant(X).plant(X):- living(X), not animal(X).

Prolog can only have one element on this side

Not will only satisfy if we can’t find that X is an animal.

• Another weakness is the way that Prolog uses its rules from top to bottom. We already saw the problem

• “not” means cannot find. It does not mean false.

exercises• Binary search Tree – nil– t(L,M,R)

• isin(item, Tree)isin(X,t(L,X,R)).isin(X,t(L,M,R)):- X<M, isin(X,L).isin(X,t(L,M,R)):- X>M, isin(X,R).• add(X,Tree,ResultTree)add(X,nil,t(nil,X,nil)).add(X,t(L,X,R),t(L,X,R)).add(X,t(L,M,R),t(L1,M,R)):- X, <M add(X,L,L1).add(X,t(L,M,R),t(L,M,R1)):- X>M, add(X,R,R1).

Controlling backtracking

• We can prevent backtracking, by using a feature called “cut”.

• Normally, prolog backtrack to find all answers, but sometimes we only need the first solution.

• Examplef(X,0):-X <3.f(X,2):- 3=<X, X<6.f(X,4):- 6=<X.

• If we try?-f(1,Y), 2<Y.

We will have Y = 0, and then2<Y will be false

So prolog will try to substitute another value for Y.

f(X,0):-X <3.f(X,2):- 3=<X, X<6.f(X,4):- 6=<X.

f(X,0):-X <3.f(X,2):- 3=<X, X<6.f(X,4):- 6=<X.

f(1,Y), 2<Y.This picture shows all the substitutions.

Rule 1Y =0

f(1,0), 2<0.

succeed

fail

Rule 2Y =2

f(1,2), 2<Y.

3=<1, 1<6.

fail

Rule 3Y =4

f(1,4), 2<4.

1 <3. 6=<1.fail

•Notice that all the rules are mutually exclusive.•If rule 1 succeed, other rules will surely fail.•There is no point substituting rule 2 and 3 if rule 1 succeeds.

f(X,0):-X <3.f(X,2):- 3=<X, X<6.f(X,4):- 6=<X.

f(X,0):-X <3, !.f(X,2):- 3=<X, X<6, !.f(X,4):- 6=<X.

Rule 1Y =0

f(1,0), 2<0.

succeed

Fail, normally it will backtrack pass 1<3.But this time it’ll stop At !

1 <3.

No further execution -> execution speed increases.

• Let’s try another example?-f(7,Y)Y = 4. (this is the answer)• First, try rule 1.– X <3 fails. So the program backtracks and uses rule 2. (we

have not pass the “cut” so it’s ok to backtrack.)• Try rule 2– 3=<7 but 7<6 fails. Therefore it backtracks to rule 3.

• Try rule 3– Succeeds.

f(X,0):-X <3, !.f(X,2):- 3=<X, X<6, !.f(X,4):- 6=<X.

• We can optimize it further.• Notice that if X<3 fails, 3=<X in rule 2 will

always succeed.• Therefore we do not need to test it. (same

reasoning for 6=<X in rule 3).• So we can rewrite the rules to:

f(X,0):-X <3, !.f(X,2):- 3=<X, X<6, !.f(X,4):- 6=<X.

f(X,0):-X <3, !.f(X,2):- X<6, !.f(X,4).

• Be careful now. If we do not have “cut”, we may get several solutions, some of which may be wrong. For example:

?-f(1,Y)Y=0 ;Y=2 ;Y=4

f(X,0):-X <3, !.f(X,2):- X<6, !.f(X,4).

We order it to try other rules here.If we do not have “cut”, it will try other rules and succeed because we’ve deleted the conditional tests.

• When finding answer up to “cut”, the system has already found solutions of B1 to Bm.

• When the “cut” is executed, solutions B1 to Bm are considered fix. For example:

C:-P,Q,R,!,S,T,U.C:-V.A:-B,C,D.?-A.• When ! Is executed. P,Q,R will be fixed (no

backtracking) and C:-V. will never get executed.• Backtracking is still possible in S,T,U but will never go

back beyond the !

H:-B1, B2, …, Bm, !, …, Bn.

We put the question here.

C:-P,Q,R,!,S,T,U.C:-V.A:-B,C,D.?-A. A

B, C, D

P,Q,R,!,S,T,U.

Can backtrack if not reach !

Can backtrack to ! But not beyond that

Let’s see another example next page.

• The rules are mutually exclusive.• So we can use “else if” for efficiency.max(X,Y,X):-X=>Y, !.max(X,Y,Y).• Be careful of the following situation:?-max(3,1,1).yes. • It does not get matched with the first rule from the start.• But it then matches the second rule, because we already took

out the conditional test.• So we fix it in the next page.

max(X,Y,X):-X=>Y.max(X,Y,Y):-X<Y.

max(X,Y,Max):- X=>Y, !, Max =X.max(X,Y,Max):- Max =Y.

max(X,Y,X):-X=>Y, !.max(X,Y,Y).

?-max(3,1,1).Program is able to enter the first rule because Max is not matched to any value.Once X=>Y in the first rule is satisfied, there is no backtracking.

Let’s see an example on list next page.

• If there are many X in the list, this definition allow any X to be returned when we order it to backtrack.

• If we want to make sure that only the first occurrence of X will be returned, we will have to use “cut”.

member(X, [X|L]).member(X, [Y|L]):-member(X, L).

member(X, [X|L]):-!member(X, [Y|L]):-member(X, L).

?-member(X, [a,b,c]).X=a;no

Order it to find another solution (backtrack)

• Add non-duplicate item into a listadd(X, L, L):-member(X,L), !.add(X, L, [X|L]).

?-add(a,[b,c],L).L=[a,b,c]

?-add(X,[b,c],L).L=[b,c]X=b

?add(a,[b,c,X],L).L=[b,c,a]X=a

This is just one solution

• Be careful.– If we define things using “cut”, we normally

intend that every rule is tried, right from the first rule. So “cut” can serve its purpose.

– Any query that allows rule skipping will destroy everything.

?add(a,[a],[a,a]).yes

Does not match the first rule, but match the second rule. This makes things incorrect.

• tennis match examplebeat(tom, jim).beat(ann, tom).beat(pat, jim).

• We want to categorize players into 3 types:– Winner: win every game– Fighter: player with mixed records– Sportman: lose every game

• X is a fighter if • X is a winner if• We can use “if then else”:class(X,fighter):- beat(X,_), beat(_,X), !.class(X,winner):-beat(X,_), !.class(X,sportman):-beat(_,X).

),(:),(: XZbeatZYXbeatY

beat(tom, jim).beat(ann, tom).beat(pat, jim).

),(:_),( XYbeatYXbeat

• We still need to be careful about rules getting skipped. For example:

?-class(tom,sportman).yes (but in fact tom is a fighter)

?-p(X).X=1;X=2;no

p(1).p(2):-!.p(3).

?-p(X),p(Y).X=1, Y=1;X=1, Y=2;X=2, Y=1;X=2, Y=2;no

?-p(X),!, p(Y).X=1, Y=1;X=1, Y=2;no

class(0,zero):-!.class(Number,positive):- Number>0, !.class(Number,negative).

class(Number,positive):- Number>0.class(0,zero).class(Number,negative):-Number<0.

Use cut

• Splitting a list to list of positive (including 0) and negative numbers.

split([],[],[]).split([H|T],[H|Z],R):- H=>0,split(T,Z,R).split([H|T],R,[H|Z]):-H<0,split(T,R,Z).

Use cut

split([],[],[]).split([H|T],[H|Z],R):- H=>0,!, split(T,Z,R).split([H|T],R,[H|Z]):- split(T,R,Z).

Careful:?-split([8,1,-3,0,-4,5],[1,0,5],[8,-3,-4]).Yes (it matches rule 3, skipping earlier rules.)

More difficult to understand

Make it bettersplit([],[],[]).split([H|T],[H|Z],R):- H=>0,!, split(T,Z,R).split([H|T],R,[H|Z]):- H<0, split(T,R,Z).

More committal

split([],[],[]).split([H|T],[H|Z],R):- H=>0,!, split(T,Z,R).split([H|T],R,[H|Z]):- H<0, !, split(T,R,Z).

Unnecessary cutsplit([],[],[]):- !split([H|T],[H|Z],R):- H=>0,!, split(T,Z,R).split([H|T],R,[H|Z]):- H<0, !, split(T,R,Z).

Any match here will not match any thing else.

H<0 is in the last clause, Whether or not H<0 fails, there are no choices laft.

Multiple choice with cutsquint([],[]).sqluint([X|T],[Y|L]):- integer(X), !, Y is X*X, squint(T,L).sqluint([X|T],[X|L]):-squint(T,L).

The third clause is not used when the goal backtracks. But it still does not stand independently.

Partial mapsevens([],[]).evens([X|T],[X|L]):- 0 is X mod 2, evens(T,L).evens([X|T],L):- 1 is X mod 2, evens(T,L).

evens([],[]).evens([X|T],[X|L]):- 0 is X mod 2, !, evens(T,L).evens([X|T],L):- 1 is X mod 2, evens(T,L).

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

setify([],[]).setify([X|T],L):- member(X,T), !, setify(T,L).setify([X|T],[X|L]):- setify(T,L).

tree

insert(I,[], n(I,[],[])).insert(I, n(N,L,R) , n(N,L1,R)):- I<N, !, insert(I, L,

L1).insert(I, n(N,L,R) , n(N,L,R1)):- I>N, !, insert(I, R,

R1).insert(I, n(I,L,R) , n(I,L,R)).

Negation as failure

likes(mary,X):-snake(X),!,fail.likes(mary,X):-animal(X).Or

likes(mary,X):-snake(X),!,fail;animal(X).

“Mary likes all animals but snake.”

different(X,X):- !, fail.different(X,Y).Ordifferent(X,Y):- X=Y, !, fail.

;true.

The “not” predicate

not(P):-P,!,fail;true.

Some prolog allows not p(X) or \+(p(X))

member(X,[X|_]).member(X,[_|T]):-member(X,T).notmem(X,L):- \+(member(X,L)).

notmem1(X,[]).notmem1(X,[Y|T]):-X\==Y, notmem1(X,T).

• Same examples with the use of “not”

likes(mary,X):-animal(X), not snake(X).

different(X,Y):- not X=Y.

class(X,fighter):- beat(X,_), beat(_,X).class(X,winner):-beat(X,_), not beat(_,X).class(X,sportman):-beat(_,X), not beat(X,_).

likes(mary,X):-animal(X), (snake(X), !, fail ; true).

It means ->otherwise

Conclusion about “cut”• Pros– Avoid unnecessary execution.– Use like if-then-else

• Cons– The rule must be tried in order, no skipping.

P:-a,bP:-c.

P:- a,!,b.P:-c.

P:-c.P:-a,!,b.

Logic is P <-> (a ^ b) V cChanging order has no effect.

Logic is P <-> (a ^ b) V ((not a) ^ c)

Logic is P <-> c V (a ^ b)

Different meaning

goodteam(manunited).expensive(manunited).goodteam(liverpool).reasonable(T):- not expensive(T).

?-goodteam(X), reasonable(X).X=liverpool.

?- reasonable(X) , goodteam(X). no

Has assigned value

Has no assigned value. The “not” clause does not assign a value for you. See next page.

?- expensive(X).Means

?-not expensive(X).Means not

)(exp: XensiveX

)(exp: XensiveX

)(exp: XensivenotX

So it gives “no” in the previous page.

It is forall, so prolog cannot instantiate a single value.

Only need to find a single value of X.

Flight • timetable(Place1, Place2, ListOfFlights)• Flight = DepTime / ArrTime / FlightNo /

ListOfDays

• timetable(london, edinburgh, [9:40 / 10:50 / ba4733 / alldays, 19:40 / 20:50 / ba4833 / [mo,tu,we,th,fr,su]]).

List of days or alldays

• route(P1, P2, Day, Route)

• flight(P1, P2, Day, Num, DepTime, ArrTime)• deptime(Route, Time)• transfer(T1, T2)

List of From / To / FlightNo / DepTime

route(P1, P2, Day, Route):- flight(P1,P2,Day,Fnum,DepTime,_).

route(P1, P2, Day, [(P1/P3/F1/Dep1)|RestRoute]):-route(P3,P2,Day,RestRoute), flight(P1,P3,Day,F1,Dep1,Arr1),deptime(RestRoute,Dep2),transfer(Arr1, Dep2).

flight(P1, P2, Day, Fnum, DepTime, ArrTime):-timetable(P1,P2, FlightList).member(DepTime / ArrTime / Fnum / Daylist, FlightList),flyday(Day,Daylist).

deptime([P1 / P2 / Fnum / Dep | _ ], Dep).

transfer(H1:M1, H2:M2):-60*(H2-H1) + M2 – M1 >= 40.

Logic circuitA B

BA C

inv(0,1).inv(1,0).and(1,1,1).and(1,0,0).and(0,1,0).and(0,0,0).