1:- module(quantity, [ quantity/0, quantity/3 ]).
2:- use_module(library(dcg/basics)).
3
4:- set_prolog_flag(float_overflow, infinity).
5:- set_prolog_flag(float_undefined, nan).
6:- set_prolog_flag(float_zero_div, infinity).
7
9quantity(Number, Options, String) :-
10 string(String),
11 string_codes(String, Codes),
12 quantity(Number, Options, Codes).
13
14quantity(Number, Options, Atom) :-
15 atom(Atom),
16 atom_codes(Atom, Codes),
17 quantity(Number, Options, Codes).
18
19quantity(Number, Options, [H | Codes]) :-
20 quantity(Number, Options, [H | Codes], []).
21
22quantity(Number, Options, [H | Codes]) :-
23 interval(Number, Options, [H | Codes], []).
24
26quantity :-
27 quantity("2.5").
28
29quantity :-
30 quantity("+2.5").
31
32quantity :-
33 quantity("-2.5").
34
35quantity :-
36 quantity(".5").
37
38quantity :-
39 quantity("-.5").
40
41quantity :-
42 quantity("-5").
43
44quantity :-
45 quantity("5").
46
47quantity :-
48 quantity("-3.3 to -3.2").
49
50quantity(String) :-
51 quantity(N, Options, String),
52 writeln(string(String)-number(N)-options(Options)).
53
55:- discontiguous quantity//2.
56
57quantity(Q, [type(natural)])
58--> nat(Q).
59
60quantity(Q, [type(integer) | Options])
61--> int(Q, Options).
62
63quantity(Q, [type(real) | Options])
64--> real(Q, Options).
65
66interval(ci(Lo, Hi), Options)
67--> quantity(Lo, LoOpt),
68 to(ToOpt),
69 quantity(Hi, HiOpt),
70 { append([LoOpt, ToOpt, HiOpt], Options) }.
71
73sign(+1, [sign(none)])
74--> "".
75
76sign(+1, [sign(plus)])
77--> "+".
78
79sign(-1, [sign(hyphen)])
80--> "-".
81
82sign(-1, [sign(dash)])
83--> [226, 136, 146].
84
85sign(-1, [sign(minus)])
86--> [8722].
87
88nat(N)
89--> digits([H | Codes]),
90 { number_codes(N, [H | Codes]) }.
91
92int(I, Options)
93--> sign(S, Options),
94 nat(N),
95 { I is S * N }.
96
97sep(dot)
98--> ".".
99
100sep(comma)
101--> ",".
102
103frac(F, [frac(given), sep(S), digits(D)])
104--> sep(S),
105 digits([H | Codes]),
106 { number_codes(N, [H | Codes]),
107 length(Codes, L),
108 D is L + 1,
109 F is N / 10^D
110 }.
111
112real(R, [int(given) | Options])
113--> sign(S, Options),
114 "∞",
115 { R is S * 1.0Inf }.
116
117real(R, [int(given) | Options])
118--> sign(S, Options),
119 "oo",
120 { R is S * 1.0Inf }.
121
122real(R, [int(given) | Options])
123--> sign(S, Options),
124 "OO",
125 { R is S * 1.0Inf }.
126
127real(R, [int(given) | Options])
128--> sign(S, Options),
129 "oO",
130 { R is S * 1.0Inf }.
131
132real(R, [int(given) | Options])
133--> sign(S, Options),
134 "inf",
135 { R is S * 1.0Inf }.
136
137real(R, [int(given) | Options])
138--> sign(S, Options),
139 "Inf",
140 { R is S * 1.0Inf }.
141
142real(R, [int(given) | Options])
143--> sign(S, Options),
144 "infty",
145 { R is S * 1.0Inf }.
146
147real(R, [int(given) | Options])
148--> sign(S, Options),
149 "Infty",
150 { R is S * 1.0Inf }.
151
152real(R, [int(given) | Options])
153--> sign(S, Opt1),
154 nat(1),
155 frac(0, Opt2),
156 "Inf",
157 { R is S * 1.0Inf,
158 append([Opt1, Opt2], Options)
159 }.
160
162real(R, [int(given) | Options])
163--> sign(S, Opt1),
164 nat(N),
165 frac(F, Opt2),
166 { R is S * (N + F),
167 append([Opt1, Opt2], Options)
168 }.
169
171real(R, [int(none) | Options])
172--> sign(S, Opt1),
173 frac(F, Opt2),
174 { R is S * F,
175 append([Opt1, Opt2], Options)
176 }.
177
179real(R, [int(given), frac(none) | Options])
180--> sign(S, Options),
181 nat(N),
182 { R is S * N }.
183
185to([to(to)])
186--> blank, blanks, "to", blank, blanks.
187
188to([to(dotdotdot)])
189--> blank, blanks, "...", blank, blanks.
190
191to([to(dash)])
192--> blank, blanks, [226, 136, 146], blank, blanks.
193
194to([to(hyphen)])
195--> blank, blanks, "-", blank, blanks