Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I am reading "Learn Prolog Now" and one of its exercises I haven't been able to solve myself is the following:
There is a street with three
neighboring houses that all have a
different color. They are red, blue,
and green. People of different
nationalities live in the different
houses and they all have a different
pet. Here are some more facts about
them:
The Englishman lives in the red house.
The jaguar is the pet of the Spanish family.
The Japanese lives to the right of the snail keeper.
The snail keeper lives to the left of the blue house.
Who keeps the zebra?
Define a predicate zebra/1 that tells you the nationality of the owner of the zebra.
Hint: Think of a representation for the houses and the street. Code the four constraints in Prolog. member and sublist might be useful predicates.
Any ideas how to code it under Prolog? Thanks.
neigh(Left, Right, List) :-
List = [Left | [Right | _]];
List = [_ | [Left | [Right]]].
zebraowner(Houses, ZebraOwner):-
member([englishman, _, red], Houses),
member([spanish, jaguar, _], Houses),
neigh([_, snail, _], [japanese, _, _], Houses),
neigh([_, snail, _], [_, _, blue], Houses),
member([ZebraOwner, zebra, _], Houses),
member([_, _, green], Houses).
zebra(X) :- zebraowner([_, _, _], X).
I'm new to Prolog, but I think the definition of neigh is not quite right.Try:
neigh(2,3,[1,2,3]).
You get away with this not quite working because there are two solutions, one with the Japanese owned zebra in the second house, and one with the zebra in the third house and your code only finds one (which is enough to answer the question :-).
This code give the right answers for neigh and hence both answers to the problem:
neigh(Left, Right, List) :-
List = [Left, Right ,_];
List = [_, Left, Right]].
but then only works for three houses. A more general implementation is:
neigh(Left, Right, List) :-
List = [Left , Right | _].
neigh(Left, Right, [_|Tail]) :-
neigh(Left, Right, Tail).
Related
The Cousin Explainer
Write a program that when given a person of reference and a degree the program can tell me all of the nth degree cousins that person has. I've started by writing my facts: male/1 female/1 and child/2 these are populated with the names of my family members. I then began writing rules for cousins I figured id write a different rule for every degree so only up to the third cousins. The problems I'm having are as follows.
firstCousin_of(X,Y):-child(X,Z1),child(Y,Z2),child(Z1,Z),child(Z2,Z). I have this to find a first cousin but the 2nd cousin is more complicated which makes me think there has gotta be a way to do this recursively.
I need the rule, all_cousins(Person, Degree, ListOfCousins), which after figuring out all of the nth degree cousins edits a list of all cousins to only include those specific nth degree cousins. I'm used to imperative languages and all i can think about with this is how do I even convey to the rule which people to remove from the list from one rule to another.
lastly I have a rule, all_cousinsRemoved(Person, Degree, removed(Number, Direction), ListOfCousins) that I don't even know where to start with but ill need the all_cousins rule for this one because it does the same thing but also only includes cousins in the edited lists w=that were removed nth times either up or down.
The best solutions is make a several rules that call other rules, here an example
male(dicky).
male(randy).
male(mike).
male(don).
male(elmer).
female(anne).
female(rosie).
female(esther).
female(mildred).
female(greatgramma).
male(blair).
male(god).
female(god).
parent(don,randy).
parent(don,mike).
parent(don,anne).
parent(rosie,randy).
parent(rosie,mike).
parent(rosie,anne).
parent(elmer,don).
parent(mildred,don).
parent(esther,rosie).
parent(esther,dicky).
parent(greatgramma,esther).
parent(randy,blair).
male(mel).
male(teo).
parent(melsr,mel).
parent(melsr,teo).
american(anne).
american(X) :- ancestor(X,anne).
american(X) :- ancestor(anne,X).
relation(X,Y) :- ancestor(A,X), ancestor(A,Y).
father(X,Y) :- male(X),parent(X,Y).
father(god, _) :- male(god).
mother(X,Y) :- female(X),parent(X,Y).
son(X,Y) :- male(X),parent(Y,X).
daughter(X,Y) :- female(X),parent(Y,X).
grandfather(X,Y) :- male(X),parent(X,Somebody),parent(Somebody,Y).
aunt(X,Y) :- female(X),sister(X,Mom),mother(Mom,Y).
aunt(X,Y) :- female(X),sister(X,Dad),father(Dad,Y).
sister(X,Y) :- female(X),parent(Par,X),parent(Par,Y), X \= Y.
uncle(X,Y) :- brother(X,Par),parent(Par,Y).
cousin(X,Y) :- uncle(Unc , X),father(Unc,Y).
ancestor(X,Y) :- parent(X,Y).
ancestor(X,Y) :- parent(X,Somebody),ancestor(Somebody,Y).
brother(X,Y) :- male(X),parent(Somebody,X),parent(Somebody,Y), X \= Y.
Retrived from this repository
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I am new to Prolog kindly assist.
Hunter, Laura, Jim, Sally, and Jack work in the same building with five adjacent offices. Hunter doesn’t work in the 5th office and Laura doesn’t work in the first office. Jim doesn’t work in the first or last office, and he is not in an office adjacent to Jack or Laura. Sally works in some office higher than Laura’s. Who works in what offices?
Write a Prolog program to solve this problem. Define what adjacency is, then what the offices are, and then create a layout(X) that allows you to put in all the rules.
Each person is put into an office that doesn’t break any of the rules given.
In this answer we use clpfd. Read a tutorial on clpfd for details!
:- use_module(library(clpfd)).
puzzle(P) :-
puzzle_vars(P, Zs),
labeling([], Zs).
puzzle_vars(P, Zs) :-
P = [hunter-Hunter, jack-Jack, jim-Jim,
laura-Laura, sally-Sally],
Zs = [Hunter,Laura,Jim,Sally,Jack],
Zs ins 1..5,
all_different(Zs),
Hunter #\= 5,
Laura #\= 1,
Jim #\= 1,
Jim #\= 5,
abs(Jim-Jack) #\= 1,
abs(Jim-Laura) #\= 1,
Sally #> Laura.
Who works in what offices? Let's ask Prolog!
?- puzzle(P).
P = [hunter-3, jack-1, jim-4, laura-2, sally-5]
; false.
Instructions: Modify the attached program so that in order for the monkey to reach the bananas, he has to stand on a smaller box, which he has placed on top of a bigger one. At the beginning of the program, the boxes should be in two different locations in the room. Display on the screen the activities of the monkey.
I've been reading through the textbook (Prolog Programming for Artificial Intelligence), and Prolog is definitely proving difficult to pick up. While the book goes over how to solve the problem if there is one box, it does not mention how to begin to tackle this problem if there is more than one box. Any guidance / suggestions would be greatly appreciated.
move(state(middle, onbox, middle, hasnot), grasp, state(middle, onbox, middle, has)).
move(state(Pos, onfloor, Pos, H), climb, state(Pos, onbox, Pos, H)).
move(state(P1, onfloor, P1, H), push(P1, P2), state(P2, onfloor, P2, H)).
move(state(P1, onfloor, P, H), walk(P1, P2), state(P2, onfloor, P, H)).
canget(state(_ ,_ ,_ , has)).
canget(state1) :-
move(State1, Move, State2),
canget(State2).
Question:
canget(state(atdoor, onfloor, atwindow, hasnot)). % (monkey's horizontal position, monkey's vertical position, position of the box, and whether or not the monkey has the banana).
Only thing I can think of is to add another field to every clause for the second box's position, e.g., state(horizontal pos, vertical pos, pos for box1, pos for box2, and banana status).
Your suggested solution is one way to solve this: You can indeed simply add one more argument to the term that represents the state.
However, let us aim for something more general: How would you go about this if there are not only one or two, but n boxes in the room? Further, let us suppose the boxes are of sizes S_1, ..., S_n (S_i not necessarily distinct), and can only be stacked when the box on top is smaller than the one on which it is placed.
I suggest the following representation to denote such states:
We will use a pair Pos-Size to denote the position and size of each box. This is just infix notation for the term -(Pos, Size), i.e., functor - and arity 2.
We will use a list of such pairs, i.e., [Pos1-Size1, Pos2-Size2, ..., Pos_n-Size_n] to represent all boxes.
When stacking boxes at the same position, we need to ensure that the boxes that are already located at the same position allow such stacking. I leave this is an exercise for you.
Further, canget/1 is not really that interesting, is it? What we actually care about is the list of moves that take us to the solution! Hence, we extend the predicate with one argument that actually lets us see all moves on the toplevel, and use a more speaking name to denote what we are actually describing:
moves(state(_ ,_ ,_ , has), []).
moves(State0, [Move|Moves]) :-
move(State0, Move, State),
moves(State, Moves).
Now we can use iterative deepening to find concrete solutions:
?- length(Ms, _), moves(State0, Ms).
where State0 is the initial state of the puzzle.
When you become more experienced with Prolog, you will increasingly use dcg notation to describe lists, in order to simplify the code. I leave this version here for you to study later:
moves(state(_ ,_ ,_ , has)) --> [].
moves(State0) --> [Move],
{ move(State0, Move, State) },
moves(State).
Usage example, again using iterative deepening to find a shortest solution:
?- length(Ms, _), phrase(moves(State0), Ms).
Have fun, and also try The Art of Prolog!
i'm new to prolog and I want to solve the puzzle Akkoy with restrictions.
So far, i've been able to implement wich cells can be painted but i don't know how to force the white areas to have all the same area.
For now when solving the problem, prolog gives two answers, but I want only the first one.
Right Answer
Wrong Answer
akkoy_solver(Rows, Cols) :-
length(Rows, X),
length(Cols, Y),
make_grid(Grid, X, Y, Vars),
reset_timer,
solver(Rows, Cols, Grid),
label(Vars),
printAkkoy(Grid, Rows, Cols),
print_time,
statistics, nl.
i downloaded some facts from open streetmap project, you can download it here http://www.mediafire.com/?15pttpp847ld71x
This program am trying to come up with will help a user get itinerary from one place to another giving shortest routes possible, someone can tell me how to implement Dijkstra's algorithm to search paths, also i had this predicate in mind -compute_path(User, Start, End, PathNodes) where User will be consistent with the user values from amsterdam.pl
Am trying to add extensions, maybe u can play with it, e.g the following:
.Tell Prolog what kind of user i am (e.g. pedestrian, cyclist,car driver, ...). then Prolog take this information into account when constructing an appropriate route. For example, a cyclist cannot use a highway.
· Make it possible to ask for an itinerary between a departure and an arrival address which explicitly visits a number of user-specified places (i.e. the user can specify that he wants to go from A to C via B).
· Make it possible to ask the Prolog for information such as "At what time do I have to leave Point A,to get to Point B,Amsterdam at 10:00AM?".
· Use human language interface like the one u just made such that the user can interact with the shell using
input like:
o how do I get from "NameA", Amsterdam to "NameB", Amsterdam
kindly get back to me if u were able to implement this, i will appreciate so much, am new in Prolog and trying to be a fast learner.
this is the code i have tried to come up with
:-dynamic(node/3).
:-dynamic(way/2).
% some nodes
node(46315543, 52.35548, 4.84315).
node(46315968, 52.35558, 4.84068).
node(46315971, 52.35531, 4.84986).
% predicate to add a node to a way
add_node_to_way(WayID, NodeID) :-
way(WayID, NodeList),
node(NodeID, _, _),
not(member(NodeID, NodeList)),
retract(way(WayID, NodeList)),
append(NodeList, [NodeID], NewNodeList),
assert(way(WayID, NewNodeList)).
% main menu
menu :-
write('1. list nodes\n'),
write('2. list ways\n'),
write('3. create node\n'),
write('4. create way\n'),
write('5. add node to way\n'),
write('6. exit\n'),
nl,
write('your option: '),
read(Option),
process(Option).
menu :-
menu.
process(1) :-
node(ID, Lat, Long),
writef('node with ID = %d, lat = %d and long = %d\n', [ID, Lat, Long]),
fail.
process(2) :-
way(ID, NodeList),
writef('way with ID = %d and nodelist = ', [ID, NodeList]),
write(NodeList),
nl,
fail.
process(3) :-
write('enter node ID: '),
read(ID),
not(node(ID, _, _)),
write('enter lat: '),
read(Lat),
write('enter long: '),
read(Long),
assert(node(ID, Lat, Long)),
fail.
process(4) :-
write('enter way ID: '),
read(ID),
not(way(ID, _)),
assert(way(ID, [])),
fail.
process(5) :-
write('enter ID of node to add: '),
read(NodeID),
node(NodeID, _, _),
write('enter ID of way to add to: '),
read(WayID),
way(WayID, _),
add_node_to_way(WayID, NodeID),
fail.
process(6) :-
% exit point
write('bye').
Some years ago I was doing something similar with the so called A* search. This search is better suited for planar non-maze like problems than Dijkstra's algorithm. A* search adds to Dijkstra's algorithm a current node to goal node distance estimator and combines it with the already archived minimal distance.
A very good result can be obtained when main roads are differently weighted compared to smaller roads. So that the algorithm first search the main roads, and only diverts into smaller roads when close to the goal or start. A very nice book which develops the A* algorithm is the following:
Nilsson, N. J. (1980). Principles of Artificial Intelligence.
Palo Alto, California: Tioga Publishing Company.
Best Regards