Prolog Small Assignment
DUE: Wed, December 12 at 11:55pm
Please submit the log of your session along with your Prolog file on Canvas. You should probably save it in your repo just in case something bad happens in the submission.
For coding, this assignment requires you to convert the Matrix logic into Prolog code. Additionally, you will have to write exactly 3 lines of Prolog code related to the size of a list.
You can try installing Prolog on your personal machine by going to http://www.swi-prolog.org/ or use the cselabs machines.
The Basics
- Create a text file that contains your KB.
- Start Prolog with swipl.
- Load your KB with consult(<filename>). Don’t use extension .pl.
- Reload your KB (after you make changes to the file) with reconsult(<filename>)..
- Ask Prolog something about your KB at the ?-prompt, followed by a period.
- If more than one answer is possible, type ;to see more.
- See backchaining in action by starting
- Halt a trace with a.
- Stop seeing all the action with
- Record your session with protocol(‘<filename>.txt’).
- Stop recording with
- Leave Prolog with or Ctrl-d.
The Matrix (10 pts)
Create a file in your favorite text editor called oracle.pl . In that file, create a Prolog knowledge base from the below knowledge base about the movie Matrix:
Noob(Neo) Disenchanted(Trinity) Loves(Trinity, Neo) forall x Noob(x) -> VisitsOracle(x) forall x Disenchanted(x) -> VisitsOracle(x) forall x VisitsOracle(x) -> PicksTheOne(x) forall x Noob(x) and VisitsOracle(x) -> OracleSaysNotTheOne(x) forall x Noob(x) and VisitsOracle(x) -> Disenchanted(x) forall x,y OraclesSaysNotTheOne(x) and Loves(y,x) and PicksTheOne(y) -> TheOne(x)
Recall that forall x Noob(x) and VisitsOracle(x) -> Disenchanted(x) and Noob(Neo) in Prolog is written as:
disenchanted(X) :- noob(X), visitsoracle(X). noob(neo).
Notice:
- lower case means it is a constant or a predicate.
- upper case means it is a variable.
- conclusions are written first, followed by “:-” to mean implication.
- comma’s are used for and’s.
- every sentence must finish with a period.
Lists (10 pts)
For a completely unrelated problem (but please put it in the same file), add this Prolog code about the number of times (N) that element E appears in a list:
count(E,[],0). count(E,[E|T],N) :- count(E,T,M), N is M+1. count(E,[H|T],N) :- \+ E==H, count(E,T,N).
- The first line means that the element E appears 0 times in an empty list [ ].
- The second line means that if the count is currently M and E is found in the list, then the new count is N=M+1 and continue looking through the rest of the list (T).
- The third line means that if the count is currently N and E is not at the head of the list, then keep the count the same and continue looking in the rest of the list (T).
Write 3 lines of code (i.e. 3 implications) that allow a user to ask about specific number of elements. The ASKs should look something like this:
exactly1(a,[a,b,c]). atmost1(a,[a,b]). atleast1(a,[a,b,c,a]).
If one asks exactly1(a,[a,b,c])., then Prolog should return True, because there is exactly 1 “a” in the list. If one asks exactly1(a,[a,a,b,c]). or exactly1(a,[b,c]). , then Prolog should return False.
Running Prolog
You can try installing Prolog on your personal machine by going to http://www.swi-prolog.org/ or use the cselabs machines.
At the command prompt at the location where your oracle.pl file is located, enter swipl. You should now see the Prolog command prompt “?-“, meaning “ask me something.”
Load your file with “consult(oracle).” Don’t forget that period!
If ever you need to reload your file, type “reconsult(oracle).”.
Test your code by entering in the following:
theone(neo).
Remember, lower case for predicates and constants. Always include a period.
If everything was entered correctly, you should get back true.
Type a period to stop the KB from searching for more answers. Or hit “;” to see more answers.
Try this …
theone(X).
Now let’s see how this works. You will use trace to see how the KB backward chains through your rules. As long as you see [trace] at the prompt, it will show backward chaining.
trace.
theone(neo).
press the “enter” key until it returns true
If ever you see “|”, this means it is waiting for more input — press period and return. If ever you are in the middle of a trace and you want to abort, type ‘a’.
Let’s see how count works. But first we will turn trace off.
notrace.
count(a,[a,b,c],N). count(a,[a,b,a,c],N). count(a,[b,c],N). count(E,[a,b,c],N). count(a,L,2). count(E,[a,b,c,b],2).
Think about what is being asked of KB. In order …
- How many ‘a’ in [a,b,c]?
- How many ‘a’ in [a,b,a,c]?
- How many ‘a’ in [b,c]?
- What elements are there in this list and how many of each?
- What list has 2 ‘a’s?
- Is there an element in [a,b,c,b] that appears 2 times?
Fun, right!
If ever it seems to hang – probably backchaining infinitely – hit Ctrl-C, h, a.
Now we are ready to test your code.
exactly1(a,[a,b,c]). exactly1(a,[b,c]). exactly1(a,[a,b,c,a]). exactly1(b,L). atmost1(a,[a,b,c]). atmost1(a,[b,c]). atmost1(a,[a,b,c,a]). atmost1(b,L). atleast1(a,[a,b,c]). atleast1(a,[b,c]). atleast1(a,[a,b,c,a]). atleast1(b,L).
LOG Your Session (10 pts)
Once you are satisfied with everything working correctly, log your session in a file for submission. Even if your code isn’t working, please record the following session. Type in the following, line by line. You start saving your session with protocol.
protocol('session.txt'). trace. theone(neo). notrace. theone(X). trace. exactly1(a,[a,b,c]). notrace. exactly1(a,[b,c]). exactly1(a,[a,b,c,a]). trace. atmost1(a,[a,b,c]). notrace. atmost1(a,[b,c]). atmost1(a,[a,b,c,a]). trace. atleast1(a,[a,b,c]). notrace. atleast1(a,[b,c]). atleast1(a,[a,b,c,a]).
noprotocol.
Congrats! You are done. Submit your session and your oracle.pl file on CANVAS.