I have the following code in prolog to produce a path from one node to other but I can't see my results on the screen. I just get true as an answer. The last variable name doesn't bind to the results:
edge(a,b).
edge(b,d).
edge(b,c).
edge(c,d).
path(A,B,P):-
path_1(A,B,[A],P).
path_1(A,B,P,Path):- last_element(P,S),S=B.
path_1(A,B,P,Path):-
edge(A,X),\+member(X,P),append(P,[X],NewP),
path_1(X,B,NewP,NewP).
last_element([X],X).
last_element([H|T],X):-
last_element(T,X).
I want to get something like: K=[a,b,d] etc.. when I run this code : path(a,d,K)
but its not showing up. only true shows up.
Want to know why. thanks
In your code, Path is not updated in the recursive rule. Change it like this:
path_1(A,B,P,Path):-
edge(A,X),\+member(X,P),append(P,[X],NewP),
path_1(X,B,NewP,P1), append([A], P1, Path).
And it runs well :)
When it is clear that there is an A-X edge and an X-B path, the A-B path should be A + X-B path.
The P variable in path/3 will be instantiated when the Path variable in path_1/4 is instantiated.
However, you never use Path in path_1/4 and therefore the variable does not bind to the results as you observed
Since you use swi-prolog you should get a warning like "Singleton variables: [Path]".
While sometimes it is ok to ignore such a warning, most of the times your code is not going to work as you expected
Related
Unfortunately, I cannot give the full text of the problem for some reason. Therefore, I will try to describe the main point.
There was a murder at the hotel in room 4. 6 visitors are suspected who came to visit someone in one of the 6 hotel rooms at different intervals (These are all facts).
Then all the suspects were interviewed, some evidence was considered and information was received from the receptionist (These are the rules).
You need to find out who was where at what time. Well, and therefore who is the killer.
my problem
I am not getting the correct result.
When calling
guest(brown, R, T).
i get false (brawn must be a killer)
and basically when i call the function
solution(Guests).
then I get a very large number of lists. And the rules are not followed in them. Why is that?
result lists screenshoot
In short, I have a suspicion that these rules work somehow separately. But I could be wrong, because in the prologue I am a complete zero. What's my mistake?
P.S. If necessary, I can try to write the full text of the assignment. The only problem is that the text is in a different language from an old book that was scanned..
The reason why your query fails is the following program fragment. I obtained it by systematically generalizing away goal after goal by adding a * in front. Because this fragment fails, also your original program will fail. I am sure it will be evident to you how to interpret this:
:- op(950, fy, *). % auxiliary definition
*_.
:- initialization(guest(brown, _R, _T)). % your failing query
evidence(taylor,R,_):- *not(R=5).
evidence(white,R,_):- *not(R=5).
evidence(smith,R,_):- *not(R=1), *not(R=3), *not(R=6), *not(R=5).
evidence(green,R,_):- *not(R=3), *not(R=6).
guest(N,R,T):-
*interrogation(N,R,T),
evidence(N,R,T),
*receptionist(N,R,T).
Just a remark, instead of not(A=B) rather use dif(A,B). It's the 21st century...
Given the code below, what is the ToConnection argument? It seems to have no connection to any other arguments and is created seemingly arbitrarily. Every other argument can be traced back to its origins when the predicate is called with given values like routing(chicago,newyork,X). ignoring X of course!
So FromCity begins as chicago and continues from there being assigned new values, same for ToCity. They have specific values in the beginning.
Like with ToConnection, X seems to also be left undefined and unreferenced. It seems like they're supposed to take up any values that match the predicates they're part of!? So ToConnection in the path() predicate becomes all the other cities that are related to FromCity=chicargo, in other words, it gets all the second values from the path() predicates that match this pattern - path(chicargo, ???).
Resulting in picking these predicates
path(chicago,atlanta).
path(chicago,milwaukee).
path(chicago,detroit).
Overall, I'd like to understand them better as they seem to be called in isolation and I'm having a hard time tracing them back to something tangible to reference what they're connected to. They are hard to understand because they don't have any obvious relation to anything at first sight!
path(chicago,atlanta).
path(chicago,milwaukee).
path(milwaukee,detroit).
path(milwaukee,newyork).
path(chicago,detroit).
path(detroit, newyork).
path(newyork, boston).
path(atlanta,boston).
path(atlanta, milwaukee).
routing(FromCity, ToCity, [FromCity, ToCity]) :-
path(FromCity, ToCity).
routing(FromCity, ToCity, [FromCity|Connections]) :-
path(FromCity, ToConnection),
routing(ToConnection, ToCity, Connections).
Code from https://stackoverflow.com/a/13172689
There are two uses of the ToConnection variable. That's perfectly normal.
routing(FromCity, ToCity, [FromCity|Connections]) :-
path(FromCity, ***ToConnection***),
routing(***ToConnection***, ToCity, Connections).
So I run into some troubles while (ab?)using
lambda.pl.
I do a "use_module(library(lambda))."
in the first lines of a file that
I consult via ["a.prolog"].
Then I get an "undefined procedure ()/3"
and some gibberish afterwards.
The same happens for any order of use_modules.
It happens whether I load a.prolog via
[...], consult or as a script from the cmdline.
I reduced the script to the currying-example from Rosseta code
https://rosettacode.org/wiki/Currying#Prolog
use_module(library(lambda)).
:- initialization(main, main).
main :-
N = 5, F = \X^Y^(Y is X+N), maplist(F, [1,2,3], L),
print(L).
It doesn't work.
It works, however, if I a manually load 'lambda'
at the swipl-prompt and immeditately consult
a.prolog. Then the goal N=5,.... works just fine.
If I, however, first consult a.prolog; then manually
use_module and then run the query, I get the error.
Reconsulting doesn't help onwards.
Somehow, the first command at the prompt needs to
be use_module.
Or do I get the loading mechanism completely wrong?
If so, please apologize; but I would love get a
hint how to solve this.
This is a common error when first using modules.
Please have a look at this line:
use_module(library(lambda)).
This is just a fact, saying "use_module(library(lambbda)) holds".
What you want instead is a directive.
A directive is a term with primary functor (:-)/1. That is, you want:
:- use_module(library(lambda)).
EDIT: For the particular case of library(lambda), I would like to add that there is a page with a lot of useful information about it that is a bit hard to find:
http://www.complang.tuwien.ac.at/ulrich/Prolog-inedit/ISO-Hiord
"Hiord" stands for higher order.
I'm trying to solve a water, jug problem (one 7L, one 4L, get 5L in the 7L jug) using dept first search. However something keeps going wrong whenever I try to get a new state back from one of my actions.
Prolog Code
I can't figure out what is going wrong, this is what the output looks like after trace:
enter image description here
Thanks in advance for any help!
You should copy and paste your code into your question; we cannot copy and paste it from your images, which makes it more work to help you, which in turn makes it less likely that we will help.
Some problems I noticed anyway:
Your first rule for go_to_goal/3 does not talk about the relation between ClosedList and Path. You will compute the path but will never be able to communicate it to the caller. (Then again, you also ignore Path in solve/0...) If your Prolog system gives you "singleton variable" warnings, you should never ignore them!
You are using the == operator wrong. The goal State == (5, X) states that at the end you are looking for a pair where the first component is 5 (this part is fine) and the second component is an unbound variable. In fact, after your computations, the second component of the pair will be bound to some arithmetic term. This comparison will always fail. You should use the = (unification) operator instead. == is only used rarely, in particular situations.
If you put a term like X+Y-7 into the head of a rule, it will not be evaluated to a number. If you want it to be evaluated to a number, you must use is/2 in the body of your rules.
Your most immediate problem, however, is the following (visible from the trace you posted): The second clause of go_to_goal/3 tries to call action/2 with a pair (0, 0) as the first argument. This always fails because the first argument of every clause of action/2 is a term state(X, Y). If you change this to state(0, 0) in go_to_goal/3, you should be able to make a little bit of progress.
I have a list structure called "stack".
At the point in my program which is causing problems, this is what stack holds:
stack([[s]],[np,[noun,john]])
I got this from running a trace, and its what stack is supposed to be holding.
When writing the next rule which is supposed to match this.
if
buffer([[Word|_]])
and aux(Word)
and stack([s],[np,[noun, john]])
If I do this then the rule executes as its supposed to. But I need to use a variable here instead of using "and stack([[s]],[np,[noun,john]])". However when I try to use anything else, the rule does not fire. I can't work out why. Other rules work fine when I use variables in the list.
Ive tried
stack([s]|Foo)
stack([s]|[Foo])
stack([MyHead]|[MyTail]... and literally every other combination I can think of.
I'm not entirely sure what is causing this problem
Your stack seems to have arity 2, where each arg is a list.
These aren't valid syntax for lists
stack([s]|Foo)
stack([s]|[Foo])
...
but since some Prolog declare the (|)/2 operator as alternative to (;)/2 (i.e. disjunction), you will not see any syntax error.
To understand you problem, you could try to unify, by mean of unification operator (=)/2
?- stack(S, Foo) = stack([[s]],[np,[noun,john]]).
you will get
S = [[s]]
Foo = [np,[noun,john]]