Research-Stack/2-Search-Space/tardygrada/tests/test_datalog.py

164 lines
4.7 KiB
Python
Executable file

#!/usr/bin/env python3
"""
Datalog Chain Reasoning Integration Test
Tests:
1. Direct fact grounding (ontology lookup)
2. Computational verification (known constants)
3. Self-growing (verified claims feed future grounding)
"""
import subprocess, json, os, sys
os.chdir(os.path.dirname(os.path.abspath(__file__)) + "/..")
BINARY = "./tardygrada"
PROGRAM = "examples/receive.tardy"
NT_FILE = os.path.abspath("tests/test_ontology.nt")
def mcp_msg(body):
b = body.encode()
return f"Content-Length: {len(b)}\r\n\r\n".encode() + b
def parse_responses(out):
results = {}
parts = out.split(b"Content-Length: ")
for part in parts:
if not part:
continue
idx = part.find(b"{")
if idx < 0:
continue
try:
j = json.loads(part[idx:])
rid = j.get("id", "?")
if "result" in j and isinstance(j["result"], dict) and "content" in j["result"]:
results[rid] = j["result"]["content"][0]["text"]
elif "result" in j:
results[rid] = str(j["result"])
except Exception:
pass
return results
def run_session(claims, load_ontology=True):
"""Run a tardygrada session with given claims. Returns verify results."""
reqs = [mcp_msg(json.dumps({
"jsonrpc": "2.0", "id": 1,
"method": "initialize", "params": {}
}))]
if load_ontology:
reqs.append(mcp_msg(json.dumps({
"jsonrpc": "2.0", "id": 2,
"method": "tools/call",
"params": {"name": "load_ontology", "arguments": {"path": NT_FILE}}
})))
rid = 10
verify_ids = []
for claim in claims:
reqs.append(mcp_msg(json.dumps({
"jsonrpc": "2.0", "id": rid,
"method": "tools/call",
"params": {"name": "submit_claim",
"arguments": {"agent": "origin", "claim": claim}}
})))
rid += 1
reqs.append(mcp_msg(json.dumps({
"jsonrpc": "2.0", "id": rid,
"method": "tools/call",
"params": {"name": "verify_claim",
"arguments": {"agent": "origin"}}
})))
verify_ids.append(rid)
rid += 1
proc = subprocess.Popen(
[BINARY, PROGRAM],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE
)
out, err = proc.communicate(input=b"".join(reqs), timeout=15)
results = parse_responses(out)
return {claims[i]: results.get(verify_ids[i], "")
for i in range(len(claims))}
def check(desc, result_text, expect_verified=True, check_grounded=False):
"""Check if a verify result matches expectation."""
if check_grounded:
# For computational claims, just check that grounding worked
grounded = "triples_grounded=1/1" in result_text or "triples_grounded=2/2" in result_text
if grounded:
print(f" PASS: {desc} (grounded)")
return True
else:
print(f" FAIL: {desc} (not grounded, result: {result_text[:120]})")
return False
verified = "verified=true" in result_text
if verified == expect_verified:
print(f" PASS: {desc}")
return True
else:
status = "verified" if verified else "not verified"
print(f" FAIL: {desc} (got {status}, result: {result_text[:120]})")
return False
# ============================================================
if not os.path.exists(BINARY):
print("FAIL: binary not found, run 'make' first")
sys.exit(1)
print("=== Datalog Chain Reasoning Test ===")
print()
passed = 0
failed = 0
# --- Test 1: Direct fact grounding ---
print("-- Direct Facts --")
results = run_session([
"Doctor Who was created by Sydney Newman",
])
for claim, result in results.items():
if check(claim, result):
passed += 1
else:
failed += 1
# --- Test 2: Computational verification (grounding check) ---
print()
print("-- Computational Verification (grounding) --")
results = run_session([
"The speed of light is 299792458 meters per second",
"The value of pi is 3.14159",
], load_ontology=False)
for claim, result in results.items():
if check(claim, result, check_grounded=True):
passed += 1
else:
failed += 1
# --- Test 3: Self-growing ontology ---
print()
print("-- Self-Growing Ontology --")
# First claim adds facts, second claim should benefit from derived knowledge
results = run_session([
"Doctor Who was created by Sydney Newman",
"Doctor Who was created in 1963",
])
for claim, result in results.items():
if check(claim, result):
passed += 1
else:
failed += 1
print()
print(f"=== Results: {passed}/{passed + failed} passed, {failed} failed ===")
if failed > 0:
sys.exit(1)