比较仿函数列表和统一变量

时间:2015-10-12 02:56:24

标签: prolog clpfd unification expression-evaluation

如何验证两个列表是否在任何给定的顺序中表示它们的变量之间的相同关系,然后统一相应的变量?

例如列表:

[#=(_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

1 个答案:

答案 0 :(得分: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).

肯定有很多改进可以做......