【问题标题】:How to a list of English arithmetical expressions and yield the numerical result如何列出英语算术表达式并产生数值结果
【发布时间】:2013-02-08 11:19:16
【问题描述】:

我是 Prolog 的新手,我遇到了一个查询计算器([三,时间,二],总计)的问题。并得出答案 Total=6。

跟进我之前的问题: 我正在使用谓词翻译让 Prolog 理解 [1,2,3,4,etc.] 是 [one,two,three,four,etc.]。

translate([],[]).    
translate([H|T],[H2|T2]):-means(H,H2),translate(T,T2).
means(0,zero).
means(1,one).
means(2,two).
means(3,three).
means(4,four).
means(5,five).
means(6,six).
means(9,nine).
means(10,ten).

我输入了查询

?-translate([1,2,3,4],X).

X=[一、二、三、四]。

Prolog 将英文数值翻译成数字。我只是需要帮助将这种翻译融入我的算术代码中。

calc([N1,times,N2],Total):-Total 为 N1*N2。

任何形式的建议都将不胜感激。 谢谢你。

【问题讨论】:

  • 这是家庭作业吗?

标签: windows prolog


【解决方案1】:

如果不给出答案,我不确定是否可以提供帮助,但我的第一个尝试是使用DCGs。它们是解析任何内容(包括原子列表)的一种非常方便的方法。例如:

word_number(1) --> [one].
word_number(2) --> [two].

您可以将其与phrase/2 一起使用:

?- phrase(word_number(N), [one]).
N = 1 ;

这里发生的事情是 Prolog 正在寻找与输入序列匹配的 DCG 规则或列表。这些 DCG 表达式只是差异列表之上的语法糖,但它们可以实现非常声明性的语法阅读。对此进行扩展:

expression(Value) --> 
  word_number(Left), 
  [times], 
  word_number(Right),
  { Value is Left * Right }.

除了--> 符号本身之外,语法糖的另一部分是您可以在大括号中嵌入任意Prolog。我们将其他 DCG 谓词用作输入中的其他标记,因此word_number(Left) 将左绑定到单词的整数值,然后Value 只是左单词数和右单词数的乘积。

?- phrase(expression(Value), [two,times,two]).
Value = 4.

希望这足以让您入门。

编辑

事实证明,您不需要将 translate/2 合并到您的 calc/2 谓词中,means/2 就可以完成这项工作:

calc([W1, times, W2], Total) :- 
  means(W1, N1), means(W2, N2),
  Total is N1*N2.

【讨论】:

  • 你好,这确实让我朝着正确的方向前进,但由于我是一个糟糕的程序员,我仍在努力让我的代码正常工作。我已经在 Prolog 上尝试了您的示例并使其正常工作,但是我正在尝试使用谓词翻译,但我似乎无法定义它以使 Prolog 理解 [1,2,3,4] = [one,two,three,four ]。这是我的代码你能帮我找出我的问题吗?谢谢。
  • 翻译([],[])。翻译(...,...):-意思是(...),翻译(...)
  • 表示(零,0)。表示(一,1)。意思是(二,2)。表示(三,3)。表示(四,4)。表示(五,5)。表示(六,6)。表示(九,9)。表示(十,10)。
  • calc([N1,times,N2],Total):-总计为 N1*N2。
  • 在这种情况下,最好用新代码编辑问题然后发表评论,因为评论限制非常繁重。今晚晚些时候我会看一下,但我也需要翻译的正文,所以如果你编辑问题会非常有帮助。
【解决方案2】:

将数字分配给符号的一种紧凑方法可以是nth0/3,并将其与“if”(参见(->)/2)结合,接受的输入可以跨越符号 数字。

valof(V, U) :-
 nth0(U, [zero, one, two], V) -> true ; U = V.

这样,一种应用于列表的简单方法可能是

calc([A, Op, B|Cs], R) :-
    valof(A, Va),
    valof(B, Vb),
    arith(Va, Op, Vb, T),
    calc([T|Cs], R).

编辑我忘记了递归的基础:

calc([A], R) :-
    valof(A, R).

arith(A, plus, B, R) :- R is A+B.
arith(A, mult, B, R) :- R is A*B.

请注意,我们弹出三个元素并替换为评估值(因此 valof 必须接受数字)。

我特意介绍了plus,一个与mult具有不同优先级的运算符。您应该看到上面的解决方案是正确的,因为它没有处理算术表达式语法的如此重要的属性。看看您是否可以更正它,将此答案与 Daniel 提供的 (+1) 和 this 我在类似问题上给出的其他答案合并。

【讨论】:

    猜你喜欢
    • 2020-02-10
    • 1970-01-01
    • 2011-01-25
    • 1970-01-01
    • 1970-01-01
    • 2010-09-27
    • 1970-01-01
    • 2014-01-12
    • 2012-02-26
    相关资源
    最近更新 更多