首页 > 解决方案 > 有没有更简洁的方法可以在序言中明确评估某些内容?

问题描述

我正在尝试学习序言,作为练习,我尝试实现扩展欧几里得算法;我到底在做什么并不是特别重要,因为我只对特定的语法感兴趣,但这里是完整的代码:

e_gcd(A, B, Lx, Ly) :-
    e_gcd(A, B, 0, 0, 1, 0, Lx, Ly).

e_gcd(_, 0, _, _, LX, LY, LX, LY).

e_gcd(A, B, X, Y, LX, LY, FX, FY) :-
    Q is A // B,
    M is A mod B,
    e_gcd(B, M, LX-Q*X, LY-Q*Y, X, Y, FX, FY).

我需要这样做M is A mod B,然后e_gcd(B, M, LX-Q*X, LY-Q*Y, X, Y, FX, FY).因为否则我稍后会得到一个零除法错误,因为我通过了检查e_gcd(_, 0, _, _, LX, LY, LX, LY).
我的问题是:有没有一种方法可以A mod B在不存储的情况下进行评估M?如果可能的话,我想避免命名我在下一行而不是其他地方使用的东西(我很好,Q因为我需要使用它两次)。

标签: prolog

解决方案


您不必立即进行评估A mod B。但请注意,形式的未计算表达式A mod B永远不会与常量 like 统一0,因此如果要将其与 0 进行比较,则需要在第一个子句中计算参数项。

所以你可以写这个,但它不会比你所拥有的更短:

e_gcd(_, B, _, _, LX, LY, LX, LY) :-
    B =:= 0.  % force evaluation of the term B to a number, then compare

e_gcd(A, B, X, Y, LX, LY, FX, FY) :-
    B =/= 0,
    Q is A // B,
    e_gcd(B, A mod B, LX-Q*X, LY-Q*Y, X, Y, FX, FY).

推荐阅读