% This is as summary of the Adventure in Prolog Tutorial % % ----------------------------- 1. Getting started ----------------------------------------% % swipl % consult(amazing). % later: reconsult(amazing). % -------------- 2-4. Facts, Simple Queries, Compount Queries ----------------% % Declare the rooms (order matters: top 2 bottom!) room(kitchen). room(office). room(hall). room('dining room'). room(cellar). %?- room(X). % Declare the locations of things location(desk, office). location(apple, kitchen). location(flashlight, desk). location('washing machine', cellar). location(nani, 'washing machine'). location(broccoli, kitchen). location(crackers, kitchen). location(computer, office). %?- location(X,kitchen). % Compount queries: order matters left 2 right. %?- room(X),location(X,Y). %?- room(Y),location(X,Y). % Declare the doors that communicate rooms door(office, hall). door(kitchen, office). door(hall, 'dining room'). door(kitchen, cellar). door('dining room', kitchen). % Identify where I can go from the kitchen and what I can get there! %?- door(kitchen, R), location(T,R). % Declare properties of some food edible(apple). edible(crackers). tastes_yucky(broccoli). % Declare flashlight's status as well as player's location. turned_off(flashlight). here(kitchen). % Built-in predicates: write, nl, fail %?- location(X, kitchen), write(X) ,nl, fail. %?- door(kitchen, R), write(R), nl, location(T,R), tab(3), write(T), nl, fail. % ----------------------------- 5. Rules ----------------------------------------% % A rule to infer where do I have food: where_food(X,Y) :- location(X,Y), edible(X). % ?- where_food(X,Y). % ?- where_food(X, kitchen). % Multiple rules for a predicate: order top 2 bottom! where_food(X,Y) :- location(X,Y), edible(X). where_food(X,Y) :- location(X,Y), tastes_yucky(X). % Using rules to connect two rooms using directed edges: X->Y, Y->X. connect(X,Y) :- door(X,Y). connect(X,Y) :- door(Y,X). % List all bi-directional connections (edges). % ?- connect(X,Y). % A rule to list things in a given Place. % Look at X list_things(Place) :- location(X, Place), tab(2), write(X), nl, fail. list_things(_). % Anonymous variable to avoid the fail of the first list_things rule. % ?- list_things(Place). % ?- list_things(cellar). % List now connection between places list_connections(Place) :- connect(Place, X), tab(2), write(X), nl, fail. list_connections(_). % ?- list_connections(hall). % A rule for looking around all the places you are look :- here(Place), write('You are in the '), write(Place), nl, write('You can see:'), nl, list_things(Place), write('You can go to:'), nl, list_connections(Place). % ?- look. % ------------------------------ 6. Arithmetics----------------------------------------% % is: the arithmetic assignment! do not use '=' % ?- X is 10. % Errors: % ?- X is X+10. % ?- X = X+10. % ?- X is 10, X is X+10. % Rules for Centigrates to Farenheit: c_to_f(C,F) :- F is C * 9 / 5 + 32. freezing(F) :- F =< 32. % ?- c_to_f(100,X). % ?- freezing(15). % Error: % ?- freezing(X). % See variable pointer (not value). % ?- writeln(X). % But from-left to-rigth we instantiate X: %?- c_to_f(100,X), freezing(X). % ------------------------ 7. Managing Data: Dynamic Predicates---------------------------% % Here tells me where I am %?- here(Place). % But I want to move somewhere. First_check: can_go(Place):- here(X), connect(X, Place). % This rule is for completness but it adds a "singleton variable" (only in the left). can_go(Place):- write('You can''t get there from here.'), nl, fail. %?- can_go(hall). % Next, I need a goto(Place) predicate to go somewhere and look. goto(Place):- can_go(Place), move(Place), look. move(Place):- retract(here(X)), asserta(here(Place)). % Error: % ?- goto(office). % We must first declare here(X) as dynamic predicate!!!!! % dynamic here/1. % ?- goto(office). % ?- here(X). % We can also take an object from a location (thereafter the object is not there). take(X):- can_take(X), take_object(X). can_take(Thing) :- here(Place), location(Thing, Place). can_take(Thing) :- write('There is no '), write(Thing), write(' here.'), nl, fail. % Taking an object means: (1) removing from its location, (2) assert new predicate have(X). take_object(X):- can_take(X), retract(location(X,_)), asserta(have(X)), write('taken'), nl. % dynamic location/2. % Take all objects I can take from where I am: %?-goto(kitchen). %?-listing(location). %?- take_object(X). %?-listing(location). %?-listing(have). % ---------------------------- 8. Recursion -------------------------------------% % % Create nested items location(envelope, desk). location(stamp, envelope). location(key, envelope). is_contained_in(T1,T2) :- location(T1,T2). % Add recursion to go deeper: is_contained_in(T1,T2) :- location(X,T2), is_contained_in(T1,X). %?- listing(location). %?- is_contained_in(X, office). % Exercise: implement the rules for factorial(X,Y), where Y is factorial of X. factorial(0,1). factorial(X,Y):- X>0, Z is X-1, factorial(Z,Y2), Y is Y2*X. % ---------------------------- 11. Lists -------------------------------------% % % Example: Alternative way of represent locations of things loc_list([apple, broccoli, crackers], kitchen). loc_list([desk, computer], office). loc_list([flashlight, envelope], desk). loc_list([stamp, key], envelope). loc_list(['washing machine'], cellar). loc_list([nani], 'washing machine'). % Empty list: there is nothing in the hall. Explicitly: loc_list([], hall). % Return things of the kitchen in a list: %?- loc_list(X, kitchen). % Head and tail of a list. %?- [Head|Tail] = [apple, broccoli, refrigerator]. % Member of a list % ?- member(apple, [apple, broccoli, crackers]). % ?- member(X, [apple, broccoli, crackers]).