convert term to variable in prolog - prolog

I have a list of terms,
[g(_G543),g(_G548),g(_G553),g(_G558),g(_G558),g(_G553),g(_G548),g(_G543)]
How can I make it to
[_G543,_G548,_G553,_G558,_G558,_G553,_G548,_G543]
only left the variables.
I was trying
replace([],[]).
replace([g(X)|T1],[X|T2]):-
replace(T1,T2).
but it just returned a false, what should I do? Thanks

If your list looks like your example
[ g(A) , g(B) , g(C) , g(A) ... ]
something like this ought to do you:
extract_vars( [] , [] ) . % if the source list is exhausted, we're done
extract_vars( [g(V)|Xs] , [V|Vs] ) :- % otherwise...
var(V) , % - ensure we've got a var
! , % - eliminate the choice point
extract_vars( Xs , Vs ) % - recurse down
. %
extract_vars( [_|Xs] , Vs ) :- % anything else, we chuck
extract_vars( Xs , Vs ) %
. % Easy!
You could probably use findall\3, too:
extract_vars( Xs , Vs ) :-
findall( V , (member(g(V),Xs),var(V)) , Vs )
.

The underscore names eg. _G553 have no real relevance, so there's no need to maintain the exact names ?
In which case, assuming all list items are all g(..), there is no need to recurse through them.. just create a new list with the same length as the input list, but without the 'g' prefix:
X=[g(_G543),g(_G548),g(_G553),g(_G558),g(_G558),g(_G553),g(_G548),g(_G543)], length(X, Len), length(Y,Len).
X = [g(_G543), g(_G548), g(_G553), g(_G558), g(_G558), g(_G553), g(_G548), g(_G543)],
Len = 8,
Y = [_G3808, _G3811, _G3814, _G3817, _G3820, _G3823, _G3826, _G3829].
Here, length/2 is used to create a list of 'Len' items.

Related

prolog List Reverse

%reverse_List
reverseList(H|T,ReversedList):-
reverseListHelper(T,[H],ReversedList).
reverseListHelper([],Accumulator.Accumulator).
reverseListHelper([H|T],Accumulator,ReversedList):-
reverseListHelper(T,[H|Accumulator],ReversedList).
I am beginner to prolog, what wrong with this code ?
it's just giving the output false
kindly explain thanks
I understand the theory of how recursive works in list reversing but not the code much, if any one could explain line by line would be great thanks
One can look at a list in Prolog as essentially a FIFO (first-in/first-out) stack: you can examine, add or remove things only from the top/head: the remainder of the list is opaque.
Reversal of such a list, then, consists of repeatedly (and recursively) popping items from the source stack and pushing each such popped item onto a result stack.
And a common idiom in prolog is the use of a helper predicate with the same name, but different arity, where the additional argument(s) carry whatever extra state is required to solve the problem. In this case, the extra state needs is a list onto which we can push/prepend things as we go, thus building the result in reverse order.
That leads to an implementation of reverse_list/2 that looks like this:
reverse_list( Xs, Ys ) :- reverse_list( Xs , [] , Ys ) .
The helper that does all the work isn't much more complicated. There are just two cases:
The limiting case, where the source list is the empty list, and
The general case, where the source list is non-empty
The limiting case is easy: if the source list is exhausted, the accumulator, whatever it might contain, is the reversed list. That gives us
reverse_list( [] , Zs, Zs ) .
The general case merely involves
removing the head of the source list,
prepending it to the accumulator, and
recursing down on the tails.
Which leads to this (you might note that we leave the final result alone until we hit the limiting case here)
reverse( [X|Xs] , [X|Ys] , Zs ) :- reverse(Xs,Ys,Zs)
Putting it all together, we get
% reverse/2 ----------------------------------------------------------
%
% reverse( Source, Reverse )
%
% Simply invoke the helper predicate, seeding the accumulator with the
% empty list.
%
% --------------------------------------------------------------------
reverse( Xs , Ys ) :- reverse(Xs,[],Ys) .
% reverse/3 ----------------------------------------------------------
%
% reverse( Source, Accumulator, Reversed )
%
% --------------------------------------------------------------------
reverse( [] , Zs , Zs ) . % source list empty: unify accumulator and result
reverse( [X|Xs] , [X|Ys] , Zs ) :- % non-empty source? Put X on the accumulator, and
reverse(Xs,Ys,Zs) . % - recurse down on the tails.

I'm trying to remove a single occurrence of an element in a list

I'm using prolog and I'm trying to remove 1 element from the list. My append code works fine same with the if the element I am looking for is the first element in the list but it just says false if it is the second element in the list. Where am I going wrong
deleteFirst([A|X],B,Y,R):-
A\=B,
appendL(Y,A,[],Y1),
deleteFirst(X,B,Y1,R).
deleteFirst([A|X],A,Y,R):-
appendL(Y,X,[],R).
Try something like this:
% ---------------------------------------------
% remove the first X from List, yielding Result
% ---------------------------------------------
delete_first( X , List , Result ) :-
append( Prefix, [X|Suffix], List ) ,
! ,
append( Prefix, Suffix, Result ) .
The cut is needed to eliminate the choice point: otherwise, on backtracking, it will put the removed item back and try to find another matching X.
If you were to roll your own (I imagine that that is what your instructor wants), something like this, just a traversal of the list will do you:
delete_first( _ , [] , [] ) . % Remove this to fail if no matching X is found
delete_first( X , [X|Rs] , Rs ) :- % Once we find an X, we're done.
!. % - and eliminate the choice point
delete_first( X , [Y|Ys] , [Y|Rs] ) :- % Otherwise, put Y on the result list and recurse down
delete_first( X , Ys, Rs ) .

Determine the maximum depth of a term

How can I implement a binary predicate ,computes the depth of the first argument as its second argument.
Remark: The depth of variables, numbers, function symbols of arity 0, and predicate symbols of arity 0 is 0.
The depth of a term or an atomic formula is the maximum depth of all subterms or subformulas
plus 1.
?-depth((p(X,a(q(Y)),c), X).
X=3
My effort: i implemented max_list predicate but i could not develop my code more.
This works in one direction I think.
depth(A,0):-
\+compound(A).
depth(A,B):-
compound(A),
A =.. [_H|T],
maplist(depth,T,Depths),
max_list(Depths,Max),
B is Max +1.
Here's a simple straightforward approach. It treats lists as if they are a flat data structure (even through in reality, they are a deeply nested ./2 structure.
depth( T , D ) :- % to compute the depth of an arbitrary term...
depth(T,0,D) % - call the worker predicate with the accumulator seeded to zero.
.
depth( T , CM , MD ) :- var(T) , ! , MD is CM+1 . % an unbound term is atomic : its depth is the current depth + 1 .
depth( T , CM , MD ) :- atomic(T) , ! , MD is CM+1 . % an atomic term is...atomic : its depth is the current depth + 1 .
depth( [X|Xs] , CD , MD ) :- % we're going to treat a list as a flat data structure (it's not really, but conceptually it is)
findall( D , (member(T,[X|Xs),depth(T,0,D)) , Ds ) , % - find the depth of each item in the list
max(Ds,N) , % - find the max depth for a list item.
MD is CD + 1 + N % - the max depth is the current depth + 1 (for the containing list) + the max depth of a list item
. %
depth( T , CD , MD ) :- % for other compound terms...
T \= [_|_] , % - excluding lists,
T =.. [_|Args] , % - decompose it into its functor and a list of arguments
depth(Args,0,N) , % - compute the depth of the argument list
MD is CD + N % - the max depth is the current depth plus the depth of the argument list.
. % Easy!
max( [N|Ns] , M ) :- max( Ns , N , M ) . % to compute the maximum value in a list, just call the worker predicate with the accumulator seeded to zero.
max( [] , M , M ) . % when we hit the end of the list, we know the max depth.
max( [N|Ns] , T , M ) :- % otherwise,
( N > T -> T1 = N ; T1 = T ) , % - update the current high water mark
max(Ns,T1,M) % - recurse down.
. % Easy!
A list is really just a term, with some syntax sugar that eases most common use. So, my depth/2 definition, a 1-liner given compound/1, aggregate/3 and arg/3 availability, answers like:
?- depth(a(a,[1,2,3],c),X).
X = 4.
?- depth(p(X,a(q(Y)),c), X).
X = 3.
edit I will leave you the pleasure to complete it: fill the dots
depth(T, D) :- compound(T) -> aggregate(max(B), P^A^(..., ...), M), D is M+1 ; D = 0.
edit apparently, no pleasure in filling the dots :)
depth(T, D) :-
compound(T)
-> aggregate(max(B+1), P^A^(arg(P, T, A), depth(A, B)), D)
; D = 0.

Prolog deep version predicate of adding to a list

I have to write a deep version of a predicate that adds a number to each number element in a list and I've done the non-deep version:
addnum(N,T,Y)
this gives something like:
e.g. ?-addnum(7,[n,3,1,g,2],X).
X=[n,10,8,g,9]
but I want to create a deep version of addnum now which should do this:
e.g. ?-addnumdeep(7,[n,[[3]],q,4,c(5),66],C).
X=[n,[[10]],q,11,c(5),73]
Can someone give me some advice? I have started with this:
islist([]).
islist([A|B]) :- islist(B).
addnumdeep(C,[],[]).
addnumdeep(C,[Y|Z],[G|M]):-islist(Z),addnum(C,Y,[G,M]),addnumdeep(C,Z,M).
but I don't think my logic is right. I was thinking along the lines of checking if the tail is a list then runing addnum on the head and then runnig addnumdeep on the rest of the tail which is a list?
maybe you could 'catch' the list in first place, adding as first clause
addnum(N,[T|Ts],[Y|Ys]) :- addnum(N,T,Y),addnum(N,Ts,Ys).
This is one solution. The cut is necessary, or else it would backtrack and give false solutions later on. I had tried to use the old addnum predicate, but you can't know if you have to go deeper afterwards, so it would only be feasible if you have a addnum_3levels_deep predicate and even then it would be clearer to use this solution and count the depth.
addnumdeep(N,[X|Y],[G|H]):-
!, % cut if it is a nonempty list
(number(X)->
G is N + X;
addnumdeep(N,X,G)), % recurse into head
addnumdeep(N,Y,H). % recurse into tail
addnumdeep(_,A,A).
Note that this also allows addnumdeep(7,3,3). if you want it to be addnumdeep(7.3.10), you'll have to extract the condition in the brackets:
addnumdeep(N,[X|Y],[G|H]):-
!, % cut if it is a nonempty list
addnumdeep(N,X,G),
addnumdeep(N,Y,H).
addnumdeep(N,X,Y):-
number(X),!, % cut if it is a number.
Y is N+X.
addnumdeep(_,A,A).
This solution is nicer, because it highlights the three basic cases you might encounter:
It is either a list, then recourse, or a number, for everything else, just put it into the result list's tail (this also handles the empty list case). On the other hand you'll need red cuts for this solution, so it might be frowned upon by some purists.
If you don't want red cuts, you can replace the last clause with
addnumdeep(_,A,A):- !, \+ number(A), \+ A = [_|_].
If you don't want non-lists to be allowed, you could check with is_list if it is a list first and then call the proposed predicate.
I'd start with something that tells me whether a term is list-like or not, something along these lines:
is_list_like( X ) :- var(X) , ! , fail .
is_list_like( [] ) .
is_list_like( [_|_] ) .
Then it's just adding another case to your existing predicate, something like this:
add_num( _ , [] , [] ) . % empty list? all done!
add_num( N , [X|Xs] , [Y|Ys] ) :- % otherwise...
number(X) , % - X is numeric?
Y is X + N , % - increment X and add to result list
add_num( N , Xs , Ys ) % - recurse down
. %
add_num( N , [X|Xs] , [Y|Ys] ) :- % otherwise...
is_list_like( X ) , % - X seems to be a list?
! ,
add_num( N , X , Y ) , % - recurse down on the sublist
add_num( N , Xs , Ys ) % - then recurse down on the remainder
. %
add_num( N , [X|XS] , [Y|Ys] ) :- % otherwise (X is unbound, non-numeric and non-listlike
X = Y , % - add to result list
add_num( N , Xs , Ys ) % - recurse down
. %

Prolog - solving problems with lists

Hello I have to solve some prolog problems with lists but i can't figure it out how these work.
I have to add "1" after every even element in a list, and to make the difference of 2 lists.
I know this seems easy, in other language like java or c# i would make it very easy, but prolog it's giving me headaches.
Please help me :|
Edited to note the clarified problem statement ("even item" meaning the item's value is even (rather than the item's ordinal position within the list):
insert_one_after_even_items( [] , [] ). % if the source list is exhaused, we're done.
insert_one_after_even_items( [X|Xs] , [X,1|Ys] ) :- % otherwise,
0 is X mod 2 , % - if the number is even, prepend it and a 1 to the result list, and
insert_one_after_even_items( Xs , Ys ) % - recurse down.
. %
insert_one_after_even_items( [X|Xs] , [X|Ys] ) :- % otherwise,
1 is X mod 2 , % - if the number is odd, prepend it to the result list, and
insert_one_after_even_items( Xs , Ys ) % - recurse down.
. % Easy!
For your second problem, producing the difference between two lists, are you talking about set differences? If so, given two sets A and B, are you talking about the relative difference (all elements of A that do not exist in B), or the absolute difference (all elements of either A or B that do not exist in both sets)?
To solve the relative set difference problem (Find all members of A that do not also exist in B), you can use the built-in member/2 predicate:
relative_difference( [] , _ , [] ) . % if the source list is exhausted, we're done
relative_difference( [A|As] , Bs , R ) :- % if the source list is non-empty, and
member(A,Bs) , % - the current A is an element of B,
! , % - we insert a deterministic cut (no backtracking)
relative_difference( As , Bs , R ) % - and recurse down, discarding the current A
. %
relative_difference( [A|As] , Bs , [A|R] ) :- % if the source list is non-empty (and A is not an element of B due to the cut inserted earlier)
relative_difference( As , Bs , R ) % we simply add A to the result list and recurse down.
.
One thing you will note here: we are building the result list in all of these examples is built from a variable. The tail of the list is unbound (and passed as the new result to the next recursive call, where it either become a new list node or, at the very end, the empty list.
This has the effect of
building the list in order (rather than in reverse order).
if the result was bound on the initial call, unification against the expected result occurs item by item as the recursion proceeds, which means
execution is short-circuited when the first unification failure occurs.
If your prolog implementation doesn't have member/2 as a built in, it's easy enough to implement. Something like this ought to do it:
member(X,[X|T]) :- ! . % A hit! cut and succeed.
member(X,[_|T]) :- member(X,T) . % ... and a miss. Just recurse down on the tail.

Resources