我定义了以下运算符:
:- op(200, xfx, plus).
:- op(100, xfx, times).
我想实现一个谓词translate / 2,这样一个给定的术语只包含数字和运算符加上和时间,这样这些运算符就会被转换成它们对应的算术运算符:+和*。
例如:
?- 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.
很抱歉没有添加更多关于我的子句如何工作的具体评论。这里的想法是产生一个列表,其中te运算符被相应的术语替换。我的问题是输出是一个列表而不是一个术语。有没有办法扭转我用= ..运算符???
所做的事情答案 0 :(得分:0)
我认为我找到了解决方案,这是我错过的语法。我忘记了= ..运算符可以为术语双方提供解决方案。因此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.
答案 1 :(得分:0)
这样的事情可能适合您的需求:
:- 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