将子句列表转换为查询?

Converting list of clauses to a query?

假设我有以下事实:

book(65).
own(named('Peter'), 65).

现在将查询作为子句列表获取:

 [what(A), own(named('Peter'), A)] 

 [who(X), book(A), own(X, A)] .

如何制定接受此列表和 return 结果的规则。请记住,问题可能是为什么、何时、谁...

我走的是平常的路:

query_lst([]).
%% query_lst([what(Q)|T], Q) :- query_lst(T). 
query_lst([H|T]) :- write('?- '),writeln(H), 
    call(H), query_lst(T).

但这不允许将 wh(Q) 中的 Q 绑定到答案,而答案可能存在于 call()

调用的任何事实中

我没有预见到的其他并发症是查询:

(what(A), own(named('Peter'), A).

会失败,因为数据库中没有 what(X) 事实。 我必须以某种方式将 what()/ 中的变量 A / 绑定到 query_lst(Goals,A) 并且当然从列表中删除 what(X) /我可以用 select/3 /

知道如何将 list-Wh-var 绑定到 query_lst 结果吗?


我当前的解决方案(假设 Q 是第一个元素):

 query_lst([G|Gs],Res) :- G =.. [Q,Res], member(Q,[what,why,who,when]), lst2conj(Gs,Conj), call(Conj).

只需将目标列表转换为连词并调用它:

list_to_conjunction([], true).
list_to_conjunction([Goal| Goals], Conjunction) :-
    list_to_conjunction(Goals, Goal, Conjunction).

list_to_conjunction([], Conjunction, Conjunction).
list_to_conjunction([Next| Goals], Goal, (Goal,Conjunction)) :-
    list_to_conjunction(Goals, Next, Conjunction).

然后:

query_list(Goals) :-
    list_to_conjunction(Goals, Conjunction),
    call(Conjunction).

您得到了答案,但这是对您问题的回答,而不是您真正想要的。此外,您在接受该答案后编辑了您的问题,这不是很有帮助。通常,当您有...一个新问题时,最好打开一个新问题。

这里是你似乎想要的的答案,这与你问的不完全一样。您有 [WhPart | Rest] 形式的列表,其中 WhPart 是带有变量的 wh-word,而 Rest 是目标列表。您想执行这些目标并获得 wh-term 范围内的变量。

好消息是,由于wh-word中的变量也出现在目标中,如果你执行它们,它就会被绑定。不需要额外的工作。执行目标就足够了。如果 wh-part 真的在列表的开头,你可以这样做:

query([_WhPart | Body]) :-
    call_body(Body).

call_body([]).
call_body([Goal | Goals]) :-
    call(Goal),
    call_body(Goals).

例如:

?- query([who(X), book(A), own(X, A)]).
X = named('Peter'),
A = 65.

?- query([what(A), own(named('Peter'), A)]).
A = 65.

如您所见,无需将查询转换为联合目标:按顺序执行查询与执行它们的联合完全相同。

此外,使用哪个 wh-word 实际上并不重要;唯一真正重要的是术语中包含的变量。由于这个原因,上面的版本根本没有检查, _WhPart 可以是任何东西。如果要检查它是否是有效术语,可以执行以下操作:

query([WhPart | Body]) :-
    wh(WhPart),
    call_body(Body).

wh(who(_X)).
wh(what(_X)).
wh(when(_X)).

这会给你带来一些“类型检查”:

?- query([foo(A), own(named('Peter'), A)]).
false.

但不是很多,因为您不知道 wh-word 是否真的符合所问的内容:

?- query([when(A), own(named('Peter'), A)]).
A = 65.