我仍然是prolog的新手,并且我试图解决为什么数学约束似乎与逻辑约束无关的方式。
似乎有足够的信息来解决这个问题:
f(A, B) :- A = (B xor 2).
但是,当我尝试f(C, 3)
时,我会回来C = 3 xor 2.
,这不是很有用。更不实用的是,如果输入被反转,它根本无法找到解决方案。使用is
代替=
会使示例输入返回正确答案,但反过来甚至拒绝尝试任何内容。
从我之前的实验中,似乎我可以编写一个功能,使用二进制文件无故障地执行此操作,实际上它会双向进行。是什么让数学与众不同?
作为参考,我第一次尝试解决我的问题是这样的:
f(Input, Output) :- A is Input xor (Input >> 11), B is A xor ((A >> 7) /\ 2636928640), C is B xor ((B << 15) /\ 4022730752), Output is C xor (C >> 18).
这从输入到输出都可以正常工作,但不是相反。如果我将is
切换为=
,它会生成一个长逻辑序列,其值已替换但无法找到数值解。
我正在使用内置xor
的swi-prolog,但它可以很容易地定义。我希望能够使用prolog在两个方向上完成这个功能,并且真的不希望必须手动实现逻辑行为。关于如何重新解决这个问题的任何建议都是值得欢迎的。
答案 0 :(得分:5)
Pure Prolog不应该处理数学。驱动Prolog的基本算法 - 统一并在失败时回溯 - 不提算术算子。大多数Prolog实现将算术作为一个丑陋的黑客添加到他们的字节码中。
原因是算术函数的行为与仿函数不同。它们不能以同样的方式统一。并非每个函数都能保证适用于地面和非地面参数的每个组合。例如,将X提升到Y的幂的算法与找到X的Yth根不对称。如果所有算术函数都是对称的,加密和加密将不起作用!
那就是说,这里有关于Prolog运营商的缺失事实:
首先,'='在Prolog中不“等于”,但是“统一”。 X = Y op Z
作为运算符的目标op
将X
与仿函数'op'(Y,Z)
统一起来。它与算术相等或赋值无关。
其次,is
,丑陋的数学黑客,并不能保证是可逆的。目标X is Expr
,其中Expr
是算术表达式,首先计算表达式,然后尝试将其分配给X
。它并不总是适用于数字和变量的每个组合 - 请检查您的Prolog库文档。
总结:
答案 1 :(得分:0)
如果要比较表达式的计算结果,则应使用运算符(=:=)/ 2,或者在检查运算符(= / =)/ 2时的分离度。
运算符也适用于按位运算,因为按位运算适用于integeres,而整数是数字。运营商是ISO核心标准的一部分。对于以下条款:
f(A, B) :- A =:= (B xor 2).
我在SWI-Prolog,Jekejeke Prolog等进行了以下运行..:
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.31)
Copyright (c) 1990-2016 University of Amsterdam, VU Amsterdam
?- f(100, 102).
true.
?- f(102, 100).
true.
?- f(100, 101).
false.
如果您想要一种更具说明性的处理位的方法,可以使用集成到Prolog中的SAT求解器。一个好的SAT求解器也应该支持有限或无限的位向量,但我现在不能告诉你这里有什么可用的限制。
请在此处查看此问题: Prolog SAT Solver