Fixed number parsing
This commit is contained in:
parent
d054989bc0
commit
1232fa0b3c
94
polymani.pl
94
polymani.pl
@ -445,100 +445,100 @@ parse_number_explicit(_, T, T, [], []) :-
|
|||||||
% Parse a floating point number
|
% Parse a floating point number
|
||||||
%
|
%
|
||||||
parse_floating_number(N) -->
|
parse_floating_number(N) -->
|
||||||
{
|
|
||||||
not(compound(N))
|
|
||||||
},
|
|
||||||
[N],
|
[N],
|
||||||
{
|
{ number(N) }.
|
||||||
% Assert it must be between negative and positive infinity
|
|
||||||
% This uses the CLPR library, which makes this reversible,
|
|
||||||
% whereas `number(N)` is always false, since it only succeeds
|
|
||||||
% if the argument is bound (to a integer or float)
|
|
||||||
(N >= 0; N < 0)
|
|
||||||
}.
|
|
||||||
parse_floating_number(op('.', TL, TR)) -->
|
parse_floating_number(op('.', TL, TR)) -->
|
||||||
%% A float is a node with a dot as the operator
|
%% A float is a node with a dot as the operator
|
||||||
%% If there's a number on the left
|
%% If there's a number on the left
|
||||||
parse_number(TL),
|
parse_integer_number(TL),
|
||||||
%% Followed by either point or dot
|
%% Followed by either point or dot
|
||||||
[RadixPoint],
|
[Sep],
|
||||||
{
|
{
|
||||||
member(RadixPoint, [point, dot]),
|
member(Sep, [point, dot]),
|
||||||
!
|
!
|
||||||
},
|
},
|
||||||
%% Followed by another number
|
%% Followed by another number
|
||||||
parse_positive_number(TR).
|
parse_positive_integer_number(TR).
|
||||||
|
parse_floating_number(TN) -->
|
||||||
|
%% Or any integer
|
||||||
|
parse_integer_number(TN).
|
||||||
|
%% Tests:
|
||||||
|
%% ?- parse_floating_number(TN, [two], _).
|
||||||
|
%@ TN = 2.
|
||||||
|
%% ?- parse_floating_number(TN, [two, dot, 4], _).
|
||||||
|
%@ TN = op('.', 2, 4).
|
||||||
|
%% ?- parse_floating_number(TN, [negative, two, dot, 4], _).
|
||||||
|
%@ TN = op('.', op(neg, 2), 4).
|
||||||
|
|
||||||
%% parse_positive_number(-tree, +stream, -not_consumed) is det
|
%% parse_positive_integer_number(-tree, +stream, -not_consumed) is det
|
||||||
%
|
%
|
||||||
% Parse an positive integer number
|
% Parse an positive integer number
|
||||||
%
|
%
|
||||||
parse_positive_number(N) -->
|
parse_positive_integer_number(N) -->
|
||||||
[N],
|
[N],
|
||||||
{
|
{
|
||||||
not(compound(N)),
|
integer(N),
|
||||||
%% CLPFD, a number between 0 and infinity
|
%% CLPFD, a number greater than 0
|
||||||
N in 0..sup, !
|
N #>= 1, !
|
||||||
}.
|
}.
|
||||||
parse_positive_number(T) -->
|
parse_positive_integer_number(T) -->
|
||||||
parse_number_explicit(void, void, T).
|
parse_number_explicit(void, void, T).
|
||||||
|
|
||||||
%% parse_number(-tree, +stream, -not_consumed) is det
|
%% parse_integer_number(-tree, +stream, -not_consumed) is det
|
||||||
%
|
%
|
||||||
% Parse an integer number
|
% Parse an integer number
|
||||||
%
|
%
|
||||||
parse_number(N) -->
|
parse_integer_number(N) -->
|
||||||
[N],
|
[N],
|
||||||
%% CLPFD, a number between negative infinity and positive infinity
|
{ integer(N), ! }.
|
||||||
{ N in inf..sup, ! }.
|
parse_integer_number(op(neg, T)) --> % TODO
|
||||||
parse_number(op(neg, T)) --> % TODO
|
%% A number can start with "negative", to negate it
|
||||||
%% A number can start with negative, to negate it
|
|
||||||
[negative],
|
[negative],
|
||||||
parse_number_explicit(void, void, T).
|
parse_number_explicit(void, void, T).
|
||||||
parse_number(T) -->
|
parse_integer_number(T) -->
|
||||||
parse_number_explicit(void, void, T).
|
parse_number_explicit(void, void, T).
|
||||||
%% Tests:
|
%% Tests:
|
||||||
%% ?- parse_number(T, [two], _).
|
%% ?- parse_integer_number(T, [two], _).
|
||||||
%@ T = 2.
|
%@ T = 2.
|
||||||
%% ?- parse_number(T, [43], _).
|
%% ?- parse_integer_number(T, [43], _).
|
||||||
%@ T = 43.
|
%@ T = 43.
|
||||||
%% ?- parse_number(T, [nineteen, two], _).
|
%% ?- parse_integer_number(T, [nineteen, two], _).
|
||||||
%@ false.
|
%@ false.
|
||||||
%% ?- parse_number(T, [twenty], _).
|
%% ?- parse_integer_number(T, [twenty], _).
|
||||||
%@ T = 20.
|
%@ T = 20.
|
||||||
%% ?- parse_number(T, [twenty, point, two], NC).
|
%% ?- parse_integer_number(T, [twenty, point, two], NC).
|
||||||
%@ T = op('.', 20, 2),
|
%@ T = op('.', 20, 2),
|
||||||
%@ NC = [].
|
%@ NC = [].
|
||||||
%% ?- parse_number(T, [twenty, twenty], _).
|
%% ?- parse_integer_number(T, [twenty, twenty], _).
|
||||||
%@ false.
|
%@ false.
|
||||||
%% ?- parse_number(T, [twenty, one], _).
|
%% ?- parse_integer_number(T, [twenty, one], _).
|
||||||
%@ T = op(+, 20, 1).
|
%@ T = op(+, 20, 1).
|
||||||
%% ?- parse_number(T, [negative, one, hundred], _).
|
%% ?- parse_integer_number(T, [negative, one, hundred], _).
|
||||||
%@ T = op(neg, op(*, 1, 100)) ;
|
%@ T = op(neg, op(*, 1, 100)) ;
|
||||||
%@ false.
|
%@ false.
|
||||||
%% ?- parse_number(T, [three, hundred], _).
|
%% ?- parse_integer_number(T, [three, hundred], _).
|
||||||
%@ T = op(*, 3, 100).
|
%@ T = op(*, 3, 100).
|
||||||
%% ?- parse_number(T, [twenty, hundred], _).
|
%% ?- parse_integer_number(T, [twenty, hundred], _).
|
||||||
%@ T = op(*, 20, 100).
|
%@ T = op(*, 20, 100).
|
||||||
%% ?- parse_number(T, [twenty, one, hundred], _).
|
%% ?- parse_integer_number(T, [twenty, one, hundred], _).
|
||||||
%@ T = op(*, op(+, 20, 1), 100).
|
%@ T = op(*, op(+, 20, 1), 100).
|
||||||
%% ?- parse_number(T, [two, hundred, and, one], _).
|
%% ?- parse_integer_number(T, [two, hundred, and, one], _).
|
||||||
%@ T = op(+, op(*, 2, 100), 1).
|
%@ T = op(+, op(*, 2, 100), 1).
|
||||||
%% ?- parse_number(T, [twenty, one, hundred, and, twenty, one], _).
|
%% ?- parse_integer_number(T, [twenty, one, hundred, and, twenty, one], _).
|
||||||
%@ T = op(+, op(+, op(*, op(+, 20, 1), 100), 20), 1).
|
%@ T = op(+, op(+, op(*, op(+, 20, 1), 100), 20), 1).
|
||||||
%% ?- parse_number(T, [twenty, one, hundred, and, twenty, one, foo, bar, blah], NC).
|
%% ?- parse_integer_number(T, [twenty, one, hundred, and, twenty, one, foo, bar, blah], NC).
|
||||||
%@ T = op(+, op(+, op(*, op(+, 20, 1), 100), 20), 1),
|
%@ T = op(+, op(+, op(*, op(+, 20, 1), 100), 20), 1),
|
||||||
%@ NC = [foo, bar, blah].
|
%@ NC = [foo, bar, blah].
|
||||||
%% ?- parse_number(T, [twenty, one, hundred, and, bleg, twenty, quux, one, foo, bar], NC).
|
%% ?- parse_integer_number(T, [twenty, one, hundred, and, bleg, twenty, quux, one, foo, bar], NC).
|
||||||
%@ T = op(*, op(+, 20, 1), 100),
|
%@ T = op(*, op(+, 20, 1), 100),
|
||||||
%@ NC = [and, bleg, twenty, quux, one, foo, bar].
|
%@ NC = [and, bleg, twenty, quux, one, foo, bar].
|
||||||
%% ?- parse_number(T, [two, hundred, thousand], _).
|
%% ?- parse_integer_number(T, [two, hundred, thousand], _).
|
||||||
%@ T = op(*, op(*, 2, 100), 1000).
|
%@ T = op(*, op(*, 2, 100), 1000).
|
||||||
%% ?- parse_number(T, [twenty, one, hundred, thousand], _).
|
%% ?- parse_integer_number(T, [twenty, one, hundred, thousand], _).
|
||||||
%@ T = op(*, op(*, op(+, 20, 1), 100), 1000).
|
%@ T = op(*, op(*, op(+, 20, 1), 100), 1000).
|
||||||
%% ?- parse_number(T, [thirty, five, million, five, hundred, thirty, four], _).
|
%% ?- parse_integer_number(T, [thirty, five, million, five, hundred, thirty, four], _).
|
||||||
%@ T = op(+, op(+, op(*, op(+, op(*, op(+, 30, 5), 1000000), 5), 100), 30), 4).
|
%@ T = op(+, op(+, op(*, op(+, op(*, op(+, 30, 5), 1000000), 5), 100), 30), 4).
|
||||||
%% ?- parse_number(T, [foo, five, million], NC).
|
%% ?- parse_integer_number(T, [foo, five, million], NC).
|
||||||
%@ false.
|
%@ false.
|
||||||
|
|
||||||
%% nlp_parse_power(?List, ?List) is det
|
%% nlp_parse_power(?List, ?List) is det
|
||||||
@ -554,7 +554,7 @@ parse_power(op(^, TB, 3)) -->
|
|||||||
parse_power(op(^, TB, TN)) -->
|
parse_power(op(^, TB, TN)) -->
|
||||||
parse_polynomial_variable(TB),
|
parse_polynomial_variable(TB),
|
||||||
[raised, to],
|
[raised, to],
|
||||||
parse_positive_number(TN).
|
parse_positive_integer_number(TN).
|
||||||
parse_power(TB) -->
|
parse_power(TB) -->
|
||||||
parse_polynomial_variable(TB).
|
parse_polynomial_variable(TB).
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user