簡體   English   中英

是否有一種無縫的方式來實現same_length / 3?

[英]Is there a cut-less way to implement same_length/3?

假設我想斷言三個列表的長度相同。 我可以這樣做:

same_length(First, Second, Third) :-
  same_length(First, Second),
  same_length(Second, Third).

FirstSecond被實例化時,這是正確的。 當所有三個參數都被實例化時它也可以工作! 然而,像length(Third, 3), same_length(First, Second, Third)這樣的調用會使它返回正確的答案(所有三個列表的長度為3)和一個選擇點,然后循環永遠生成永遠不會匹配的解決方案。

我寫過一個版本,我認為在任何情況下都是正確的:

same_length(First, Second, Third) :-
  /* naively calling same_length(First, Second), same_length(Second, Third) doesn't work,
     because it will fail to terminate in the case where both First and Second are
     uninstantiated.
     by always giving the first same_length/2 clause a real list we prevent it from
     generating infinite solutions */
  ( is_list(First), same_length(First, Second), same_length(First, Third), !
  ; is_list(Second), same_length(Second, First), same_length(Second, Third), !
  ; is_list(Third), same_length(Third, First), same_length(Third, Second), !
    % if none of our arguments are instantiated then it's appropriate to not terminate:
  ; same_length(First, Second), same_length(Second, Third) ).

我一直聽說如何盡可能避免切割,是否有可能在這里避免它?

作為一個額外的問題,我認為這些是綠色削減,因為最終的謂詞是完全關系的,這是真的嗎?

為什么不以相同的方式定義same_length/3通常定義same_length/2

same_length([], [], []).
same_length([_| T1], [_| T2], [_| T3]) :-
    same_length(T1, T2, T3).

在所有參數未綁定的情況下調用時可以正常工作:

?- same_length(L1, L2, L3).
L1 = L2, L2 = L3, L3 = [] ;
L1 = [_990],
L2 = [_996],
L3 = [_1002] ;
L1 = [_990, _1008],
L2 = [_996, _1014],
L3 = [_1002, _1020] ;
L1 = [_990, _1008, _1026],
L2 = [_996, _1014, _1032],
L3 = [_1002, _1020, _1038] ;
...

在您提及的情況下,沒有虛假的選擇點或非終止回溯:

?- length(L3, 3), same_length(L1, L2, L3).
L3 = [_1420, _1426, _1432],
L1 = [_1438, _1450, _1462],
L2 = [_1444, _1456, _1468].

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM