Related
I am new to prolog and I was wondering if anyone could help me with this problem. The problem: given the integers 1,2,3,4, and the predicates mult/2, div/2, div/2, minus/2, and minus/2, and eval/2, I need to write a predicate solutions/1 that, when called like this:
?- solutions(L).
it should terminate with the variable L unified to a list of expressions with value 6. Expressions are of the form:
X, Y, exp/2
But my code is not working. I have two versions. The first freezes up SWI-Prolog, not returning any answer after I type a period, and not letting me evaluate anything else afterward:
eval(1,1.0).
eval(2,2.0).
eval(3,3.0).
eval(4,4.0).
eval(mult(X,Y),Z) :-
eval(X,A),
eval(Y,B),
Z is A*B.
eval(div(X,Y),Z) :-
eval(X,A),
eval(Y,B),
Z is A/B.
eval(minus(X,Y),Z) :-
eval(X,A),
eval(Y,B),
Z is A-B.
solutions(L) :-
setof(X,eval(X,6),L),
print(L).
The second version just returns false when I type ?- solutions(L).:
solutions(L) :-
setof([exp,X,Y],eval(exp(X,Y),6),L),
print(L).
Thank you so much for taking the time to help!
Maybe you're looking for something like
solutions(L) :-
Ns = [1,2,3,4],
Ex = [*,/,-],
findall((X,Y,E),
(member(X,Ns),member(Y,Ns),member(E,Ex),F=..[E,X,Y],6=:=F),
L).
that yields
?- solutions(L).
L = [(2, 3, (*)), (3, 2, (*))].
Expressions are usually recursive, that is, arguments could be expressions instead of plain numbers. But then, in my opinion your problem is underspecified, as we need criteria to stop the infinite flow of solutions resulting - for instance - by repeated application of operations that don't change the value. Like multiply or divide by 1.
The problem is that your code is going in infinite recursion with eval/2 predicate.
You can try this solution:
num(1).
num(2).
num(3).
num(4).
eval(mult(A,B),Z) :-
num(A),
num(B),
Z is A*B.
eval(div(A,B),Z) :-
num(A),
num(B),
Z is A/B.
eval(minus(A,B),Z) :-
num(A),
num(B),
Z is A-B.
test(L) :-
setof(X,eval(X,6),L),
print(L).
Which yields:
?- test(L).
[mult(2,3),mult(3,2)]
L = [mult(2, 3), mult(3, 2)].
I am trying to learn Prolog. I have a problem and the solution for that in Prolog. Though I am unable to understand the code completely.
The problem is -
Write a procedure mydelete( X, HasXs, OneLessXs ) that returns
% ?- mydelete( 2, [1,2,3,4], L ) . --> L = [1,3,4]
% ?- mydelete( 2, [1,2,3,2], L ) . --> L = [1,3,2] ; L = [1,2,3]
Basically, the problem is t remove the member one by one which matches X and print the result after each removal.
I have a solution , but, I am exactly, not sure how this code is working.
mydelete(X,[X|T],T).
mydelete(X,[H|T1],[H|T2]) :- mydelete(X,T1,T2).
As per my understanding, the first line, displays the L = ... when it finds a match with X in the head of the list.
In the second line of the code, it simply pops out the head from the input list and send that updated list recursively.
But, here, we haven't defined T2.
Let us consider an example for that.
mydelete( 2, [1,2,3,4], L ) . --> this is the call.
X=2, list is = [1,2,3,4], so, H=1, T=[2,3,4].
So, it does not execute line 1 of the code. Now, it comes to the second line of the code.
mydelete(X,[H|T1],[H|T2]) :- mydelete(X,T1,T2).
Here also X=2, H =1, T1=[2,3,4], T2= .
So, on the next recursion,
X=2, list = [2,3,4], H matches X, thus line 1 will get executed.
Therefore, X=2, T=[3,4]
So, it should print = [3,4].(I know, [1,3,4] is the right answer. I am not able to understand the explanation behind this code)
My, question is, what is wrong in my understanding?
And, what is the use of [H|T2] in
mydelete(X,[H|T1],[H|T2]) :- mydelete(X,T1,T2).
Thanks! Please help me out!
edit: I tried removing H from [H|T2]. It is printing [3,4]. How H is adding 1 as the prefix to the list [3,4] ?
The best way to think of this as an imperative programmer is that the last argument is kind of the return value. You see that the first call you make "returns" [H|T2], not merely T2 this is how the first element of the list remains: after recursing to compute the value of T2, mydelete is adding H (which happens to equal 1 in this case) to the start of the returned list.
What is the use of [H|T2]?
In your explanations, you forgot to consider that the third argument, L, is being unified with [H|T2]. Up to this point, L was free (in your case), and now you know that it is a list starting with H. The rest of the list T2 is now the third argument to the recursive call and will be unified likewise, until you reach the base case.
By the way, what happens when your list is empty?
I got this grid:
tab([[s,f,f,f,s,f,f,f,s],
[f,s,f,f,f,f,f,s,f],
[f,f,s,f,f,f,s,f,f],
[f,f,f,f,f,f,f,f,f],
[s,f,f,f,m,f,f,f,s],
[f,f,f,f,f,f,f,f,f],
[f,f,s,f,f,f,s,f,f],
[f,s,f,f,f,f,f,s,f],
[s,f,f,f,s,f,f,f,s]]).
I want to print in the screen without brackets and commas.
By the way I can't print it right with or without them.
These are the print rules:
viewTab([]).
viewTab([H|T]) :-
printList(H),
viewTab(T).
printList([]) :-
nl.
printList([H|T]) :-
write(H),
write(' | '),
printList(T).
I call it in the Prolog's terminal like:
?- viewTab(X), tab(X).
I can't print a thing, and I get an infinite loop at:
printList([]) :-
nl.
Can you help me find my mistake?
Or some tips to make the code easier to work with.
Your viewTab/1 is not a purely logical predicate: it has a side effect, and it does not terminate for if its argument is a variable.
For example:
?- listing(foo).
foo([]).
foo([_|A]) :-
foo(A).
true.
?- foo(X).
X = [] ;
X = [_G256] ;
X = [_G256, _G259] ;
X = [_G256, _G259, _G262] ;
X = [_G256, _G259, _G262, _G265] ;
X = [_G256, _G259, _G262, _G265, _G268] . % and so on
So this:
?- viewTab(X), tab(X).
Puts a list in X, then tab(X) fails, and you are back at viewTab(X), ad infinitum.
You should try:
?- tab(X), viewTab(X).
Use dcg!
Definite clause grammars are a versatile, logical way of processing input/output.
For a start, read this well-written DCG primer by Markus Triska, also known as #mat on SO!
Right now, as a quick fix, use the built-in predicate format/2 like this:
?- X = [a,b,c], format('~s~n',[X]).
abc % output via side-effect
X = [a, b, c]. % query succeeds
I'm not really good with lists in Prolog. What I'm trying to do is to split one list [1,2,3,4] into two lists. The catch is that the elements of those two lists can be in any order.
This is what I have right now:
divideList([],[],[]).
divideList(L1,L2,[H|T]) :-
select(H,L1,L1C),
length(L1,Length1),
length([H|T],LengthHT),
Length1 =< LengthHT,
divideList(L1C,L2,T).
divideList(L1,L2,[H|T]) :-
select(H,L2,L2C),
length(L2,Length2),
length([H|T],LengthHT),
Length2 =< LengthHT,
divideList(L1,L2C,T).
It works when I put in all the lists and it just has to check if it's true or false.
?- divideList([1,2],[4,3],[1,2,3,4]).
true .
?- divideList([2,1],[4,3],[1,2,3,4]).
true .
?- divideList([2,1],[3,4],[1,2,3,4]).
true .
However if I try to do this: ?- divideList(A,[3,4],[1,2,3,4]).
It shows me this ERROR: Out of global stack .
When I want it to show me this:
?- divideList(A,[3,4],[1,2,3,4]).
A = [1,2] ;
A = [2,1].
Any ideas on how to fix this?
You could simplify it a bit using permutation/2:
divideList([A|As], [B|Bs], L) :-
permutation(L, P),
append([A|As], [B|Bs], P).
The [A|As] and [B|Bs] prevent [] from being a solution for the first or second argument.
I need some help with three prolog predicates for checking and manipulating lists. I'm new to prolog and any help would be much appreciated.
The three predicates are:
double_up(+List1, -List2) is true when List2 has each element of List1 twice. The query double_up([a,b,c],X) should give X=[a,a,b,b,c,c]. The order of the elements in the output list does not matter.
pivot(+List1, +Pivot, -Smaller, -GreaterEq) is true when Smaller is the list of numbers in List1 smaller than Pivot, and GreaterEq is the list of numbers in List1 bigger than or equal to Pivot.
fancy_replace(+List, +Takeout,+Putin, -NewList, -Count) is true when NewList is the same list as the input List, but where each Takeout element in the list is replaced with the Putin element. Count should be the number of Takeouts that got replaced. For example, the query fancy_replace([9,10,1,9,2],9,0, X, C) should give X = [0,10,1,0,2] and C = 2. The order of the elements in the output list does not matter.
The simpler pattern to process lists in Prolog imposes a recursive predicate with 2 arguments, matching - conventionally - input and output data, and a base case, stopping the recursion, matching the empty list. Then
double_up([X|Xs], [X,X|Ys]) :- double_up(Xs, Ys).
double_up([], []).
This predicate it's a bit more general than what's required, because it works also in mode double_up(-List1, +List2). For instance
?- double_up(L,[1,1,2,2]).
L = [1, 2].
To restrict its mode as required, I think it's necessary to uselessly complicate the code, moving that clean loop in a service predicate, and leaving double_up just to test the arguments:
double_up(I, O) :- is_list(I), var(O), double_up_(I, O).
double_up_([X|Xs], [X,X|Ys]) :- double_up_(Xs, Ys).
double_up_([], []).
pivot/4 could be 'one-liner' in SWI-Prolog:
pivot(List1, Pivot, Smaller, GreaterEq) :-
partition(>(Pivot), List1, Smaller, GreaterEq).
like partition, foldl from library(apply) it's an easy inplementation of the last required predicate:
fancy_replace(List, Takeout, Putin, NewList, Count) :-
foldl(swap_n_count(Takeout, Putin), List, NewList, 0, Count).
swap_n_count(Takeout, Putin, L, N, C0, C) :-
( L == Takeout
-> N = Putin, C is C0 + 1
; N = L, C = C0
).
to be honest, i hate prolog... even though it is fun and easy after you learn it
i think this is a good reference as I was having trouble understanding how prolog works couple weeks ago.
what does the follow prolog codes do?
anyway.. this is the answer for your first problem; Hopefully you could solve the rest yourself :D
double([]).
double([H|[]], [H,H|[]]).
double([H|T],[H,H|T1]):- double(T, T1).
btw, this might not the only solution...but it works