Prolog:从谓词列表中生成一组所有基本术语 [英] Prolog: generate a set of all ground terms from a list of predicates
问题描述
鉴于以下事实:
female(alice).
male(bob).
male(charlie).
lives(alice,oxford).
lives(bob,oxford).
lives(charlie,cambridge).
我要生成集合:
[alice,bob,charlie,oxford,cambridge].
我知道如何处理单个谓词:
I know how to this for a single predicate:
?- setof(X, male(X), S).
S = [bob, charlie].
但我不知道如何概括这一点.目的是使用谓词列表查询程序:
But I do not know how to generalise this. The aim is to query the program with a list of predicates:
f([male/1,female/1,lives/2]).
我试图概括上面的setof"语句:
I tried to generalise the above 'setof' statements:
g(P,1) :-
Atom = [P,X],
Goal =..Atom,
setof(X, Goal(X, Y), S),
write(S).
g(P,2).
f([]).
f([H|T]) :-
H = P/A,
g(P,A),
f(T).
但这没有用.
有人可以帮忙吗?
推荐答案
大功告成.Prolog 中的高阶编程可以通过call
或 apply
谓词.这是一个带有 call/1
的版本,由 ISO 标准化:
You're almost there. Higher-order programming in Prolog can be achieved with the call
or apply
predicates. Here's a version with call/1
, which is standardized by ISO:
get_ground_args(Goal, Args) :-
findall(X, (call(Goal), Goal =.. [_|GoalArgs], member(X, GoalArgs)), Args).
示例:
?- get_ground_args(lives(_,_), Args).
Args = [alice, oxford, bob, oxford, charlie, cambridge].
现在要将其与您的原始设置联系起来,使用 length/2
在嵌套的 setof
/findall
中生成初始参数:
Now to tie this in to your original setup, use length/2
to generate the initial arguments inside a nested setof
/findall
:
all_ground_args(Preds, Args) :-
setof(X, (findall(Y, (member(Pred/Arity, Preds),
length(GoalArgs, Arity),
Goal =.. [Pred|GoalArgs],
get_ground_args(Goal, GroundArgs),
member(Y, GroundArgs)),
AllArgs),
member(X, AllArgs)),
Args).
演示:
?- all_ground_args([male/1,female/1,lives/2], Args).
Args = [alice, bob, cambridge, charlie, oxford].
(当谓词具有非基础参数时,所有这些都可能会失败.)
(All of this will probably fail when a predicate has non-ground args.)
这篇关于Prolog:从谓词列表中生成一组所有基本术语的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!