在描述状态变量时,Mercury 参考手册说:“ !X可能不会在函数应用程序中作为参数出现,因为考虑到状态变量和函数的通常解释,这是没有道理的”(第14页)。 我想更好地理解这种推理:关于状态变量和函数的什么使组合变得毫无意义?

我的部分困惑来自下面的代码,在这里我可以使用状态变量的!.X, !:X形式,但不能使用!X形式。 如果可以使用前者,为什么不使用后者呢?

此代码编译并按预期运行:

% Choose values, A and B, from the list of values, subject to certain restrictions
:- pred pick_a_b(int, int, list(int), list(int)).
:- mode pick_a_b(out, out, in,        out) is nondet.
pick_a_b(A, B, !Values) :-
    A = pick(!.Values, !:Values),
    B = pick(!.Values, !:Values),
    A \= 3, A > 2, B > 2, B \= 4.

% Choose any item from the input list; pass all the un-chosen items back to the caller.
:- func pick(list(int), list(int)) = int.
:- mode pick(in,        out)       = out is nondet.
pick([X | Xs], Xs)      = X.
pick([X | Xs], [X | Zs]) = pick(Xs, Zs).

main(!IO) :-
    if 
        Values = [1, 2, 3, 4, 5],
        pick_a_b(A, B, Values, _)
    then
        io.format("A = %i\n", [i(A)], !IO),
        io.format("B = %i\n", [i(B)], !IO)
    else
        io.format("Something went wrong\n", [], !IO).

但是更改pick_a_b的前两行pick_a_b导致编译错误。

pick_a_b(A, B, !Values) :-
    A = pick(!Values),
    B = pick(!Values),
    A \= 3, A > 2, B > 2, B \= 4.

===============>>#1 票数:3 已采纳

您的“功能”选择有一个奇怪的模式,(进,出)=出。 这是非常不寻常的,这就是!:Values语法在第一个示例中起作用的原因。 通常情况下,函数不会具有(in,in,...,in)= out模式。

参考手册正确地说,!X语法在函数调用中没有意义,我也相信您对!:Values的使用和函数的模式也没有意义。 是的,您的代码是合法的,编译器接受并可以编译它,但是我不知道为什么有人会在这里使用函数而不是谓词。 这样做很可能使将来的人们混淆您的代码阅读。

===============>>#2 票数:1

状态变量的通常解释是,一对变量中的一个是输入,另一个是输出,而函数的通常解释是,所有参数都是输入,而返回值是输出。 参考手册指出,根据这些解释,使用状态变量作为参数是没有意义的。

推理可以概括为:仅仅因为您可以允许程序员写点东西,并不意味着您应该这样做

  ask by Evan translate from so

未解决问题?本站智能推荐:

1回复

使用子目录中的子模块构建Mercury程序

我有一个从其他文件导入模块的汞程序。 我希望能够将此文件放在子目录中。 我怎样才能做到这一点? 我正在使用mmc -E --make --trace deep filename来制作程序。 我看过构建多模块Mercury程序,但它似乎没有处理子目录问题,尽管我可能错了。
3回复

Mercury中的ADT属性

我徘徊为什么Mercury(10.04)不能推断下一个片段的确定性: 它抱怨说: 但是io.res只有io.ok/1和io.error/1 。 下一段代码汇编得很好: 更新#1 :它甚至可以决定:
1回复

如何使用Mercury编程语言进行编译以进行调试?

在Ubuntu 14.04上使用Mercury 14.01.1。 从源代码安装了四个等级,包括调试等级。 尝试了以下每个方法,但均未成功(缺少文件/目录) $ mmc-调试文件名 $ mmc --decl-debug文件名 问:我应该输入什么呢?
3回复

水星中的“:=”和“ =>”

我最近在Mercury中遇到了以下代码示例: 作为一名Prolog程序员,我想知道:这里使用的普通统一=和:=或=>有什么区别? 在《 Mercury参考》中 ,这些运算符具有不同的优先级,但没有解释差异。
1回复

水星中lambda和谓词的匹配确定性

在Mercury中,我是否可以将Lambda声明为与包含Lambda的谓词模式具有相同的确定性? 这就是我想要做的。 我写了一个折叠函数(在下面),该函数可用于array2d类型。 fold为数组中的每个元素调用调用者提供的谓词。 只要它仅接受det谓词作为参数,它就可以正常工作。
3回复

汞中无限制的变量名声明

我想在Mercury中声明一个数据类型,该数据类型可以具有可变数量的值和名称。 例如 : 有三个变量/值。 我想要类似的东西: 变量的数量不受限制或固定。 因此,我可以使用myplayer声明值/变量,例如v1, v2, v3 and v4. 第二次,我可以用它来
1回复

Mercury语言中类型类的多态实例

考虑下一个声明: 水星(10.04)产生: 即使没有功能依赖性,也不允许使用类型变量声明实例。 我是否缺少某些内容,或者Mercury不允许以地面实例结尾的实例? 有什么方法可以声明多态类型的实例,该实例是任何类型的包装器(无约束)吗? 也许存在像all_types(T
3回复

支持Mercury的IDE或编辑器[关闭]

除了emacs之外,是否还有支持Mercury的IDE或编辑器?
2回复

Det中的汞含量

在Mercury中,假设您处于det谓词中,并且想要按以下方式调用nondet谓词。 如果没有解决方案,则需要Result = [] ; 如果有一个或多个, Result = [FirstSolution]想要第一个,例如Result = [FirstSolution] 。 nondet谓
3回复

Mercury:如何声明高阶数据类型的确定性?

当我编译下面的Mercury代码时,我从编译器中得到这个错误: 我认为编译器所说的是“当你声明类型test_case ,你没有指定一个确定性,所以我认为你的意思是det 。但是你传入了一个semidet lambda。” 我的问题: 声明类型的确定性的语法是什么? 我尝