Recursive func Prolog - prolog

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.

Related

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 to add to end of list in prolog

I am trying to add one item to the end of a list in prolog, but it keeps on failing.
insertAtEnd(X,[ ],[X]).
insertAtEnd(X,[H|T],[H|Z]) :- insertAtEnd(X,T,Z).
letters([a,b,c]).
I do not understand why this below does not work.
insertAtEnd(d,letters(Stored),letters(Stored)).
I am also attempting to store this list in the variable Stored throughout, but I am not sure if the above is correct way to proceed.
you can use append
and put your item as second list
like this:
insertAtEnd(X,Y,Z) :- append(Y,[X],Z).
Prolog implements a relational computation model, and variables can only be instantiated, not assigned. Try
?- letters(Stored),
insertAtEnd(d, Stored, Updated),
write(Updated).

Function inputs and outputs in PROLOG

I'm building some relatively simple functions in PROLOG that take one input and one output. For simplicity, something like
func(List, Item, [Item | List]).
Now, I've got code that will call several of these functions in a row and pass the result on. The issue is that I have to keep creating new variable names for all of the outputs.
someOtherFunc(List, Item) :-
func(List, Item, Output1),
doSomething(Output1).
The issue here is that I actually have several func and several doSomething and would really appreciate not having to bind an Output1 variable explicitly. Is there any way to achieve this?
I'm not sure about what you're asking, but first of all please note that those are not functions, but predicates. This is a totally different programming paradigm. Variables are not "boxes" where you put in and out some data: they're closer to the mathematical meaning of variable, since once you bind them to some constraints on their values it's forever.
To go back to your question, the answer is no, you can't avoid binding some Output1 like that. Sometimes you can put in an underscore to tell prolog you just don't care about that value, but doing so you lose the ability to make use of that particular value. In your example you would like to do something like this (in a imperative pseudocode):
var list = ..., item = ...;
doSomething(func(list, item));
There's no other way in prolog as far as I know, you just have to use intermediate variables as you did. The only improvement I can suggest, is to choose very carefully predicates and variables names.
func1(Input1, Input2) :-
func2(Input1, Input2, Output1),
useFun(Output1, Output2).
/* Output2 the result I obtain from the function useFun */

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.

Prolog wildcards

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).

Resources