我知道我需要弄清自己的功課,但是看到班上沒有人能弄明白,我需要一些幫助。序言:認識到一個^ n b ^(n + 1)語言n> = 1
寫Prolog程序,使得
p(X)
爲真,如果X
是由n
a
的後面n+1
b
的名單,對於任何n >= 1
。
我知道我需要弄清自己的功課,但是看到班上沒有人能弄明白,我需要一些幫助。序言:認識到一個^ n b ^(n + 1)語言n> = 1
寫Prolog程序,使得
p(X)
爲真,如果X
是由n
a
的後面n+1
b
的名單,對於任何n >= 1
。
您應該使用計數器來跟蹤您迄今爲止發現的內容。當您找到b
時,請在計數器中添加一個。當你找到一個a
時,減去一個。您的計數器在整個列表遍歷後的最終值應爲1,因爲您希望b
的數量比a
的數量多1。這裏有一個如何編寫代碼的例子:
% When we see an "a" at the head of a list, we decrement the counter.
validList([a|Tail], Counter) :-
NewCounter is Counter - 1,
validList(Tail, NewCounter).
% When we see an "b" at the head of a list, we increment the counter.
validList([b|Tail], Counter) :-
NewCounter is Counter + 1,
validList(Tail, NewCounter).
% When we have been through the whole list, the counter should be 1.
validList([], 1).
% Shortcut for calling the function with a single parameter.
p(X) :-
validList(X, 0).
現在,這個會做幾乎你想要的東西 - 它匹配所有n >= 0
規則,當你想爲所有n >= 1
。在典型的家庭作業答案中,我留下了最後一點讓你自己補充。
謝謝,作業已經到期,我只想知道該怎麼做。我的課程是關於編程語言原理的,因此我們正在接受像Prolog和Ada這樣的教學,但沒有被教授語言,所以我們需要學習。所以謝謝! – poorStudent
我不記得如何在Prolog的這一點,但這個想法是這樣的:
規則1: 如果LISTSIZE是1,如果該元素是B.
第2條返回true : 如果列表大小爲2,則返回false。
規則3: 檢查列表中的第一項是A,最後一個是B. 如果這是真的,返回元素2 LISTSIZE-1解決方案。
如果我正確理解您的問題,那應該是完美的Prolog樣式解決方案。
編輯:我完全忘了這件事。我編輯了答案,考慮了n = 1和n = 2的情況。感謝Heath Hunnicutt。
這是一個很好的答案。它留下了一些情況,如列表少於2個字符長。爲0和1項目列表添加條款將使這個答案成爲「完美的Prolog式解決方案。「 –
是的,我忘了添加這些規則,謝謝你告訴我,我將在以後的帖子中編輯它(現在必須離開) – George
問題在於檢查鏈表的最後一項是O(n )操作,這很慢並且沒有自然的語法,它更符合邏輯聲明式的風格,但不幸的是,在這種特殊情況下,這不是Prolog所鼓勵的。 –
這裏是我的深奧的解決方案
:-use_module(library(clpfd)).
n(L, N) -->
[L],
{N1 #= N-1
},
!, n(L, N1).
n(_, 0) --> [], !.
ab -->
n(a, N),
{N1 is N + 1
},
n(b, N1).
p(X) :- phrase(ab, X).
test :-
p([b]),
p([a,b,b]),
p([a,a,b,b,b]),
p([a,a,a,b,b,b,b]),
\+ p([a]),
\+ p([a,b]),
\+ p([a,a,b,b]),
\+ p([a,b,b,c]).
測試:
?- [ab].
% ab compiled 0.00 sec, -36 bytes
true.
?- test.
true.
請教老師。如果真的沒有人理解它,問題在於教學,你需要和老師一起提出。 – GManNickG
@ Neil Butterwork:我記得,'!'是我認爲可以防止回溯的切割符號。不記得發生了什麼,如果你把它們放在一起。 – FrustratedWithFormsDesigner
問題是您的目標語言還是執行此操作所需的邏輯?但是,格曼是正確的。假設你爲這種教育付款,你應該首先與教授或TA聯繫。 – avirtuos