1

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

跟进我之前的问题:我正在使用谓词翻译让 Prolog 了解 [1,2,3,4 等] 是 [一、二、三、四等]。

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).

我输入了查询

?-翻译([1,2,3,4],X)。

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

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

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

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

4

2 回答 2

2

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

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)要将 Left 绑定到单词的整数值,然后Value只是左单词数和右单词数的乘积。

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

希望这足以让你开始。

编辑

事实证明,您不需要将其合并translate/2calc/2谓词中,means/2就可以很好地完成工作:

calc([W1, times, W2], Total) :- 
  means(W1, N1), means(W2, N2),
  Total is N1*N2.
于 2013-02-06T05:02:23.520 回答
1

将数字分配给符号的紧凑方法可能是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不同的运算符。您应该看到上面的解决方案是正确的,因为它没有处理算术表达式语法的如此重要的属性。看看您是否可以更正它,将此答案与 Daniel 提供的 (+1) 合并,以及我在类似问题上给出的另一个答案mult

于 2013-02-06T07:26:59.643 回答