2

我想写一个谓词invert(X, Y),它成立 when YisX但每次出现+替换为-

例如

?- invert(2 + 3, 2 - 3). 
yes. 

例如

?- invert(3 + (2 + 4), X). 
X = 3 - (2 - 4).
4

2 回答 2

3

您可以使用 univ=..来检查表达式的条款,并将运算符替换为+/2运算-/2符。

invert(Left+Right, ILeft-IRight):-
  !,
  invert(Left, ILeft),
  invert(Right, IRight).
invert(Exp, IExp):-
  Exp=..[Functor|Args],
  findall(NArg,
    ( member(Arg, Args),
      invert(Arg, NArg)
    ), NArgs),
  IExp=..[Functor|NArgs].

第一个子句处理带有主函子 + 的术语。第二条适用于具有不同主函子的术语。

[编辑] 正如其中一条评论所暗示的,当 的两个参数都未实例化时,您可以更改第一个子句以避免无限循环invert/2,只需将其替换为该子句

invert(Exp, ILeft-IRight):-
  Exp=..[+, Left, Right],
  !,
  invert(Left, ILeft),
  invert(Right, IRight).
于 2012-04-26T16:31:12.333 回答
1

我会建议一些更简单的东西:

invert(P,P):-atomic(P). % P is konstant, e.g. invert(3,3)->true
invert(T-P,T1-P1):-invert(P,P1),invert(T,T1).
invert(T+P,T1-P1):-invert(P,P1),invert(T,T1).
于 2012-04-26T16:51:20.587 回答