diff --git a/polymani.pl b/polymani.pl index 16f83e4..307954f 100644 --- a/polymani.pl +++ b/polymani.pl @@ -1,4 +1,4 @@ -%% -*- mode: prolog-*- +%% -*- Mode: Prolog-*- %% vim: set softtabstop=4 shiftwidth=4 tabstop=4 expandtab: /** @@ -187,42 +187,122 @@ nlp_compute(simplify, P) :- nlp_compute(_,_) :- fail. -parse_digit(zero, 0). -parse_digit(one, 1). -parse_digit(two, 2). -parse_digit(three, 3). -parse_digit(four, 4). -parse_digit(five, 5). -parse_digit(six, 6). -parse_digit(seven, 7). -parse_digit(eight, 8). -parse_digit(nine, 9). +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). + +word_tree([W], N) :- + special_word_number(W, N, P), + member(P, [f, fy]). +word_tree([W, W2], op(+, N, N2)) :- + special_word_number(W, N, fy), + special_word_number(W2, N2, f). +word_tree([W, W2], op(*, N, N2)) :- + special_word_number(W, N, P), + member(P, [f, fy]), + special_word_number(W2, N2, xfy). +word_tree([W, W2, W3], op(*, op(+, N, N2), N3)) :- + special_word_number(W, N, fy), + special_word_number(W2, N2, f), + special_word_number(W3, N3, xfy). + +join_trees(Op, L, void, L) :- !. +join_trees(Op, L, R, op(Op, L, R)). +%% ?- join_trees(+, op(+, 3, 2), void, T). +%@ T = op(+, 3, 2). +%% ?- join_trees(+, op(+, 3, 2), op(*, 3, 4), T). +%@ T = op(+, op(+, 3, 2), op(*, 3, 4)). + +parse_number([WN, WN2, WN3 | R], NC, T) :- + parse_number(R, NC, TR), + word_tree([WN, WN2, WN3], TL), + %% Red cut? If we can consume three words, do so + !, + join_trees(+, TL, TR, T). +parse_number([WN, WN2 | R], NC, T) :- + parse_number(R, NC, TR), + word_tree([WN, WN2], TL), + !, + join_trees(+, TL, TR, T). +parse_number([WN | R], NC, T) :- + parse_number(R, NC, TR), + word_tree([WN], TL), + !, + join_trees(+, TL, TR, T). +parse_number([and, WN | R], NC, T) :- + parse_number(R, NC, TR), + word_tree([WN], TL), + !, + join_trees(+, TL, TR, T). +parse_number(R, R, void) :- + not(word_tree(R, _)). +%% Tests: +%% ?- parse_number([two], NC, T). +%@ NC = [], +%@ T = 2. +%% ?- parse_number([twenty], NC, T). +%@ NC = [], +%@ T = 20. +%% ?- parse_number([twenty, one], NC, T). +%@ NC = [], +%@ T = op(+, 20, 1). +%% ?- parse_number([hundred], NC, T). +%@ NC = [hundred], +%@ T = void. +%% ?- parse_number([three, hundred], NC, T). +%@ NC = [], +%@ T = op(*, 3, 100). +%% ?- parse_number([twenty, hundred], NC, T). +%@ NC = [], +%@ T = op(*, 20, 100). +%% ?- parse_number([twenty, one, hundred], NC, T). +%@ NC = [], +%@ T = op(*, op(+, 20, 1), 100). +%% ?- parse_number([two, hundred, and, one], NC, T). +%@ NC = [], +%@ T = op(+, op(*, 2, 100), 1). +%% ?- parse_number([twenty, one, hundred, and, twenty, one], NC, T). +%@ NC = [], +%@ T = op(+, op(*, op(+, 20, 1), 100), op(+, 20, 1)). +%% ?- parse_number([twenty, one, hundred, and, twenty, one, foo, bar, blah], NC, T). +%@ NC = [foo, bar, blah], +%@ T = op(+, op(*, op(+, 20, 1), 100), op(+, 20, 1)). +%% ?- parse_number([twenty, one, hundred, and, bleg, twenty, quux, one, foo, bar, blah], NC, T). +%@ NC = [and, bleg, twenty, quux, one, foo, bar, blah], +%@ T = op(*, op(+, 20, 1), 100). + -parse_digit(ten, 10). -parse_digit(eleven, 11). -parse_digit(twelve, 12). -parse_digit(thirteen, 13). -parse_digit(fourteen, 14). -parse_digit(fifteen, 15). -parse_digit(sixteen, 16). -parse_digit(seventeen, 17). -parse_digit(eighteen, 18). -parse_digit(nineteen, 19). -parse_digit(twenty, 20). -parse_digit(thirty, 30). -parse_digit(forty, 40). -parse_digit(fifty, 50). -parse_digit(sixty, 60). -parse_digit(seventy, 70). -parse_digit(eighty, 80). -parse_digit(ninety, 90). -parse_number([],0). -parse_number([N|L], X) :- - parse_digit(N, X1), - parse_number(L, X2), - X is X1 + X2. /******************************* * BACKEND *