GrandNexus / tests_lab /test_learning_loop.py
Khaled
Add GrandNexus 7.2.3 RC learning loop
f33457d
Raw History Blame Contribute Delete
3.17 kB
"""Offline test of the learning loop (no API): a scripted reader reads carelessly, is corrected on the experience
pool (verified by the engine), and reads correctly on the test set only when a RELEVANT experience is shown."""
import json, pathlib, sys, tempfile
from types import SimpleNamespace
sys.path.insert(0, "."); sys.path.insert(0, "tools")
CARELESS = '```nx\nbird(X) => fly(X). @ "Every bird in the zoo can fly"\npenguin({n}). @ "{N} is a penguin"\n? fly({n}).\n```'
CAREFUL = ('```nx\nbird(X) => fly(X). @ "Every bird in the zoo can fly"\npenguin({n}). @ "{N} is a penguin"\n'
'penguin(X) => bird(X). @ "Penguins are birds in the zoo"\npenguin(X) => not fly(X). @ "Penguins cannot fly"\n? fly({n}).\n```')
NAMES = ["Tweety", "Pingu", "Skipper", "Kowalski", "Rico", "Private"]
def item(i):
n = NAMES[i]
return {"id": str(i), "text": f"Every bird in the zoo can fly. {n} is a penguin. Penguins are birds in the zoo. Penguins cannot fly.",
"query": f"Can {n} fly?", "expected": "contradictory"}
DOGS = ["Rex", "Fido", "Max"]
def dog(i):
n = DOGS[i]
return {"id": f"d{i}", "text": f"All dogs bark. {n} is a dog.", "query": f"Does {n} bark?", "expected": "yes"}
DOGPROG = '```nx\ndog(X) => bark(X). @ "All dogs bark"\ndog({n}). @ "{N} is a dog"\n? bark({n}).\n```'
class Scripted:
def __init__(self): self.messages, self.calls = self, []
def create(self, model, max_tokens, system, messages):
u = messages[0]["content"]; self.calls.append(u)
tail = u.split("TEXT:")[-1]
dn = next((x for x in DOGS if x in tail), None)
if dn:
body = DOGPROG.format(n=dn.lower(), N=dn) # the dog pattern is always read right
else:
n = next(x for x in NAMES if x in tail)
if "The engine answered" in u: # reflection -> the careful program
body = CAREFUL.format(n=n.lower(), N=n)
elif "EXAMPLES OF VERIFIED PAST READINGS" in u and "penguin(X) => not fly(X)" in u:
body = CAREFUL.format(n=n.lower(), N=n) # a relevant example shown -> careful reading
else:
body = CARELESS.format(n=n.lower(), N=n) # careless first reading
return SimpleNamespace(id="fake", model=model, content=[SimpleNamespace(text=body)],
usage=SimpleNamespace(input_tokens=1, output_tokens=1))
d = tempfile.mkdtemp()
jl = pathlib.Path(d) / "pool.jsonl"
# pool order is shuffled by the bench with --exp-seed: experience = 6 items (3 penguin, 3 dog), test = the 3 remaining penguins
pool = [item(0), item(1), item(2), dog(0), dog(1), dog(2), item(3), item(4), item(5)]
jl.write_text("\n".join(json.dumps(x) for x in pool), encoding="utf-8")
import bench_learning as B
s = B.main(["--jsonl", str(jl), "--exp-n", "6", "--test-n", "3", "--k", "1", "--exp-seed", "0", "--out", d], client=Scripted())
m = s["modes"]
ok = (s["experience"].get("verified", 0) >= 1 and m["none"]["acc"] == 0 and m["learned"]["acc"] == 3 and m["random"]["acc"] <= 3)
print("ALL OK" if ok else f"FAIL {json.dumps({k: v['acc'] for k, v in m.items()})} {s['experience']}")