2015-10-12 65 views
1

如何驗證兩個列表是否表示它們的變量之間的任何給定順序之間的相同關係,然後統一相應的變量?比較函數列表和統一變量列表

例如列表:

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

這是功課?還是有一些你需要這樣做的背景?因爲經常_avoiding_做一些複雜的事情比僅僅做它更容易。 –

+0

我製作了一個使用CLPFD解決一些問題的程序,但我注意到其中的大部分都非常相似,我希望它能更快地解決類似的輸入問題。 – fpg1503

+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). 

肯定也有一些改進可以做...