给定谓词和列表的 Prolog 基础

Ele*_*ena 3 prolog

给定一个谓词和一个列表,我想要一个所有可能的接地方式的列表。例如:

gounding(predicate(X), [a,b,c], Grounded).
Run Code Online (Sandbox Code Playgroud)

应该返回

[predicate(a), predicate(b), predicate(c)]
Run Code Online (Sandbox Code Playgroud)

而且我还希望它使用多个变量,例如:

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)]
Run Code Online (Sandbox Code Playgroud)

问题在于谓词并不总是相同的,因此需要将其作为变量传递。喜欢:

grounding(Predicate, Arity, [a,b,c], Grounded).
Run Code Online (Sandbox Code Playgroud)

是否有什么已经这样做了还是应该手动完成?我尝试将atom_concat与谓词的名称、方括号和列表的元素一起使用,但它返回带有引号的列表,例如:

['predicate(a)', 'predicate(b)', 'predicate(c)']
Run Code Online (Sandbox Code Playgroud)

Isa*_*bie 5

让我们从一个更简单的问题开始:给定一个变量列表和一个地面值列表,将这些地面值分配给变量。例如:

?- variables_values([X], [a, b, c]).
X = a ;
X = b ;
X = c.
Run Code Online (Sandbox Code Playgroud)

这可以像这样实现:

variables_values([], _Values).
variables_values([Variable | Variables], Values) :-
    member(Variable, Values),
    variables_values(Variables, Values).
Run Code Online (Sandbox Code Playgroud)

一个更大的例子:

?- 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.
Run Code Online (Sandbox Code Playgroud)

term_variables/2谓词为您提供了一个学期的所有变量的列表。您可以将其与上述谓词结合使用:

?- 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.
Run Code Online (Sandbox Code Playgroud)

请注意,实例化列表中的变量也会在模式中实例化它们——变量是共享的。

鉴于此,难题的最后一部分是计算模式实例化列表的谓词,给定一些实例化变量的谓词。findall/3是这项工作的正确工具:

pattern_values_grounded(Pattern, Values, Grounded) :-
    term_variables(Pattern, Variables),
    findall(Pattern, variables_values(Variables, Values), Grounded).
Run Code Online (Sandbox Code Playgroud)

这做你似乎想要的:

?- 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(..., ...)].
Run Code Online (Sandbox Code Playgroud)