如何在prolog中对列表元素进行分组

时间:2015-12-03 16:11:41

标签: list prolog

我正在尝试对元素列表进行分组。在这种情况下,我有一些语法符号,我想在同一组中分组元素。如果列表中有一些水果,那么所有水果都合并在一个列表中。就像那样没有鸟,那么鸟类列表就是空的。我尝试使用append/3匹配但不起作用。

语法规则:

animals-->[cat]|[dog]|[cow].
birds-->[parrot],[peacock]|[penquin].
fruits-->[apple]|[orange]|[banana].

目标将来临

?- grouped([[apple],[dog],[cat],[banana],[cow],[car]],Animals,Birds,Fruits,Rest).
Animals=[dog,cat,cow],
Birds=[],
Fruits=[apple,banana],
Rest[car].

2 个答案:

答案 0 :(得分:1)

您可以先创建某种数据库来解决这个问题:

animals(cat).
animals(dog).
animals(cow).

birds(parrot).
birds(peacock).
birds(penquin).

fruits(apple).
fruits(orange).
fruits(banana).

接下来,您将创建某种过滤器:

grouped([],[],[],[],[]).
grouped([[H]|T],[H|A],B,F,R) :-
    animals(H),
    !,
    grouped(T,A,B,F,R).
grouped([[H]|T],A,[H|B],F,R) :-
    birds(H),
    !,
    grouped(T,A,B,F,R).
grouped([[H]|T],A,B,[H|F],R) :-
    fruits(H),
    !,
    grouped(T,A,B,F,R).
grouped([[H]|T],A,B,F,[H|R]) :-
    !,
    grouped(T,A,B,F,R).

请注意,此谓词仅以一种方式工作。您可以通过删除剪切并更改最后一个子句来将其更改为多向工作:

grouped([],[],[],[],[]).
grouped([[H]|T],[H|A],B,F,R) :-
    animals(H),
    grouped(T,A,B,F,R).
grouped([[H]|T],A,[H|B],F,R) :-
    birds(H),
    grouped(T,A,B,F,R).
grouped([[H]|T],A,B,[H|F],R) :-
    fruits(H),
    grouped(T,A,B,F,R).
grouped([[H]|T],A,B,F,[H|R]) :-
    \+ animals(H),
    \+ birds(H),
    \+ fruits(H),
    grouped(T,A,B,F,R).

现在有可能会发生冲突(parrot例如birdanimal

但在我看来,这个问题几乎没有什么奇怪之处:<​​/ p>

  • 为什么要使用列表清单? [[apple],[dog],[cat],[banana],[cow],[car]]代替[apple,dog,cat,banana,cow,car]
  • 使用参数作为过滤器输入/输出(类别)的设计相当奇怪。如果要定义新类别,则会导致重写整个谓词。肯定有更好的方法来做到这一点。

答案 1 :(得分:1)

我与其他评论员分享了一些关于你的代表性的困惑。另外,我认为这个条款

birds-->[parrot],[peacock]|[penquin].

应该是

birds-->[parrot]|[peacock]|[penquin].

给出语义,但在语法上有意义处理DCG的一般性 - 也就是说,不假设每个DCG子句仅匹配一个文字,如在您的示例中。然后,我的解决方案

:- meta_predicate capture(//,+,-,-).

capture(NT, L0, Capture, R) :-
    phrase(NT, L0, L1),
    append(C0, L1, L0), % recover tokens matched by NT
    capture(NT, L1, C1, R),
    !, append(C0, C1, Capture).
capture(NT, [Skip|L0], Capture, [Skip|R]) :-
    !, capture(NT, L0, Capture, R).
capture(_, L, [], L).

grouped(L0,Animals,Birds,Fruits,Rest) :-
    capture(animals,L0,Animals,L1),
    capture(birds,L1,Birds,L2),
    capture(fruits,L2,Fruits,Rest).

产量

?- grouped([apple,dog,cat,banana,cow,car],Animals,Birds,Fruits,Rest).
Animals = [dog, cat, cow],
Birds = [],
Fruits = [apple, banana],
Rest = [car].

对于美学观点,grouped/4并不太喜欢我......但它确实有它的作用