簡體   English   中英

解決和調試Prolog中的邏輯難題

[英]Solving and debugging a logic puzzle in Prolog

我正在嘗試使用Prolog解決以下邏輯難題:

確定比賽中每位車手的名字和姓氏,每輛賽車的贊助商以及每位車手在什么位置結束比賽。

  1. 由Flash Automotive贊助的車手獲得了第三名。 霍華德不是由曲軸機油贊助的,他沒有以第五名的身份完成比賽。
  2. 姓賴恩(Right)的瑞安(Ryan)不是由NAPA汽車配件公司贊助的。 Barry Straight不是由Fleet Bodyworks贊助的。
  3. 由Crank Motor Oil贊助的駕駛員比悉尼高一個位置,后者的姓氏不是Element。
  4. Chariot先生的名字不是亞當,他獲得了第一名。 霍華德比右派低一個位置。
  5. NAPA汽車零部件贊助了獲得第四名的車手,而巴里不是。
  6. 五位車手排名不分先后,分別是亞當(Adam),特雷德·泰瑞斯(Tredco Tires),羅特(Right)先生和拉夫(Rafe)先生贊助的車手。

使用與此處類似的方法: http : //www.anselm.edu/internet/compsci/faculty_staff/mmalita/HOMEPAGE/logic/aa6.txt

我想出了以下答案:

    race(Drivers) :- Drivers = [[howard,_,_,_],[barry,_,_,_],[ryan,_,_,_],
        [sydney,_,_,_],[adam,_,_,_],[_,straight,_,_],[_,chariot,_,_],
        [_,right,_,_],[_,element,_,_],[_,rafe,_,_],[_,_,flashautomotive,_],
        [_,_,crankmotoroil,_],[_,_,napaautoparts,_],[_,_,fleetbodyworks,_],
        [_,_,tredcotires,_],[_,_,_,1],[_,_,_,2],[_,_,_,3],[_,_,_,4],[_,_,_,5]],
        member([barry,straight,C,D], Drivers), C \= fleetbodyworks, 
            C \= napaautoparts, D \= 4,
        member([howard,_,G,H], Drivers), G \= crankmotoroil, H \= 5, H =:= X - 1,
        member([ryan,J,K,_], Drivers), J \= right, K \= napaautoparts,
        member([sydney,N,_,P], Drivers), N \= element,
        member([Q,chariot,_,T], Drivers), Q \= adam, T = 1,
        member([_,right,_,X], Drivers),
        member([_, _, _, crankmotoroil, DD], Drivers), DD =:= P + 1,
        member([EE,_,napaautoparts,HH], Drivers), HH = 4, EE \= barry,
        member([_,_,flashautomotive,LL], Drivers), LL = 3.

將其加載到Windows SWI-Prolog IDE中時,它沒有錯誤,但是在調試時會產生以下結果:

[debug] [1] 12 ?- race(X)
|    .
    T Call: (13) race(_G4168)
    T Fail: (13) race(_G4168)
false.

我對Prolog顯然很陌生,但是我想知道是什么原因導致失敗以及如何解決(因為在我了解如何使用調試器的情況下,調試器在這種情況下不是很有用)。 另外,有沒有更干凈的方法來解決類似的邏輯問題?

您對“搜索空間”的表示是不正確的:在鏈接的示例中,請注意,只有一個值槽與常量綁定。 在給定約束的正確位置之后,此常數將有效地識別其他變量元素。

此外,讓Prolog應用由各種member / 2進行的“排列游戲”,並且僅檢查了身份,差異等之后。...找到解決方案之后,您可以嘗試優化搜索過程,以提高檢查效率,但是總是分配了相關的插槽之后 ...

一個很好的選擇是使用數字字段,因此您可以以明顯的方式應用算術來強制執行約束。 因此,我嘗試修改您的代碼:

race(Drivers) :-
    Drivers = [
        [_,_,_,1],
        [_,_,_,2],
        [_,_,_,3],
        [_,_,_,4],
        [_,_,_,5]
    ],
        member([barry,straight,C,D], Drivers),
        member([howard,_,G,H], Drivers),
        member([ryan,J,K,_], Drivers),
        member([sydney,N,_,P], Drivers),
        member([Q,chariot,_,T], Drivers),
        member([_,right,_,X], Drivers),
        member([_,_,crankmotoroil,DD], Drivers),
        member([EE,_,napaautoparts,HH], Drivers),
        member([_,_,flashautomotive,LL], Drivers),

    C \= fleetbodyworks, C \= napaautoparts, D \= 4,
    G \= crankmotoroil, H \= 5, H =:= X - 1,
    J \= right, K \= napaautoparts,
    N \= element,
    Q \= adam, T = 1,
%   DD =:= P + 1,
    HH = 4, EE \= barry,
    LL = 3.

請注意注釋行:如果取消注釋,則沒有解決方案可用...注釋限制是可用於此簡單模式的更簡單的調試工具。

這是基於CapelliC答案的可行解決方案。 最初,借助I的幫助,我誤解了部分問題並忘記了一些規則,因此,錯誤已得到修復,並且在此解決方案中添加了其他規則。

    race(Drivers) :-
        Drivers = [
            [_,_,_,1],
            [_,_,_,2],
            [_,_,_,3],
            [_,_,_,4],
            [_,_,_,5]
        ],
            member([barry,straight,Barrysponsor,Barryplace], Drivers),
            member([howard,_,Howardsponsor,Howardplace], Drivers),
            member([ryan,Ryanlastname,Ryansponsor,_], Drivers),
            member([sydney,Sydneylastname,_,Sydneyplace], Drivers),
            member([adam,Adamlastname,Adamsponsor,Adamplace], Drivers),
            member([Chariotfirstname,chariot,_,1], Drivers),
            member([Rightfirstname,right,Rightsponsor,Rightplace], Drivers),
            member([_,element,_,_], Drivers),
            member([_,rafe,_,_], Drivers),
            member([_,_,crankmotoroil,Crankmotoroilplace], Drivers),
            member([Napaautopartsfirstname,_,napaautoparts,4], Drivers),
            member([_,_,flashautomotive,3], Drivers),
            member([Tredcotiresfirstname,Tredcotireslastname,tredcotires,Tredcotiresplace], Drivers),
            member([_,_,fleetbodyworks,_], Drivers),

    Barrysponsor \= fleetbodyworks, Barrysponsor \= napaautoparts, Barryplace \= 4,
    Howardsponsor \= crankmotoroil, Howardplace \= 5, Howardplace =:= Rightplace + 1,
    Ryanlastname \= right, Ryansponsor \= napaautoparts,
    Adamplace \= 2, Adamsponsor \= tredcotires,
    Adamlastname \= right, Adamlastname \= rafe,
    Sydneylastname \= element,
    Chariotfirstname \= adam,
    Rightfirstname \= adam, Rightplace \= 2, Rightsponsor \= tredcotires,
    Crankmotoroilplace =:= Sydneyplace - 1,
    Napaautopartsfirstname \= barry,
    Tredcotiresfirstname \= adam, Tredcotiresplace \= 2, 
    Tredcotireslastname \= rafe, Tredcotireslastname \= right.

暫無
暫無

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

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