Prolog 初学者:如何与算术比较运算符统一或如何将 set var 获取到值的范围

发布于 2024-09-04 07:53:17 字数 769 浏览 7 评论 0原文

我是 Prolog 新手。我需要编写一个整数加法器,它将 0-9 之间的数字与其他数字 0-9 相加,并产生一个解决方案 0-18。这就是我想做的:

% pseudo code
add(in1, in2, out) :-
    in1 < 10,
    in2 < 10,
    out < 18.

我希望能够像这样调用它:

检查它是否是有效的添加:

?- add(1,2,3).
true.
?- add(1,2,4).
false.

缺少一个变量:

?- add(X,2,3).
X = 1.
?- add(1,4,X).
X = 5.

缺少多个变量:

?- add(X,Y,Z).
% Some output that would make sense.  Some examples could be:
X=1, Y=1, Z=2 ;
X=2, Y=1, Z=3 ......

我意识到这可能是一个非常简单的问题并且这可能非常简单。但是,根据我正在使用的 Prolog 教程

“与统一算术比较运算符不同,运算符不能用于为变量赋予值。只有在实例化每一侧的每个项时才能对其求值。”

I am new to Prolog. I need to write an integer adder that will add numbers between 0-9 to other numbers 0-9 and produce a solution 0-18. This is what I want to do:

% pseudo code
add(in1, in2, out) :-
    in1 < 10,
    in2 < 10,
    out < 18.

I would like to be able to call it like this:

To check if it is a valid addition:

?- add(1,2,3).
true.
?- add(1,2,4).
false.

With one missing variable:

?- add(X,2,3).
X = 1.
?- add(1,4,X).
X = 5.

With multiple missing variables:

?- add(X,Y,Z).
% Some output that would make sense.  Some examples could be:
X=1, Y=1, Z=2 ;
X=2, Y=1, Z=3 ......

I realize that this is probably a pretty simplistic question and it is probably very straightforward. However, according to the Prolog tutorial I am using:

"Unlike unification Arithmetic Comparison Operators operators cannot be used to give values to a variable. The can only be evaluated when every term on each side have been instantiated."

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

还如梦归 2024-09-11 07:53:17

所有现代 Prolog 系统都提供有限域约束,这些约束是可以在所有方向上使用的真实关系(与更底层的算术谓词如 is/2 和 >/2 相比)。在 SWI-Prolog 中:

:- use_module(library(clpfd)).

plus(X, Y, Z) :-
        [X,Y] ins 0..9,
        X + Y #= Z.

示例的结果:

?- plus(1,2,3).
true.

?- plus(1,2,4).
false.

?- plus(X,2,3).
X = 1.

?- plus(1,4,X).
X = 5.

?- plus(X,Y,Z).
X in 0..9,
X+Y#=Z,
Y in 0..9,
Z in 0..18.

由于谓词可以在所有方向上使用,因此将其称为“add/3”不再有意义,因为这意味着一个方向,但谓词真正描述了关系何时成立,因而更具有一般性。

All modern Prolog systems provide finite domain constraints, which are true relations that can (in contrast to more low-level arithmetic predicates like is/2 and >/2) be used in all directions. In SWI-Prolog:

:- use_module(library(clpfd)).

plus(X, Y, Z) :-
        [X,Y] ins 0..9,
        X + Y #= Z.

Results for your examples:

?- plus(1,2,3).
true.

?- plus(1,2,4).
false.

?- plus(X,2,3).
X = 1.

?- plus(1,4,X).
X = 5.

?- plus(X,Y,Z).
X in 0..9,
X+Y#=Z,
Y in 0..9,
Z in 0..18.

Since the predicate can be used in all directions, it does no longer make sense to call it "add/3", as that would imply a direction, but the predicate truly describes when the relation holds and is thus more general.

终陌 2024-09-11 07:53:17

这个怎么样?:

add(X,Y,Z) :-
        Z is X + Y,
        X < 10,
        Y < 10,
        Z < 19.

问题:这对于 add(1,1,X) 形式的查询非常有效,因为 Z<< 之前实例化。 /code> 调用,但当您请求 add(X,1,2) 时失败。您可以使用 var/1 来区分查询的类型(var/1 告诉您变量是否未实例化),但这听起来很痛苦。

What about this?:

add(X,Y,Z) :-
        Z is X + Y,
        X < 10,
        Y < 10,
        Z < 19.

Problem: this works nicely for queries of the form add(1,1,X) because Z's instantiated before the < calls, but fails when you ask add(X,1,2). You could use var/1 to distinguish the kind of query (var/1 tells you whether a variable's uninstantiated or not), but that sounds like a lot of pain.

樱娆 2024-09-11 07:53:17

解决方案:

lessThanTen(9).
lessThanTen(8).
lessThanTen(7).
lessThanTen(6).
lessThanTen(5).
lessThanTen(4).
lessThanTen(3).
lessThanTen(2).
lessThanTen(1).
lessThanTen(0).

addSimple(Add1,Add2,Sol) :-
    lessThanTen(Add1),
    lessThanTen(Add2),
    Sol is Add1+Add2.

Solution:

lessThanTen(9).
lessThanTen(8).
lessThanTen(7).
lessThanTen(6).
lessThanTen(5).
lessThanTen(4).
lessThanTen(3).
lessThanTen(2).
lessThanTen(1).
lessThanTen(0).

addSimple(Add1,Add2,Sol) :-
    lessThanTen(Add1),
    lessThanTen(Add2),
    Sol is Add1+Add2.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文