Link everything properly and some small improvements

This commit is contained in:
Diogo Cordeiro 2018-12-17 04:22:12 +00:00
parent 047d6b9a4b
commit 0dfe64e740
1 changed files with 125 additions and 157 deletions

View File

@ -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