2016-01-05 23 views
2

我在語言練習中停留了一些語法。這是我第一次用語法(用任何語言)。我需要創建一個解析器,它將計算機器人的目標座標以及當前指向的方向(以n,s,w,e之一表示)。序言,機器人移動語法+解析器

可能的舉措是:[go,10](或任何數字),[turn, left][turn, right]。 這是很容易(我覺得..)編寫解析器識別正確的句子,如:[go,10,turn,right,go,10]:然而

robot_p-->pol. 

pol-->[go],num. 
pol-->[go],num,pol. 
pol-->[turn],[left]. 
pol-->[turn],[left],pol. 
pol-->[turn],[right]. 
pol-->[turn],[right],pol. 
num-->[D],{number(D)}. 
robot(L):-robot_p(L,[]). 

現在,我不知道,我怎麼會積累每一個步驟,因此對於句子我舉了一個例子,結果是[10,10,e]。我想我應該寫這樣的東西:

robot_p(result)-->pol(result). 

但是,如果是這樣,它會怎麼樣呢?我可以改變num到:

num(D)-->[D],{number(D)}. 

下,這將啓動:

pol([X,Y,N])-->[go],num(D),{N==n;//here I don't know what next}. 

然而,我不知道這是否是好辦法,如果是這樣,現在給做。

編輯:

我忘記說了,我需要通過開始座標。 因此,對於[0,0,n]和移動[go,10,turn,right,go,10]結果是[10,10,e]

EDIT2:

非常感謝@BretC尋求幫助。我已經按照你的提示創建了令我滿意的版本。也許這將幫助別人:)

pol([X])-->[go],num(X). 
pol([X| T])-->[go],num(X),pol(T). 
pol([left])-->[turn],[left]. 
pol([left | T])-->[turn],[left],pol(T). 
pol([right])-->[turn],[right]. 
pol([right | T])-->[turn],[right],pol(T). 

commands(L,V):-pol(V,L,[]). 
move([X,Y,D],V,[X1,Y,D]):-D==n,X1 is X+V. 
move([X,Y,D],V,[X1,Y,D]):-D==s,X1 is X-V. 
move([X,Y,D],V,[X,Y1,D]):-D==w,Y1 is Y-V. 
move([X,Y,D],V,[X,Y1,D]):-D==e,Y1 is Y+V. 
rotate(D,P,D1):-P==left,D==n,D1=w. 
rotate(D,P,D1):-P==left,D==s,D1=e. 
rotate(D,P,D1):-P==left,D==w,D1=s. 
rotate(D,P,D1):-P==left,D==e,D1=n. 
rotate(D,P,D1):-P==right,D==n,D1=e. 
rotate(D,P,D1):-P==right,D==s,D1=w. 
rotate(D,P,D1):-P==right,D==w,D1=n. 
rotate(D,P,D1):-P==right,D==e,D1=s. 
robot_H(D,[],D). 
robot_H([X,Y,D],[H|T],K):-number(H),move([X,Y,D],H,ND),robot_H(ND,T,K). 
robot_H([X,Y,D],[H|T],K):- \+number(H),rotate(D,H,D1),robot_H([X,Y,D1],T,K). 

robot(S,P,K):-commands(P,P1),robot_H(S,P1,K). 
num(X)-->[X],{number(X)}. 

所以,舉例來說:

?- robot([0,0,n],[go, 10, turn, left,turn,left, go, 20],K).
K = [-10, 0, s]

+1

應該不是'POL的一個稱之爲 - >【轉],[右],pol.'線實際上是'pol-- > [轉],[左],pol'? – BretC

+0

謝謝,通過重寫錯誤(在Prolog中,我有不同語言的公式)。 –

回答

3

不知道這是否會有所幫助,但我會用DGC打造條款的代表名單自然語言,然後處理這些條款。

例如,如果您下面的參數添加到您的語法......

pol([move(X)])-->[go],num(X). 
pol([move(X) | T])-->[go],num(X),pol(T). 
pol([turn(left)])-->[turn],[left]. 
pol([turn(left) | T])-->[turn],[left],pol(T). 
pol([turn(right)])-->[turn],[right]. 
pol([turn(right) | T])-->[turn],[right],pol(T). 
num(D)-->[D],{number(D)}. 

...現在你可以得到「命令」列表,例如...

4 ?- pol(X, [go,10,turn,left,go,10], []). 
X = [move(10), turn(left), move(10)] . 

所以這是分析一下,現在你需要編寫的條款來處理模擬,例如...

% Parses grammar and processes commands 
robot(SENTANCE, XOut, YOut) :- 
    % Parse the sentance 
    pol(COMMANDS, SENTANCE, []), 
    % Process the commands 
    process(COMMANDS, north, 0, 0, XOut, YOut). 

% process(COMMAND_LIST, HEADING, XSTART, YSTART, XOUT, YOUT) 

% Case 1: No commands to process, return current position 
process([], _, X, Y, X, Y). 
% Case 2: Process a single command then process the rest of the commands 
process([COMMAND | T], Heading, XIn, YIn, XOut, YOut) :- 
    do_command(COMMAND, Heading, XIn, YIn, HeadingTmp, XTmp, YTmp), 
    process(T, HeadingTmp, XTmp, YTmp, XOut, YOut). 

% do_command(COMMAND, HEADING_START, XSTART, YSTART, HEADING_OUT, XOUT, YOUT). 
% Move in current direction command 
do_command(move(N), Heading, X, Y, Heading, XOut, YOut) :- 
    x_delta(Heading, N, XDelta), 
    y_delta(Heading, N, YDelta), 
    XOut is X + XDelta, 
    YOut is Y + YDelta. 
% Turn command 
do_command(turn(Dir), HeadingIn, X, Y, HeadingOut, X, Y) :- 
    turn(HeadingIn, Dir, HeadingOut). 

% Utility clauses to help with deltas + turns 
x_delta(north, _, 0). 
x_delta(south, _, 0). 
x_delta(east, X, X). 
x_delta(west, X, Y) :- Y is -X. 

y_delta(north, X, X). 
y_delta(south, X, Y) :- Y is -X. 
y_delta(east, _, 0). 
y_delta(west, _, 0). 

turn(north, right, east). 
turn(east, right, south). 
turn(south, right, west). 
turn(west, right, north). 

turn(north, left, west). 
turn(east, left, north). 
turn(south, left, east). 
turn(west, left, south). 

示例輸出...

2 ?- robot([go, 10, turn, left, go, 11], X, Y). 
X = -11, 
Y = 10 
+0

您可以修改它以傳入開始座標和標題 - 最好將它表示爲「狀態」構造,而不是X,Y和標題的三個獨立變量,即狀態(0,-2,東)'或者其他東西 – BretC

+0

嗨,謝謝你的建議,我非常感謝。我只是認爲我只能通過編寫語法部分來解決這個任務,沒有任何幫助函數:)再次感謝! –

2

我會應用每一個動作來改變當前狀態,獲得更新狀態。

pol(Curr,Curr) --> []. 
pol(Curr,Last) --> move(Curr,Next), pol(Next, Last). 

move(s(X,Y,D), s(X1,Y1,D)) --> 
    [go, N], { 
    D == n -> X1 is X, Y1 is Y+N 
    ;D == e -> X1 is X-N, Y1 is Y 
    ... 
    }. 

move(s(X,Y,D), s(X,Y,D1)) --> 
    [turn, left], { D == n -> D1 = e ; ... }. 

和將與短語/ 2

?- phrase(pol(s(0,0,n),F), [go,10]). 
+0

謝謝,這很好:) –