Lambda 从Prolog中调用执行的主体检索输出
假设我们有一个谓词Lambda 从Prolog中调用执行的主体检索输出,lambda,prolog,meta-predicate,Lambda,Prolog,Meta Predicate,假设我们有一个谓词p/2,它执行类似的操作: p('an atom', OutputList) :- some_predicate_1, some_predicate_2, ... findall(...,...,OutputList). p/2做了一些任意复杂的事情,最后将一些结果放入OutputList 假设我需要将谓词p/2的主体放在一个列表中: Body=[some_predicate_1,…,findall(…,…,OutputList)]我想执行它 如果我执行类似于
p/2
,它执行类似的操作:
p('an atom', OutputList) :-
some_predicate_1,
some_predicate_2,
...
findall(...,...,OutputList).
p/2
做了一些任意复杂的事情,最后将一些结果放入OutputList
假设我需要将谓词p/2
的主体放在一个列表中:
Body=[some_predicate_1,…,findall(…,…,OutputList)]
我想执行它
如果我执行类似于调用(Body)
的操作,如何检索输出列表
还有其他谓词可以使用吗
也许call/1
或call/2
不适合这个目的。可能很容易做到
get_output_list(Predicates, Outputlist) :-
last(Predicates, findall(_,_,Outputlist)),
maplist(call, Predicates).
如果findall/3并不总是最后一个,那么它应该可以工作
get_output_list(Predicates, Outputlist) :-
maplist(call, Predicates),
member(findall(_,_,Outputlist), Predicates).
在谓词中可能有多个findall的情况下,将member/2放在maplist/2之后将获得回溯上的所有Outputlist
get_output_list(Predicates, Outputlist) :-
last(Predicates, findall(_,_,Outputlist)),
maplist(call, Predicates).
如果findall/3并不总是最后一个,那么它应该可以工作
get_output_list(Predicates, Outputlist) :-
maplist(call, Predicates),
member(findall(_,_,Outputlist), Predicates).
如果谓词中可能有多个findall,那么将member/2放在maplist/2之后将使所有Outputlist返回到backtracking上很容易做到:除了目标列表之外,还要跟踪变量,以便轻松引用它。例如,使用类似于
OutputList-[some_predicate_1,…,findall(…,…,OutputList)]
的对。然后,在maplist(call,Ls)
之后(其中Ls
是这一对的第二部分,即目标列表),您可以参考OutputList
,它很容易作为这一对的第一项。这是解决这些问题的一个相当普遍的办法。您只需要跟踪以后要引用的变量。顺便说一下,请注意这些结构与实际的Prolog规则的相似性!谢谢,但我不确定我能不能做到。我必须使用变量体,比如call(Body)。我无法将其与实际谓词相关联,因为它们可以是任意的。不管怎样,您仍然可以使用像OutputList Body
这样的一对谓词,在call(Body)
之后,您可以参考OutputList
。然而,我强烈推荐一个清晰的目标列表,这也是你在问题中指出的。在您的问题中,Body
是一个列表,您可以使用maplist(call,goals)
来调用这些目标。这是一个更好的表示方式,因为它不是默认的。简单操作:除了目标列表之外,还要跟踪变量,以便您可以轻松地引用它。例如,使用类似于OutputList-[some_predicate_1,…,findall(…,…,OutputList)]
的对。然后,在maplist(call,Ls)
之后(其中Ls
是这一对的第二部分,即目标列表),您可以参考OutputList
,它很容易作为这一对的第一项。这是解决这些问题的一个相当普遍的办法。您只需要跟踪以后要引用的变量。顺便说一下,请注意这些结构与实际的Prolog规则的相似性!谢谢,但我不确定我能不能做到。我必须使用变量体,比如call(Body)。我无法将其与实际谓词相关联,因为它们可以是任意的。不管怎样,您仍然可以使用像OutputList Body
这样的一对谓词,在call(Body)
之后,您可以参考OutputList
。然而,我强烈推荐一个清晰的目标列表,这也是你在问题中指出的。在您的问题中,Body
是一个列表,您可以使用maplist(call,goals)
来调用这些目标。这是一个更好的表述,因为它不是默认的。谢谢,但我不能假设结果总是作为最后一条给出。再次感谢。虽然结果几乎不一定是findall,但它始终是规则p/2头部的第二个参数。我可以通过子句/2得到这个结果,但是我不知道在我执行了body中的所有谓词之后如何将它与OutputList绑定(我也将body作为一个变量,它不与它的实际谓词绑定,因为它们可能不同,而且我无法提前预测结构)。子句/2似乎不太合适。。。也许你应该进一步澄清你的期望。似乎与你的问题不符。谢谢,但我不能假设结果总是作为最后一条给出。再次感谢。虽然结果几乎不一定是findall,但它始终是规则p/2头部的第二个参数。我可以通过子句/2得到这个结果,但是我不知道在我执行了body中的所有谓词之后如何将它与OutputList绑定(我也将body作为一个变量,它不与它的实际谓词绑定,因为它们可能不同,而且我无法提前预测结构)。子句/2似乎不太合适。。。也许你应该进一步澄清你的期望。似乎与你的问题不符。