在Prolog中掩饰

bgi*_*ers 3 list prolog masking clpfd

我最近一直试图找出Prolog并且一直在搞乱Prolog中的列表清单.我试图在p Prolog中创建一种掩模.我有一个谓词,它决定了Prolog中两个列表列表(L1和L2可以说)之间的区别,并将它们保存为列表列表(让我们说R).我有另一个谓词,只是说明差异是否等于零(noDifference).我希望有两个结果列表(M1和M2)基于L1和L2与R相比.例如我想将L1和L2的所有值与R进行比较,如果负值在某个位置然后,在L1的相同位置的值被保存到M1中.如果正值位于R的位置,那么L2的相同位置的值将被保存到M2中,如果这是有意义的话.在所有这些之前,我检查我的noDifference函数,看看差异是否为0,如果是这样,M1和M2的列表列表的所有值都将为0.

这是我到目前为止(我不确定我是否正确启动)

masker(L1,L2,R,M1,M2):- noDifference(R1), M1=R, M2=R1;
Run Code Online (Sandbox Code Playgroud)

而对于其余部分,这里的一些示例值应该在引擎盖下

L1=[[1,5,3,8],[1,5,3,8]]
L2=[[5,4,7,4],[5,4,7,4]]
R=[[4,-1,4,-4],[4,-1,4,-4]]
M1=[[0,5,0,8],[0,5,0,8]]Neg values of L1 at R are stored rest are 0)
M2=[[5,0,7,0],[5,0,7,0]](Pos values of L2 at R are stored rest are 0)
Run Code Online (Sandbox Code Playgroud)

如果我到目前为止所做的任何见解是正确的,如何正确地制定子目标/我应该去的地方将是非常棒的!

用ex谓词编辑

?- masker([[1,5,3,8],[1,5,3,8]],
          [[5,4,7,4],[5,4,7,4]],
          [[4,-1,4,-4],[4,-1,4,-4]], M1, M2).
M1=[[0,5,0,8],[0,5,0,8]].
M2=[[5,0,7,0],[5,0,7,0]].
Run Code Online (Sandbox Code Playgroud)

tas*_*tas 5

想想你的谓词应该描述什么.它是五个列表列表之间的关系,根据您提供的示例,它们具有相同的长度.这表明基本情况有五个空列表.否则,所有五个列表的头部都是列表本身,它们彼此具有特定的关系,我们称之为lists_mask_mlists/5.当然,对于尾部也应如此,这可以通过递归目标来实现.所以你的谓词masker/5可能看起来像这样:

masker([],[],[],[],[]).
masker([X|Xs],[Y|Ys],[M|Ms],[R1|R1s],[R2|R2s]) :-
   lists_mask_mlists(X,Y,M,R1,R2),
   masker(Xs,Ys,Ms,R1s,R2s).
Run Code Online (Sandbox Code Playgroud)

实际的屏蔽关系也有一个带有五个空列表的基本情况.否则还有两个案例:

1)当前屏蔽元素(第三个列表的头部)是否定的:第一个列表的头部是第四个列表的头部,第五个列表的头部是 0

2)当前屏蔽元素为正:第二个列表的头部是第五个列表的头部,第四个列表的头部是 0

你可以像这样表达:

lists_mask_mlists([],[],[],[],[]).
lists_mask_mlists([X|Xs],[_Y|Ys],[M|Ms],[X|R1s],[0|R2s]) :-   % 1)
   M < 0,
   lists_mask_mlists(Xs,Ys,Ms,R1s,R2s).
lists_mask_mlists([_X|Xs],[Y|Ys],[M|Ms],[0|R1s],[Y|R2s]) :-   % 2)
   M >= 0,
   lists_mask_mlists(Xs,Ys,Ms,R1s,R2s).
Run Code Online (Sandbox Code Playgroud)

使用此谓词,您的示例查询将产生所需的结果:

   ?- masker([[1,5,3,8],[1,5,3,8]],[[5,4,7,4],[5,4,7,4]],[[4,-1,4,-4],[4,-1,4,-4]],M1,M2).
M1 = [[0,5,0,8],[0,5,0,8]],
M2 = [[5,0,7,0],[5,0,7,0]] ? ;
no
Run Code Online (Sandbox Code Playgroud)

然而需要注意的是,由于<>=这只作品,如果第三列表是可变的自由.用4变量替换第三个参数中的第一个会产生实例化错误:

   ?- masker([[1,5,3,8],[1,5,3,8]],[[5,4,7,4],[5,4,7,4]],[[X,-1,4,-4],[4,-1,4,-4]],M1,M2).
     ERROR at  clause 2 of user:masked/5 !!
     INSTANTIATION ERROR- =:=/2: expected bound value
Run Code Online (Sandbox Code Playgroud)

如果您打算将谓词与第三个不可变的参数一起使用,您可能会考虑使用clpfd.包括该行

:-use_module(library(clpfd)).
Run Code Online (Sandbox Code Playgroud)

在你的源文件和alter lists_mask_mlists/5中如下:

lists_mask_mlists([],[],[],[],[]).
lists_mask_mlists([X|Xs],[_Y|Ys],[M|Ms],[X|R1s],[0|R2s]) :-
   M #< 0,                                                    % <- here
   lists_mask_mlists(Xs,Ys,Ms,R1s,R2s).
lists_mask_mlists([_X|Xs],[Y|Ys],[M|Ms],[0|R1s],[Y|R2s]) :-
   M #>= 0,                                                   % <- here
   lists_mask_mlists(Xs,Ys,Ms,R1s,R2s).
Run Code Online (Sandbox Code Playgroud)

现在第二个查询也有效:

   ?- masker([[1,5,3,8],[1,5,3,8]],[[5,4,7,4],[5,4,7,4]],[[X,-1,4,-4],[4,-1,4,-4]],M1,M2).
M1 = [[1,5,0,8],[0,5,0,8]],
M2 = [[0,0,7,0],[5,0,7,0]],
X in inf.. -1 ? ;
M1 = [[0,5,0,8],[0,5,0,8]],
M2 = [[5,0,7,0],[5,0,7,0]],
X in 0..sup ? ;
no
Run Code Online (Sandbox Code Playgroud)