Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
201 views
in Technique[技术] by (71.8m points)

Grounding in Prolog given a predicate and a list

Given a predicate and a list I want a list of all the possible ways of grounding. For example:

gounding(predicate(X), [a,b,c], Grounded).

Should return

[predicate(a), predicate(b), predicate(c)]

And I would also like it to work with more than one variable, for example:

grounding(predicate(X,Y), [a,b,c], Grounded).
Grounded = [predicate(a,a), predicate(a,b), predicate(a,c), predicate(b,a), predicate(b,b), predicate(b,c), predicate(c,a), predicate(c,b), predicate(c,c)]

The problem is given by the fact that the predicate is not always the same, so it needs to be passed as a variable. Like:

grounding(Predicate, Arity, [a,b,c], Grounded).

Is there something that already does this or should it be done manually? I tried using atom_concat with the name of the predicate, the brackets and the elements of the list, but it returns the list with quotes like:

['predicate(a)', 'predicate(b)', 'predicate(c)']

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Let's start with a simpler problem: Given a list of variables and a list of ground values, assign those ground values to the variables. For example:

?- variables_values([X], [a, b, c]).
X = a ;
X = b ;
X = c.

This can be implemented like this:

variables_values([], _Values).
variables_values([Variable | Variables], Values) :-
    member(Variable, Values),
    variables_values(Variables, Values).

A bigger example:

?- variables_values([X, Y], [a, b, c]).
X = Y, Y = a ;
X = a,
Y = b ;
X = a,
Y = c ;
X = b,
Y = a ;
X = Y, Y = b ;
X = b,
Y = c ;
X = c,
Y = a ;
X = c,
Y = b ;
X = Y, Y = c.

The term_variables/2 predicate gives you a list of all the variables in a term. You can combine this with the above predicate:

?- Pattern = predicate(X, Y), term_variables(Pattern, Variables), variables_values(Variables, [a, b, c]).
Pattern = predicate(a, a),
X = Y, Y = a,
Variables = [a, a] ;
Pattern = predicate(a, b),
X = a,
Y = b,
Variables = [a, b] ;
Pattern = predicate(a, c),
X = a,
Y = c,
Variables = [a, c] ;
Pattern = predicate(b, a),
X = b,
Y = a,
Variables = [b, a] .  % etc.

Note that instantiating the variables in the list also instantiates them in the pattern -- the variables are shared.

Given this, the last piece of the puzzle is a predicate that computes a list of instantiations of a pattern, given some predicate that instantiates variables. findall/3 is the right tool for this job:

pattern_values_grounded(Pattern, Values, Grounded) :-
    term_variables(Pattern, Variables),
    findall(Pattern, variables_values(Variables, Values), Grounded).

This does what you seem to want:

?- pattern_values_grounded(predicate(X), [a, b, c], Grounded).
Grounded = [predicate(a), predicate(b), predicate(c)].

?- pattern_values_grounded(predicate(X, Y), [a, b, c], Grounded).
Grounded = [predicate(a, a), predicate(a, b), predicate(a, c), predicate(b, a), predicate(b, b), predicate(b, c), predicate(c, a), predicate(c, b), predicate(..., ...)].

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...