除了1个由(X,Y)参数化的元素外,我想检查数组的元素是否小于0。 我尝试使用maplist,但无法保持相等。 我尝试过的另一个选择是:
verifyMatrix(X,Y,M) :-
verifyMatrix(X,Y,0,M).
verifyMatrix(,,_,[]) :-
!.
verifyMatrix(X,Y,I,[M|Ms]):-
rowVerify(0,M),
Ni is I,
verifyMatrix(X,Y,Ni,Ms).
verifyMatrix(X,Y,X,[M|Ms]):-
rowVerify(Y,M),
I is X,
verifyMatrix(-1,-1,I,Ms).
rowVerify(,,[]) :- !.
rowVerify(Ec,I,[R|Rs]):-
((R < 0) ; (Ec is I)),
Ni is I,
rowVerify(Ec,Ni,Rs).
rowVerify(Ec,R):-
rowVerify(Ec,0,R).
答案 0 :(得分:2)
使用nth1/3
(如果希望从0开始索引,则使用nth0/3
)来枚举大于ou等于零的矩阵元素:
?- Matrix =[[-1,-2,-3],[-4,-5,+6],[-7,-8,-9]], nth1(R,Matrix,Row), nth1(C,Row,Element), Element>=0.
Matrix = [[-1, -2, -3], [-4, -5, 6], [-7, -8, -9]],
R = 2,
Row = [-4, -5, 6],
C = 3,
Element = 6 ;
false.
然后,使用findall/3
验证该元素是否唯一并位于给定位置:
?- Matrix =[[-1,-2,-3],[-4,-5,+6],[-7,-8,-9]],
findall(R-C, (nth1(R,Matrix,Row),
nth1(C,Row,Element), Element>=0),[I-J]).
Matrix = [[-1, -2, -3], [-4, -5, 6], [-7, -8, -9]],
I = 2,
J = 3.
因此,我们可以将谓词less_than_zero_except/3
定义为:
less_than_zero_except(I, J, Matrix) :-
findall(R-C, (nth1(R,Matrix,Row), nth1(C,Row,Element), Element>=0), [I-J]).
此谓词可用于验证特定位置或查找该位置:
?- less_than_zero_except(2,3,[[-1,-2,-3],[-4,-5,+6],[-7,-8,-9]]).
true.
?- less_than_zero_except(I,J,[[-1,-2,-3],[-4,-5,+6],[-7,-8,-9]]).
I = 2,
J = 3.
?- less_than_zero_except(I,J,[[-1,-2,-3],[-4,-5,+6],[-7,-8,+9]]).
false.
?- less_than_zero_except(I,J,[[-1,-2,-3],[-4,-5,-6],[-7,-8,-9]]).
false.
答案 1 :(得分:1)
通过尝试同时解决所有问题,您在这里使事情变得太难了。让我们首先编写一个谓词,以验证列表(“ 行”)中的所有元素都小于零,我们稍后将担心该特殊元素。我们可以通过以下方式进行验证:
less_zero(L) :-
maplist(>(0), L).
我们还可以使用forall/2
[swi-doc]检查除给定索引以外的所有元素是否都符合条件:
less_zero_except(L, J) :-
forall((nth0(I, L, V), dif(I, J)), V < 0).
例如:
?- less_zero_except([-1, -2, 3, -5], 2).
true.
?- less_zero_except([-1, -2, 3, -5], 1).
false.
我们可以生成一个谓词,以检查行索引是否与给定的相同,并将其相应地路由到less_zero/1
或less_zero_except/2
,例如:
verify_row(Row, I, I, ColJ) :-
less_zero_except(Row, ColJ).
verify_row(Row, I, J, _) :-
dif(I, J),
less_zero(Row).
现在我们也可以在矩阵级别使用forall/2
:
verifyMatrix(RowI, ColJ, Matrix) :-
forall(nth0(I, Matrix, Row), verify_row(Row, I, RowI, ColJ)).
以上内容不是双向的:我们不能在此处传递矩阵,然后让Prolog确定非负值的坐标(假设存在该值)。但是,我们可以通过使用clpfd
library [swi-doc]来实现这一点:
:- use_module(library(clpfd)).
validate_cell(V, I, J, I, J) :-
V #>= 0.
validate_cell(V, _, _, _, _) :-
V #< 0.
现在,我们可以迭代这些值,例如:
validate_row([], _, _, _, _).
validate_row([C|T], RowI, ColJ, I, J) :-
validate_cell(C, RowI, ColJ, I, J),
J1 is J+1,
validate_row(T, RowI, ColJ, I, J1).
然后我们可以验证矩阵:
validate_matrix([], _, _, _).
validate_matrix([Row|T], RowI, ColJ, I) :-
validate_row(Row, RowI, ColJ, I, 0),
I1 is I+1,
validate_matrix(T, RowI, ColJ, I1).
然后我们可以根据validate_matrix/3
来定义validate_matrix/4
:
validate_matrix(ColI, RowJ, Matrix) :-
validate_matrix(Matrix, ColI, RowJ, 0).
我们现在可以生成满足给定约束的矩阵,并找出非负元素的坐标,并验证给定坐标对的矩阵:
?- validate_matrix(I, J, M).
M = [] ;
M = [[]] ;
M = [[], []] ;
M = [[], [], []] ;
M = [[], [], [], []] ;
M = [[], [], [], [], []] ;
M = [[], [], [], [], [], []] ;
M = [[], [], [], [], [], [], []] ;
M = [[], [], [], [], [], [], [], []] .
?- validate_matrix(I, J, [R1, R2, R3]).
R1 = R2, R2 = R3, R3 = [] ;
I = 2,
J = 0,
R1 = R2, R2 = [],
R3 = [_5416],
_5416 in 0..sup ;
I = 2,
J = 0,
R1 = R2, R2 = [],
R3 = [_5672, _5678],
_5672 in 0..sup,
_5678 in inf.. -1 ;
I = 2,
J = 0,
R1 = R2, R2 = [],
R3 = [_5916, _5922, _5928],
_5916 in 0..sup,
_5922 in inf.. -1,
_5928 in inf.. -1.
?- validate_matrix(I, J, [[1, -1], [-2, -3]]).
I = J, J = 0 ;
false.
?- validate_matrix(I, J, [[-1, -1], [-2, 3]]).
I = J, J = 1 ;
false.
?- validate_matrix(I, J, [[-1, 1], [-2, 3]]).
false.
?- validate_matrix(0, 1, [[-1, -1], [-2, 3]]).
false.
?- validate_matrix(1, 1, [[-1, -1], [-2, 3]]).
true ;
false.