1

我是 prolog 的新手,我发现很难以递归方式思考。假设我有两个列表:list1[0,0,0,1,1,0,1,1],list2[1,0,1,0,0,0,1,1]。当 list1 或 list 2 在相应位置有 1 时,我想返回一个有 1 的列表。

merge([H1|[]],[H2|[]],[H3|[]]):- H2 = 1, H3 = 1, H1 is 1.
merge([H1|T1],[H2|T2],[H3|T3]):- merge(T1,T2,T3), H2 = 1, H3 = 1, H1 is 1.

我知道我不能以上述形式扭动,但这与我现在所能做的一样接近序言形式。递归似乎太难了!

4

3 回答 3

2

解决此类任务的一个好方法是首先描述每个列表的单个元素之间的关系,然后maplist/[2,3,4]将相同的推理扩展到列表。

例如:

either_is_one(0, 1, 1).
either_is_one(1, 0, 1).
either_is_one(1, 1, 1).

但是,如果两个列表中的任何一个在特定位置都没有“1”,情况会怎样呢现在,我假设您将其与“0”相关联:

either_is_one(0, 0, 0).

然后,很简单,我们使用将这些元素的列表maplist/4相互关联:

?- maplist(either_is_one, [0,0,0,1,1,0,1,1], [1,0,1,0,0,0,1,1], Ls).
Ls = [1, 0, 1, 1, 1, 0, 1, 1] ;
false.

请注意,这是完全纯粹的,也适用于其他方向。例如:

?- length(As, _), maplist(either_is_one, As, Bs, Cs).
As = Bs, Bs = Cs, Cs = [] ;
As = [0],
Bs = Cs, Cs = [1] ;
As = Cs, Cs = [1],
Bs = [0]
As = Bs, Bs = Cs, Cs = [1] ;
etc.
于 2015-10-30T15:11:26.107 回答
2

使用

向@mat 致敬!事实上,两次:一次给评论者,一次给实现者。

:- use_module ( library(clpb) )。

bool_bool_or(A,B,AB) :- sat(AB =:= A + B)。

示例查询使用maplist/4

?- maplist (bool_bool_or, [1,1,1], Bs, ABs)。
ABs = [1,1,1],Bs = [_X,_Y,_Z],sat(_X=:=_X),sat(_Y=:=_Y),sat(_Z=:=_Z)。

?- maplist(bool_bool_or, [1,1,1], _, ABs)。
AB = [1,1,1]。

?- maplist(bool_bool_or, [0,0,0,1,1,0,1,1], [1,0,1,0,0,0,1,1], ABs)。
AB = [1,0,1,1,1,0,1,1]。
于 2015-11-13T13:07:09.163 回答
1

如何在中使用合适的算术表达式?

:- use_module(library(clpfd)).

z_z_max(A,B,AB) :-
   [A,B,AB] ins 0..1,
   AB #= max(A,B).

示例查询maplist/3

?- maplist(z_z_max, [0,0,0,1,1,0,1,1], [1,0,1,0,0,0,1,1], Ls).
Ls = [1,0,1,1,1,0,1,1].           % succeeds deterministically

提供了一个高级接口来控制流优化,可以将回溯搜索速度提高几个数量级。用它!

于 2015-10-30T17:04:39.583 回答