I've a problem.
I have 5 constants.
C(1).
C(2).
C(3).
C(4).
C(5).
And I've a predicate named "check" that receives two arguments.
Example:
check( [C(1), C(3), C(4), _, C(5)], ListFinal).
And now it should give me
ListFinal = [C(1), C(3), C(4), C(2), C(5)].
How do I do this? How to check for that black space to put there, the constant I haven't used? It is possible to change the implementation of the constants.
You could try
check( [] , [] ) .
check( [c(X)|Xs] , [c(X)|Rs] ) :- c(X) , check(Xs,Rs) .
You might also look at findall/3
.
You should note however, that your 'constants' aren't constants in prolog. The way you've written them they are are facts. And the ones you've listed aren't syntactically valid Prolog: The functor of a term must be either a bareword atom like c(3).
or an atom enclosed in single quotes like 'C'(3).
(though why anybody would voluntarily choose to do something like that is beyond me.)
check(L, C) :-
check(L, [], C).
check([], _, []).
check([c(X)|T], A, [c(X)|C]) :-
c(X),
\+ memberchk(c(X), A),
check(T, [c(X)|A], C).
Some tests:
| ?- check([_, c(3), c(4), _, c(5)], ListFinal).
ListFinal = [c(1),c(3),c(4),c(2),c(5)] ? a
ListFinal = [c(2),c(3),c(4),c(1),c(5)]
no
| ?- check([c(1), c(3), c(4), _, c(5)], ListFinal).
ListFinal = [c(1),c(3),c(4),c(2),c(5)] ? a
no
| ?-
Here's a DCG approach:
remap([c(X)|T], A) --> {c(X), \+ memberchk(c(X), A)}, [c(X)], remap(T, [c(X)|A]).
remap([], _) --> [].
check(L, C) :- phrase(remap(L, []), C).
once corrected the syntax, check each argument (easy to do with maplist/3)
check(In, Out) :-
exclude(var, In, NoVars),
maplist(check_var(NoVars), In, Out).
check_var(In, X, Y) :-
var(X) -> c(Z), \+ memberchk(c(Z), In), Y = c(Z) ; Y = X.
usage example
1 ?- check([c(1),X,c(3),c(5)],L).
L = [c(1), c(2), c(3), c(5)] ;
L = [c(1), c(4), c(3), c(5)] ;
false.