List 是否将子句列表转换为查询?

List 是否将子句列表转换为查询?,list,prolog,call,clause,List,Prolog,Call,Clause,假设我有以下事实: book(65). own(named('Peter'), 65). 现在以子句列表的形式获取查询: [what(A), own(named('Peter'), A)] 或 如何制定接受此列表并返回结果的规则。请记住,问题可能是为什么,何时,谁 我照常走: query_lst([]). %% query_lst([what(Q)|T], Q) :- query_lst(T). query_lst([H|T]) :- write('?- '),writeln(H),

假设我有以下事实:

book(65).
own(named('Peter'), 65).
现在以子句列表的形式获取查询:

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

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

我照常走:

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/来查询(Goals,A),当然还要从列表中删除what(X),我可以使用select/3来执行此操作/

知道如何将list Wh var绑定到查询结果吗


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


只需将目标列表转换为连词,并将其称为:

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).
然后:


你得到了答案,但这是对你问题的回答,而不是你真正想要的。另外,你在接受答案后编辑了你的问题,这并没有多大帮助。通常情况下,当你有。。。一个新问题

这是一个你似乎想要的答案,而不是你所要求的。您有
[WhPart | Rest]
格式的列表,其中
WhPart
是一个带变量的wh单词,
Rest
是一个目标列表。您希望执行这些目标并获得wh术语范围中的变量

好消息是,由于wh单词中的变量也出现在目标中,因此如果执行它们,它将被绑定。不需要额外的工作。执行这些目标就足够了。如果wh部分真的在列表的开头,您可以这样做:

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词实际上并不重要;唯一真正重要的是术语中包含的变量。由于这个原因,上面的版本根本不进行检查,
\u WhPart
可以是任何内容。如果要检查该术语是否有效,可以执行以下操作:

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

wh(who(_X)).
wh(what(_X)).
wh(when(_X)).
这为您带来了一些“类型检查”:

但不是很多,因为你不知道wh这个词是否真的适合被问到的问题:

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

谢谢我只是好奇为什么我们不能用l2c()中的一个来实现同样的事情……这似乎应该是可行的:l2c([G | Gs],Conj):-l2c(Gs,(Conj,G))。但是l2c([],2;)。使其不可能。
list\u to\u连接/2
谓词的定义利用了第一个参数索引,以避免在使用绑定项列表调用时出现虚假的选择点。它还避免了在连接结束时(使用非空的目标列表)添加对
true/0
的冗余调用。第一个参数索引?很好。。但是这个列表是隐藏的。。生成(Txt、GLst)、查询(GLst)。。。您只需返回true | false,而不是统一的Wh变量,因为它不会在整个过程中“表面化”!!你可以定义wh(who(X),X)。wh(what(X),X)。等,然后
查询(X,[WhPart | Body]):-wh(WhPart,X),调用_Body(Body)。
显示变量。
?- query([who(X), book(A), own(X, A)]).
X = named('Peter'),
A = 65.

?- query([what(A), own(named('Peter'), A)]).
A = 65.
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.
?- query([when(A), own(named('Peter'), A)]).
A = 65.