diff --git a/polymani.pl b/polymani.pl index 8f9eac1..e9e65ce 100644 --- a/polymani.pl +++ b/polymani.pl @@ -37,19 +37,23 @@ * NLP * *******************************/ +debug_print(false). + %% polyplay() is det % % Interactive prompt for the NLP Interface % polyplay :- prompt(OldPrompt, '> '), - read_string(user_input, "\n", "\r\t ", _, In), + read_line_to_codes(user_input, InCodes), + %% read_string(user_input, "\n", "\r\t ", _, In), prompt(_, OldPrompt), - split_string(In, " ", "", LS), - maplist(atom_string, LA, LS), + split_string(InCodes, " ", "\r\t", LS), + maplist(name, LA, LS), ( LA == [bye], write("See ya"), + nl, ! ; ( @@ -59,69 +63,91 @@ polyplay :- writeln("I didn't understand what you want."), writeln(NC) ; - process_input(TIn) + ( + debug_print(true), + write(LA), + nl, + write(TIn), + nl + ; + process_input(TIn) + ) ) ; writeln("I didn't understand what you want.") ), - polyplay + polyplay ), !. -%process_input(show(P, void)) :- -% P \== void, -% polynomial_store(P, T), -% write(P), -% write(" = "), -% print_polynomial_tree(T), -% nl. -process_input(command(C1, C2)) :- - process_input(C1), - process_input(C2). -process_input(show_stored_polynomials) :- - findall(nm(X,Y), polynomial_store(X,Y),D), +process_input(command(CL, void)) :- + do_process_input(CL). +process_input(command(CL, TCR)) :- + %% Process first command + do_process_input(CL), + %% If there's a tree on the right + TCR \== void, + %% recurse + process_input(TCR). + +do_process_input(show_stored_polynomials) :- + findall(nm(X,Y), polynomial_store(X,Y), D), nlp_print_memory(D). -process_input(show(P, T)) :- +do_process_input(show(load(P), void)) :- + P \== void, + ( + polynomial_store(P, T), + write(P), + write(" = "), + print_polynomial_tree(T), + nl + ; + write("Variable not stored"), + nl + ). +do_process_input(show(P, T)) :- P \== void, T \== void, write(P), write(" = "), print_polynomial_tree(T), nl. -process_input(show(void, T)) :- +do_process_input(show(void, T)) :- T \== void, print_polynomial_tree(T), nl. -process_input(store(P, T)) :- +do_process_input(store(P, T)) :- assertz(polynomial_store(P, T)), write(P), write(" = "), print_polynomial_tree(T), nl. -process_input(forget(P)) :- +do_process_input(forget(P)) :- retract(polynomial_store(P,_)). -process_input(simplify(P)) :- +do_process_input(simplify(P)) :- polynomial_tree_to_polynomial(P, PP), simpoly(PP, SP), write(SP), nl. -process_input(op(Op, TL, TR)) :- - process_input(simplify(op(Op, TL, TR))). +%% do_process_input(T) :- +%% %% Empty command, assume simplfiy +%% do_process_input(simplify(T)). print_polynomial_tree(op(Op, TL, TR)) :- + !, write(TL), write(Op), + TR \== void, print_polynomial_tree(TR). print_polynomial_tree(T) :- write(T). polynomial_tree_to_polynomial(A,B) :- polynomial_tree_to_atomic_polynomial(A,Pa), - term_to_atom(B, Pa). + name(B, Pa). polynomial_tree_to_atomic_polynomial(load(L), P) :- polynomial_store(L, P). - polynomial_tree_to_atomic_polynomial(op(Op, TL, TR), P) :- polynomial_tree_to_atomic_polynomial(TL,A), polynomial_tree_to_atomic_polynomial(TR,B), @@ -166,7 +192,8 @@ special_word_number(ninety, 90, fy). special_word_number(hundred, 100, xfy). special_word_number(thousand, 1000, xfy). special_word_number(million, 1000000, xfy). -special_word_number(IC, IC, _) :- number(IC). +%% NOTE This does not belong here. The time wasted on this... Don't put this here +%% special_word_number(IC, IC, _) :- number(IC). %% nlp_number(?W:Atom, ?D:Int) is det % @@ -207,12 +234,15 @@ parse_number_explicit(_, T, T, [], []) :- !. parse_number(T, SL, NC) :- - parse_number_explicit(void, void, T1, SL, NC), - polynomial_tree_to_polynomial(T1, PP), - simpoly(PP, T). + parse_number_explicit(void, void, T, SL, NC). + %% NOTE This is not supposed to be here. + %% polynomial_tree_to_polynomial(T1, PP), + %% simpoly(PP, T2). %% Tests: %% ?- parse_number(T, [two], _). %@ T = 2. +%% ?- parse_number(T, [43], _). +%@ T = 43. %% ?- parse_number(T, [nineteen, two], _). %@ false. %% ?- parse_number(T, [twenty], _). @@ -271,14 +301,30 @@ parse_operation(+) --> [plus]. parse_operation(*) --> [times]. parse_polynomial_operand(T) --> parse_number(T). +parse_polynomial_operand(N) --> [N], { number(N), ! }. parse_polynomial_operand(T) --> parse_power(T). -parse_polynomial_operand(T) --> parse_stored_variable(T). +%% parse_polynomial_operand(T) --> parse_stored_variable(T). +%% Tests: +%% ?- parse_polynomial_operand(N, [3], _). +%@ N = 3. :- dynamic polynomial_store/2. -parse_stored_variable(P) --> %% NOTE Not sure if it's better to load now or later - [load(P)], - { polynomial_store(P, _) }. +parse_stored_variable(P) --> + [P], + { + atom_codes(P, L), + cons(F, R, L), + code_type(F, prolog_var_start), + maplist(code_type_swap(prolog_identifier_continue), R) + }. +%% Tests: +%% ?- parse_stored_variable(P, ['P1'], _). +%@ P = 'P1'. +%% ?- parse_stored_variable(P, ['x1'], _). +%@ false. + +code_type_swap(X, Y) :- code_type(Y, X). parse_polynomial_variable(B) --> [B], @@ -289,6 +335,8 @@ parse_polynomial(T, NC, NC) :- !. parse_polynomial(T) --> parse_polynomial_explicit(_-_, T). +parse_polynomial(T) --> + parse_stored_variable(T). parse_polynomial_explicit(void-_, T) --> parse_polynomial_operand(TL), @@ -337,33 +385,38 @@ parse_polynomial_explicit(void-_, T) --> %@ 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_polynomial(T, [2, plus, 3, plus, 1, times, y], _). +%@ T = op(+, op(+, 2, 3), op(*, 1, y)). parse_command(show_stored_polynomials) --> [show, stored, polynomials]. -parse_command(store(P, T)) --> +parse_command(command(show(P, T), + command(store(P, T), + void))) --> [show], parse_polynomial(T), [as], - [P]. + parse_stored_variable(P). parse_command(forget(P)) --> [forget], - [P]. + parse_stored_variable(P). +parse_command(show(load(P), void)) --> + [show], + parse_stored_variable(P). parse_command(show(void, T)) --> %% NOTE Probably easier if the tree is always binary [show], - parse_polynomial(T). -parse_command(show(P, void)) --> - [show], - [P]. + parse_polynomial(T), + { nonvar(T) }. parse_command(store(P, T)) --> [let], - [P], + parse_stored_variable(P), [be], parse_polynomial(T). parse_command(store(P, T)) --> [store], parse_polynomial(T), [as], - [P]. + parse_stored_variable(P). parse_command(simplify(T)) --> [simplify], parse_polynomial(T). @@ -377,16 +430,20 @@ parse_command(op(+, TN, TP)) --> parse_polynomial(TN), [with], parse_polynomial(TP). +%% Tests: +%% ?- parse_command(T, [show, 3], NC). +%@ T = show(void, 3), +%@ NC = []. parse_input(command(TCL, TCR)) --> parse_command(TCL), [and], !, parse_input(TCR). -parse_input(TC) --> +parse_input(command(TC, void)) --> parse_command(TC). -parse_input(void, [], _). - +%% ?- parse_input(CT, [show, 3], _). +%@ CT = command(show(void, 3), void). %% nlp_print_memory % @@ -431,6 +488,9 @@ simpoly(P, S) :- is_polynomial_valid_in_predicate(P, "simpoly"), simplify_polynomial(P, S), !. +%% Tests: +%% ?- simpoly(2+2+1*y, S). +%@ S = y+4. /* scalepoly/3 multiplies a polynomial represented as an expression by a scalar @@ -910,7 +970,7 @@ simplify_polynomial(P, P2) :- % % Simplifies a polynomial represented as a list. % -simplify_polynomial_as_list(L, L13) :- +simplify_polynomial_as_list(L, L14) :- %% Convert each term to a list maplist(term_to_list, L, L2), %% Sort each sublist so that the next @@ -941,12 +1001,16 @@ simplify_polynomial_as_list(L, L13) :- ; %% Otherwise, this is the result L13 = L12 - ). + ), + %% Further make sure all terms are simplified + maplist(simplify_term, L13, L14). %% Tests: %% ?- simplify_polynomial_as_list([x, 1, x^2, x*y, 3*x^2, 4*x], L). %@ L = [1, 4*x^2, 5*x, x*y] . %% ?- simplify_polynomial_as_list([1, x^2, x*y, 3*x^2, -4, -1*x], L). %@ L = [-3, -1*x, 4*x^2, x*y] . +%% ?- simplify_polynomial_as_list([1, 1*x], L). +%@ L = [1, x] . %% ?- simplify_polynomial_as_list([0*x, 0], L). %@ L = [0] .