我想写一个谓词invert(X, Y)
,它成立 when Y
isX
但每次出现+
替换为-
。
例如
?- invert(2 + 3, 2 - 3).
yes.
例如
?- invert(3 + (2 + 4), X).
X = 3 - (2 - 4).
您可以使用 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).
我会建议一些更简单的东西:
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).