Evaluators
The deterministic evaluators of the checks: exact arithmetic, symbolic identity, and numeric sampling.
A model writes the expressions these evaluate, so none of them is ever passed to eval, sympify
or parse_expr. Each is parsed with ast and walked against a whitelist: numerals written in
plain decimal or exponent notation, + - * / **, unary signs and parentheses, and, for the
symbolic evaluator only, declared symbols, a fixed set of functions and the constants pi, E
and I. Anything else is refused before any value is computed.
arithmetic computes exactly, with every numeral read as a Fraction of its decimal text.
identity asks sympy whether two expressions are equal for every value of their symbols, and
says error when sympy cannot decide. sample and agree_at evaluate the same two
expressions at points drawn from a seeded generator, so the points can be recorded and drawn again.
Arithmetic
dataclass
¶
The exact value of an arithmetic expression.
Attributes:
| Name | Type | Description |
|---|---|---|
value |
Fraction
|
The value. |
numerals |
tuple[str, ...]
|
The text of every numeral in the expression, in the order written. |
Source code in src/credencegraph_extract/evaluate.py
126 127 128 129 130 131 132 133 134 135 136 | |
EvaluationError
¶
Bases: ValueError
An expression is refused or cannot be evaluated.
Source code in src/credencegraph_extract/evaluate.py
90 91 | |
agree_at(lhs, rhs, declared, names, points)
¶
Compare two expressions at each point, to a relative tolerance of RTOL.
The point's values are substituted exactly, as rationals, so a pole gives no finite value rather
than a large one, and each side is then evaluated to 30 significant digits. Sides agree at a point when
|lhs - rhs| <= RTOL * max(|lhs|, |rhs|).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lhs
|
Expr
|
One side. |
required |
rhs
|
Expr
|
The other. |
required |
declared
|
Sequence[Mapping[str, Any]]
|
The symbols with their assumptions, which every point must satisfy. |
required |
names
|
Mapping[str, Symbol]
|
The symbols by name. |
required |
points
|
Sequence[Mapping[str, str]]
|
The points, as returned by |
required |
Returns:
| Type | Description |
|---|---|
str
|
The result and what was found: |
str
|
the first point where they do not, |
tuple[str, str]
|
side has no finite value there. |
Source code in src/credencegraph_extract/evaluate.py
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 | |
arithmetic(expression)
¶
Evaluate an arithmetic expression exactly.
Numerals are read as the Fraction of their decimal text, so 0.1 + 0.2 is exactly
3/10. A power needs an integer exponent, since a root of a fraction is not a fraction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
expression
|
str
|
Numerals joined by |
required |
Returns:
| Type | Description |
|---|---|
Arithmetic
|
The value and the numerals. |
Raises:
| Type | Description |
|---|---|
EvaluationError
|
If the expression holds anything else, divides by zero, or raises to a power that is not an integer or is too large. |
Source code in src/credencegraph_extract/evaluate.py
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | |
identity(lhs, rhs)
¶
Decide symbolically whether two expressions are equal for every value of their symbols.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lhs
|
Expr
|
One side. |
required |
rhs
|
Expr
|
The other. |
required |
Returns:
| Type | Description |
|---|---|
str
|
The result and what sympy found: |
str
|
|
tuple[str, str]
|
neither, since a difference sympy cannot simplify is not evidence either way. |
Source code in src/credencegraph_extract/evaluate.py
291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 | |
sample(declared, seed, count=POINTS)
¶
Draw points in the symbols' domains from a generator seeded with seed.
A symbol with the integer assumption takes integers in its domain; any other takes floats,
written with repr so the recorded text reads back as the same value.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
declared
|
Sequence[Mapping[str, Any]]
|
Each symbol as |
required |
seed
|
int
|
The seed. |
required |
count
|
int
|
How many points. |
POINTS
|
Returns:
| Type | Description |
|---|---|
list[dict[str, str]]
|
The points, each a symbol name to the text of its value. |
Raises:
| Type | Description |
|---|---|
EvaluationError
|
If a symbol has no finite domain |
Source code in src/credencegraph_extract/evaluate.py
326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 | |
seed_of(encoding)
¶
Return the seed of an encoding's sample points: the first 52 bits of the SHA-256 of its canonical JSON.
52 bits keep the seed exact in any JSON reader, which reads numbers as doubles.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
encoding
|
Mapping[str, Any]
|
The encoding. |
required |
Returns:
| Type | Description |
|---|---|
int
|
The seed. |
Source code in src/credencegraph_extract/evaluate.py
311 312 313 314 315 316 317 318 319 320 321 322 323 | |
symbolic(expression, names)
¶
Build the sympy expression of a text, without eval.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
expression
|
str
|
Numerals, the symbols in |
required |
names
|
Mapping[str, Symbol]
|
The declared symbols. |
required |
Returns:
| Type | Description |
|---|---|
Expr
|
The expression; numerals are exact rationals. |
Raises:
| Type | Description |
|---|---|
EvaluationError
|
If the text holds anything else, or a power of two numbers is too large. |
Source code in src/credencegraph_extract/evaluate.py
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 | |
symbols(declared)
¶
Create the sympy symbols an encoding declares.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
declared
|
Sequence[Mapping[str, Any]]
|
Each symbol as |
required |
Returns:
| Type | Description |
|---|---|
dict[str, Symbol]
|
The symbols by name. |
Raises:
| Type | Description |
|---|---|
EvaluationError
|
If a name is not an identifier, is repeated, or names a function or constant;
or an assumption is not one of |
Source code in src/credencegraph_extract/evaluate.py
214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 | |
text_numerals(text)
¶
Return every numeral of a text with the rounding its own digits imply.
The numerals are found with the core's numeral pattern, the one its faithfulness rule uses, and
each value is computed the same way: groups removed, the exponent applied, the sign kept. The
rounding is half a unit of the last digit written, so 30 is 30 ± 0.5 and 1.20e-3 is
0.00120 ± 0.000005. A numeral followed by % contributes its value and its value divided by
100, each with its rounding scaled alike, as the core's numerals does.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The text. |
required |
Returns:
| Type | Description |
|---|---|
list[tuple[Fraction, Fraction]]
|
|
Source code in src/credencegraph_extract/evaluate.py
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 | |