【问题标题】:Prolog- translating English to CProlog-将英语翻译成C
【发布时间】:2012-11-06 18:27:15
【问题描述】:

我们有一个相对简单的任务,我在理论上可以理解,但我认为我对 Prolog 的语法还不够了解,无法将其写入代码。基本上,我们有一个表示 C 中操作的英文符号列表。当它们被传递给我们的 Prolog 程序时,它们被存储为一个列表。例如:

add 4 to 3

[add, 4, to, 3]

我们需要编写一个函数来获取该列表并返回等效项。所以如果我打电话给

english2C([add,4,to,3], C).
C = 4+3

它将 C 绑定到结果。所以数据结构本身类似于 +(4(3))。我们有一个我们必须翻译的英语符号的列表,所以它是一个有限的数字。我们不必考虑所有可能性。还有组合,它们采用两个操作并将它们组合起来(中间用逗号)

english2C([add,3,to,5,',',then,subtract,7], C).
C = 3+5-7

我只是有点困惑如何开始。我知道我可以获取列表的第一个元素,它始终是一个运算符(+、-、* 等),然后我可以递归地遍历列表以查找操作数。问题在于需要操作顺序的事物,例如“将 3 加到 5 然后乘以 4”,它应该表示为 (3+5)*4 但如果你直接翻译它,你会得到 3+5*4 .

哦,我们必须看看我们是否可以让它向后运行(给它一个 C 语句 (3+5) 并翻译回英文(添加 3 到 5))。那部分我真的一点想法都没有。

编辑:可能的英文符号有足够大的排列,我不能只是模式匹配所有内容。我知道我需要做的是将第一个运算符与其相应的算术符号匹配,然后找到操作数。对于组合语句,这将是第一部分(所以我会有 3+5),然后会有一个逗号,然后是下一个语句。顺便说一句,组合语句可以随心所欲,所以不仅仅是两个语句,我已经完成了。

【问题讨论】:

    标签: list prolog nlp dcg


    【解决方案1】:

    如果有合理的少量模式,您可以这样做:

    english2C([add,X,to,Y], R) :- R is X+Y.
    english2C([add,A,to,B,',',then,subtract,C], R) :- R is A+B-C.
    

    编辑

    上面的那些规则计算值。要翻译,我们可以使用 DCG 进行匹配,它也可以“向后”工作。

    english2C(In, R) :- phrase(toe(R), In, []).
    
    toe(X+Y) --> [add,X,to,Y].
    toe(X*Y) --> [multiply,X,by,Y].
    toe(L-R) --> toe(L), [',',then,subtract,R].
    

    测试:

    ?- english2C(X,3+6).
    X = [add, 3, to, 6].
    

    编辑抱歉,我忘记剪辑了。加上这个,我得到了

    ?- english2C([add,3,to,5,',',then,subtract,4],X).
    X = 3+5-4.
    
    ?- english2C(L,3+5-4).
    L = [add, 3, to, 5, ',', then, subtract, 4].
    

    没有,后面有循环;

    ?- english2C([add,3,to,5,',',then,subtract,4],X).
    X = 3+5-4 ;
    ^CAction (h for help) ? goals
    [698,875] toe(_G2096630, [add, 3, to, 5, ',', then, subtract, 4], _G2096652)
    [698,874] toe('<garbage_collected>', '<garbage_collected>', _G2096652)
    ...
    

    单点变化:你更喜欢自己找吗?

    【讨论】:

    • 不幸的是它不是那么小 XD 但这个想法是正确的。基本上我的想法是将第一个元素与运算符匹配,然后进入列表以获取操作数,但这必须是递归的,我必须能够分离组合语句。
    • 哦,这比我尝试做的要简单得多。它也更可靠地工作。非常感谢。
    • 哦,几乎无论如何。我必须对其进行一些调整,因为它适用于定义规则的所有情况,但是如果我使用一些未在规则中定义的随机短语(它应该返回 no),则会出现堆栈溢出错误。但除此之外,我认为它有效。
    • 哦,我明白了。有两次崩溃。如果它给了我一个答案并且我不接受它(键入';'),它会尝试重做呼叫,但前一个呼叫 (3+5) 的答案已经存储并且它进入一个无限循环。但我不认为我可以添加一个削减来阻止它。同样,如果它在规则列表中找不到该短语,它会进入无限循环。应该有一种方法可以返回不。
    • 尽量保持代码简单,尽可能模仿语法。这可能是一个相当“无效”的提示,因为将程序简化为更重要的术语可能很困难或不可能......
    猜你喜欢
    • 1970-01-01
    • 2011-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多