【问题标题】:Evaluating(interpreting) a list in Prolog在 Prolog 中评估(解释)一个列表
【发布时间】:2014-11-17 18:08:03
【问题描述】:

如果我在 Prolog 中有一个由运算符和操作数组成的列表,您如何解释该列表以在适当的操作数上实现适当的运算符?

假设我们有一个列表

[100, 25, 和, 2, 乘, 800, 50, 减, 和]

应该通过以下步骤得到[1000]

// 100 and 25 are summed together, making it
[125, 2, multiply, 800, 50, subtract, sum]
// 125 and 2 are multiplied, making it 250
[250, 800, 50, subtract, sum]
// 50 is subtracted from 800, making it 750
[250, 750, sum]
// 250 is added to 750, making it 1000
[1000]

我正在尝试了解如何实现这一点的结构(特别是,如何遍历列表并做出适当的操作,而不是做实际工作的辅助谓词 [sum、multiple 等] )。哪种方案最好,我还应该考虑哪些其他因素?

场景 1 '沿途'(主谓词,有 list1(评估前)和 list2(最终列表)):

  1. 在list1中查找非整数的第一个实例
  2. 检查该“单词”是否在字典或列表中(可能使用member),如果是,则查看列表中是否有足够的前面值来完成它,如果是,则返回完成的带尾的操作,如果没有,返回false。
  3. 继续直到找不到更多单词

场景2“向前看”(主谓词,有list1(评估前)和list2(最终列表)):

  1. 查看列表中的每个元素,跟踪最长运算符所需的最大数字数(假设名为 duplicatePairs 的操作需要两组对,因此需要 4 个数字)
  2. 如果遇到运算符,请执行该操作,并返回未使用的头部(如果有)以及完成的结果和尾部。
  3. 继续直到找不到更多单词

场景 3 'Fold Left'(主谓词,有 list1(评估前)和 list2(最终列表)):

  • 使用一些 map 函数(可能是 maplist/3),以某种方式递归地左折叠 list1 直到获得最终列表(从函数式编程 [Haskell] 中借用这个想法)

【问题讨论】:

标签: prolog


【解决方案1】:

我能想到的更简单的代码:

eval([A1,A2,sum|Rest], Result) :- Sum is A1+A2, !, eval([Sum|Rest], Result).
eval(Result, Result).

等等……测试:

?- eval([1,2,sum,4,sum],R).
R = [7].

当然,'catchall' eval(Result, Result). 必须是最后一条规则...

【讨论】:

  • 使用堆栈的唯一原因是输入已经不是列表。对于这个例子,你的解决方案确实更好。
  • Hrm,当列表与正确条目不匹配时,这会出现问题。例如eval([1,2,3,4,sum,6],R). 将返回R = [1,2,3,4,sum,6] 而不是预期的R = [1,2,7,6]
  • @chrisFrisina:在包罗万象之前添加“跳过值规则”很容易:eval([H|T], [H|R]) :- eval(T, R).
猜你喜欢
  • 1970-01-01
  • 2013-04-14
  • 1970-01-01
  • 2015-01-02
  • 1970-01-01
  • 2016-02-26
  • 2013-10-12
  • 1970-01-01
相关资源
最近更新 更多