Variable not printing the entire value Prolog - prolog

If I assign something like
process([[baby],[boy],[[is]dancing],[with],[[the][family]]],A),
then it gives output as
A = [[baby],[boy],[[is]dancing],[with],[[..][..]]].
I want it to show all the values on terminal.
Something like
A = [[baby],[boy],[[is]dancing],[with],[[the][family]]].

The problem is that the toplevel is truncating the list when they are shown.
You can configure the depth of the maximum nesting with the prolog flag toplevel_print_option, with option max_depth(0), with 0 meaning to show everything.
The helper procedure will modify the prolog flag to change only max_depth to 0, leaving the other options unchanged:
set_toplevel_flags:-
current_prolog_flag(toplevel_print_options, Opts),
(select(max_depth(_), Opts, TOpts) -> NOpts=TOpts ; NOpts=Opts),
set_prolog_flag(toplevel_print_options, [max_depth(0)|NOpts]).

Use the current_prolog_flag/2 predicate with the toplevel_print_options flag. Something like this:
?- current_prolog_flag(toplevel_print_options, X).
X = [quoted(true), portray(true), max_depth(10), spacing(next_argument)].
You can modify the max_depth option value, or alternatively you can type w after getting the abbreviated answer, and prolog will print the answer fully. Pressing p will restore the original format. To make the Prolog wait wor your input after printing the answer, you might want to add some non-determinism to the query by appending ; true. to it. For more information see here.

Related

Edit Prolog program to output the result of a computation

I've found something about this in other questions, but mine is a bit different.
Given a string, I have to output another string with no adjacent duplicates.
E.g., given [a,a,b,b,c,d,a], my output will be [a,b,c,d,a].
Now, I've wrote the following recursive program to check if a certain given string has adjacent duplicates:
notequal(A,[]).
notequal(A,[X|S]) :- not(A=X).
noadj([]):-!.
noadj([A|S]) :- notequal(A,S), noadj(S).
How would I modify it in order to output what I described? I've tried multiple times but I'm new to prolog and I can't seem to get into its logic.
Of course, I'll need another variable, which would contain an element if notequal is true for that element.
So my idea is to iterate through the list and only add a certain term to the result if it passes the "notequal" test.
I'll edit this: I finally managed to do something like that by adding
noadjlist([X|S],[X|LS]) :- notequal(X,S), noadjlist(S,LS).
noadjlist([X|S],LS) :- noadjlist(S,LS).
noadjlist([],LS):-!.
However, my results are like:
?- noadjlist([1,2,2,3],LS).
LS = [1, 2, 3|_19316] .
why do I get that uninstantiated variable at the end?
noadjlist([],LS):-!.
should be
noadjlist([],[]):-!.

How to print variable value from a question?

I´m making a one bit addition:
sumbit(CIN,A,B,CO,R):- ...
?- sumbit(0
,1
,1
,CO
,R)
,write(CIN),nl
,write(A),nl
,write("+"),nl
,write(B),nl
,write("--"),nl
,write(CO),write(R),nl.
What I want to do is to print the variable values of CIN,A,B,CO and R.
It should come out something like this:
0
1
+
1
--
10
Instead it comes out as this:
_40
_73
+
_149
--
10
Yes.
Also is there a way to not print the "Yes"?
I´m using strawberry prolog if it helps.
Thank you in advance
One way to achieve that without altering your predicate definition is to tweak the query, like so:
?- [CIN, A, B] = [0, 1, 1]
,sumbit(CIN
,A
,B
,CO
,R)
,write(CIN),nl
,write(A),nl
,write("+"),nl
,write(B),nl
,write("--"),nl
,write(CO),write(R),nl.
Now all variables are instantiated, either by the call itself, or prior to the call.
When a variable is not instantiated, there's no value to print, so its "name" is printed instead. But since non-used name has no meaning in itself, it can be freely renamed by the system to anything. In SWI Prolog:
1 ?- write(A).
_G1338
true.
The renaming is usually done, as part of the Prolog problem solving process, to ensure that any two separate invocations of the same predicate do not interfere with each other.
So where SWI Prolog uses names like _G1338, the Prolog implementation you're using evidently uses names with the numbers only, after the underscore, like _40.
I found an answer by putting the write() inside the sumbit(...) predicate:
sumbit(CIN,A,B,CO,R):-
xor_(A,B,R1)
,and(A,B,R2)
,xor_(R1,CIN,R)
,and(R1,CIN,R4)
,or(R2,R4,CO)
,write(CIN),nl
,write(A),nl
,write("+"),nl
,write(B),nl
,write("--"),nl
,write(R),nl.
There are still some unanswered questions though:
is there a way to not print the "Yes"?
what was the _number that came out before?

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???

How do you save all possible solutions in SWI-Prolog?

I have this predicate that has about a thousand possibilities and I need all possibilities as an output. It is not possible to simply copy and paste all listed possibilities in SWI-Prolog on Windows since you can only scroll up so much.
My predicate looks like this:
?- question(X,Y,Z).
X = 'Fo',
Y = 'Ob',
Z = 'Ar' ;
X = 'Fo2',
etc...
I was wondering if there was a way to save the result in a file or something?
Use findall/3:
findall([X,Y,Z],question(X,Y,Z),R).
R shall be bound to the list of all [X,Y,Z] such that question(X,Y,Z) succeeds.
For more information see: Documentatin on Findall
You can use something like this:
main :-
tell('output.txt'),
(
question(X,Y,Z),
writeln([X, Y, Z]),
fail
;
told
).
Or you can run the query ( question(X,Y,Z), writeln([X, Y, Z]), fail ; true ). in Prolog and get all solutions at standard output (screen).
SWI-Prolog offers a way to save the interaction carried on the REPL (Read,Eval,Print,Loop) console: see the protocol builtins. This way variables names are retained. Beware, the output could be difficult to process, and long variables will be replaced by ellipsis (you can change this, see these answers).
Otherwise, forall/2 could be a viable alternative
?- open('a.txt',write,S), forall(member(X,[martin,carlo]), format(S,'~q~n',[X])), close(S).

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