簡體   English   中英

Prolog謂詞解決方案

[英]Prolog Predicate Solution

我正在為即將到來的Prolog考試解決一些過去的考試問題。

這是問題:

  1. (a)編寫一個謂詞insert(Xs, Y, Zs) ,該謂詞在Zs是通過將Y插入列表Xs中獲得的列表時成立。 查詢,例如:

     ? - insert([1,2,3], 4, Zs). 

應該成功四次,並給出以下答案:

Zs = [4, 1, 2, 3]

Zs = [1, 4, 2, 3]

Zs = [1, 2, 4, 3]

Zs = [1, 2, 3, 4]. 

我有點擔心,因為我不知道從哪里開始。 在我需要示例解決方案來練習考試的過程中,有人可以提供幫助嗎?

非常感謝您的幫助。

我們從更改此謂詞的可怕名稱開始:謂詞應描述什么成立而不是做什么。 名稱應反映出這一點。 我建議使用list_with_element/3 ,並鼓勵您嘗試尋找更好的名稱,最好是明確每個參數的含義。

然后,我們要做我們打算做的事情:描述使這種關系成立的情況。

例如:

list_with_element([], E, [E]).
list_with_element([L|Ls], E, [E,L|Ls]).
list_with_element([L|Ls0], E, [L|Ls]) :-
        ...

我留在填寫...作為一個簡單練習。 說明子句頭為真所必需的條件!

編輯 :我想說更多有關上述模式。 以我的經驗,推論描述列表的謂詞的一種好方法(絕對是在開始時)是考慮以下兩種基本情況:

  1. 原子[] ,表示空列表
  2. 形式為'.'(E, Es)術語,也寫為[E|Es] ,其中E是列表的第一個元素, Es也是列表。

這遵循列表的歸納定義。

在這種特定情況下的缺點是,這種方法導致情況再次需要將情況(2)分為兩個子情況,並且以某種方式意外地需要三個子句來處理這兩個基本情況。 顯然,這與我們直覺地期望兩個子句就足夠相反。 的確確實如此,但是我們需要注意不要意外丟失解決方案。 在這種情況下,上面的前兩個子句包含在以下事實中:

list_with_element(Ls, E, [E|Ls]).

每個有經驗的Prolog編碼器都將以這種方式編寫謂詞,或者僅在這種情況下直接使用select/3 這就是@lurker的感知和暗示,而@tas正確地表明了一個不同的子句(很容易意外地想到)並沒有完全包含我們要表達的所有情況。

因此,我仍然發現首先明確考慮空列表,確保正確設置大小寫,然后繼續處理更復雜的情況,然后查看是否可以更緊湊地編寫現有程序,要容易得多。 這也是我用於此示例代碼的方式,但是我沒有使其盡可能短。 請注意,對於單調代碼,有多余的事實是完全可以的!

請注意,是專門為沒有確定,只是通過更換前兩個條款:

list_with_element([L|Ls], E, [E|Ls]).

因為此子句不包含上述情況(1)。

我猜想這個問題可能正在尋找的一個答案遵循以下思路:

insert(List, Element, NewList) :-
    append(Front, Back, List), % split list in two
    append(Front, [Element|Back], NewList). % reassemble list

如果您希望聲明式閱讀:

NewList在List的前后之間具有Element。

仔細檢查是否在先前的問題或學習材料中出現了append/3或具有相同語義的謂詞。

並請注意,如果我正確理解的話,這實際上與@mat建議完全相同 有關詳細信息,請查閱append/3的教科書定義。 甚至更好的是,查看append/3的教科書定義, append/3其修改為在“插入”時使用。

盡管參數的順序不同,但內置的謂詞select/3可以執行相同的操作。

請記住,(如果定義正確)謂詞可以在不同方向上工作。 例如,它可以告訴你一個列表看起來像移除元素后,它可以(盡管這也很簡單)告訴您從一個列表中刪除哪些因素再弄,也可以告訴你列出,有后給定元素被刪除,將類似於給定列表。
(提示:您可能要研究最后一個)。

暫無
暫無

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

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