Expanded parser and fixed parsing numbers
This commit is contained in:
parent
ea80d57ef9
commit
d7f3a9996b
204
polymani.pl
204
polymani.pl
@ -198,16 +198,16 @@ special_word_number(six, 6, f).
|
||||
special_word_number(seven, 7, f).
|
||||
special_word_number(eight, 8, f).
|
||||
special_word_number(nine, 9, f).
|
||||
special_word_number(ten, 10, f).
|
||||
special_word_number(eleven, 11, f).
|
||||
special_word_number(twelve, 12, f).
|
||||
special_word_number(thirteen, 13, f).
|
||||
special_word_number(fourteen, 14, f).
|
||||
special_word_number(fifteen, 15, f).
|
||||
special_word_number(sixteen, 16, f).
|
||||
special_word_number(seventeen, 17, f).
|
||||
special_word_number(eighteen, 18, f).
|
||||
special_word_number(nineteen, 19, f).
|
||||
special_word_number(ten, 10, g).
|
||||
special_word_number(eleven, 11, g).
|
||||
special_word_number(twelve, 12, g).
|
||||
special_word_number(thirteen, 13, g).
|
||||
special_word_number(fourteen, 14, g).
|
||||
special_word_number(fifteen, 15, g).
|
||||
special_word_number(sixteen, 16, g).
|
||||
special_word_number(seventeen, 17, g).
|
||||
special_word_number(eighteen, 18, g).
|
||||
special_word_number(nineteen, 19, g).
|
||||
special_word_number(twenty, 20, fy).
|
||||
special_word_number(thirty, 30, fy).
|
||||
special_word_number(forty, 40, fy).
|
||||
@ -220,64 +220,76 @@ special_word_number(hundred, 100, xfy).
|
||||
special_word_number(thousand, 1000, xfy).
|
||||
special_word_number(million, 1000000, xfy).
|
||||
|
||||
parse_number(void, T, [WN | R], NC) :-
|
||||
parse_number_explicit(void, void, T, [WN | R], NC) :-
|
||||
special_word_number(WN, N, P),
|
||||
member(P, [f, fy]),
|
||||
parse_number(N, T, R, NC),
|
||||
!.
|
||||
parse_number(TL, T, [WN | R], NC) :-
|
||||
member(P, [f, g, fy]),
|
||||
!,
|
||||
parse_number_explicit(P, N, T, R, NC).
|
||||
parse_number_explicit(fy, NL, T, [WN | R], NC) :-
|
||||
special_word_number(WN, N, f),
|
||||
!,
|
||||
parse_number_explicit(P, op(+, NL, N), T, R, NC).
|
||||
parse_number_explicit(xfy, TL, T, [WN | R], NC) :-
|
||||
TL \= void,
|
||||
special_word_number(WN, N, P),
|
||||
member(P, [f, fy]),
|
||||
parse_number(op(+, TL, N), T, R, NC),
|
||||
!.
|
||||
parse_number(TL, T, [WN | R], NC) :-
|
||||
member(P, [f, g, fy]),
|
||||
!,
|
||||
parse_number_explicit(P, op(+, TL, N), T, R, NC).
|
||||
parse_number_explicit(P, TL, T, [WN | R], NC) :-
|
||||
special_word_number(WN, N, xfy),
|
||||
TL \= void,
|
||||
parse_number(op(*, TL, N), T, R, NC),
|
||||
!.
|
||||
parse_number(TL, T, [and, WN | R], NC) :-
|
||||
!,
|
||||
parse_number_explicit(xfy, op(*, TL, N), T, R, NC).
|
||||
parse_number_explicit(P, TL, T, [and, WN | R], NC) :-
|
||||
special_word_number(WN, _, _),
|
||||
parse_number(TL, T, [WN | R], NC),
|
||||
parse_number_explicit(P, TL, T, [WN | R], NC),
|
||||
!.
|
||||
parse_number(T, T, [WN | R], [WN | R]) :-
|
||||
parse_number_explicit(_, T, T, [WN | R], [WN | R]) :-
|
||||
T \= void,
|
||||
not(special_word_number(WN, _, _)),
|
||||
!.
|
||||
parse_number(T, T, [], []) :-
|
||||
parse_number_explicit(_, T, T, [], []) :-
|
||||
T \= void,
|
||||
!.
|
||||
|
||||
parse_number(T, SL, NC) :-
|
||||
parse_number_explicit(void, void, T, SL, NC).
|
||||
%% Tests:
|
||||
%% ?- parse_number(void, T, [two], _).
|
||||
%% ?- parse_number(T, [two], _).
|
||||
%@ T = 2.
|
||||
%% ?- parse_number(void, T, [twenty], _).
|
||||
%@ T = 20.
|
||||
%% ?- parse_number(void, T, [twenty, one], _).
|
||||
%@ T = op(+, 20, 1).
|
||||
%% ?- parse_number(void, T, [hundred], _).
|
||||
%% ?- parse_number(T, [nineteen, two], _).
|
||||
%@ false.
|
||||
%% ?- parse_number(void, T, [three, hundred], _).
|
||||
%% ?- parse_number(T, [twenty], _).
|
||||
%@ T = 20.
|
||||
%% ?- parse_number(T, [twenty, twenty], _).
|
||||
%@ false.
|
||||
%% ?- parse_number(T, [twenty, one], _).
|
||||
%@ T = op(+, 20, 1).
|
||||
%% ?- parse_number(T, [hundred], _).
|
||||
%@ false.
|
||||
%% ?- parse_number(T, [three, hundred], _).
|
||||
%@ T = op(*, 3, 100).
|
||||
%% ?- parse_number(void, T, [twenty, hundred], _).
|
||||
%% ?- parse_number(T, [twenty, hundred], _).
|
||||
%@ T = op(*, 20, 100).
|
||||
%% ?- parse_number(void, T, [twenty, one, hundred], _).
|
||||
%% ?- parse_number(T, [twenty, one, hundred], _).
|
||||
%@ T = op(*, op(+, 20, 1), 100).
|
||||
%% ?- parse_number(void, T, [two, hundred, and, one], _).
|
||||
%% ?- parse_number(T, [two, hundred, and, one], _).
|
||||
%@ T = op(+, op(*, 2, 100), 1).
|
||||
%% ?- parse_number(void, T, [twenty, one, hundred, and, twenty, one], _).
|
||||
%% ?- parse_number(T, [twenty, one, hundred, and, twenty, one], _).
|
||||
%@ T = op(+, op(+, op(*, op(+, 20, 1), 100), 20), 1).
|
||||
%% ?- parse_number(void, T, [twenty, one, hundred, and, twenty, one, foo, bar, blah], NC).
|
||||
%% ?- parse_number(T, [twenty, one, hundred, and, twenty, one, foo, bar, blah], NC).
|
||||
%@ T = op(+, op(+, op(*, op(+, 20, 1), 100), 20), 1),
|
||||
%@ NC = [foo, bar, blah].
|
||||
%% ?- parse_number(void, T, [twenty, one, hundred, and, bleg, twenty, quux, one, foo, bar], NC).
|
||||
%% ?- parse_number(T, [twenty, one, hundred, and, bleg, twenty, quux, one, foo, bar], NC).
|
||||
%@ T = op(*, op(+, 20, 1), 100),
|
||||
%@ NC = [and, bleg, twenty, quux, one, foo, bar].
|
||||
%% ?- parse_number(void, T, [two, hundred, thousand], _).
|
||||
%% ?- parse_number(T, [two, hundred, thousand], _).
|
||||
%@ T = op(*, op(*, 2, 100), 1000).
|
||||
%% ?- parse_number(void, T, [twenty, one, hundred, thousand], _).
|
||||
%% ?- parse_number(T, [twenty, one, hundred, thousand], _).
|
||||
%@ T = op(*, op(*, op(+, 20, 1), 100), 1000).
|
||||
%% ?- parse_number(void, T, [thirty, five, million], _).
|
||||
%@ T = op(*, op(+, 30, 5), 1000000).
|
||||
%% ?- parse_number(void, T, [foo, five, million], NC).
|
||||
%% ?- parse_number(T, [thirty, five, million, five, hundred, thirty, four], _).
|
||||
%@ T = op(+, op(+, op(*, op(+, op(*, op(+, 30, 5), 1000000), 5), 100), 30), 4).
|
||||
%% ?- parse_number(T, [foo, five, million], NC).
|
||||
%@ false.
|
||||
|
||||
operations(times, *).
|
||||
@ -285,27 +297,99 @@ operations(plus, +).
|
||||
|
||||
parse_operation(Op) --> [WOp], { operations(WOp, Op) }.
|
||||
|
||||
parse_expression(TLP-TL, op(Op, TLP-TL, TR)) --> parse_number(void, TL),
|
||||
parse_operation(Op),
|
||||
parse_expression(op(Op, TL, TRP)-TRP, TR).
|
||||
parse_expression(void, T) --> parse_number(void, T), { T \= void }.
|
||||
parse_expression(TL, TL-TR) --> parse_number(void, TR), { TR \= void, TL \= void }.
|
||||
parse_polynomial_operand(T) --> parse_number(T).
|
||||
parse_polynomial_operand(T) --> parse_power(T).
|
||||
parse_polynomial_operand(T) --> parse_stored_variable(T).
|
||||
|
||||
parse_stored_variable(op(load, P, void)) --> %% NOTE Not sure if it's better to load now or later
|
||||
[P],
|
||||
polynomial_store(P, T).
|
||||
|
||||
parse_polynomial_variable(B) -->
|
||||
[B],
|
||||
{ polynomial_variable(B) }.
|
||||
|
||||
%% Order matters
|
||||
parse_power(op(^, TB, 2)) -->
|
||||
parse_polynomial_variable(TB),
|
||||
[squared].
|
||||
parse_power(op(^, TB, 3)) -->
|
||||
parse_polynomial_variable(TB),
|
||||
[cubed].
|
||||
parse_power(op(^, TB, TN)) -->
|
||||
parse_polynomial_variable(TB),
|
||||
[raised, to],
|
||||
parse_number(TN).
|
||||
parse_power(TB) -->
|
||||
parse_polynomial_variable(TB).
|
||||
|
||||
parse_polynomial(void-_, T) -->
|
||||
parse_polynomial_operand(TL),
|
||||
parse_operation(Op),
|
||||
!,
|
||||
parse_polynomial(op(Op, TL, TRP)-TRP, T).
|
||||
parse_polynomial(TLP-TL, T) -->
|
||||
parse_polynomial_operand(TL),
|
||||
parse_operation(+),
|
||||
!,
|
||||
parse_polynomial(op(+, TLP, TRP)-TRP, T).
|
||||
parse_polynomial(TLP-T, TLP) -->
|
||||
parse_polynomial_operand(TL),
|
||||
parse_operation(*),
|
||||
!,
|
||||
parse_polynomial(op(*, TL, TRP)-TRP, T).
|
||||
parse_polynomial(TLP-TL, TLP) -->
|
||||
{ TLP \= void },
|
||||
parse_polynomial_operand(TL),
|
||||
!,
|
||||
{ TL \= void }.
|
||||
parse_polynomial(void-_, T) -->
|
||||
parse_polynomial_operand(T), { T \= void }.
|
||||
%% Tests:
|
||||
%% ?- parse_expression(T, [], _).
|
||||
%% ?- parse_polynomial(_-_, T, [], _).
|
||||
%@ false.
|
||||
%% ?- parse_expression(T, [two], _).
|
||||
%% ?- parse_polynomial(_-_, T, [two], _).
|
||||
%@ T = 2.
|
||||
%% ?- parse_expression(void, T, [two, times, two], _).
|
||||
%@ T = 2 ;
|
||||
%@ false.
|
||||
%@ T = 2 ;
|
||||
%@ false.
|
||||
%@ T = op(*, 2, 2).
|
||||
%% ?- parse_expression(T, [two, times, three, plus, two], _).
|
||||
%% ?- parse_polynomial(_-_, T, [two, times, three], _).
|
||||
%@ T = op(*, 2, 3).
|
||||
%@ T = op(*, 2, op(+, 3, 2)).
|
||||
%% ?- parse_expression(T, [two, times, times, two], _).
|
||||
%@ false.
|
||||
%% ?- parse_polynomial(_-_, T, [two, times, three, plus, four], _).
|
||||
%@ T = op(+, op(*, 2, 3), 4).
|
||||
%% ?- parse_polynomial(_-_, T, [two, plus, three, times, four], _).
|
||||
%@ T = op(+, 2, op(*, 3, 4)).
|
||||
%% ?- parse_polynomial(_-_, T, [two, plus, three, times, four, plus, six, times, five], _).
|
||||
%@ T = op(+, 2, op(+, op(*, 3, 4), op(*, 6, 5))).
|
||||
%% ?- parse_polynomial(_-_, T, [two, times, times, two], NC); write(NC).
|
||||
%@ _3164
|
||||
%@ true. %% NOTE Potential problem. It seems NC isn't unified with the list, if it fails
|
||||
%% ?- parse_polynomial(_-_, T, [two, plus, x, times, four], _).
|
||||
%@ T = op(+, 2, op(*, x, 4)).
|
||||
%% ?- parse_polynomial(_-_, T, [two, plus, x, times, four, plus, y, raised, to, five], _).
|
||||
%@ T = op(+, 2, op(+, op(*, x, 4), op(^, y, 5))).
|
||||
%% ?- parse_polynomial(_-_, T, [two, plus, two, plus, one, times, y], _).
|
||||
%@ T = op(+, op(+, 2, 2), op(*, 1, y)).
|
||||
|
||||
|
||||
parse_command(op(show, T, void)) --> %% NOTE Probably easier if the tree is always binary
|
||||
[show],
|
||||
parse_polynomial(T).
|
||||
parse_command(op(show, op(store, P, T))) -->
|
||||
[show],
|
||||
parse_polynomial(T),
|
||||
[as],
|
||||
[P].
|
||||
parse_command(op(store, P, T)) -->
|
||||
[let],
|
||||
[P],
|
||||
[be],
|
||||
parse_polynomial(T).
|
||||
parse_command(T) -->
|
||||
[simplify],
|
||||
parse_polynomial(T).
|
||||
parse_command(op(*, TN, TP)) -->
|
||||
[multiply],
|
||||
parse_number(TN),
|
||||
[by],
|
||||
parse_polynomial(TP).
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user