Link everything properly and some small improvements
This commit is contained in:
parent
047d6b9a4b
commit
0dfe64e740
282
polymani.pl
282
polymani.pl
@ -152,177 +152,145 @@ is_number_in_predicate(C, F) :-
|
||||
write(C),
|
||||
fail.
|
||||
|
||||
/*******************************
|
||||
* NLP *
|
||||
*******************************/
|
||||
|
||||
/* DCG */
|
||||
separator --> ["and"].
|
||||
separator --> ["by"].
|
||||
|
||||
command --> ["show"].
|
||||
command --> ["multiply"].
|
||||
command --> ["simplify"].
|
||||
command --> ["add"].
|
||||
command --> ["forget"].
|
||||
expression(A,B,C):-writeln("oi"),writeln(A),writeln(B),writeln(C),writeln("bye").
|
||||
instruction(Left_expr, Right_expr) --> command, expression(Left_expr), separator, expression(Right_expr).
|
||||
|
||||
%% polyplay() is det
|
||||
%
|
||||
% Interactive prompt for the NLP Interface
|
||||
%
|
||||
polyplay :-
|
||||
write("> "),
|
||||
read_string(user_input, "\n", "\r\t ", _, Stdin),
|
||||
split_string(Stdin, " ", "", R),
|
||||
string_lower(Stdin, Stdin_lower),
|
||||
split_string(Stdin_lower, " ", "", LS),
|
||||
list_of_strings_to_list_of_atoms(LS, R),
|
||||
(
|
||||
R == ["bye"],
|
||||
write("See ya"),
|
||||
!
|
||||
R == [bye],
|
||||
write("See ya"),
|
||||
!
|
||||
;
|
||||
(
|
||||
nlp_understand(R, P, I),
|
||||
writeln("That's trivial:"),
|
||||
nlp_compute(P, I)
|
||||
;
|
||||
writeln("I didn't understand what you want.")
|
||||
),
|
||||
nlp_handler(R, Z),
|
||||
writeln(Z)
|
||||
;
|
||||
writeln("I didn't understand what you want.")
|
||||
),
|
||||
polyplay
|
||||
),
|
||||
!.
|
||||
|
||||
nlp_understand(R, P, I) :-
|
||||
(
|
||||
R == ["simplify", "x", "squared"],
|
||||
P = simplify,
|
||||
I = x^2
|
||||
;
|
||||
fail
|
||||
).
|
||||
/*******************************
|
||||
* NLP *
|
||||
*******************************/
|
||||
|
||||
nlp_compute(simplify, P) :-
|
||||
!,
|
||||
simplify_polynomial(P, O),
|
||||
writeln(O).
|
||||
nlp_compute(_,_) :-
|
||||
fail.
|
||||
%% nlp_number(?W:Atom, ?D:Int) is det
|
||||
%
|
||||
% Definition of a Alphabetical and Numerical relation
|
||||
%
|
||||
nlp_number(zero, 0).
|
||||
nlp_number(one, 1).
|
||||
nlp_number(two, 2).
|
||||
nlp_number(three, 3).
|
||||
nlp_number(four, 4).
|
||||
nlp_number(five, 5).
|
||||
nlp_number(six, 6).
|
||||
nlp_number(seven, 7).
|
||||
nlp_number(eight, 8).
|
||||
nlp_number(nine, 9).
|
||||
nlp_number(ten, 10).
|
||||
|
||||
special_word_number(zero, 0, f).
|
||||
special_word_number(a, 1, f).
|
||||
special_word_number(one, 1, f).
|
||||
special_word_number(two, 2, f).
|
||||
special_word_number(three, 3, f).
|
||||
special_word_number(four, 4, f).
|
||||
special_word_number(five, 5, f).
|
||||
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(twenty, 20, fy).
|
||||
special_word_number(thirty, 30, fy).
|
||||
special_word_number(forty, 40, fy).
|
||||
special_word_number(fifty, 50, fy).
|
||||
special_word_number(sixty, 60, fy).
|
||||
special_word_number(seventy, 70, fy).
|
||||
special_word_number(eighty, 80, fy).
|
||||
special_word_number(ninety, 90, fy).
|
||||
special_word_number(hundred, 100, xfy).
|
||||
special_word_number(thousand, 1000, xfy).
|
||||
special_word_number(million, 1000000, xfy).
|
||||
%% nlp_get_number_from_string(+X:String, -D:Int) is det
|
||||
%
|
||||
% Get number from string graciously
|
||||
%
|
||||
nlp_get_number_from_string(X, Z) :- nlp_number(X, Z), !.
|
||||
nlp_get_number_from_string(X, X).
|
||||
|
||||
parse_number(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) :-
|
||||
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) :-
|
||||
special_word_number(WN, N, xfy),
|
||||
TL \= void,
|
||||
parse_number(op(*, TL, N), T, R, NC),
|
||||
!.
|
||||
parse_number(TL, T, [and, WN | R], NC) :-
|
||||
special_word_number(WN, _, _),
|
||||
parse_number(TL, T, [WN | R], NC),
|
||||
!.
|
||||
parse_number(T, T, [WN | R], [WN | R]) :-
|
||||
T \= void,
|
||||
not(special_word_number(WN, _, _)),
|
||||
!.
|
||||
parse_number(T, T, [], []) :-
|
||||
T \= void,
|
||||
!.
|
||||
%% Tests:
|
||||
%% ?- parse_number(void, 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], _).
|
||||
%@ false.
|
||||
%% ?- parse_number(void, T, [three, hundred], _).
|
||||
%@ T = op(*, 3, 100).
|
||||
%% ?- parse_number(void, T, [twenty, hundred], _).
|
||||
%@ T = op(*, 20, 100).
|
||||
%% ?- parse_number(void, T, [twenty, one, hundred], _).
|
||||
%@ T = op(*, op(+, 20, 1), 100).
|
||||
%% ?- parse_number(void, T, [two, hundred, and, one], _).
|
||||
%@ T = op(+, op(*, 2, 100), 1).
|
||||
%% ?- parse_number(void, 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).
|
||||
%@ 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).
|
||||
%@ T = op(*, op(+, 20, 1), 100),
|
||||
%@ NC = [and, bleg, twenty, quux, one, foo, bar].
|
||||
%% ?- parse_number(void, T, [two, hundred, thousand], _).
|
||||
%@ T = op(*, op(*, 2, 100), 1000).
|
||||
%% ?- parse_number(void, 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).
|
||||
%@ false.
|
||||
%% nlp_parse_numbers(?List, ?List) is det
|
||||
%
|
||||
% Parse numbers
|
||||
%
|
||||
nlp_parse_numbers([H|T], [N|U]) :- nlp_get_number_from_string(H, N), nlp_parse_numbers(T, U).
|
||||
nlp_parse_numbers([], []).
|
||||
|
||||
operations(times, *).
|
||||
operations(plus, +).
|
||||
%% nlp_parse_power(?List, ?List) is det
|
||||
%
|
||||
% Parse powers
|
||||
%
|
||||
nlp_parse_power([X, raised, to, Y | T], [K|NewT]) :-
|
||||
number(X),
|
||||
number(Y),
|
||||
K is X ** Y,
|
||||
nlp_parse_power(T, NewT),
|
||||
!.
|
||||
nlp_parse_power([X, raised, to, Y | T], [X^Y|NewT]) :-
|
||||
number(X),
|
||||
nlp_parse_power(T, NewT),
|
||||
!.
|
||||
nlp_parse_power([X, raised, to, Y | T], Z) :-
|
||||
poly2list(X^Y, K),
|
||||
nlp_parse_power(T, NewT),
|
||||
append(K, NewT, Z),
|
||||
!.
|
||||
nlp_parse_power([X, squared | T], Z) :-
|
||||
number(X),
|
||||
A is X**2,
|
||||
nlp_parse_power([A|T], Z),
|
||||
!.
|
||||
nlp_parse_power([X, squared | T], [X^2|Z]) :-
|
||||
nlp_parse_power(T, Z),
|
||||
!.
|
||||
nlp_parse_power([H|T], [H|Z]) :-
|
||||
nlp_parse_power(T, Z).
|
||||
nlp_parse_power([], []).
|
||||
|
||||
parse_operation(Op) --> [WOp], { operations(WOp, Op) }.
|
||||
%% nlp_parse_multiplication(?List, ?List) is det
|
||||
%
|
||||
% Parse multiplication
|
||||
%
|
||||
nlp_parse_multiplication([X, times, Y | T], Z) :-
|
||||
simpoly(X*Y, A),
|
||||
nlp_parse_multiplication([A|T], Z),
|
||||
!.
|
||||
nlp_parse_multiplication([multiply, X, by, Y | T], Z) :-
|
||||
simpoly(X*Y, A),
|
||||
nlp_parse_multiplication([A|T], Z),
|
||||
!.
|
||||
nlp_parse_multiplication([H|T], [H|Z]) :-
|
||||
nlp_parse_multiplication(T, Z).
|
||||
nlp_parse_multiplication([], []).
|
||||
|
||||
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 }.
|
||||
%% Tests:
|
||||
%% ?- parse_expression(T, [], _).
|
||||
%@ false.
|
||||
%% ?- parse_expression(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], _).
|
||||
%@ T = op(*, 2, 3).
|
||||
%@ T = op(*, 2, op(+, 3, 2)).
|
||||
%% ?- parse_expression(T, [two, times, times, two], _).
|
||||
%@ false.
|
||||
%% nlp_parse_sum(?List, ?List)
|
||||
%
|
||||
% Parse sums
|
||||
%
|
||||
nlp_parse_sum([X, plus, Y|T], Z) :-
|
||||
simpoly(X+Y, A),
|
||||
nlp_parse_sum([A|T], Z),
|
||||
!.
|
||||
nlp_parse_sum([H|T], [H|Z]) :-
|
||||
nlp_parse_sum(T, Z).
|
||||
nlp_parse_sum([], []).
|
||||
|
||||
%% list_of_atoms_to_list_of_strings(+List, -List) is det
|
||||
%
|
||||
% Converts a list of strings to a list of atoms
|
||||
%
|
||||
list_of_strings_to_list_of_atoms([H|T], [N|U]) :- string_to_atom(H,N), list_of_strings_to_list_of_atoms(T,U).
|
||||
list_of_strings_to_list_of_atoms([],[]).
|
||||
|
||||
%polynomial_variable_from_string(A, B) :- polynomial_variable(B),string_to_atom(A,B).
|
||||
%nlp_parse_poly_vars([H|T], [N|U]) :- (polynomial_variable_from_string(H, N);H=N), nlp_parse_poly_vars(T, U),!.
|
||||
%nlp_parse_poly_vars([], []).
|
||||
|
||||
nlp_parse(L, Z) :- nlp_parse_numbers(L, A), nlp_parse_power(A, B), nlp_parse_multiplication(B, C), nlp_parse_sum(C, Z).
|
||||
|
||||
%% nlp_handler(+L:List, -Z:String) is det
|
||||
%
|
||||
% Takes the user's request and returns the result in a pretty string.
|
||||
%
|
||||
nlp_handler([simplify|L], Z) :-
|
||||
nlp_parse(L,[Z]).
|
||||
nlp_handler(L, Z) :-
|
||||
nlp_parse(L, [Z]).
|
||||
|
||||
/*******************************
|
||||
* BACKEND *
|
||||
@ -740,8 +708,8 @@ simplify_polynomial_as_list(L, L13) :-
|
||||
%% Sort list converting back gives the result in the correct order
|
||||
sort(0, @=<, L11, L12),
|
||||
(
|
||||
%% If the list is empty, the result is a list with 0
|
||||
L12 = [], L13 = [0]
|
||||
%% If the list is empty, the result is a list with 0
|
||||
L12 = [], L13 = [0]
|
||||
;
|
||||
%% Otherwise, this is the result
|
||||
L13 = L12
|
||||
|
Reference in New Issue
Block a user