[英]How can I convert a list of binary 0 to 1 numbers PROLOG
如何将 Prolog 中的二进制 0 到 1 数字列表转换为以下结果:
?- cryptoA( [1,1,0,1,0,0,0,1], L2).
L2 = [0,0,1,0,1,1,1,0]
很简单,就是
cryptoA([1,1,0,1,0,0,0,1], [0,0,1,0,1,1,1,0]).
但当然它太具体了。 可能应该添加更多案例,例如
cryptoA([1,1,0,1,0,0,0], [0,0,1,0,1,1,1] ).
cryptoA([1,1,0,1,0,0], [0,0,1,0,1,1] ).
cryptoA([1,1,0,1,0], [0,0,1,0,1] ).
.....
cryptoA([1,1,0], [0,0,1] ).
.....
cryptoA([ 1 ], [ 0 ] ).
cryptoA([ 0], [ 1] ).
正确的? 但是多少具体案例就足够了? 会不会,够了吗?
为了处理无限数量的结构化案例,我们可以使用递归编写结构化代码。 最后两个子句似乎很少,为什么要将它们包含在这样的列表中?
cryptoB( 1 , 0 ).
cryptoB( , ).
% fill the blanks
什么是递归案例?
cryptoA( [A | B], [C | D] ) :-
cryptoB( , ), % fill the blanks
cryptoA( B, D).
基本情况是什么?
cryptoA( [ ], [ ] ). % fill the blanks
完成最后一个子句的定义特别容易。
我们可以通过使用给定示例的相同方式来获得这种“递归”解决方案,对其进行简化,然后对其进行泛化。
让我们来看看。 往另一个方向走,就是
cryptoA( [1,1,0,1,0,0,0], [0,0,1,0,1,1,1] ). % which means this must hold:
cryptoA( [ 1,0,1,0,0,0], [ 0,1,0,1,1,1] ). % and also this must hold:
cryptoA( [1 ], [0 ] ). % which is to say,
cryptoB( 1 , 0 ). % this must hold
所以,让我们写下来吧!
cryptoA( [1,1,0,1,0,0,0], [0,0,1,0,1,1,1] ) :-
cryptoA([ 1,0,1,0,0,0], [ 0,1,0,1,1,1] ),
cryptoB( 1 , 0 ).
%% or, equivalently,
cryptoA( X, Y ) :-
X = [1,1,0,1,0,0,0], Y = [0,0,1,0,1,1,1], % specific case
X = [A | B ], Y = [C | D ], % general structure
cryptoA( B, D ), % recursive step
cryptoB( A , C ). % single-step processing
现在,我们可以通过简单地删除特定案例定义来进行概括。 当然,相同的方案必须完全适用于任何其他特定数据!
当然不是每个列表都可以匹配到一个非空列表[_ | _]
[_ | _]
模式,只是因为并非所有列表都是非空的。 一些列表实际上是空的, []
,这产生了基本情况。
最后,递归步骤最好最后指定,在所谓的尾position 中,因为整个谓词是尾递归的。 这种方式效率更高。
使用 maplist 可以轻松完成列表中的一一对应:
cryptoA(A,B) :- maplist(\X^Y^(X=1,Y=0;X=0,Y=1),A,B).
您应该安装 library(lambda) 以使其正常工作,例如在 SWI-Prolog 中
?- pack_install(lambda).
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.