prolog - 有人可以逐步描述这个 Prolog 代码吗?

标签 prolog division predicate clpfd

Prolog 对我来说是新的。我试图理解这段代码。如果有人能用 child 语言逐步解释它,那将是一个很大的帮助;)谢谢!

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.

最佳答案

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

What relation does the predicate describe?

实际上,这个问题很难回答,因为我们会一步一步地解决这个问题。但是有一种更好更清洁的方法!由于您的程序仅使用整数,我们可以映射模式关系 (<)/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 ... 股息
  • D ... 除数
  • Q ...商数
  • R ... 剩余

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

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

下一个答案:

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

商是 1,被除数是除数加余数,而且——在所有答案中——余数小于除数

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

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

;  Q = 3, _A+D#=N, _B+D#=_A, R+D#=_B, R#=<D+ -1, N#>=D, _A#>=D, _B#>=D
;  Q = 4, _A+D#=N, _B+D#=_A, _C+D#=_B, R+D#=_C, R#=<D+ -1,
   N#>=D, _A#>=D, _B#>=D, _C#>=D
;  ... .

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

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

甚至更好:

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

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

当您启动 Prolog 时,请关注声明方面。正如谓词所描述的(集合/关系)。程序方面稍后会毫不费力地加入。

关于prolog - 有人可以逐步描述这个 Prolog 代码吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20005036/

相关文章:

swift - 具有字典参数的 Realm 中的谓词

python - ANTLR 语义谓词 - 不阻止规则

list - 在Prolog中设置两个兼容列表的差异

recursion - 序言递归跳过相同的结果

prolog - SWI-Prolog 中的方程求解器

java - 如何在 Eclipse 中使用 JPL(swi-prolog 的 java prolog 接口(interface))?

c++ - 带unsigned int的字节数组的求余算法

java - 查找一个非常大的数是否可以被 7 整除的高效算法

ruby - 为什么我不能将一个 fixnum 除以另一个 fixnum?

c# - 在 C# 中使用谓词替换 'if' 的示例?