Skip to content

fix: more cli argument validation, cli's defaults compatibility, implied arguments - #95

Merged
ondrik merged 2 commits into
masterfrom
fix/85-cli-errors
Oct 27, 2026
Merged

ondrik merged 2 commits into
masterfrom
fix/85-cli-errors

Conversation

@jkhav

@jkhav jkhav commented Oct 16, 2026

Copy link
Copy Markdown
Member

Closes #85.

Exit status (F39)

milq now exits non-zero when synthesis fails:

Status Meaning
0 a circuit was synthesized
1 error: missing input, unparsable QASM, solver failure, Gurobi license limit, ...
2 invalid options (argparse usage message)
3 no circuit found: unsat, or none within --max-depth / -pt

synthesis failed and errors go to stderr. The exit codes are documented in docs/reference.md.

Option defaults and errors (F40)

  • -a defaults to the backend's solver: yices2 for -s smt, cbc for -s milp, gurobi for -s gurobi. milq x.qasm -s smt now works. A solver that doesn't fit the backend (e.g. -s smt -a cbc) is a usage error that lists the valid choices.
  • ValueError, OSError, RuntimeError, SolverError and GurobiError are caught and printed as milq: error: ... instead of a traceback.
  • Numeric options are checked by argparse: -d ≥ 0, --max-depth ≥ 1, -T ≥ 1, -A ≥ 0, -f in [0, 1], -pt > 0. synthesis() also rejects a negative d.
  • Fixed the -f help text (it is for -ap, not dreal).

Options outside their mode (F79 and similar)

These options used to be accepted and silently ignored. They are now rejected outside the mode they apply to:

  • -d: only basic/binary/topdown/bottomup (the message points to --max-depth)
  • --max-depth: only incremental/pareto-incremental (the message points to -d)
  • -f: only with -ap
  • -pt: only with -m pareto-incremental
  • -T, -A: only with -v rus

-d stays separate from --max-depth. In the incremental modes d sizes the encoding (preallocated layers, value bounds, max_k) and is not a limit, so each CLI flag still maps to exactly one synthesis() argument.

cli/simulator.py

  • Same treatment: simulator: error: ... instead of tracebacks, -m limited to 0/1, -T/-A checked and only with -v rus, works through a symlink (realpath), corrected help text, unused imports removed.
  • Unparsable QASM raised a bare Exception. It now raises ValueError and names the line.
  • -v rus with no targets, or with fewer targets + ancillas than the circuit's qubits, crashed with IndexError. It now raises a ValueError that explains why.

Behaviour changes

  • Commands that passed -d, --max-depth, -f, -pt, -T or -A where they had no effect now stop with exit 2. Results of valid commands are unchanged.
  • A failed synthesis now exits 3 instead of 0.

Tests

  • New tests/test_cli.py runs both scripts and checks the exit codes and that no traceback is printed.
  • Unit tests for the sim.py errors and for a negative d.
  • Full suite: 501 passed.

@codecov

codecov Bot commented Oct 16, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@ondrik
ondrik force-pushed the fix/85-cli-errors branch from e6f68d5 to 45210c4 Compare October 27, 2026 13:15
jkhav and others added 2 commits October 27, 2026 14:41
The reference documents the simulator's -T as at least 1, as for milq,
but it accepted 0, which then failed in simulate_rus with exit status 1
instead of a usage error (2).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0177AhE9SXm3iJ1KP8GTSk6o
@ondrik
ondrik force-pushed the fix/85-cli-errors branch from 45210c4 to 7c822d5 Compare October 27, 2026 13:45
@ondrik
ondrik merged commit e5a5216 into master Oct 27, 2026
4 checks passed
@ondrik
ondrik deleted the fix/85-cli-errors branch October 27, 2026 14:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

milq exits 0 on failure and prints tracebacks for user errors

2 participants