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.
Related
I'm trying to solve:
Given facts such as
Bob is taller than Mike.
Mike is taller than Jim
Jim is taller than George
Write a recursive program that will determine that Bob's height is greater than George's.
My solution so far is:
taller_than(bob, mike).
taller_than(mike, jim).
taller_than(jim, george).
taller_than(X,Y):-
taller_than(X, Z),
taller_than(Z, Y).
It returns True as expected, but then I reach the stack limit. I'm guessing I need a base case, but I'm not sure what it would be? Is my solution otherwise correct?
Oh so close.
Your main problem is that you have facts taller_than/2 and predicates taller_than/2 with the same signature. This even caught me off guard when I gave it an initial test run. You need to change the name of either the fact or the predicate. For this the name of the predicate is changed.
As you noted you need a base case and had you done the name change I think you would have figured this out also.
taller_than_rule(X,Y) :-
taller_than(X,Y).
taller_than_rule(X,Y) :-
taller_than(X, Z),
taller_than_rule(Z, Y).
Example run:
?- taller_than_rule(bob,Who).
Who = mike ;
Who = jim ;
Who = george ;
false.
Is there a way one can show all solutions and/or find how many there are in SICSTus prolog? For instance, the code below maybe used to solve the map colouring problem.
:- use_module(library(clpfd)).
solve_AUSTRALIA(WA,NT,Q,SA,NSW,V):-
domain([WA,NT,Q,SA,NSW,V], 1, 4),%colours represented by integers from 1 to 4
WA #\= NT,
WA #\= SA,
NT #\= SA,
NT #\= Q,
SA #\= Q,
SA #\= NSW,
SA #\= V,
Q #\= NSW,
NSW #\= V,
labeling([],[WA,NT,Q,SA,NSW,V]).
At the moment,I am typing ; every time to see further solutions till Prolog says no. Is there a way I can tell prolog to show all solutions at once, or better, a way I can find how many there. Like prolog tells me there are five solutions to the problem.
The following is for counting the number of answers. When you ask a query or execute a predicate, what you get back from Prolog are answers. Sometimes these answers are solutions, may contain more than one solution, infinitely many solutions, and sometimes even no solution at all.
The simplest way to go is to say findall(t, Goal_0, Ts), length(Ts, N). The only disadvantage is that this requires space proportional to the number of answers counted.
If you want to go one step further you need some kind of counter. Currently in SICStus 4.3.3 you can do this like so:
:- meta_predicate count_answers(0, ?).
:- meta_predicate count_answers1(0, +, ?). % internal
:- use_module(library(types),[must_be/4]).
:- use_module(library(structs),
[new/2,
dispose/1,
get_contents/3,
put_contents/3]).
count_answers(G_0, N) :-
( nonvar(N)
-> must_be(N, integer, count_answers(G_0, N), 2)
; true
),
new(unsigned_64, Ref),
call_cleanup(count_answers1(G_0, Ref, N), dispose(Ref) ).
count_answers1(G_0, Ref, N) :-
( call(G_0),
get_contents(Ref, contents, N0),
N1 is N0+1,
put_contents(Ref, contents, N1),
fail
; get_contents(Ref, contents, N)
).
See this answer how counters can be implemented in other systems. Example use:
| ?- count_answers(member(_,"abcde"),Ans).
Ans = 5 ? ;
no
Is there a way I can tell Prolog to show all solutions at once
This part of your question is related to the prolog-toplevel. In Prolog IV all answers (not necessarily solutions) were shown by default. The top level loop of a couple of Prolog systems permits to enter a to see all answers at once:
GNU-Prolog (originator)
Trealla-Prolog
Scryer-Prolog
Problem:
Jack is looking at Anne, Anne is looking at George
Jack is married, George is not.
Is a married person looking at an unmarried person?
I am looking at this solution found in this link which entails:
unmarried(X) :- not(married(X)).
unmarried("George").
unmarried("Anne").
married("Jack").
married("Anne").
looking_at("Jack", "Anne").
looking_at("Anne", "George").
check(X, Y):-
looking_at(X,Y),
married(X),
unmarried(Y).
There are several questions immediately apparent once this much is done. For the first part, I was confused as to why Anne is defined as Married("Anne") and Unmarried("Anne"), but I quickly put that aside assuming that it possibly means to define Anne as either married or unmarried
A quick look at SO doesn't help either, as I found only some remotely
related questions; This particular question being the closest one.
Now back to the problem that I have here...
unmarried(X) :- not(married(X)). handles the operation such that if Anne is passed as the first argument of check(_, _)
The programmer for that solution has handled it with a single check(_, _) according to which:
check(Anne,George) will infer:
Anne looking at George
Anne being married
George being unmarried
That compiler produces this result as:
Anne->Jack->Anne->Anne
George->Anne->George->George
At this point, I don't know why the compiler is producing those results. And as far as I know, this is not giving the solution either. In the old desktop version of prolog that I used, check(Anne,George). should have produced a YES, seeing as all the conditions were TRUE(Well I have never tried the online swi-prolog tbh; is it different?)
For check(Jack,Anne) it is:
Jack looking at Anne
Jack being married
Anne being unmarried
I don't see how this necessarily solves the problem. Could someone post a better solution or explain in detail how this is working?
Requirement:
I need a solution for the Problem that I posted at the begining of this question. If you can resolve it from the existing condition that I have posted, thats cool. However, I am also open to alternate ideas and solutions.
First lets look at the puzzle itself. The question "Is a married person looking at an unmarried person?" is clearly a yes/no question. Considering the marital status we have incomplete knowledge(Anne). The people who's marital status we know are not gazing at each other, so we have to consider Anne to find an answer. If we assume that:
Anne is married then the answer is yes because she is looking at the unmarried George.
Anne is not married then the answer is yes because the married Jack is looking at her.
So either way there is a married person looking at an unmarried person, thus the answer to the puzzle is yes.
Regarding the given solution: I think the author tries to model "Anne is either married or not married" by the facts married("Anne") and unmarried("Anne"). However the facts seem to express that Anne is married and unmarried at the same time. Also the rule unmarried(X) :- not(married(X)). in combination with the facts married/1 and unmarried/1 yields the solution "Anne" twice. Thus check/2 also yields the Anne-looks-at-George solution twice:
?- check(X,Y).
X = "Jack",
Y = "Anne" ? ;
X = "Anne",
Y = "George" ? ;
X = "Anne",
Y = "George"
I can see where the author is trying to go with his solution but it isn't really expressing that there is an assumption involved and how the two unique solutions are connected.
My attempt is the following: I would keep four facts from the original version and add another one for Anne:
married(jack).
unmarried(george).
looking_at(jack,anne).
looking_at(anne,george).
unknown(anne).
Then I can make assumptions about people who's marital status I don't know:
person_assumption(A,married) :- unknown(A).
person_assumption(A,unmarried) :- unknown(A).
Now the relevant cases for the yes-answer are: (1) a known unmarried person is being looked at by a known married person and (2) a person P1 is
looking at known unmarried person under the assumtion that P1 is married
AND
being looked at by a known married person under the assumption that P1 is unmarried
The predicate problematicgaze/1 is modeling these observations:
problematicgaze((P1-P2)) :- % case (1)
married(P1),
unmarried(P2),
looking_at(P1,P2).
problematicgaze((if_married(P1)-P2,P3-if_unmarried(P1))) :- % case (2)
assumedproblematic(if_married(P1),P2),
assumedproblematic(P3,if_unmarried(P1)).
assumedproblematic(if_married(P1),P2) :-
person_assumption(P1,married),
unmarried(P2),
looking_at(P1,P2).
assumedproblematic(P1,if_unmarried(P2)) :-
person_assumption(P2,unmarried),
married(P1),
looking_at(P1,P2).
This breaks down to: either I get a solution and the answer is yes or the predicate fails and the answer is no. So I ask if there is a problematic gaze in the given situation:
?- problematicgaze(G).
G = (if_married(anne)-george,jack-if_unmarried(anne)) ? ;
no
As expected there is no answer from the first rule of problematicgaze/1 but from the second. No matter which assumption is taken for Anne a married person is looking at an unmarried one. Other than that no solution is found.
The solution to which you have linked is not correct. A pointed out in the comments, I am not sure how this gives answers:
?- check(X, Y).
X = "Jack",
Y = "Anne" ;
X = "Anne",
Y = "George" ;
X = "Anne",
Y = "George".
Please if someone knows the program was meant to be used, explain. I am afraid I am just missing something.
Here is one attempt at a real solution. First, we leave the ground facts exactly as given:
looking_at(jack, anne).
looking_at(anne, george).
married(jack).
unmarried(george).
I will now define a predicate solution/2 which has the solution and any possible bindings that explain it. There are three possible solutions, if I understand: "yes", "no", and "undetermined". In the case of a "yes" answer:
solve(yes, married_unmarried(A, B)) :-
married(A),
looking_at(A, B),
unmarried(B).
The "no" case is a bit different. It is supposed to say:
For all A looking at a B, either A is unmarried or B is married.
With SWI-Prolog and forall/2, you can write:
solve(no, false) :-
forall(looking_at(A, B),
( unmarried(A) ; married(B) )).
This is equivalent to:
solve(no, false) :-
\+ ( looking_at(A, B),
\+ ( unmarried(A) ; married(B) ).
The undetermined case is more interesting, but we could try and cheat:
solve(undetermined, B) :-
\+ solve(yes, B),
\+ solve(no, B).
We can neither prove that someone is looking nor that no one is looking.
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 7 years ago.
Improve this question
If the sun shines then it is true that I get wet if it rains.
If the sun shines then it is summer.
It is not summer.
Therefore, I get wet if the sun shines.
I. A proposition symbol represents something that can be either true or false. For example claims 1, 2, and 4. Above, there are statements like “the sun shines” that can be either true or false. Define a propositional symbol for each of these statements.
II. Translate 1, 2, 3 and 4 to propositional logic sentences using your proposition symbols from (i).
Using CLP(B) in SICStus Prolog or SWI to to prove the final implication from the preceding statements:
?- sat(Sun =< (Wet =< Rain)),
sat(Sun =< Summer),
sat(~Summer),
taut(Sun =< Wet, T).
yielding:
...
T = 1,
...
This shows that the final implication follows from the previous statements.
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).