Parsing integer numbers

This commit is contained in:
Hugo Sales 2018-12-09 00:01:22 +00:00
parent 7fd64223fc
commit 75cae0b25f
1 changed files with 114 additions and 34 deletions

View File

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