[英]Are algebraic predicates supported in Mercury?
I'm very new to Mercury and logic programming in general. 我对Mercury和逻辑编程很新。 I haven't found a numeric example like this in the docs or samples...
我没有在文档或示例中找到这样的数字示例......
Take the example predicate: 以示例谓词为例:
:- pred diffThirtyFour(float, float).
:- mode diffThirtyFour(in, out) is det.
diffThirtyFour(A,B) :-
( B = A + 34.0 ).
With this, A must be ground, and B is free. 有了这个,A必须被磨削,B是自由的。 What if I want A to be free and B to be ground (eg, adding
mode diffThirtyFour(out,in) is det.
). 如果我希望A自由并且B要被接地(例如,添加
mode diffThirtyFour(out,in) is det.
) mode diffThirtyFour(out,in) is det.
? Can this sort of algebra be performed at compile time? 这种代数可以在编译时执行吗? I could easily define another predicate, but that doesn't seem very logical...
我可以很容易地定义另一个谓词,但这似乎不合逻辑......
Update 更新
So, something like this kind of works: 所以,像这样的作品:
:- pred diffThirtyFour(float, float).
:- mode diffThirtyFour(in, out) is semidet.
:- mode diffThirtyFour(out, in) is semidet.
diffThirtyFour(A,B) :-
( B = A + 34.0, A = B - 34.0 ).
A little wary of the semidet
, and the redundancy of the second goal. 对
semidet
有点警惕,以及第二个目标的冗余。 Is this the only way of doing it? 这是唯一的方法吗?
Update 2 更新2
This might be the answer...it issues a warning at compile time about the disjunct never having any solutions. 这可能就是答案......它在编译时发出关于从不具有任何解决方案的析取的警告。 A correct warning, but perhaps unnecessary code-smell?
一个正确的警告,但也许是不必要的代码味道? This does what I need, but if there are better solutions out there, feel free to post them...
这就是我需要的,但如果有更好的解决方案,请随意发布它们......
:- pred diffThirtyFour(float, float).
:- mode diffThirtyFour(in, out) is det.
:- mode diffThirtyFour(out, in) is det.
diffThirtyFour(A,B) :-
( A = B - 34.0,
B = A + 34.0
;
error("The impossible happened...")
).
Just discovered the ability to enter different clauses for different modes . 刚刚发现了为不同模式输入不同子句的能力。 This isn't quite an algebraic solver (which I wouldn't have expected anyway), but offers the precise organizational structure I was looking for:
这不是一个代数求解器(我不会想到它),但提供了我正在寻找的精确组织结构:
:- pred diffThirtyFour(float, float).
:- mode diffThirtyFour(in, out) is det.
:- mode diffThirtyFour(out, in) is det.
:- pragma promise_pure(diffThirtyFour/2).
diffThirtyFour(A::out,B::in) :- A = B - 34.0.
diffThirtyFour(A::in, B::out) :- B = A + 34.0.
As described in the link, the promise_pure
pragma is required because this feature can be used to break semantic consistency. 如链接中所述,
promise_pure
编译指示是必需的,因为此功能可用于打破语义一致性。 It would also suffice to use the promise_equivalent_clauses
pragma, which promises logical consistency without purity. 使用
promise_equivalent_clauses
pragma也足够了,它提供了逻辑一致性而没有纯度。 It is still possible to declare clauses with inconsistent semantics with the impure
keyword in the pred declaration. 它仍然是有可能与不一致的语义声明条款
impure
在预解码申报关键字。
Interestingly, addition and subtraction in the standard int
module are inversible, but not in the float
module. 有趣的是,标准
int
模块中的加法和减法是不可逆的,但在float
模块中则不然。 Perhaps the choice was made because of possible errors in floating point arithmetic.... 也许选择是因为浮点算法可能存在错误....
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.