所以我有這樣的數學語言,它是這樣的:定義的數學語言在序言
E -> number
[+,E,E,E] //e.g. [+,1,2,3] is 1+2+3 %we can put 2 to infinite Es here.
[-,E,E,E] //e.g. [-,1,2,3] is 1-2-3 %we can put 2 to infinite Es here.
[*,E,E,E] //e.g. [*,1,2,3] is 1*2*3 %we can put 2 to infinite Es here.
[^,E,E] //e.g. [^,2,3] is 2^3
[sin,E] //e.g. [sin,0] is sin 0
[cos,E] //e.g. [cos,0] is cos 0
,我想寫找到一個數學表達式由該語言編寫的數值設定的規則在序言中。
我第一次寫了一個名爲「檢查」功能,它會檢查根據語言如果該列表是用正確的方式有:
check1([]).
check1([L|Ls]):- number(L),check1(Ls).
check([L|Ls]):-atom(L),check1(Ls).
現在我需要寫函數「評估「這個表達式是一個用這種語言編寫的表達式,而一個變量是與這種語言相對應的數字值。 例如:
?-evaluate([*,1,[^,2,2],[*,2,[+,[sin,0],5]]]],N) -> N = 40
所以我寫了這個:
sum([],0).
sum([L|Ls],N):- not(is_list(L)),sum(Ls,No),N is No + L.
min([],0).
min([L|Ls],N):-not(is_list(L)), min(Ls,No),N is No - L.
pro([],0).
pro([X],[X]).
pro([L|Ls],N):-not(is_list(L)), pro(Ls,No), N is No * L.
pow([L|Ls],N):-not(is_list(L)), N is L^Ls.
sin_(L,N):-not(is_list(L)), N is sin(L).
cos_(L,N):-not(is_list(L)), N is cos(L).
d([],0).
d([L|Ls],N):- L == '+' ,sum(Ls,N);
L == '-',min(Ls,N);
L == '*',pro(Ls,N);
L == '^',pow(Ls,N);
L == 'sin',sin_(Ls,N);
L == 'cos',cos_(Ls,N).
evaluate([],0).
evaluate([L|Ls],N):-
is_list(L) , check(L) , d(L,N),L is N,evaluate(Ls,N);
is_list(L), not(check(L)) , evaluate(Ls,N);
not(is_list(L)),not(is_list(Ls)),check([L|Ls]),d([L|Ls],N),
L is N,evaluate(Ls,N);
is_list(Ls),evaluate(Ls,N).
,它的工作只是一個列表,並返回正確的答案,但不包括主列表內的多個列表,我的代碼應該怎麼?
如果'檢查(L)'名單上出現故障,應該不是整個謂語簡單地失敗,而比試圖評估一個無效列表?而'not(is_list(Ls))'在語義上可能不是合理的,因爲在這種情況下列表的尾部(在這種情況下爲'Ls')預計總是列表。 – lurker
我不會用這種方式來組織程序,但是考慮到你的方法,你需要做的就是讓每個運算符謂詞遞歸調用到'd/2',並且在遇到任何時候調用'd/2'子目錄(你目前只允許'not(is_list(L))')。 – lurker