Skip to main content
Quick reference for the QWED-Logic Domain Specific Language.

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

All expressions are enclosed in parentheses. The operator comes first, followed by arguments.

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 BLOCKED for any other binder, including a list such as (x) or (x y), a number, an operator name, or True/False.
  • The bound variable takes its declared sort, or Int if 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 unknown on a hard quantified formula, the result is UNKNOWN. It is never reported as verified.

Examples


Special types

Boolean literals

Variable sorts

Variables are Int, 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.
The compiler checks operand sorts and never coerces a Boolean to 1 or 0:
  • EQ/NEQ between a Boolean (a literal, Bool variable, or comparison) and a non-Boolean value is a compile error.
  • GT, LT, GTE, and LTE reject Boolean operands, because Booleans have no ordering.
  • PLUS, MINUS, MULT, DIV, POW, and MOD reject Boolean operands.
  • An undeclared name compared with True or False is a compile error. Declare it Bool.
A compile error returns ERROR, never SAT or VERIFIED.

Complete examples

Example 1: age validation

Python:

Example 2: budget constraint

Example 3: password rules

Example 4: scheduling constraint

Example 5: quadratic equation


Verification results

Reading results

The table above is the DSL verdict, which 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.

Common patterns

Range check

Mutual exclusion

At most one

Exactly one


Error handling


Grammar (EBNF)


Full specification

See QWED-Logic DSL Specification for the complete formal grammar.