Spaces:
Sleeping
Sleeping
Update app.py
#16
by
olcapone
- opened
app.py
CHANGED
|
@@ -299,6 +299,90 @@ class BasicAgent:
|
|
| 299 |
return m.group(1).strip()
|
| 300 |
|
| 301 |
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 302 |
|
| 303 |
def _answer_from_op_table(self, question: str, table_text: str):
|
| 304 |
parsed = self._parse_op_table_from_text(table_text)
|
|
|
|
| 299 |
return m.group(1).strip()
|
| 300 |
|
| 301 |
return None
|
| 302 |
+
|
| 303 |
+
def _parse_op_table_from_text(self, text: str):
|
| 304 |
+
"""
|
| 305 |
+
Parse a Markdown table like:
|
| 306 |
+
|*|a|b|c|
|
| 307 |
+
|---|---|---|---|
|
| 308 |
+
|a|a|b|c|
|
| 309 |
+
|b|b|c|a|
|
| 310 |
+
|c|c|a|b|
|
| 311 |
+
Returns (S, T) where S is a list of symbols, and
|
| 312 |
+
T is a dict-of-dicts T[row][col] = result.
|
| 313 |
+
"""
|
| 314 |
+
if not text:
|
| 315 |
+
return None
|
| 316 |
+
|
| 317 |
+
lines = [ln.strip() for ln in text.splitlines() if "|" in ln]
|
| 318 |
+
if not lines:
|
| 319 |
+
return None
|
| 320 |
+
|
| 321 |
+
# find header line (the one starting with |*|)
|
| 322 |
+
header = None
|
| 323 |
+
for ln in lines:
|
| 324 |
+
cells = [c.strip() for c in ln.strip("|").split("|")]
|
| 325 |
+
if cells and cells[0] in {"*", "∗"}:
|
| 326 |
+
header = cells
|
| 327 |
+
break
|
| 328 |
+
if not header:
|
| 329 |
+
return None
|
| 330 |
+
|
| 331 |
+
symbols = header[1:]
|
| 332 |
+
if not symbols:
|
| 333 |
+
return None
|
| 334 |
+
|
| 335 |
+
# build table from subsequent lines that look like rows
|
| 336 |
+
T = {r: {} for r in symbols}
|
| 337 |
+
for ln in lines:
|
| 338 |
+
cells = [c.strip() for c in ln.strip("|").split("|")]
|
| 339 |
+
if not cells or cells[0] not in symbols:
|
| 340 |
+
continue
|
| 341 |
+
row = cells[0]
|
| 342 |
+
vals = cells[1:]
|
| 343 |
+
if len(vals) != len(symbols):
|
| 344 |
+
continue
|
| 345 |
+
for col, val in zip(symbols, vals):
|
| 346 |
+
T[row][col] = val
|
| 347 |
+
|
| 348 |
+
# sanity: ensure all rows present
|
| 349 |
+
if any(r not in T or len(T[r]) != len(symbols) for r in symbols):
|
| 350 |
+
return None
|
| 351 |
+
|
| 352 |
+
return symbols, T
|
| 353 |
+
|
| 354 |
+
def _find_identity(self, S, T):
|
| 355 |
+
# two-sided identity e satisfies e*x = x and x*e = x for all x
|
| 356 |
+
for e in S:
|
| 357 |
+
if all(T[e][x] == x for x in S) and all(T[x][e] == x for x in S):
|
| 358 |
+
return e
|
| 359 |
+
return None
|
| 360 |
+
|
| 361 |
+
def _is_commutative(self, S, T):
|
| 362 |
+
for x in S:
|
| 363 |
+
for y in S:
|
| 364 |
+
if T[x][y] != T[y][x]:
|
| 365 |
+
return False
|
| 366 |
+
return True
|
| 367 |
+
|
| 368 |
+
def _is_associative(self, S, T):
|
| 369 |
+
for x in S:
|
| 370 |
+
for y in S:
|
| 371 |
+
for z in S:
|
| 372 |
+
if T[T[x][y]][z] != T[x][T[y][z]]:
|
| 373 |
+
return False
|
| 374 |
+
return True
|
| 375 |
+
|
| 376 |
+
def _inverse_of(self, x, S, T, e):
|
| 377 |
+
if e is None:
|
| 378 |
+
return None
|
| 379 |
+
for y in S:
|
| 380 |
+
if T[x][y] == e and T[y][x] == e:
|
| 381 |
+
return y
|
| 382 |
+
return None
|
| 383 |
+
|
| 384 |
+
def _idempotents(self, S, T):
|
| 385 |
+
return [x for x in S if T[x][x] == x]
|
| 386 |
|
| 387 |
def _answer_from_op_table(self, question: str, table_text: str):
|
| 388 |
parsed = self._parse_op_table_from_text(table_text)
|