有人可以一步一步地描述这个Prolog代码吗?

时间:2013-11-15 15:51:08

标签: prolog division predicate clpfd

Prolog对我来说是新手。我正在尝试理解这段代码。如果有人能用儿童语言逐步解释这将是一个很大的帮助;)谢谢你!

divide_by(X,D,I,R) :- 
   X < D,
   I is 0,
   R is X.
divide_by(X,D,I,R) :- 
   X >= D,
   Q is X - D, 
   divide_by(Q, D, S, R),
   I is S +1.

2 个答案:

答案 0 :(得分:3)

嗯,我不能。你问的是错误的问题。正确的问题是:

  

谓词描述的是什么关系?

实际上,这很难回答,因为我们会一步一步地完成它。但是有一种更好,更清洁的方式!由于您的程序仅使用整数,我们可以将模式化关系(<)/2(is)/2等映射到CLP(FD)中的声明对应关系。因此,我将<更改为#<,将is更改为#=,将>=更改为#>=

:- use_module(library(clpfd)).

divide_by(X,D,I,R):-
    X #< D, I #= 0, R #= X.
 divide_by(X,D,I,R):-
    X #>= D, Q #= X - D,
    I #= S +1,
    divide_by(Q, D, S, R).

现在最大的优势是我可以向Prolog询问它认为关系所描述的内容。只需询问:(不要担心Q=Q,只是重新排序变量)

  • N ... dividend
  • D ... divisor
  • Q ... quotient
  • R ...余下

?- Q=Q, divide_by(N,D,Q,R).
 Q = 0,
 N = R,
 R#=<D+ -1

这个答案如下:商为零,被除数和余数相同,余数小于除数。所以这描述了0是“结果”或商的所有情况。

下一个回答:

;
 Q = 1,
 R+D#=N,
 N#>=D,
 R#=<D+ -1

商是1,被除数是除数加上余数,而且 - 如同所有答案一样 - 余数小于除数

;
 Q = 2,
 _G1665+D#=N,
 N#>=D,
 R+D#=_G1665,
 _G1665#>=D,
 R#=<D+ -1

此答案与R+D+D#= N相同。系统引入了一些额外的变量。没错,但读起来有点笨拙。

;
 Q = 3,
 _G1930+D#=N,
 N#>=D,
 _G1951+D#=_G1930,
 _G1930#>=D,
 R+D#=_G1951,
 _G1951#>=D,
 R#=<D+ -1
;
 Q = 4,
 _G2195+D#=N,
 N#>=D,
 _G2216+D#=_G2195,
 _G2195#>=D,
 _G2237+D#=_G2216,
 _G2216#>=D,
 R+D#=_G2237,
 _G2237#>=D,
 R#=<D+ -1 ...

等等。让我总结一下。所有答案都是这样的:

N#>=D, R#< D,  R+D+...+D#= N
                 ^^^^^^^ Q times

甚至更好:

N#>=D, R #< D, R+Q*D #= N, Q #>= 0.

所以我们回答的是这个关系所描述的

当你启动Prolog时,请关注声明方面。正如谓词所描述的那样(集合/关系)。程序方将在以后不加努力地加入。

答案 1 :(得分:1)

第一条规则称为base case。它将终止递归。

divide_by(X,D,I,R):- 
    X < D,   % this rule apply only if numerically X is < D
    I is 0,  % will fail if I \= 0
    R is X.  % if I = 0 assign expression X to R

这是另一个递归步骤。

divide_by(X,D, I, R):- 
    X >= D,      % this rule apply only if X is >= D
    Q is X - D,  % evaluate Q
    divide_by(Q, D, S, R),  % recursive call. Q & D are surely instantiated
    I is S + 1.  % evaluate I as S + 1

所以,我会说:它将计算X的整数除以D,其余为R,在模式divide_by(+,+,-,-)中调用时,即前两个参数绑定到整数最后两个免费。

无论如何,错误的答案是非常好的,因为它显示了一种可能的方法来推理“常见”编程语言中没有的算法。