Lets say i have simple hello world code
hworld:-writeln('hello world').
This code always returns something like this:
hello world
true.
As far as i understand prolog, it returns either variable value (of X i.e. fact(5,X).) or true/false, if predicate can be solved (i.e. fact(5,120).).
What i need is to hide true/false predicate result on stdout (so there will be only results of writeln() predicate). How to do so? Thanks.
Related
I am trying to write a function longer(S1,S2) which should be true if S1 is longer than S2, otherwise false. What I have so far is the following:
longer(A,nil).
longer(nil,B) :- false.
longer([A,AS],[B,BS]) :- longer(AS,BS).
But for some reason I cannot seem to get it to parse correctly when I provide for instance the input: longer([1,2],[1]).
But when I run the above through swi-prolog it return false.
Another example is running the: longer([1],nil) which also return false, even though it should be true by matching with list(cons(A,As)) where As = nil, finally matching the end clause.
What am I missing? Can someone point me in the right direction here, as I cannot see how this is not evaluating to true.
Edit: it should be noted that I am still fairly new to prolog at this point.
Update I have had some misunderstanding in relation to what is common prolog semantic. Including trying to force the program to yield a false value (probably being steered by my understanding of non-declarative language semantics). I have updated my answer with the inputs from #tiffi.
That is a solution that is pretty close to the thinking behind what you have come up with:
longer([_|_],[]).
longer([_|As], [_|Bs]):- longer(As,Bs).
Your idea with regard to the first clause (before your edit) could be expressed like this:
longer(A,[]):- is_list(A). %is_list/1 is inbuilt
However, that doesn't give you the right result, since the empty list is also a list. Thus you need to make sure that the first argument is a non-empty list.
I am new to Prolog. Not really able to get how it works.
fillmap([HF|TF],[HG|TG],L,X,Y,Map1):-
...
replace((EX,EY,none),Map1,(EX,EY,HF),Map2),
...
(L1>0-> write("G0"),fillmap(TF,TG,L1,EX,EY,Map2);
write("G=0")).
Map is a list. I am changing it in every recursive call and I can see it in the output by write func. But I want to get the changed Map where I am calling it. But I am not getting the updated Map there. How to get that?
Thanks in advance.
If I understand your question correctly, you are satisfied with the values for Map2 that are computed by this predicate and printed out, and you just want to be able to "pass it back" or "return it" to a caller.
All passing of data between predicates in Prolog is done via predicate arguments. So you need an extra argument for the fillmap predicate:
fillmap([HF|TF], [HG|TG], L, X, Y, Map1, Map2):-
... % your code exactly as before
When you call this predicate, pass in a fresh variable NewMap as the last argument, and after the call that variable will be bound to the new map.
Assume I made a function like below in swi-prolog.
function1(param) :- VALUE is 0, findValue(VALUE), write(VALUE).
However 0 is always printed out. findValue function is logically correct.'
Is it impossible to use calculated VALUE in function1?
Omit VALUE is 0.
By stating it, the function findValue will set the rest of the variables according to VALUE, because the claims you provide first are the axiom-level true ones, and the rest correspond to them.
For example, take
func(X):- X is 0.
If you query func(X). it will result in X=0 because it assumes you want to make an assignment.
However, if you query with a number like func(0). it will check if X==0 or not, resulting in a boolean answer.
i know there is a build-in function findall/3 in prolog,
and im trying to find the total numbers of hours(Thrs) and store them in a list, then sum the list up. but it doesnt work for me. here is my code:
totalLecHrs(LN,THrs) :-
lecturer(LN,LId),
findall(Thrs, lectureSegmentHrs(CC,LId,B,E,THrs),L),
sumList(L,Thrs).
could you tell me what's wrong with it? thanks a lot.
You need to use a "dummy" variable for Hours in the findall/3 subgoal. What you wrote uses THrs both as the return value for sumList/2 and as the variable to be listed in L by findall/3. Use X as the first argument of findall and in the corresponding subgoal lectureSegmentHrs/5 as the last argument.
It looks like the problem is that you're using the same variable (Thrs) twice for different things. However it's hard to tell as you've also used different capitalisation in different places. Change the findall line so that the initial variable has the same capitalisation in the lectureSegmentHrs call. Then use a different variable completely to get the final output value (ie the one that appears in sumList and in the return slot of the entire predicate).
You need to use a different variable because Prolog does not support variable reassignment. In a logical language, the notion of reassigning a variable is inherently impossible. Something like the following may seem sensible...
...
X = 10,
X = 11,
...
But you have to remember that , in Prolog is the conjunction operator. You're effectively telling Prolog to find a solution to your problem where X is both 10 and 11 at the same time. So it's obviously going to tell you that that can't be done.
Instead you have to just make up new variable names as you go along. Sometimes this does get a bit annoying but it's just goes with the territory of a logical languages.
I was wondering, how would I use the underscore twice but check that both instances of that underscore unify?
What I basically need is something that returns true if two elements of the same value in one mapping exist...
I.E member((_,_),[(a,a),(b,a),(c,a)]).
If I use a variable does that make them unified?
I.E member((A,A),[(a,a),(b,a),(c,a)]).
But it returns the variable rather than true.
I need some enlightenment.
Your solution with a variable is correct.
Returning a variable is a way to return true. It really means: this goal is true when var = value, as opposed to this goal is true.
Note that using this as a clause in a different predicate will hide the variable:
contains_identical_pair(List) :- member((A,A),List).
You can use double negation to avoid variable bindings:
?- \+ \+ member((A,A),[(a,a),(b,a),(c,a)]).
true.
The bindings for the variables printed on the prolog screen are just there to make life easier in an interactive prompt so that you don't have to print out the variables you care about each time. They don't affect the logic of your code at all.
They will only be printed for variables are are entered at the prompt. So if the predicate you are writing is part of a larger program, you can just ignore this output, or if you want this to be a top-level predicate that people will call from the prompt and you don't want the output printed, then simply wrap your call in a predicate that has no arguments or has only input arguments. ie:
wrapper :-
predicate(Out1,Out2).
or:
wrapper(In1,In2) :-
predicate(In1,In2,Out1,Out2).