【问题标题】:Define a predicate inside a predicate in prolog在prolog中的谓词内定义谓词
【发布时间】:2013-02-17 00:36:36
【问题描述】:

我正在尝试定义一个内联谓词以将其传递给 Prolog 中的另一个谓词。

% Test if a "product" of graphs G1 and G2 has a "mini-loop" starting from Q
test_property_combined(G1,G2,Q):-
    (g12(Q1,Q2) :- combine(G1,G2,Q1,Q2)),
    some_property(g12,Q).

(上面的语法显然是错误的。)

稍后g12 将被call 调用

% Test if a graph G has a "mini-loop" starting from Q
some_property(G,Q):-
    Goal1 =.. [G,Q,C],
    Goal2 =.. [G,C,Q],
    call(Goal1),
    call(Goal2).

问题仍然存在,因为我想在某种先前定义的谓词的聚合上测试 some_property

% Create a "product" of graphs G1 and G2
combine(G1,G2,(Q1,Q2),(Q3,Q4)):-
    Goal1 =.. [G1,Q1,Q3],
    Goal2 =.. [G2,Q2,Q4],
    call(Goal1),
    call(Goal2).

上述谓词和测试查询示例:

% g1 and g2 are graphs
g1(a,b).
g1(b,a).

g2(c,d).
g2(d,c).


?- test_property_combined(g1,g2,(a,c)).

如何去做?

【问题讨论】:

  • 对不起,我不明白这一点。你知道lambda吗?
  • 不,但在这里使用它似乎有点矫枉过正。不过感谢您的链接。
  • 不要使用(=..)/2 来模拟高阶编程。请改用 call/N。它更通用,允许使用library(lambda)

标签: lambda prolog metaprogramming predicate


【解决方案1】:

我不确定要明白这一点,但这有效:

test_property_combined(G1,G2,Q):-
    assert((g12(Q1,Q2) :- combine(G1,G2,Q1,Q2))),
    some_property(g12,Q).

好的,可能是这样的

:- use_module(library(lambda)).

test_property_combined(G1,G2,Q):-
    % (g12(Q1,Q2) :- combine(G1,G2,Q1,Q2)),
    Pred = \Z^T^combine(G1,G2,Z,T),
    some_property(Pred,Q).


combine(G1,G2,(Q1,Q2),(Q3,Q4)):-
    Goal1 =.. [G1,Q1,Q3],
    Goal2 =.. [G2,Q2,Q4],
    call(Goal1),
    call(Goal2).


some_property(G,Q):-
    call(G, Q, C),
    call(G, C, Q).

最后一次编辑(希望如此)完整代码:

test_property_combined(G1,G2,Q):-
    some_property(combine(G1,G2),Q).

combine(G1,G2,(Q1,Q2),(Q3,Q4)):-
    call(G1,Q1,Q3),
    call(G2,Q2,Q4).

some_property(G,Q):-
    call(G, Q, C),
    call(G, C, Q).

g1(a,b).
g1(b,a).

g2(c,d).
g2(d,c).

@false => 有用的评论,像往常一样!

【讨论】:

  • 不要忘记通过收回临时谓词进行清理。
  • 是的,retractall(g12(_,_))
  • 谢谢,这行得通。这实际上是我实际代码的淡化版本,但我希望在这里仍然需要定义一个谓词内联。
  • @RihardsKrišlauks:在 some_property/2 内 combine(G1,G2) 将像这样调用: call(combine(G1,G2),Q,C) 有效地调用 combine(G1,G2,Q ,C)
  • @Rihards:如果参数的顺序不完美,并且想要添加更多参数,则需要 lambda。但是要注意变量的作用域:上图,应该是Pred = {G1,G2}+\Z^T^combine(G1,G2,Z,T),