Overview
QWED-Logic is an S-expression based DSL for expressing logical constraints. It’s verified by the Z3 SMT solver for mathematical correctness.Why S-expressions? They’re unambiguous, easy to parse, and map directly to Z3 constraints.
Basic syntax
Logical operators
Examples
IFF is a biconditional, not equality. Its operands must be comparisons, Bool variables, or True/False. (IFF x y) on two Int variables is a compile error, not x == y.
Comparison operators
Only these names are on the operator whitelist.
NE, GE, LE, and MUL return BLOCKED with Unknown operator.
Examples
Arithmetic operators
Examples
Quantifiers
A quantifier takes a binder and a body:
(FORALL x body) or (EXISTS x body).
- The binder is one plain variable name. The parser returns
BLOCKEDfor any other binder, including a list such as(x)or(x y), a number, an operator name, orTrue/False. - The bound variable takes its declared sort, or
Intif it isn’t declared. - The binding applies inside the body only. A free variable with the same name outside the quantifier is unaffected.
- The body must be Boolean.
(FORALL x (PLUS x 1))is a compile error. - If Z3 returns
unknownon a hard quantified formula, the result isUNKNOWN. It is never reported as verified.
Examples
Special types
Boolean literals
Variable sorts
Variables areInt, Real, or Bool. An undeclared variable is an Int. Declare other sorts in the variables argument of DSLLogicVerifier.verify_from_dsl(), for example variables=[{"name": "flag", "type": "Bool"}]. On POST /verify/logic the query is natural language, and the translator declares the variables it emits. A (VAR flag Bool) form inside a larger expression does not compile, even though the compiler’s error message suggests it.
1 or 0:
EQ/NEQbetween a Boolean (a literal,Boolvariable, or comparison) and a non-Boolean value is a compile error.GT,LT,GTE, andLTEreject Boolean operands, because Booleans have no ordering.PLUS,MINUS,MULT,DIV,POW, andMODreject Boolean operands.- An undeclared name compared with
TrueorFalseis a compile error. Declare itBool.
ERROR, never SAT or VERIFIED.
Complete examples
Example 1: age validation
Example 2: budget constraint
Example 3: password rules
Example 4: scheduling constraint
Example 5: quadratic equation
Verification results
Reading results
DSLLogicVerifier.verify_from_dsl() returns as is. POST /verify/logic, and so client.verify_logic(), maps it: SAT is VERIFIED with the model as evidence, UNSAT is UNVERIFIABLE, and anything else is BLOCKED. The route makes no admission decision, so the Python SDK’s is_verified stays False; read status and the model.
API usage
Python
CLI
HTTP API
POST /verify/logic takes a natural-language query. The server translates it into this DSL with the LLM provider you configured, then checks the DSL with Z3. It does not take DSL directly.