Re: Meta Predicates and Variables in SWI Prolog
From: Bart Demoen (bmd_at_cs.kuleuven.ac.be)
Date: 03/31/04
- Previous message: Michael David Pedersen: "Re: Meta Predicates and Variables in SWI Prolog"
- In reply to: Michael David Pedersen: "Re: Meta Predicates and Variables in SWI Prolog"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Wed, 31 Mar 2004 15:59:44 +0200
Michael David Pedersen wrote:
> Hi Bart,
>
> Thank you for your prompt reply.
>
>
>>Michael David Pedersen wrote:
>>
>>>However the list is being constructed at runtime and looks like
>>>['A','B',
>>>'_']. I thus need to convert this to a list of atoms as needed in the
>>>apply predicate.
>>>
>>
>>I would expect you to want to convert the list ['A', 'B', '_']
>>to a list of VARIABLES. No ?
>
>
> Right, I actually though that variables are atoms as well -- clearly, this
> is wrong (variables are terms).
>
>
>
>>>term_to_atom('A', Atom).
>>
>>term_to_atom is not what you need. You could use it as follows:
>>
>>?- term_to_atom(X,'A').
>>
>>and that will unify X with a free variable - but that doesn't
>>do much, does it ?
>>Moreover, if you do
>>
>>
>>?- term_to_atom(X,'A'), term_to_atom(Y,'A').
>>
>>X and Y will be DIFFERENT variables and that might not be what you want
>>...
>
>
> Right, this is not what I want.
>
>
>>Maybe you should consider changing the generation of the list in the first
>>place.
>
>
> But this is my problem -- I cannot find a way to do this. Maybe an excerpt
> from the code I am working with will help. I am trying to implement part
> of the relational algebra in prolog, and the following is a (simplified)
> example of how projection would work:
> -------------------------
> /********************
> Project is the top-level projection predicate
> ********************/
> project(Rel, AttrList) :-
> sort(AttrList, Sorted),
> pad(1, 3, Sorted, Padded),
> apply(Rel, PaddedAtoms). /** PROBLEM **/
>
> /**************************
> The pad predicate pads a sorted list of integers (x1, x2, ..., xn) with
> underscores so that each xi occurs on position i in the list. Furthermore,
> each xi is prepended with an 'A', so that it can be interpreted as a Prolog
> variable. Example where Arity=6:
>
> (1, 2, 5) -> ('A1', 'A2', '_', '_', 'A5', '_')
> ***************************/
> /* bottom case */
> pad(Arity, Arity, [X], [AX]) :-
> string_concat('A', X, AX).
>
> /* The next two predicates handle the case where underscores must be
> prepended */
> pad(Arity, Arity, [], ['_']).
>
> pad(Pos, Arity, [], ['_'|Xs]) :-
> Pos \== Arity,
> succ(Pos, Pos2),
> pad(Pos2, Arity, [], Xs).
>
> pad(Pos, Arity, [X|Xs], [AX|Ys]) :-
> Pos \== Arity,
> Pos == X,
> string_concat('A', X, AX),
> succ(Pos, Pos2),
> pad(Pos2, Arity, Xs, Ys).
>
> pad(Pos, Arity, [X|Xs], ['_'|Ys]) :-
> Pos \== Arity,
> Pos \== X,
> succ(Pos, Pos2),
> pad(Pos2, Arity, [X|Xs], Ys).
>
> /*************
> Here follows an example relation used to test the code above.
> *************/
> rela(a, b, c).
> rela(d, e, g).
> -------------------------
>
> project(rela, [1, 3]) should then return A1=a, A3=c and A1=d, A3=g which
> is what I want. However the list [1, 3] is the result of lexing and parsing,
> and hence it _IS_ on the form ['1', '3'] (and subsequently on the form
> ['A1', 'A2'] after coming through the pad predicate). So this still does not
> work in the apply predicate.
>
> Do you have any further ideas/hints on how to convert the list of character
> strings into a list of VARIABLES, as you correctly understood?
>
>
>>BTW, if you don't understand how term_to_atom works, try (to start with)
>>queries like
>>
>>?- term_to_atom(X,'f(asd,[X],3.14)').
>>
>>and
>>
>>?- term_to_atom(X,'f(asd,[X],3.14').
>
>
> What is the difference between the two queries (except a missing bracket,
> which causes a syntax error)?
>
> Thanks a lot for your help!
> Regards,
>
> Michael David Pedersen
>
I might have just what you need ...
pad(N,Max,Positions,VarsAtPositions,VarList) :-
(N > Max ->
VarList = [],
VarsAtPositions = []
;
VarList = [NewVar|RestVarList],
N1 is N + 1,
(Positions = [N|RestPositions] ->
VarsAtPositions = [NewVar|RestVarsAtPositions],
pad(N1,Max,RestPositions,RestVarsAtPositions,RestVarList)
;
pad(N1,Max,Positions,VarsAtPositions,RestVarList)
)
).
/*
try
?- pad(1,6,[1,2,5],VarsAtPositions,VarList).
*/
rel(a, b, c).
rel(d, e, g).
project(PredName,Positions,VarsAtPositions) :-
Max = 3, % you have to decide on the arity
pad(1,Max,Positions,VarsAtPositions,VarList),
Goal =.. [PredName|VarList],
call(Goal).
/*
?- project(rel,[1,3],Out).
*/
Cheers :-)
Bart Demoen
- Previous message: Michael David Pedersen: "Re: Meta Predicates and Variables in SWI Prolog"
- In reply to: Michael David Pedersen: "Re: Meta Predicates and Variables in SWI Prolog"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]