【问题标题】:Prolog - translating operatorsProlog - 翻译运算符
【发布时间】:2018-03-08 02:29:00
【问题描述】:

我定义了以下运算符:

:- op(200, xfx, plus).
:- op(100, xfx, times).

我想实现一个谓词 translate/2,以便给定的术语仅由数字和运算符 plus 和 times 组成,这样这些运算符将被翻译成它们相应的算术运算符:+ 和 *。

例如:

?- translate((4 plus 5), Result).
   Result = 4 + 5.

?- translate(((3 times 2) times 7 plus 4), Result).
   Result = (3 * 2) * 7 + 4.

?-translate((5 times 3 plus 4 times 5)), Result).
  Result = 5 * 3 + 4 * 5.

更新:好的,所以到目前为止我提出的代码是:

replace([], _, _, []).

replace([El1|List], El1, El2, [El2|Result]) :-
replace(List, El1, El2, Result), !.

replace([H|List], El1, El2, [H|Result]) :-
replace(List, El1, El2, Result). %replaces an element in a list with 
                                  %another element.


translate(Term, ListResult2):-
  Term =.. ListResult,
  replace(ListResult, times, *, ListResult1),
  replace(ListResult1, plus, +, ListResult2). %This will make a list of a 
                                              % a term and replace the
                                              %operators the right way.                                   

很抱歉没有为我的条款如何工作添加更具体的 cmets。这里的想法是生成一个列表,其中 te 运算符被相应的术语替换。我的问题是输出是一个列表而不是一个术语。有没有办法扭转我对 =.. 运算符所做的事情???

【问题讨论】:

  • 你自己尝试过什么?什么不工作?你遇到了什么问题?

标签: prolog operators predicate operator-precedence


【解决方案1】:

我想我找到了解决方案,这是我错过的语法。我忘记了 =.. 运营商可以在期限上为双方提供解决方案。所以 X =.. [1,2,3] 会将列表 [1,2,3] 转换为相应的项,反之亦然。解决方案如下所示:

replace([], _, _, []).

replace([El1|List], El1, El2, [El2|Result]) :-
replace(List, El1, El2, Result), !.

replace([H|List], El1, El2, [H|Result]) :-
replace(List, El1, El2, Result).


translate(Term, TrueResult):-
  Term =.. ListResult,
  replace(ListResult, times, *, ListResult1),
  replace(ListResult1, plus, +, ListResult2),
  TrueResult =.. ListResult2.

【讨论】:

  • 如果你的例子是递归的怎么办?喜欢(a plus b) times c
  • 庆祝太早了...所以我需要检查 i plus/times 是列表成员的一部分,然后替换而不是仅仅将 plus/times 视为可能的成员。
【解决方案2】:

这样的东西可能适合您的需求:

:- op(200, yfx, plus).
:- op(100, yfx, times).

translate(Z, Z1):-
  (
    nonvar(Z),
    Z \= _ plus _,
    Z \= _ times _
  ) -> Z1=Z ;
  (
    member(Z-Z1, [(X plus Y)-(X1 + Y1), (X times Y)-(X1 * Y1)]),
    translate(X, X1),
    translate(Y, Y1)
  ).

测试用例:

?- translate((4 plus 5), Result).
Result = 4+5 
?- translate(((3 times 2) times 7 plus 4), Result).
Result = 3*2*7+4
?- translate((5 times 3 plus 4 times 5), Result).
Result = 5*3+4*5
?- translate((a plus b) times c, Result).
Result = (a+b)*c
?- translate(5 times (3 plus 4) times 5, Result).
Result = 5* (3+4)*5

【讨论】:

  • 非常感谢!!你认为它也可以用我上面展示的 =.. 方法来完成,还是最终会变得太不实用??
  • @WillemvanderSpek:我认为你可以使用=.. 让它工作,尽管你应该修改你的过程以递归调用每个操作数。
猜你喜欢
  • 1970-01-01
  • 2010-11-27
  • 1970-01-01
  • 1970-01-01
  • 2014-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-28
相关资源
最近更新 更多