prolog检查清单

时间:2012-01-08 00:42:31

标签: list prolog

我有以下代码:

check([],[]).
check([X], [Y]) :-
    X > 0,
    Y is 1.
check([X], [Y]) :-
    X =:= 0,
    Y is 0.
check([L1|Tail], [L2|Tail2]) :-
    L1 > 0,
    L2 is 1,
    check(Tail,Tail2).
check([L1|Tail], [L2|Tail2]) :-
    L1 =:= 0,
    L2 is 0,
    check(Tail,Tail2).

谓词检查会创建一个表格,将所有大于0的项目替换为1。 此谓词适用于此L = [3,4,5,6,0]之类的简单列表,并生成列表L1 = [1,1,1,1,0]

我需要进行谓词检查以接受列表作为项目的列表。

例如:L = [[2, 3, 4], [4, 0, 6], [5, 6, 3]]。列表中的项目与项目列表的项目一样多。这意味着如果列表包含3个项目列表,则每个项目列表应包含3个项目。

2 个答案:

答案 0 :(得分:6)

对于列表中每个项目的相同关系,通常最好描述单个元素的关系,然后使用maplist / 3:

check(0, 0).
check(N, 1) :- N > 0.

示例查询:

?- maplist(check, [3,4,5,6,0], Ls).
Ls = [1, 1, 1, 1, 0] ;
false.

现在,嵌套列表的情况转换为嵌套的maplist / 3:

?- maplist(maplist(check), [[2, 3, 4], [4, 0, 6], [5, 6, 3]], Ls).
Ls = [[1, 1, 1], [1, 0, 1], [1, 1, 1]] ;
false.

答案 1 :(得分:0)

首先,不需要你的第二和第三个条款,它们只是产生重复的解决方案,这是一个更好的check/2谓词:

check([],[]).
check([L1|Tail], [L2|Tail2]) :-
    L1 > 0,
    L2 is 1,
    check(Tail,Tail2).
check([L1|Tail], [L2|Tail2]) :-
    L1 =:= 0,
    L2 is 0,
    check(Tail,Tail2).

然后,您可以直接在子句的开头指定L2值,而不是使用is/2为L2分配值,而不是:

check([],[]).
check([L1|Tail], [1|Tail2]) :-
    L1 > 0,
    check(Tail,Tail2).
check([L1|Tail], [0|Tail2]) :-
    L1 =:= 0,
    check(Tail,Tail2).

然后,您可以再次直接指定第二个子句头部的值,而不是使用=:=/2

check([],[]).
check([L1|Tail], [1|Tail2]) :-
    L1 > 0,
    check(Tail,Tail2).
check([0|Tail], [0|Tail2]) :-
    check(Tail,Tail2).

现在,您的check/2谓词看起来已经好多了!

让我们添加一个子句来处理列表嵌套:

check([],[]).
check([L1|Tail], [L2|Tail2]) :-
    L1 = [_|_],
    check(L1, L2),
    check(Tail, Tail2).
check([L1|Tail], [1|Tail2]) :-
    \+ L1 = [_|_],
    L1 > 0,
    check(Tail,Tail2).
check([0|Tail], [0|Tail2]) :-
    check(Tail,Tail2).

正如您所看到的,我们还需要添加一个测试,即L1不是我们前一个子句中的列表,因此列表不会以这种方式生成并产生奇怪的解决方案。

希望它有所帮助。