write always initial value in Prolog programming - prolog

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.

Related

Prolog list length comparison return true/false

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.

base case to returning false on a condition prolog

I am working on a basic project in Prolog. I want to write a function that returns a number based on the input list. I also want to make sure that when the input list is empty, the result is false.
The function should be like this
parseList(List, N) where N is a number. I would like to know a way that returns False when we try
parseList([], N).
where N is any number.
I tried doing this for the base case
parseList([], False).
However,this does not seem to work.
Could anyone please help me with this? Thank You!
As Lurker said in his comment, in this instance, leaving out the empty list condition and handling the list of one element will cause the empty list to fail. However, in the more general case, if you want to declare a rule that fails, simply include false, because that can never be true, or fail which does the same. For example:
parseList([],_) :- false.
or (now deprecated)
parseList([],_) :- fail.
(where _ is used to denote an unimportant variable, otherwise a singleton-variable-warning will be triggered).

Prolog hide returned predicate value

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.

How do i count words in prolog?

I try to count words in a string in prolog. Like "No, I am definitely not a pie!"
To give me the number 7 and next example "w0w such t3xt... to give number 5.
I had thougt about subtract that are a library function and only get back white-characters. But the problem then is No way will give back 5 and not two words.
I thought about
filter([],L).
filter([X,Y|XS],[Y|XS]):- X = ' ',Y = ' ',L = [Y|XS], filter([Y|XS],L).
filter([X|XS],L):- filter(Xs,L).
That will remove white spaces and get back No way but it dosent work anbody have a tip.
Strings in Prolog are lists of character codes not of atoms, what explains why tests like X=' ' fail. See what is the result of executing
write("ab cd"), nl.
in your Prolog system.
You have errors in your 3 clauses:
What to do you expect the first clause to return in the last argument?
L is, as any other variable in a Prolog program, a variable that is local to the clause it appears in, never a global variable.
The second clause unifies L with a list and you use it as second argument of the recursive call: do you expect the recursive call to change the value of L? This will never be the case: in Prolog there is no assignment of variables, changes are made by building terms and unifying them with new variables.
What happens to X in your third clause???

Correct use of findall/3, especially the first template argument

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.

Resources