Notes for CS3310 Artificial Intelligence Part 1 Prof. Neil C. Rowe

advertisement

Notes for CS3310

Artificial Intelligence

Part 4: Inference rules

Prof. Neil C. Rowe

Naval Postgraduate School

Version of July 2009

Principles of Prolog rules

• A Prolog rule is a predicate expression, followed by ":-", followed by a query.

• The predicate expression is the "left side"; the query is the "right side".

• It means that when the left side is queried it substitutes the right-side query for it. So a rule defines a subroutine.

• Rules with the same left side are alternative ways to prove that left side.

• Variables in the rule left side are bound first.

• Example: a(X) :- b(X,Y), c(Y).

Example rules--write these in Prolog

1. Something is northwest of Y if it is both north and west of Y.

2. Any large carrier in the Persian Gulf is American.

3. A superboss of someone is a boss of a boss of that person.

More example rules--write these in Prolog

4. There's no class on a day if it is a holiday, and there's no class if it is a weekend.

5. The person-boss of a person P is the incumbent in the job that bosses the job that P is an incumbent in.

6. A thing is above another thing if it is resting on that thing, or else if it is resting on a third thing that is above the second thing.

Answers to first rule exercise

1. northwest_of(X,Y) :- north_of(X,Y), west_of(X,Y).

2. nationality(X,us) :- size(X,large), a_kind_of(X,carrier), location(X,persian_gulf).

[This rule is "heuristic" or not guaranteed to be true.]

3. superboss_of(J1,J2) :- boss_of(J1,J3), boss_of(J3,J2).

[Note local variable J3.]

4. noclass(D) :- weekday(D). noclass(D) :- weekend(D).

[Rules with the same left side amount to an "or” of the right sides.]

5. is_person_boss_of(P1,P2) :- incumbent(J1,P1), boss_of(J1,J2), incumbent(J2,P2).

6. above(X,Y) :- on(X,Y). above(X,Y) :- on(X,Z), above(Z,Y).

[Last line illustrates “tail recursion”, equivalent to iteration.]

The logical (declarative) meaning of Prolog rules

• Prolog rules represent predicate calculus statements with one implication (“:-” means “  ”).

• The right side of a rule contains the “premises” of the implication, and the left side is the “conclusion”.

• Variables in the left side are universally quantified.

• Other variables ("local variables") are existentially quantified within the scope of any applicable universal quantifications.

Corollary 1: Facts are rules with no right side. Hence variables in facts are universally quantified.

• Corollary 2: Queries are rules with no left side. Hence variables in queries are existentially quantified.

Recursion

Recursion = a rule that refers to itself.

Example, a “transitivity” definition:

superior(X,Y) :- boss_of(X,Y). (basis) superior(X,Y) :- boss_of(X,Z), superior(Z,Y).

(induction step)

Recursion handles indefinitely long chains of reasoning.

Recursion has 1 or more "basis" (easy) cases, facts or rules, and 1 or more "induction" (self-referencing) rules.

The induction rules must decompose the problem into simpler subproblems.

Decomposition must eventually reach a basis case.

Transitivity definitions

• Transitivity definitions in Prolog always require two rules together.

• Let r be a relationship predicate used only in facts, and t be a new "transitive" version of r . Then a transitivity definition should always be in this two-rule form:

– t(X,Y) :- r(X,Y).

– t(X,Y) :- r(X,Z), t(Z,Y).

• In predicate calculus: 

X

Y(t(X,Y)

(r(X,Y)

 

Z(r(X,Z)

 t(Z,Y))).

Inheritance definitions

• Inheritance definitions always consist of just one rule (the basis conditions are database facts).

• Let r be a relationship predicate used only in facts, p be a property predicate or other two-argument predicate, and t be a type predicate. Any Prolog inheritance definition must be one of the following rules:

– p(X,Y) :- r(X,Z), p(Z,Y).

– p(X,Y) :- r(Z,X), p(Z,Y).

– t(X) :- r(X,Z), t(Z).

– t(X) :- r(Z,X), t(Z).

• In predicate calculus, the first is:

X

Y(p(X,Y)

 

Z(r(X,Z)

 t(Z,Y)).

Inheritance examples owner(truck4382, nps).

location(truck4382, nps_lot_s).

part_of(battery73428, truck4382).

status(battery73428, defective).

a_kind_of(battery73428, vehicle_battery).

purpose(vehicle_battery, starting).

a_kind_of(vehicle_battery, electrical_battery).

mechanism(electrical_battery, electricity).

What indirect conclusions should we infer?

Semantic network for inheritance examples truck4382 part_of battery73428 a_kind_of owner location status nps nps_lot_s defective starting vehicle_battery a_kind_of electrical_battery purpose mechanism electrical

When do transitivity and inheritance hold?

• This requires careful analysis.

• Is a particular proposed transitivity or inheritance "common sense"? If so, use it.

Common sense doesn't mean guaranteed, but just "reasonable and usual" in the world with occasional exceptions.

• For instance, "north_of" is transitive but not

“west_of” (because of wraparound).

• Similarly, "owner" inherits with respect to

"part_of” in one way because if the owner of

X is O and Y is part of X, then it is common sense that O owns Y too.

Transitivity and inheritance, cont.

• Transitivity and inheritance are "defaults" which can be overridden occasionally by exceptions. In Prolog, facts explaining exceptions go at the top of the Prolog database.

• Note:

– Given B 

A and a case where A is true yet B is false, that contradicts the implication.

– Given B 

A and a case where A is false yet B is true, the implication is still possible, since another implication may explain why B is true.

The genealogy example

• Suppose we have facts of the form:

– child(Father,Mother,Child,Sex)

• where Father is the name of the father; where

Mother is the name of the mother; where Child is the name of the child; and Sex is either "m" or "f".

• Example fact: child(tom,mary,joe,m).

• Exercise: define the following new predicates for a database containing child facts. The rules you write can refer to previously defined predicates too.

Genealogy exercises: Define these father(X,Y) X is father of Y mother(X,Y): X is mother of Y parent(X,Y): X is parent of Y son(X,Y): X is son of Y grandfather(X,Y): X is grandfather of Y uncle(X,Y): X is uncle of Y brother(X,Y): X is brother of Y half_brother(X,Y): X is half-brother of Y ancestor(X,Y) : X is ancestor of Y family_name(X,N): N is family name of X [assume additional facts exist for this predicate]

Exercise 1 of rule rearrangement via predicate calculus

Suppose if a car is hit by lightning, the fuses are blown and the computer is dead:

X ((fusestatus(X,blown)

 dead(X,computer))

(hit_by(X,lightning)

 a_kind_of(X,car))).

Represent this in Prolog using logic transformations.

Example 2 of rule rearrangement via predicate calculus

Suppose if a car won't start and the radio won't play, then either the battery is dead or a fuse is blown:

X ((dead(X,battery)

 blown(X,fuse))

(~ starts(X)

~ plays(X,radio))).

Represent this as best you can (you can’t catch it all) in Prolog, using logic transformations.

Quantification in English

• All p are q (= every p is a q):

X (q(X)

 p(X)) p

• No p is a q (= p is never a q):

X (~ q(X)

 p(X)) p q

• Some p are q (= It’s false that no p is a q):

X(p(X)

 q(X))

 

X~(~p(X)

~q(X))

~

X (~q(X)

 p(X)) [note

 in first!]

• Only a p is a q: 

X (p(X)

 q(X)) q q p

Examples of predicate calculus

• "All American ships are gray."

S [color(S,gray)

(a_kind_of(S,ship)

 nationality(S,us))]

• "No American ships are blue destroyers."

S [~(color(S,blue)

 a_kind_of(S,destroyer))

(a_kind_of(S,ship)

 nationality(S,us))]

• "Some American ships are spraypainted gray."

S

A [color(S,gray)

 object(A,S)

 a_kind_of(A,spraypainting)

 a_kind_of(S,ship)

 nationality(S,us)]

Predicate calculus exercise

• Represent: "Every American ship has some homeport."

Type assertions that establish the meaning of variables go in the “if” part of an implication

• “A person is a parent if they have a child.”

X

Y [ parent ( X )

( person ( X )

 has ( X , Y )

 child ( Y ))]

• You put the business about being a person in the “if” part, because this rule as stated only defines human parents.

•  

( ( )

( ))

( ( )

( , )

( ))

[( p

 would be redundant because: q )

( q

 r )]

[( p

 q )

~ q

~ r ]

[[ p

~ q

~ r ]

[ q

~ q

~ r ]]

[[ p

~ q

~ r ]

[ true

~ r ]]

[[ p

~ q

~ r ]

 true ]

[ p

~ q

~ r ]

[ p

( q

 r )]

A fact can mean the same as a rule

• The fact a_kind_of(ship,vehicle) can also be written as a rule: a_kind_of(X,vehicle) :- a_kind_of(X,ship).

• Which is better? Usually the second, because it gives you more flexibility with variables.

• So we prefer you use the rule form when you can.

Existential quantifiers in a conclusion

• Consider: “Every civilian at NPS has a badge.”

“A” signals a variable. This should be:

P[

B[a_kind_of(B,badge)

 has(P,B)]

(a_kind_of(P,civilian)

 at(P,nps))]

This cannot be done in Prolog.

• It would be incorrect to write:

P[has(P,badge)

(a_kind_of(P,civilian)

 at(P,nps))] because that would mean that every civilian at NPS has the same badge. Badges occupy different physical space, have different pictures on them, etc.

Other ways to say the same thing

• Consider: “No civilian at NPS does not have a badge.” This means there does not exist a P such that P is a civilian, P is at NPS, and P does not have some badge:

 

P[

 

B[a_kind_of(B, badge)

 has(P,B)]

 a_kind_of(P,civilian)

 at(P,nps)

• We can use equivalences on this expression:



P[

B[a_kind_of(B, badge)

 has(P,B)]

(a_kind_of(P,civilian)

 at(P,nps))]

• 

P[

B[a_kind_of(B, badge)

 has(P,B)]

(a_kind_of(P,civilian)

 at(P,nps))] which is the expression as the previous page.

Some variations

• 

P[

B[a_kind_of(B, badge)

 has(P,B)

 at(P,nps)]

 a_kind_of(P,civilian)]

This says that anyone who is a civilian must also be at NPS with some badge.

•  

P[

 

B[a_kind_of(B, badge)

 has(P,B)]

(a_kind_of(P,civilian)

 at(P,nps))]

 

P[

 

B[a_kind_of(B, badge)

 has(P,B)]



(a_kind_of(P,civilian)

 at(P,nps))]



P[

B[a_kind_of(B, badge)

 has(P,B)]

(a_kind_of(P,civilian)

 at(P,nps))]

This says that every person in the world is a civilian at NPS with some badge.

Quantification in Java

Ip ( I )

Ip ( I assuming that predicate p is only meaningful for arguments which are integers 0 through N-1. An array represents "p". The loops iterate over 0 through N-1, and "~" means negation.

public static boolean universalquantification {

(boolean p[], integer N) { for (int I=0; I<N; I++) {if (~p[I]) return false; } return true; } public static boolean existentialquantification {

(boolean p[], integer N) { for (int I=0; I<N; I++) {if (p[I]) return true; } return false; }

Universal quantification on right sides in Prolog

It’s automatic if the variable is on the left side of a rule. Otherwise try negating an existential.

Example: Suppose p is true if for every X of type t , q(X) is true. (Let p

= “computer system is ok”, t(X)

= “X is a bug”, q(X)

= “X is fixed”.) p

 

X (q(X)

 t(X))

 p

~

X ~ (q(X)

 t(X))

 p

~

X ~ (q(X)

~ t(X))

 p

~

X (~ q(X)

 t(X))

The last can be represented as a Prolog rule: p :- \+ (t(X), \+ q(X)).

More rule representation exercises

1. Suppose a programming team is balanced if it has a leader, a librarian, and a liaison. (Use only the two-argument predicates a_kind_of , part_of , balanced , and purpose .)

Rule representation problem 2

• 2. Suppose that if we are within the Atlantic fleet, then every nuclear ship is a submarine. (Use only predicates a_kind_of , within , and propulsion .)

The interaction of a_kind_of and part_of

• Part_of doesn’t inherit with respect to

( a_kind_of, but an inference is possible

(“reasoning by analogy”):

   

[( _ ( , )

_ _ ( , ))

_ ( , )

_ _ ( , ))] a_kind_of

T part_of

S

Q part_of

P a_kind_of

Example: Ships have hulls, so the

Enterprise has something which is a hull.

Prolog implementation of variable binding

1. Rules can be stored in the Prolog database along with facts.

The order of the rules and facts in the database is the order they are tried.

2. When a rule is matched a query expression, first all variable bindings in the expression are copied to the corresponding variables on the left side of the rule. (If a binding conflicts with a constant in the left side, the rule fails.) This is "head matching" with "call-by-value".

3. When a rule succeeds, all bindings (besides head matching) that it made of its left-side variables are copied to the corresponding variables in the calling expression.

Example of variable binding

Consider the query:

?- superbossed_by(bob,A).

with database: superbossed_by(X,Y) :- bossed_by(X,Z), bossed_by(Z,Y).

bossed_by(tom,ann).

bossed_by(bob,tom).

• The binding

X=bob is made on rule entry.

Z=tom is made at the first bossed_by expression.

• Y=ann at the second bossed_by expression.

A=ann is made on rule exit.

Backtracking with rules

Backtracking always returns to the most recent action.

That includes rule-entry and rule-exit; it helps to make these columns in the zigzag diagram. Skip columns when both facts and rules can match a query expression.

Query: ?- a(X), d(X).

Database: b(0).

b(1).

a(3).

a(Y) :- b(Y), c(Y).

c(1).

c(2).

c(0).

d(R) :- c(Z), e(R).

e(1).

Zigzag diagram for example a(Y) succeeds

 b(Y) c(Y) a(X) d(R) c(Z) e(R)

X=3

R=3

Z=1

 fails

Z=2

 fails

Z=0

 fails

 fails

 fails

Y=0

 succeeds

X=0

R=0

Z=1

 fails

Z=2

 fails

Z=0

 fails

 fails

 fails

 fails

 fails

Y=1

 succeeds

X=1

R=1

Z=1

 succeeds

Don’t define transitivity with one rule

Suppose you define transitivity as per mathematics books: on(d,c).

on(c,b).

on(b,a).

on(X,Y) :- on(X,Z), on(Z,Y).

This gives an answer of "yes" to the query on(d,a), But it gets stuck in an infinite loop for ?- on(r,s):

1. Bindings X=r and Y=s are made in on(X,Y).

2. In on(X,Z), the first argument is bound to r and second argument is unbound.

3. X=r is made in on(X,Y) in this recursive call.

4. In on(X,Z) in the recursive call, the first argument is r from step 3 and the second argument is unbound.

5. But step 4 = step 2. We've got an infinite loop.

AI programming style in general

• Lots of short rules. (So you can easily chain them.) Rules refer to one another, sometimes recursively.

• Rules usually should be interpreted "declaratively"

(as a logical description of a result), not

"procedurally" (as steps to be followed). I.e.,

"what", not "how".

• So don't worry too much about exactly what a program will do when it starts running, but treat the program as an answer specification.

• This is especially helpful in understanding recursive programs.

Traffic lights program

Two ways to use:

?-action(car,stop).

(Checks if action specified is legal with current facts)

?-action(car,X).

(Asks for a legal action, given current facts)

Format of the facts:

light(<color>,<state>) for solid-color light facts

light(arrow,<color>,<direction>) for arrow lights

light(<form>,<state>) for pedestrian signals

safe_stop_possible if car can stop before intersection

clockwise_cross if pedestrian moves clockwise around intersection

Traffic-lights rules action(car,stop) :- light(yellow_arrow,Direction), safe_stop_possible.

action(car,yield_and_leftturn) :light(yellow_arrow,left), \+ safe_stop_possible.

action(car,yield_and_rightturn) :light(yellow_arrow,right), \+ safe_stop_possible.

action(car,yield_and_leftturn) :light(green_arrow,left).

action(car,yield_and_rightturn) :light(green_arrow,right).

action(car,stop) :- light(red,steady).

action(car,stop_and_go) :- light(red,flashing).

action(car,stop) :- light(yellow,steady), safe_stop_possible.

action(car,yield_and_go) :- light(yellow,steady),

\+ safe_stop_possible.

action(car,yield_and_go) :- light(green,steady).

action(car,slow) :- light(yellow,flashing).

action(car,stop) :- light(red_arrow,Direction).

action(pedestrian,stop) :- pedhalt(steady).

action(pedestrian,stop) :- \+ pedsignals, greenfacing.

action(pedestrian,stop) :- pedhalt(flashing), safe_stop_possible.

action(pedestrian,yield_and_go) :- pedhalt(flashing),

\+ safe_stop_possible.

action(pedestrian,A) :- \+ pedsignals, \+ greenfacing, action(car,A).

action(A,go) :- \+ cautious_action_recommended(A).

pedsignals :- (pedhalt(State); pedgo(State)).

pedhalt(State) :- (light(wait,State) light(dont_walk,State); light(hand,State) ).

pedgo(State) :- (light(walk,State); light(walking_person,State)).

greenfacing :- light(green_arrow,right),

\+ clockwise_cross.

greenfacing :- light(green_arrow,left), clockwise_cross.

cautious_action_recommended(X) :- (action(X,stop); action(X,stop_and_go); action(X,yield_and_go); action(X,yield_and_rightturn); action(X,yield_and_leftturn) ).

Defaults

= General-purpose rules that can be overridden by exceptions.

In Prolog, put the exception facts first, with ":- !." at end of each. That’s the "cut symbol" which prevents backtracking if the fact matches.

Example (with inheritance as default): location(truck_3459, spanagel_lot).

location(truck_3459_radio, joes_repair_shop) :part_of(truck_3459_radio, truck_3459), !.

location(X,L) :- part_of(X,Y), location(Y,L).

Cut predicates always succeed, but have the side effect of throwing away backtracking information for the left-side expression. They can be tricky to use, since they are purely procedural programming.

Practice question #1

Consider an accounting department. Describe the direction of inheritance, if any, of the following properties with respect to part_of : (a) there are crooks in it; (b) half the employees in it are crooks; (c) regulations controlling crookedness are enforced; and (d) the crooks in it have been caught and punished.

Practice question #2

(a) Clint is a movie star; Clint is mayor; hence a movie star is mayor. But consider: John is a little stupid; John is mayor; hence a little stupid is mayor. What's wrong?

(b) Clint is the mayor; the mayor is respected; hence

Clint is respected. But consider: Clint is the mayor; the mayor is an elected office; hence Clint is an elected office. What's wrong?

(c) Clint is a movie star; a movie star is a celebrity; hence Clint is a celebrity. But consider: Clint is a movie star; a movie star is rare in Monterey; hence

Clint is rare in Monterey. What's wrong?

Practice question #3

3. Draw a zigzag diagram showing how all the answers are found by a Prolog interpreter to the query:

?- u(X,Y), u(Y,Z), \+ u(X,Z).

with database: u(a,b).

u(b,b).

u(c,d).

u(d,a).

u(d,c).

u(X,Y)

X=a,Y=b

X=b, Y=b

X=c, Y=d

X=d, Y=a

X=d, Y=c

 fails

Answer to practice question 3 u(Y,Z)

Z=b

 fails

Z=b

 fails

Z=a

\+ u(X,Z) fails

 fails

Z=c

 fails

Z=b

 succeeds

 fails

 succeeds

 fails

 succeed

 fails

 fails

Z=d

 fails

 succeeds

 fails

Practice question #4

(a) List in order all answers found by the query

?- o(M,N).

for the following database. (No zigzag diagram necessary.) p(R,S,T) :- o(R,S), o(S,T).

o(X,Y) :- oo(X,Y).

o(X,Y) :- oo(X,Z), oo(Z,Y).

oo(c,d).

oo(a,b).

oo(b,c) .

(b) List in order all answers found to the query

?- p(E,F,G).

on the preceding database.

Practice question #5

(a) Which of the following (pick only one) is a

Prolog rule for downward inheritance of "owns" with respect to the part-of relationship?

( owns(P,T) means P owns thing T.) part_of(P,T) :- owns(P,Q), part_of(Q,T).

part_of(P,T) :- owns(U,T), part_of(U,P).

part_of(P,T) :- part_of(T,Q), owns(P,T).

owns(P,T) :- part_of(P,Q), owns(Q,T).

owns(P,T) :- part_of(T,U), owns(U,P).

owns(P,T) :- owns(P,Q), owns(Q,T).

(b) Suppose the U.S. Navy owns the Enterprise.

Hence the U.S. Government owns the Enterprise; does that follow from the inheritance rule you selected above? If so, what do the variables match? If not, why not?

Practice question #6

Suppose predicate necessary(X,Y) means that a specific single action X must occur before specific single action Y can occur.

(a) Is predicate necessary transitive?

(b) Consider the predicate before9(X ) which is true if specific single action X occurred before 9AM on February 10, 1986. Does before9 inherit with respect to necessary in any way? If so, describe how.

Practice question #7

(a) Express the following in predicate calculus using only predicates for (i) existence of a threat, (ii) presence of an aerial object, (iii) speed toward you, (iv) whether something is identified, and (v) greater_than.

A threat is an aerial object coming toward you at more than 30 knots, or an aerial object of some speed for which it is not true that either it is identified or it is going less than or equal to 5 knots toward you.

(b) Use the distributive law and a DeMorgan's Law on the predicate-calculus form of the rule to to simplify it and remove redundancy.

Practice question #8

(a) Represent the following statements in predicate calculus using exactly four predicates, one quantifier, and one variable representing "military officer". (Hint: use oneletter names.)

Either Congress will cut defense and get a sufficiently balanced budget, or Congress will cut defense and every military officer will be worried about their job. Both of the following are also true: (1) Congress will not get a sufficiently balanced budget; (2) if Congress will cut defense, military promotions will be harder to get.

(b) Using the above statements and the equivalences and proof methods of predicate calculus given in the notes, prove that military promotions will be harder to get.

Download