2016-04-28 52 views
0

我在序言以下代碼:從事實中獲取最大值?

designer(name("Ivan", "Ivanov"), "Bulgarian", 12, 11). 
designer(name("John", "Turturro"), "Italian", 2, 9). 
designer(name("John", "McLane"), "American", 32, 26). 
designer(name("Roberto", "Turturro"), "Italian", 32, 8). 
designer(name("Petar", "Petrov"), "Bulgarian", 32, 23). 

designer_max_points(FirstName, LastName, Points) :- 
    designer(name(FirstName, LastName), _, _, Points), 
    not(designer(name(_,_), _,_, Points1), Points1 > Points). 

我的目標是讓每個設計師其實最大點值(最終值)。

上述解決方案的工作,但我不知道爲什麼。我已經研究了而不是謂詞,並且顯然它的參數在失敗時成功(例如?-not(2 = 3),將返回true)。

但是,如果是這樣的話:

designer_max_points(FirstName, LastName, Points) :- 
    designer(name(FirstName, LastName), _, _, Points), 
    designer(name(_, _), _,_, Points1), 
    Points > Points1. 

...爲什麼不此代碼的工作?

回答

0

它回答了一個不同的問題:

有比其他任何點的任何設計師?

它將與許多重複的答案成功,例如

name("Ivan", "Ivanov")name("John", "Turturro")name("Roberto", "Turturro")更多的積分,所以你應該得到兩次

FirstName='Ivan', LastName='Ivanov', Points=11 

等等...

+0

謝謝,這是有道理的。你能解釋一下在謂詞中究竟發生了什麼嗎? – HornedDemoN

+0

mmh ... *精確*是一個很大的詞......查看維基百科關於[Negation as failure]的文章(https://en.wikipedia.org/wiki/Negation_as_failure) – CapelliC

0

它不起作用,因爲它所做的全部成功每個 2個設計師的組合,約束條件成立。你想要做的是這樣的:

designer_max_points(Name, Surname , Points) :- 
    findall(d(N,S,P) , designer(name(N,S),_,_,P) , Ds) , % get the list of info you need 
    max_in_list(Ds,d(Name,Surname,Points))    % then scan it to find the desired value 
    . 

max_in_list([D|Ds],M) :- max_in_list(Ds,D,M) . % get find the max value in the list, invoke the worker predicate using the head of the list as the current max. 

max_in_list([] , M , M) .      % once the source list is exhausted, the current max is the final max 
max_in_list([d(N,S,P)|Ds] , d(Nm,Sm,Pm) , M) :- % otherwise... 
    (P > Pm -> T1 = d(N,S,P) ; T1 = d(Nm,Sm,Pm)) , % pick the new current max (T1), 
    max_in_list(Ds,T1,M)        % then recurse down on the tail. 
    .            % easy!