简体   繁体   English

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

[英]How can I convert a list of binary 0 to 1 numbers PROLOG

How can I convert a list of binary 0 to 1 numbers in Prolog to give me the following results:如何将 Prolog 中的二进制 0 到 1 数字列表转换为以下结果:

?- cryptoA( [1,1,0,1,0,0,0,1], L2).
L2 = [0,0,1,0,1,1,1,0]

Simple, it's很简单,就是

cryptoA([1,1,0,1,0,0,0,1], [0,0,1,0,1,1,1,0]).

But of course it's too specific.但当然它太具体了。 More cases should probably be added, like可能应该添加更多案例,例如

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]          ).

right?正确的? But how many concrete cases is enough?但是多少具体案例就足够了? Is it ever going to be, enough?会不会,够了吗?

To deal with the infinite number of structured cases, we can write down a structured code, using recursion.为了处理无限数量的结构化案例,我们可以使用递归编写结构化代码。 The last two clauses seem minimal, and why should they be enclosed in lists like that?最后两个子句似乎很少,为什么要将它们包含在这样的列表中?

cryptoB(   1 ,                0             ).
cryptoB(     ,                              ).         
                               % fill the blanks

What is the recursive case?什么是递归案例?

cryptoA( [A | B], [C | D] ) :-
  cryptoB(  ,  ),              % fill the blanks
  cryptoA( B, D).

What is the base case?基本情况是什么?

cryptoA( [    ], [    ] ).     % fill the blanks

Finishing the last clause's definition is particularly easy.完成最后一个子句的定义特别容易。


We could arrive at this "recursive" solution by the same way of playing with the given example, simplifying it, and then generalizing it.我们可以通过使用给定示例的相同方式来获得这种“递归”解决方案,对其进行简化,然后对其进行泛化

Let's see.让我们来看看。 Going in another direction, it is往另一个方向走,就是

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

So, let's write this down!所以,让我们写下来吧!

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

and now, we can generalize by simply removing that specific case definition.现在,我们可以通过简单地删除特定案例定义来进行概括。 Surely the same scheme must hold with any other specific data at all!当然,相同的方案必须完全适用于任何其他特定数据!

Of course not every list can be matched up with a non-empty list [_ | _]当然不是每个列表都可以匹配到一个非空列表[_ | _] [_ | _] pattern, just because not all lists are non-empty. [_ | _]模式,只是因为并非所有列表都是非空的。 Some lists are actually empty, [] , and this gives rise to the base case.一些列表实际上是空的, [] ,这产生了基本情况。

Lastly, the recursive step is preferred to be specified last, in so called tail position, for the overall predicate to be tail recursive.最后,递归步骤最好最后指定,在所谓的position 中,因为整个谓词是递归的。 It is much more efficient this way.这种方式效率更高。

one to one correspondence in lists is easily done with maplist:使用 maplist 可以轻松完成列表中的一一对应:

cryptoA(A,B) :- maplist(\X^Y^(X=1,Y=0;X=0,Y=1),A,B).

You should install library(lambda) for this to work, in SWI-Prolog for instance您应该安装 library(lambda) 以使其正常工作,例如在 SWI-Prolog 中

?- pack_install(lambda).

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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