1

2 つのリストが任意の順序で変数間の同じ関係を表しているかどうかを確認し、対応する変数を統合するにはどうすればよいですか?

たとえば、リスト:

[#=(_G13544,_G13547+1),#=(_G13553,_G13554),#=(_G13559,2),#>(_G13559, _G13544)]

次と同等です。

[#>(_G13453,_G13430),#=(_G13409,_G13355),#=(_G13453,2),#=(_G13430,1+_G13370)]

どちらも次のように記述できるためです。

[A#>B,C#=D,A#=2,B#=E+1]

変数は次のようにバインドされます。

_G13453 = _G13559                  # Equivalent to A
_G13430 = _G13544                  # Equivalent to B
_G13409 = _G13553                  # Equivalent to C 
_G13355 = _G13554                  # Equivalent to D
_G13370 = _G13547                  # Equivalent to E

ファンクターは、次の CLPFD 演算子です。

  • 対称: #=/2+/2-/2、および#\//2;
  • 対称ではありません: #>/2、および#</2;
  • 単項:abs/1
4

1 に答える 1

0

始めるための何か

'same relationship between their variables'(L1, L2, Vs) :-
    copy_term(L1, T1),
    copy_term(L2, T2),
    numbervars(T1, 0, N),
    numbervars(T2, 0, N),
    rel_pairs(T1, T2, [], Vs).

rel_pairs([], [], B, B).
rel_pairs(Xs, Ys, B0, B2) :-
    select(X, Xs, Xr),
    select(Y, Ys, Yr),
    assign(X, Y, B0, B1),
    rel_pairs(Xr, Yr, B1, B2).

assign(A#=B, C#=D, B0, B2) :-
    assign(A, C, B0, B1),
    assign(B, D, B1, B2)
    ;
    assign(A, D, B0, B1),
    assign(B, C, B1, B2).
assign(A#>B, C#>D, B0, B2) :-
    assign(A, C, B0, B1),
    assign(B, D, B1, B2).

assign(A+B, C+D,  B0, B2) :-
    assign(A, C, B0, B1),
    assign(B, D, B1, B2)
    ;
    assign(A, D, B0, B1),
    assign(B, C, B1, B2).

assign('$VAR'(A), '$VAR'(B),  B0, B0) :-
    memberchk(A-B, B0), !.
assign('$VAR'(A), '$VAR'(B),  B0, [A-B|B0]) :-
    \+memberchk(A-_, B0),
    \+memberchk(_-B, B0), !.
assign(X, X, B, B).

確かに、実行できる改善点はたくさんあります...

于 2015-10-12T12:41:47.570 に答える