繁体   English   中英

如何将二进制 0 到 1 数字列表 PROLOG

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM