2

私は述語invert(X, Y)を書きたいと思っています。YX+-

例えば

?- 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].

最初の節は主関手 + を伴う項を扱います。2 番目の節は、主関手が異なる項に適用されます。

[編集] コメントの 1 つが示唆するように、最初の句を変更して、両方の引数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 に答える