2016-09-14 48 views
2

我在理解這段代碼時遇到了一些麻煩。瞭解附加語法

powerset(L, [H|T]):- 
    append([H|T], _, L). 

它起源於這個thread,正是我想要的;不過,我還想了解我正在使用的代碼。

回答

3

讓我們首先考慮在隔離條款的唯一目標:

?- append([H|T], _, L). 

這是什麼意思?使用純粹的Prolog代碼,有一個很好的和方便的方式來了解更多關於關係:只需在頂層發佈查詢,看看什麼樣的解決方案。

試一試吧!例如:

 
?- append([H|T], _, L). 
L = [H|_1282], 
T = [] ; 
L = [H, _1078|_1096], 
T = [_1078] ; 
L = [H, _1078, _1084|_1108], 
T = [_1078, _1084] ; 
L = [H, _1078, _1084, _1090|_1120], 
T = [_1078, _1084, _1090] ; 
etc. 

由此我們看到,append/3這個調用定義了它的參數之間的關係,我們看到下面的模式:

L總是包括:

  • H爲第一個元素
  • 後面跟着所有元素T
  • f由後綴貶低。

這不是suprising,因爲這正是append([H|Ts], _, Ls)意味着:[H|Ts]其次任何列表中的所有構成列表  Ls

在您的具體使用案例中,很顯然L是爲了實例化,所以後綴不能任意長。

例如:

 
?- append([H|T], _, [a,b,c]). 
H = a, 
T = [] ; 
H = a, 
T = [b] ; 
H = a, 
T = [b, c] ; 
false. 

所以我們看到整個條款的含義(我已經改名變量,使列表由後綴  小號在變量名錶示):

 
powerset(Ls, [H|Ts]):- 
    append([H|Ts], _, Ls). 

如果Ls是包含作爲其第一元件H,隨後元件Ts列表,其次是什麼都沒有,然後列表[H|Ts]L的powerset的成員。

通俗地說:

列表中的每一個非空前綴是冪的一員。

而從這個我們也看到powerset/2一個明顯的遺漏,因爲它出現在這個線程:該條款中沒有得到的空 設置爲冪的一員,更令人不安的是,他們沒有接受空集爲一組有效的,所以下面的錯誤失敗

 
?- powerset([], _). 
false. % empty set is not a set? 

練習:正確powerset/2,以便它實際上成功了所有powerset的元素。