0
votes

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

2
@DanielLyons I was trying to make my explanation simple, didn't notice that, corrected. - jacobbb
@false but it returns a false - jacobbb
@false I solved the problem, the program is really work, the problem is somewhere else, thanks - jacobbb

2 Answers

0
votes

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

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.