expressir 2.4.31-arm-linux → 2.4.36-arm-linux
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/conformance.yml +34 -0
- data/.gitignore +3 -0
- data/Gemfile +1 -1
- data/TODO.eengine/00-overview.md +39 -0
- data/TODO.eengine/01-resolution-diagnostics.md +30 -0
- data/TODO.eengine/02-check-catalog-completion.md +53 -0
- data/TODO.eengine/03-entity-computations.md +22 -0
- data/TODO.eengine/04-shtolo-rule-audit.md +32 -0
- data/TODO.eengine/05-shtolo-longform-flatten.md +12 -0
- data/TODO.eengine/06-population-p21.md +34 -0
- data/TODO.eengine/07-schema-compare-patch.md +25 -0
- data/TODO.eengine/08-official-corpus-gate.md +7 -0
- data/TODO.eengine/09-mim-mapping-parser.md +9 -0
- data/TODO.parity-ee/00-overview.md +1 -1
- data/TODO.sota/00-overview.md +57 -0
- data/TODO.sota/01-type-checking.md +115 -0
- data/TODO.sota/02-evaluator.md +86 -0
- data/TODO.sota/03-conformance.md +53 -0
- data/TODO.sota/04-lsp.md +70 -0
- data/TODO.sota/05-interop.md +55 -0
- data/TODO.sota/06-dialects.md +57 -0
- data/TODO.sota/07-reference-artifacts.md +55 -0
- data/TODO.suma-improvements/07-part28-xml.md +10 -13
- data/docs/_guides/interop/index.adoc +25 -0
- data/docs/_guides/interop/json-schema.adoc +88 -0
- data/docs/_guides/interop/owl-rdf.adoc +87 -0
- data/docs/_guides/reference/checker-notes.adoc +55 -0
- data/docs/_guides/reference/checker.adoc +36 -0
- data/docs/_guides/reference/evaluator.adoc +40 -0
- data/docs/_guides/reference/grammar-crosswalk.adoc +299 -0
- data/docs/_guides/reference/index.adoc +22 -0
- data/docs/_guides/reference/lsp.adoc +41 -0
- data/docs/_guides/reference/p21.adoc +30 -0
- data/docs/_guides/reference/shtolo.adoc +36 -0
- data/exe/expressir-lsp +6 -0
- data/expressir.gemspec +2 -2
- data/lib/expressir/3.2/expressir_core.so +0 -0
- data/lib/expressir/3.3/expressir_core.so +0 -0
- data/lib/expressir/3.4/expressir_core.so +0 -0
- data/lib/expressir/4.0/expressir_core.so +0 -0
- data/lib/expressir/cli.rb +25 -0
- data/lib/expressir/commands/check.rb +3 -1
- data/lib/expressir/commands/export_json_schema.rb +29 -0
- data/lib/expressir/commands/export_owl.rb +26 -0
- data/lib/expressir/commands/smrl_xml_index.rb +25 -0
- data/lib/expressir/commands/validate.rb +3 -0
- data/lib/expressir/commands.rb +3 -0
- data/lib/expressir/conformance/trend.rb +100 -0
- data/lib/expressir/conformance.rb +8 -0
- data/lib/expressir/eval/environment.rb +83 -0
- data/lib/expressir/eval/expression.rb +610 -0
- data/lib/expressir/eval/interpreter.rb +316 -0
- data/lib/expressir/eval/rules.rb +88 -0
- data/lib/expressir/eval/values.rb +74 -0
- data/lib/expressir/eval.rb +17 -0
- data/lib/expressir/express/builder.rb +17 -5
- data/lib/expressir/express/builders/entity_decl_builder.rb +17 -5
- data/lib/expressir/express/builders/expression_builder.rb +9 -1
- data/lib/expressir/express/checker.rb +970 -5
- data/lib/expressir/express/dialect.rb +44 -0
- data/lib/expressir/express/formatters/declarations_formatter.rb +21 -14
- data/lib/expressir/express/formatters/expressions_formatter.rb +4 -1
- data/lib/expressir/express/parser.rb +9 -4
- data/lib/expressir/express/pretty_formatter.rb +9 -14
- data/lib/expressir/express/schema_compare.rb +194 -0
- data/lib/expressir/express/shtolo.rb +194 -63
- data/lib/expressir/express.rb +3 -0
- data/lib/expressir/interop/json_schema.rb +195 -0
- data/lib/expressir/interop/owl.rb +216 -0
- data/lib/expressir/interop.rb +13 -0
- data/lib/expressir/lsp/document.rb +226 -0
- data/lib/expressir/lsp/server.rb +184 -0
- data/lib/expressir/lsp/workspace.rb +402 -0
- data/lib/expressir/lsp.rb +11 -0
- data/lib/expressir/model/declarations/entity.rb +132 -0
- data/lib/expressir/model/declarations/schema.rb +37 -6
- data/lib/expressir/p21/builder.rb +92 -0
- data/lib/expressir/p21/grammar.rb +107 -0
- data/lib/expressir/p21/parser.rb +16 -0
- data/lib/expressir/p21/population.rb +35 -0
- data/lib/expressir/p21/validator.rb +213 -0
- data/lib/expressir/p21.rb +17 -0
- data/lib/expressir/reference/grammar_crosswalk.rb +122 -0
- data/lib/expressir/reference/grammar_crosswalk.yml +800 -0
- data/lib/expressir/reference/note_catalog.rb +54 -0
- data/lib/expressir/reference.rb +10 -0
- data/lib/expressir/version.rb +1 -1
- data/lib/expressir.rb +5 -0
- data/lib/tasks/conformance.rake +27 -0
- data/lib/tasks/reference.rake +25 -0
- metadata +68 -4
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# 03 — Conformance: measure against the standard's own yardstick
|
|
2
|
+
|
|
3
|
+
## Parts (each ships)
|
|
4
|
+
|
|
5
|
+
1. Part 21 conformance corpus: extract the conformance-requirement
|
|
6
|
+
examples from the detached ISO 10303-21 source (annexes + body
|
|
7
|
+
worked examples) into fixtures; a gate spec runs the P21
|
|
8
|
+
reader/validator over every positive fixture (clean) and every
|
|
9
|
+
negative fixture (the intended note id, only).
|
|
10
|
+
2. Grammar-conformance harness: property-based generation from the
|
|
11
|
+
ISO 10303-11 Annex A/B productions (finite fragments first:
|
|
12
|
+
declarations, then expressions). Invariants: parse→format→parse
|
|
13
|
+
idempotence, formatter output re-parses, ill-formed input rejected
|
|
14
|
+
with a diagnostic (no silent recovery on the strict faces).
|
|
15
|
+
Promoted to a nightly CI tier.
|
|
16
|
+
3. G.1.7 closure: the BASED_ON enumeration-chain corpus fixture —
|
|
17
|
+
the last unaudited Annex G rule (annex-g-rules.md table tail).
|
|
18
|
+
|
|
19
|
+
## Acceptance
|
|
20
|
+
|
|
21
|
+
- `rake conformance` (or the spec tier) green; negatives fail with
|
|
22
|
+
exactly the intended note, positives with zero notes.
|
|
23
|
+
|
|
24
|
+
## Status: done
|
|
25
|
+
|
|
26
|
+
- Part 1 (Part 21 conformance corpus): the ISO 10303-21 detachment
|
|
27
|
+
examples are extracted to `spec/fixtures/p21/conformance/`:
|
|
28
|
+
annex-e-0/1 (named data sections), annex-h-0 (the worked exchange
|
|
29
|
+
structure, 13 instances), annex-i-0/1 (ANCHOR/REFERENCE), annex-j-0
|
|
30
|
+
(constants). `spec/expressir/p21/parser_conformance_spec.rb` parses
|
|
31
|
+
every positive fixture with zero notes and asserts the intended
|
|
32
|
+
failure for the forms this ladder does not implement yet (annex E
|
|
33
|
+
named sections and `..`, annex I ANCHOR/REFERENCE, annex J
|
|
34
|
+
constants/`....` and STEP-21-ED2 extended literals) — they fail
|
|
35
|
+
loudly, not silently. Malformed negatives are rejected.
|
|
36
|
+
- Part 2 (grammar-conformance harness):
|
|
37
|
+
`spec/expressir/express/formatter_roundtrip_conformance_spec.rb`
|
|
38
|
+
asserts parse → format → parse structural idempotence over a fixture
|
|
39
|
+
slice, over generated fragments (Annex A/B production levels:
|
|
40
|
+
expression → simple_expression → term, declarations, arrays, QUERY,
|
|
41
|
+
unary/logical/relational forms, deterministically seeded), and
|
|
42
|
+
rejection of terminators removed from generated input. The
|
|
43
|
+
`EXPRESSIR_CONFORMANCE=1` tier round-trips the full stepmod resource
|
|
44
|
+
slice (<250 KB; 266 files on this box) and `rake conformance` runs it; the
|
|
45
|
+
nightly `conformance.yml` workflow checks out the sparse stepmod
|
|
46
|
+
corpus. En route the generator found a formatter bug: nested unary
|
|
47
|
+
minus formatted as `--x`, which EXPRESS reads as a comment; unary
|
|
48
|
+
operands are now parenthesized. Generator lesson: relational
|
|
49
|
+
operators are non-associative, and reserved words (e.g. `VALUE`)
|
|
50
|
+
cannot name parameters.
|
|
51
|
+
- Part 3 (G.1.7 closure): the BASED_ON enumeration-chain example is in
|
|
52
|
+
`shtolo_annex_g_rule_audit_spec.rb`; every Annex G rule now has a
|
|
53
|
+
live worked example and the audit table has no unaudited tail.
|
data/TODO.sota/04-lsp.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# 04 — LSP + incremental platform
|
|
2
|
+
|
|
3
|
+
Make Expressir IDE-grade. The resolution/checking machinery is the
|
|
4
|
+
hard part and it exists; this task wires it to a language server.
|
|
5
|
+
|
|
6
|
+
## Parts (each ships)
|
|
7
|
+
|
|
8
|
+
1. Scaffold: `expressir-lsp` (solo binary or gem — decide by the
|
|
9
|
+
metanorma toolchain's needs) speaking stdio LSP 3.17: initialize,
|
|
10
|
+
diagnostics push, document symbols.
|
|
11
|
+
2. Diagnostics: Checker notes as publishDiagnostics with model-node
|
|
12
|
+
→ LSP range mapping (NodePositionIndex exists).
|
|
13
|
+
3. Navigation: definition (ScopeResolver + the USE/REFERENCE ladder +
|
|
14
|
+
alias map), references, document/rename — rename updates the
|
|
15
|
+
model in place and re-emits via the Formatter (the compare/patch
|
|
16
|
+
engine provides the structural diff safety net).
|
|
17
|
+
4. Hover: PrettyFormatter excerpt of the target declaration + its
|
|
18
|
+
remarks.
|
|
19
|
+
5. Incremental: document-open/parse via the expressir-rs core path
|
|
20
|
+
when available (parsanol incremental machinery); fallback full
|
|
21
|
+
reparse. Cold-open target: SRL-scale schema set interactive on
|
|
22
|
+
this box.
|
|
23
|
+
|
|
24
|
+
## Acceptance
|
|
25
|
+
|
|
26
|
+
- A live editor session on the stepmod corpus: diagnostics on open,
|
|
27
|
+
go-to-definition across a USE ladder, rename across two schemas
|
|
28
|
+
with the diff verified by SchemaCompare.
|
|
29
|
+
|
|
30
|
+
## Status: done
|
|
31
|
+
|
|
32
|
+
- Part 1 (scaffold): `exe/expressir-lsp` ships in the gem
|
|
33
|
+
(`executables`), speaking JSON-RPC 2.0 over stdio with LSP 3.17
|
|
34
|
+
framing (`Content-Length`), lifecycle (initialize/shutdown/exit) and
|
|
35
|
+
full-sync text documents (didOpen/didChange/didSave/didClose).
|
|
36
|
+
`Expressir::Lsp::{Document,Workspace,Server}` are autoloaded from
|
|
37
|
+
`lib/expressir/lsp.rb`.
|
|
38
|
+
- Part 2 (diagnostics): `Workspace#diagnostics` runs the Checker over
|
|
39
|
+
the open documents, maps notes through NodePositionIndex/LineMap to
|
|
40
|
+
byte→UTF-16 ranges, and publishes `textDocument/publishDiagnostics`.
|
|
41
|
+
Parse failures publish a diagnostic at the reported line/char and
|
|
42
|
+
keep the last good tree for navigation. Cross-document unresolved
|
|
43
|
+
notes are suppressed when another open document supplies the
|
|
44
|
+
referenced schema or interfaced declaration (the checker sees one
|
|
45
|
+
file at a time).
|
|
46
|
+
- Part 3 (navigation): definition resolves declaration tokens,
|
|
47
|
+
local references, the USE/REFERENCE ladder and its alias map
|
|
48
|
+
(`colour AS hue` jumps to `colour`); references walks every open
|
|
49
|
+
document and interface item; rename computes minimal edits for the
|
|
50
|
+
declaration and every reference across schemas, then applies them in
|
|
51
|
+
memory, verifies each document reparses, runs SchemaCompare to
|
|
52
|
+
reject any removal other than the renamed declaration, and re-emits
|
|
53
|
+
the renamed schema through the Formatter to prove it formats. Rename
|
|
54
|
+
keeps aliases untouched: only the imported name at the interface
|
|
55
|
+
item and usages written with the original name change.
|
|
56
|
+
- Part 4 (hover): `Express::PrettyFormatter` excerpt in a markdown
|
|
57
|
+
`express` code fence (remarks included by the formatter).
|
|
58
|
+
- Part 5 (incremental): changes reparse through the native/core parser
|
|
59
|
+
path; identical text is a no-op and checker results are memoized
|
|
60
|
+
across requests for the same document set. There is no incremental
|
|
61
|
+
parse API in the expressir-rs core to call, so true content-
|
|
62
|
+
incremental reparse remains a measured gap: cold open of the 186 KB
|
|
63
|
+
geometric_model_schema on this loaded box takes ~9.4 s (document
|
|
64
|
+
parse) and ~0.03 s for the symbol index. Recorded for an
|
|
65
|
+
expressir-rs incremental API when it exists; semantics stay Ruby.
|
|
66
|
+
- Specs: `spec/expressir/lsp/document_spec.rb` (positions, UTF-16,
|
|
67
|
+
tokens, symbols, parse-failure retention) and
|
|
68
|
+
`spec/expressir/lsp/server_spec.rb` (capabilities, diagnostics,
|
|
69
|
+
symbols, USE/alias definition, references, hover, cross-schema
|
|
70
|
+
rename verified by SchemaCompare and Formatter) — 14 examples.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# 05 — Interop exports: EXPRESS as a source
|
|
2
|
+
|
|
3
|
+
Expressir as the interchange point between EXPRESS and the rest of the
|
|
4
|
+
modeling world. These mappings are contributions (no ISO mapping
|
|
5
|
+
exists) — every decision is documented in the output module's docs.
|
|
6
|
+
|
|
7
|
+
## Parts (each ships)
|
|
8
|
+
|
|
9
|
+
1. JSON Schema export: entities → object schemas (attribute order,
|
|
10
|
+
OPTIONAL → nullable, aggregates → arrays with bounds where
|
|
11
|
+
expressible, SELECT → anyOf, ENUM → enum). Subtype handling: the
|
|
12
|
+
closure flattened into allOf groups. Documented decisions file.
|
|
13
|
+
2. OWL/RDF export: the ifcOWL lineage generalized to arbitrary
|
|
14
|
+
EXPRESS — entities → classes, supertype closure → subclass axes,
|
|
15
|
+
attributes → properties with domain/range from the model, SELECT
|
|
16
|
+
→ union semantics, WHERE rules NOT exported (documented scope
|
|
17
|
+
limit). Cite ifcOWL/EXPRESS→OWL literature in the decisions file.
|
|
18
|
+
3. Optional tier: UML/XMI export.
|
|
19
|
+
|
|
20
|
+
## Acceptance
|
|
21
|
+
|
|
22
|
+
- Export the SRL corpus; a consumer round-trip (validate exported
|
|
23
|
+
JSON Schema against a Part 21-derived JSON serialization of the
|
|
24
|
+
Annex H population).
|
|
25
|
+
|
|
26
|
+
## Status: done
|
|
27
|
+
|
|
28
|
+
- Part 1 (JSON Schema): `Expressir::Interop::JsonSchema` renders a
|
|
29
|
+
schema as JSON Schema 2020-12 — entities as object definitions
|
|
30
|
+
composed with `allOf` over `SUBTYPE OF` parents, explicit attributes
|
|
31
|
+
in declaration order, OPTIONAL attributes nullable and out of
|
|
32
|
+
`required`, aggregates as arrays with declared bounds, SELECT as
|
|
33
|
+
`anyOf` (BASED_ON folded), ENUMERATION as a string enum (BASED_ON
|
|
34
|
+
folded), defined types through to their underlying primitive.
|
|
35
|
+
Derived/inverse attributes, WHERE/UNIQUE rules and constants are
|
|
36
|
+
documented exclusions. CLI: `expressir export-json-schema`.
|
|
37
|
+
Decisions: `docs/_guides/interop/json-schema.adoc`.
|
|
38
|
+
- Part 2 (OWL/RDF): `Expressir::Interop::Owl` renders Turtle — entities
|
|
39
|
+
as `owl:Class` with `rdfs:subClassOf` per supertype, explicit
|
|
40
|
+
attributes as object/datatype properties with domain and range,
|
|
41
|
+
SELECT as an `owl:unionOf` equivalent class, ENUMERATION items as
|
|
42
|
+
individuals, primitive defined types as `rdfs:Datatype` with XSD
|
|
43
|
+
equivalences; aggregates range over `rdf:List`. WHERE/UNIQUE bodies,
|
|
44
|
+
cardinalities and aggregate bounds are documented scope limits. CLI:
|
|
45
|
+
`expressir export-owl`. Decisions and the ifcOWL lineage citations:
|
|
46
|
+
`docs/_guides/interop/owl-rdf.adoc`.
|
|
47
|
+
- Part 3 (UML/XMI): explicitly the optional tier; not shipped.
|
|
48
|
+
- Acceptance: the Annex H population is serialized to JSON in Part 21
|
|
49
|
+
slot order (supertype attributes first, `$`/`*` null, references
|
|
50
|
+
expanded with a cycle guard) and validated against the exported
|
|
51
|
+
entity definitions with an independent consumer validator in
|
|
52
|
+
`spec/expressir/interop/json_schema_spec.rb` — 13 instances, zero
|
|
53
|
+
errors; dropping a required attribute fails. A gated
|
|
54
|
+
`EXPRESSIR_CONFORMANCE` tier exports every schema in the stepmod
|
|
55
|
+
resource slice (<250 KB; >200 schemas).
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# 06 — Dialect awareness
|
|
2
|
+
|
|
3
|
+
EXPRESS the standard has editions; Expressir should speak them
|
|
4
|
+
explicitly.
|
|
5
|
+
|
|
6
|
+
## Parts (each ships)
|
|
7
|
+
|
|
8
|
+
1. Dialect flag: parser + checker accept `dialect: :"10303-11:1994" |
|
|
9
|
+
:"10303-11:2004"` (default 2004). Gating: EXTENSIBLE/BASED_ON/
|
|
10
|
+
GENERIC_ENTITY are 2004-only (1994 corpora exist in legacy
|
|
11
|
+
resources); 1994 rejects them with a dialect note, 2004 accepts.
|
|
12
|
+
2. Amendment tracking: the Amd1 change list as a source document;
|
|
13
|
+
edition-sensitive checker notes (`:check_dialect_*`).
|
|
14
|
+
3. Corpus pass: run both dialects over the resource slice; mixed
|
|
15
|
+
dialects in one file produce a clear diagnostic.
|
|
16
|
+
|
|
17
|
+
## Acceptance
|
|
18
|
+
|
|
19
|
+
- A 1994-era resource schema parses clean under 1994, flags its
|
|
20
|
+
non-1994 constructs under 2004-diagnostics mode.
|
|
21
|
+
|
|
22
|
+
## Status: done
|
|
23
|
+
|
|
24
|
+
- Part 1 (dialect flag): `Expressir::Express::Dialect` normalizes the
|
|
25
|
+
`:"10303-11:1994"` / `:"10303-11:2004"` editions (also "1994",
|
|
26
|
+
"2004", full strings) and rejects anything else with
|
|
27
|
+
`InvalidOptionError`. `Parser.from_file/from_files/from_exp` accept
|
|
28
|
+
`dialect:` (default 2004) and validate it; the grammar parses the
|
|
29
|
+
union of both editions so a model can be inspected under either.
|
|
30
|
+
`Checker.new(repository, dialect:)` emits the edition notes:
|
|
31
|
+
under 1994, `:check_dialect_2004_only` (error) for EXTENSIBLE,
|
|
32
|
+
BASED_ON, GENERIC_ENTITY and SUBTYPE_CONSTRAINT declarations; under
|
|
33
|
+
2004, `:check_dialect_deprecated` (warning) for the edition-1 inline
|
|
34
|
+
subtype-constraint syntax that Annex K deprecates in favour of
|
|
35
|
+
SUBTYPE_CONSTRAINT. Notes are emitted only when a dialect is passed,
|
|
36
|
+
so the default checker report is unchanged.
|
|
37
|
+
- Part 2 (amendment tracking): the audited change list is a checked-in
|
|
38
|
+
source document at
|
|
39
|
+
`spec/fixtures/dialects/iso-10303-11-2004-changes.yaml`, with the
|
|
40
|
+
clause each construct comes from (8.4.1, 8.4.2, clause 9, Annex K,
|
|
41
|
+
Annex G) and a live example per entry.
|
|
42
|
+
`spec/expressir/express/dialect_spec.rb` asserts every change entry's
|
|
43
|
+
declared note fires under 1994 (or 2004 for the deprecated syntax),
|
|
44
|
+
that no note id is outside `Dialect::NOTE_IDS`, and that the 2004
|
|
45
|
+
examples are accepted under 2004. A 1994-era plain schema produces
|
|
46
|
+
no notes under either dialect.
|
|
47
|
+
- Part 3 (corpus pass): a gated `EXPRESSIR_CONFORMANCE` tier runs both
|
|
48
|
+
dialects over the stepmod resource slice (266 files <250 KB), and
|
|
49
|
+
`:check_dialect_mixed` gives one clear diagnostic when a file
|
|
50
|
+
combines 2004-only declarations with edition-1 inline
|
|
51
|
+
subtype-constraint syntax. Installations without the corpus skip the
|
|
52
|
+
tier.
|
|
53
|
+
- Limitation recorded: the 2004 text grammar is effectively a superset
|
|
54
|
+
of 1994, so the only edition-1-only signals available to a text
|
|
55
|
+
checker are the Annex K deprecations; EXPRESS-G notation and the
|
|
56
|
+
enumeration-ordering semantics deprecated by Annex K have no text
|
|
57
|
+
form to flag.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# 07 — Reference artifacts: the citable Expressir
|
|
2
|
+
|
|
3
|
+
The academic endgame — make the implementation provable and citable.
|
|
4
|
+
|
|
5
|
+
## Parts (each ships)
|
|
6
|
+
|
|
7
|
+
1. Grammar cross-walk: rule-by-rule table, parsanol grammar rule ↔
|
|
8
|
+
ISO 10303-11 Annex A/B production, with divergences (extensions,
|
|
9
|
+
recoveries) classified — rendered into docs/ and kept in sync by a
|
|
10
|
+
spec that fails when a grammar rule lacks a row.
|
|
11
|
+
2. Property-based corpus testing as a published nightly tier (03's
|
|
12
|
+
harness, trended: parse rate, diagnostic rate, idempotence rate).
|
|
13
|
+
3. Published guides: one doc per subsystem (checker + note-id
|
|
14
|
+
catalog, shtolo + annex-g-rules linkage, p21, evaluator, lsp),
|
|
15
|
+
generated where possible from the model (note-id catalog from the
|
|
16
|
+
Checker's constants).
|
|
17
|
+
|
|
18
|
+
## Acceptance
|
|
19
|
+
|
|
20
|
+
- docs/ builds with the cross-walk and guides; the sync spec is part
|
|
21
|
+
of the default suite.
|
|
22
|
+
|
|
23
|
+
## Status: done
|
|
24
|
+
|
|
25
|
+
- Part 1 (grammar cross-walk): `Expressir::Reference::GrammarCrosswalk`
|
|
26
|
+
reads the audited mapping in
|
|
27
|
+
`lib/expressir/reference/grammar_crosswalk.yml` and renders
|
|
28
|
+
`docs/_guides/reference/grammar-crosswalk.adoc`. All 250 parsanol
|
|
29
|
+
rules are accounted for: 207 aligned with the same-named Annex A
|
|
30
|
+
production (CamelCase normalized to snake_case), 8 decomposed into
|
|
31
|
+
PEG sub-rules, 30 literal operator/delimiter tokens, 4 lexical
|
|
32
|
+
whitespace/delimiter rules and 1 PEG-internal keyword guard. The 12
|
|
33
|
+
Annex A productions without a dedicated rule are listed and
|
|
34
|
+
classified (remark productions are handled by
|
|
35
|
+
RemarkScanner/RemarkAttacher; the rest are PEG lookaheads or
|
|
36
|
+
character classes). The Annex A snapshot lives at
|
|
37
|
+
`spec/fixtures/reference/annex-ab-productions.txt`. The spec fails
|
|
38
|
+
when a grammar rule lacks a row, a row names a missing rule/status,
|
|
39
|
+
an Annex production is unaccounted for, or the published guide is
|
|
40
|
+
stale; regenerate with `rake reference:crosswalk`.
|
|
41
|
+
- Part 2 (trended nightly tier): `Expressir::Conformance::Trend`
|
|
42
|
+
measures a corpus slice — file count, parse rate, format-idempotence
|
|
43
|
+
rate, diagnostic rate (Checker notes per parsed file), error/warning counts and per-note-id counts —
|
|
44
|
+
and writes a JSON artifact. `rake conformance:trend` runs it over the
|
|
45
|
+
stepmod resource slice; the nightly `conformance.yml` workflow runs
|
|
46
|
+
it after the round-trip tier and uploads `conformance-trend.json`.
|
|
47
|
+
Spec: `spec/expressir/conformance/trend_spec.rb`.
|
|
48
|
+
- Part 3 (published guides): `docs/_guides/reference/` now carries an
|
|
49
|
+
index plus subsystem guides — checker (with the generated note-id
|
|
50
|
+
catalog, `rake reference:notes`), Part 21, SHTOLO/Annex G (linked to
|
|
51
|
+
`annex-g-rules.md` and the audit spec), evaluator, and the language
|
|
52
|
+
server. The two generated pages are checked for staleness by
|
|
53
|
+
`spec/expressir/reference/*_spec.rb`, which run in the default suite.
|
|
54
|
+
The docs site build (`.github/workflows/docs.yml`) covers the new
|
|
55
|
+
pages.
|
|
@@ -1,15 +1,12 @@
|
|
|
1
|
-
# 07 — Part 28 XML: select mapping v2 (#276)
|
|
1
|
+
# 07 — Part 28 XML: select mapping v2 (#276) — DONE
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
Shipped: the ISO 10303-28 SELECT mapping lives in
|
|
4
|
+
lib/expressir/express/xsd.rb (complexType + xs:choice, entity members
|
|
5
|
+
as global-element refs, defined-type members by name+type, extensible-
|
|
6
|
+
empty fallback to sequence) and is covered by spec/expressir/express/
|
|
7
|
+
xsd_spec.rb. The CLI exposes both halves: `expressir xsd` and
|
|
8
|
+
`expressir xml-index` (#503).
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
- validate generated XSDs against the ISO 10303-28 conformance examples
|
|
12
|
-
|
|
13
|
-
## Acceptance
|
|
14
|
-
- a select-typed attribute renders per the standard (not xs:anyType)
|
|
15
|
-
- the v1 examples still generate unchanged except where v2 improves them
|
|
10
|
+
Remaining escalation (moved to parity-ee 17 scope): validating the
|
|
11
|
+
generated XSDs against the Part 28 reference corpus — the detached
|
|
12
|
+
docs carry the standard text only, not the reference XSDs.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Interop Exports
|
|
3
|
+
nav_order: 12
|
|
4
|
+
has_children: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
= Interop Exports
|
|
8
|
+
|
|
9
|
+
== Purpose
|
|
10
|
+
|
|
11
|
+
Expressir can render an EXPRESS schema into JSON Schema and OWL/RDF.
|
|
12
|
+
No ISO mapping exists for either rendering: these are contributions of
|
|
13
|
+
the Expressir project, and the decisions behind them are documented in
|
|
14
|
+
the child guides so consumers can rely on stable semantics.
|
|
15
|
+
|
|
16
|
+
== Commands
|
|
17
|
+
|
|
18
|
+
[source,shell]
|
|
19
|
+
----
|
|
20
|
+
expressir export-json-schema path/to/schema.exp -o schema.json
|
|
21
|
+
expressir export-owl path/to/schema.exp -o schema.ttl
|
|
22
|
+
----
|
|
23
|
+
|
|
24
|
+
The Ruby API is available as `Expressir::Interop::JsonSchema` and
|
|
25
|
+
`Expressir::Interop::Owl`.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: JSON Schema Export
|
|
3
|
+
parent: Interop Exports
|
|
4
|
+
grand_parent: Guides
|
|
5
|
+
nav_order: 1
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
= JSON Schema Export
|
|
9
|
+
|
|
10
|
+
== Purpose
|
|
11
|
+
|
|
12
|
+
`Expressir::Interop::JsonSchema` renders one EXPRESS schema as a JSON
|
|
13
|
+
Schema 2020-12 document. The mapping is a project contribution; this
|
|
14
|
+
guide records every decision so consumers can depend on it.
|
|
15
|
+
|
|
16
|
+
== Mapping decisions
|
|
17
|
+
|
|
18
|
+
Entities::
|
|
19
|
+
Each entity becomes a definition under `$defs`. An entity with
|
|
20
|
+
supertypes is an `allOf` of one `$ref` per `SUBTYPE OF` parent plus an
|
|
21
|
+
object schema holding its own explicit attributes. The subtype closure
|
|
22
|
+
is therefore expressed compositionally rather than duplicated.
|
|
23
|
+
Attributes appear in declaration order (inherited attributes come
|
|
24
|
+
through the parent branch of `allOf`). An entity without supertypes is
|
|
25
|
+
the object schema itself with a `title`.
|
|
26
|
+
|
|
27
|
+
Explicit attributes::
|
|
28
|
+
Only explicit attributes are exported. Derived and inverse attributes
|
|
29
|
+
are not part of the Part 21 exchange structure and are omitted.
|
|
30
|
+
|
|
31
|
+
OPTIONAL attributes::
|
|
32
|
+
An optional attribute is left out of `required` and its type becomes
|
|
33
|
+
`anyOf: [type, {type: null}]` — absent and explicit `$` both validate.
|
|
34
|
+
|
|
35
|
+
Types::
|
|
36
|
+
`INTEGER` → `integer`; `REAL`/`NUMBER` → `number`; `STRING` → `string`;
|
|
37
|
+
`BOOLEAN` → `boolean`; `LOGICAL` → `enum: [true, false, null]`
|
|
38
|
+
(`UNKNOWN` maps to null); `BINARY` → a string matching `[01]*`.
|
|
39
|
+
|
|
40
|
+
Enumerations::
|
|
41
|
+
An `ENUMERATION` becomes `{type: string, enum: [...]}`. `BASED_ON`
|
|
42
|
+
chains are folded into the full domain, matching Annex G semantics.
|
|
43
|
+
|
|
44
|
+
SELECT::
|
|
45
|
+
A named select becomes `{anyOf: [$ref, ...]}` over its items;
|
|
46
|
+
`BASED_ON` chains are folded into the full item list. Items referencing
|
|
47
|
+
declarations are `$ref`s.
|
|
48
|
+
|
|
49
|
+
Aggregates::
|
|
50
|
+
`LIST`, `ARRAY`, `SET` and `BAG` become JSON arrays. `minItems` and
|
|
51
|
+
`maxItems` come from the declared bounds (an unbounded upper bound is
|
|
52
|
+
omitted). `SET`, and `LIST ... OF UNIQUE`, set `uniqueItems: true`.
|
|
53
|
+
|
|
54
|
+
Names::
|
|
55
|
+
EXPRESS identifiers are used verbatim. EXPRESS is case-insensitive but
|
|
56
|
+
preserves case; JSON property names are case-sensitive, so consumers
|
|
57
|
+
must use the declared spelling.
|
|
58
|
+
|
|
59
|
+
Root document::
|
|
60
|
+
The root carries `$schema`, `$id`, `title`, every declaration in
|
|
61
|
+
`$defs`, and an `anyOf` over the entity definitions (one JSON document
|
|
62
|
+
describes one entity instance). A schema with no entities has no root
|
|
63
|
+
`anyOf`. Because an instance of a subtype also satisfies each ancestor
|
|
64
|
+
definition, a consumer that knows the EXPRESS entity of an instance
|
|
65
|
+
should validate against that entity's definition under `$defs` rather
|
|
66
|
+
than the root `anyOf`.
|
|
67
|
+
|
|
68
|
+
Not exported::
|
|
69
|
+
`WHERE` and `UNIQUE` rules, `GENERIC`/`GENERIC_ENTITY`, constants and
|
|
70
|
+
subtype constraint expressions. They have no direct JSON Schema
|
|
71
|
+
counterpart and are left to the consumer's semantic layer.
|
|
72
|
+
|
|
73
|
+
== Programmatic use
|
|
74
|
+
|
|
75
|
+
[source,ruby]
|
|
76
|
+
----
|
|
77
|
+
schema = Expressir::Express::Parser.from_file("example.exp").schemas.first
|
|
78
|
+
document = Expressir::Interop::JsonSchema.new(schema).to_json
|
|
79
|
+
File.write("example.schema.json", document)
|
|
80
|
+
----
|
|
81
|
+
|
|
82
|
+
== Part 21 population check
|
|
83
|
+
|
|
84
|
+
Part 21 instances serialize to JSON objects keyed by attribute name in
|
|
85
|
+
the Part 21 slot order (supertype attributes first), with `$` and `*`
|
|
86
|
+
omitted or null, enum values as strings, and references expanded
|
|
87
|
+
in-line (a cycle guard falls back to `{"$ref": "#id"}`). The acceptance
|
|
88
|
+
spec validates the Annex H population against the exported schema.
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: OWL/RDF Export
|
|
3
|
+
parent: Interop Exports
|
|
4
|
+
grand_parent: Guides
|
|
5
|
+
nav_order: 2
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
= OWL/RDF Export
|
|
9
|
+
|
|
10
|
+
== Purpose
|
|
11
|
+
|
|
12
|
+
`Expressir::Interop::Owl` renders one EXPRESS schema as OWL 2 in Turtle.
|
|
13
|
+
The approach generalizes the ifcOWL lineage from IFC to arbitrary
|
|
14
|
+
EXPRESS. This guide records the decisions and the literature the
|
|
15
|
+
approach follows.
|
|
16
|
+
|
|
17
|
+
== Lineage
|
|
18
|
+
|
|
19
|
+
The mapping follows the published EXPRESS-to-OWL work:
|
|
20
|
+
|
|
21
|
+
* J. Beetz, J. van Leeuwen, B. de Vries, "IfcOWL: A case of transforming
|
|
22
|
+
EXPRESS schemas into ontologies", _Artificial Intelligence for
|
|
23
|
+
Engineering Design, Analysis and Manufacturing_ 23(1), 2009, 89-101.
|
|
24
|
+
* P. Pauwels, W. Terkaj, "EXPRESS to OWL for construction industry:
|
|
25
|
+
Towards a recommendable and usable ifcOWL ontology", _Automation in
|
|
26
|
+
Construction_ 63, 2016, 100-133.
|
|
27
|
+
* W. Terkaj, A. Sojic, "Ontology-based representation of IFC EXPRESS
|
|
28
|
+
rules: An enhancement of the ifcOWL ontology", _Automation in
|
|
29
|
+
Construction_ 57, 2015, 188-201.
|
|
30
|
+
|
|
31
|
+
The last reference is the source of our scope decision on WHERE rules:
|
|
32
|
+
this exporter does not translate rule bodies (see below).
|
|
33
|
+
|
|
34
|
+
== Mapping decisions
|
|
35
|
+
|
|
36
|
+
Entities::
|
|
37
|
+
Each entity becomes an `owl:Class` with one `rdfs:subClassOf` per
|
|
38
|
+
`SUBTYPE OF` parent. Abstract entities carry an `rdfs:comment
|
|
39
|
+
"EXPRESS ABSTRACT SUPERTYPE"`; they are not made equivalent to their
|
|
40
|
+
subtype union.
|
|
41
|
+
|
|
42
|
+
Explicit attributes::
|
|
43
|
+
Each explicit attribute becomes a property with `rdfs:domain` on its
|
|
44
|
+
entity and `rdfs:range` from the attribute type. Entity, select and
|
|
45
|
+
enumeration ranges are object properties; primitive ranges are
|
|
46
|
+
datatype properties. `OPTIONAL` is recorded as an `rdfs:comment`
|
|
47
|
+
rather than an OWL cardinality restriction, because cardinalities
|
|
48
|
+
belong to the entity class and would multiply restrictions per
|
|
49
|
+
attribute.
|
|
50
|
+
|
|
51
|
+
Primitive types::
|
|
52
|
+
`INTEGER` → `xsd:integer`; `REAL`/`NUMBER` → `xsd:double`; `STRING` →
|
|
53
|
+
`xsd:string`; `BOOLEAN` → `xsd:boolean`; `BINARY` → `xsd:hexBinary`.
|
|
54
|
+
`LOGICAL` maps to `xsd:boolean`; EXPRESS `UNKNOWN` has no XSD
|
|
55
|
+
counterpart and is a documented loss. Defined types over primitives are
|
|
56
|
+
emitted as `rdfs:Datatype` with `owl:equivalentClass` to the XSD type.
|
|
57
|
+
|
|
58
|
+
Aggregates::
|
|
59
|
+
`LIST`, `ARRAY`, `SET` and `BAG` attributes are object properties with
|
|
60
|
+
range `rdf:List`; element type and ordering live in the RDF collection.
|
|
61
|
+
|
|
62
|
+
SELECT::
|
|
63
|
+
A named select becomes an `owl:Class` with an `owl:equivalentClass`
|
|
64
|
+
restriction whose `owl:unionOf` lists the item classes (union
|
|
65
|
+
semantics). `BASED_ON` chains are folded into the item list.
|
|
66
|
+
|
|
67
|
+
Enumerations::
|
|
68
|
+
An enumeration becomes an `owl:Class`; each item becomes an
|
|
69
|
+
`owl:NamedIndividual` of that class. `BASED_ON` chains are folded.
|
|
70
|
+
|
|
71
|
+
Not exported::
|
|
72
|
+
`WHERE` and `UNIQUE` rule bodies, subtype constraint expressions,
|
|
73
|
+
derived and inverse attributes, and aggregate bounds. Rule translation
|
|
74
|
+
is a research problem in its own right (see Terkaj & Sojic); consumers
|
|
75
|
+
that need rule semantics should consume the EXPRESS model directly.
|
|
76
|
+
|
|
77
|
+
== Programmatic use
|
|
78
|
+
|
|
79
|
+
[source,ruby]
|
|
80
|
+
----
|
|
81
|
+
schema = Expressir::Express::Parser.from_file("example.exp").schemas.first
|
|
82
|
+
turtle = Expressir::Interop::Owl.new(
|
|
83
|
+
schema,
|
|
84
|
+
base_iri: "https://example.org/my-schema#",
|
|
85
|
+
).export
|
|
86
|
+
File.write("example.ttl", turtle)
|
|
87
|
+
----
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
= Checker note-id catalog
|
|
2
|
+
|
|
3
|
+
// Generated from lib/expressir/express/checker.rb by
|
|
4
|
+
// `rake reference:notes`. Do not edit by hand; the reference
|
|
5
|
+
// spec fails when this file is stale.
|
|
6
|
+
|
|
7
|
+
== Purpose
|
|
8
|
+
|
|
9
|
+
Every note id the Checker can raise, with the number of call
|
|
10
|
+
sites in the implementation. New checks use `:check_*` ids;
|
|
11
|
+
the conformance-derived ids (`:check_expr_*`, `:check_dialect_*`)
|
|
12
|
+
cite their clause in the note message.
|
|
13
|
+
|
|
14
|
+
[cols="3,1", options="header"]
|
|
15
|
+
|===
|
|
16
|
+
| Note id | Call sites
|
|
17
|
+
|
|
18
|
+
| `check_agg_type` | 1
|
|
19
|
+
| `check_attrib_name_fun` | 1
|
|
20
|
+
| `check_attribute_redeclaration` | 3
|
|
21
|
+
| `check_dialect_2004_only` | 1
|
|
22
|
+
| `check_dialect_deprecated` | 1
|
|
23
|
+
| `check_dialect_mixed` | 1
|
|
24
|
+
| `check_duplicate_declaration` | 1
|
|
25
|
+
| `check_enumeration_extended_type` | 1
|
|
26
|
+
| `check_expr_assignment_type` | 1
|
|
27
|
+
| `check_expr_initializer_type` | 1
|
|
28
|
+
| `check_expr_operand_domain` | 7
|
|
29
|
+
| `check_expr_return` | 2
|
|
30
|
+
| `check_expr_unique_duplicate` | 1
|
|
31
|
+
| `check_expr_where_boolean` | 1
|
|
32
|
+
| `check_interface_kind_restriction` | 1
|
|
33
|
+
| `check_inverse_attrib_ref` | 2
|
|
34
|
+
| `check_inverse_derive` | 1
|
|
35
|
+
| `check_inverse_entity` | 1
|
|
36
|
+
| `check_inverse_inverse` | 1
|
|
37
|
+
| `check_schema_iface_resource_duplicate` | 1
|
|
38
|
+
| `check_schema_interface_redundant` | 1
|
|
39
|
+
| `check_select_extended_type` | 1
|
|
40
|
+
| `check_select_named_type` | 1
|
|
41
|
+
| `check_self_schema_reference` | 2
|
|
42
|
+
| `check_string_no_entity` | 1
|
|
43
|
+
| `check_subtype_cycle` | 1
|
|
44
|
+
| `check_subtype_ref` | 1
|
|
45
|
+
| `check_subtypeof_invalid` | 1
|
|
46
|
+
| `check_supertype_ref` | 2
|
|
47
|
+
| `check_unique_name_pattern` | 1
|
|
48
|
+
| `check_unresolved_ref` | 3
|
|
49
|
+
| `check_where_name_pattern` | 1
|
|
50
|
+
| `qualified_attrib_attr_not_found` | 1
|
|
51
|
+
| `qualified_attrib_group_not_ancestor` | 1
|
|
52
|
+
| `qualified_attrib_group_not_found` | 1
|
|
53
|
+
|===
|
|
54
|
+
|
|
55
|
+
The catalog covers 35 note ids.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Checker
|
|
3
|
+
parent: Reference
|
|
4
|
+
grand_parent: Guides
|
|
5
|
+
nav_order: 3
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
= Checker
|
|
9
|
+
|
|
10
|
+
== Purpose
|
|
11
|
+
|
|
12
|
+
`Expressir::Express::Checker` performs static, edition-aware semantic
|
|
13
|
+
checks over a parsed repository. Notes carry a stable id, a severity,
|
|
14
|
+
the schema, a message citing the ISO 10303-11 clause where the check
|
|
15
|
+
comes from, and the offending model node.
|
|
16
|
+
|
|
17
|
+
== Note ids
|
|
18
|
+
|
|
19
|
+
The catalog is generated from the checker source and published as the
|
|
20
|
+
"Checker note-id catalog" guide. New conformance-derived
|
|
21
|
+
checks use `:check_expr_*`, `:check_statement_*`, `:check_rule_*` and
|
|
22
|
+
`:check_dialect_*` ids; the message carries the clause.
|
|
23
|
+
|
|
24
|
+
== Dialects
|
|
25
|
+
|
|
26
|
+
`Checker.new(repository, dialect: :"10303-11:1994")` reports
|
|
27
|
+
2004-only constructs as errors when targeting the 1994 edition;
|
|
28
|
+
`dialect: :"10303-11:2004"` reports the Annex K deprecated inline
|
|
29
|
+
subtype-constraint syntax as warnings. Without a dialect the report is
|
|
30
|
+
unchanged. See the Dialect awareness task notes (TODO.sota/06).
|
|
31
|
+
|
|
32
|
+
== Severities and validity
|
|
33
|
+
|
|
34
|
+
`Checker#valid?` is true when no error-severity note was raised.
|
|
35
|
+
Indeterminate expression results are not violations; only a proven
|
|
36
|
+
false WHERE rule is.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Evaluator
|
|
3
|
+
parent: Reference
|
|
4
|
+
grand_parent: Guides
|
|
5
|
+
nav_order: 6
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
= Evaluator
|
|
9
|
+
|
|
10
|
+
== Purpose
|
|
11
|
+
|
|
12
|
+
`Expressir::Eval` executes EXPRESS: expressions over a value model,
|
|
13
|
+
functions (parameters, locals, control flow), and WHERE rules over a
|
|
14
|
+
Part 21 population.
|
|
15
|
+
|
|
16
|
+
== Expressions
|
|
17
|
+
|
|
18
|
+
`Expressir::Eval::Expression` implements ISO 10303-11 clause 12:
|
|
19
|
+
arithmetic with result typing, logical tables (12.4), relational
|
|
20
|
+
orderings (12.2.1), IN (12.2.3), LIKE patterns (12.2.5, table 11),
|
|
21
|
+
intervals, aggregate operations (tables 16-18 including element
|
|
22
|
+
singletons), QUERY, and indeterminate propagation. The value model
|
|
23
|
+
lives in `Values`: logical constants, enumeration and binary values,
|
|
24
|
+
aggregates and Part 21 instances.
|
|
25
|
+
|
|
26
|
+
== Execution
|
|
27
|
+
|
|
28
|
+
`Expressir::Eval::Interpreter` runs functions and procedures:
|
|
29
|
+
assignment (including indexed), IF/CASE, WHILE/UNTIL/increment REPEAT
|
|
30
|
+
with SKIP and ESCAPE, RETURN (falling off the end is an error), and the
|
|
31
|
+
builtin set A (`ABS` … `VALUE`, `TYPEOF`, `USEDIN`). Populations are
|
|
32
|
+
read through `Expressir::Eval::Environment`, which maps Part 21 slots
|
|
33
|
+
in clause 12 order.
|
|
34
|
+
|
|
35
|
+
== Rules
|
|
36
|
+
|
|
37
|
+
`Expressir::Eval::Rules.check(population, schema)` evaluates each
|
|
38
|
+
instance's entity WHERE rules with `SELF` and both bare and
|
|
39
|
+
`SELF\attribute` bindings. A rule is violated only when it evaluates
|
|
40
|
+
to false; indeterminate is not a violation (clause 9.4).
|