docs← Back to article

Markdown for LLMs

The structural layer, form by form

The source Markdown for this article. Copy it into your assistant or download it as a text file.

Download this articlePlain text ↗
# The structural layer, form by form

A structural query names its tables in `from`, narrows rows in `where`, and shapes the answer in `select`. Every query below runs against the two-package reference fixture: a base package with rules, duties, interpretations and a pinned article, and a second package that imports it. Column aliases follow `as`.

```lawq
from r in rules
where r.head_predicate == "urn:law:demo:lawqlbase#eligible"
select r.id as producer, r.strength as strength, anchor(r.id) as anchors
```

The answer is rows with provenance: every row names the model nodes it was assembled from and the anchors into the pinned text. There is no row without a node.

## Reading a computed answer

`let` binds a name; `eval` materializes a stored answer document for a package and its case. The number of such materializations is always bounded explicitly.

```lawq
let doc = eval("demo.lawqlbase", "verify/ci/gates/release/lawql_reference_fixtures/base")
from r in doc.results
select r.query as query
```

Any top-level key of the stored document reads as a table afterwards: results, positions, issues, derivations. Reading the document is not recomputing it: truth, defeat and the reason something did not follow are computed by the core.

## Narrowing to packages

A relation accepts a package scope in front of it. `corpus` takes a glob over package names, `package` names one package exactly.

```lawq
from r in corpus("demo.lawql*").rules
where r.strength == "strict"
select r.id as rule, r.package as package
```

```lawq
from n in package("demo.lawqlbase").nodes
where n.kind == "rule"
select n.id as rule
```

## Asking about another row

`exists` and `not exists` quantify over an already bound variable: the inner query may compare its rows with the outer row. Rules that share their head predicate with another rule:

```lawq
from r in rules
where exists(s in rules where s.head_predicate == r.head_predicate and s.id != r.id)
select r.id as rule
```

Rules whose head predicate no body ever mentions:

```lawq
from r in rules
where not exists(l in literals where l.predicate == r.head_predicate)
select r.id as rule
```

## Asking the core to derive

Whatever needs recursion, negation or ordering goes to an inference query: it compiles into a short-lived package over the named model and runs the core. The facts of a case travel in the case clause.

```lawq
query eligible_ann over "demo.lawqlbase" {
  for a: Applicant;
  case "verify/ci/gates/release/lawql_reference_fixtures/base/case.json";
  where resident(a);
  select eligible(a);
}
```

## Keywords

The structural layer reserves exactly these words, in both implementations:

`from`, `in`, `where`, `select`, `as`, `and`, `or`, `exists`, `not`, `let`, `eval`, `true`, `false`, `null`, `query`, `over`

Every reserved word above is listed here; no other word is reserved.

## Command flags

The user-facing flags of `law query`, checked against the command itself:

- `--corpus` — scope by package name or glob; without it the whole slice is read.
- `--pkg` — the package argument of a named question.
- `--json` — the canonical answer document instead of human text.
- `--format` — human, json or tsv output.
- `--explain` — row counts after every clause, the same funnel the answer document carries.
- `--limit` — bound on eval materializations; required whenever the query materializes.
- `--param` — a named-question argument as name and value; repeatable.
- `--schema` — the live dictionary of relations and functions instead of an answer.
- `--list` — the catalog of named questions instead of an answer.