Prolog中的列表练习列表

Posted

技术标签:

【中文标题】Prolog中的列表练习列表【英文标题】:Lists of list exercsie in Prolog 【发布时间】:2020-12-16 10:26:40 【问题描述】:

我有这个练习:

编写一个成功的确定性 Prolog 程序test( +List, ?Integer ) 当且仅当IntegerList 中两个不同元素的方式数 可以选择第一个元素比第一个元素多一个 第二个。

示例查询:

?- test( [ [], [0], [0,0], [0,1], [1,0] ], N ).
N = 5

但我无法弄清楚我将如何做到这一点。希望有人可以帮忙

【问题讨论】:

【参考方案1】:

这是一个想法,同时完全消除了对性能的任何想法:

子目标:

    使用member/2选择第一个元素(列表);和 使用member/2 选择第二个元素(列表);和 使用length/2计算第一个选定元素/列表的长度;和 使用length/2计算第二个选定元素/列表的长度;和 使用</2 确保这两个长度符合您的长度限制 如果不是这种情况会失败,回溯备份此列表 但如果成功了,这个目标就成功了。

使用bagof/3收集子目标的所有解决方案

【讨论】:

如何使用 memeber 选择元素? @fewfrg 查看手册:member/2 并在命令行或SWISH 中尝试。没有其他学习方法。【参考方案2】:

Prolog 可能......当你刚开始的时候很难理解。

首先,尝试编写一个谓词,该谓词将在回溯时返回列表的整个笛卡尔连接,如下所示:

test( List, result( A, B ) ) :-
  member( A, List ),
  member( B, List )
  .

用测试数据运行它:test( [ [], [0], [0,0], [0,1], [1,0] ], R ). 将连续返回 25 个结果(样本列表中有 5 个项目,所以 5 × 5 给我们 25 个结果,对吗?):

R = result( []    , []     )
R = result( []    , [0]    )
R = result( []    , [0, 0] )
R = result( []    , [0, 1] )
R = result( []    , [1, 0] )
R = result( [0]   , []     )
R = result( [0]   , [0]    )
R = result( [0]   , [0, 0] )
R = result( [0]   , [0, 1] )
R = result( [0]   , [1, 0] )
R = result( [0, 0], []     )
R = result( [0, 0], [0]    )
R = result( [0, 0], [0, 0] )
R = result( [0, 0], [0, 1] )
R = result( [0, 0], [1, 0] )
R = result( [0, 1], []     )
R = result( [0, 1], [0]    )
R = result( [0, 1], [0, 0] )
R = result( [0, 1], [0, 1] )
R = result( [0, 1], [1, 0] )
R = result( [1, 0], []     )
R = result( [1, 0], [0]    )
R = result( [1, 0], [0, 0] )
R = result( [1, 0], [0, 1] )
R = result( [1, 0], [1, 0] )

一旦你有了它,就很容易计算两个子列表之间的长度差异:

test( List, result( A, B ) ) :-
  member( A, List ),
  member( B, List ),
  length( A, L1   ),
  length( B, L2   ),
  Delta is L1 - L2
  .

而且更容易过滤:

test( List, result( A, B ) ) :-
  member( A, List ),
  member( B, List ),
  length( A, L1   ),
  length( B, L2   ),
  Delta is L1 - L2,
  Delta = 1
  .

【讨论】:

以上是关于Prolog中的列表练习列表的主要内容,如果未能解决你的问题,请参考以下文章

Prolog 中的子列表谓词

Prolog中的展平列表[重复]

Prolog 列表中的两颗星

列表中的唯一元素(Prolog)

如何将 csv 文件读入 SWI prolog 中的列表列表,其中内部列表代表 CSV 的每一行?

如何通过Prolog将字符串连接到列表中的多个元素?