"""Run the cat, a cat, and cat? examples and save their graphs and paths.""" from __future__ import annotations import argparse from pathlib import Path import sys from robocrunch import Graph, RoboCrunchClient, RoboCrunchError from robocrunch_paths import get_full_paths def main(argv: list[str] | None = None) -> int: """Call the API sequentially and save three files for each example.""" parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--api", default="https://robocrunch.net/api/run", help="API endpoint URL.") parser.add_argument("--rulebase", default="https://symsuper.com/grammars/english-tau-c/", help="RuleBase directory URL.") parser.add_argument("--output-dir", default="examples", help="Directory for the saved examples.") parser.add_argument("--timeout", type=float, default=120.0, help="HTTP timeout in seconds.") parser.add_argument("--max-paths", type=int, default=10000, help="Maximum paths per example.") args = parser.parse_args(args=argv) cases = (("cat", "cat"), ("a-cat", "a cat"), ("cat-question", "cat?")) try: if args.max_paths < 1: raise ValueError("--max-paths must be a positive integer.") directory = Path(args.output_dir) directory.mkdir(parents=True, exist_ok=True) client = RoboCrunchClient(api_url=args.api, timeout=args.timeout) for name, text in cases: graph = Graph.from_text(text=text) graph.write_file(path=str(directory / f"{name}-InputGraph.txt")) result = client.run(rule_base_url=args.rulebase, graph=graph) result.write_file(path=str(directory / f"{name}-OutputGraph.txt")) output = result.output_graph metadata = result.metadata if output.node_count != metadata.get("nodeCount") or output.edge_count != metadata.get("edgeCount"): raise ValueError(f"{name}: graph counts disagree with the API metadata.") paths = get_full_paths(graph=output, max_paths=args.max_paths) if not paths: raise ValueError(f"{name}: the output has no complete begin-to-end Token path.") lines = [ f"Input text: {text!r}", f"RuleBase: {metadata['ruleBaseUrl']}", f"Level / Direction: {metadata['level']} / {metadata['direction']}", f"Rules loaded: {metadata['ruleCount']}", f"Graph: {output.node_count} nodes, {output.edge_count} edges.", f"Full Token paths: {len(paths)}", "" ] for number, token_path in enumerate(paths, start=1): lines.append(f"{number}. {token_path.to_text()}") lines.append(" Token IDs: " + ", ".join(node.id for node in token_path.tokens)) (directory / f"{name}-Paths.txt").write_text(data="\n".join(lines) + "\n", encoding="utf-8") print(f"{text!r}: {output.node_count} nodes, {output.edge_count} edges, {len(paths)} full paths.") print(f"Example files saved to {directory.resolve()}") return 0 except (RoboCrunchError, ValueError, OSError) as error: print(f"Error: {error}", file=sys.stderr) return 1 if __name__ == "__main__": raise SystemExit(main())