Assume we have the following Prolog database:
parent(tom, liz).
parent(tim, bob).
parent(bob, ann).
parent(bob, pat).
parent(pat, jim).
male(tim).
male(tom).
male(bob).
male(jim).
female(pam).
female(liz).
female(pat).
female(ann).
mother(X) :- parent(X, _), female(X).
- Write Prolog queries for the following questions:
- Who is Ann’s parent?
- Is Jim Bob’s child?
- Who is Jim’s grandparent?
- Write a rule that describes a child, so that
child(X, Y)
meansX
is the child ofY
. Don’t allow a person to be his or her own child. - Define an ancestor rule. An ancestor is a parent of a person, a
grandparent, a great-grandparent, etc. Naturally, this rule is
recursive (like the
member
predicate in the notes). - Define a “has no parents” rule. Use negation (“negation as failure”).
Make sure you actually test your queries and rules with SWI-Prolog! And look at the video from Day 13, about the 14 minute mark, for help.
Do the following unify, and if so, what are values for the variables that make the unification work? Note: Each pair of terms has new variable assignments. Look at the video from Day 14 for help.
parent(tom, liz)
andparent(tom, X)
parent(X, liz)
andparent(liz, X)
parent(X, Y)
andparent(Y, X)
head(X, [a, b, c])
andhead(b, [a, b, c])
head(foo(Y), X)
andhead(foo(Z), [foo(w)])
foo(bar(a, b), baz(c))
andfoo(bar(X), baz(Y))
Draw a resolution tree for mother(X)
, refering back to the database
above. Note that there is a particular order by which Prolog creates
subgoals (that is, the order that facts/rules are written in the
knowledge base). You only need to show the tree until the first time
the predicate is proved. Look at the video from Day 14 for help.
Extend the Prolog program at the bottom of this page to support the
following interactions. (The user types the stuff after the |:
) Look
at the video from Day 15, starting at about the 18 minute mark, for
help. In particular, you’ll need to use assertz
(21:30 mark in the
video). *Write this in a Prolog source file (hw6.pl
maybe), and test
your code. Submit the source file so the grader can also test your
code.*
?- consult('nldb.pl'). % library(error) compiled into error 0.00 sec, 18,352 bytes % library(lists) compiled into lists 0.01 sec, 46,096 bytes % library(readln) compiled into readln 0.01 sec, 60,696 bytes % nldb.pl compiled 0.01 sec, 78,560 bytes true. ?- run. |: quit. Ok we're done! true. ?- run. |: anteater is bigger than ant. Ok, I learned that ant is smaller than anteater |: ant is smaller than foot. Ok, I learned that ant is smaller than foot |: what is bigger than ant? These are bigger: anteater, foot. |: what is smaller than anteater? These are smaller: ant. |: what is smaller than ant? These are smaller: |: godzilla is bigger than anteater. Ok, I learned that anteater is smaller than godzilla |: what is bigger than ant? These are bigger: anteater, foot, godzilla. |: what is smaller than godzilla? These are smaller: anteater, ant. |: today is thursday. Ok, I learned that today is a/an thursday |: socrates is mortal. Ok, I learned that socrates is a/an mortal |: what is socrates? socrates is a/an: mortal. |: what is today? today is a/an: thursday. |: what is xyz? I'm not sure! Care to tell me? |: is xyz abc? No |: xyz is abc. Ok, I learned that xyz is a/an abc |: is xyz abc? Yes |: what is 15? 15 |: what is 2 + 2? 4 |: what is 2 - 3 * 5? -13 |: what is 2 * 3 - 2? 2 |: what is 4 / 3? 1.3333333333333333 |: wow, you are very smart! Huh? |: quit. Ok we're done! true. ?-
Start with this code. Pay special attention to the “TODO” comments.
:- use_module(library(readln)).
% these allow us to use assertz with these two predicates
:- dynamic(learned_isa/2).
:- dynamic(learned_smaller/2).
% strip_puncation/2 & read_sentence/1 from The Art of Prolog 2nd Ed. (Sterling & Shaprio)
strip_punctuation([], []).
strip_punctuation([Word|Tail], [Word|Result]) :-
\+(member(Word, ['.', ',', '?', '!'])),
strip_punctuation(Tail, Result).
strip_punctuation([_|Tail], Result) :-
strip_punctuation(Tail, Result).
read_sentence(Input) :-
readln(Input1),
strip_punctuation(Input1, Input).
reply([Head|Tail]) :- write(Head), write(' '), reply(Tail).
reply([]) :- nl.
% TODO: code reply_list/1
run :- read_sentence(Input), run(Input), !.
run(['quit']) :- reply(['Ok we\'re done!']).
run(Input) :-
process_sentence(Input),
read_sentence(NextInput),
!, run(NextInput).
process_sentence([what, is, bigger, than, Object]) :-
% TODO: code findall using Object and creating Things
reply(['These are bigger:']),
reply_list(Things).
process_sentence([what, is, smaller, than, Object]) :-
% TODO: finish predicate
process_sentence([what, is | Math]) :-
math(Math, Z),
reply([Z]).
process_sentence([what, is, Object]) :-
% TODO: finish predicate
process_sentence([what, is, _]) :-
reply(['I''m not sure! Care to tell me?']).
process_sentence([is, Subject, Object]) :-
% TODO: put a line of code here
reply(['Yes']).
% TODO: handle case where "is xyz abc" says "No"
% (i.e., above predicate failed)
process_sentence([Subject, is, Object]) :-
assertz(learned_isa(Subject, Object)),
reply(['Ok, I learned that', Subject, 'is a/an', Object]).
% TODO: handle "x is bigger than y" and "x is smaller than y"
% similarly to how "is" is handled above,
% using assertz(learned_smaller(...))
process_sentence(_) :-
reply(['Huh?']).
% right-associative math
% default math case (an atom)
math(X, Z) :-
number(X),
Z = X.
% default math case (a list)
math([X], Z) :-
number(X),
Z = X.
math([X, + | Tail], Z) :-
% TODO: finish predicate
% TODO: code rest of math
isa(X, Y) :- learned_isa(X, Y).
% TODO: code transitive isa
smaller(X, Y) :- learned_smaller(X, Y).
% TODO: code transitive smaller