繁体   English   中英

否定 \+ 和香草元解释器

[英]negation \+ and vanilla meta-interpreter

以下是 prolog 的经典“教科书”香草元解释器。

% simplest meta-interpreter
solve(true) :- !.
solve((A,B)):- !, solve(A), solve(B).
solve(A) :- clause(A,B), solve(B).

下面是一个简单的程序,它建立了两个“正”关系和一个使用失败\+否定的关系。

% fruit
fruit(apple). 
fruit(orange). 
fruit(banana).

% colour
yellow(banana).

% Mary likes all fruit 
likes(mary, X) :- fruit(X).

% James likes all fruit, as long as it is yellow
likes(james, X) :- fruit(X), yellow(X).

% Sally likes all fruit, except yellow fruit
likes(sally, X) :- fruit(X), \+ (yellow(X)).

元解释器可以处理与前两个关系相关的目标?-solve(likes(mary,X))?- solve(likes(james,X)_

然而,它失败了与第三个关系相关的目标?- solve(likes(sally,X) 。swi-prolog 报告在程序崩溃之前达到了堆栈限制。

问题 1:是什么导致元解释器失败? 是否可以轻松调整以应对\+否定? 这是否与有时讨论的内置函数不被香草元解释器执行的问题有关?

问题 2:我在哪里可以了解到原始元解释器需要进行这些削减?


跟踪表明目标正在无限增长:

clause(\+call(call(call(call(yellow(apple))))),_5488)
 Exit:clause(\+call(call(call(call(yellow(apple))))),\+call(call(call(call(call(yellow(apple)))))))
 Call:solve(\+call(call(call(call(call(yellow(apple)))))))
 Call:clause(\+call(call(call(call(call(yellow(apple)))))),_5508)
 Exit:clause(\+call(call(call(call(call(yellow(apple)))))),\+call(call(call(call(call(call(yellow(apple))))))))
 Call:solve(\+call(call(call(call(call(call(yellow(apple))))))))

solve(A)更改为:

solve(Goal) :-
    writeln(Goal),
    sleep(1),
    clause(Goal, Body),
    solve(Body).

...我们看到:

?- solve_mi(likes(sally,X)).
likes(sally,_8636)
fruit(_8636)
\+yellow(apple)
\+call(yellow(apple))
\+call(call(yellow(apple)))
\+call(call(call(yellow(apple))))
...

clause/2\+yellow(apple)的主体确定为\+call(yellow(apple)) ,这不是简化。

可以改用:

solve_mi(true) :-
    !.
solve_mi((Goal1, Goal2)):-
    !,
    solve_mi(Goal1),
    solve_mi(Goal2).
solve_mi(\+ Goal) :-
    !,
    \+ solve_mi(Goal).
solve_mi(Goal) :-
    clause(Goal, Body),
    solve_mi(Body).

swi-prolog 中的结果:

?- solve_mi(likes(sally,X)).
X = apple ;
X = orange ;
false.

我使用solve_mi是因为solve与例如 clpBNR 的冲突,并且我没有使用变量名AB ,因为它们没有任何意义。

为了理解削减,我建议gtrace ,以查看与其他目标的不必要的统一,否则会发生。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM