【问题标题】:lists in new list in prolog without using flatten/2 [duplicate]在 prolog 中的新列表中列出而不使用 flatten/2 [重复]
【发布时间】:2021-03-03 02:32:27
【问题描述】:

我正在从列表中检索多个列表并将它们放入一个新列表中。但我想制作单个项目的新列表,而不是带有列表的列表。所以说我有列表 [[a,b],c,[d,e]] 我想得到 [a,b,c,d,e]。我该怎么办?

【问题讨论】:

  • 使用flatten/2
  • 它是给学校的,我不能用 flatten 大声笑
  • 那你应该告诉我们你尝试了什么,你卡在哪里了

标签: list prolog


【解决方案1】:
flatten(SOURCEs,TARGETs)
:-
phrase(flatten(SOURCEs),TARGETs)
.

flatten([HEAD|TAILs]) --> { is_list(HEAD) } , HEAD , flatten(TAILs) .
flatten([HEAD|TAILs]) --> { \+ is_list(HEAD) } , [HEAD] , flatten(TAILs) .
flatten([]) --> [] .
/**
?- flatten([[a,b],c,[d,e]],TARGETs) .
TARGETs = [a, b, c, d, e] ;
false.

?- 

【讨论】:

    【解决方案2】:

    使用今天从一个随机问题中截取的示例代码:假设您有如下知识库:

    step('pancakes', 1, 'mix butter and sugar in a bowl', [butter, sugar], [bowl]). 
    step('pancakes', 2, 'add eggs', [eggs], []). 
    step('pancakes', 3, 'mix flour and bakingpowder', [flour, bakingpowder], []). 
    

    你对一道菜的所有配料感兴趣。第一个想法是

    ?- Dish='pancakes', findall(X,step(Dish,_,_,X,_),I).
    Dish = pancakes,
    I = [[butter, sugar], [eggs], [flour, bakingpowder]] ;
    false.
    

    但这里的问题是配料表是嵌套的。由于不允许使用 flatten/2,因此您现在有 2 种选择:要么将结果变平,要么使用每个 step 的成分列表中的所有成分来查找菜肴。

    对于扁平化,我建议使用来自this 帖子的实现flatten2/2。由此产生的问题可能是这样的:

    ?- Dish='pancakes', findall(X,step(Dish,_,_,X,_),I), flatten2(I,J).
    

    如果您想删除 this 帖子中声明的重复项,请添加 sort/2

    如果你想使用第二种方法,你必须创建一个辅助谓词来显示所有菜肴的成分。 ingredients/3 将配料作为每道菜和步骤编号的单个元素。因此,对于每个 DishStep,可以使用不同成分的多个条目。

    ingredients(Dish,Step,Ingred):-
        step(Dish,Step,_,L,_),
        member(Ingred,L).
    
    ?- Dish='pancakes', findall(X,ingredients(Dish,_,X),I).
    Dish = pancakes,
    I = [butter, sugar, eggs, flour, bakingpowder] ;
    false.
    

    要删除重复项,请使用sort/2

    PS:我还是不知道你是否可以使用findall/3

    【讨论】:

      猜你喜欢
      • 2021-03-04
      • 2015-06-30
      • 1970-01-01
      • 1970-01-01
      • 2017-12-05
      • 1970-01-01
      • 2021-12-24
      • 1970-01-01
      相关资源
      最近更新 更多