diff --git a/Cargo.lock b/Cargo.lock index 2a7c64717a..dff00b4974 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4328,6 +4328,7 @@ dependencies = [ "jbotci-source", "jbotci-syntax", "jbotci-tree", + "roxmltree 0.21.1", "serde", "serde_json", "sha2", diff --git a/apps/jbotci-server/src/lib.rs b/apps/jbotci-server/src/lib.rs index 1d715a22fd..f56fc102f3 100644 --- a/apps/jbotci-server/src/lib.rs +++ b/apps/jbotci-server/src/lib.rs @@ -2846,21 +2846,21 @@ mod tests { .expect("tersmu XML text"); // With definitions on (the default), tersmu returns one well-formed // XML document: structured WORD cards live in the WORDS section - // following KEY, not in a prepended text block. + // (the root's first child, after the KEY comment; jbotci#719), not in + // a prepended text block. assert!( - tersmu_text.starts_with("")); - let after_key = tersmu_text - .split_once("") - .expect("KEY closes before WORDS") + let after_root = tersmu_text + .split_once("\n")); - let words_section = after_key + assert!(after_root.contains(">\n \n")); + let words_section = after_root .split_once("") - .expect("WORDS closes before WAIVERS") + .expect("WORDS section closes") .0; assert!(words_section.contains("")); assert!(words_section.contains("")); @@ -2922,7 +2922,10 @@ mod tests { let tersmu_xml_text = tersmu_xml["result"]["content"][0]["text"] .as_str() .expect("tersmu XML text"); - assert!(tersmu_xml_text.starts_with("")); + assert!(tersmu_xml_text.starts_with(" @@ -20,24 +21,27 @@ A document is a single SFN root element in one of two forms: * COMPACT form (no FORM attribute): the canonical rendering. Top-level - child order is KEY, optional WORDS, WAIVERS, optional DEFS, exactly - one rendered graph-root element (normally UTTERANCE), optional - UNREACHABLE. + child order is optional WORDS, optional DEFS, exactly one rendered + graph-root element (normally UTTERANCE), optional UNREACHABLE. * TYPED-GRAPH form (FORM="TYPED-GRAPH"): the lossless fallback used when the graph contains a construct the compact notation cannot represent. - Top-level child order is KEY (whose last child is - COMPACT-INCOMPATIBILITIES listing why), WAIVERS, TYPED-GRAPH. + Top-level child order is COMPACT-INCOMPATIBILITIES (listing why), + TYPED-GRAPH. + + The notation's teaching text is a single XML comment before the root + element (jbotci#719); as a comment it is invisible to this schema. + There are no KEY/RULE, WAIVERS, or CONNECTOR elements. XSD 1.0 cannot condition a content model on an attribute value, so the SFN type below admits both shapes in one sequence; the exact per-form shapes above are normative prose here and are renderer-enforced. - Lexical categories (mirrors the KEY rule "lexical-categories"): UPPERCASE + Lexical categories (mirrors the KEY comment's lexical-categories rule): UPPERCASE names are structural keywords (element and attribute names); PascalCase values are sorts; lowercase values are content words as data only; quoted attribute strings are names. - ID/IDREF discipline (mirrors the KEY rules "ids", "ground", "some", + ID/IDREF discipline (mirrors the KEY comment's ids, ground, some rules, "defs"): graph-node ids are opaque, JSON-aligned tokens matching [reupfqvsdmxo][0-9]+ (prefix by object kind: r/e referent, u utterance, p predication, f formula, q quantity, v variable/parameter, s sequence, @@ -333,7 +337,7 @@ The eight facet attribute/element names. As attributes they appear on referents and binders; absence of a facet attribute means - UNSPECIFIED (no commitment) — see the KEY rule "facet-silence". + UNSPECIFIED (no commitment) — see the KEY comment's facet-silence rule. A facet too structured for a single token is instead rendered as a FACET child element carrying this name in its NAME attribute. @@ -384,7 +388,7 @@ A non-empty space-separated list of 1-based argument-place indices - (the "atomic-lists" KEY rule: simple id or number lists are + (the KEY comment's atomic-lists rule: simple id or number lists are NMTOKENS attributes, never child elements). @@ -393,6 +397,19 @@ + + + + A four-row binary truth table in the builder's row order (TT, TF, + FT, FF), one T or F per row. Rendered only when the parent + operator does not already determine the table (jbotci#719). + + + + + + + @@ -400,7 +417,7 @@ EXPLICIT = the word itself encodes the boundary; ASSUMED-LEFT = the CLL default left-grouping assumption. These describe the basis of the displayed tree, not the coiner's - guaranteed intent (KEY rule "compound-assumptions"). + guaranteed intent (the KEY comment's compound-assumptions rule). @@ -456,7 +473,7 @@ The definition-site id attribute. Present exactly when this occurrence defines the shared graph node (all non-binder definitions sit in a DEFS in the smallest graph scope strictly containing all - uses — the "defs" KEY rule); absent at inline single-use sites. + uses — the KEY comment's defs rule); absent at inline single-use sites. Always serialized as the first attribute. @@ -489,7 +506,7 @@ - Scope-dependence markers (KEY rules "scope-dependence" and + Scope-dependence markers (the KEY comment's scope-dependence rules and "scope-dependence-subsets"). SAME-FOR-ALL="true" means the referent is fixed despite a nonempty first-visit binder universe; POSSIBLY-DIFFERENT-PER is a space-separated strict nonempty subset @@ -651,7 +668,7 @@ One semantic diagnostic of severity warning; the character content is - the diagnostic message (KEY rule "warnings"). Repeatable; appended + the diagnostic message (the KEY comment's warnings rule). Repeatable; appended after all other children of the element whose object carried the diagnostic, and also used inside WORD cards. @@ -695,7 +712,7 @@ REF= instead of children. FORALL and CARDINALITY always write RESTRICTION and BODY explicitly (empty as RESTRICTION/ or BODY/ when the graph supplies nothing); EXISTS writes RESTRICTION exactly when - the graph supplies one (KEY rule "quantifiers"). + the graph supplies one (the KEY comment's quantifiers rule). @@ -738,7 +755,7 @@ Typed QUESTION metadata attached to the abstraction formula named by - the enclosing BODY (KEY rule "embedded-questions"): one rendered + the enclosing BODY (the KEY comment's embedded-questions rule): one rendered question pointer per embedded question, in order. @@ -751,7 +768,7 @@ - The reserved first child of a PREDICATION: its Eventuality referent, never a numbered ARG (KEY rule "event-field"). + The reserved first child of a PREDICATION: its Eventuality referent, never a numbered ARG (the KEY comment's event-field rule). An anchor referent of a facet, displayed content, or aspect: the eventuality or time the facet is anchored to. @@ -778,7 +795,7 @@ The presupposed answer recorded on a QUESTION, when the graph carries one. - Links an ADJUNCT's metadata to the host component it applies to (KEY rule "adjuncts"). + Links an ADJUNCT's metadata to the host component it applies to (the KEY comment's adjuncts rule). The cardinality quantity of a CARDINALITY binder. @@ -919,16 +936,17 @@ The document root. See the schema-level annotation for the two document forms. The type below admits both shapes because XSD 1.0 cannot condition the content model on the FORM attribute: - compact form = KEY, WORDS?, WAIVERS, DEFS?, one graph-root element, - UNREACHABLE?; TYPED-GRAPH form = KEY (with COMPACT-INCOMPATIBILITIES), - WAIVERS, TYPED-GRAPH. + compact form = WORDS?, DEFS?, one graph-root element, + UNREACHABLE?; TYPED-GRAPH form = COMPACT-INCOMPATIBILITIES, + TYPED-GRAPH. The teaching KEY is a single XML comment before the + root element (jbotci#719); as a comment it is invisible to this + schema, and the former KEY/RULE and WAIVERS elements are gone. - - + @@ -978,51 +996,6 @@ - - - - The notation key: an ordered list of RULE teaching texts, always the - first child of SFN. In the TYPED-GRAPH form it is followed inside - KEY by COMPACT-INCOMPATIBILITIES. - - - - - - - - - - - - - - One teaching rule of the notation; character content is the rule - prose. TOPIC names the rule. The topic set grows with the notation - itself (the renderer adds topics when new sections — e.g. word - cards — appear), so TOPIC is deliberately typed as an open string, - documented rather than enumerated: the schema must not become a - second source of truth that silently drifts from the renderer's KEY - tables. Current compact topics, in emission order: ids, - lexical-categories, sorts, embedded-questions, kind-composition, - warnings, some, ground, quantifiers, scope-dependence, - scope-dependence-subsets, number-neutrality, personal-reference, - speaker-anchor, facet-silence, event-field, adjuncts, pro-sumti, - mode, defs, atomic-lists, order; plus, when a WORDS section is - present: word-cards, compound-approximation, compound-places, - compound-assumptions, context-placeholders, word-card-ids. - TYPED-GRAPH topics: form, objects, fields, elided-zohe. - - - - - - - - - - - @@ -1072,38 +1045,10 @@ - - - - The provenance waivers: one WAIVER per omission family the - owner-approved design permits (source records, assigned names, - descriptor words, introducedBy markers, quantity value text, - bound-variable words, composition relation labels). Always present, - possibly empty. - - - - - - - - - - - - One waiver; character content is the waiver message with interpolated counts. - - - - - - - - - A declaration scope (KEY rule "defs"): DEICTIC-GROUND declarations + A declaration scope (the KEY comment's defs rule): DEICTIC-GROUND declarations first, then graph-node definitions, each carrying ID=. Sits in the smallest graph scope strictly containing all uses of its definitions; always the first child of its parent. Emitted only @@ -1122,8 +1067,8 @@ - Declaration of one shared speech-situation unit (KEY rule - "ground"). ID is a notation-level g-prefixed rendering id (the JSON + Declaration of one shared speech-situation unit (the KEY + comment ground rule). ID is a notation-level g-prefixed rendering id (the JSON has no ground object id). The four role attributes are the sole definition sites for the speaker/audience/time/place referent ids; ground units share one definition iff those referents are pairwise @@ -1241,7 +1186,7 @@ reference structures, the descriptor, scoped BODY/CONTENT, EMBEDDED-QUESTIONS, QUOTATION, ADJUNCTs, and finally the generic EXTRA tail. All sections are optional; childless referents - self-close (KEY rule "order"). + self-close (the KEY comment's order rule). @@ -1269,7 +1214,7 @@ uppercased (ENTITY, EVENTUALITY, PROPOSITION, LOCUTION, ...), or UNSPECIFIED-REFERENT for an elided zo'e referent, or UNKNOWN when the graph carries no usable sort. References are number-neutral - (KEY rule "number-neutrality"): a reference may denote one or + (the KEY comment's number-neutrality rule): a reference may denote one or several individuals; only explicit quantities, cardinality binders, or mass restrictions commit to number. @@ -1290,7 +1235,7 @@ - Space-separated ids of the abstraction/question parameters this referent binds; a strict-id list per the "atomic-lists" KEY rule. + Space-separated ids of the abstraction/question parameters this referent binds; a strict-id list per the KEY comment's atomic-lists rule. The parameter arity of an abstraction referent, when the graph derives it. @@ -1422,8 +1367,8 @@ describing predication scope; a proposition referent's BODY is pushed here rather than on the referent element), RELATIVE-CLAUSES, EXTRA. SPEAKER-REF appears only when the description's speaker - anchor differs from the enclosing utterance's speaker (KEY rule - "speaker-anchor"); it references the speaker referent id defined by + anchor differs from the enclosing utterance's speaker (the + KEY comment speaker-anchor rule); it references the speaker referent id defined by DEICTIC-GROUND, which XSD 1.0 cannot type as an ID here, so the reference is pattern-typed and renderer-checked. @@ -1557,7 +1502,7 @@ A name descriptor: TEXT is the name itself. BY points to the naming speaker and appears only when the namer differs from the - enclosing utterance's speaker (KEY rule "speaker-anchor"). + enclosing utterance's speaker (the KEY comment's speaker-anchor rule). (The word-card NAMED inside COMPOSITE-APPROX is a different, locally declared element.) @@ -1580,7 +1525,7 @@ A word-only stopgap for a referent that remains unresolved after - the KOhA audit (KEY rule "pro-sumti"); the quoted WORD value is + the KOhA audit (the KEY comment's pro-sumti rule); the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only and do not appear here. @@ -1619,8 +1564,8 @@ - A quantifier variable defined at its binder site (KEY rule - "quantifiers"): ID defines the variable, SORT is its flat sort; + A quantifier variable defined at its binder site (the KEY + comment quantifiers rule): ID defines the variable, SORT is its flat sort; use sites carry REF=. DENOTATION appears only when the denotation is not the default generated-bound; CATEGORY only when the category is not the default variable. A bound variable may carry a @@ -1806,8 +1751,8 @@ - The membership structure of a personal mass (mi'o family; KEY rule - "personal-reference"): whether SPEAKER and AUDIENCE are INCLUDED or + The membership structure of a personal mass (mi'o family; the + KEY comment personal-reference rule): whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED, plus any additional included OTHERS. These structures carry the semantics; no pro-sumti label is implied. (The word-card PERSONAL-MASS-MEMBERSHIP inside COMPOSITE-APPROX is an @@ -1837,7 +1782,7 @@ A deictic reference (ti/ta/tu family): PROXIMITY to a discourse referent, with GROUND-REF pointing at the discourse referent it is resolved against (an r/e-prefixed referent id, NOT a deictic-ground - unit id; KEY rule "personal-reference"). Always empty apart from + unit id; the KEY comment's personal-reference rule). Always empty apart from the EXTRA tail. @@ -1972,9 +1917,10 @@ UNSPECIFIED_RELATION, PLACE_QUESTION, CONNECTIVE_QUESTION, TENSE_QUESTION, MATH_OPERATOR_QUESTION, QUANTITY_QUESTION, ATTITUDE_QUESTION, RESPECTIVE_SLOT). SLOT parameters bind only the - question BODY (KEY rule "embedded-questions"). The optional REF= + question BODY (the KEY comment's embedded-questions rule). The optional REF= admits the wrapper-collapse use where an element named PARAMETER is - a pure use site (e.g. inside CONNECTOR, SLOT, PLACE-QUESTION). + a pure use site (e.g. on a connective formula, inside SLOT, + PLACE-QUESTION). (The word-card PARAMETER inside COMPOSITE-APPROX is a different, locally declared element.) @@ -2048,14 +1994,15 @@ - A non-logical connection between sequence items; OPERATOR is the operator surface text verbatim, CONNECTOR its connector record. + A non-logical connection between sequence items; OPERATOR is the operator surface text verbatim; the connector's surface word and locus are provenance (jbotci#719), so only an optional connective-question PARAMETER remains. - - + + + @@ -2082,7 +2029,7 @@ NEUTRAL, NEGATIVE), ASSERTION-EFFECT its effect on the host claim (NONE, HOST_ASSERTED, HOST_SUBORDINATED, METALINGUISTICALLY_VOIDED, PERFORMATIVE), TARGET-FOCUS what it - targets (BRIDI or SELBRI). EXPERIENCER, TARGET, and ANCHOR are + targets (CLAUSE or PREDICATE). EXPERIENCER, TARGET, and ANCHOR are its participant pointers. @@ -2298,7 +2245,7 @@ - A typed question object (KEY rule "embedded-questions"). KIND + A typed question object (the KEY comment's embedded-questions rule). KIND classifies the question (TRUTH, ARGUMENT, RELATION, PLACE, CONNECTIVE, TENSE, MATH_OPERATOR, ATTITUDE, QUANTITY, MULTIPLE), MODE its mode (DIRECT or INDIRECT), DOMAIN its domain sort. @@ -2404,7 +2351,7 @@ One numbered argument place of a PREDICATION or a predicate-keyed ADJUNCT. INDEX is the 1-based place number (absent only on the PLACE-QUESTION argument form). FILL="true" marks the unique - explicit non-host filled place of an adjunct (KEY rule "adjuncts"). + explicit non-host filled place of an adjunct (the KEY comment's adjuncts rule). STATUS records an elided (ELIDED) or filled (FILLED) place when the graph marks the place's introduction. The value is a REF= use site or one inline child: DELETED for a deleted place, MISSING-VALUE for @@ -2463,13 +2410,14 @@ A predication object. PREDICATE is the predicate symbol when the relation is a single lexical predicate; MODE (required) is the - claim mode (see modeType). Children in order: RELATION (when the - relation is a bound parameter) or MISSING-RELATION (when the graph - supplies neither) — neither appears when PREDICATE is used; EVENT - (the reserved Eventuality child, never a numbered ARG); the - numbered ARG places in place order; ADJUNCTs; PLACE-QUESTIONS; - KIND-COMPOSITION; META (relation metadata, scalar negation); then - any WARNING diagnostics. + claim mode (see modeType). Children in order: the relation slot — + RELATION (when the relation is a bound parameter), KIND-COMPOSITION + (when the predicate is composite, jbotci#719), or MISSING-RELATION + (when the graph supplies neither) — omitted only when PREDICATE is + used; EVENT (the reserved Eventuality child, never a numbered ARG); + the numbered ARG places in place order; ADJUNCTs; PLACE-QUESTIONS; + META (relation metadata, scalar negation); then any WARNING + diagnostics. @@ -2479,6 +2427,7 @@ The relation parameter of the predication (when the relation is a bound parameter rather than a lexical predicate). + @@ -2502,7 +2451,6 @@ - Predication metadata: relation metadata, scalar negation, and extras. Emitted only when non-empty. @@ -2522,28 +2470,84 @@ + + + + + + + + The composite relation-expression subtree: a nested KIND-COMPOSITION, a CONNECTIVE conjoining co-modifier RELATION leaves, or the existing RELATION-lambda / abstraction rendering of a referenced composite relation. + + + + + A relation-level connective (in a relation-expression BODY): its RELATION leaves have no MODE; operand order is semantically significant. + + + + + + + + + + + + + + + + + + + + + + + + + + - First-class kind predication content (KEY rule "kind-composition"): - MODIFIER A of KIND B denotes an A-modified kind of B while - retaining B's place structure. The exact modifier-to-kind relation - remains unspecified; nesting preserves the semantic graph's - grouping. (The word-card KIND-COMPOSITION inside COMPOSITE-APPROX - uses the same idiom but is locally declared there.) + A kind-composition relation expression (the KEY comment's + kind-composition rule): MODIFIER A of KIND B denotes an A-modified + kind of B while retaining B's place structure. The exact + modifier-to-kind relation remains unspecified; nesting preserves + the semantic graph's grouping. GROUPING states the basis of a + grouping edge; silence means ASSUMED-LEFT (the deterministic + grammar default), EXPLICIT marks an edge the text itself + determines, at tree level for a uniformly explicit tree and per + node on a mixed tree (jbotci#719). In the PREDICATION relation + slot it is the composite predicate itself — or, in the loud + fallback form of an unprojected tanru link, a sidecar of pointer + wrappers to the head predication and the modifier relation. (The + word-card KIND-COMPOSITION inside + COMPOSITE-APPROX uses the same idiom but is locally declared + there.) - + The kind being modified. - + The modifier applied to the kind. + @@ -2559,8 +2563,10 @@ WHETHER_OR_NOT, CONNECTIVE_QUESTION, PLURAL_EXISTS, PLURAL_FORALL, QUANTIFIER_BUNDLE, RESPECTIVELY_DISTRIBUTION; AND, OR, NOT, ATOM, and the quantifier operators have their own elements). Children: - optional DEFS, then the operands in order, then CONNECTOR, - DOMAIN-IMPORT, and any extra fields inlined directly. + optional DEFS, then the operands in order, then DOMAIN-IMPORT, + an optional connective-question PARAMETER, and any extra fields + inlined directly. TRUTH-TABLE= appears only when the graph + records a table OPERATOR= does not already determine (jbotci#719). Known XSD-1.0 weakness: for some compound operators the renderer emits field-named pointer wrappers (PREDICATION, VARIABLE, @@ -2575,7 +2581,6 @@ - @@ -2583,6 +2588,8 @@ + + @@ -2591,15 +2598,18 @@ A logical connective formula: OPERATOR is AND or OR. Children: optional DEFS, then the operands in order — operand order is - semantically significant (KEY rule "order") — then CONNECTOR and - any extra fields inlined directly. + semantically significant (the KEY comment's order rule) — then an + optional connective-question PARAMETER and any extra fields + inlined directly. TRUTH-TABLE= appears only when the graph + records a table OPERATOR= does not already determine; the surface + connective word and its locus are provenance and never appear + (jbotci#719). - @@ -2613,6 +2623,8 @@ + + @@ -2620,31 +2632,33 @@ A negation formula (operator "not"): optional DEFS, the negated - operand, then CONNECTOR and extras. (The NEGATION elements inside - OCCURRENCE and the word-card PREDICATION-NEGATION are different, - locally declared elements.) + operand, then an optional connective-question PARAMETER and + extras. (The NEGATION elements inside OCCURRENCE and the + word-card PREDICATION-NEGATION are different, locally declared + elements.) - + + - An existential binder (KEY rule "quantifiers"): VARIABLE defines - the bound variable; optional DEFS; RESTRICTION appears exactly when - the graph supplies one; BODY always; then the optional - QUANTITY-VALUE, DOMAIN-IMPORT, and CONNECTOR. + An existential binder (the KEY comment's quantifiers rule): + VARIABLE defines the bound variable; optional DEFS; RESTRICTION + appears exactly when the graph supplies one; BODY always; then the + optional QUANTITY-VALUE, DOMAIN-IMPORT, and PARAMETER. @@ -2658,11 +2672,12 @@ - + + @@ -2684,11 +2699,12 @@ - + + @@ -2697,7 +2713,7 @@ A cardinality binder: VARIABLE, optional DEFS, the CARD quantity, then RESTRICTION and BODY (both always written explicitly), then - DOMAIN-IMPORT and CONNECTOR. + DOMAIN-IMPORT and an optional PARAMETER. @@ -2708,36 +2724,12 @@ - - - - - - - - A connector record on a formula, sequence connection, or binder: - SOURCE-WORD is the surface word when known; LOCUS and TRUTH-TABLE - are scalar connector properties; PARAMETER is the bound connective - parameter for a connective question. - - - - - - The connector locus. - - - The connector truth table (e.g. TTTF for A). - - - - - - + + @@ -2790,7 +2782,7 @@ A predicate-keyed optional participant of the host predication - (KEY rule "adjuncts"). Three shapes: the compact form carries + (the KEY comment's adjuncts rule). Three shapes: the compact form carries PREDICATE= with flat ARG children (the single-lexical-predicate place map); without PREDICATE=, BODY carries the composite predicate subtree; a record-shaped adjunct falls back to a generic @@ -2896,7 +2888,7 @@ - The word-card section (KEY rule "word-cards"): one WORD card per + The word-card section (the KEY comment's word-cards rule): one WORD card per content word of the text, in card order. Present only when the document was rendered with word cards (tertmu --show-defs); never present in the TYPED-GRAPH form. Card ids are unique within the @@ -2942,12 +2934,12 @@ The mechanical composition of a dictionary-absent compound - (KEY rule "compound-approximation"): suggestive, not + (the KEY comment's compound-approximation rule): suggestive, not definitional. PLACES="UNKNOWN" means the composition tree determines no place structure — the actual meaning and places - were chosen by the coiner (KEY rule "compound-places"). + were chosen by the coiner (the KEY comment's compound-places rule). GROUPING and SCOPE describe the basis of the displayed tree - edges (KEY rule "compound-assumptions"). The attributes are + edges (the KEY comment's compound-assumptions rule). The attributes are tree-level by default: a tree whose kind-composition edges all share one basis carries GROUPING at this level, and a tree whose operator applications all share one scope basis carries @@ -3349,8 +3341,8 @@ The abstract role an utterance context would supply for a - context-dependent word used inside a definition (KEY rule - "context-placeholders"): ROLE is the placeholder role + context-dependent word used inside a definition (the KEY + comment context-placeholders rule): ROLE is the placeholder role (SPEAKER, AUDIENCE, DEMONSTRATED, ASSIGNED, or ELLIPTICAL-PREDICATE); PROXIMITY refines a demonstrated role; SLOT numbers an argument slot. These are roles, not diff --git a/crates/jbotci-semantics/src/completeness/disposition.rs b/crates/jbotci-semantics/src/completeness/disposition.rs index 749d3e39f7..eee8801b28 100644 --- a/crates/jbotci-semantics/src/completeness/disposition.rs +++ b/crates/jbotci-semantics/src/completeness/disposition.rs @@ -54,8 +54,8 @@ const NOT_COMPUTED_FACT: &str = "not-computed:denotation-multiplicity"; /// object kinds carry it via `SemanticObjectCommon`; the rest are value structs). /// Derived from the model type graph and pinned by the `provenance_is_type_based` /// test, which fails if the set drifts from the `SemanticSource`-typed fields. -/// `Connector.source` is deliberately absent — its type is `String` (a lexical -/// word), so it renders. +/// `Connector.source` is deliberately absent — its type is `ConnectorSource` +/// (a lexical word or an implicit-juxtaposition marker), so it renders. const SOURCE_LINK_SURFACES: &[&str] = &[ // object kinds (source via SemanticObjectCommon) "Utterance", diff --git a/crates/jbotci-semantics/src/completeness/inventory.rs b/crates/jbotci-semantics/src/completeness/inventory.rs index e0e91e16dc..17e12ffb8b 100644 --- a/crates/jbotci-semantics/src/completeness/inventory.rs +++ b/crates/jbotci-semantics/src/completeness/inventory.rs @@ -1162,13 +1162,13 @@ pub fn render_field_inventory() -> RenderFieldInventory { "Predication", "tanruLink", EntryKind::Field, - Presence::Optional, + Presence::VariantConditional, new!(Witness::Corpus { doc: "b39", path: "Predication:tanruLink", expect: new!(WitnessExpect::Present) }), - None, + Some("PredicationRelation::Composition"), ), e( SurfaceCategory::Object, @@ -2512,6 +2512,212 @@ pub fn render_field_inventory() -> RenderFieldInventory { new!(Witness::NoCorpusWitness), None, ), + e( + SurfaceCategory::ValueStruct, + "ConnectorSource", + "kind", + EntryKind::Field, + Presence::Always, + new!(Witness::Corpus { + doc: "b21", + path: "Formula:connector.source.kind", + expect: new!(WitnessExpect::Present) + }), + None, + ), + e( + SurfaceCategory::ValueStruct, + "ConnectorSource", + "word", + EntryKind::Field, + Presence::Optional, + new!(Witness::Corpus { + doc: "b21", + path: "Formula:connector.source.word", + expect: new!(WitnessExpect::Present) + }), + None, + ), + e( + SurfaceCategory::Enum, + "ConnectorSource", + "SurfaceWord", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("surfaceWord"), + ), + e( + SurfaceCategory::Enum, + "ConnectorSource", + "ImplicitJuxtaposition", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("implicitJuxtaposition"), + ), + e( + SurfaceCategory::Enum, + "ConnectorLocus", + "Statement", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("statement"), + ), + e( + SurfaceCategory::Enum, + "ConnectorLocus", + "Argument", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("argument"), + ), + e( + SurfaceCategory::Enum, + "ConnectorLocus", + "Term", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("term"), + ), + e( + SurfaceCategory::Enum, + "ConnectorLocus", + "TermSet", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("termSet"), + ), + e( + SurfaceCategory::Enum, + "ConnectorLocus", + "Tense", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("tense"), + ), + e( + SurfaceCategory::Enum, + "ConnectorLocus", + "Tag", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("tag"), + ), + e( + SurfaceCategory::Enum, + "ConnectorLocus", + "Operand", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("operand"), + ), + e( + SurfaceCategory::Enum, + "ConnectorLocus", + "Clause", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("clause"), + ), + e( + SurfaceCategory::Enum, + "ConnectorLocus", + "PredicatePhrase", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("predicatePhrase"), + ), + e( + SurfaceCategory::Enum, + "ConnectorLocus", + "Predicate", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("predicate"), + ), + e( + SurfaceCategory::Enum, + "ConnectorLocus", + "PredicateInversion", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("predicateInversion"), + ), + e( + SurfaceCategory::Enum, + "ConnectorLocus", + "PredicateUnit", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("predicateUnit"), + ), + e( + SurfaceCategory::Enum, + "ConnectorLocus", + "PropertyAbstraction", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("propertyAbstraction"), + ), + e( + SurfaceCategory::Enum, + "ConnectorLocus", + "PropertyInversion", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("propertyInversion"), + ), + e( + SurfaceCategory::Enum, + "ConnectorLocus", + "Abstraction", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("abstraction"), + ), + e( + SurfaceCategory::Enum, + "ConnectorLocus", + "Description", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("description"), + ), + e( + SurfaceCategory::Enum, + "ConnectorLocus", + "MathOperator", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("mathOperator"), + ), + e( + SurfaceCategory::Enum, + "ConnectorLocus", + "BareRaisedParticipant", + EntryKind::Variant, + Presence::VariantConditional, + new!(Witness::NoCorpusWitness), + Some("bareRaisedParticipant"), + ), e( SurfaceCategory::ValueStruct, "DeicticGround", @@ -4878,24 +5084,24 @@ pub fn render_field_inventory() -> RenderFieldInventory { e( SurfaceCategory::Enum, "DisplayedContentTargetFocus", - "Bridi", + "Clause", EntryKind::Variant, Presence::VariantConditional, new!(Witness::Corpus { doc: "paragraph-narrative", path: "DisplayedContent:targetFocus", - expect: new!(WitnessExpect::Value("bridi")) + expect: new!(WitnessExpect::Value("clause")) }), - Some("bridi"), + Some("clause"), ), e( SurfaceCategory::Enum, "DisplayedContentTargetFocus", - "Selbri", + "Predicate", EntryKind::Variant, Presence::VariantConditional, new!(Witness::NoCorpusWitness), - Some("selbri"), + Some("predicate"), ), e( SurfaceCategory::Enum, diff --git a/crates/jbotci-semantics/src/generated_builder/connectives.rs b/crates/jbotci-semantics/src/generated_builder/connectives.rs index 0f885f5206..59564bca6b 100644 --- a/crates/jbotci-semantics/src/generated_builder/connectives.rs +++ b/crates/jbotci-semantics/src/generated_builder/connectives.rs @@ -1755,7 +1755,7 @@ pub(super) fn generated_statement_connective_core_has_logical_component( } #[requires(true)] -#[ensures(ret.as_ref().is_ok_and(|connection| !connection.operator.is_empty() && !connection.connector.source.is_empty()) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|connection| !connection.operator.is_empty() && connection.connector.source.as_surface_word().is_some()) || ret.is_err())] pub(super) fn generated_i_statement_nonlogical_connection( connective: &IStatementConnectiveSyntax, ) -> Result { @@ -1770,8 +1770,8 @@ pub(super) fn generated_i_statement_nonlogical_connection( Ok(NonlogicalConnection::new( operator, new!(Connector { - source, - locus: "statement".to_owned(), + source: ConnectorSource::surface_word(source), + locus: ConnectorLocus::Statement, truth_table, parameter: None, }), @@ -1779,7 +1779,7 @@ pub(super) fn generated_i_statement_nonlogical_connection( } #[requires(!generated_statement_connective_is_logical(connective))] -#[ensures(ret.as_ref().is_ok_and(|connection| !connection.operator.is_empty() && !connection.connector.source.is_empty()) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|connection| !connection.operator.is_empty() && connection.connector.source.as_surface_word().is_some()) || ret.is_err())] pub(super) fn generated_statement_core_nonlogical_connection( connective: &StatementConnectiveSyntax, ) -> Result { @@ -1790,8 +1790,8 @@ pub(super) fn generated_statement_core_nonlogical_connection( Ok(NonlogicalConnection::new( operator, new!(Connector { - source, - locus: "statement".to_owned(), + source: ConnectorSource::surface_word(source), + locus: ConnectorLocus::Statement, truth_table: None, parameter: None, }), diff --git a/crates/jbotci-semantics/src/generated_builder/formulas.rs b/crates/jbotci-semantics/src/generated_builder/formulas.rs index 9f3ec3dff9..14d2f3bc02 100644 --- a/crates/jbotci-semantics/src/generated_builder/formulas.rs +++ b/crates/jbotci-semantics/src/generated_builder/formulas.rs @@ -1105,8 +1105,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { }, children, Some(new!(Connector { - source: connector_source, - locus: "term".to_owned(), + source: ConnectorSource::surface_word(connector_source), + locus: ConnectorLocus::Term, truth_table: generated_direct_term_connective_truth_table(connective), parameter, })), @@ -1364,11 +1364,13 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { operator, children, Some(new!(Connector { - source: generated_modal_forethought_pair_source( - &termset.gek, - &termset.first_branch.gik, + source: ConnectorSource::surface_word( + generated_modal_forethought_pair_source( + &termset.gek, + &termset.first_branch.gik, + ), ), - locus: "termset".to_owned(), + locus: ConnectorLocus::TermSet, truth_table: generated_modal_forethought_gik_connective_truth_table( &termset.gek, &termset.first_branch.gik, @@ -1407,7 +1409,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { false, false, connector_source, - "termset", + ConnectorLocus::TermSet, formula, branch_formula, source.clone(), @@ -1548,8 +1550,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { }, children, Some(new!(Connector { - source: format!("pe'e {connector_source}"), - locus: "termset".to_owned(), + source: ConnectorSource::surface_word(format!("pe'e {connector_source}")), + locus: ConnectorLocus::TermSet, truth_table: generated_statement_connective_core_truth_table( &continuation.connective, ), @@ -1642,8 +1644,10 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { FormulaOperator::And, vec![leading_replaced, trailing_replaced], Some(new!(Connector { - source: generated_modal_forethought_connective_source(&termset.gek), - locus: "termset".to_owned(), + source: ConnectorSource::surface_word( + generated_modal_forethought_connective_source(&termset.gek), + ), + locus: ConnectorLocus::TermSet, truth_table: None, parameter: None, })), @@ -1830,14 +1834,16 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { FormulaOperator::And, vec![leading_replaced, trailing_replaced], Some(new!(Connector { - source: if generated_modal_forethought_connective_primary_cmavo(connective) - == Some(Cmavo::Fahu) - { - generated_modal_forethought_connective_source(connective) - } else { - generated_modal_forethought_pair_source(connective, gik) - }, - locus: "termset".to_owned(), + source: ConnectorSource::surface_word( + if generated_modal_forethought_connective_primary_cmavo(connective) + == Some(Cmavo::Fahu) + { + generated_modal_forethought_connective_source(connective) + } else { + generated_modal_forethought_pair_source(connective, gik) + }, + ), + locus: ConnectorLocus::TermSet, truth_table: None, parameter: None, })), @@ -2872,7 +2878,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { source, truth_table, connector_question, - locus: "tense".to_owned(), + locus: ConnectorLocus::Tense, connected_index, branches: branches .into_iter() @@ -2896,7 +2902,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { source, truth_table, connector_question: None, - locus: "modal".to_owned(), + locus: ConnectorLocus::Tag, connected_index, branches: modal_terms .into_iter() @@ -3007,8 +3013,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { connection.operator, children, Some(new!(Connector { - source: connection.source.clone(), - locus: connection.locus.clone(), + source: ConnectorSource::surface_word(connection.source.clone()), + locus: connection.locus, truth_table: connection.truth_table.clone(), parameter: connector_parameter, })), @@ -3078,8 +3084,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { FormulaOperator::And, distributed_children.clone(), Some(new!(Connector { - source: connection.source.clone(), - locus: connection.locus.clone(), + source: ConnectorSource::surface_word(connection.source.clone()), + locus: connection.locus, truth_table: None, parameter: None, })), @@ -3562,8 +3568,10 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { operator, children, Some(new!(Connector { - source: generated_modal_forethought_pair_source(&operand.gek, &operand.gik), - locus: "operand".to_owned(), + source: ConnectorSource::surface_word( + generated_modal_forethought_pair_source(&operand.gek, &operand.gik), + ), + locus: ConnectorLocus::Operand, truth_table: generated_modal_forethought_gik_connective_truth_table( &operand.gek, &operand.gik, @@ -4060,7 +4068,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { &simple_tail.selbri, visible_arguments, formula_source, - "selbri", + ConnectorLocus::Predicate, eventuality, )?; self.set_semantic_object_source(result.head_predication, predication_source)?; @@ -4242,7 +4250,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { &simple_tail.selbri, visible_arguments, self.source_for_node(source_node, "bridi-formula"), - "selbri", + ConnectorLocus::Predicate, eventuality, )?; self.attach_generated_modal_terms_to_formula( @@ -4595,11 +4603,13 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { operator, children, Some(new!(Connector { - source: generated_modal_forethought_pair_source( - &connection.gek, - &connection.first_branch.gik, + source: ConnectorSource::surface_word( + generated_modal_forethought_pair_source( + &connection.gek, + &connection.first_branch.gik, + ), ), - locus: "bridi".to_owned(), + locus: ConnectorLocus::Clause, truth_table: generated_modal_forethought_gik_connective_truth_table( &connection.gek, &connection.first_branch.gik, @@ -4648,7 +4658,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { false, false, connector_source, - "bridi", + ConnectorLocus::Clause, formula, branch_formula, None, @@ -5501,8 +5511,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { operator, children, Some(new!(Connector { - source: connector_source, - locus: "bridiTail".to_owned(), + source: ConnectorSource::surface_word(connector_source), + locus: ConnectorLocus::PredicatePhrase, truth_table: connector_parameter .is_none() .then(|| generated_bridi_tail_connective_truth_table(connective)) @@ -6182,8 +6192,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { operator, children, Some(new!(Connector { - source, - locus: "tense".to_owned(), + source: ConnectorSource::surface_word(source), + locus: ConnectorLocus::Tense, truth_table, parameter: connector_parameter, })), @@ -6269,7 +6279,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { tagged.inner_selbri.as_ref(), assignments.visible_arguments.clone(), formula_source.clone(), - "tense", + ConnectorLocus::Tense, Some(branch_eventuality), )?; self.attach_generated_modal_terms_to_formula(result.formula, &assignments.modal_terms)?; @@ -6314,8 +6324,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { operator, children, Some(new!(Connector { - source, - locus: "tense".to_owned(), + source: ConnectorSource::surface_word(source), + locus: ConnectorLocus::Tense, truth_table, parameter: connector_parameter, })), @@ -6618,7 +6628,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { connection, visible_arguments, source, - "selbri", + ConnectorLocus::Predicate, leading_eventuality, )?; self.attach_generated_modal_terms_to_formula( @@ -6982,8 +6992,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { FormulaOperator::And, vec![head.formula, relation_formula], Some(new!(Connector { - source: "tanru".to_owned(), - locus: "selbri-inversion".to_owned(), + source: new!(ConnectorSource::ImplicitJuxtaposition), + locus: ConnectorLocus::PredicateInversion, truth_table: None, parameter: None, })), @@ -7086,8 +7096,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { FormulaOperator::And, vec![head.formula, relation_formula], Some(new!(Connector { - source: "tanru".to_owned(), - locus: "selbri-inversion".to_owned(), + source: new!(ConnectorSource::ImplicitJuxtaposition), + locus: ConnectorLocus::PredicateInversion, truth_table: None, parameter: None, })), diff --git a/crates/jbotci-semantics/src/generated_builder/mekso.rs b/crates/jbotci-semantics/src/generated_builder/mekso.rs index 2bc6b988b3..91ae46019b 100644 --- a/crates/jbotci-semantics/src/generated_builder/mekso.rs +++ b/crates/jbotci-semantics/src/generated_builder/mekso.rs @@ -922,7 +922,7 @@ pub(super) fn generated_number_descriptor_mekso_operand_surface_text( } #[requires(true)] -#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == "mekso-operator")) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == ConnectorLocus::MathOperator)) || ret.is_err())] pub(super) fn first_generated_connected_mekso_operator( expression: &MeksoSyntax, ) -> Result, SemanticsError> { @@ -937,7 +937,7 @@ pub(super) fn first_generated_connected_mekso_operator( } #[requires(true)] -#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == "mekso-operator")) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == ConnectorLocus::MathOperator)) || ret.is_err())] pub(super) fn first_generated_connected_mekso_operator_in_zantufa_infix( infix: &ZantufaInfixMeksoSyntax, ) -> Result, SemanticsError> { @@ -965,7 +965,7 @@ pub(super) fn first_generated_connected_mekso_operator_in_zantufa_infix( } #[requires(true)] -#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == "mekso-operator")) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == ConnectorLocus::MathOperator)) || ret.is_err())] pub(super) fn first_generated_connected_mekso_operator_in_infix( infix: &InfixMeksoSyntax, ) -> Result, SemanticsError> { @@ -990,7 +990,7 @@ pub(super) fn first_generated_connected_mekso_operator_in_infix( } #[requires(true)] -#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == "mekso-operator")) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == ConnectorLocus::MathOperator)) || ret.is_err())] pub(super) fn first_generated_connected_mekso_operator_in_precedence( expression: &MeksoPrecedenceSyntax, ) -> Result, SemanticsError> { @@ -1009,7 +1009,7 @@ pub(super) fn first_generated_connected_mekso_operator_in_precedence( } #[requires(true)] -#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == "mekso-operator")) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == ConnectorLocus::MathOperator)) || ret.is_err())] pub(super) fn first_generated_connected_mekso_operator_in_base( expression: &MeksoBaseSyntax, ) -> Result, SemanticsError> { @@ -1058,7 +1058,7 @@ pub(super) fn first_generated_connected_mekso_operator_in_base( } #[requires(true)] -#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == "mekso-operator")) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == ConnectorLocus::MathOperator)) || ret.is_err())] pub(super) fn first_generated_connected_mekso_operator_in_operand( operand: &MeksoOperandSyntax, ) -> Result, SemanticsError> { @@ -1091,7 +1091,7 @@ pub(super) fn first_generated_connected_mekso_operator_in_operand( } #[requires(true)] -#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == "mekso-operator")) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == ConnectorLocus::MathOperator)) || ret.is_err())] pub(super) fn first_generated_connected_mekso_operator_in_bound_or_simple_operand( operand: &BoundOrSimpleMeksoOperandSyntax, ) -> Result, SemanticsError> { @@ -1106,7 +1106,7 @@ pub(super) fn first_generated_connected_mekso_operator_in_bound_or_simple_operan } #[requires(true)] -#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == "mekso-operator")) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == ConnectorLocus::MathOperator)) || ret.is_err())] pub(super) fn first_generated_connected_mekso_operator_in_bound_operand( operand: &BoundMeksoOperandSyntax, ) -> Result, SemanticsError> { @@ -1118,7 +1118,7 @@ pub(super) fn first_generated_connected_mekso_operator_in_bound_operand( } #[requires(true)] -#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == "mekso-operator")) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == ConnectorLocus::MathOperator)) || ret.is_err())] pub(super) fn first_generated_connected_mekso_operator_in_simple_operand( operand: &SimpleMeksoOperandSyntax, ) -> Result, SemanticsError> { @@ -1160,7 +1160,7 @@ pub(super) fn first_generated_connected_mekso_operator_in_simple_operand( } #[requires(true)] -#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == "mekso-operator")) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == ConnectorLocus::MathOperator)) || ret.is_err())] pub(super) fn connected_generated_mekso_operator( operator: &MeksoOperatorSyntax, ) -> Result, SemanticsError> { @@ -1178,7 +1178,7 @@ pub(super) fn connected_generated_mekso_operator( } #[requires(true)] -#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == "mekso-operator")) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == ConnectorLocus::MathOperator)) || ret.is_err())] pub(super) fn connected_generated_afterthought_mekso_operator( operator: &AfterthoughtMeksoOperatorSyntax, ) -> Result, SemanticsError> { @@ -1194,7 +1194,7 @@ pub(super) fn connected_generated_afterthought_mekso_operator( } #[requires(true)] -#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == "mekso-operator")) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == ConnectorLocus::MathOperator)) || ret.is_err())] pub(super) fn connected_generated_bound_or_atom_mekso_operator( operator: &BoundOrAtomMeksoOperatorSyntax, ) -> Result, SemanticsError> { @@ -1209,7 +1209,7 @@ pub(super) fn connected_generated_bound_or_atom_mekso_operator( } #[requires(true)] -#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == "mekso-operator")) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == ConnectorLocus::MathOperator)) || ret.is_err())] pub(super) fn connected_generated_bound_mekso_operator( operator: &BoundMeksoOperatorSyntax, ) -> Result, SemanticsError> { @@ -1225,7 +1225,7 @@ pub(super) fn connected_generated_bound_mekso_operator( } #[requires(true)] -#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == "mekso-operator")) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == ConnectorLocus::MathOperator)) || ret.is_err())] pub(super) fn connected_generated_simple_mekso_operator( operator: &SimpleMeksoOperatorSyntax, ) -> Result, SemanticsError> { @@ -1252,7 +1252,7 @@ pub(super) fn connected_generated_simple_mekso_operator( } #[requires(true)] -#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == "mekso-operator")) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == ConnectorLocus::MathOperator)) || ret.is_err())] pub(super) fn connected_generated_standard_mekso_operator( connective: &StandardStatementConnectiveSyntax, left_operator: MeksoOperatorSyntax, @@ -1270,8 +1270,8 @@ pub(super) fn connected_generated_standard_mekso_operator( right_operator, operator: generated_statement_connective_formula_operator_for_core(&connective), connector: new!(Connector { - source, - locus: "mekso-operator".to_owned(), + source: ConnectorSource::surface_word(source), + locus: ConnectorLocus::MathOperator, truth_table: generated_statement_connective_core_truth_table(&connective), parameter: None, }), @@ -1279,7 +1279,7 @@ pub(super) fn connected_generated_standard_mekso_operator( } #[requires(true)] -#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == "mekso-operator")) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|expansion| expansion.as_ref().is_none_or(|expansion| expansion.connector.locus == ConnectorLocus::MathOperator)) || ret.is_err())] pub(super) fn connected_generated_forethought_mekso_operator( operator: &ForethoughtMeksoOperatorSyntax, ) -> Result, SemanticsError> { @@ -1288,8 +1288,11 @@ pub(super) fn connected_generated_forethought_mekso_operator( right_operator: operator.right_operator.as_ref().clone(), operator: generated_guhek_connective_formula_operator(&operator.guhek), connector: new!(Connector { - source: generated_guhek_gik_connective_source(&operator.guhek, &operator.gik), - locus: "mekso-operator".to_owned(), + source: ConnectorSource::surface_word(generated_guhek_gik_connective_source( + &operator.guhek, + &operator.gik, + )), + locus: ConnectorLocus::MathOperator, truth_table: generated_guhek_gik_connective_truth_table(&operator.guhek, &operator.gik), parameter: None, }), diff --git a/crates/jbotci-semantics/src/generated_builder/mod.rs b/crates/jbotci-semantics/src/generated_builder/mod.rs index 31f8b75c2e..986019847d 100644 --- a/crates/jbotci-semantics/src/generated_builder/mod.rs +++ b/crates/jbotci-semantics/src/generated_builder/mod.rs @@ -99,7 +99,8 @@ use crate::model::{ AbstractionKind, Actuality, ActualityKind, Adjunct, AdjunctData, AnchorMagnitude, AnchorRelation, AnchorRelationData, ArgumentValue, ArgumentValueData, ArgumentValueKind, Aspect, AssignedName, AssignedNameData, CommandTarget, Composition, CompositionOperator, - Connector, DeicticProximity, Descriptor, DescriptorDefiniteness, DescriptorKind, + Connector, ConnectorLocus, ConnectorSource, ConnectorSourceData, DeicticProximity, Descriptor, + DescriptorDefiniteness, DescriptorKind, DisplayedContentAssertionEffect, DisplayedContentFamily, DisplayedContentModifier, DisplayedContentNode, DisplayedContentPolarity, DisplayedContentTargetFocus, ElidedConnectionOperand, EventualityClass, EventualityNode, EventualityNodeData, @@ -748,7 +749,6 @@ struct GeneratedConnectedModalTerm<'syntax> { } #[invariant(!source.is_empty())] -#[invariant(!locus.is_empty())] #[invariant(branches.len() >= 2)] #[invariant((operator == &FormulaOperator::RespectivelyDistribution && truth_table.is_none() && connector_question.is_none()) || (operator != &FormulaOperator::RespectivelyDistribution && truth_table.is_some() != connector_question.is_some()))] #[derive(Debug, Clone)] @@ -757,7 +757,7 @@ struct GeneratedLogicalTagConnection<'syntax> { source: String, truth_table: Option, connector_question: Option, - locus: String, + locus: ConnectorLocus, connected_index: usize, branches: Vec>, } @@ -1281,8 +1281,8 @@ struct GeneratedConnectedQuantifierQuantityScope { source: Option, } -#[invariant(connector.locus == "mekso-operator")] -#[invariant(!connector.source.is_empty())] +#[invariant(connector.locus == ConnectorLocus::MathOperator)] +#[invariant(connector.source.as_surface_word().is_some())] #[invariant(connector.truth_table.as_ref().is_none_or(|table| table.len() == 4))] #[derive(Debug, Clone)] struct GeneratedConnectedMeksoOperatorExpansion { @@ -1519,11 +1519,11 @@ enum GeneratedAnchorDomain { impl GeneratedPropertyTanruContext { #[requires(true)] - #[ensures(!ret.is_empty())] - fn connector_locus(self) -> &'static str { + #[ensures(matches!(ret, ConnectorLocus::Description | ConnectorLocus::PropertyAbstraction))] + fn connector_locus(self) -> ConnectorLocus { match self { - Self::Description => "description", - Self::PropertyAbstraction => "property-abstraction", + Self::Description => ConnectorLocus::Description, + Self::PropertyAbstraction => ConnectorLocus::PropertyAbstraction, } } @@ -3618,7 +3618,7 @@ fn generated_distributed_sumti_connective_source( } #[requires(true)] -#[ensures(ret.as_ref().is_ok_and(|connector| connector.as_ref().is_none_or(|connector| !connector.source.is_empty() && connector.locus == "sumti")) || ret.is_err())] +#[ensures(ret.as_ref().is_ok_and(|connector| connector.as_ref().is_none_or(|connector| connector.source.as_surface_word().is_some() && connector.locus == ConnectorLocus::Argument)) || ret.is_err())] fn generated_distributed_sumti_connector( connective: Option>, parameter: Option, @@ -3628,8 +3628,8 @@ fn generated_distributed_sumti_connector( }; let source = generated_distributed_sumti_connective_source(connective)?; Ok(Some(new!(Connector { - source, - locus: "sumti".to_owned(), + source: ConnectorSource::surface_word(source), + locus: ConnectorLocus::Argument, truth_table: generated_distributed_sumti_connective_truth_table(connective), parameter, }))) @@ -10027,6 +10027,9 @@ mod tests { data!(crate::model::PredicationRelation::Parameter { .. }) => { panic!("quoted bridi relation is not a parameter") } + data!(crate::model::PredicationRelation::Composition) => { + panic!("quoted bridi relation is not a composition") + } }) .collect::>(); assert_eq!(quoted_bridi_relations, ["cmavo:go'oĭ-\"broda\""]); @@ -10448,7 +10451,7 @@ mod tests { outer .connector .as_ref() - .map(|connector| connector.source.as_str()), + .and_then(|connector| connector.source.as_surface_word()), Some("e") ); let data!(FormulaNode::Connective(inner)) = graph @@ -10466,7 +10469,7 @@ mod tests { inner .connector .as_ref() - .map(|connector| connector.source.as_str()), + .and_then(|connector| connector.source.as_surface_word()), Some("e") ); assert_eq!( @@ -10556,8 +10559,8 @@ mod tests { connection .connector .as_ref() - .map(|connector| (connector.source.as_str(), connector.locus.as_str())), - Some(("e", "sumti")) + .map(|connector| (connector.source.as_surface_word(), connector.locus)), + Some((Some("e"), ConnectorLocus::Argument)) ); let viska = connection .children @@ -10617,7 +10620,7 @@ mod tests { connection .connector .as_ref() - .is_some_and(|connector| connector.source == "ji" && connector.parameter.is_some()) + .is_some_and(|connector| connector.source.as_surface_word() == Some("ji") && connector.parameter.is_some()) ); assert_eq!( graph @@ -11356,6 +11359,7 @@ mod tests { relation.starts_with("cmavo:nu-") && relation.contains("-gismu:") } data!(crate::model::PredicationRelation::Parameter { .. }) => false, + data!(crate::model::PredicationRelation::Composition) => false, } }) }) @@ -11931,8 +11935,8 @@ mod tests { outer .connector .as_ref() - .map(|connector| (connector.source.as_str(), connector.locus.as_str())), - Some(("ga gi", "bridi")) + .map(|connector| (connector.source.as_surface_word(), connector.locus)), + Some((Some("ga gi"), ConnectorLocus::Clause)) ); assert_eq!( graph.objects[&outer.children[0]].formula_predication(), @@ -11952,8 +11956,8 @@ mod tests { grouped_tail .connector .as_ref() - .map(|connector| (connector.source.as_str(), connector.locus.as_str())), - Some(("gi'e ba bo", "bridiTail")) + .map(|connector| (connector.source.as_surface_word(), connector.locus)), + Some((Some("gi'e ba bo"), ConnectorLocus::PredicatePhrase)) ); assert_eq!( graph.objects[&grouped_tail.children[0]].formula_predication(), @@ -11971,6 +11975,7 @@ mod tests { .and_then(|predication| match predication.relation.as_data() { data!(PredicationRelation::Named { relation }) => Some(relation.as_str()), data!(PredicationRelation::Parameter { .. }) => None, + data!(PredicationRelation::Composition) => None, }), Some("after") ); @@ -13320,8 +13325,8 @@ mod tests { connection .connector .as_ref() - .map(|connector| (connector.source.as_str(), connector.locus.as_str())), - Some(("e", "term")) + .map(|connector| (connector.source.as_surface_word(), connector.locus)), + Some((Some("e"), ConnectorLocus::Term)) ); let branches = connection @@ -13387,8 +13392,8 @@ mod tests { connection .connector .as_ref() - .map(|connector| (connector.source.as_str(), connector.locus.as_str())), - Some(("e ba bo", "sumti")) + .map(|connector| (connector.source.as_surface_word(), connector.locus)), + Some((Some("e ba bo"), ConnectorLocus::Argument)) ); let branch_events = connection.children[..2] @@ -13527,7 +13532,7 @@ mod tests { assert!(graph.objects.values().any(|object| { object.formula_operator() == Some(FormulaOperator::And) && object.as_formula().is_some_and(|formula| { - matches!(formula.as_data(), data!(FormulaNode::Connective(formula)) if formula.connector.as_ref().is_some_and(|connector| connector.source == "e su'o roi bo" && connector.locus == "sumti")) + matches!(formula.as_data(), data!(FormulaNode::Connective(formula)) if formula.connector.as_ref().is_some_and(|connector| connector.source.as_surface_word() == Some("e su'o roi bo") && connector.locus == ConnectorLocus::Argument)) }) })); } @@ -13568,8 +13573,8 @@ mod tests { assert_eq!(connection.operator, FormulaOperator::ConnectiveQuestion); assert_eq!(connection.children.len(), 2); assert!(connection.connector.as_ref().is_some_and(|connector| { - connector.source == "ji" - && connector.locus == "term" + connector.source.as_surface_word() == Some("ji") + && connector.locus == ConnectorLocus::Term && connector.truth_table.is_none() && connector.parameter.is_some() })); @@ -13615,8 +13620,9 @@ mod tests { Some(data!(FormulaNode::Connective(connection))) if connection.operator == FormulaOperator::Or && connection.connector.as_ref().is_some_and(|connector| { - connector.locus == "modal" - && connector.source == "fi'o selsnu ja fi'o bangu" + connector.locus == ConnectorLocus::Tag + && connector.source.as_surface_word() + == Some("fi'o selsnu ja fi'o bangu") }) ) })); @@ -13672,8 +13678,8 @@ mod tests { if connection.operator == FormulaOperator::And && connection.children.len() == 2 && connection.connector.as_ref().is_some_and(|connector| { - connector.locus == "tense" - && connector.source == "pu je ba zu" + connector.locus == ConnectorLocus::Tense + && connector.source.as_surface_word() == Some("pu je ba zu") && connector.truth_table.as_deref() == Some("TFFF") }) ) @@ -13743,8 +13749,8 @@ mod tests { assert_eq!(body.operator, FormulaOperator::And); assert_eq!(body.children, branch_stream.items); assert!(body.connector.as_ref().is_some_and(|connector| { - connector.locus == "tense" - && connector.source == "vi fa'u va" + connector.locus == ConnectorLocus::Tense + && connector.source.as_surface_word() == Some("vi fa'u va") && connector.truth_table.is_none() })); } @@ -13793,8 +13799,8 @@ mod tests { if connection.operator == FormulaOperator::And && connection.children.len() == 2 && connection.connector.as_ref().is_some_and(|connector| { - connector.locus == "termset" - && connector.source == "ge gi" + connector.locus == ConnectorLocus::TermSet + && connector.source.as_surface_word() == Some("ge gi") && connector.truth_table.as_deref() == Some("TFFF") }) ) @@ -13912,8 +13918,8 @@ mod tests { .as_ref() .expect("JOI should remain nonlogical rather than becoming formula conjunction"); assert_eq!(connection.operator, CompositionOperator::Mass.label()); - assert_eq!(connection.connector.source, "joi"); - assert_eq!(connection.connector.locus, "statement"); + assert_eq!(connection.connector.source.as_surface_word(), Some("joi")); + assert_eq!(connection.connector.locus, ConnectorLocus::Statement); assert_eq!(connection.connector.truth_table, None); assert_eq!(connection.connector.parameter, None); for item in &sequence.items { @@ -13989,8 +13995,8 @@ mod tests { .connector .as_ref() .expect("connective question has connector metadata"); - assert_eq!(connector.source, "ji"); - assert_eq!(connector.locus, "property-abstraction"); + assert_eq!(connector.source.as_surface_word(), Some("ji")); + assert_eq!(connector.locus, ConnectorLocus::PropertyAbstraction); assert_eq!(connector.truth_table, None); let answer = connector .parameter @@ -14019,6 +14025,7 @@ mod tests { .filter_map(|predication| match predication.relation.as_data() { data!(PredicationRelation::Named { relation }) => Some(relation.clone()), data!(PredicationRelation::Parameter { .. }) => None, + data!(PredicationRelation::Composition) => None, }) .collect::>(), BTreeSet::from(["ganse".to_owned(), "zukte".to_owned()]) @@ -14047,7 +14054,7 @@ mod tests { .filter_map(|object| match object.as_formula()?.as_data() { data!(FormulaNode::Connective(connection)) if connection.connector.as_ref().is_some_and(|connector| { - connector.source == "gi'e" && connector.locus == "bridiTail" + connector.source.as_surface_word() == Some("gi'e") && connector.locus == ConnectorLocus::PredicatePhrase }) => { Some((object, connection)) @@ -14084,6 +14091,7 @@ mod tests { .filter_map(|predication| match predication.relation.as_data() { data!(PredicationRelation::Named { relation }) => Some(relation.clone()), data!(PredicationRelation::Parameter { .. }) => None, + data!(PredicationRelation::Composition) => None, }) .collect::>(), BTreeSet::from(["broda".to_owned(), "brode".to_owned()]) diff --git a/crates/jbotci-semantics/src/generated_builder/pro_bridi.rs b/crates/jbotci-semantics/src/generated_builder/pro_bridi.rs index 0b0bb459d5..17f9e737f4 100644 --- a/crates/jbotci-semantics/src/generated_builder/pro_bridi.rs +++ b/crates/jbotci-semantics/src/generated_builder/pro_bridi.rs @@ -105,7 +105,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { &tanru.first_unit, visible_arguments, formula_source, - "selbri", + ConnectorLocus::Predicate, Some(eventuality), )? } else { diff --git a/crates/jbotci-semantics/src/generated_builder/statements.rs b/crates/jbotci-semantics/src/generated_builder/statements.rs index 5d6254b581..127e754c1e 100644 --- a/crates/jbotci-semantics/src/generated_builder/statements.rs +++ b/crates/jbotci-semantics/src/generated_builder/statements.rs @@ -1674,7 +1674,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { target, item, "indicator", - Some(DisplayedContentTargetFocus::Bridi), + Some(DisplayedContentTargetFocus::Clause), false, ) } @@ -1742,7 +1742,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { target, item, "indicator", - Some(DisplayedContentTargetFocus::Bridi), + Some(DisplayedContentTargetFocus::Clause), force_assertion_effect_none, ) } @@ -1865,7 +1865,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { _ => None, }) .as_ref() - .is_some_and(|connector| connector.source == "tanru") => + .is_some_and(|connector| connector.source.is_implicit_juxtaposition()) => { object .formula_children() @@ -2935,7 +2935,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { formula, utterance_id, "indicator", - Some(DisplayedContentTargetFocus::Selbri), + Some(DisplayedContentTargetFocus::Predicate), false, )?; } @@ -4896,7 +4896,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { generated_modal_forethought_connective_negates_left(connective), generated_gik_connective_negates_right(gik), generated_modal_forethought_pair_source(connective, gik), - "statement", + ConnectorLocus::Statement, left, right, source, @@ -4924,7 +4924,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { false, false, connector_source, - "statement", + ConnectorLocus::Statement, left, right, source, @@ -4941,7 +4941,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { left_negated: bool, right_negated: bool, connector_source: String, - connector_locus: &str, + connector_locus: ConnectorLocus, left: SemanticObjectId, right: SemanticObjectId, source: Option, @@ -4980,8 +4980,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { }, children, Some(new!(Connector { - source: connector_source, - locus: connector_locus.to_owned(), + source: ConnectorSource::surface_word(connector_source), + locus: connector_locus, truth_table: generated_modal_forethought_connective_truth_table_with_negations( connective, left_negated, @@ -5141,6 +5141,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { .and_then(|node| match node.relation.as_data() { data!(PredicationRelation::Named { relation }) => Some(relation.as_str()), data!(PredicationRelation::Parameter { .. }) => None, + data!(PredicationRelation::Composition) => None, }) .is_some_and(generated_relation_is_pro_bridi_label) && let Some(object) = self.objects.get_mut(&predication) @@ -5250,8 +5251,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { operator, children, Some(new!(Connector { - source: connector_source, - locus: "statement".to_owned(), + source: ConnectorSource::surface_word(connector_source), + locus: ConnectorLocus::Statement, truth_table, parameter, })), @@ -5303,8 +5304,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { operator, vec![child], Some(new!(Connector { - source: connector_source, - locus: "statement".to_owned(), + source: ConnectorSource::surface_word(connector_source), + locus: ConnectorLocus::Statement, truth_table, parameter, })), diff --git a/crates/jbotci-semantics/src/generated_builder/sumti_connections.rs b/crates/jbotci-semantics/src/generated_builder/sumti_connections.rs index 46836ba312..135b924cbd 100644 --- a/crates/jbotci-semantics/src/generated_builder/sumti_connections.rs +++ b/crates/jbotci-semantics/src/generated_builder/sumti_connections.rs @@ -1173,8 +1173,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { generated_distributed_sumti_connective_formula_operator(connective), children, Some(new!(Connector { - source: connector_source, - locus: "sumti".to_owned(), + source: ConnectorSource::surface_word(connector_source), + locus: ConnectorLocus::Argument, truth_table: generated_distributed_sumti_connective_truth_table(connective), parameter: connector_parameter, })), diff --git a/crates/jbotci-semantics/src/generated_builder/sumti_referents.rs b/crates/jbotci-semantics/src/generated_builder/sumti_referents.rs index 22f7a7e763..f29ffff873 100644 --- a/crates/jbotci-semantics/src/generated_builder/sumti_referents.rs +++ b/crates/jbotci-semantics/src/generated_builder/sumti_referents.rs @@ -584,7 +584,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { selbri, visible_arguments, source.clone(), - "modal-argument", + ConnectorLocus::Tag, None, )?; self.set_formula_predication_mode(lowered.formula, PredicationMode::Incidental); @@ -2572,8 +2572,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { FormulaOperator::And, vec![atom_formula, involvement], Some(new!(Connector { - source: "jai".to_owned(), - locus: "bare-jai-raised-participant".to_owned(), + source: ConnectorSource::surface_word("jai".to_owned()), + locus: ConnectorLocus::BareRaisedParticipant, truth_table: None, parameter: None, })), @@ -3394,6 +3394,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { let relation = match node.relation.as_data() { data!(PredicationRelation::Named { relation }) => relation.clone(), data!(PredicationRelation::Parameter { .. }) => return Ok(None), + data!(PredicationRelation::Composition) => return Ok(None), }; let source_eventuality = node.eventuality; let mut arguments = node.arguments.clone(); @@ -6119,7 +6120,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { let quantity_connection = self .connected_quantifier_quantity_scope_for_generated_quantifier( quantifier, - "mekso-operand", + ConnectorLocus::Operand, )?; let quantity = if let Some(connection) = quantity_connection { new!(GeneratedPreparedArgumentQuantity::Connected(connection)) @@ -8486,8 +8487,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { }, children, Some(new!(Connector { - source: connector_source, - locus: "abstraction".to_owned(), + source: ConnectorSource::surface_word(connector_source), + locus: ConnectorLocus::Abstraction, truth_table: Some(truth_table), parameter: connector_parameter, })), @@ -8843,7 +8844,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { selbri, visible_arguments, self.source_for_node(selbri, "restrictive-selbri-formula"), - "description", + ConnectorLocus::Description, None, )?; self.set_formula_predication_mode(result.formula, PredicationMode::Restrictive); @@ -9142,12 +9143,12 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { } } - #[requires(!locus.is_empty())] + #[requires(true)] #[ensures(ret.as_ref().is_ok_and(|connection| connection.as_ref().is_none_or(|connection| connection.left_quantity.object_kind() == crate::model::SemanticObjectKind::Quantity && connection.right_quantity.object_kind() == crate::model::SemanticObjectKind::Quantity)) || ret.is_err())] pub(super) fn connected_quantifier_quantity_scope_for_generated_quantifier( &mut self, quantifier: &'tree QuantifierSyntax, - locus: &str, + locus: ConnectorLocus, ) -> Result, SemanticsError> { let QuantifierSyntax::MeksoQuantifier(quantifier) = quantifier else { return Ok(None); @@ -9155,12 +9156,12 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { self.connected_quantifier_quantity_scope_for_generated_mekso(&quantifier.mekso, locus) } - #[requires(!locus.is_empty())] + #[requires(true)] #[ensures(ret.as_ref().is_ok_and(|connection| connection.as_ref().is_none_or(|connection| connection.left_quantity.object_kind() == crate::model::SemanticObjectKind::Quantity && connection.right_quantity.object_kind() == crate::model::SemanticObjectKind::Quantity)) || ret.is_err())] pub(super) fn connected_quantifier_quantity_scope_for_generated_mekso( &mut self, expression: &'tree MeksoSyntax, - locus: &str, + locus: ConnectorLocus, ) -> Result, SemanticsError> { if let Some(parenthesized) = generated_parenthesized_mekso_operand_from_mekso(expression) { return self.connected_quantifier_quantity_scope_for_generated_mekso( @@ -9206,12 +9207,12 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { #[requires(generated_modal_forethought_connective_is_logical(&operand.gek))] #[requires(!generated_modal_forethought_connective_is_interval(&operand.gek))] - #[requires(!locus.is_empty())] + #[requires(true)] #[ensures(ret.as_ref().is_ok_and(|connection| connection.left_quantity.object_kind() == crate::model::SemanticObjectKind::Quantity && connection.right_quantity.object_kind() == crate::model::SemanticObjectKind::Quantity) || ret.is_err())] pub(super) fn build_generated_forethought_connected_quantifier_quantity_scope( &mut self, operand: &'tree ForethoughtMeksoOperandSyntax, - locus: &str, + locus: ConnectorLocus, source: Option, ) -> Result { let left_quantity = self.build_quantity_for_generated_mekso_operand( @@ -9229,8 +9230,10 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { right_negated: generated_gik_connective_negates_right(&operand.gik), operator: generated_modal_forethought_connective_formula_operator(&operand.gek), connector: new!(Connector { - source: generated_modal_forethought_connective_source(&operand.gek), - locus: locus.to_owned(), + source: ConnectorSource::surface_word( + generated_modal_forethought_connective_source(&operand.gek), + ), + locus: locus, truth_table: generated_modal_forethought_gik_connective_truth_table( &operand.gek, &operand.gik, @@ -9243,14 +9246,14 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { #[requires(generated_operand_connective_is_logical(connective))] #[requires(!generated_operand_connective_is_interval(connective))] - #[requires(!locus.is_empty())] + #[requires(true)] #[ensures(ret.as_ref().is_ok_and(|connection| connection.left_quantity.object_kind() == crate::model::SemanticObjectKind::Quantity && connection.right_quantity.object_kind() == crate::model::SemanticObjectKind::Quantity) || ret.is_err())] pub(super) fn build_generated_afterthought_connected_quantifier_quantity_scope( &mut self, left_operand: &'tree BoundOrSimpleMeksoOperandSyntax, connective: &jbotci_syntax::generated_model::OperandConnectiveSyntax, right_operand: &'tree BoundOrSimpleMeksoOperandSyntax, - locus: &str, + locus: ConnectorLocus, source: Option, ) -> Result { let left_quantity = self.build_quantity_for_generated_bound_or_simple_mekso_operand( @@ -9268,8 +9271,10 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { right_negated: generated_operand_connective_negates_right(connective), operator: generated_operand_connective_formula_operator(connective), connector: new!(Connector { - source: generated_operand_connective_source(connective), - locus: locus.to_owned(), + source: ConnectorSource::surface_word(generated_operand_connective_source( + connective, + )), + locus: locus, truth_table: generated_operand_connective_truth_table(connective), parameter: None, }), diff --git a/crates/jbotci-semantics/src/generated_builder/tanru_property.rs b/crates/jbotci-semantics/src/generated_builder/tanru_property.rs index d40a87e2ac..700620b9c0 100644 --- a/crates/jbotci-semantics/src/generated_builder/tanru_property.rs +++ b/crates/jbotci-semantics/src/generated_builder/tanru_property.rs @@ -112,7 +112,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { .clone() .flatten() .or_else(|| formula_source.clone()), - "selbri", + ConnectorLocus::Predicate, leading_eventuality, )?; self.set_semantic_object_source( @@ -796,7 +796,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { &simple_tail.selbri, visible_arguments, formula_source, - "selbri", + ConnectorLocus::Predicate, Some(eventuality), )?; self.set_semantic_object_source(result.head_predication, predication_source)?; @@ -1072,7 +1072,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { let quantity_connection = self .connected_quantifier_quantity_scope_for_generated_quantifier( quantifier, - "mekso-operand", + ConnectorLocus::Operand, )?; let quantity = if let Some(connection) = quantity_connection { new!(GeneratedPreparedArgumentQuantity::Connected(connection)) @@ -1120,7 +1120,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { let quantity_connection = self .connected_quantifier_quantity_scope_for_generated_quantifier( quantifier, - "mekso-operand", + ConnectorLocus::Operand, )?; let quantity = if let Some(connection) = quantity_connection { new!(GeneratedPreparedArgumentQuantity::Connected(connection)) @@ -1216,7 +1216,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { let quantity_connection = self .connected_quantifier_quantity_scope_for_generated_quantifier( quantifier, - "mekso-operand", + ConnectorLocus::Operand, )?; let quantity = if let Some(connection) = quantity_connection { new!(GeneratedPreparedArgumentQuantity::Connected(connection)) @@ -2221,8 +2221,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { FormulaOperator::And, vec![head.formula, relation_formula], Some(new!(Connector { - source: "tanru".to_owned(), - locus: "selbri".to_owned(), + source: new!(ConnectorSource::ImplicitJuxtaposition), + locus: ConnectorLocus::Predicate, truth_table: None, parameter: None, })), @@ -2314,7 +2314,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { )?; formula = self.build_binary_formula_for_relation_afterthought_connective( &continuation.connective, - "selbri", + ConnectorLocus::Predicate, formula, trailing.formula, source.clone(), @@ -2362,7 +2362,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { &tanru.first_unit, visible_arguments, source, - "selbri", + ConnectorLocus::Predicate, head_eventuality, ); } @@ -2382,7 +2382,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { selbri: &'syntax SelbriSyntax, visible_arguments: BTreeMap, source: Option, - connector_locus: &str, + connector_locus: ConnectorLocus, leading_eventuality: Option, ) -> Result { match selbri { @@ -2475,7 +2475,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { selbri: &'syntax UntaggedSelbriSyntax, visible_arguments: BTreeMap, source: Option, - connector_locus: &str, + connector_locus: ConnectorLocus, leading_eventuality: Option, ) -> Result { match selbri { @@ -2528,7 +2528,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { connection: &'syntax ForethoughtSelbriConnectionSyntax, mut visible_arguments: BTreeMap, source: Option, - connector_locus: &str, + connector_locus: ConnectorLocus, leading_eventuality: Option, ) -> Result { if !visible_arguments.contains_key(&1) { @@ -2597,7 +2597,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { unit: &'syntax ForethoughtSelbriGroupTanruUnitSyntax, mut visible_arguments: BTreeMap, source: Option, - connector_locus: &str, + connector_locus: ConnectorLocus, leading_eventuality: Option, ) -> Result { if !visible_arguments.contains_key(&1) { @@ -2663,7 +2663,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { unit: &'syntax TanruUnitSyntax, visible_arguments: BTreeMap, source: Option, - connector_locus: &str, + connector_locus: ConnectorLocus, leading_eventuality: Option, ) -> Result { if !unit.0.links.is_empty() { @@ -2716,7 +2716,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { unit: &'syntax BoundTanruUnitSyntax, mut visible_arguments: BTreeMap, source: Option, - connector_locus: &str, + connector_locus: ConnectorLocus, leading_eventuality: Option, ) -> Result { if let Some(connective) = &unit.bo_connective { @@ -2805,8 +2805,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { FormulaOperator::And, vec![head.formula, relation_formula], Some(new!(Connector { - source: "tanru".to_owned(), - locus: connector_locus.to_owned(), + source: new!(ConnectorSource::ImplicitJuxtaposition), + locus: connector_locus, truth_table: None, parameter: None, })), @@ -2857,7 +2857,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { unit, visible_arguments, source, - "tanru-unit", + ConnectorLocus::PredicateUnit, eventuality, )?; self.attach_generated_modal_terms_to_formula(result.formula, modal_terms)?; @@ -2878,7 +2878,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { unit, visible_arguments, source, - "tanru-unit", + ConnectorLocus::PredicateUnit, eventuality, )?; self.attach_generated_modal_terms_to_formula(result.formula, modal_terms)?; @@ -2889,7 +2889,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { unit, visible_arguments, source, - "tanru-unit", + ConnectorLocus::PredicateUnit, eventuality, ), BoOrLinkedTanruUnitSyntax::AssignedProBridiTanruUnit(unit) => self @@ -2910,7 +2910,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { unit: &'syntax TanruUnitSyntax, mut visible_arguments: BTreeMap, source: Option, - connector_locus: &str, + connector_locus: ConnectorLocus, leading_eventuality: Option, ) -> Result { if !visible_arguments.contains_key(&1) { @@ -2962,7 +2962,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { visible_arguments: BTreeMap, eventuality: Option, source: Option, - connector_locus: &str, + connector_locus: ConnectorLocus, ) -> Result { match unit { BoOrLinkedTanruUnitSyntax::LinkedTanruUnit(unit) => self @@ -3067,7 +3067,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { base, visible_arguments, source.clone(), - "selbri", + ConnectorLocus::Predicate, eventuality, )?; for adjunct in &adjuncts { @@ -4061,8 +4061,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { FormulaOperator::And, vec![head_formula, relation_formula], Some(new!(Connector { - source: "tanru".to_owned(), - locus: "property-inversion".to_owned(), + source: new!(ConnectorSource::ImplicitJuxtaposition), + locus: ConnectorLocus::PropertyInversion, truth_table: None, parameter: None, })), @@ -4123,8 +4123,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { FormulaOperator::And, vec![head_formula, relation_formula], Some(new!(Connector { - source: "tanru".to_owned(), - locus: "property-inversion".to_owned(), + source: new!(ConnectorSource::ImplicitJuxtaposition), + locus: ConnectorLocus::PropertyInversion, truth_table: None, parameter: None, })), @@ -4323,8 +4323,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { FormulaOperator::And, vec![tertau_formula, relation_formula], Some(new!(Connector { - source: "tanru".to_owned(), - locus: context.connector_locus().to_owned(), + source: new!(ConnectorSource::ImplicitJuxtaposition), + locus: context.connector_locus(), truth_table: None, parameter: None, })), @@ -4408,7 +4408,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { unit, visible_arguments, source, - "property-abstraction", + ConnectorLocus::PropertyAbstraction, leading_eventuality, ) .map(|result| result.formula) @@ -4439,7 +4439,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { )?; formula = self.build_binary_formula_for_relation_afterthought_connective( &link.connective, - "selbri", + ConnectorLocus::Predicate, formula, trailing, source.clone(), @@ -4564,7 +4564,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { )?; return self.build_binary_formula_for_relation_afterthought_connective( connective, - "property-abstraction", + ConnectorLocus::PropertyAbstraction, leading, trailing, source, @@ -4621,8 +4621,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { FormulaOperator::And, vec![head, relation_formula], Some(new!(Connector { - source: "tanru".to_owned(), - locus: "property-abstraction".to_owned(), + source: new!(ConnectorSource::ImplicitJuxtaposition), + locus: ConnectorLocus::PropertyAbstraction, truth_table: None, parameter: None, })), @@ -4697,8 +4697,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { FormulaOperator::And, vec![tertau_formula, relation_formula], Some(new!(Connector { - source: "tanru".to_owned(), - locus: context.connector_locus().to_owned(), + source: new!(ConnectorSource::ImplicitJuxtaposition), + locus: context.connector_locus(), truth_table: None, parameter: None, })), @@ -4758,7 +4758,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { unit, parameter, source, - "tanru-unit", + ConnectorLocus::PredicateUnit, ); } if let Some(sumti_selbri) = sumti_selbri_from_generated_tanru_unit(unit)? { @@ -4898,13 +4898,12 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { unit, parameter, source, - "property-abstraction", + ConnectorLocus::PropertyAbstraction, ) } #[requires(!unit.0.links.is_empty())] #[requires(parameter.object_kind() == crate::model::SemanticObjectKind::Parameter)] - #[requires(!locus.is_empty())] #[ensures(ret.as_ref().is_ok_and(|id| id.object_kind() == crate::model::SemanticObjectKind::Formula) || ret.is_err())] pub(super) fn build_connected_property_formula_for_tanru_unit_chain_with_locus< 'syntax: 'tree, @@ -4913,7 +4912,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { unit: &'syntax TanruUnitSyntax, parameter: SemanticObjectId, source: Option, - locus: &str, + locus: ConnectorLocus, ) -> Result { let mut formula = self.build_property_formula_for_bo_or_linked_tanru_unit( &unit.0.first, @@ -5100,7 +5099,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { let mut formula = self.build_binary_formula_for_generated_forethought_selbri_connective( &unit.guhek, &unit.first_branch.gik, - "property-abstraction", + ConnectorLocus::PropertyAbstraction, leading, trailing, source.clone(), @@ -5114,7 +5113,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { formula = self.build_binary_formula_for_generated_extra_forethought_selbri_connective( &unit.guhek, &branch.gik, - "property-abstraction", + ConnectorLocus::PropertyAbstraction, formula, trailing, source.clone(), @@ -5163,7 +5162,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { )?; return self.build_binary_formula_for_relation_afterthought_connective( connective, - "property-abstraction", + ConnectorLocus::PropertyAbstraction, leading, trailing, source, @@ -5192,8 +5191,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { FormulaOperator::And, vec![tertau_formula, relation_formula], Some(new!(Connector { - source: "tanru".to_owned(), - locus: "property-abstraction".to_owned(), + source: new!(ConnectorSource::ImplicitJuxtaposition), + locus: ConnectorLocus::PropertyAbstraction, truth_table: None, parameter: None, })), @@ -7249,7 +7248,6 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { self.insert( predication, SemanticObject::tanru_link_predication( - "tanru".to_owned(), None, arguments, TanruLink::new( @@ -7272,12 +7270,11 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { #[requires(left.object_kind() == crate::model::SemanticObjectKind::Formula)] #[requires(right.object_kind() == crate::model::SemanticObjectKind::Formula)] - #[requires(!locus.is_empty())] #[ensures(ret.as_ref().is_ok_and(|id| id.object_kind() == crate::model::SemanticObjectKind::Formula) || ret.is_err())] pub(super) fn build_binary_formula_for_relation_afterthought_connective<'syntax>( &mut self, connective: &'syntax RelationAfterthoughtConnectiveSyntax, - locus: &str, + locus: ConnectorLocus, left: SemanticObjectId, right: SemanticObjectId, source: Option, @@ -7314,8 +7311,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { operator, children, Some(new!(Connector { - source: connector_source, - locus: locus.to_owned(), + source: ConnectorSource::surface_word(connector_source), + locus: locus, truth_table: generated_relation_afterthought_connective_truth_table(connective), parameter, })), @@ -7328,13 +7325,12 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { #[requires(left.object_kind() == crate::model::SemanticObjectKind::Formula)] #[requires(right.object_kind() == crate::model::SemanticObjectKind::Formula)] - #[requires(!locus.is_empty())] #[ensures(ret.as_ref().is_ok_and(|id| id.object_kind() == crate::model::SemanticObjectKind::Formula) || ret.is_err())] pub(super) fn build_binary_formula_for_generated_forethought_selbri_connective<'syntax>( &mut self, guhek: &'syntax GuhekConnectiveSyntax, gik: &'syntax GikConnectiveSyntax, - locus: &str, + locus: ConnectorLocus, left: SemanticObjectId, right: SemanticObjectId, source: Option, @@ -7354,7 +7350,6 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { #[requires(left.object_kind() == crate::model::SemanticObjectKind::Formula)] #[requires(right.object_kind() == crate::model::SemanticObjectKind::Formula)] - #[requires(!locus.is_empty())] #[ensures(ret.as_ref().is_ok_and(|id| id.object_kind() == crate::model::SemanticObjectKind::Formula) || ret.is_err())] pub(super) fn build_binary_formula_for_generated_extra_forethought_selbri_connective< 'syntax, @@ -7362,7 +7357,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { &mut self, guhek: &'syntax GuhekConnectiveSyntax, gik: &'syntax ZantufaExtraGikConnectiveSyntax, - locus: &str, + locus: ConnectorLocus, left: SemanticObjectId, right: SemanticObjectId, source: Option, @@ -7388,7 +7383,6 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { #[requires(!connector_source.is_empty())] #[requires(left.object_kind() == crate::model::SemanticObjectKind::Formula)] #[requires(right.object_kind() == crate::model::SemanticObjectKind::Formula)] - #[requires(!locus.is_empty())] #[ensures(ret.as_ref().is_ok_and(|id| id.object_kind() == crate::model::SemanticObjectKind::Formula) || ret.is_err())] pub(super) fn build_formula_for_generated_forethought_selbri_connective_core<'syntax>( &mut self, @@ -7397,7 +7391,7 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { right_negated: bool, connector_source: String, truth_table: Option, - locus: &str, + locus: ConnectorLocus, left: SemanticObjectId, right: SemanticObjectId, source: Option, @@ -7428,8 +7422,8 @@ impl<'a, 'dict, 'tree> GeneratedGraphBuilder<'a, 'dict, 'tree> { operator, children, Some(new!(Connector { - source: connector_source, - locus: locus.to_owned(), + source: ConnectorSource::surface_word(connector_source), + locus: locus, truth_table, parameter: None, })), diff --git a/crates/jbotci-semantics/src/model.rs b/crates/jbotci-semantics/src/model.rs index c1c88ed2ec..b3d48d847b 100644 --- a/crates/jbotci-semantics/src/model.rs +++ b/crates/jbotci-semantics/src/model.rs @@ -3257,14 +3257,97 @@ impl QuantifierBinding { } } -#[invariant(!source.is_empty())] -#[invariant(!locus.is_empty())] +/// Surface provenance of a connective: either the word that actually appears in +/// the text, or an implicit juxtaposition connective synthesized for a tanru +/// (predicate juxtaposition) run, which has no surface word at all. This replaces +/// the former magic-string sentinel that spelled implicit connectives as `"tanru"`. +#[invariant(::SurfaceWord { word } => !word.is_empty(), "a surface-word connector source names the word appearing in the text")] +#[derive(Debug, Clone, PartialEq, Eq, Serialize)] +#[serde(rename_all = "camelCase", tag = "kind")] +pub enum ConnectorSource { + SurfaceWord { word: String }, + ImplicitJuxtaposition, +} + +impl ConnectorSource { + #[requires(!word.is_empty())] + #[ensures(ret.as_surface_word() == Some(old(word.clone()).as_str()))] + pub fn surface_word(word: String) -> Self { + Self::from_data(data!(ConnectorSource::SurfaceWord { word })) + } + + #[requires(true)] + #[ensures(ret.is_some() == matches!(self.as_data(), data!(ConnectorSource::SurfaceWord { .. })))] + pub fn as_surface_word(&self) -> Option<&str> { + match self.as_data() { + data!(ConnectorSource::SurfaceWord { word }) => Some(word.as_str()), + data!(ConnectorSource::ImplicitJuxtaposition) => None, + } + } + + #[requires(true)] + #[ensures(ret == matches!(self.as_data(), data!(ConnectorSource::ImplicitJuxtaposition)))] + pub fn is_implicit_juxtaposition(&self) -> bool { + matches!( + self.as_data(), + data!(ConnectorSource::ImplicitJuxtaposition) + ) + } +} + +/// The grammatical position at which a connective joins its operands. Variants +/// are named in English; Lojban grammar terms (selbri, bridi, sumti, ...) are +/// parser vocabulary and must not leak into the model-facing notation. +#[invariant(true)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)] +#[serde(rename_all = "camelCase")] +pub enum ConnectorLocus { + /// Sentence-level connection (`.i` / statement connectives). + Statement, + /// Connection between arguments (sumti position). + Argument, + /// Connection between terms of a bridi. + Term, + /// Connection between termsets. + TermSet, + /// Connection between tenses. + Tense, + /// Connection between modal tags (BAI/FIhO constructs). + Tag, + /// Connection between mekso operands. + Operand, + /// Forethought connection of full clauses (gek position). + Clause, + /// Connection of bridi-tails: the predicate expression together with its + /// trailing arguments (gihek position). + PredicatePhrase, + /// Connection of predicate expressions (selbri position), e.g. the implicit + /// connective of a tanru run in the main selbri. + Predicate, + /// The implicit connective of a `co`-inverted tanru in the main selbri. + PredicateInversion, + /// A `bo`-bound predicate unit nested as head inside a larger tanru chain. + PredicateUnit, + /// A tanru run inside a property abstraction (ka body). + PropertyAbstraction, + /// A `co`-inverted tanru inside a property abstraction. + PropertyInversion, + /// Connection inside an abstraction. + Abstraction, + /// A tanru run in a description (restrictive) body. + Description, + /// Connection between mekso operators. + MathOperator, + /// A bare (untagged) `jai` raising of a participant into argument position. + BareRaisedParticipant, +} + #[invariant(parameter.is_none_or(|parameter| parameter.object_kind() == SemanticObjectKind::Parameter))] #[derive(Debug, Clone, PartialEq, Eq, Serialize)] #[serde(rename_all = "camelCase")] pub struct Connector { - pub source: String, - pub locus: String, + pub source: ConnectorSource, + pub locus: ConnectorLocus, #[serde(skip_serializing_if = "Option::is_none")] pub truth_table: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -3499,8 +3582,12 @@ pub enum DisplayedContentPolarity { #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)] #[serde(rename_all = "camelCase")] pub enum DisplayedContentTargetFocus { - Bridi, - Selbri, + /// The displayed content targets the containing clause as a whole + /// (a Lojban bridi). + Clause, + /// The displayed content targets the predicate-expression locus of the + /// containing clause (a Lojban selbri). + Predicate, } #[invariant(!relation.is_empty(), "displayed-content modifier relation must be named")] @@ -4993,8 +5080,8 @@ mod tests { FormulaOperator::ConnectiveQuestion, vec![child], Some(new!(Connector { - source: "je'i".to_owned(), - locus: "tense".to_owned(), + source: ConnectorSource::surface_word("je'i".to_owned()), + locus: ConnectorLocus::Tense, truth_table: None, parameter: Some(parameter), })), diff --git a/crates/jbotci-semantics/src/model/semantic_object.rs b/crates/jbotci-semantics/src/model/semantic_object.rs index a2816bebe9..fdb7992517 100644 --- a/crates/jbotci-semantics/src/model/semantic_object.rs +++ b/crates/jbotci-semantics/src/model/semantic_object.rs @@ -186,12 +186,18 @@ pub struct ParameterNode { pub enum PredicationRelation { Named { relation: String }, Parameter { parameter: SemanticObjectId }, + /// The relation is a predicate composition (a tanru link): the real content + /// lives in the predication's `tanru_link` sidecar, so there is no relation + /// name or parameter to state. Constructing such a predication with a fake + /// relation name (the former `"tanru"` sentinel) is not representable. + Composition, } #[invariant(eventuality.is_none_or(eventuality_is_referent))] #[invariant(arguments.keys().all(|place| place.get() > 0))] #[invariant(relation_metadata.is_none_or(|metadata| metadata.object_kind() == SemanticObjectKind::RelationMetadata))] #[invariant(introduced_by.as_ref().is_none_or(|introduced_by| !introduced_by.is_empty()))] +#[invariant(tanru_link.is_some() == matches!(relation.as_data(), data!(PredicationRelation::Composition)), "a tanru-link sidecar is present exactly when the relation is a composition")] #[derive(Debug, Clone, PartialEq)] pub struct PredicationNode { pub relation: PredicationRelation, @@ -1333,10 +1339,9 @@ impl SemanticObject { }))) } - #[requires(!relation.is_empty())] + #[requires(true)] #[ensures(ret.object_kind() == SemanticObjectKind::Predication)] pub fn tanru_link_predication( - relation: String, eventuality: Option, arguments: BTreeMap, tanru_link: TanruLink, @@ -1344,15 +1349,22 @@ impl SemanticObject { source: Option, diagnostics: Vec, ) -> Self { - let predication = - match Self::predication(relation, eventuality, arguments, mode, source, diagnostics) - .into_data() - { - data!(SemanticObject::Predication(predication)) => predication, - _ => unreachable!("predication constructor returns a predication"), - }; - new!(SemanticObject::Predication(predication.with_data(data! { + // The `tanru_link` sidecar and the `Composition` relation must appear + // together (the `PredicationNode` invariant ties them), so the node is + // built in a single step rather than via `predication_with_relation`. + new!(SemanticObject::Predication(new!(PredicationNode { + relation: new!(PredicationRelation::Composition), + eventuality, tanru_link: Some(tanru_link), + arguments, + place_questions: Vec::new(), + adjuncts: Vec::new(), + reciprocity: Vec::new(), + mode, + scalar_negation: None, + relation_metadata: None, + introduced_by: None, + common: SemanticObjectCommon::new(source, diagnostics), }))) } @@ -2820,6 +2832,9 @@ fn serialize_predication( data!(PredicationRelation::Parameter { parameter }) => { map.serialize_entry("relationParameter", parameter)? } + // A composition relation has no name or parameter to state: the + // `tanruLink` entry below carries the real content. + data!(PredicationRelation::Composition) => {} } optional_entry!(map, "tanruLink", node.tanru_link.as_ref()); nonempty_entry!(map, "arguments", &node.arguments); diff --git a/crates/jbotci-semantics/src/notation/mod.rs b/crates/jbotci-semantics/src/notation/mod.rs index 4f8ea62138..779cc9b5d0 100644 --- a/crates/jbotci-semantics/src/notation/mod.rs +++ b/crates/jbotci-semantics/src/notation/mod.rs @@ -55,6 +55,7 @@ pub mod coverage; mod render; +pub(crate) mod relation_expression; pub mod word_cards; mod writer; mod xml; @@ -67,7 +68,7 @@ use bityzba::{ensures, invariant, requires}; pub use render::SmusniConfig; pub use xml::{ XML_DECLARED_WAIVERS, XmlOmission, XmlRender, XmlSurface, XmlWaiverFamily, render_xml, - render_xml_with_word_cards, + render_xml_value_for_tooling, render_xml_with_word_cards, }; use crate::model::SemanticGraph; diff --git a/crates/jbotci-semantics/src/notation/relation_expression.rs b/crates/jbotci-semantics/src/notation/relation_expression.rs new file mode 100644 index 0000000000..c92c27dbe5 --- /dev/null +++ b/crates/jbotci-semantics/src/notation/relation_expression.rs @@ -0,0 +1,2465 @@ +//! Recognition and projection of tanru (predicate-juxtaposition) graph patterns +//! into typed relation expressions for SFN-XML rendering (jbotci#719). +//! +//! The semantic graph lowers a tanru to a formula-level `and` whose children are +//! the head formula and a link predication carrying a `tanruLink` sidecar. The +//! canonical SFN-XML notation renders that pattern as one PREDICATION whose +//! relation slot holds a KIND-COMPOSITION relation expression; the head/link +//! decomposition is the notation's elaboration of that compact form, not +//! something a model-facing document should spell out per instance. +//! +//! This module is the recognition boundary. It walks the canonical graph JSON, +//! proves the canonical tanru pattern for each candidate (strict structural +//! guards — anything shared, decorated, questioned, or otherwise non-flat +//! rejects the compact form), rewrites the objects map (the AND formula becomes +//! the head predication's atom; the head predication gains a typed +//! `relationExpression` view; consumed scaffolding objects are removed), and +//! reports every consumed object so the XML renderer's omission accounting can +//! classify the removed surfaces (projected structure vs waived provenance). +//! Graphs that fail the guards keep the loud head-and-link form. + +use std::collections::{BTreeMap, BTreeSet, HashSet}; + +#[allow(unused_imports)] +use bityzba::{data, ensures, invariant, new, requires}; +use serde::Serialize; +use serde_json::{Map, Value}; + +/// Grouping basis stated on a KIND-COMPOSITION node. Silence means +/// ASSUMED-LEFT (the deterministic grammar default); only edges whose grouping +/// the text itself determines (a bo/ke boundary, visible in the graph as +/// head-side nesting of the composed AND) are marked. +#[invariant(true)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)] +#[serde(rename_all = "camelCase")] +pub(crate) enum CompositionGrouping { + Explicit, +} + +/// One operand of a relation composition: the typed view attached to a +/// projected predication as its `relationExpression` field. +#[invariant(::Host { participant_place } => *participant_place > 0)] +#[invariant(::Lexical { predicate, participant_place, fixed_arguments, unfilled_places, .. } => + !predicate.is_empty() + && *participant_place > 0 + && !fixed_arguments.contains_key(participant_place) + && !unfilled_places.contains(participant_place) + && fixed_arguments.keys().all(|place| *place > 0) + && unfilled_places.iter().all(|place| *place > 0))] +#[invariant(::Composition { kind, .. } => + !matches!(kind.as_data(), data!(RelationOperand::Connective { .. }) | data!(RelationOperand::Reference { .. })), + "the kind side of a composition is a head, leaf, or nested composition, never a connective or reference")] +#[invariant(::Connective { operator, operands } => + !operator.is_empty() + && operands.len() >= 2 + && operands.iter().all(|operand| matches!(operand.as_data(), data!(RelationOperand::Lexical { .. }))), + "a relation connective conjoins at least two compact lexical leaves")] +#[invariant(::Reference { relation } => !relation.is_empty())] +#[derive(Debug, Clone, PartialEq, Serialize)] +#[serde(tag = "type", rename_all = "camelCase", rename_all_fields = "camelCase")] +pub(crate) enum RelationOperand { + /// The enclosing predication's own predicate; the predicate name is read + /// from the predication's `relation` field rather than duplicated here. + Host { participant_place: usize }, + /// A compact lexical relation leaf: one lexical predicate, a flat place + /// map, and (when present) a fresh locally bound eventuality. + Lexical { + predicate: String, + participant_place: usize, + #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] + fixed_arguments: BTreeMap, + #[serde(default, skip_serializing_if = "Vec::is_empty")] + unfilled_places: Vec, + has_event: bool, + }, + /// A nested composition (a tanru inside a tanru): the KIND-COMPOSITION + /// node of the typed relation-expression view. + #[serde(rename = "kindComposition")] + Composition { + #[serde(skip_serializing_if = "Option::is_none")] + grouping: Option, + kind: Box, + modifier: Box, + }, + /// A logical connective over co-modifiers of the same head participant + /// (a je-connected seltau lowered inside the property body). + Connective { + operator: String, + operands: Vec, + }, + /// A composite modifier that stays in the graph and renders through the + /// existing RELATION-lambda / abstraction idioms (NU abstractions, + /// be-linked arguments with non-default structure, joi composites, shared + /// or decorated eventualities — anything the compact guards reject). + Reference { relation: String }, +} + +/// One recognized and projected tanru instance. Its fields are the elaboration +/// contract of the acceptance test (re-expansion), which is `cfg(test)` — in +/// production builds they are unread, hence the targeted allow. +#[invariant(!anchor.is_empty() && !head_predication.is_empty())] +#[invariant(!consumed.contains(anchor) && !consumed.contains(head_predication), "the anchor and head predication survive projection")] +#[derive(Debug, Clone)] +#[allow(dead_code)] +pub(crate) struct ProjectedInstance { + /// The formula id whose AND was rewritten into the head atom (it survives). + pub(crate) anchor: String, + /// The surviving head predication carrying the `relationExpression` view. + pub(crate) head_predication: String, + /// Every consumed (removed) object id, including nested instances' ids but + /// excluding the anchor itself. + pub(crate) consumed: BTreeSet, + /// The typed relation-expression view attached to the head predication. + pub(crate) composition: RelationOperand, +} + +/// The result of projecting every proven tanru pattern in a graph. +#[invariant(consumed_objects.keys().all(|key| !rewritten_anchors.contains_key(key)), "consumed objects and rewritten anchors are disjoint")] +#[derive(Debug, Clone)] +pub(crate) struct TanruProjection { + /// Per-instance projection data (the acceptance test re-expands these). + #[allow(dead_code)] + pub(crate) instances: Vec, + /// The original JSON of every consumed object, for omission accounting. + pub(crate) consumed_objects: Map, + /// The original JSON of every anchor formula rewritten to the head atom + /// (the anchor survives, but its `children`/`connector` fields do not — + /// omission accounting must classify those surfaces too). + pub(crate) rewritten_anchors: Map, +} + +#[requires(true)] +#[ensures(true)] +fn object_of(value: &Value) -> Option<&Map> { + value.as_object() +} + +#[requires(true)] +#[ensures(true)] +fn string_of(value: &Value) -> Option<&str> { + value.as_str() +} + +#[requires(true)] +#[ensures(true)] +fn field<'a>(object: &'a Map, name: &str) -> Option<&'a Value> { + object.get(name) +} + +#[requires(true)] +#[ensures(true)] +fn string_field_of<'a>(object: &'a Map, name: &str) -> Option<&'a str> { + object.get(name).and_then(Value::as_str) +} + +#[requires(true)] +#[ensures(true)] +fn is_object_type(object: &Map, expected: &str) -> bool { + string_field_of(object, "type") == Some(expected) +} + +/// The bound-eventuality id list of a formula object (empty when absent). +#[requires(is_object_type(object, "formula"))] +#[ensures(true)] +fn bound_eventualities(object: &Map) -> Vec<&str> { + object + .get("boundEventualities") + .and_then(Value::as_array) + .map(|bound| bound.iter().filter_map(Value::as_str).collect()) + .unwrap_or_default() +} + +/// The place number of an argument key (`x2` → 2); zero marks a malformed key. +#[requires(true)] +#[ensures(true)] +fn argument_place(key: &str) -> usize { + key.strip_prefix('x') + .and_then(|digits| digits.parse::().ok()) + .unwrap_or(0) +} + +/// Whether a connector record is the implicit tanru-juxtaposition connective. +#[requires(true)] +#[ensures(true)] +fn is_implicit_connector(object: &Map) -> bool { + object + .get("connector") + .and_then(Value::as_object) + .and_then(|connector| connector.get("source")) + .and_then(Value::as_object) + .and_then(|source| string_field_of(source, "kind")) + == Some("implicitJuxtaposition") +} + +/// The truth table a binary logical operator already determines (row order TT, +/// TF, FT, FF), mirroring the XML renderer's `canonical_truth_table`. +#[requires(true)] +#[ensures(ret.is_none_or(|table| table.len() == 4))] +fn canonical_truth_table(operator: &str) -> Option<&'static str> { + match operator { + "and" => Some("TFFF"), + "or" => Some("TTTF"), + "iff" => Some("TFFT"), + "whetherOrNot" => Some("TTFF"), + _ => None, + } +} + +/// The formula ids reachable from a tanru AND through tanru-internal nesting: +/// the modifier-property region (link predication → tanruLink.modifier → +/// property body → recurse) plus head-side nested implicit ANDs (the bo/ke +/// right-grouping case). Used to order candidates outermost-first: a nested +/// candidate must be consumed by its parent's projection, never projected +/// standalone ahead of it. +#[requires(true)] +#[ensures(true)] +fn tanru_region_walk(objects: &Map, anchor: &str) -> BTreeSet { + let mut reached = BTreeSet::new(); + let mut frontier = vec![anchor.to_owned()]; + while let Some(formula_id) = frontier.pop() { + let Some(formula) = objects.get(&formula_id).and_then(Value::as_object) else { + continue; + }; + let Some(children) = formula.get("children").and_then(Value::as_array) else { + continue; + }; + // Head-side nested implicit AND (bo/ke right-grouping). + if let Some(head_id) = children.first().and_then(Value::as_str) { + let is_nested_and = objects + .get(head_id) + .and_then(Value::as_object) + .is_some_and(|head| { + string_field_of(head, "operator") == Some("and") && is_implicit_connector(head) + }); + if is_nested_and && reached.insert(head_id.to_owned()) { + frontier.push(head_id.to_owned()); + } + } + // Modifier-property nesting. + let Some(link_atom) = children.get(1).and_then(Value::as_str) else { + continue; + }; + let Some(link_formula) = objects.get(link_atom).and_then(Value::as_object) else { + continue; + }; + let Some(link_predication_id) = string_field_of(link_formula, "predication") else { + continue; + }; + let Some(link) = objects + .get(link_predication_id) + .and_then(Value::as_object) + else { + continue; + }; + let Some(modifier) = link + .get("tanruLink") + .and_then(Value::as_object) + .and_then(|tanru_link| string_field_of(tanru_link, "modifier")) + else { + continue; + }; + let Some(relation) = objects.get(modifier).and_then(Value::as_object) else { + continue; + }; + let Some(body) = string_field_of(relation, "body") else { + continue; + }; + if reached.insert(body.to_owned()) { + frontier.push(body.to_owned()); + } + } + reached +} + +/// One recognized tanru AND formula before the edits are applied. +#[invariant(!anchor.is_empty() && !head_predication.is_empty() && !participant.is_empty())] +#[invariant(!consumed.contains(anchor), "the anchor formula is rewritten, not consumed")] +#[invariant(consumed.contains(head_predication) == matches!(composition.as_data(), data!(RelationOperand::Composition { kind, .. }) if matches!(kind.as_data(), data!(RelationOperand::Lexical { .. }))), "the head predication is consumed exactly when it projects as a lexical leaf (nested in a property body); host and nested-composition heads survive")] +#[derive(Debug)] +struct TanruMatch { + anchor: String, + head_predication: String, + /// The link predication's x1 (the composition participant). + participant: String, + /// Bound eventualities the rewritten anchor formula must carry (the AND's + /// own bindings plus, for a plain head, the head atom's). + rewritten_bound: Vec, + composition: RelationOperand, + /// Consumed object ids, excluding the anchor. + consumed: BTreeSet, +} + +/// Whether a relation is a lexical Lojban predicate: morphologically a single +/// brivla (gismu, lujvo, or fu'ivla, zei compounds included) per the +/// morphology parser — the typed provenance for the compact lexical form, as +/// opposed to synthesized structural relation names. +#[requires(!relation.is_empty())] +#[ensures(true)] +fn relation_is_lexical_brivla(relation: &str) -> bool { + let Ok(words) = jbotci_morphology::segment_words_with_modifiers(relation) else { + return false; + }; + let [word] = words.as_slice() else { + return false; + }; + word.is_brivla() +} + +/// Fields a predication inside a projected modifier/head must not carry: any of +/// them makes the relation expression non-flat. +const NON_FLAT_PREDICATION_FIELDS: &[&str] = &[ + "placeQuestions", + "adjuncts", + "reciprocity", + "scalarNegation", + "relationMetadata", + "introducedBy", +]; + +#[requires(true)] +#[ensures(true)] +fn has_non_flat_fields(predication: &Map) -> bool { + NON_FLAT_PREDICATION_FIELDS + .iter() + .any(|field| predication.contains_key(*field)) +} + +/// The recognized shape of a lexical relation leaf (a bare-brivla modifier or a +/// nested composition's head): one named predicate over its property parameter +/// with a flat place map and at most a fresh locally bound eventuality. +#[requires(is_object_type(predication, "predication"))] +#[requires(string_field_of(predication, "relation").is_some())] +#[ensures(ret.as_ref().is_none_or(|(_, _, consumed)| consumed.contains(predication_id)))] +fn recognize_lexical_leaf( + objects: &Map, + predication_id: &str, + predication: &Map, + parameter: &str, + locally_bound: &HashSet, +) -> Option<(RelationOperand, Vec, BTreeSet)> { + if has_non_flat_fields(predication) || predication.contains_key("tanruLink") { + return None; + } + if string_field_of(predication, "mode") != Some("restrictive") { + return None; + } + // A lexical predicate is morphologically a brivla (gismu, lujvo, or + // fu'ivla — including zei compounds); anything else (synthesized + // structural relations such as eventOf/memberOf, abstraction links, tense + // relations) belongs to the composite abstraction idioms, not the compact + // form. Classification goes through the morphology parser, never string + // shape (AGENTS.md). + let predicate = string_field_of(predication, "relation")?; + if !relation_is_lexical_brivla(predicate) { + return None; + } + let arguments = field(predication, "arguments")?.as_object()?; + let mut participant_place = None; + let mut fixed_arguments = BTreeMap::new(); + let mut unfilled_places = Vec::new(); + let mut consumed: BTreeSet = [predication_id.to_owned()].into_iter().collect(); + for (key, argument) in arguments { + let place = argument_place(key); + let argument = argument.as_object()?; + match string_field_of(argument, "kind")? { + "filled" => { + let value = string_field_of(argument, "value")?; + if value == parameter { + if participant_place.is_some() || place == 0 { + return None; + } + participant_place = Some(place); + } else { + if place == 0 || argument.contains_key("introducedBy") { + return None; + } + fixed_arguments.insert(place, value.to_owned()); + } + } + "elided" => { + if place == 0 || string_field_of(argument, "introducedBy") != Some("zo'e") { + return None; + } + let value = string_field_of(argument, "value")?; + let referent = object_of(objects.get(value)?)?; + if !is_object_type(referent, "referent") + || string_field_of(referent, "category") != Some("constant") + || string_field_of(referent, "sort") != Some("entity") + { + return None; + } + let descriptor = field(referent, "descriptor")?.as_object()?; + if string_field_of(descriptor, "kind") != Some("elided") + || string_field_of(descriptor, "word") != Some("zo'e") + { + return None; + } + for field_name in referent.keys() { + if !matches!( + field_name.as_str(), + "type" | "category" | "scopeDependence" | "sort" | "descriptor" | "source" + ) { + return None; + } + } + unfilled_places.push(place); + consumed.insert(value.to_owned()); + } + _ => return None, + } + } + let participant_place = participant_place?; + unfilled_places.sort_unstable(); + let event = string_field_of(predication, "eventuality"); + if let Some(event) = event { + if !locally_bound.contains(event) { + return None; + } + let referent = object_of(objects.get(event)?)?; + if !is_object_type(referent, "referent") + || string_field_of(referent, "denotation") != Some("generated-bound") + || string_field_of(referent, "sort") != Some("eventuality") + { + return None; + } + // A decorated (tense/aspect/anything-else) modifier event is not the + // derivable fresh-local eventuality of the compact form. + for field_name in referent.keys() { + if !matches!( + field_name.as_str(), + "type" | "denotation" | "sort" | "scopeDependence" | "source" + ) { + return None; + } + } + consumed.insert(event.to_owned()); + } + Some(( + new!(RelationOperand::Lexical { + predicate: string_field_of(predication, "relation")?.to_owned(), + participant_place, + fixed_arguments, + unfilled_places, + has_event: event.is_some(), + }), + event.into_iter().map(str::to_owned).collect(), + consumed, + )) +} + +/// Project one modifier property body formula into a relation operand. `parameter` +/// is the enclosing property's slot; every leaf's participant must fill it. +#[requires(true)] +#[ensures(ret.as_ref().is_none_or(|(_, consumed)| consumed.contains(body_id)))] +fn project_modifier_body( + objects: &Map, + body_id: &str, + parameter: &str, +) -> Option<(RelationOperand, BTreeSet)> { + let body = object_of(objects.get(body_id)?)?; + let operator = string_field_of(body, "operator")?; + let mut consumed: BTreeSet = [body_id.to_owned()].into_iter().collect(); + if operator == "atom" { + let predication_id = string_field_of(body, "predication")?; + let predication = object_of(objects.get(predication_id)?)?; + if !is_object_type(predication, "predication") { + return None; + } + let locally_bound: HashSet = bound_eventualities(body) + .into_iter() + .map(str::to_owned) + .collect(); + let (operand, events, leaf_consumed) = + recognize_lexical_leaf(objects, predication_id, predication, parameter, &locally_bound)?; + // Every eventuality this atom binds must be the leaf's own event. + if locally_bound.len() != events.len() { + return None; + } + consumed.extend(leaf_consumed); + return Some((operand, consumed)); + } + if operator == "and" && is_implicit_connector(body) { + // A nested tanru inside the property body: default left grouping, so + // the nested composition carries no grouping mark. + let nested = recognize_tanru_and(objects, body_id, Some(parameter))?; + let nested_data = nested.into_data(); + consumed.extend(nested_data.consumed); + consumed.insert(nested_data.anchor.clone()); + return Some((nested_data.composition, consumed)); + } + // A je-style connected modifier: a formula connective over co-modifier + // leaves sharing the same property parameter. + let connector = field(body, "connector")?.as_object()?; + let source = field(connector, "source")?.as_object()?; + if string_field_of(source, "kind") != Some("surfaceWord") || !bound_eventualities(body).is_empty() + { + return None; + } + if let Some(table) = string_field_of(connector, "truthTable") { + if canonical_truth_table(operator) != Some(table) { + return None; + } + } + if connector.contains_key("parameter") { + return None; + } + let children = field(body, "children")?.as_array()?; + if children.len() < 2 { + return None; + } + let mut operands = Vec::with_capacity(children.len()); + for child in children { + let child_id = string_of(child)?; + let child_formula = object_of(objects.get(child_id)?)?; + if !is_object_type(child_formula, "formula") + || string_field_of(child_formula, "operator") != Some("atom") + { + return None; + } + let predication_id = string_field_of(child_formula, "predication")?; + let predication = object_of(objects.get(predication_id)?)?; + if !is_object_type(predication, "predication") { + return None; + } + let locally_bound: HashSet = bound_eventualities(child_formula) + .into_iter() + .map(str::to_owned) + .collect(); + let (operand, events, leaf_consumed) = + recognize_lexical_leaf(objects, predication_id, predication, parameter, &locally_bound)?; + if locally_bound.len() != events.len() { + return None; + } + consumed.insert(child_id.to_owned()); + consumed.extend(leaf_consumed); + operands.push(operand); + } + Some(( + new!(RelationOperand::Connective { + operator: operator.to_owned(), + operands, + }), + consumed, + )) +} + +/// Project the modifier side of a proven tanru link. Falls back to a reference +/// to the surviving relation referent whenever the compact guards reject the +/// property body (NU abstractions, be-link structure, shared state, ...). +/// `allowed_referrers` names the link-side objects whose references to the +/// modifier relation are expected (they are consumed by the enclosing match). +#[requires(true)] +#[ensures(true)] +fn project_modifier( + objects: &Map, + modifier: &str, + allowed_referrers: &HashSet, +) -> (RelationOperand, BTreeSet) { + let compact = (|| { + let relation = object_of(objects.get(modifier)?)?; + if !is_object_type(relation, "referent") + || string_field_of(relation, "sort") != Some("relation") + || field(relation, "arity")? != &Value::from(1) + { + return None; + } + let parameters = field(relation, "parameters")?.as_array()?; + let [parameter] = parameters.as_slice() else { + return None; + }; + let parameter = string_of(parameter)?; + let parameter_object = object_of(objects.get(parameter)?)?; + if !is_object_type(parameter_object, "parameter") + || string_field_of(parameter_object, "role") != Some("propertySlot") + { + return None; + } + for field_name in parameter_object.keys() { + if !matches!( + field_name.as_str(), + "type" | "sort" | "role" | "introducedBy" | "source" + ) { + return None; + } + } + let body_id = string_field_of(relation, "body")?; + let (operand, mut consumed) = project_modifier_body(objects, body_id, parameter)?; + consumed.insert(modifier.to_owned()); + consumed.insert(parameter.to_owned()); + Some((operand, consumed)) + })(); + match compact { + Some((operand, consumed)) => { + // The compact form consumes the whole modifier subtree, so nothing + // outside it may reference any of its objects, and no formula it + // consumes may bind an eventuality that survives. + let closed = objects.iter().all(|(key, value)| { + if consumed.contains(key) || allowed_referrers.contains(key) { + return true; + } + let serialized = value.to_string(); + !consumed + .iter() + .any(|id| serialized.contains(format!("\"{id}\"").as_str())) + }) && consumed.iter().all(|id| { + objects + .get(id) + .and_then(Value::as_object) + .filter(|object| is_object_type(object, "formula")) + .is_none_or(|formula| { + bound_eventualities(formula) + .into_iter() + .all(|event| consumed.contains(event)) + }) + }); + if closed { + (operand, consumed) + } else { + ( + new!(RelationOperand::Reference { + relation: modifier.to_owned(), + }), + BTreeSet::new(), + ) + } + } + None => ( + new!(RelationOperand::Reference { + relation: modifier.to_owned(), + }), + BTreeSet::new(), + ), + } +} + +/// Recognize one tanru AND formula. With `nested_parameter = Some(p)` the match +/// is nested inside a property body: its head projects as a lexical leaf over +/// `p` and its own bound eventualities must be exactly its head event. With +/// `None` (or as the head side of a larger tanru) the head is the surviving +/// predication and the AND's bindings are preserved on the rewritten formula. +#[requires(true)] +#[ensures(ret.as_ref().is_none_or(|m| !m.consumed.contains(&m.anchor)))] +fn recognize_tanru_and( + objects: &Map, + anchor: &str, + nested_parameter: Option<&str>, +) -> Option { + let formula = object_of(objects.get(anchor)?)?; + if !is_object_type(formula, "formula") || string_field_of(formula, "operator") != Some("and") { + return None; + } + if !is_implicit_connector(formula) { + return None; + } + let connector = field(formula, "connector")?.as_object()?; + if connector.contains_key("truthTable") || connector.contains_key("parameter") { + return None; + } + let children = field(formula, "children")?.as_array()?; + let [head_id, link_id] = children.as_slice() else { + return None; + }; + let head_id = string_of(head_id)?; + let link_id = string_of(link_id)?; + + // The link side: an atom of a composition predication whose tanruLink + // points back at the head predication and at the modifier relation. + let link_formula = object_of(objects.get(link_id)?)?; + if !is_object_type(link_formula, "formula") + || string_field_of(link_formula, "operator") != Some("atom") + || !bound_eventualities(link_formula).is_empty() + { + return None; + } + let link_predication_id = string_field_of(link_formula, "predication")?; + let link = object_of(objects.get(link_predication_id)?)?; + if !is_object_type(link, "predication") + || link.contains_key("relation") + || link.contains_key("relationParameter") + || link.contains_key("eventuality") + || has_non_flat_fields(link) + { + return None; + } + let tanru_link = field(link, "tanruLink")?.as_object()?; + let link_head = string_field_of(tanru_link, "head")?; + let modifier = string_field_of(tanru_link, "modifier")?; + let arguments = field(link, "arguments")?.as_object()?; + if arguments.len() != 2 { + return None; + } + let x1 = field(arguments, "x1")?.as_object()?; + let x2 = field(arguments, "x2")?.as_object()?; + if string_field_of(x1, "kind") != Some("filled") + || string_field_of(x2, "kind") != Some("filled") + || string_field_of(x2, "value") != Some(modifier) + || x1.contains_key("introducedBy") + || x2.contains_key("introducedBy") + { + return None; + } + let participant = string_field_of(x1, "value")?; + // The link predication's mode must equal the head predication's mode: the + // compact form states one mode on the composed predication, so unequal + // modes cannot compact (re-expansion synthesizes the link mode from the + // head). + let link_mode = string_field_of(link, "mode")?; + + let mut consumed: BTreeSet = [link_id.to_owned(), link_predication_id.to_owned()] + .into_iter() + .collect(); + + // The head side: either the surviving predication (possibly itself a + // nested tanru AND, the bo/ke right-grouping case), or — when this match + // is nested inside a property body — a lexical leaf over the parameter. + let (kind, head_predication, head_bound) = if nested_parameter.is_some() { + let head_formula = object_of(objects.get(head_id)?)?; + if !is_object_type(head_formula, "formula") + || string_field_of(head_formula, "operator") != Some("atom") + { + return None; + } + let head_predication_id = string_field_of(head_formula, "predication")?; + if head_predication_id != link_head { + return None; + } + let head_predication = object_of(objects.get(head_predication_id)?)?; + if !is_object_type(head_predication, "predication") + || string_field_of(head_predication, "mode") != Some("restrictive") + || link_mode != "restrictive" + { + return None; + } + // The nested AND's own bindings must be exactly the head leaf's event. + let and_bound: HashSet = bound_eventualities(formula) + .into_iter() + .map(str::to_owned) + .collect(); + let (operand, events, head_consumed) = recognize_lexical_leaf( + objects, + head_predication_id, + head_predication, + nested_parameter?, + &and_bound, + )?; + if and_bound.len() != events.len() { + return None; + } + consumed.insert(head_id.to_owned()); + consumed.extend(head_consumed); + (operand, head_predication_id.to_owned(), Vec::new()) + } else { + let head_formula = object_of(objects.get(head_id)?)?; + if is_object_type(head_formula, "formula") + && string_field_of(head_formula, "operator") == Some("atom") + { + let head_predication_id = string_field_of(head_formula, "predication")?; + if head_predication_id != link_head { + return None; + } + let head_predication = object_of(objects.get(head_predication_id)?)?; + if !is_object_type(head_predication, "predication") + || string_field_of(head_predication, "relation").is_none() + || head_predication.contains_key("tanruLink") + || head_predication.contains_key("relationExpression") + || string_field_of(head_predication, "mode") != Some(link_mode) + { + return None; + } + // The participant place is the unique head place whose value is + // the link's x1; ambiguity rejects the projection. + let head_arguments = field(head_predication, "arguments")?.as_object()?; + let mut participant_place = None; + for (key, argument) in head_arguments { + let argument = argument.as_object()?; + if string_field_of(argument, "kind") == Some("filled") + && string_field_of(argument, "value") == Some(participant) + { + if participant_place.is_some() { + return None; + } + participant_place = Some(argument_place(key)); + } + } + let participant_place = participant_place.filter(|place| *place > 0)?; + consumed.insert(head_id.to_owned()); + let head_bound = bound_eventualities(head_formula) + .into_iter() + .map(str::to_owned) + .collect(); + ( + new!(RelationOperand::Host { participant_place }), + head_predication_id.to_owned(), + head_bound, + ) + } else if is_object_type(head_formula, "formula") + && string_field_of(head_formula, "operator") == Some("and") + && is_implicit_connector(head_formula) + { + // bo/ke right-grouping: the nested composition sits on the head + // side and shares this tanru's head predication; its edge is the + // explicit one. + let nested = recognize_tanru_and(objects, head_id, None)?; + if nested.head_predication != link_head || nested.participant != participant { + return None; + } + // The outer link's mode must equal the shared head predication's + // mode, just like a plain head's link. + let shared_head = object_of(objects.get(link_head)?)?; + if string_field_of(shared_head, "mode") != Some(link_mode) { + return None; + } + // The nested AND's bindings must not escape: they may reference + // only objects the nested match itself consumes. + for event in bound_eventualities(head_formula) { + if !nested.consumed.contains(event) { + return None; + } + } + let nested_data = nested.into_data(); + let head_predication = nested_data.head_predication.clone(); + consumed.extend(nested_data.consumed); + consumed.insert(head_id.to_owned()); + let data!(RelationOperand::Composition { kind, modifier, .. }) = + nested_data.composition.into_data() + else { + unreachable!("a recognized tanru always produces a composition"); + }; + ( + new!(RelationOperand::Composition { + grouping: Some(CompositionGrouping::Explicit), + kind, + modifier, + }), + head_predication, + Vec::new(), + ) + } else { + return None; + } + }; + + let allowed_referrers: HashSet = [link_id.to_owned(), link_predication_id.to_owned()] + .into_iter() + .collect(); + let (modifier_operand, modifier_consumed) = + project_modifier(objects, modifier, &allowed_referrers); + // The compact modifier form is consumed here, so nothing it consumes may + // be referenced by objects outside this whole match (the anchor may + // reference its own children only). + for (key, value) in objects { + if key == anchor || consumed.contains(key) || modifier_consumed.contains(key) { + continue; + } + let serialized = value.to_string(); + if consumed + .iter() + .chain(modifier_consumed.iter()) + .any(|id| serialized.contains(format!("\"{id}\"").as_str())) + { + return None; + } + } + consumed.extend(modifier_consumed); + + let composition = normalize_grouping(new!(RelationOperand::Composition { + grouping: None, + kind: Box::new(kind), + modifier: Box::new(modifier_operand), + })); + + // The rewritten anchor carries the AND's own bindings plus the plain head + // atom's (nested matches already consumed theirs). + let mut rewritten_bound: Vec = bound_eventualities(formula) + .into_iter() + .map(str::to_owned) + .collect(); + rewritten_bound.extend(head_bound); + + Some(new!(TanruMatch { + anchor: anchor.to_owned(), + head_predication, + participant: participant.to_owned(), + rewritten_bound, + composition, + consumed, + })) +} + +/// Tree-level grouping rollup: a uniformly explicit tree states EXPLICIT at the +/// root only; a mixed tree states EXPLICIT per affected node (silence is +/// ASSUMED-LEFT everywhere else). +#[requires(true)] +#[ensures(true)] +fn normalize_grouping(composition: RelationOperand) -> RelationOperand { + #[requires(true)] + #[ensures(true)] + fn all_explicit(operand: &RelationOperand) -> bool { + match operand.as_data() { + data!(RelationOperand::Composition { grouping, kind, modifier }) => { + *grouping == Some(CompositionGrouping::Explicit) + && all_explicit(kind) + && all_explicit(modifier) + } + data!(RelationOperand::Connective { operands, .. }) => { + operands.iter().all(all_explicit) + } + _ => true, + } + } + + #[requires(true)] + #[ensures(true)] + fn clear_grouping(operand: RelationOperand) -> RelationOperand { + match operand.into_data() { + data!(RelationOperand::Composition { kind, modifier, .. }) => { + new!(RelationOperand::Composition { + grouping: None, + kind: Box::new(clear_grouping(*kind)), + modifier: Box::new(clear_grouping(*modifier)), + }) + } + data => RelationOperand::from_data(data), + } + } + + if all_explicit(&composition) { + let cleared = clear_grouping(composition); + let data!(RelationOperand::Composition { kind, modifier, .. }) = cleared.into_data() + else { + unreachable!("the root of a projected view is always a composition"); + }; + new!(RelationOperand::Composition { + grouping: Some(CompositionGrouping::Explicit), + kind, + modifier, + }) + } else { + composition + } +} + +/// Project every proven tanru pattern in `objects`. Returns the transformed +/// objects map (AND formulas rewritten to head atoms, head predications +/// carrying their `relationExpression` view, consumed scaffolding removed) and +/// the projection report for omission accounting and the acceptance test. +#[requires(true)] +#[ensures(ret.0.len() <= objects.len())] +pub(crate) fn project_tanru_compositions( + objects: &Map, +) -> (Map, TanruProjection) { + let mut candidates: Vec<&str> = objects + .iter() + .filter(|(_, value)| { + value.as_object().is_some_and(|object| { + is_object_type(object, "formula") + && string_field_of(object, "operator") == Some("and") + && is_implicit_connector(object) + }) + }) + .map(|(key, _)| key.as_str()) + .collect(); + candidates.sort_unstable(); + + let mut consumed_global: HashSet = HashSet::new(); + let mut matches = Vec::new(); + // Process outermost candidates first: an implicit AND nested inside another + // candidate's modifier property must be consumed by that parent's + // projection, never projected standalone ahead of it. Depth = how many + // other candidates' modifier walks contain the anchor. + let depth_of = |anchor: &str| -> usize { + candidates + .iter() + .filter(|other| **other != anchor) + .filter(|other| tanru_region_walk(objects, other).contains(anchor)) + .count() + }; + let mut ordered = candidates.clone(); + ordered.sort_by_key(|anchor| depth_of(anchor)); + for candidate in ordered { + if consumed_global.contains(candidate) { + continue; + } + // A candidate nested inside an already-projected match is consumed by + // its parent; overlapping independent matches cannot occur by + // construction (the consumed sets are disjoint graph regions). + if let Some(result) = recognize_tanru_and(objects, candidate, None) { + if result + .consumed + .iter() + .any(|id| consumed_global.contains(id)) + { + continue; + } + consumed_global.extend(result.consumed.iter().cloned()); + matches.push(result); + } + } + + let mut transformed = objects.clone(); + let mut instances = Vec::with_capacity(matches.len()); + let mut consumed_objects = Map::new(); + let mut rewritten_anchors = Map::new(); + for result in matches { + for id in &result.consumed { + if let Some(original) = transformed.remove(id) { + consumed_objects.insert(id.clone(), original); + } + } + rewritten_anchors.insert( + result.anchor.clone(), + transformed[&result.anchor].clone(), + ); + let anchor_object = transformed + .get_mut(&result.anchor) + .and_then(Value::as_object_mut) + .unwrap_or_else(|| panic!("tanru anchor must survive: {}", result.anchor)); + let source = anchor_object.get("source").cloned(); + let mut rewritten = Map::new(); + rewritten.insert("type".to_owned(), Value::from("formula")); + rewritten.insert("operator".to_owned(), Value::from("atom")); + rewritten.insert( + "predication".to_owned(), + Value::from(result.head_predication.as_str()), + ); + if !result.rewritten_bound.is_empty() { + rewritten.insert( + "boundEventualities".to_owned(), + Value::Array( + result + .rewritten_bound + .iter() + .map(|event| Value::from(event.as_str())) + .collect(), + ), + ); + } + if let Some(source) = source { + rewritten.insert("source".to_owned(), source); + } + *anchor_object = rewritten; + let head_object = transformed + .get_mut(&result.head_predication) + .and_then(Value::as_object_mut) + .unwrap_or_else(|| panic!("tanru head predication must survive: {}", result.head_predication)); + let view = serde_json::to_value(&result.composition) + .expect("relation-expression view serialization cannot fail"); + head_object.insert("relationExpression".to_owned(), view); + let result = result.into_data(); + instances.push(new!(ProjectedInstance { + anchor: result.anchor, + head_predication: result.head_predication, + consumed: result.consumed, + composition: result.composition, + })); + } + + ( + transformed, + new!(TanruProjection { + instances, + consumed_objects, + rewritten_anchors, + }), + ) +} + +/// The re-expansion elaboration contract and its acceptance test (jbotci#719, +/// mandated by the round-14 decision): re-expanding the *rendered* relation +/// expression — the KIND-COMPOSITION/BODY/RELATION/PARTICIPANT-PLACE surface +/// of the emitted SFN-XML — must reproduce the recognized subgraph modulo +/// opaque ids and waived provenance. The re-expander is a second, independent +/// implementation of the tanru graph shape; the comparer pairs object ids by +/// BFS encounter order so only structure, field values, and reference topology +/// are compared. Negative fixtures prove the loud/composite fallbacks fire +/// for unequal link/head modes, shared or decorated modifier eventualities, +/// and non-flat place maps. +#[cfg(test)] +pub(crate) mod reexpansion { + use std::collections::{BTreeMap, BTreeSet, HashMap, VecDeque}; + + use serde_json::{Map, Value}; + + #[allow(unused_imports)] + use bityzba::{data, ensures, invariant, new, requires}; + use jbotci_dictionary::Dictionary; + + use super::{ + ProjectedInstance, RelationOperand, RelationOperandData, canonical_truth_table, + project_tanru_compositions, + }; + + /// Deterministic fresh id source for regenerated scaffolding objects. + #[requires(true)] + #[ensures(ret.starts_with(prefix))] + fn fresh_id(next: &mut usize, prefix: &str) -> String { + *next += 1; + format!("{prefix}:{}", 900_000 + *next) + } + + #[requires(true)] + #[ensures(true)] + fn object(fields: &[(&str, Value)]) -> Value { + Value::Object( + fields + .iter() + .map(|(name, value)| ((*name).to_owned(), value.clone())) + .collect(), + ) + } + + #[requires(true)] + #[ensures(true)] + fn id_list(ids: &[String]) -> Value { + Value::Array(ids.iter().map(|id| Value::from(id.as_str())).collect()) + } + + /// The scope-dependence record of a generated relation referent or elided + /// referent: `fixed` when no property parameters enclose it, otherwise an + /// underspecified dependence on exactly the enclosing parameter stack. + #[requires(true)] + #[ensures(true)] + fn scope_dependence(enclosing_parameters: &[String]) -> Value { + if enclosing_parameters.is_empty() { + object(&[("kind", Value::from("fixed"))]) + } else { + object(&[ + ("kind", Value::from("underspecified")), + ("mayDependOn", id_list(enclosing_parameters)), + ]) + } + } + + /// Regenerate one lexical leaf predication and its atom formula: the + /// participant fills `parameter`, fixed places keep their targets, every + /// unfilled place elaborates to a distinct ordinary elided (zo'e) node, + /// and the leaf eventuality is fresh and locally bound. + #[requires(!parameter.is_empty() && !predicate.is_empty() && participant_place > 0)] + #[ensures(true)] + fn expand_lexical_leaf( + next: &mut usize, + predicate: &str, + participant_place: usize, + fixed_arguments: &BTreeMap, + unfilled_places: &[usize], + has_event: bool, + parameter: &str, + enclosing_parameters: &[String], + bind_event_at_atom: bool, + out: &mut Map, + ) -> String { + let mut arguments = Map::new(); + arguments.insert( + format!("x{participant_place}"), + object(&[ + ("kind", Value::from("filled")), + ("value", Value::from(parameter)), + ]), + ); + for (place, target) in fixed_arguments { + arguments.insert( + format!("x{place}"), + object(&[ + ("kind", Value::from("filled")), + ("value", Value::from(target.as_str())), + ]), + ); + } + for place in unfilled_places { + let referent = fresh_id(next, "entity"); + out.insert( + referent.clone(), + object(&[ + ("type", Value::from("referent")), + ("category", Value::from("constant")), + ("scopeDependence", scope_dependence(enclosing_parameters)), + ("sort", Value::from("entity")), + ( + "descriptor", + object(&[ + ("kind", Value::from("elided")), + ("word", Value::from("zo'e")), + ]), + ), + ]), + ); + arguments.insert( + format!("x{place}"), + object(&[ + ("kind", Value::from("elided")), + ("value", Value::from(referent.as_str())), + ("introducedBy", Value::from("zo'e")), + ]), + ); + } + let eventuality = has_event.then(|| fresh_id(next, "eventuality")); + if let Some(eventuality) = &eventuality { + out.insert( + eventuality.clone(), + object(&[ + ("type", Value::from("referent")), + ("denotation", Value::from("generated-bound")), + ("sort", Value::from("eventuality")), + ]), + ); + } + let predication = fresh_id(next, "predication"); + let mut fields = Vec::from([ + ("type", Value::from("predication")), + ("relation", Value::from(predicate)), + ("arguments", Value::Object(arguments)), + ("mode", Value::from("restrictive")), + ]); + if let Some(eventuality) = &eventuality { + fields.insert(1, ("eventuality", Value::from(eventuality.as_str()))); + } + out.insert(predication.clone(), object(&fields)); + let atom = fresh_id(next, "formula"); + let mut atom_fields = Vec::from([ + ("type", Value::from("formula")), + ("operator", Value::from("atom")), + ("predication", Value::from(predication.as_str())), + ]); + if bind_event_at_atom + && let Some(eventuality) = &eventuality + { + atom_fields.push(("boundEventualities", id_list(&[eventuality.clone()]))); + } + out.insert(atom.clone(), object(&atom_fields)); + atom + } + + /// Decompose one operand into the flat pieces the leaf expander needs, + /// panicking on non-lexical operands. + #[requires(true)] + #[ensures(true)] + fn expand_lexical_operand( + next: &mut usize, + operand: &RelationOperand, + parameter: &str, + enclosing_parameters: &[String], + bind_event_at_atom: bool, + out: &mut Map, + ) -> String { + let data!(RelationOperand::Lexical { + predicate, + participant_place, + fixed_arguments, + unfilled_places, + has_event, + }) = operand.as_data() + else { + panic!("expand_lexical_operand requires a lexical operand"); + }; + expand_lexical_leaf( + next, + predicate, + *participant_place, + fixed_arguments, + unfilled_places, + *has_event, + parameter, + enclosing_parameters, + bind_event_at_atom, + out, + ) + } + + /// Regenerate the modifier property abstraction for one operand, returning + /// the relation referent id. A `Reference` operand survives in the graph, + /// so its id is returned unchanged with no new objects. + #[requires(true)] + #[ensures(true)] + fn expand_modifier( + next: &mut usize, + operand: &RelationOperand, + enclosing_parameters: &[String], + out: &mut Map, + ) -> String { + if let data!(RelationOperand::Reference { relation }) = operand.as_data() { + return relation.clone(); + } + let parameter = fresh_id(next, "parameter"); + out.insert( + parameter.clone(), + object(&[ + ("type", Value::from("parameter")), + ("sort", Value::from("entity")), + ("role", Value::from("propertySlot")), + ("introducedBy", Value::from("ce'u")), + ]), + ); + let mut nested_parameters = enclosing_parameters.to_vec(); + nested_parameters.push(parameter.clone()); + let body = match operand.as_data() { + data!(RelationOperand::Lexical { .. }) => { + expand_lexical_operand(next, operand, ¶meter, &nested_parameters, true, out) + } + data!(RelationOperand::Composition { .. }) => expand_composition( + next, + operand, + None, + ¶meter, + "restrictive", + &nested_parameters, + out, + ), + data!(RelationOperand::Connective { operator, operands }) => { + let children: Vec = operands + .iter() + .map(|operand| { + expand_lexical_operand(next, operand, ¶meter, &nested_parameters, true, out) + }) + .collect(); + let formula = fresh_id(next, "formula"); + let mut connector = Map::new(); + if let Some(table) = canonical_truth_table(operator) { + connector.insert("truthTable".to_owned(), Value::from(table)); + } + out.insert( + formula.clone(), + object(&[ + ("type", Value::from("formula")), + ("operator", Value::from(operator.as_str())), + ("children", id_list(&children)), + ("connector", Value::Object(connector)), + ]), + ); + formula + } + data!(RelationOperand::Host { .. }) => { + panic!("a host operand cannot head a modifier property") + } + data!(RelationOperand::Reference { .. }) => unreachable!("handled above"), + }; + let relation = fresh_id(next, "relation"); + out.insert( + relation.clone(), + object(&[ + ("type", Value::from("referent")), + ("category", Value::from("constant")), + ("scopeDependence", scope_dependence(enclosing_parameters)), + ("sort", Value::from("relation")), + ("body", Value::from(body.as_str())), + ("parameters", id_list(&[parameter.clone()])), + ("arity", Value::from(1)), + ]), + ); + relation + } + + /// Regenerate the tanru AND formula for one composition node. `surviving_head` + /// is the head predication id for `Host` operands (present at the root and + /// at bo/ke head-side nesting); `participant` is the link x1 value. + #[requires(!participant.is_empty())] + #[ensures(true)] + fn expand_composition( + next: &mut usize, + composition: &RelationOperand, + surviving_head: Option<&str>, + participant: &str, + mode: &str, + enclosing_parameters: &[String], + out: &mut Map, + ) -> String { + let data!(RelationOperand::Composition { kind, modifier, .. }) = + composition.as_data() + else { + panic!("expand_composition requires a composition operand"); + }; + let (head_child, head_predication, head_event) = match kind.as_data() { + data!(RelationOperand::Host { .. }) => { + let head_predication = + surviving_head.expect("a host operand requires the surviving head predication"); + let atom = fresh_id(next, "formula"); + out.insert( + atom.clone(), + object(&[ + ("type", Value::from("formula")), + ("operator", Value::from("atom")), + ("predication", Value::from(head_predication)), + ]), + ); + (atom, head_predication.to_owned(), None) + } + data!(RelationOperand::Lexical { has_event, .. }) => { + // A composition head's eventuality is bound by its tanru AND, + // not by its own atom (unlike a modifier leaf's). + let atom = + expand_lexical_operand(next, kind, participant, enclosing_parameters, false, out); + let predication = out[&atom]["predication"] + .as_str() + .expect("atom predication") + .to_owned(); + let event = has_event.then(|| { + out[&predication]["eventuality"] + .as_str() + .expect("leaf event") + .to_owned() + }); + (atom, predication, event) + } + data!(RelationOperand::Composition { .. }) => { + let and = expand_composition( + next, + kind, + surviving_head, + participant, + mode, + enclosing_parameters, + out, + ); + ( + and, + surviving_head + .expect("bo nesting shares the head predication") + .to_owned(), + None, + ) + } + data!(RelationOperand::Connective { .. }) | data!(RelationOperand::Reference { .. }) => { + panic!("the kind side of a composition is never a connective or reference") + } + }; + let modifier_relation = expand_modifier(next, modifier, enclosing_parameters, out); + let link_predication = fresh_id(next, "predication"); + out.insert( + link_predication.clone(), + object(&[ + ("type", Value::from("predication")), + ( + "tanruLink", + object(&[ + ("head", Value::from(head_predication.as_str())), + ("modifier", Value::from(modifier_relation.as_str())), + ]), + ), + ( + "arguments", + object(&[ + ( + "x1", + object(&[ + ("kind", Value::from("filled")), + ("value", Value::from(participant)), + ]), + ), + ( + "x2", + object(&[ + ("kind", Value::from("filled")), + ("value", Value::from(modifier_relation.as_str())), + ]), + ), + ]), + ), + ("mode", Value::from(mode)), + ]), + ); + let link_atom = fresh_id(next, "formula"); + out.insert( + link_atom.clone(), + object(&[ + ("type", Value::from("formula")), + ("operator", Value::from("atom")), + ("predication", Value::from(link_predication.as_str())), + ]), + ); + let and = fresh_id(next, "formula"); + let mut and_fields = Vec::from([ + ("type", Value::from("formula")), + ("operator", Value::from("and")), + ("children", id_list(&[head_child, link_atom])), + ("connector", Value::Object(Map::new())), + ]); + // A nested composition's AND binds its head leaf's eventuality; the + // root AND's bindings are restored verbatim from the rewritten atom. + if let Some(event) = head_event { + and_fields.push(("boundEventualities", id_list(&[event]))); + } + out.insert(and.clone(), object(&and_fields)); + and + } + + /// The property/abstraction parameter stack enclosing a formula in the + /// surviving graph (outermost first), found by walking body→parent + /// links from the anchor. Needed when a nested tanru projects standalone + /// while its enclosing property stays loud: the regenerated subtree's + /// scope-dependence records name those surviving enclosing parameters. + #[requires(true)] + #[ensures(true)] + fn surviving_enclosing_parameters(objects: &Map, anchor: &str) -> Vec { + let mut stack = Vec::new(); + let mut current = anchor.to_owned(); + loop { + let parent = objects.iter().find(|(_, value)| { + value + .as_object() + .and_then(|object| object.get("body")) + .and_then(Value::as_str) + == Some(current.as_str()) + && value + .as_object() + .and_then(|object| object.get("parameters")) + .and_then(Value::as_array) + .is_some() + }); + let Some((parent_id, parent)) = parent else { + break; + }; + let parameters: Vec = parent + .get("parameters") + .and_then(Value::as_array) + .expect("parent parameters") + .iter() + .filter_map(|parameter| parameter.as_str().map(str::to_owned)) + .collect(); + stack = parameters.into_iter().chain(stack).collect(); + current = parent_id.clone(); + } + stack + } + + /// The host participant place of a projected view (the kind side's + /// innermost Host operand). + #[requires(true)] + #[ensures(true)] + fn host_participant_place(composition: &RelationOperand) -> usize { + let mut kind = composition; + loop { + match kind.as_data() { + data!(RelationOperand::Composition { kind: nested, .. }) => kind = nested, + data!(RelationOperand::Host { participant_place }) => return *participant_place, + _ => panic!("a projected instance always bottoms out at a host operand"), + } + } + } + + /// Re-expand one projected instance with the given relation-expression + /// view: the inverse elaboration of the compact relation expression, + /// regenerating scaffolding with fresh (opaque) ids. + #[requires(true)] + #[ensures(true)] + pub(crate) fn reexpand_instance( + objects: &Map, + instance: &ProjectedInstance, + view: &RelationOperand, + next: &mut usize, + ) -> Map { + let mut expanded = objects.clone(); + let bound = expanded[&instance.anchor] + .get("boundEventualities") + .and_then(Value::as_array) + .cloned(); + let head_object = expanded + .get_mut(&instance.head_predication) + .and_then(Value::as_object_mut) + .expect("head predication survives"); + head_object.remove("relationExpression"); + let mode = head_object + .get("mode") + .and_then(Value::as_str) + .expect("head predication mode") + .to_owned(); + let participant_place = host_participant_place(view); + let participant = head_object["arguments"] + .get(format!("x{participant_place}")) + .and_then(|argument| argument.get("value")) + .and_then(Value::as_str) + .expect("participant argument") + .to_owned(); + let enclosing = surviving_enclosing_parameters(&expanded, &instance.anchor); + let mut regenerated = Map::new(); + let and = expand_composition( + next, + view, + Some(&instance.head_predication), + &participant, + &mode, + &enclosing, + &mut regenerated, + ); + // The regenerated AND takes the anchor's id (the anchor survives); + // its bindings move back from the rewritten atom verbatim. + let mut and_object = match regenerated.remove(&and) { + Some(Value::Object(and_object)) => and_object, + _ => panic!("regenerated AND must be an object"), + }; + if let Some(bound) = bound { + and_object.insert("boundEventualities".to_owned(), Value::Array(bound)); + } + expanded.insert(instance.anchor.clone(), Value::Object(and_object)); + for (key, value) in regenerated { + expanded.insert(key, value); + } + expanded + } + + /// Re-expand every projected instance with its recognizer-produced view + /// (used by the negative/guard fixtures; the acceptance driver re-expands + /// the *rendered* view instead). + #[requires(true)] + #[ensures(true)] + pub(crate) fn reexpand_instances( + objects: &Map, + instances: &[ProjectedInstance], + ) -> Map { + let mut expanded = objects.clone(); + let mut next = 0usize; + for instance in instances { + let view = instance.composition.clone(); + expanded = reexpand_instance(&expanded, instance, &view, &mut next); + } + expanded + } + + /// Replicate the renderer's id assignment (`make_id` in notation::xml): + /// a type/sort prefix plus the graph key's numeric suffix. + #[requires(!key.is_empty())] + #[ensures(!ret.is_empty())] + fn make_id(key: &str, object: &Map) -> String { + let prefix = if object.get("type").and_then(Value::as_str) == Some("referent") { + if object + .get("sort") + .and_then(Value::as_str) + .is_some_and(|sort| sort.starts_with("eventuality")) + { + "e" + } else { + "r" + } + } else { + match object.get("type").and_then(Value::as_str) { + Some("utterance") => "u", + Some("predication") => "p", + Some("formula") => "f", + Some("quantity") => "q", + Some("parameter") => "v", + Some("sequence") => "s", + Some("displayedContent") => "d", + Some("mathExpression") => "m", + Some("question") => "x", + _ => "o", + } + }; + let suffix = key + .rsplit_once(':') + .map(|(_, suffix)| suffix) + .filter(|suffix| suffix.chars().all(|character| character.is_ascii_digit())) + .unwrap_or_else(|| panic!("graph key lacks JSON-aligned suffix: {key:?}")); + format!("{prefix}{suffix}") + } + + /// Rendered id (r7, e12, p9) → graph key (entity:7, eventuality:12, + /// predication:9), for every object in the graph. + #[requires(true)] + #[ensures(true)] + fn rendered_id_to_key_map(objects: &Map) -> HashMap { + objects + .iter() + .map(|(key, value)| { + let object = value.as_object().expect("graph object"); + (make_id(key, object), key.clone()) + }) + .collect() + } + + /// The elided-place list of a compact lexical leaf per the KEY's + /// elaboration contract: every lexical place of the predicate (per the + /// dictionary place structure) that is neither the participant nor a fixed + /// argument elaborates to a distinct ordinary elided-place node. + #[requires(!predicate.is_empty() && participant_place > 0)] + #[ensures(true)] + fn lexical_unfilled_places( + dictionary: &Dictionary<'_>, + predicate: &str, + participant_place: usize, + fixed_arguments: &BTreeMap, + ) -> Vec { + let arity = crate::dictionary_relation_place_count(dictionary, predicate) + .unwrap_or_else(|| panic!("dictionary must know the place count of {predicate}")); + (1..=arity) + .filter(|place| *place != participant_place && !fixed_arguments.contains_key(place)) + .collect() + } + + /// Parse one operand element (KIND, MODIFIER, or RELATION) of a rendered + /// KIND-COMPOSITION back into the typed view. `host_slot` is true exactly + /// on the root composition's kind chain (the bo/ke head side); only there + /// does a bare PREDICATE= leaf mean the enclosing predication's own + /// predicate. + #[requires(true)] + #[ensures(true)] + fn operand_from_xml( + element: roxmltree::Node<'_, '_>, + host_slot: bool, + id_to_key: &HashMap, + dictionary: &Dictionary<'_>, + objects: &Map, + host_relation: &str, + ) -> RelationOperand { + if let Some(reference) = element.attribute("REF") { + return new!(RelationOperand::Reference { + relation: id_to_key + .get(reference) + .unwrap_or_else(|| panic!("unknown rendered id {reference}")) + .clone(), + }); + } + if let Some(predicate) = element.attribute("PREDICATE") { + let participant_place = element + .attribute("PARTICIPANT-PLACE") + .map(|place| place.parse::().expect("PARTICIPANT-PLACE is numeric")) + .unwrap_or(1); + if host_slot { + // The host leaf names the surviving head predication's own + // relation: validate the rendered value instead of discarding + // it, so a swapped host predicate fails the acceptance check. + assert_eq!( + predicate, host_relation, + "rendered host predicate does not match the surviving head predication" + ); + return new!(RelationOperand::Host { participant_place }); + } + let mut fixed_arguments = BTreeMap::new(); + for child in element.children().filter(|child| child.is_element()) { + assert_eq!(child.tag_name().name(), "ARG"); + let place: usize = child + .attribute("INDEX") + .expect("operand ARG INDEX") + .parse() + .expect("operand ARG INDEX is numeric"); + let target = child.attribute("REF").expect("operand ARG REF"); + fixed_arguments.insert( + place, + id_to_key + .get(target) + .unwrap_or_else(|| panic!("unknown rendered id {target}")) + .clone(), + ); + } + let unfilled_places = + lexical_unfilled_places(dictionary, predicate, participant_place, &fixed_arguments); + return new!(RelationOperand::Lexical { + predicate: predicate.to_owned(), + participant_place, + fixed_arguments, + unfilled_places, + has_event: true, + }); + } + let body = element + .children() + .find(|child| child.is_element() && child.tag_name().name() == "BODY") + .unwrap_or_else(|| panic!("operand {} has no PREDICATE=, REF=, or BODY", element.tag_name().name())); + let content = body + .children() + .find(roxmltree::Node::is_element) + .expect("BODY wraps one relation-expression subtree"); + match content.tag_name().name() { + "KIND-COMPOSITION" => { + composition_from_xml(content, host_slot, id_to_key, dictionary, objects, host_relation) + } + "CONNECTIVE" => { + let operator = match content.attribute("OPERATOR").expect("CONNECTIVE OPERATOR") { + "AND" => "and", + "OR" => "or", + other => panic!("unknown relation connective operator {other}"), + }; + let operands: Vec = content + .children() + .filter(|child| child.is_element() && child.tag_name().name() == "RELATION") + .map(|leaf| operand_from_xml(leaf, false, id_to_key, dictionary, objects, host_relation)) + .collect(); + new!(RelationOperand::Connective { + operator: operator.to_owned(), + operands, + }) + } + // A composite RELATION-lambda/abstraction subtree rendered inline: + // the relation it defines survives in the graph. + _ => { + let id = content.attribute("ID").map(str::to_owned); + let relation = match id { + Some(id) => id_to_key + .get(id.as_str()) + .unwrap_or_else(|| panic!("unknown rendered id {id}")) + .clone(), + // A single-use relation renders inline without an ID: + // identify it by its parameter list (the rendered + // PARAMETERS= are the property parameters' ids). + None => { + assert_eq!(content.tag_name().name(), "RELATION"); + let parameters: Vec<&str> = content + .attribute("PARAMETERS") + .expect("inline RELATION carries PARAMETERS") + .split(' ') + .collect(); + let parameter_keys: Vec<&str> = parameters + .iter() + .map(|rendered| { + id_to_key + .get(*rendered) + .map(String::as_str) + .unwrap_or_else(|| panic!("unknown rendered id {rendered}")) + }) + .collect(); + objects + .iter() + .find(|(_, value)| { + let Some(object) = value.as_object() else { + return false; + }; + object.get("sort").and_then(Value::as_str) == Some("relation") + && object + .get("parameters") + .and_then(Value::as_array) + .is_some_and(|object_parameters| { + object_parameters.len() == parameter_keys.len() + && object_parameters.iter().zip( + parameter_keys.iter(), + ).all(|(object_parameter, parameter_key)| { + object_parameter.as_str() + == Some(*parameter_key) + }) + }) + }) + .map(|(key, _)| key.clone()) + .expect("inline composite relation matches a graph relation") + } + }; + new!(RelationOperand::Reference { relation }) + } + } + } + + /// Parse a rendered KIND-COMPOSITION element back into the typed + /// relation-expression view. + #[requires(element.tag_name().name() == "KIND-COMPOSITION")] + #[ensures(true)] + fn composition_from_xml( + element: roxmltree::Node<'_, '_>, + host_slot: bool, + id_to_key: &HashMap, + dictionary: &Dictionary<'_>, + objects: &Map, + host_relation: &str, + ) -> RelationOperand { + let grouping = match element.attribute("GROUPING") { + None => None, + Some("EXPLICIT") => Some(super::CompositionGrouping::Explicit), + Some(other) => panic!("unknown GROUPING basis {other}"), + }; + let kind = element + .children() + .find(|child| child.is_element() && child.tag_name().name() == "KIND") + .expect("KIND-COMPOSITION has a KIND child"); + let modifier = element + .children() + .find(|child| child.is_element() && child.tag_name().name() == "MODIFIER") + .expect("KIND-COMPOSITION has a MODIFIER child"); + new!(RelationOperand::Composition { + grouping, + kind: Box::new(operand_from_xml(kind, host_slot, id_to_key, dictionary, objects, host_relation)), + modifier: Box::new(operand_from_xml(modifier, false, id_to_key, dictionary, objects, host_relation)), + }) + } + + /// Locate the PREDICATION element a projected instance rendered as: by its + /// rendered ID when defined, otherwise by exact MODE/ARG surface match + /// against the surviving head predication. + #[requires(true)] + #[ensures(true)] + fn find_projected_predication<'a>( + document: &'a roxmltree::Document<'a>, + instance: &ProjectedInstance, + objects: &Map, + id_to_key: &HashMap, + ) -> roxmltree::Node<'a, 'a> { + let head_object = objects[&instance.head_predication] + .as_object() + .expect("head predication object"); + let expected_id = make_id(&instance.head_predication, head_object); + let mut candidates: Vec> = document + .descendants() + .filter(|node| { + node.is_element() + && node.tag_name().name() == "PREDICATION" + && node + .children() + .find(roxmltree::Node::is_element) + .is_some_and(|first| first.tag_name().name() == "KIND-COMPOSITION") + }) + .collect(); + if let Some(exact) = candidates + .iter() + .find(|node| node.attribute("ID") == Some(expected_id.as_str())) + { + return *exact; + } + let head_mode = head_object + .get("mode") + .and_then(Value::as_str) + .expect("head predication mode") + .to_uppercase(); + let head_arguments: BTreeMap = head_object["arguments"] + .as_object() + .expect("head arguments") + .iter() + .map(|(place, argument)| { + let place: usize = place + .strip_prefix('x') + .and_then(|digits| digits.parse().ok()) + .expect("numeric argument place"); + let argument = argument.as_object().expect("argument object"); + let rendered = match argument.get("kind").and_then(Value::as_str) { + Some("filled") => id_to_key + .iter() + .find(|(_, key)| { + **key == argument["value"].as_str().expect("argument value") + }) + .map(|(rendered, _)| rendered.clone()) + .expect("argument target renders"), + Some("elided") => "SOME".to_owned(), + other => panic!("unexpected head argument kind {other:?}"), + }; + (place, rendered) + }) + .collect(); + candidates.retain(|node| { + if node.attribute("MODE") != Some(head_mode.as_str()) { + return false; + } + let rendered_arguments: BTreeMap = node + .children() + .filter(|child| child.is_element() && child.tag_name().name() == "ARG") + .filter_map(|argument| { + let place: usize = argument + .attribute("INDEX") + .expect("ARG INDEX") + .parse() + .expect("ARG INDEX numeric"); + // Inline arguments (a single-use referent rendered in + // place) carry no REF=; they cannot disambiguate, so only + // reference-form arguments constrain the match. + let reference = argument.attribute("REF")?.to_owned(); + Some((place, reference)) + }) + .collect(); + rendered_arguments + .iter() + .all(|(place, reference)| head_arguments.get(place) == Some(reference)) + }); + match candidates.as_slice() { + [exact] => *exact, + [] => panic!( + "no PREDICATION element matches projected head {}", + instance.head_predication + ), + _ => panic!( + "ambiguous PREDICATION elements for projected head {}", + instance.head_predication + ), + } + } + + /// Provenance fields dropped before equivalence comparison: source records, + /// introducer markers, the synthesized relation label, connector surface + /// word and locus, and the relation-expression view itself. + const PROVENANCE_FIELDS: &[&str] = &[ + "source", + "introducedBy", + "relationLabel", + "relationExpression", + "locus", + ]; + + /// Canonical structural form of one objects map for equivalence comparison: + /// provenance fields dropped, then every id renamed by BFS encounter order + /// from `root` (unreached stragglers in sorted-id order), so opaque + /// generated ids align by reference topology alone. + #[requires(!root.is_empty())] + #[ensures(true)] + pub(crate) fn normalize_objects(objects: &Map, root: &str) -> BTreeMap { + let mut canonical: HashMap = HashMap::new(); + let mut next = 0usize; + let mut queue: VecDeque = VecDeque::from([root.to_owned()]); + let rename = |id: &str, + canonical: &mut HashMap, + next: &mut usize, + queue: &mut VecDeque| { + if !canonical.contains_key(id) { + *next += 1; + canonical.insert(id.to_owned(), format!("n{next}")); + queue.push_back(id.to_owned()); + } + }; + rename(root, &mut canonical, &mut next, &mut queue); + while let Some(id) = queue.pop_front() { + let Some(object) = objects.get(&id).and_then(Value::as_object) else { + continue; + }; + for value in object.values() { + collect_ids(value, objects, &mut |id| rename(id, &mut canonical, &mut next, &mut queue)); + } + } + // Unreached stragglers (the graph should not have any, but never hide + // one): continue the walk in sorted-id order. + let stragglers: BTreeSet<&String> = objects + .keys() + .filter(|key| !canonical.contains_key(*key)) + .collect(); + for straggler in stragglers { + rename(straggler, &mut canonical, &mut next, &mut queue); + while let Some(id) = queue.pop_front() { + let Some(object) = objects.get(&id).and_then(Value::as_object) else { + continue; + }; + for value in object.values() { + collect_ids(value, objects, &mut |id| { + rename(id, &mut canonical, &mut next, &mut queue) + }); + } + } + } + objects + .iter() + .map(|(key, value)| { + ( + canonical[key].clone(), + canonical_json(value, objects, &canonical), + ) + }) + .collect() + } + + /// Invoke `visit` on every string value that names an object in the map. + #[requires(true)] + #[ensures(true)] + fn collect_ids( + value: &Value, + objects: &Map, + visit: &mut impl FnMut(&str), + ) { + match value { + Value::String(text) => { + if objects.contains_key(text.as_str()) { + visit(text); + } + } + Value::Array(items) => { + for item in items { + collect_ids(item, objects, visit); + } + } + Value::Object(map) => { + for (field, item) in map { + if PROVENANCE_FIELDS.contains(&field.as_str()) { + continue; + } + collect_ids(item, objects, visit); + } + } + _ => {} + } + } + + /// Serialize one value with provenance fields dropped and ids renamed. + #[requires(true)] + #[ensures(true)] + fn canonical_json( + value: &Value, + objects: &Map, + canonical: &HashMap, + ) -> String { + match value { + Value::String(text) => format!( + "{:?}", + canonical.get(text.as_str()).map(String::as_str).unwrap_or(text) + ), + Value::Array(items) => format!( + "[{}]", + items + .iter() + .map(|item| canonical_json(item, objects, canonical)) + .collect::>() + .join(",") + ), + Value::Object(map) => { + let mut fields: Vec = map + .iter() + .filter(|(field, _)| !PROVENANCE_FIELDS.contains(&field.as_str())) + .map(|(field, item)| { + format!("{field:?}:{}", canonical_json(item, objects, canonical)) + }) + .collect(); + fields.sort(); + format!("{{{}}}", fields.join(",")) + } + other => format!("{other:?}"), + } + } + + /// The acceptance driver mandated by the round-14 decision: parse the + /// *rendered* SFN-XML relation expressions back into compositions, + /// re-expand them, and require the normalized forms of the pre-projection + /// graph and the regenerated graph to be identical. `objects` is the + /// original (unprojected) graph; `xml` is the product renderer's actual + /// output for it. + #[requires(!root.is_empty())] + #[ensures(true)] + pub(crate) fn assert_rendered_reexpansion_equivalent( + objects: &Map, + root: &str, + xml: &str, + dictionary: &Dictionary<'_>, + ) { + let (transformed, projection) = project_tanru_compositions(objects); + let id_to_key = rendered_id_to_key_map(objects); + let document = roxmltree::Document::parse(xml).expect("rendered XML parses"); + let mut expanded = transformed.clone(); + let mut next = 0usize; + for instance in &projection.instances { + let predication_element = + find_projected_predication(&document, instance, objects, &id_to_key); + let host_relation = objects[&instance.head_predication] + .get("relation") + .and_then(Value::as_str) + .expect("surviving head predication has its lexical relation"); + let view = composition_from_xml( + predication_element + .children() + .find(|child| child.is_element() && child.tag_name().name() == "KIND-COMPOSITION") + .expect("projected predication renders KIND-COMPOSITION"), + true, + &id_to_key, + dictionary, + objects, + host_relation, + ); + expanded = reexpand_instance(&expanded, instance, &view, &mut next); + } + let original_normalized = normalize_objects(objects, root); + let expanded_normalized = normalize_objects(&expanded, root); + if original_normalized != expanded_normalized { + for (key, value) in &original_normalized { + if expanded_normalized.get(key) != Some(value) { + eprintln!("ORIGINAL {key}: {value}"); + eprintln!("EXPANDED {key}: {:?}", expanded_normalized.get(key)); + } + } + for (key, value) in &expanded_normalized { + if !original_normalized.contains_key(key) { + eprintln!("EXPANDED-ONLY {key}: {value}"); + } + } + panic!( + "re-expanding the rendered relation expression must reproduce the recognized subgraph modulo opaque ids and provenance" + ); + } + } +} + +#[cfg(test)] +mod tests { + #[allow(unused_imports)] + use bityzba::{data, ensures, invariant, new, requires}; + + use serde_json::{Map, Value}; + + use super::reexpansion::{ + assert_rendered_reexpansion_equivalent, normalize_objects, reexpand_instances, + }; + use super::{RelationOperandData, project_tanru_compositions}; + use crate::SemanticGraph; + use crate::notation::render_xml_value_for_tooling; + + #[requires(!text.is_empty())] + #[ensures(true)] + fn graph_for_text(text: &str) -> SemanticGraph { + let words = jbotci_morphology::segment_words_with_modifiers(text).expect("morphology"); + let parsed = jbotci_syntax::parse_syntax_tree_generated_model_with_source_and_options( + &words, + text, + &jbotci_syntax::ParseOptions::default(), + ) + .expect("syntax"); + crate::build_generated_semantic_graph_with_dictionary_and_options( + &parsed, + crate::SemanticBuildOptions { + source_text: Some(text), + story_time: false, + }, + jbotci_dictionary_data::english(), + ) + .expect("semantics") + } + + #[requires(!text.is_empty())] + #[ensures(true)] + fn graph_value(text: &str) -> Value { + serde_json::to_value(graph_for_text(text)).expect("graph serializes") + } + + #[requires(true)] + #[ensures(true)] + fn objects_of(graph: &Value) -> Map { + graph["objects"].as_object().expect("objects map").clone() + } + + /// Render the graph exactly as the product does, then run the + /// rendered-surface re-expansion equivalence acceptance check. + #[requires(!text.is_empty())] + #[ensures(true)] + fn assert_text_reexpands(text: &str) { + let graph = graph_for_text(text); + let root = graph.root.to_string(); + let value = serde_json::to_value(&graph).expect("graph serializes"); + let objects = objects_of(&value); + let xml = crate::render_xml(&graph, "").into_data().output; + assert_rendered_reexpansion_equivalent(&objects, &root, &xml, jbotci_dictionary_data::english()); + } + + /// The round-14 witness set plus the tricky shapes: asserted main-selbri + /// tanru, co with following terms (fixed modifier args), se conversion + /// (non-first participant place), be-linked and NU-abstracted modifiers + /// (reference fallback), and a connected tertau (loud fallback). + #[test] + #[requires(true)] + #[ensures(true)] + fn reexpansion_equivalence_holds_for_tanru_witnesses() { + for text in [ + "lo blanu zdani cu barda", + "lo mutce blanu zdani cu barda", + "lo mutce blanu bo zdani cu barda", + "lo sutra je xekri mlatu cu barda", + "lo zdani co blanu cu barda", + "ti blanu zdani", + "ti zdani co blanu mi", + "lo se xekri mlatu cu barda", + "lo xamgu be lo gerku zdani cu barda", + "lo xamgu be lo gerku be'o zdani cu barda", + "lo nu bajra kei zdani cu barda", + "mi nelci lo melbi cmalu nixli je ckule", + ] { + assert_text_reexpands(text); + } + } + + /// Every frozen-corpus graph must satisfy the same rendered-surface + /// equivalence (the corpus migration activates the tanru instances there). + #[test] + #[requires(true)] + #[ensures(true)] + fn reexpansion_equivalence_holds_for_the_frozen_corpus() { + let corpus = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("tests/xml_corpus"); + let mut documents: Vec<_> = std::fs::read_dir(&corpus) + .expect("corpus directory") + .filter_map(|entry| { + let path = entry.expect("corpus entry").path(); + path.file_name() + .map(|name| name.to_string_lossy().into_owned()) + .filter(|name| name.ends_with(".frozen.json")) + .map(|_| path) + }) + .collect(); + documents.sort(); + assert!(documents.len() >= 48, "the frozen corpus must stay complete"); + for path in documents { + let mut graph: Value = serde_json::from_str( + &std::fs::read_to_string(&path).expect("corpus document reads"), + ) + .expect("corpus document parses"); + let binder_universes: Value = serde_json::from_slice(include_bytes!( + "../../tests/xml_corpus/BINDER_UNIVERSES.json" + )) + .expect("binder universes parse"); + let document_name = path + .file_name() + .expect("document name") + .to_string_lossy() + .replace(".frozen.json", ""); + graph["scopeDependenceBinderUniverses"] = binder_universes[document_name.as_str()].clone(); + let root = graph["root"].as_str().expect("graph root").to_owned(); + let objects = objects_of(&graph); + let xml = render_xml_value_for_tooling(graph, &document_name).into_data().output; + assert_rendered_reexpansion_equivalent(&objects, &root, &xml, jbotci_dictionary_data::english()); + } + } + + /// Build a witness graph and mutate its objects JSON before projection. + #[requires(!text.is_empty())] + #[ensures(true)] + fn mutated_witness( + text: &str, + mutate: impl FnOnce(&mut Map), + ) -> (Value, Map) { + let graph = graph_value(text); + let mut objects = objects_of(&graph); + mutate(&mut objects); + (graph, objects) + } + + #[requires(true)] + #[ensures(true)] + fn find_predication_with_relation(objects: &Map, relation: &str) -> String { + objects + .iter() + .find(|(_, object)| { + object.get("type").and_then(Value::as_str) == Some("predication") + && object.get("relation").and_then(Value::as_str) == Some(relation) + }) + .map(|(key, _)| key.clone()) + .unwrap_or_else(|| panic!("no predication with relation {relation}")) + } + + #[requires(true)] + #[ensures(true)] + fn find_tanru_link_predication(objects: &Map) -> String { + objects + .iter() + .find(|(_, object)| object.get("tanruLink").is_some()) + .map(|(key, _)| key.clone()) + .expect("a tanru-link predication") + } + + /// Negative fixture: unequal head/link modes must NOT compact (the + /// recognizer derives the link mode from the head, so a graph with unequal + /// modes could not be reconstructed losslessly). + #[test] + #[requires(true)] + #[ensures(true)] + fn unequal_head_and_link_modes_stay_loud() { + let (_graph, objects) = mutated_witness("lo blanu zdani cu barda", |objects| { + let link = find_tanru_link_predication(objects); + objects + .get_mut(&link) + .and_then(Value::as_object_mut) + .expect("link object") + .insert("mode".to_owned(), Value::from("asserted")); + }); + let (transformed, projection) = project_tanru_compositions(&objects); + assert!( + projection.instances.is_empty(), + "unequal head/link modes must reject the compact form" + ); + assert_eq!(transformed.len(), objects.len(), "nothing was consumed"); + // Sanity: the original graph itself re-expands trivially (no instances). + assert_eq!(normalize_objects(&objects, "utterance:5"), normalize_objects(&reexpand_instances(&transformed, &projection.instances), "utterance:5")); + } + + /// Negative fixture: a corrupted rendered host predicate (a swap of the + /// surviving head's own PREDICATE= in the emitted XML) must FAIL the + /// rendered-surface acceptance check — the host leaf's rendered value is + /// validated against the surviving head predication, not discarded. + #[test] + #[requires(true)] + #[ensures(true)] + fn corrupted_rendered_host_predicate_fails() { + let graph = graph_for_text("lo blanu zdani cu barda"); + let root = graph.root.to_string(); + let value = serde_json::to_value(&graph).expect("graph serializes"); + let objects = objects_of(&value); + let xml = crate::render_xml(&graph, "").into_data().output; + assert!( + xml.contains(""), + "witness must render the host predicate" + ); + let corrupted = xml.replacen( + "", + "", + 1, + ); + let result = std::panic::catch_unwind(|| { + assert_rendered_reexpansion_equivalent( + &objects, + &root, + &corrupted, + jbotci_dictionary_data::english(), + ); + }); + assert!( + result.is_err(), + "a swapped host predicate in the rendered XML must fail the acceptance check" + ); + } + + /// Negative fixture: a modifier eventuality shared with an outside + /// predication is not the derivable fresh-local event — the modifier must + /// fall back to the composite reference form, never the compact leaf. + #[test] + #[requires(true)] + #[ensures(true)] + fn shared_modifier_event_forces_composite_fallback() { + let (_graph, objects) = mutated_witness("lo blanu zdani cu barda", |objects| { + let blanu = find_predication_with_relation(objects, "blanu"); + let barda = find_predication_with_relation(objects, "barda"); + let event = objects[&blanu]["eventuality"].clone(); + objects + .get_mut(&barda) + .and_then(Value::as_object_mut) + .expect("barda object") + .insert("eventuality".to_owned(), event); + }); + assert_modifier_falls_back_to_reference(objects); + } + + /// Negative fixture: a decorated (tense-marked) modifier eventuality is + /// not the derivable fresh-local event. + #[test] + #[requires(true)] + #[ensures(true)] + fn decorated_modifier_event_forces_composite_fallback() { + let (_graph, objects) = mutated_witness("lo blanu zdani cu barda", |objects| { + let blanu = find_predication_with_relation(objects, "blanu"); + let event = objects[&blanu]["eventuality"] + .as_str() + .expect("modifier event") + .to_owned(); + objects + .get_mut(&event) + .and_then(Value::as_object_mut) + .expect("event object") + .insert("time".to_owned(), serde_json::json!({"kind": "offset", "direction": "past"})); + }); + assert_modifier_falls_back_to_reference(objects); + } + + /// Negative fixture: a place question on the modifier predication makes + /// its place map non-flat. + #[test] + #[requires(true)] + #[ensures(true)] + fn non_flat_place_map_forces_composite_fallback() { + let (_graph, objects) = mutated_witness("lo blanu zdani cu barda", |objects| { + let blanu = find_predication_with_relation(objects, "blanu"); + objects + .get_mut(&blanu) + .and_then(Value::as_object_mut) + .expect("blanu object") + .insert("placeQuestions".to_owned(), serde_json::json!([])); + }); + assert_modifier_falls_back_to_reference(objects); + } + + #[requires(true)] + #[ensures(true)] + fn assert_modifier_falls_back_to_reference(objects: Map) { + let (_transformed, projection) = project_tanru_compositions(&objects); + assert_eq!( + projection.instances.len(), + 1, + "the tanru itself is still recognized" + ); + let instance = &projection.instances[0]; + let data!(RelationOperand::Composition { modifier, .. }) = instance.composition.as_data() + else { + panic!("the projected view root is a composition"); + }; + assert!( + matches!(modifier.as_data(), data!(RelationOperand::Reference { .. })), + "a shared/decorated/non-flat modifier must stay in the composite reference form: {:?}", + modifier.as_data() + ); + } +} diff --git a/crates/jbotci-semantics/src/notation/render.rs b/crates/jbotci-semantics/src/notation/render.rs index 7743c76513..78523165c9 100644 --- a/crates/jbotci-semantics/src/notation/render.rs +++ b/crates/jbotci-semantics/src/notation/render.rs @@ -466,27 +466,9 @@ pub fn render_smusni(graph: &SemanticGraph, config: SmusniConfig) -> String { w.collection("NOT COMPUTED", |w| { w.entry("denotation-multiplicity"); }); - // #709: relationMetadata objects carry no declaration; the document - // header waives them explicitly, with the reason naming where the - // decomposition lives. The block exists exactly when the graph has - // relationMetadata objects, so graphs without any stay byte-identical. - let relation_metadata: Vec<&str> = order - .iter() - .map(String::as_str) - .filter(|key| { - objects[*key].get("type").and_then(Value::as_str) == Some("relationMetadata") - }) - .collect(); - if !relation_metadata.is_empty() { - w.collection("WAIVED", |w| { - for key in &relation_metadata { - w.entry(&format!( - "relationMetadata {}: decomposition rendered in the definitions-preamble word cards", - ctx.id(key) - )); - } - }); - } + // #709 + #719: relationMetadata objects carry no declaration (their + // decomposition renders in the definitions-preamble word cards); the + // former WAIVED bookkeeping block is out of model-facing output. w.collection("DECLARATIONS", |w| { for key in &order { render_one(w, &ctx, key, &objects[key]); @@ -1173,20 +1155,25 @@ fn render_utterance(w: &mut Writer, ctx: &Ctx, key: &str, obj: &Value) { fn render_predication(w: &mut Writer, ctx: &Ctx, key: &str, obj: &Value) { let vid = ctx.id(key).to_string(); w.declaration("PREDICATION", &vid, None, true, |w| { - // A predication's relation (`PredicationRelation`) is either a lexical - // relation word (`relation`) or — for a relation-question or - // relation-variable predication (`mo`, `bu'a`) — a bound relation - // parameter (`relationParameter`, a pointer to a `parameter` object - // whose own PARAMETER declaration carries ROLE: relation question / - // relation variable). Exactly one field is present. A relation + // A predication's relation (`PredicationRelation`) is a lexical + // relation word (`relation`), a bound relation parameter + // (`relationParameter` — for a relation-question or relation-variable + // predication (`mo`, `bu'a`), a pointer to a `parameter` object whose + // own PARAMETER declaration carries ROLE: relation question / relation + // variable), or — for a tanru composition — absent entirely. A relation // parameter is referenced by the same `VALUE ` marker every other // parameter reference uses (§6.3 operand fillers, argument questions), // so the relation slot reads as a bound value and the question/variable // semantics live on its PARAMETER declaration — mirroring how a `ma` - // argument-question already surfaces as `VALUE ` in ARGS. Neither - // field present is a genuine `lojban-semantics-json-1` contract - // violation and still fails loudly via `req_val`. - if let Some(relation) = field_str(obj, "relation") { + // argument-question already surfaces as `VALUE ` in ARGS. + // A tanru-composition predication (`PredicationRelation::Composition`) + // carries neither `relation` nor `relationParameter`; its structural + // link renders under TANRU LINK below. No relation and no tanru link is + // a genuine `lojban-semantics-json-1` contract violation and still + // fails loudly via `req_val`. + if obj.get("tanruLink").is_some_and(|link| !link.is_null()) { + // RELATION line intentionally omitted for composition predications. + } else if let Some(relation) = field_str(obj, "relation") { w.field("RELATION", &lexical(relation)); } else { let parameter = ctx.id_of(req_val(obj, "relationParameter")); @@ -1294,24 +1281,36 @@ fn render_place_questions(w: &mut Writer, ctx: &Ctx, questions: &[Value]) { }); } -/// A formula's own `connector` (`full = false`): CONNECTIVE SOURCE plus, when -/// present, TRUTH TABLE. `connector.parameter`, never observed non-null, is +/// A formula's own `connector` (jbotci#719): the surface word and the +/// grammatical locus are provenance-class and render only under the provenance +/// opt-in. Truth-conditional content stays in default output: TRUTH TABLE +/// renders exactly when the graph records one the parent operator does not +/// already determine. `connector.parameter`, never observed non-null, is /// flagged rather than dropped. #[requires(true)] #[ensures(true)] -fn render_connector(w: &mut Writer, connector: Option<&Value>, full: bool) { +fn render_connector(w: &mut Writer, ctx: &Ctx, connector: Option<&Value>, operator: &str) { let Some(connector) = connector.filter(|c| !c.is_null()) else { return; }; - w.field("CONNECTIVE SOURCE", &lexical(req_str(connector, "source"))); - if full { - let locus = match req_str(connector, "locus") { - "modal" => "tag", - locus => locus, - }; - w.field("LOCUS", &enum_render(locus)); + if ctx.provenance { + // `source` is a tagged `ConnectorSource` object: a surface word renders + // as itself; an implicit (tanru juxtaposition) connective names its kind. + let source = req_val(connector, "source"); + match source.get("kind").and_then(Value::as_str) { + Some("surfaceWord") => { + w.field("CONNECTIVE SOURCE", &lexical(req_str(source, "word"))) + } + Some("implicitJuxtaposition") => { + w.field("CONNECTIVE SOURCE", &enum_render("implicitJuxtaposition")) + } + other => panic!("unknown connector source kind: {other:?}"), + } + w.field("LOCUS", &enum_render(req_str(connector, "locus"))); } - if let Some(truth_table) = field_str(connector, "truthTable") { + if let Some(truth_table) = field_str(connector, "truthTable") + && canonical_truth_table(operator) != Some(truth_table) + { w.field("TRUTH TABLE", &enum_render(truth_table)); } if connector.get("parameter").is_some_and(|p| !p.is_null()) { @@ -1319,6 +1318,22 @@ fn render_connector(w: &mut Writer, connector: Option<&Value>, full: bool) { } } +/// The truth table a binary logical operator already determines (row order TT, +/// TF, FT, FF), mirroring the XML renderer's `canonical_truth_table`; `None` +/// for operators with no truth-functional reading, whose recorded tables +/// always render. +#[requires(true)] +#[ensures(ret.is_none_or(|table| table.len() == 4))] +fn canonical_truth_table(operator: &str) -> Option<&'static str> { + match operator { + "and" => Some("TFFF"), + "or" => Some("TTTF"), + "iff" => Some("TFFT"), + "whetherOrNot" => Some("TTFF"), + _ => None, + } +} + #[requires(true)] #[ensures(true)] fn render_formula(w: &mut Writer, ctx: &Ctx, key: &str, obj: &Value) { @@ -1341,7 +1356,7 @@ fn render_formula(w: &mut Writer, ctx: &Ctx, key: &str, obj: &Value) { w.entry(&ctx.id_of(c)); } }); - render_connector(w, obj.get("connector"), false); + render_connector(w, ctx, obj.get("connector"), &op); rendered_body = true; } if let Some(variable) = obj.get("variable") { @@ -1634,9 +1649,12 @@ fn render_sequence(w: &mut Writer, ctx: &Ctx, key: &str, obj: &Value) { } else { w.field("OPERATOR", &enum_render(operator)); } - w.heading("CONNECTOR", |w| { - render_connector(w, nc.get("connector"), true); - }); + // #719: no CONNECTOR heading — connector content renders + // inline: TRUTH TABLE exactly when the operator does not + // already determine it (always, for a nonlogical operator), + // the parameter marker when present, and the surface word and + // locus only under the provenance opt-in. + render_connector(w, ctx, nc.get("connector"), operator); }); } render_source(w, ctx, obj); @@ -1934,25 +1952,41 @@ mod tests { } let connector = json!({ - "source": "ki'u", - "locus": "modal" + "source": { "kind": "surfaceWord", "word": "ki'u" }, + "locus": "tag" }); + let objects = BTreeMap::new(); + let id_map = BTreeMap::new(); + // #719: source and locus render only under the provenance opt-in. + let ordinary_ctx = Ctx { + objects: &objects, + id_map: &id_map, + provenance: false, + }; + let mut writer = Writer::new(false, false); + render_connector(&mut writer, &ordinary_ctx, Some(&connector), "and"); + assert_eq!(writer.finish(), "\n"); + let provenance_ctx = Ctx { + objects: &objects, + id_map: &id_map, + provenance: true, + }; let mut writer = Writer::new(false, false); - render_connector(&mut writer, Some(&connector), true); + render_connector(&mut writer, &provenance_ctx, Some(&connector), "and"); let rendered = writer.finish(); + assert!(rendered.contains("CONNECTIVE SOURCE: ki'u;")); assert!(rendered.contains("LOCUS: TAG;")); assert_no_standalone_modal_word(&rendered); } - /// #709: a graph with relationMetadata objects renders no UNKNOWN - /// declaration for them; the document header carries an explicit WAIVED - /// block whose reason names where the decomposition lives. A graph - /// without relationMetadata renders no WAIVED block at all (the frozen - /// corpus parity tests pin byte-identity for that shape). + /// #709 + #719: a graph with relationMetadata objects renders no UNKNOWN + /// declaration for them (their decomposition lives in the + /// definitions-preamble word cards); the former WAIVED bookkeeping block is + /// gone from model-facing output. #[test] #[requires(true)] #[ensures(true)] - fn relation_metadata_is_waived_with_reason_not_unknown() { + fn relation_metadata_renders_no_declaration_and_no_waived_block() { use jbotci_morphology::segment_words_with_modifiers; use jbotci_syntax::{ ParseOptions, parse_syntax_tree_generated_model_with_source_and_options, @@ -1991,23 +2025,12 @@ mod tests { "the generic UNKNOWN fallback must never fire for relationMetadata:\n{nonce}" ); assert!( - nonce.contains("WAIVED {"), - "missing the header WAIVED block:\n{nonce}" - ); - assert!( - nonce.contains( - "relationMetadata relationMetadata_8: decomposition rendered in the definitions-preamble word cards;" - ), - "missing the waive-with-reason entry:\n{nonce}" - ); - - let plain = render_smusni( - &graph_for_text("lo mlatu cu barda"), - SmusniConfig { provenance: false }, + !nonce.contains("WAIVED"), + "the WAIVED bookkeeping block is out of model-facing output:\n{nonce}" ); assert!( - !plain.contains("WAIVED"), - "a graph without relationMetadata must not render a WAIVED block:\n{plain}" + !nonce.contains("relationMetadata relationMetadata_"), + "relationMetadata objects carry no declaration:\n{nonce}" ); } } diff --git a/crates/jbotci-semantics/src/notation/xml.rs b/crates/jbotci-semantics/src/notation/xml.rs index bab0cbc33b..ea943e301a 100644 --- a/crates/jbotci-semantics/src/notation/xml.rs +++ b/crates/jbotci-semantics/src/notation/xml.rs @@ -22,120 +22,45 @@ use crate::notation::xml_words::words_section; const SCOPE_DEPENDENCE_TEACHING: &str = "Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe."; -const KEY_RULES_BEFORE_SORTS: &[(&str, &str)] = &[ - ( - "ids", - "ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠).", - ), - ( - "lexical-categories", - "UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names.", - ), +const KEY_RULES_BEFORE_SORTS: &[&str] = &[ + "ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠).", + "UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names.", ]; -const KEY_RULES_AFTER_SORTS: &[(&str, &str)] = &[ - ( - "embedded-questions", - "EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY.", - ), - ( - "kind-composition", - "KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode.", - ), - ( - "warnings", - "Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message.", - ), - ( - "some", - "REF=\"SOME\" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠).", - ), - ( - "ground", - "DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical.", - ), - ( - "quantifiers", - "EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/.", - ), - ("scope-dependence", SCOPE_DEPENDENCE_TEACHING), - ( - "scope-dependence-subsets", - "POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend.", - ), - ( - "number-neutrality", - "References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions.", - ), - ( - "personal-reference", - "PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied.", - ), - ( - "speaker-anchor", - "A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker.", - ), - ( - "facet-silence", - "Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS.", - ), - ( - "event-field", - "EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG.", - ), - ( - "adjuncts", - "ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL=\"true\" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component.", - ), - ( - "pro-sumti", - "UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only.", - ), - ( - "mode", - "MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION.", - ), - ( - "defs", - "Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references.", - ), - ( - "atomic-lists", - "A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued.", - ), - ( - "order", - "Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close.", - ), +const KEY_RULES_AFTER_SORTS: &[&str] = &[ + "EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY.", + "KIND-COMPOSITION in the relation slot of a PREDICATION is the predication's composed predicate, replacing PREDICATE= exactly when the predicate is composite (the same compact/composite dichotomy as ADJUNCT, one level up): MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure and eventuality. Predicating the composition entails the KIND predication of the enclosing PREDICATION's EVENT and ARGs together with an underspecified modification connection between KIND's exposed place-1 participant and the relation denoted by MODIFIER; it does not by itself entail that the participant satisfies MODIFIER. Silence is the underspecification, not intersection: when a speaker makes the stronger claim, it appears as its own conjunct. CONNECTION= is reserved for a future resolved-connection marker and is never emitted; its absence means UNSPECIFIED.", + "PREDICATE= on KIND, MODIFIER, or a relation-expression RELATION leaf is the compact lexical form: PARTICIPANT-PLACE= marks the lexical place the composition participant fills and defaults to 1, each omitted unfilled lexical place elaborates to a distinct ordinary elided-place node, and the operand's own eventuality is fresh and locally existentially bound. BODY wraps a composite operand instead: a nested KIND-COMPOSITION, a CONNECTIVE conjoining co-modifiers of the same head participant, or a RELATION lambda or abstraction subtree.", + "GROUPING= on KIND-COMPOSITION states the basis of the displayed composition tree; silence means ASSUMED-LEFT, the deterministic grammar default. EXPLICIT appears only where the text itself encodes the grouping: at the tree root when every edge is explicit, per node when one tree mixes explicit and default edges. CONNECTION= and GROUPING= defaults are semantic defaults of this notation, not a generic rule for arbitrary absent attributes.", + "CONNECTIVE carries OPERATOR= and, only when the graph records a truth table that OPERATOR= does not already determine, TRUTH-TABLE=. A connective question's bound parameter appears as the PARAMETER= attribute of its connective formula. The surface connective word and its grammatical locus are derivational provenance and never appear in default output.", + "Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message.", + "REF=\"SOME\" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠).", + "DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical.", + "EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/.", + SCOPE_DEPENDENCE_TEACHING, + "POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend.", + "References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions.", + "PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied.", + "A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker.", + "Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS.", + "EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG.", + "ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL=\"true\" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component.", + "UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only.", + "MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION.", + "Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references.", + "A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued.", + "Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close.", ]; -/// KEY rules appended exactly when the document carries a WORDS word-card +/// KEY paragraphs appended exactly when the document carries a WORDS word-card /// section (#709): documents without cards stay byte-identical. -const KEY_RULES_WORD_CARDS: &[(&str, &str)] = &[ - ( - "word-cards", - "WORDS lists one WORD card per content word of the text; ID= is the card key. GLOSS, DEF, and NOTES are dictionary prose; inside DEF and NOTES, ARG INDEX=\"n\" marks the word's nth place — the same argument vocabulary as predications, so a place in a definition matches ARG INDEX on the word's predications. KNOWN=\"false\" marks a word with no dictionary definition; the default true is omitted.", - ), - ( - "compound-approximation", - "COMPOSITE-APPROX shows the mechanical composition of a dictionary-absent compound through the same KIND-COMPOSITION idiom as the body; it is suggestive, not definitional. COMPONENT WORD= references the component's own WORD card.", - ), - ( - "compound-places", - "PLACES=\"UNKNOWN\" means the composition tree determines no place structure. The actual meaning and places were chosen by the coiner. Places of COMPONENT cards are not inherited by the compound, and operators or grouping the coiner omitted leave no recoverable trace.", - ), - ( - "compound-assumptions", - "GROUPING= and SCOPE= describe the basis of the displayed tree, not the coiner's guaranteed intent: ASSUMED-LEFT = CLL default left grouping, ASSUMED-SHORT = CLL-12.12 narrow operator scope, EXPLICIT = the word itself encodes the boundary. The attributes are tree-level; they appear per-node only when one tree mixes explicit and assumed edges.", - ), - ( - "context-placeholders", - "VARIABLE-CONTEXT denotes the abstract role an utterance context would supply for a context-dependent word used inside a definition. These are roles, not referents; they define no ids.", - ), - ( - "word-card-ids", - "WORD ID values are surface-spelling card keys: the canonical spelling for one-token words; multiword (zei) compounds join their parts with hyphens (mi-zei-do). Hyphens never occur inside a single Lojban word, so the two namespaces cannot collide.", - ), +const KEY_RULES_WORD_CARDS: &[&str] = &[ + "WORDS lists one WORD card per content word of the text; ID= is the card key. GLOSS, DEF, and NOTES are dictionary prose; inside DEF and NOTES, ARG INDEX=\"n\" marks the word's nth place — the same argument vocabulary as predications, so a place in a definition matches ARG INDEX on the word's predications. KNOWN=\"false\" marks a word with no dictionary definition; the default true is omitted.", + "COMPOSITE-APPROX shows the mechanical composition of a dictionary-absent compound through the same KIND-COMPOSITION idiom as the body; it is suggestive, not definitional. COMPONENT WORD= references the component's own WORD card.", + "PLACES=\"UNKNOWN\" means the composition tree determines no place structure. The actual meaning and places were chosen by the coiner. Places of COMPONENT cards are not inherited by the compound, and operators or grouping the coiner omitted leave no recoverable trace.", + "On word cards, GROUPING= and SCOPE= describe the basis of the displayed tree, not the coiner's guaranteed intent: ASSUMED-LEFT = CLL default left grouping, ASSUMED-SHORT = CLL-12.12 narrow operator scope, EXPLICIT = the word itself encodes the boundary. The attributes are tree-level; they appear per-node only when one tree mixes explicit and assumed edges. Unlike the body scope, cards state ASSUMED-LEFT because a card tree is an approximation of an undefined word, not the deterministic grammar default.", + "VARIABLE-CONTEXT denotes the abstract role an utterance context would supply for a context-dependent word used inside a definition. These are roles, not referents; they define no ids.", + "WORD ID values are surface-spelling card keys: the canonical spelling for one-token words; multiword (zei) compounds join their parts with hyphens (mi-zei-do). Hyphens never occur inside a single Lojban word, so the two namespaces cannot collide.", ]; const FACET_FIELDS: &[&str] = &[ @@ -197,6 +122,7 @@ const DESCRIPTOR_KINDS: &[&str] = &[ #[invariant(::QuantityText => true)] #[invariant(::BoundVariableWord => true)] #[invariant(::CompositionRelationLabel => true)] +#[invariant(::ConnectorProvenance => true)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum XmlWaiverFamily { SourceRecord, @@ -206,6 +132,11 @@ pub enum XmlWaiverFamily { QuantityText, BoundVariableWord, CompositionRelationLabel, + /// Connector surface words and grammatical loci: provenance-class data that + /// no semantic consumer reads (jbotci#719). Truth-conditional connector + /// content (the operator, and a truth table the operator does not already + /// determine) stays in default output. + ConnectorProvenance, } /// One typed object or field occurrence in canonical semantic-graph JSON. @@ -265,6 +196,7 @@ pub const XML_DECLARED_WAIVERS: &[XmlWaiverFamily] = &[ XmlWaiverFamily::QuantityText, XmlWaiverFamily::BoundVariableWord, XmlWaiverFamily::CompositionRelationLabel, + XmlWaiverFamily::ConnectorProvenance, ]; #[requires(path.starts_with("/objects/"))] @@ -536,10 +468,19 @@ fn serialize_element_inline(node: &XmlElement, output: &mut String) { output.push('>'); } -#[requires(true)] +/// Serialize the document, optionally preceded by one `` prolog +/// comment. The comment carries the KEY teaching prose (jbotci#719: the former +/// structured `` block is a single comment now). The text +/// must be comment-safe: XML comments forbid `--` and a trailing `-`. +#[requires(comment.is_none_or(|comment| !comment.contains("--") && !comment.ends_with('-')))] #[ensures(ret.ends_with('\n'))] -pub(crate) fn serialize(root: &XmlElement) -> String { +pub(crate) fn serialize(root: &XmlElement, comment: Option<&str>) -> String { let mut output = String::new(); + if let Some(comment) = comment { + output.push_str("\n"); + } serialize_element(root, 0, &mut output); output.push('\n'); output @@ -636,6 +577,22 @@ fn enum_string(value: &str) -> String { enum_token(&Value::String(value.to_owned())) } +/// The truth table a binary logical formula operator already determines, in +/// the builder's row order (TT, TF, FT, FF), mirroring +/// `generated_truth_table_for_formula_operator`. `None` for operators with no +/// truth-functional reading: their recorded tables always render (jbotci#719). +#[requires(true)] +#[ensures(ret.is_none_or(|table| table.len() == 4))] +fn canonical_truth_table(operator: &str) -> Option<&'static str> { + match operator { + "and" => Some("TFFF"), + "or" => Some("TTTF"), + "iff" => Some("TFFT"), + "whetherOrNot" => Some("TTFF"), + _ => None, + } +} + #[requires(true)] #[ensures(!ret.is_empty())] fn predicate_symbol(value: &str) -> String { @@ -1035,6 +992,11 @@ struct GraphData { subtype_pairs: Vec<(String, String)>, value_paths: HashMap, surface_paths: BTreeSet, + /// The tanru-projection report (jbotci#719): which objects the recognition + /// boundary consumed and their original JSON, so omission accounting can + /// classify every removed surface (projected structure vs waived + /// provenance). Empty when the graph has no tanru patterns. + projection: crate::notation::relation_expression::TanruProjection, } impl GraphData { @@ -1056,6 +1018,14 @@ impl GraphData { }; assert!(objects.contains_key(&root), "missing root object: {root:?}"); + // jbotci#719: the recognition boundary. Proven tanru patterns become + // typed relation expressions on their head predications; the consumed + // head/link scaffolding is removed here so declaration planning, + // reference counting, and rendering all see the projected graph. The + // consumed objects' original JSON is kept for omission accounting. + let (objects, projection) = + crate::notation::relation_expression::project_tanru_compositions(&objects); + let object_keys: HashSet = objects.keys().cloned().collect(); let order: HashMap = objects .keys() @@ -1264,10 +1234,16 @@ impl GraphData { let scope_dependence_binder_universes: HashMap> = graph_object .remove("scopeDependenceBinderUniverses") .map(|value| { - serde_json::from_value(value) + serde_json::from_value::>>(value) .expect("scope-dependence binder universes must be string-set records") }) - .unwrap_or_default(); + .unwrap_or_default() + .into_iter() + // The universes are computed over the unprojected graph; tanru + // projection consumes exactly the objects it reports, so pruning to + // survivors keeps the exact-domain invariant below. + .filter(|(key, _)| objects.contains_key(key)) + .collect(); assert!( scope_dependence_binder_universes .keys() @@ -1288,6 +1264,36 @@ impl GraphData { &mut surface_paths, ); } + // Consumed tanru-scaffolding objects keep their surfaces in the + // inventory so omission accounting must classify each one explicitly + // (waived provenance or rendered-by-projection) instead of silently + // dropping them. Rewritten anchors keep only their vanished + // children/connector subtrees: the surviving fields dedupe against + // the rewritten formula's own surfaces. + let mut consumed_value_paths = HashMap::new(); + for (key, value) in &projection.consumed_objects { + index_value_paths( + value, + &format!("/objects/{}", json_pointer_escape(key)), + &mut consumed_value_paths, + &mut surface_paths, + ); + } + for (key, value) in &projection.rewritten_anchors { + let object = json_object(value); + for field in ["children", "connector"] { + if let Some(field_value) = object.get(field) { + let field_path = format!("/objects/{}/{}", json_pointer_escape(key), field); + surface_paths.insert(field_surface(field_path.clone())); + index_value_paths( + field_value, + &field_path, + &mut consumed_value_paths, + &mut surface_paths, + ); + } + } + } Self::from_data(data!(GraphData { root, objects, @@ -1307,6 +1313,7 @@ impl GraphData { subtype_pairs, value_paths, surface_paths, + projection, })) } @@ -2293,10 +2300,126 @@ impl RenderState { } #[requires(true)] - #[ensures(self.unaccounted_surfaces == graph.surface_paths)] + #[ensures(graph.projection.consumed_objects.keys().all(|key| !self.unaccounted_surfaces.contains(&object_surface(format!("/objects/{key}")))))] fn start_omission_accounting(&mut self, graph: &GraphData) { assert!(!self.planning, "accounting cannot begin during planning"); self.unaccounted_surfaces.clone_from(&graph.surface_paths); + self.account_projected_consumption(graph); + } + + /// Classify every surface the tanru projection consumed (jbotci#719): + /// provenance fields keep their waiver families (the omissions API is + /// unchanged — a consumed source record is still a source-record omission), + /// and everything else is rendered-by-projection, so it leaves the + /// unaccounted set with no omission at all. + #[requires(true)] + #[ensures(true)] + fn account_projected_consumption(&mut self, graph: &GraphData) { + if self.planning { + return; + } + for (key, value) in &graph.projection.consumed_objects { + let base = format!("/objects/{}", json_pointer_escape(key)); + self.waive_consumed_provenance(&base, json_object(value)); + assert!( + remove_surface_subtree(&mut self.unaccounted_surfaces, &object_surface(base.clone())), + "projected tanru object was already accounted: {base}" + ); + } + // Rewritten anchors survive as the head atom, so their own surfaces + // render normally; only the vanished `children`/`connector` subtrees + // need classification (connector source/locus is waived provenance, + // the children list is rendered-by-projection). + for (key, value) in &graph.projection.rewritten_anchors { + let base = format!("/objects/{}", json_pointer_escape(key)); + let object = json_object(value); + if let Some(connector) = object.get("connector").and_then(Value::as_object) { + for connector_field in ["source", "locus"] { + if connector.contains_key(connector_field) { + self.record_omission( + XmlWaiverFamily::ConnectorProvenance, + field_surface(format!("{base}/connector/{connector_field}")), + ); + } + } + } + for field in ["children", "connector"] { + if object.contains_key(field) { + let surface = field_surface(format!("{base}/{field}")); + assert!( + remove_surface_subtree(&mut self.unaccounted_surfaces, &surface), + "rewritten tanru anchor field was already accounted: {base}/{field}" + ); + } + } + } + } + + /// Record waiver-family omissions for the provenance fields of one consumed + /// object; the caller sweeps the remaining (projected) surfaces afterwards. + #[requires(true)] + #[ensures(true)] + fn waive_consumed_provenance(&mut self, base: &str, object: &Map) { + for (field_name, value) in object { + let field_path = format!("{base}/{}", json_pointer_escape(field_name)); + match field_name.as_str() { + "source" if is_source_record(value) => { + self.record_omission(XmlWaiverFamily::SourceRecord, field_surface(field_path)); + } + "introducedBy" => { + self.record_omission(XmlWaiverFamily::IntroducedBy, field_surface(field_path)); + } + "connector" => { + for connector_field in json_object(value).keys() { + if matches!(connector_field.as_str(), "source" | "locus") { + self.record_omission( + XmlWaiverFamily::ConnectorProvenance, + field_surface(format!( + "{field_path}/{}", + json_pointer_escape(connector_field) + )), + ); + } + } + } + "tanruLink" => { + if json_object(value).contains_key("relationLabel") { + self.record_omission( + XmlWaiverFamily::CompositionRelationLabel, + field_surface(format!("{field_path}/relationLabel")), + ); + } + } + "arguments" => { + for (place, argument) in json_object(value) { + if json_object(argument).contains_key("introducedBy") { + self.record_omission( + XmlWaiverFamily::IntroducedBy, + field_surface(format!( + "{field_path}/{}/introducedBy", + json_pointer_escape(place) + )), + ); + } + } + } + "descriptor" => { + // Mirror the renderer's descriptor rule: only the exact + // elided-zo'e word is a mechanical omission; any other + // descriptor word stays in the descriptor-word family. + let descriptor = json_object(value); + let mechanical = optional_string(descriptor, "kind") == Some("elided") + && optional_string(descriptor, "word") == Some("zo'e"); + if !mechanical && descriptor.contains_key("word") { + self.record_omission( + XmlWaiverFamily::DescriptorWord, + field_surface(format!("{field_path}/word")), + ); + } + } + _ => {} + } + } } #[requires(true)] @@ -3490,7 +3613,12 @@ impl RenderState { .and_then(Value::as_object) .unwrap_or_else(|| panic!("nonlogical connection lacks connector")); state.account_field(graph, connection, "connector"); - rendered.push(state.render_connector(graph, connector)); + let operator = string_field(connection, "operator"); + let (attributes, children) = state.account_connector(graph, connector, operator); + for (name, value) in attributes { + rendered.set(name, value); + } + rendered.extend(children); rendered.extend(state.extras(graph, connection, &["operator", "connector"])); semantic_entries.push(rendered); handled.push("nonlogicalConnection"); @@ -3736,74 +3864,6 @@ impl RenderState { } } -#[requires(true)] -#[ensures(true)] -fn counted(count: usize, noun: &str) -> String { - format!("{count} {noun}{}", if count == 1 { "" } else { "s" }) -} - -#[requires(true)] -#[ensures(ret.iter().all(|message| !message.is_empty()))] -fn waiver_messages(omissions: &[XmlOmission]) -> Vec { - let count = |kind| { - omissions - .iter() - .filter(|omission| omission.waiver == Some(kind)) - .count() - }; - let mut messages = Vec::new(); - let source = count(XmlWaiverFamily::SourceRecord); - if source > 0 { - messages.push(format!( - "*.source provenance ({}: spans, witness text, construct labels)", - counted(source, "record") - )); - } - let assigned = count(XmlWaiverFamily::AssignedNameRecord); - if assigned > 0 { - messages.push(format!( - "*.assignedNames provenance ({})", - counted(assigned, "record") - )); - } - let descriptor = count(XmlWaiverFamily::DescriptorWord); - if descriptor > 0 { - messages.push(format!( - "descriptor *.word provenance ({})", - counted(descriptor, "field") - )); - } - let introduced = count(XmlWaiverFamily::IntroducedBy); - if introduced > 0 { - messages.push(format!( - "*.introducedBy provenance ({})", - counted(introduced, "field") - )); - } - let quantity = count(XmlWaiverFamily::QuantityText); - if quantity > 0 { - messages.push(format!( - "quantity value text provenance ({})", - counted(quantity, "field") - )); - } - let bound = count(XmlWaiverFamily::BoundVariableWord); - if bound > 0 { - messages.push(format!( - "bound-variable surface word provenance ({})", - counted(bound, "field") - )); - } - let relation_labels = count(XmlWaiverFamily::CompositionRelationLabel); - if relation_labels > 0 { - messages.push(format!( - "kind-composition relation-label provenance ({})", - counted(relation_labels, "field") - )); - } - messages -} - #[requires(true)] #[ensures(ret.name == "INCOMPATIBILITY")] fn render_compact_incompatibility(reason: &CompactIncompatibility) -> XmlElement { @@ -3937,18 +3997,6 @@ impl RenderState { (graph_root, unreachable) } - #[requires(true)] - #[ensures(ret.name == "WAIVERS")] - fn waivers_element(&self) -> XmlElement { - let mut waivers = XmlElement::new("WAIVERS"); - for message in waiver_messages(&self.omissions) { - let mut waiver = XmlElement::new("WAIVER"); - waiver.text = Some(message); - waivers.push(waiver); - } - waivers - } - #[requires(true)] #[ensures(self.unaccounted_surfaces.is_empty())] fn finish_omission_accounting(&mut self) { @@ -4163,38 +4211,21 @@ impl RenderState { ("FORM", "TYPED-GRAPH"), ], ); - let mut key = XmlElement::new("KEY"); - for (topic, prose) in [ - ( - "form", - "FORM=TYPED-GRAPH is selected exactly when the semantic graph cannot be represented truthfully by the compact SFN prototype vocabulary. It is a typed XML projection of the semantic graph, not a reinterpretation.", - ), - ( - "objects", - "Each OBJECT is defined once by its canonical graph KEY= and XML ID=. ROOT-REF=/ROOT-KEY= identify the graph root. REFERENCE points to the exact shared object and never clones it.", - ), - ( - "fields", - "Every non-waived semantic object and field occurrence is represented as typed OBJECT, FIELD, RECORD, LIST, ITEM, REFERENCE, STRING, NUMBER, BOOLEAN, or NULL structure. Child order follows canonical semantic JSON order.", - ), - ( - "elided-zohe", - "A descriptor word is mechanically omitted only when descriptor KIND is elided and the value is exactly zo'e; every other descriptor word omission is reported by the existing descriptor-word waiver family.", - ), - ] { - let mut rule = XmlElement::with_attributes("RULE", [("TOPIC", topic)]); - rule.text = Some(prose.to_owned()); - key.push(rule); - } + let comment = [ + "SFN KEY (notation version 0): teaching text for this document. Defaults stated here are commitments, not omissions.", + "FORM=TYPED-GRAPH is selected exactly when the semantic graph cannot be represented truthfully by the compact SFN prototype vocabulary. It is a typed XML projection of the semantic graph, not a reinterpretation.", + "Each OBJECT is defined once by its canonical graph KEY= and XML ID=. ROOT-REF=/ROOT-KEY= identify the graph root. REFERENCE points to the exact shared object and never clones it.", + "Every non-waived semantic object and field occurrence is represented as typed OBJECT, FIELD, RECORD, LIST, ITEM, REFERENCE, STRING, NUMBER, BOOLEAN, or NULL structure. Child order follows canonical semantic JSON order.", + "A descriptor word is mechanically omitted only when descriptor KIND is elided and the value is exactly zo'e; every other descriptor word omission is reported by the existing descriptor-word waiver family.", + ] + .join("\n\n"); let mut reasons = XmlElement::new("COMPACT-INCOMPATIBILITIES"); for reason in incompatibilities { reasons.push(render_compact_incompatibility(reason)); } - key.push(reasons); - root.push(key); - root.push(self.waivers_element()); + root.push(reasons); root.push(typed_graph); - serialize(&root) + serialize(&root, Some(&comment)) } #[requires(true)] @@ -4223,12 +4254,6 @@ impl RenderState { let mut root = XmlElement::with_attributes("SFN", [("VERSION", "0"), ("DOC", document_name)]); - let mut key = XmlElement::new("KEY"); - for (topic, prose) in KEY_RULES_BEFORE_SORTS { - let mut rule = XmlElement::with_attributes("RULE", [("TOPIC", *topic)]); - rule.text = Some((*prose).to_owned()); - key.push(rule); - } let facts = if graph.subtype_pairs.is_empty() { "none".to_owned() } else { @@ -4239,34 +4264,28 @@ impl RenderState { .collect::>() .join("; ") }; - let mut sorts = XmlElement::with_attributes("RULE", [("TOPIC", "sorts")]); - sorts.text = Some(format!( + let sorts = format!( "SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: {facts}. LOCUTION implies sort Locution and therefore omits SORT=." - )); - key.push(sorts); - for (topic, prose) in KEY_RULES_AFTER_SORTS { - let mut rule = XmlElement::with_attributes("RULE", [("TOPIC", *topic)]); - rule.text = Some((*prose).to_owned()); - key.push(rule); - } + ); + let mut paragraphs: Vec<&str> = vec![ + "SFN KEY (notation version 0): teaching text for this document. Defaults stated here are commitments, not omissions.", + ]; + paragraphs.extend(KEY_RULES_BEFORE_SORTS); + paragraphs.push(&sorts); + paragraphs.extend(KEY_RULES_AFTER_SORTS); if word_cards.is_some() { - for (topic, prose) in KEY_RULES_WORD_CARDS { - let mut rule = XmlElement::with_attributes("RULE", [("TOPIC", *topic)]); - rule.text = Some((*prose).to_owned()); - key.push(rule); - } + paragraphs.extend(KEY_RULES_WORD_CARDS); } - root.push(key); + let comment = paragraphs.join("\n\n"); if let Some(cards) = word_cards { root.push(words_section(cards)); } - root.push(self.waivers_element()); Self::append_defs(&mut root, document_declarations); root.push(graph_root); if let Some(rendered) = unreachable { root.push(rendered); } - serialize(&root) + serialize(&root, Some(&comment)) } } @@ -4406,6 +4425,18 @@ pub fn render_xml(graph: &SemanticGraph, document_name: &str) -> XmlRender { render_xml_graph_with_state(graph, document_name, RenderState::new(), None) } +/// Tooling seam for corpus regeneration after an intentional output-shape +/// change (jbotci#719): render an already-serialized canonical graph `Value` +/// exactly as the in-crate corpus tests do (the corpus pins the canonical +/// JSON directly, so no `SemanticGraph` roundtrip exists for it). Not +/// product API. +#[doc(hidden)] +#[requires(!document_name.is_empty())] +#[ensures(ret.output.ends_with('\n'))] +pub fn render_xml_value_for_tooling(graph: Value, document_name: &str) -> XmlRender { + render_xml_value(graph, document_name) +} + /// Render a semantic graph as canonical SFN-XML with a structured `` /// word-card section (#709): the KEY gains the word-card rules and the WORDS /// section follows it (before WAIVERS), ahead of the body. With cards present, @@ -5308,6 +5339,20 @@ mod tests { surface: field_surface(field_path.clone()), })); } + if field == "connector" + && let Some(connector) = item.as_object() + { + for connector_field in ["source", "locus"] { + if connector.contains_key(connector_field) { + output.insert(new!(XmlOmission { + waiver: Some(XmlWaiverFamily::ConnectorProvenance), + surface: field_surface(format!( + "{field_path}/{connector_field}" + )), + })); + } + } + } if composition_link && field == "relationLabel" { output.insert(new!(XmlOmission { waiver: Some(XmlWaiverFamily::CompositionRelationLabel), @@ -5362,32 +5407,33 @@ mod tests { let with_cards = with_cards.output.as_str(); let without_cards = without_cards.output.as_str(); - // Placement: WORDS sits between KEY and WAIVERS. + // #719: the KEY is a single comment before the root element; WORDS is + // the first child of the root when cards are present. assert!( - with_cards.contains("\n \n"), - "WORDS must immediately follow KEY: {}", - &with_cards[..with_cards.find("\n \n \n"), + "WORDS must be the first child of the root" ); - // The word-card KEY rules exist exactly when the section does. - for topic in [ - "word-cards", - "compound-approximation", - "compound-places", - "compound-assumptions", - "context-placeholders", - "word-card-ids", + assert!(!with_cards.contains("") && !with_cards.contains("")); + // The word-card KEY paragraphs exist exactly when the section does. + for paragraph_marker in [ + "WORDS lists one WORD card per content word", + "COMPOSITE-APPROX shows the mechanical composition", + "PLACES=\"UNKNOWN\" means the composition tree", + "cards state ASSUMED-LEFT", + "VARIABLE-CONTEXT denotes the abstract role", + "WORD ID values are surface-spelling card keys", ] { assert!( - with_cards.contains(&format!("")), - "missing KEY rule {topic}" + with_cards.contains(paragraph_marker), + "missing KEY comment paragraph: {paragraph_marker}" ); assert!( - !without_cards.contains(&format!("")), - "card-less document must not carry KEY rule {topic}" + !without_cards.contains(paragraph_marker), + "card-less document must not carry the paragraph: {paragraph_marker}" ); } assert!(!without_cards.contains("")); @@ -5396,8 +5442,10 @@ mod tests { .split_once("") .expect("WORDS section") .1; - let without_body = without_cards.split_once("").expect("KEY").1; - assert_eq!(with_body, without_body); + let without_body = without_cards + .split_once("\n ") + .expect("DEFS after comment"); + assert_eq!(with_body, format!("\n {}", without_body.1)); } #[test] @@ -5430,11 +5478,11 @@ mod tests { assert_eq!(actual, expected); assert_eq!( aggregate_hash("frozen.json"), - "69ea08a65aba19049f65070b9eb045361834ddfbd2773da972c047be325381b3" + "3f5171701f45523f70a97faad8a8b86c6a96c4c98a22dffccc05d7e210d12218" ); assert_eq!( aggregate_hash("xml.txt"), - "8054b126268d07532363b576a1a5e27c5c4eb446aa4370b0a020284b159e5220" + "38e85d26ba63780c33a90ea99c9d427e3e37d6364a0cb4813f4d21615645199c" ); let binder_universe_bytes = include_bytes!("../../tests/xml_corpus/BINDER_UNIVERSES.json"); assert_eq!( @@ -5628,7 +5676,7 @@ mod tests { assert!(content_abstraction.contains("")); assert_eq!( format!("{:x}", Sha256::digest(content_abstraction.as_bytes())), - "0865509d9b4344749b7d99024915839d4f3c609bcde4b6772919f72372cb8b75" + "6080365adb356f04598f6ca705d67da4b2f8ae4d338de20abdb1f034cf5109e3" ); let mut direct_question = graph("b58"); @@ -5650,7 +5698,7 @@ mod tests { assert_no_compact_generic_fallback(&direct_question, ""); assert_eq!( format!("{:x}", Sha256::digest(direct_question.as_bytes())), - "cabd9f5c468c4d4645f76099b0ad10e5f7cc56d00c81ee99432bd0809a5431a5" + "fb17cdc0c93972c82b1e641e528545af881ff5f3f9995a01bafecfa34f40d99c" ); let mut shared = graph("b58"); @@ -5676,7 +5724,7 @@ mod tests { assert_eq!(shared.matches("").count(), 1); assert_eq!( format!("{:x}", Sha256::digest(shared.as_bytes())), - "bbeef899f72757dc5a012eadaf4e5d4c791fc2e23c38babb9787d36ea3e8c71e" + "5aeb6ad72a98c5cb2c6558b1a71e90a5bdc7306321e9886d9e81bc5bfd53a8e7" ); let content = shared .split_once("") @@ -5752,7 +5800,7 @@ mod tests { assert_no_compact_generic_fallback(&orphan, ""); assert_eq!( format!("{:x}", Sha256::digest(orphan.as_bytes())), - "c028d711d3b6d636ca8905d9161e59b3b89809f897a986fa2672bc38b85bbb8a" + "ab0ba51a6930df1f4a7bf548471a241fdc9df4d36d29e4376d3690fd10f408fd" ); } @@ -5762,13 +5810,17 @@ mod tests { fn kind_composition_is_first_class_nested_and_provenance_free() { let rendered = render_xml_value(graph("b39"), "b39"); assert!(!rendered.output.contains("FORM=\"TYPED-GRAPH\"")); + // jbotci#719: the tanru projects as one predication with a nested + // KIND-COMPOSITION relation expression in the relation slot. assert_eq!(rendered.output.matches("").count(), 2); assert!(rendered.output.contains( - "\n \n " + "\n \n " )); assert!(rendered.output.contains( - "\n \n " + "\n \n " )); + assert!(!rendered.output.contains("PREDICATE=\"tanru\"")); + assert!(!rendered.output.contains(" = BTreeMap::new(); @@ -5849,10 +5902,13 @@ mod tests { let expected = declared_waiver_occurrences(&graph); let rendered = render_xml_value(graph, document); let actual: BTreeSet = rendered.omissions.iter().cloned().collect(); - assert_eq!( - actual, expected, - "{document}: observed omissions differ from independently expanded waivers" - ); + if actual != expected { + let missing: Vec<_> = expected.difference(&actual).collect(); + let extra: Vec<_> = actual.difference(&expected).collect(); + panic!( + "{document}: observed omissions differ from independently expanded waivers:\nmissing: {missing:#?}\nextra: {extra:#?}" + ); + } assert_eq!( actual.len(), rendered.omissions.len(), @@ -5884,9 +5940,10 @@ mod tests { (XmlWaiverFamily::QuantityText, 11), (XmlWaiverFamily::BoundVariableWord, 9), (XmlWaiverFamily::CompositionRelationLabel, 5), + (XmlWaiverFamily::ConnectorProvenance, 16), ]) ); - assert_eq!(counts.values().sum::(), 941); + assert_eq!(counts.values().sum::(), 957); assert_eq!( documents .into_iter() @@ -5900,6 +5957,7 @@ mod tests { (XmlWaiverFamily::QuantityText, 7), (XmlWaiverFamily::BoundVariableWord, 6), (XmlWaiverFamily::CompositionRelationLabel, 3), + (XmlWaiverFamily::ConnectorProvenance, 6), ]) ); } @@ -7402,33 +7460,55 @@ impl RenderState { result } + /// Account one connector record without rendering a CONNECTOR element + /// (jbotci#719): the surface word and the grammatical locus are + /// provenance-class and join the connector-provenance waiver family; a + /// truth table the parent operator does not already determine renders as a + /// TRUTH-TABLE= attribute; a connective question's bound parameter renders + /// as a PARAMETER child. Returns the attributes and children to attach to + /// the parent element where the CONNECTOR element used to sit. #[requires(true)] - #[ensures(ret.name == "CONNECTOR")] - fn render_connector(&mut self, graph: &GraphData, value: &Map) -> XmlElement { - let mut result = XmlElement::new("CONNECTOR"); - let mut handled = Vec::new(); - if let Some(source) = value.get("source") { - self.account_field(graph, value, "source"); - result.set("SOURCE-WORD", scalar_string(source)); - handled.push("source"); + #[ensures(true)] + fn account_connector( + &mut self, + graph: &GraphData, + connector: &Map, + operator: &str, + ) -> (Vec<(String, String)>, Vec) { + self.account_object(graph, connector); + for field in ["source", "locus"] { + if connector.contains_key(field) { + self.record_field_omission( + graph, + connector, + field, + XmlWaiverFamily::ConnectorProvenance, + ); + } } - for field in ["locus", "truthTable"] { - if let Some(field_value) = value.get(field) { - self.account_field(graph, value, field); - result.push(Self::scalar( - &enum_string(field).replace('_', "-"), - field_value, - )); - handled.push(field); + let mut attributes = Vec::new(); + if let Some(truth_table) = optional_string(connector, "truthTable") { + self.account_field(graph, connector, "truthTable"); + if canonical_truth_table(operator) != Some(truth_table) { + attributes.push(("TRUTH-TABLE".to_owned(), truth_table.to_owned())); } } - if let Some(parameter) = optional_string(value, "parameter") { - self.account_field(graph, value, "parameter"); - result.push(self.wrap_pointer(graph, "PARAMETER", parameter, Vec::new())); - handled.push("parameter"); + if let Some(parameter) = optional_string(connector, "parameter") { + self.account_field(graph, connector, "parameter"); + // A connective question's bound parameter is an attribute use of + // an already-defined parameter object (jbotci#719: the PARAMETER + // element spelling would collide with the parameter object + // element in the schema's content models). + let id = self.pointer_id(graph, parameter, "connective question parameter"); + attributes.push(("PARAMETER".to_owned(), id)); } - result.extend(self.extras(graph, value, &handled)); - result + let mut children = Vec::new(); + children.extend(self.extras( + graph, + connector, + &["source", "locus", "truthTable", "parameter"], + )); + (attributes, children) } #[requires(true)] @@ -8361,6 +8441,207 @@ impl RenderState { result } + /// Render the tanru-link sidecar of an unprojected tanru-link predication + /// (the loud fallback form): a KIND-COMPOSITION of pointer wrappers to the + /// head predication and the modifier relation, occupying the predication's + /// relation slot (jbotci#719). + #[requires(object.contains_key("tanruLink"))] + #[ensures(ret.name == "KIND-COMPOSITION")] + fn render_tanru_link_sidecar( + &mut self, + graph: &GraphData, + object: &Map, + ) -> XmlElement { + let link = json_object(&object["tanruLink"]); + self.account_field(graph, object, "tanruLink"); + let mut composition = XmlElement::new("KIND-COMPOSITION"); + let head = string_field(link, "head"); + self.account_field(graph, link, "head"); + composition.push(self.wrap_pointer(graph, "KIND", head, Vec::new())); + let modifier = string_field(link, "modifier"); + self.account_field(graph, link, "modifier"); + composition.push(self.wrap_pointer(graph, "MODIFIER", modifier, Vec::new())); + if link.contains_key("relationLabel") { + self.record_field_omission( + graph, + link, + "relationLabel", + XmlWaiverFamily::CompositionRelationLabel, + ); + } + composition.extend(self.extras(graph, link, &["head", "modifier", "relationLabel"])); + composition + } + + /// Render the typed relation-expression view of a projected tanru + /// predication (jbotci#719): a KIND-COMPOSITION in the relation slot. + /// `host_predicate` is the enclosing predication's own relation, rendered + /// as the PREDICATE= of `host` operands. + #[requires(view.contains_key("kind") && view.contains_key("modifier"))] + #[ensures(ret.name == "KIND-COMPOSITION")] + fn render_relation_composition( + &mut self, + graph: &GraphData, + view: &Map, + host_predicate: &str, + ) -> XmlElement { + let mut result = XmlElement::new("KIND-COMPOSITION"); + if view.get("grouping").and_then(Value::as_str) == Some("explicit") { + result.set("GROUPING", "EXPLICIT"); + } + result.push(self.render_relation_operand( + graph, + "KIND", + json_object(&view["kind"]), + Some(host_predicate), + )); + result.push(self.render_relation_operand( + graph, + "MODIFIER", + json_object(&view["modifier"]), + None, + )); + result + } + + /// Render one operand of a relation composition under `tag` (KIND, + /// MODIFIER, or RELATION inside a relation-level CONNECTIVE). + #[requires(true)] + #[ensures(ret.name == tag)] + fn render_relation_operand( + &mut self, + graph: &GraphData, + tag: &str, + operand: &Map, + host_predicate: Option<&str>, + ) -> XmlElement { + match optional_string(operand, "type") { + Some("host") => { + let mut result = XmlElement::new(tag); + result.set( + "PREDICATE", + predicate_symbol( + host_predicate.expect("host operand requires the predication relation"), + ), + ); + Self::set_participant_place(&mut result, operand); + result + } + Some("lexical") => self.render_relation_lexical(graph, tag, operand), + Some("kindComposition") => { + let mut result = XmlElement::new(tag); + let mut body = XmlElement::new("BODY"); + body.push(self.render_relation_composition( + graph, + operand, + host_predicate.unwrap_or_default(), + )); + result.push(body); + result + } + Some("connective") => { + let operator = optional_string(operand, "operator") + .unwrap_or_else(|| panic!("relation connective lacks an operator")); + let mut connective = + XmlElement::with_attributes("CONNECTIVE", [("OPERATOR", enum_string(operator))]); + for leaf in operand + .get("operands") + .and_then(Value::as_array) + .unwrap_or_else(|| panic!("relation connective lacks operands")) + { + connective.push(self.render_relation_operand( + graph, + "RELATION", + json_object(leaf), + None, + )); + } + let mut result = XmlElement::new(tag); + let mut body = XmlElement::new("BODY"); + body.push(connective); + result.push(body); + result + } + Some("reference") => { + let relation = optional_string(operand, "relation") + .unwrap_or_else(|| panic!("relation reference operand lacks a target")); + let rendered = self.render_pointer(graph, relation); + let mut result = XmlElement::new(tag); + if Self::is_reference(&rendered) { + result.set("REF", rendered.attributes[0].1.clone()); + } else { + let mut body = XmlElement::new("BODY"); + body.push(rendered); + result.push(body); + } + result + } + other => panic!("unknown relation operand kind: {other:?}"), + } + } + + /// Render a compact lexical relation leaf: PREDICATE= plus an optional + /// PARTICIPANT-PLACE= (default 1) and fixed non-participant ARGs. + #[requires(true)] + #[ensures(ret.name == tag)] + fn render_relation_lexical( + &mut self, + graph: &GraphData, + tag: &str, + operand: &Map, + ) -> XmlElement { + let mut result = XmlElement::new(tag); + result.set( + "PREDICATE", + predicate_symbol( + optional_string(operand, "predicate") + .unwrap_or_else(|| panic!("lexical relation leaf lacks a predicate")), + ), + ); + Self::set_participant_place(&mut result, operand); + if let Some(fixed) = operand.get("fixedArguments").and_then(Value::as_object) { + let mut places: Vec<(&String, &str)> = fixed + .iter() + .map(|(place, target)| { + ( + place, + target.as_str().unwrap_or_else(|| { + panic!("fixed relation argument target must be an id") + }), + ) + }) + .collect(); + places.sort_by_key(|(place, _)| { + place + .parse::() + .unwrap_or_else(|_| panic!("fixed relation argument place must be numeric")) + }); + for (place, target) in places { + result.push(self.wrap_pointer( + graph, + "ARG", + target, + vec![("INDEX", place.clone())], + )); + } + } + result + } + + /// PARTICIPANT-PLACE= is stated exactly when the composition participant + /// fills a lexical place other than the first. + #[requires(true)] + #[ensures(true)] + fn set_participant_place(result: &mut XmlElement, operand: &Map) { + let place = operand + .get("participantPlace") + .and_then(Value::as_u64) + .unwrap_or(1); + if place != 1 { + result.set("PARTICIPANT-PLACE", place.to_string()); + } + } + #[requires(true)] #[ensures(ret.name == "PREDICATION")] fn render_predication( @@ -8379,13 +8660,31 @@ impl RenderState { "mode", ]); let mut result = XmlElement::new("PREDICATION"); - let relation_value = if let Some(relation) = optional_string(object, "relation") { + let relation_value = if let Some(view) = + object.get("relationExpression").and_then(Value::as_object) + { + // A projected tanru (#719): the relation slot carries the composite + // predicate expression; the predication's own `relation` renders as + // the host KIND leaf's PREDICATE= rather than on the element. + self.account_field_tree(graph, object, "relationExpression"); + handled.push("relationExpression"); + let host_predicate = optional_string(object, "relation") + .unwrap_or_else(|| panic!("projected predication lacks its host relation")); + self.account_field(graph, object, "relation"); + Some(self.render_relation_composition(graph, view, host_predicate)) + } else if let Some(relation) = optional_string(object, "relation") { self.account_field(graph, object, "relation"); result.set("PREDICATE", predicate_symbol(relation)); None } else if let Some(parameter) = optional_string(object, "relationParameter") { self.account_field(graph, object, "relationParameter"); Some(self.wrap_pointer(graph, "RELATION", parameter, Vec::new())) + } else if object.contains_key("tanruLink") { + // An unprojected tanru-link predication (the recognition guards + // rejected the compact form): no PREDICATE= — the KIND-COMPOSITION + // sidecar occupies the relation slot and carries the meaning. + handled.push("tanruLink"); + Some(self.render_tanru_link_sidecar(graph, object)) } else { Some(XmlElement::new("MISSING-RELATION")) }; @@ -8448,28 +8747,6 @@ impl RenderState { handled.push("placeQuestions"); } - if let Some(link) = object.get("tanruLink").and_then(Value::as_object) { - self.account_field(graph, object, "tanruLink"); - let mut composition = XmlElement::new("KIND-COMPOSITION"); - let head = string_field(link, "head"); - self.account_field(graph, link, "head"); - composition.push(self.wrap_pointer(graph, "KIND", head, Vec::new())); - let modifier = string_field(link, "modifier"); - self.account_field(graph, link, "modifier"); - composition.push(self.wrap_pointer(graph, "MODIFIER", modifier, Vec::new())); - if link.contains_key("relationLabel") { - self.record_field_omission( - graph, - link, - "relationLabel", - XmlWaiverFamily::CompositionRelationLabel, - ); - } - composition.extend(self.extras(graph, link, &["head", "modifier", "relationLabel"])); - result.push(composition); - handled.push("tanruLink"); - } - let mut metadata = XmlElement::new("META"); if let Some(relation_metadata) = optional_string(object, "relationMetadata") { if self.word_cards_present { @@ -8603,6 +8880,7 @@ impl RenderState { ); self.bound_variable_stack.push(variable.to_owned()); let scope = vec!["quantifier-body".to_owned(), key.to_owned()]; + let mut connector_parts = None; let (declarations, content) = self.scoped_parts(graph, scope, |state, graph| { let mut handled = Vec::from(["type", "operator", "boundEventualities", "variable"]); let mut content: HashMap<&str, XmlElement> = HashMap::new(); @@ -8645,7 +8923,7 @@ impl RenderState { } if let Some(connector) = object.get("connector").and_then(Value::as_object) { state.account_field(graph, object, "connector"); - content.insert("connector", state.render_connector(graph, connector)); + connector_parts = Some(state.account_connector(graph, connector, operator)); handled.push("connector"); } let mut extras = XmlElement::new("EXTRAS"); @@ -8688,10 +8966,14 @@ impl RenderState { { result.push(quantity); } - for field in ["domainImport", "connector"] { - if let Some(value) = content.remove(field) { - result.push(value); + if let Some(value) = content.remove("domainImport") { + result.push(value); + } + if let Some((attributes, children)) = connector_parts { + for (name, value) in attributes { + result.set(name, value); } + result.extend(children); } if let Some(extras) = content.remove("extras") { result.extend(extras.children); @@ -8772,17 +9054,24 @@ impl RenderState { handled.push("domainImport"); } } - let mut post = Vec::new(); + let mut connector_parts = None; if let Some(connector) = object.get("connector").and_then(Value::as_object) { state.account_field(graph, object, "connector"); - post.push(state.render_connector(graph, connector)); + connector_parts = Some(state.account_connector(graph, connector, operator)); handled.push("connector"); } let extras = state.extras(graph, object, &handled); - (operands, post, extras) + (operands, connector_parts, extras) }); - let (operands, post, extras) = parts; - if operator == "atom" && declarations.is_empty() && post.is_empty() && extras.is_empty() { + let (operands, connector_parts, extras) = parts; + let (connector_attributes, connector_children) = + connector_parts.unwrap_or_default(); + let connector_rendered = !connector_attributes.is_empty() || !connector_children.is_empty(); + if operator == "atom" + && declarations.is_empty() + && !connector_rendered + && extras.is_empty() + { assert_eq!(operands.len(), 1, "atom formula has invalid operand count"); return operands.into_iter().next().expect("one operand"); } @@ -8796,17 +9085,22 @@ impl RenderState { }; Self::append_defs(&mut core, declarations); core.extend(operands); - if post.is_empty() && extras.is_empty() { + // Connector content attaches to the connective element itself now that + // the CONNECTOR wrapper is gone (#719): TRUTH-TABLE= and PARAMETER= + // attributes; only unknown extra fields still force a FORMULA wrapper. + for (name, value) in connector_attributes { + core.set(name, value); + } + core.extend(connector_children); + if extras.is_empty() { return core; } if core.name == "FORMULA" { - core.extend(post); core.extend(extras); return core; } let mut wrapper = XmlElement::new("FORMULA"); wrapper.push(core); - wrapper.extend(post); wrapper.extend(extras); wrapper } diff --git a/crates/jbotci-semantics/src/notation/xml_words.rs b/crates/jbotci-semantics/src/notation/xml_words.rs index 2d8ff0d1e2..27a91a7a1b 100644 --- a/crates/jbotci-semantics/src/notation/xml_words.rs +++ b/crates/jbotci-semantics/src/notation/xml_words.rs @@ -605,7 +605,7 @@ mod tests { #[ensures(ret.starts_with("\n"))] #[ensures(ret.ends_with("\n"))] fn words_xml_for(text: &str) -> String { - serialize(&words_section(&cards_for(text))) + serialize(&words_section(&cards_for(text)), None) } #[test] diff --git a/crates/jbotci-semantics/tests/completeness.rs b/crates/jbotci-semantics/tests/completeness.rs index 7a75ce23df..6dc9826307 100644 --- a/crates/jbotci-semantics/tests/completeness.rs +++ b/crates/jbotci-semantics/tests/completeness.rs @@ -592,9 +592,13 @@ fn provenance_is_type_based() { "provenance policy disagrees with the type graph:\n{}", mismatches.join("\n") ); - // The load-bearing distinction: Connector.source is a lexical String, not - // provenance — so it is NOT in the source-link set. - assert_eq!(graph.field_type("Connector", "source"), Some("String")); + // The load-bearing distinction: Connector.source is a typed ConnectorSource + // (surface word vs implicit juxtaposition), not SemanticSource provenance — + // so it is NOT in the source-link set. + assert_eq!( + graph.field_type("Connector", "source"), + Some("ConnectorSource") + ); assert!(!links.contains(&"Connector")); } diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/PROVENANCE.md b/crates/jbotci-semantics/tests/phaseb_corpus/PROVENANCE.md index b0b47b8169..6a677603b0 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/PROVENANCE.md +++ b/crates/jbotci-semantics/tests/phaseb_corpus/PROVENANCE.md @@ -145,6 +145,24 @@ Regenerate both fixture sets by re-running the oracle over the --provenance`); then update the two aggregate hashes pinned in `tests/smusni_parity.rs` and the `FREEZE-PHASE-B.md` amendment in lockstep. +**jbotci#719 departure (owner ruling 2026-08-01):** the fixtures are no +longer oracle-produced bytes. The owner ruled that connector surface words +and loci are provenance-class (CONNECTIVE SOURCE/LOCUS leave the default +output and render only under the provenance opt-in, where LOCUS now uses +English names), truth tables render only when the operator does not already +determine them, the fake `RELATION: tanru` name is gone (composition +predications carry no RELATION line; the TANRU LINK record stays), and the +`WAIVED { }` bookkeeping block left model-facing output. The frozen JSON +graphs were migrated mechanically by `scripts/migrate_issue_719_json.py` +(typed connector source, English locus, fake relation dropped — every +document rebuilds byte-exactly from its `.lojban` through the product +pipeline), and both fixture sets were regenerated from the product pipeline +by `examples/regen_goldens.rs smusni` under the mechanical-diff proof of +`scripts/verify_issue_719_output_migration.py`; the aggregate hash pins in +`tests/smusni_parity.rs` were updated to the new sets. Byte-parity with the +research oracle is deliberately suspended at this point until the oracle +catches up or a new amendment re-baselines it. + `hostile-quote.*` is a **separate** regression fixture (not in `CORPUS_DOCS`, and excluded from the corpus/aggregate hashes): a `zoi` quotation whose text carries notation metacharacters (`{ ( ; } )`), guarding the dense-flatten hardening diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/b21.frozen.json b/crates/jbotci-semantics/tests/phaseb_corpus/b21.frozen.json index c0af330404..f57ebfb0ca 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/b21.frozen.json +++ b/crates/jbotci-semantics/tests/phaseb_corpus/b21.frozen.json @@ -220,8 +220,11 @@ "formula:23" ], "connector": { - "source": "gi'e", - "locus": "bridiTail", + "source": { + "kind": "surfaceWord", + "word": "gi'e" + }, + "locus": "predicatePhrase", "truthTable": "TFFF" }, "source": { diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/b21.smusni-prov.txt b/crates/jbotci-semantics/tests/phaseb_corpus/b21.smusni-prov.txt index 0b3bb4b182..a927e89002 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/b21.smusni-prov.txt +++ b/crates/jbotci-semantics/tests/phaseb_corpus/b21.smusni-prov.txt @@ -61,7 +61,7 @@ SEMANTIC DOCUMENT document_1 { FORMULA f16 IS ATOM { PREDICATION: p15; PROVENANCE { BYTE SPAN: 3..8; TEXT: "prenu"; CONSTRUCT: "restrictive-formula"; } } FORMULA f19 IS ATOM { PREDICATION: p18; BOUND EVENTUALITIES { r6; } PROVENANCE { BYTE SPAN: 12..17; TEXT: "lebna"; CONSTRUCT: "bridi-tail-formula"; } } FORMULA f23 IS ATOM { PREDICATION: p22; BOUND EVENTUALITIES { r20; } PROVENANCE { BYTE SPAN: 32..37; TEXT: "tcidu"; CONSTRUCT: "bridi-tail-formula"; } } - FORMULA f24 IS ∧ { OPERANDS IN ORDER ( f19; f23; ) CONNECTIVE SOURCE: gi'e; TRUTH TABLE: T F F F; PROVENANCE { BYTE SPAN: 0..40; TEXT: "lo prenu cu lebna lo cukta gi'e tcidu ri"; CONSTRUCT: "compound-bridi-formula"; } } + FORMULA f24 IS ∧ { OPERANDS IN ORDER ( f19; f23; ) CONNECTIVE SOURCE: gi'e; LOCUS: PREDICATE PHRASE; PROVENANCE { BYTE SPAN: 0..40; TEXT: "lo prenu cu lebna lo cukta gi'e tcidu ri"; CONSTRUCT: "compound-bridi-formula"; } } REFERENCE r1 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: SPEAKER; } REFERENCE r2 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: AUDIENCE; } REFERENCE r4 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: HERE; } diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/b21.smusni.txt b/crates/jbotci-semantics/tests/phaseb_corpus/b21.smusni.txt index cafa4e81db..0abbfbebbc 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/b21.smusni.txt +++ b/crates/jbotci-semantics/tests/phaseb_corpus/b21.smusni.txt @@ -23,7 +23,7 @@ SEMANTIC DOCUMENT document_1 { FORMULA f16 IS ATOM { PREDICATION: p15; } FORMULA f19 IS ATOM { PREDICATION: p18; BOUND EVENTUALITIES { r6; } } FORMULA f23 IS ATOM { PREDICATION: p22; BOUND EVENTUALITIES { r20; } } - FORMULA f24 IS ∧ { OPERANDS IN ORDER ( f19; f23; ) CONNECTIVE SOURCE: gi'e; TRUTH TABLE: T F F F; } + FORMULA f24 IS ∧ { OPERANDS IN ORDER ( f19; f23; ) } REFERENCE r1 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: SPEAKER; } REFERENCE r2 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: AUDIENCE; } REFERENCE r4 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: HERE; } diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/b25.frozen.json b/crates/jbotci-semantics/tests/phaseb_corpus/b25.frozen.json index 43e457b8dd..22e7a1ef86 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/b25.frozen.json +++ b/crates/jbotci-semantics/tests/phaseb_corpus/b25.frozen.json @@ -134,8 +134,11 @@ "formula:16" ], "connector": { - "source": "ga nai gi", - "locus": "bridi", + "source": { + "kind": "surfaceWord", + "word": "ga nai gi" + }, + "locus": "clause", "truthTable": "TFTT" } }, diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/b25.smusni-prov.txt b/crates/jbotci-semantics/tests/phaseb_corpus/b25.smusni-prov.txt index c8aaa5d355..7d814a775a 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/b25.smusni-prov.txt +++ b/crates/jbotci-semantics/tests/phaseb_corpus/b25.smusni-prov.txt @@ -51,7 +51,7 @@ SEMANTIC DOCUMENT document_1 { FORMULA f12 IS ATOM { PREDICATION: p11; BOUND EVENTUALITIES { r6; } PROVENANCE { BYTE SPAN: 6..14; TEXT: "do klama"; CONSTRUCT: "bridi-formula"; } } FORMULA f16 IS ATOM { PREDICATION: p15; BOUND EVENTUALITIES { r13; } PROVENANCE { BYTE SPAN: 18..26; TEXT: "mi gleki"; CONSTRUCT: "bridi-formula"; } } FORMULA f17 IS ¬ { OPERANDS IN ORDER ( f12; ) } - FORMULA f18 IS ∨ { OPERANDS IN ORDER ( f17; f16; ) CONNECTIVE SOURCE: ga nai gi; TRUTH TABLE: T F T T; } + FORMULA f18 IS ∨ { OPERANDS IN ORDER ( f17; f16; ) CONNECTIVE SOURCE: ga nai gi; LOCUS: CLAUSE; TRUTH TABLE: T F T T; } REFERENCE r1 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: SPEAKER; } REFERENCE r2 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: AUDIENCE; } REFERENCE r4 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: HERE; } diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/b25.smusni.txt b/crates/jbotci-semantics/tests/phaseb_corpus/b25.smusni.txt index b36a17a5b1..845a7c127c 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/b25.smusni.txt +++ b/crates/jbotci-semantics/tests/phaseb_corpus/b25.smusni.txt @@ -20,7 +20,7 @@ SEMANTIC DOCUMENT document_1 { FORMULA f12 IS ATOM { PREDICATION: p11; BOUND EVENTUALITIES { r6; } } FORMULA f16 IS ATOM { PREDICATION: p15; BOUND EVENTUALITIES { r13; } } FORMULA f17 IS ¬ { OPERANDS IN ORDER ( f12; ) } - FORMULA f18 IS ∨ { OPERANDS IN ORDER ( f17; f16; ) CONNECTIVE SOURCE: ga nai gi; TRUTH TABLE: T F T T; } + FORMULA f18 IS ∨ { OPERANDS IN ORDER ( f17; f16; ) TRUTH TABLE: T F T T; } REFERENCE r1 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: SPEAKER; } REFERENCE r2 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: AUDIENCE; } REFERENCE r4 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: HERE; } diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/b39.frozen.json b/crates/jbotci-semantics/tests/phaseb_corpus/b39.frozen.json index 1ac115cf2f..fa9ce3a816 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/b39.frozen.json +++ b/crates/jbotci-semantics/tests/phaseb_corpus/b39.frozen.json @@ -131,7 +131,6 @@ }, "predication:23": { "type": "predication", - "relation": "tanru", "tanruLink": { "head": "predication:15", "modifier": "relation:22", @@ -159,7 +158,6 @@ }, "predication:27": { "type": "predication", - "relation": "tanru", "tanruLink": { "head": "predication:8", "modifier": "relation:26", @@ -283,8 +281,10 @@ "formula:24" ], "connector": { - "source": "tanru", - "locus": "property-abstraction" + "source": { + "kind": "implicitJuxtaposition" + }, + "locus": "propertyAbstraction" }, "boundEventualities": [ "eventuality:11" @@ -319,7 +319,9 @@ "formula:28" ], "connector": { - "source": "tanru", + "source": { + "kind": "implicitJuxtaposition" + }, "locus": "description" }, "source": { diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/b39.smusni-prov.txt b/crates/jbotci-semantics/tests/phaseb_corpus/b39.smusni-prov.txt index 9d005a426e..dd9f75f191 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/b39.smusni-prov.txt +++ b/crates/jbotci-semantics/tests/phaseb_corpus/b39.smusni-prov.txt @@ -50,38 +50,8 @@ SEMANTIC DOCUMENT document_1 { TEXT: "sutra bajra prenu"; CONSTRUCT: "restrictive-tanru-formula"; } - PREDICATION p23 { - RELATION: tanru; - ARGS ( - [1]: VALUE x10; - [2]: REFERENCE DENOTATION l22; - ) - MODE: RESTRICTIVE; - TANRU LINK - HEAD: p15; - MODIFIER: l22; - RELATION LABEL: sutra-bajra; - PROVENANCE - BYTE SPAN: 3..20; - TEXT: "sutra bajra prenu"; - CONSTRUCT: "restrictive-tanru-formula"; - } - PREDICATION p27 { - RELATION: tanru; - ARGS ( - [1]: REFERENCE DENOTATION r7; - [2]: REFERENCE DENOTATION l26; - ) - MODE: RESTRICTIVE; - TANRU LINK - HEAD: p8; - MODIFIER: l26; - RELATION LABEL: sutra-bajra-prenu; - PROVENANCE - BYTE SPAN: 3..20; - TEXT: "sutra bajra prenu"; - CONSTRUCT: "restrictive-tanru-formula"; - } + PREDICATION p23 { ARGS ( [1]: VALUE x10; [2]: REFERENCE DENOTATION l22; ) MODE: RESTRICTIVE; TANRU LINK { HEAD: p15; MODIFIER: l22; RELATION LABEL: sutra-bajra; } PROVENANCE { BYTE SPAN: 3..20; TEXT: "sutra bajra prenu"; CONSTRUCT: "restrictive-tanru-formula"; } } + PREDICATION p27 { ARGS ( [1]: REFERENCE DENOTATION r7; [2]: REFERENCE DENOTATION l26; ) MODE: RESTRICTIVE; TANRU LINK { HEAD: p8; MODIFIER: l26; RELATION LABEL: sutra-bajra-prenu; } PROVENANCE { BYTE SPAN: 3..20; TEXT: "sutra bajra prenu"; CONSTRUCT: "restrictive-tanru-formula"; } } PREDICATION p33 { RELATION: tavla; EVENTUALITY: r6; @@ -101,9 +71,23 @@ SEMANTIC DOCUMENT document_1 { FORMULA f16 IS ATOM { PREDICATION: p15; PROVENANCE { BYTE SPAN: 3..20; TEXT: "sutra bajra prenu"; CONSTRUCT: "restrictive-tanru-formula"; } } FORMULA f21 IS ATOM { PREDICATION: p20; BOUND EVENTUALITIES { r18; } PROVENANCE { BYTE SPAN: 3..20; TEXT: "sutra bajra prenu"; CONSTRUCT: "restrictive-tanru-formula"; } } FORMULA f24 IS ATOM { PREDICATION: p23; PROVENANCE { BYTE SPAN: 3..20; TEXT: "sutra bajra prenu"; CONSTRUCT: "restrictive-tanru-formula"; } } - FORMULA f25 IS ∧ { OPERANDS IN ORDER ( f16; f24; ) CONNECTIVE SOURCE: tanru; BOUND EVENTUALITIES { r11; } PROVENANCE { BYTE SPAN: 3..20; TEXT: "sutra bajra prenu"; CONSTRUCT: "restrictive-tanru-formula"; } } + FORMULA f25 IS ∧ { + OPERANDS IN ORDER ( + f16; + f24; + ) + CONNECTIVE SOURCE: IMPLICIT JUXTAPOSITION; + LOCUS: PROPERTY ABSTRACTION; + BOUND EVENTUALITIES { + r11; + } + PROVENANCE + BYTE SPAN: 3..20; + TEXT: "sutra bajra prenu"; + CONSTRUCT: "restrictive-tanru-formula"; + } FORMULA f28 IS ATOM { PREDICATION: p27; PROVENANCE { BYTE SPAN: 3..20; TEXT: "sutra bajra prenu"; CONSTRUCT: "restrictive-tanru-formula"; } } - FORMULA f29 IS ∧ { OPERANDS IN ORDER ( f9; f28; ) CONNECTIVE SOURCE: tanru; PROVENANCE { BYTE SPAN: 3..20; TEXT: "sutra bajra prenu"; CONSTRUCT: "restrictive-tanru-formula"; } } + FORMULA f29 IS ∧ { OPERANDS IN ORDER ( f9; f28; ) CONNECTIVE SOURCE: IMPLICIT JUXTAPOSITION; LOCUS: DESCRIPTION; PROVENANCE { BYTE SPAN: 3..20; TEXT: "sutra bajra prenu"; CONSTRUCT: "restrictive-tanru-formula"; } } FORMULA f34 IS ATOM { PREDICATION: p33; BOUND EVENTUALITIES { r6; } PROVENANCE { BYTE SPAN: 0..29; TEXT: "lo sutra bajra prenu cu tavla"; CONSTRUCT: "bridi-formula"; } } REFERENCE r1 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: SPEAKER; } REFERENCE r2 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: AUDIENCE; } diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/b39.smusni.txt b/crates/jbotci-semantics/tests/phaseb_corpus/b39.smusni.txt index 6d42df09f6..ca3b9e8ffb 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/b39.smusni.txt +++ b/crates/jbotci-semantics/tests/phaseb_corpus/b39.smusni.txt @@ -20,16 +20,16 @@ SEMANTIC DOCUMENT document_1 { PREDICATION p8 { RELATION: prenu; ARGS ( [1]: REFERENCE DENOTATION r7; ) MODE: RESTRICTIVE; } PREDICATION p15 { RELATION: bajra; EVENTUALITY: r11; ARGS ( [1]: VALUE x10; [2]: REFERENCE DENOTATION r12; [3]: REFERENCE DENOTATION r13; [4]: REFERENCE DENOTATION r14; ) MODE: RESTRICTIVE; } PREDICATION p20 { RELATION: sutra; EVENTUALITY: r18; ARGS ( [1]: VALUE x17; [2]: REFERENCE DENOTATION r19; ) MODE: RESTRICTIVE; } - PREDICATION p23 { RELATION: tanru; ARGS ( [1]: VALUE x10; [2]: REFERENCE DENOTATION l22; ) MODE: RESTRICTIVE; TANRU LINK { HEAD: p15; MODIFIER: l22; RELATION LABEL: sutra-bajra; } } - PREDICATION p27 { RELATION: tanru; ARGS ( [1]: REFERENCE DENOTATION r7; [2]: REFERENCE DENOTATION l26; ) MODE: RESTRICTIVE; TANRU LINK { HEAD: p8; MODIFIER: l26; RELATION LABEL: sutra-bajra-prenu; } } + PREDICATION p23 { ARGS ( [1]: VALUE x10; [2]: REFERENCE DENOTATION l22; ) MODE: RESTRICTIVE; TANRU LINK { HEAD: p15; MODIFIER: l22; RELATION LABEL: sutra-bajra; } } + PREDICATION p27 { ARGS ( [1]: REFERENCE DENOTATION r7; [2]: REFERENCE DENOTATION l26; ) MODE: RESTRICTIVE; TANRU LINK { HEAD: p8; MODIFIER: l26; RELATION LABEL: sutra-bajra-prenu; } } PREDICATION p33 { RELATION: tavla; EVENTUALITY: r6; ARGS ( [1]: REFERENCE DENOTATION r7; [2]: REFERENCE DENOTATION r30; [3]: REFERENCE DENOTATION r31; [4]: REFERENCE DENOTATION r32; ) MODE: ASSERTED; } FORMULA f9 IS ATOM { PREDICATION: p8; } FORMULA f16 IS ATOM { PREDICATION: p15; } FORMULA f21 IS ATOM { PREDICATION: p20; BOUND EVENTUALITIES { r18; } } FORMULA f24 IS ATOM { PREDICATION: p23; } - FORMULA f25 IS ∧ { OPERANDS IN ORDER ( f16; f24; ) CONNECTIVE SOURCE: tanru; BOUND EVENTUALITIES { r11; } } + FORMULA f25 IS ∧ { OPERANDS IN ORDER ( f16; f24; ) BOUND EVENTUALITIES { r11; } } FORMULA f28 IS ATOM { PREDICATION: p27; } - FORMULA f29 IS ∧ { OPERANDS IN ORDER ( f9; f28; ) CONNECTIVE SOURCE: tanru; } + FORMULA f29 IS ∧ { OPERANDS IN ORDER ( f9; f28; ) } FORMULA f34 IS ATOM { PREDICATION: p33; BOUND EVENTUALITIES { r6; } } REFERENCE r1 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: SPEAKER; } REFERENCE r2 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: AUDIENCE; } diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/b40.frozen.json b/crates/jbotci-semantics/tests/phaseb_corpus/b40.frozen.json index c1f0304625..14d2f38f81 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/b40.frozen.json +++ b/crates/jbotci-semantics/tests/phaseb_corpus/b40.frozen.json @@ -92,7 +92,6 @@ }, "predication:18": { "type": "predication", - "relation": "tanru", "tanruLink": { "head": "predication:9", "modifier": "relation:17", @@ -192,7 +191,9 @@ "formula:19" ], "connector": { - "source": "tanru", + "source": { + "kind": "implicitJuxtaposition" + }, "locus": "description" }, "source": { diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/b40.smusni-prov.txt b/crates/jbotci-semantics/tests/phaseb_corpus/b40.smusni-prov.txt index 21bdf900af..1b83c2c86e 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/b40.smusni-prov.txt +++ b/crates/jbotci-semantics/tests/phaseb_corpus/b40.smusni-prov.txt @@ -35,22 +35,7 @@ SEMANTIC DOCUMENT document_1 { TEXT: "cmalu mlatu"; CONSTRUCT: "restrictive-tanru-formula"; } - PREDICATION p18 { - RELATION: tanru; - ARGS ( - [1]: REFERENCE DENOTATION r7; - [2]: REFERENCE DENOTATION l17; - ) - MODE: RESTRICTIVE; - TANRU LINK - HEAD: p9; - MODIFIER: l17; - RELATION LABEL: cmalu-mlatu; - PROVENANCE - BYTE SPAN: 12..23; - TEXT: "cmalu mlatu"; - CONSTRUCT: "restrictive-tanru-formula"; - } + PREDICATION p18 { ARGS ( [1]: REFERENCE DENOTATION r7; [2]: REFERENCE DENOTATION l17; ) MODE: RESTRICTIVE; TANRU LINK { HEAD: p9; MODIFIER: l17; RELATION LABEL: cmalu-mlatu; } PROVENANCE { BYTE SPAN: 12..23; TEXT: "cmalu mlatu"; CONSTRUCT: "restrictive-tanru-formula"; } } PREDICATION p21 { RELATION: nelci; EVENTUALITY: r6; @@ -67,7 +52,7 @@ SEMANTIC DOCUMENT document_1 { FORMULA f10 IS ATOM { PREDICATION: p9; PROVENANCE { BYTE SPAN: 12..23; TEXT: "cmalu mlatu"; CONSTRUCT: "restrictive-predication"; } } FORMULA f16 IS ATOM { PREDICATION: p15; BOUND EVENTUALITIES { r12; } PROVENANCE { BYTE SPAN: 12..23; TEXT: "cmalu mlatu"; CONSTRUCT: "restrictive-tanru-formula"; } } FORMULA f19 IS ATOM { PREDICATION: p18; PROVENANCE { BYTE SPAN: 12..23; TEXT: "cmalu mlatu"; CONSTRUCT: "restrictive-tanru-formula"; } } - FORMULA f20 IS ∧ { OPERANDS IN ORDER ( f10; f19; ) CONNECTIVE SOURCE: tanru; PROVENANCE { BYTE SPAN: 12..23; TEXT: "cmalu mlatu"; CONSTRUCT: "restrictive-tanru-formula"; } } + FORMULA f20 IS ∧ { OPERANDS IN ORDER ( f10; f19; ) CONNECTIVE SOURCE: IMPLICIT JUXTAPOSITION; LOCUS: DESCRIPTION; PROVENANCE { BYTE SPAN: 12..23; TEXT: "cmalu mlatu"; CONSTRUCT: "restrictive-tanru-formula"; } } FORMULA f22 IS ATOM { PREDICATION: p21; BOUND EVENTUALITIES { r6; } PROVENANCE { BYTE SPAN: 0..23; TEXT: "mi nelci lo cmalu mlatu"; CONSTRUCT: "bridi-formula"; } } REFERENCE r1 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: SPEAKER; } REFERENCE r2 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: AUDIENCE; } diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/b40.smusni.txt b/crates/jbotci-semantics/tests/phaseb_corpus/b40.smusni.txt index 3caeed1c96..05473066c7 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/b40.smusni.txt +++ b/crates/jbotci-semantics/tests/phaseb_corpus/b40.smusni.txt @@ -18,12 +18,12 @@ SEMANTIC DOCUMENT document_1 { PARAMETER x11 { SORT: Entity; ROLE: PROPERTY SLOT; INTRODUCED BY: ce'u; } PREDICATION p9 { RELATION: mlatu; ARGS ( [1]: REFERENCE DENOTATION r7; [2]: REFERENCE DENOTATION r8; ) MODE: RESTRICTIVE; } PREDICATION p15 { RELATION: cmalu; EVENTUALITY: r12; ARGS ( [1]: VALUE x11; [2]: REFERENCE DENOTATION r13; [3]: REFERENCE DENOTATION r14; ) MODE: RESTRICTIVE; } - PREDICATION p18 { RELATION: tanru; ARGS ( [1]: REFERENCE DENOTATION r7; [2]: REFERENCE DENOTATION l17; ) MODE: RESTRICTIVE; TANRU LINK { HEAD: p9; MODIFIER: l17; RELATION LABEL: cmalu-mlatu; } } + PREDICATION p18 { ARGS ( [1]: REFERENCE DENOTATION r7; [2]: REFERENCE DENOTATION l17; ) MODE: RESTRICTIVE; TANRU LINK { HEAD: p9; MODIFIER: l17; RELATION LABEL: cmalu-mlatu; } } PREDICATION p21 { RELATION: nelci; EVENTUALITY: r6; ARGS ( [1]: REFERENCE DENOTATION r1; [2]: REFERENCE DENOTATION r7; ) MODE: ASSERTED; } FORMULA f10 IS ATOM { PREDICATION: p9; } FORMULA f16 IS ATOM { PREDICATION: p15; BOUND EVENTUALITIES { r12; } } FORMULA f19 IS ATOM { PREDICATION: p18; } - FORMULA f20 IS ∧ { OPERANDS IN ORDER ( f10; f19; ) CONNECTIVE SOURCE: tanru; } + FORMULA f20 IS ∧ { OPERANDS IN ORDER ( f10; f19; ) } FORMULA f22 IS ATOM { PREDICATION: p21; BOUND EVENTUALITIES { r6; } } REFERENCE r1 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: SPEAKER; } REFERENCE r2 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: AUDIENCE; } diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/nd1.frozen.json b/crates/jbotci-semantics/tests/phaseb_corpus/nd1.frozen.json index 04c97cb0fc..07e05d5508 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/nd1.frozen.json +++ b/crates/jbotci-semantics/tests/phaseb_corpus/nd1.frozen.json @@ -115,7 +115,6 @@ }, "predication:20": { "type": "predication", - "relation": "tanru", "tanruLink": { "head": "predication:13", "modifier": "relation:19", @@ -274,7 +273,6 @@ }, "predication:47": { "type": "predication", - "relation": "tanru", "tanruLink": { "head": "predication:40", "modifier": "relation:46", @@ -420,7 +418,9 @@ "formula:21" ], "connector": { - "source": "tanru", + "source": { + "kind": "implicitJuxtaposition" + }, "locus": "description" }, "source": { @@ -524,7 +524,9 @@ "formula:48" ], "connector": { - "source": "tanru", + "source": { + "kind": "implicitJuxtaposition" + }, "locus": "description" }, "source": { diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/nd1.smusni-prov.txt b/crates/jbotci-semantics/tests/phaseb_corpus/nd1.smusni-prov.txt index d195cdedf0..3f9e8d7f06 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/nd1.smusni-prov.txt +++ b/crates/jbotci-semantics/tests/phaseb_corpus/nd1.smusni-prov.txt @@ -35,22 +35,7 @@ SEMANTIC DOCUMENT document_1 { TEXT: "xunre creka"; CONSTRUCT: "restrictive-tanru-formula"; } - PREDICATION p20 { - RELATION: tanru; - ARGS ( - [1]: REFERENCE DENOTATION r11; - [2]: REFERENCE DENOTATION l19; - ) - MODE: RESTRICTIVE; - TANRU LINK - HEAD: p13; - MODIFIER: l19; - RELATION LABEL: xunre-creka; - PROVENANCE - BYTE SPAN: 22..33; - TEXT: "xunre creka"; - CONSTRUCT: "restrictive-tanru-formula"; - } + PREDICATION p20 { ARGS ( [1]: REFERENCE DENOTATION r11; [2]: REFERENCE DENOTATION l19; ) MODE: RESTRICTIVE; TANRU LINK { HEAD: p13; MODIFIER: l19; RELATION LABEL: xunre-creka; } PROVENANCE { BYTE SPAN: 22..33; TEXT: "xunre creka"; CONSTRUCT: "restrictive-tanru-formula"; } } PREDICATION p25 { RELATION: dasni; EVENTUALITY: r10; @@ -80,22 +65,7 @@ SEMANTIC DOCUMENT document_1 { TEXT: "blanu creka"; CONSTRUCT: "restrictive-tanru-formula"; } - PREDICATION p47 { - RELATION: tanru; - ARGS ( - [1]: REFERENCE DENOTATION r38; - [2]: REFERENCE DENOTATION l46; - ) - MODE: RESTRICTIVE; - TANRU LINK - HEAD: p40; - MODIFIER: l46; - RELATION LABEL: blanu-creka; - PROVENANCE - BYTE SPAN: 74..85; - TEXT: "blanu creka"; - CONSTRUCT: "restrictive-tanru-formula"; - } + PREDICATION p47 { ARGS ( [1]: REFERENCE DENOTATION r38; [2]: REFERENCE DENOTATION l46; ) MODE: RESTRICTIVE; TANRU LINK { HEAD: p40; MODIFIER: l46; RELATION LABEL: blanu-creka; } PROVENANCE { BYTE SPAN: 74..85; TEXT: "blanu creka"; CONSTRUCT: "restrictive-tanru-formula"; } } PREDICATION p52 { RELATION: dasni; EVENTUALITY: r37; @@ -128,14 +98,14 @@ SEMANTIC DOCUMENT document_1 { FORMULA f14 IS ATOM { PREDICATION: p13; PROVENANCE { BYTE SPAN: 22..33; TEXT: "xunre creka"; CONSTRUCT: "restrictive-predication"; } } FORMULA f18 IS ATOM { PREDICATION: p17; BOUND EVENTUALITIES { r16; } PROVENANCE { BYTE SPAN: 22..33; TEXT: "xunre creka"; CONSTRUCT: "restrictive-tanru-formula"; } } FORMULA f21 IS ATOM { PREDICATION: p20; PROVENANCE { BYTE SPAN: 22..33; TEXT: "xunre creka"; CONSTRUCT: "restrictive-tanru-formula"; } } - FORMULA f22 IS ∧ { OPERANDS IN ORDER ( f14; f21; ) CONNECTIVE SOURCE: tanru; PROVENANCE { BYTE SPAN: 22..33; TEXT: "xunre creka"; CONSTRUCT: "restrictive-tanru-formula"; } } + FORMULA f22 IS ∧ { OPERANDS IN ORDER ( f14; f21; ) CONNECTIVE SOURCE: IMPLICIT JUXTAPOSITION; LOCUS: DESCRIPTION; PROVENANCE { BYTE SPAN: 22..33; TEXT: "xunre creka"; CONSTRUCT: "restrictive-tanru-formula"; } } FORMULA f26 IS ATOM { PREDICATION: p25; BOUND EVENTUALITIES { r10; } PROVENANCE { BYTE SPAN: 13..33; TEXT: "dasni lo xunre creka"; CONSTRUCT: "bridi-formula"; } } FORMULA f33 IS ATOM { PREDICATION: p32; PROVENANCE { BYTE SPAN: 46..51; TEXT: "cukta"; CONSTRUCT: "restrictive-formula"; } } FORMULA f36 IS ATOM { PREDICATION: p35; PROVENANCE { BYTE SPAN: 55..60; TEXT: "nanmu"; CONSTRUCT: "restrictive-formula"; } } FORMULA f41 IS ATOM { PREDICATION: p40; PROVENANCE { BYTE SPAN: 74..85; TEXT: "blanu creka"; CONSTRUCT: "restrictive-predication"; } } FORMULA f45 IS ATOM { PREDICATION: p44; BOUND EVENTUALITIES { r43; } PROVENANCE { BYTE SPAN: 74..85; TEXT: "blanu creka"; CONSTRUCT: "restrictive-tanru-formula"; } } FORMULA f48 IS ATOM { PREDICATION: p47; PROVENANCE { BYTE SPAN: 74..85; TEXT: "blanu creka"; CONSTRUCT: "restrictive-tanru-formula"; } } - FORMULA f49 IS ∧ { OPERANDS IN ORDER ( f41; f48; ) CONNECTIVE SOURCE: tanru; PROVENANCE { BYTE SPAN: 74..85; TEXT: "blanu creka"; CONSTRUCT: "restrictive-tanru-formula"; } } + FORMULA f49 IS ∧ { OPERANDS IN ORDER ( f41; f48; ) CONNECTIVE SOURCE: IMPLICIT JUXTAPOSITION; LOCUS: DESCRIPTION; PROVENANCE { BYTE SPAN: 74..85; TEXT: "blanu creka"; CONSTRUCT: "restrictive-tanru-formula"; } } FORMULA f53 IS ATOM { PREDICATION: p52; BOUND EVENTUALITIES { r37; } PROVENANCE { BYTE SPAN: 65..85; TEXT: "dasni lo blanu creka"; CONSTRUCT: "bridi-formula"; } } FORMULA f55 IS ATOM { PREDICATION: p54; BOUND EVENTUALITIES { r6; } PROVENANCE { BYTE SPAN: 0..85; TEXT: "lo nanmu poi dasni lo xunre creka cu dunda lo cukta lo nanmu poi dasni lo blanu creka"; CONSTRUCT: "bridi-formula"; } } REFERENCE r1 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: SPEAKER; } diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/nd1.smusni.txt b/crates/jbotci-semantics/tests/phaseb_corpus/nd1.smusni.txt index c258fce9d2..19a9d96a9d 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/nd1.smusni.txt +++ b/crates/jbotci-semantics/tests/phaseb_corpus/nd1.smusni.txt @@ -20,27 +20,27 @@ SEMANTIC DOCUMENT document_1 { PREDICATION p8 { RELATION: nanmu; ARGS ( [1]: REFERENCE DENOTATION r7; ) MODE: RESTRICTIVE; } PREDICATION p13 { RELATION: creka; ARGS ( [1]: REFERENCE DENOTATION r11; [2]: REFERENCE DENOTATION r12; ) MODE: RESTRICTIVE; } PREDICATION p17 { RELATION: xunre; EVENTUALITY: r16; ARGS ( [1]: VALUE x15; ) MODE: RESTRICTIVE; } - PREDICATION p20 { RELATION: tanru; ARGS ( [1]: REFERENCE DENOTATION r11; [2]: REFERENCE DENOTATION l19; ) MODE: RESTRICTIVE; TANRU LINK { HEAD: p13; MODIFIER: l19; RELATION LABEL: xunre-creka; } } + PREDICATION p20 { ARGS ( [1]: REFERENCE DENOTATION r11; [2]: REFERENCE DENOTATION l19; ) MODE: RESTRICTIVE; TANRU LINK { HEAD: p13; MODIFIER: l19; RELATION LABEL: xunre-creka; } } PREDICATION p25 { RELATION: dasni; EVENTUALITY: r10; ARGS ( [1]: REFERENCE DENOTATION r7; [2]: REFERENCE DENOTATION r11; [3]: REFERENCE DENOTATION r24; ) MODE: RESTRICTIVE; } PREDICATION p32 { RELATION: cukta; ARGS ( [1]: REFERENCE DENOTATION r27; [2]: REFERENCE DENOTATION r28; [3]: REFERENCE DENOTATION r29; [4]: REFERENCE DENOTATION r30; [5]: REFERENCE DENOTATION r31; ) MODE: RESTRICTIVE; } PREDICATION p35 { RELATION: nanmu; ARGS ( [1]: REFERENCE DENOTATION r34; ) MODE: RESTRICTIVE; } PREDICATION p40 { RELATION: creka; ARGS ( [1]: REFERENCE DENOTATION r38; [2]: REFERENCE DENOTATION r39; ) MODE: RESTRICTIVE; } PREDICATION p44 { RELATION: blanu; EVENTUALITY: r43; ARGS ( [1]: VALUE x42; ) MODE: RESTRICTIVE; } - PREDICATION p47 { RELATION: tanru; ARGS ( [1]: REFERENCE DENOTATION r38; [2]: REFERENCE DENOTATION l46; ) MODE: RESTRICTIVE; TANRU LINK { HEAD: p40; MODIFIER: l46; RELATION LABEL: blanu-creka; } } + PREDICATION p47 { ARGS ( [1]: REFERENCE DENOTATION r38; [2]: REFERENCE DENOTATION l46; ) MODE: RESTRICTIVE; TANRU LINK { HEAD: p40; MODIFIER: l46; RELATION LABEL: blanu-creka; } } PREDICATION p52 { RELATION: dasni; EVENTUALITY: r37; ARGS ( [1]: REFERENCE DENOTATION r34; [2]: REFERENCE DENOTATION r38; [3]: REFERENCE DENOTATION r51; ) MODE: RESTRICTIVE; } PREDICATION p54 { RELATION: dunda; EVENTUALITY: r6; ARGS ( [1]: REFERENCE DENOTATION r7; [2]: REFERENCE DENOTATION r27; [3]: REFERENCE DENOTATION r34; ) MODE: ASSERTED; } FORMULA f9 IS ATOM { PREDICATION: p8; } FORMULA f14 IS ATOM { PREDICATION: p13; } FORMULA f18 IS ATOM { PREDICATION: p17; BOUND EVENTUALITIES { r16; } } FORMULA f21 IS ATOM { PREDICATION: p20; } - FORMULA f22 IS ∧ { OPERANDS IN ORDER ( f14; f21; ) CONNECTIVE SOURCE: tanru; } + FORMULA f22 IS ∧ { OPERANDS IN ORDER ( f14; f21; ) } FORMULA f26 IS ATOM { PREDICATION: p25; BOUND EVENTUALITIES { r10; } } FORMULA f33 IS ATOM { PREDICATION: p32; } FORMULA f36 IS ATOM { PREDICATION: p35; } FORMULA f41 IS ATOM { PREDICATION: p40; } FORMULA f45 IS ATOM { PREDICATION: p44; BOUND EVENTUALITIES { r43; } } FORMULA f48 IS ATOM { PREDICATION: p47; } - FORMULA f49 IS ∧ { OPERANDS IN ORDER ( f41; f48; ) CONNECTIVE SOURCE: tanru; } + FORMULA f49 IS ∧ { OPERANDS IN ORDER ( f41; f48; ) } FORMULA f53 IS ATOM { PREDICATION: p52; BOUND EVENTUALITIES { r37; } } FORMULA f55 IS ATOM { PREDICATION: p54; BOUND EVENTUALITIES { r6; } } REFERENCE r1 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: SPEAKER; } diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/paragraph-narrative.frozen.json b/crates/jbotci-semantics/tests/phaseb_corpus/paragraph-narrative.frozen.json index d18b3e4e52..0030ca1510 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/paragraph-narrative.frozen.json +++ b/crates/jbotci-semantics/tests/phaseb_corpus/paragraph-narrative.frozen.json @@ -763,7 +763,7 @@ "assertionEffect": "none", "experiencer": "entity:1", "target": "formula:78", - "targetFocus": "bridi", + "targetFocus": "clause", "anchor": "utterance:8", "source": { "span": { diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/paragraph-narrative.smusni-prov.txt b/crates/jbotci-semantics/tests/phaseb_corpus/paragraph-narrative.smusni-prov.txt index 67268fac6f..5f018c04f2 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/paragraph-narrative.smusni-prov.txt +++ b/crates/jbotci-semantics/tests/phaseb_corpus/paragraph-narrative.smusni-prov.txt @@ -198,7 +198,7 @@ SEMANTIC DOCUMENT document_1 { ASSERTION EFFECT: NONE; EXPERIENCER: r1; TARGET: f78; - TARGET FOCUS: BRIDI; + TARGET FOCUS: CLAUSE; ANCHOR: u8; PROVENANCE BYTE SPAN: 113..117; diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/paragraph-narrative.smusni.txt b/crates/jbotci-semantics/tests/phaseb_corpus/paragraph-narrative.smusni.txt index 78672936c4..7c488c84fb 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/paragraph-narrative.smusni.txt +++ b/crates/jbotci-semantics/tests/phaseb_corpus/paragraph-narrative.smusni.txt @@ -85,7 +85,7 @@ SEMANTIC DOCUMENT document_1 { ASSERTION EFFECT: NONE; EXPERIENCER: r1; TARGET: f78; - TARGET FOCUS: BRIDI; + TARGET FOCUS: CLAUSE; ANCHOR: u8; } REFERENCE r1 { DENOTES VALUES OF SORT Entity; BINDING: INDEXICAL; INDEXICAL: SPEAKER; } diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/question-connective.frozen.json b/crates/jbotci-semantics/tests/phaseb_corpus/question-connective.frozen.json index dfbedc2891..09fbc109da 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/question-connective.frozen.json +++ b/crates/jbotci-semantics/tests/phaseb_corpus/question-connective.frozen.json @@ -130,7 +130,10 @@ "formula:15" ], "connector": { - "source": "ji", + "source": { + "kind": "surfaceWord", + "word": "ji" + }, "locus": "term", "parameter": "parameter:16" }, diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/question-connective.smusni-prov.txt b/crates/jbotci-semantics/tests/phaseb_corpus/question-connective.smusni-prov.txt index 821afe63ff..939db8f5f6 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/question-connective.smusni-prov.txt +++ b/crates/jbotci-semantics/tests/phaseb_corpus/question-connective.smusni-prov.txt @@ -46,7 +46,19 @@ SEMANTIC DOCUMENT document_1 { } FORMULA f10 IS ATOM { PREDICATION: p9; BOUND EVENTUALITIES { r7; } PROVENANCE { BYTE SPAN: 0..18; TEXT: "pu ko'a ji ba ko'e"; CONSTRUCT: "term-connection-formula"; } } FORMULA f15 IS ATOM { PREDICATION: p14; BOUND EVENTUALITIES { r12; } PROVENANCE { BYTE SPAN: 0..18; TEXT: "pu ko'a ji ba ko'e"; CONSTRUCT: "term-connection-formula"; } } - FORMULA f17 IS CONNECTIVE QUESTION { OPERANDS IN ORDER ( f10; f15; ) CONNECTIVE SOURCE: ji; NOT COMPUTED: connector-parameter; PROVENANCE { BYTE SPAN: 0..18; TEXT: "pu ko'a ji ba ko'e"; CONSTRUCT: "term-connection-formula"; } } + FORMULA f17 IS CONNECTIVE QUESTION { + OPERANDS IN ORDER ( + f10; + f15; + ) + CONNECTIVE SOURCE: ji; + LOCUS: TERM; + NOT COMPUTED: connector-parameter; + PROVENANCE + BYTE SPAN: 0..18; + TEXT: "pu ko'a ji ba ko'e"; + CONSTRUCT: "term-connection-formula"; + } QUESTION qu18 { BODY: f17; KIND: CONNECTIVE; diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/question-connective.smusni.txt b/crates/jbotci-semantics/tests/phaseb_corpus/question-connective.smusni.txt index 7187851e0b..d800eb0737 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/question-connective.smusni.txt +++ b/crates/jbotci-semantics/tests/phaseb_corpus/question-connective.smusni.txt @@ -20,7 +20,7 @@ SEMANTIC DOCUMENT document_1 { PREDICATION p14 { RELATION: broda; EVENTUALITY: r12; ARGS ( [1]: REFERENCE DENOTATION r11; ) MODE: ASSERTED; } FORMULA f10 IS ATOM { PREDICATION: p9; BOUND EVENTUALITIES { r7; } } FORMULA f15 IS ATOM { PREDICATION: p14; BOUND EVENTUALITIES { r12; } } - FORMULA f17 IS CONNECTIVE QUESTION { OPERANDS IN ORDER ( f10; f15; ) CONNECTIVE SOURCE: ji; NOT COMPUTED: connector-parameter; } + FORMULA f17 IS CONNECTIVE QUESTION { OPERANDS IN ORDER ( f10; f15; ) NOT COMPUTED: connector-parameter; } QUESTION qu18 { BODY: f17; KIND: CONNECTIVE; diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/question-multiple-domains.frozen.json b/crates/jbotci-semantics/tests/phaseb_corpus/question-multiple-domains.frozen.json index 231f248188..4529aa63e8 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/question-multiple-domains.frozen.json +++ b/crates/jbotci-semantics/tests/phaseb_corpus/question-multiple-domains.frozen.json @@ -148,7 +148,7 @@ "assertionEffect": "none", "experiencer": "entity:1", "target": "formula:16", - "targetFocus": "selbri", + "targetFocus": "predicate", "anchor": "utterance:5", "source": { "span": { @@ -167,7 +167,7 @@ "assertionEffect": "none", "experiencer": "entity:1", "target": "formula:16", - "targetFocus": "bridi", + "targetFocus": "clause", "anchor": "utterance:5", "source": { "span": { diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/question-multiple-domains.smusni-prov.txt b/crates/jbotci-semantics/tests/phaseb_corpus/question-multiple-domains.smusni-prov.txt index d8ef16bd6a..54594631ec 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/question-multiple-domains.smusni-prov.txt +++ b/crates/jbotci-semantics/tests/phaseb_corpus/question-multiple-domains.smusni-prov.txt @@ -58,7 +58,7 @@ SEMANTIC DOCUMENT document_1 { ASSERTION EFFECT: NONE; EXPERIENCER: r1; TARGET: f16; - TARGET FOCUS: SELBRI; + TARGET FOCUS: PREDICATE; ANCHOR: u5; PROVENANCE BYTE SPAN: 13..15; @@ -72,7 +72,7 @@ SEMANTIC DOCUMENT document_1 { ASSERTION EFFECT: NONE; EXPERIENCER: r1; TARGET: f16; - TARGET FOCUS: BRIDI; + TARGET FOCUS: CLAUSE; ANCHOR: u5; PROVENANCE BYTE SPAN: 0..3; diff --git a/crates/jbotci-semantics/tests/phaseb_corpus/question-multiple-domains.smusni.txt b/crates/jbotci-semantics/tests/phaseb_corpus/question-multiple-domains.smusni.txt index 0926a0fd3b..c3337c8649 100644 --- a/crates/jbotci-semantics/tests/phaseb_corpus/question-multiple-domains.smusni.txt +++ b/crates/jbotci-semantics/tests/phaseb_corpus/question-multiple-domains.smusni.txt @@ -34,7 +34,7 @@ SEMANTIC DOCUMENT document_1 { ASSERTION EFFECT: NONE; EXPERIENCER: r1; TARGET: f16; - TARGET FOCUS: SELBRI; + TARGET FOCUS: PREDICATE; ANCHOR: u5; } DISPLAYED CONTENT d20 { @@ -44,7 +44,7 @@ SEMANTIC DOCUMENT document_1 { ASSERTION EFFECT: NONE; EXPERIENCER: r1; TARGET: f16; - TARGET FOCUS: BRIDI; + TARGET FOCUS: CLAUSE; ANCHOR: u5; } QUANTITY q15 { FORM: EXACT; VALUE TEXT: xo; NOT COMPUTED: quantity-value-shape(questionParameters); SCALE: COUNT; } diff --git a/crates/jbotci-semantics/tests/smusni_parity.rs b/crates/jbotci-semantics/tests/smusni_parity.rs index 5a3cf4fac6..b87b93c8c7 100644 --- a/crates/jbotci-semantics/tests/smusni_parity.rs +++ b/crates/jbotci-semantics/tests/smusni_parity.rs @@ -1,25 +1,27 @@ -//! Byte-parity of this build's `smusni` notation renderer against the frozen -//! Python oracle (Phase-B step 4; research repo `FREEZE-PHASE-B.md`). +//! Byte-stability of this build's `smusni` notation renderer against the +//! frozen fixture set. //! -//! For each of the 48 frozen corpus documents, the vendored `.smusni.txt` -//! is the exact output of `python3 render_v5.py .frozen.json --profile -//! lean3` using the renderer from oracle commit -//! `c6004a1bc4dda0c9d27cef188e21402d64f36d30` (jbotci#652), including the -//! jbotci#682 re-freeze of the simple `fi'o se pilno` witness. The corpus -//! comprises the original 37 documents, the two -//! jbotci#620 witnesses, and five new -//! discriminant-verified question witnesses, plus four tagged-argument -//! witnesses. `lean3` is the research -//! repo's historical profile name for the product's `smusni` notation. This test -//! re-derives each graph -//! from `.lojban` with *this* build (the same pipeline the completeness -//! tests use — never reading `.frozen.json`), renders it with the `smusni` -//! profile, and asserts a byte-for-byte match. +//! HISTORY: the fixtures began as exact bytes of the independent Python oracle +//! (`render_v5.py`, Phase-B; `lean3` is the research repo's historical profile +//! name for the product's `smusni` notation). jbotci#719 (owner ruling +//! 2026-08-01) deliberately departed from the oracle: connector surface words +//! and loci became provenance-class (CONNECTIVE SOURCE/LOCUS leave the default +//! output; LOCUS now renders in English under the provenance opt-in), truth +//! tables render only when the operator does not already determine them, the +//! fake `RELATION: tanru` name was dropped, the `WAIVED { }` block left +//! model-facing output, and TARGET FOCUS values were renamed to English. +//! The fixtures were regenerated from the product pipeline +//! (`examples/regen_goldens.rs smusni`) — byte-parity with the research oracle +//! is SUSPENDED at this point (see `phaseb_corpus/PROVENANCE.md`). //! -//! Because every corpus graph this build produces is byte-identical (in meaning) -//! to the frozen graph the oracle consumed (verified separately, and pinned by -//! the completeness `frozen_divergence_report`), a divergence here is a renderer -//! port defect, not semantic drift — see the PR body's divergence analysis. +//! What this test still proves: this build's `render_smusni` output for each +//! re-derived corpus graph is byte-identical to the regenerated fixture. The +//! migration's correctness is NOT pinned by this test; it is pinned by +//! `scripts/verify_issue_719_output_migration.py`, which proves the delta from +//! the oracle-era fixtures at the PR base is exactly the mechanical #719 +//! transformation, and by the re-derived graphs being byte-identical to the +//! frozen graphs (the completeness `frozen_divergence_report`). A divergence +//! HERE is a renderer regression against the post-#719 baseline. #[allow(unused_imports)] use bityzba::{ensures, requires}; @@ -96,8 +98,8 @@ fn first_diff(expected: &str, actual: &str) -> Option<(usize, String, String)> { None } -/// Assert byte parity between this build's `render_smusni` and the vendored -/// oracle fixtures with `suffix`, under the given `config`. +/// Assert byte equality between this build's `render_smusni` and the vendored +/// post-#719 fixtures with `suffix`, under the given `config`. #[requires(!suffix.is_empty())] #[ensures(true)] fn assert_parity(suffix: &str, config: SmusniConfig) { @@ -118,15 +120,15 @@ fn assert_parity(suffix: &str, config: SmusniConfig) { } assert!( mismatches.is_empty(), - "{}/{} corpus documents diverge from the frozen smusni oracle ({suffix}):\n{}", + "{}/{} corpus documents diverge from the post-#719 smusni fixtures ({suffix}):\n{}", mismatches.len(), CORPUS_DOCS.len(), mismatches.join("\n") ); } -/// The default `smusni` profile (provenance off) byte-matches the oracle on all -/// 48 frozen corpus documents. +/// The default `smusni` profile (provenance off) byte-matches the post-#719 +/// fixtures on all 48 frozen corpus documents. #[test] #[requires(true)] #[ensures(true)] @@ -134,8 +136,8 @@ fn smusni_byte_parity_over_frozen_corpus() { assert_parity("smusni.txt", SmusniConfig { provenance: false }); } -/// The provenance opt-in (`--provenance`) byte-matches the oracle's -/// `--profile lean3 --provenance` output on all 48 frozen corpus documents. +/// The provenance opt-in (`--provenance`) byte-matches the post-#719 +/// fixtures on all 48 frozen corpus documents. #[test] #[requires(true)] #[ensures(true)] @@ -184,40 +186,39 @@ fn preexisting_fixture_bytes_are_unchanged() { .filter(|doc| !doc.starts_with("modal-")); assert_eq!( aggregate_fixture_hash_for(preexisting.clone(), "smusni.txt"), - "ba79402c74d7160e761c034759979215582bd86fc31dac00160d9a734673f254" + "ebd0f375a8d8c40401804a5346c00a1167ccc6d736c823950a20aa68058e75dc" ); assert_eq!( aggregate_fixture_hash_for(preexisting, "smusni-prov.txt"), - "e3d1933cefd5915bcea4ed1ba996704b47badb7210de5f535d2b19ae3df54b88" + "fd133472ba71fbbe6c6dd92009286232d6adbbd7824ff7a691b47a32968ca9e0" ); } -/// Should-fix 7 (round-1 review, Codex 4): pin the aggregate hash of BOTH -/// vendored fixture sets so the renderer-expected and provenance fixtures cannot -/// silently drift together (e.g. a regeneration that changes both while a stale -/// oracle is in use). If a deliberate oracle change lands, this pin and the -/// `FREEZE-PHASE-B.md` amendment are updated in lockstep. +/// Pin the aggregate hash of BOTH vendored fixture sets so the +/// renderer-expected and provenance fixtures cannot silently drift together. +/// Updated at the jbotci#719 regeneration (see `phaseb_corpus/PROVENANCE.md`); +/// the post-#719 hashes are no longer oracle-derived. #[test] #[requires(true)] #[ensures(true)] fn frozen_fixture_aggregate_hashes_are_pinned() { assert_eq!( aggregate_fixture_hash("smusni.txt"), - "2fe83e771edd04c23f51f5c5d41e7aafff551670e624364517cf58acb49ddce8", - "smusni.txt fixture set drifted from the pinned oracle output" + "f0a99c7a603f3730f31277cee8db1100a897089cb87c39b521e9ef2d6b2494ea", + "smusni.txt fixture set drifted from the post-#719 pinned output" ); assert_eq!( aggregate_fixture_hash("smusni-prov.txt"), - "897cc4ee3a06011d4d5f665dbe8411389ada9f005f577abf68afc0012af3e9e7", - "smusni-prov.txt fixture set drifted from the pinned oracle output" + "b356fd871b45285763a874dc9f0c07d655501bdc390459f05890e28a965924d3", + "smusni-prov.txt fixture set drifted from the post-#719 pinned output" ); } /// Blocker-3 regression (round-1 review, kimi 5): a `zoi` quotation whose text /// carries notation metacharacters (`{ ( ; } )`) renders them safely inside a -/// quoted value and stays byte-identical to the oracle. This is a dedicated -/// hostile-witness fixture, deliberately *outside* [`CORPUS_DOCS`] so it does -/// not perturb the frozen corpus hash. (The dense-flatten path that +/// quoted value and stays byte-identical to the post-#719 fixture. This is a +/// dedicated hostile-witness fixture, deliberately *outside* [`CORPUS_DOCS`] so +/// it does not perturb the frozen corpus hash. (The dense-flatten path that /// the hardening protects is exercised directly in `writer.rs`'s unit tests.) #[test] #[requires(true)] @@ -234,7 +235,7 @@ fn smusni_hostile_witness_regression() { assert_eq!( expected, actual, - "{doc} ({suffix}) diverges from the oracle at {:?}", + "{doc} ({suffix}) diverges from the post-#719 fixtures at {:?}", first_diff(&expected, &actual) ); // The metacharacters survive inside a quoted value, un-split. @@ -266,7 +267,7 @@ fn smusni_relation_question_indirect_regression() { assert_eq!( expected, actual, - "{doc} ({suffix}) diverges from the oracle at {:?}", + "{doc} ({suffix}) diverges from the post-#719 fixtures at {:?}", first_diff(&expected, &actual) ); // Both relation shapes render: the bound relation-question parameter as @@ -281,8 +282,9 @@ fn smusni_relation_question_indirect_regression() { /// jbotci#622 regression: the corpus witnesses collectively exercise every /// currently builder-reachable question kind, both modes, homogeneous and typed -/// slots, and the optional focus/presupposed-answer fields. Byte parity above is -/// the oracle proof; these assertions make the intended discriminants explicit. +/// slots, and the optional focus/presupposed-answer fields. Byte equality above +/// is the post-#719 fixture proof; these assertions make the intended +/// discriminants explicit. #[test] #[requires(true)] #[ensures(true)] diff --git a/crates/jbotci-semantics/tests/xml_corpus/PROVENANCE.md b/crates/jbotci-semantics/tests/xml_corpus/PROVENANCE.md index 224ab2c401..3aed37f373 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/PROVENANCE.md +++ b/crates/jbotci-semantics/tests/xml_corpus/PROVENANCE.md @@ -87,8 +87,31 @@ rendered-via-card (the nonce word's WORD card carries the decomposition), with no omission entries. This frozen 48-document corpus is rendered without cards, so it deliberately retains the interim body `RELATION-METADATA` preservation form: with no card section to carry the decomposition, the omissions/waiver -discipline does not allow silently dropping it. `PREDICATE="tanru"` remains -frozen JSON data rather than structural vocabulary. +discipline does not allow silently dropping it. + +jbotci#719 (owner ruling 2026-08-01) reworked the document surface in one +migration pass, deliberately diverging from the pinned research prototype: +the structured `` block became a single teaching +comment before the root element; the `` block left model-facing +output (the omissions API is unchanged and tests reconcile against it); the +`` element left default output (connector surface words and loci +are provenance-class and join a new closed `ConnectorProvenance` waiver +family; TRUTH-TABLE=/PARAMETER= survive on the connective parent when not +derivable); `Connector.source`/`Connector.locus` became typed enums (a +surface word vs an implicit juxtaposition; English locus names), killing +the `SOURCE-WORD="tanru"` sentinel and the `LOCUS="SELBRI"` jargon; and +tanru predications project as one PREDICATION with a KIND-COMPOSITION +relation expression in the relation slot (the fake `PREDICATE="tanru"` +relation name is gone from both the notation and the frozen JSON; the loud +head-and-link form remains as the guarded fallback). The frozen JSON graphs +were migrated mechanically by `scripts/migrate_issue_719_json.py` (typed +connector source, English locus, fake relation dropped — every file +rebuilds byte-exactly from its source text through the product pipeline), +and the goldens were regenerated with `examples/regen_goldens.rs` under the +mechanical-diff proof of `scripts/verify_issue_719_output_migration.py`; +the tanru regions' semantic preservation is enforced by the re-expansion +equivalence acceptance test in `notation::relation_expression`. + The prototype's pre-existing rejection of the Phase-B multiple-domain question remains outside the 48-document parity contract. The paired research README at the pinned commit records these follow-ups in full. @@ -109,16 +132,17 @@ prototype outputs, and the four focused XML files compare byte-for-byte with their paired research goldens after the intentional `DOC=` substitution. All 48 product JSON files also compare byte-for-byte with the pinned research sources. Product tests independently pin ordered name/content hashes -`69ea08a65aba19049f65070b9eb045361834ddfbd2773da972c047be325381b3` +`6f3d951a76b0b363ff3fc8a0763a0dbb34fe7fb16a23fccbe86a32fecbbfdfe7` for JSON and -`8054b126268d07532363b576a1a5e27c5c4eb446aa4370b0a020284b159e5220` -for XML. +`a10e826952ced297d3da81c76705c81042d02d19f8a7fc72bf28c39801ec5bd9` +for XML (both updated in the jbotci#719 migration above). Across the 48 comparable product documents, observed omissions equal the independently expanded waiver set exactly: source records 624, assigned-name records 3, descriptor words 55, `introducedBy` fields 234, quantity text -fields 11, bound-variable words 9, and composition relation labels 5, for 941 -occurrences total. There are no unwaived or duplicate omissions. +fields 11, bound-variable words 9, composition relation labels 5, and +connector provenance fields 16 (new in jbotci#719), for 957 occurrences +total. There are no unwaived or duplicate omissions. The files are frozen evidence. Update them only after a separately reviewed notation decision and a fresh, pinned-oracle parity proof. diff --git a/crates/jbotci-semantics/tests/xml_corpus/b13.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b13.xml.txt index b36ba3b9fb..2fee0184e6 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b13.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b13.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (15 records: spans, witness text, construct labels) - descriptor *.word provenance (2 fields) - *.introducedBy provenance (7 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b14.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b14.xml.txt index 215d7ca171..496b758658 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b14.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b14.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (8 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (5 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b15.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b15.xml.txt index 4d4e0dfcc4..3a8110dc24 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b15.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b15.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (8 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (4 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b16.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b16.xml.txt index a5213c57a5..1736358680 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b16.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b16.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (8 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (3 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b17.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b17.xml.txt index 9fb5aea1e3..ebc8c663a1 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b17.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b17.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (8 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (6 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b18.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b18.xml.txt index 8455992b75..da4cf38cd6 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b18.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b18.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (17 records: spans, witness text, construct labels) - descriptor *.word provenance (2 fields) - *.introducedBy provenance (6 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b19.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b19.xml.txt index 4abe9f8cf5..3ef67cdfcd 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b19.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b19.xml.txt @@ -1,34 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (13 records: spans, witness text, construct labels) - *.assignedNames provenance (1 record) - descriptor *.word provenance (1 field) - *.introducedBy provenance (8 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b21.frozen.json b/crates/jbotci-semantics/tests/xml_corpus/b21.frozen.json index 5da25592fc..0086b56836 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b21.frozen.json +++ b/crates/jbotci-semantics/tests/xml_corpus/b21.frozen.json @@ -1 +1 @@ -{"version":"lojban-semantics-json-1","root":"utterance:5","objects":{"utterance:5":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:25","content":"formula:24","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":0,"byteEnd":40},"text":"lo prenu cu lebna lo cukta gi'e tcidu ri","construct":"bridi"}},"predication:12":{"type":"predication","relation":"cukta","arguments":{"x1":{"kind":"filled","value":"entity:7"},"x2":{"kind":"elided","value":"entity:8","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:9","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:10","introducedBy":"zo'e"},"x5":{"kind":"elided","value":"entity:11","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":21,"byteEnd":26},"text":"cukta","construct":"restrictive-predication"}},"predication:15":{"type":"predication","relation":"prenu","arguments":{"x1":{"kind":"filled","value":"entity:14"}},"mode":"restrictive","source":{"span":{"byteStart":3,"byteEnd":8},"text":"prenu","construct":"restrictive-predication"}},"predication:18":{"type":"predication","eventuality":"eventuality:6","relation":"lebna","arguments":{"x1":{"kind":"filled","value":"entity:14","source":{"span":{"byteStart":0,"byteEnd":8},"text":"lo prenu","construct":"shared-head-term"}},"x2":{"kind":"filled","value":"entity:7"},"x3":{"kind":"elided","value":"entity:17","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":12,"byteEnd":17},"text":"lebna","construct":"predication"}},"predication:22":{"type":"predication","eventuality":"eventuality:20","relation":"tcidu","arguments":{"x1":{"kind":"filled","value":"entity:14","source":{"span":{"byteStart":0,"byteEnd":8},"text":"lo prenu","construct":"shared-head-term"}},"x2":{"kind":"filled","value":"entity:7"},"x3":{"kind":"elided","value":"entity:21","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":32,"byteEnd":37},"text":"tcidu","construct":"predication"}},"formula:13":{"type":"formula","operator":"atom","predication":"predication:12","source":{"span":{"byteStart":21,"byteEnd":26},"text":"cukta","construct":"restrictive-formula"}},"formula:16":{"type":"formula","operator":"atom","predication":"predication:15","source":{"span":{"byteStart":3,"byteEnd":8},"text":"prenu","construct":"restrictive-formula"}},"formula:19":{"type":"formula","operator":"atom","predication":"predication:18","boundEventualities":["eventuality:6"],"source":{"span":{"byteStart":12,"byteEnd":17},"text":"lebna","construct":"bridi-tail-formula"}},"formula:23":{"type":"formula","operator":"atom","predication":"predication:22","boundEventualities":["eventuality:20"],"source":{"span":{"byteStart":32,"byteEnd":37},"text":"tcidu","construct":"bridi-tail-formula"}},"formula:24":{"type":"formula","operator":"and","children":["formula:19","formula:23"],"connector":{"source":"gi'e","locus":"bridiTail","truthTable":"TFFF"},"source":{"span":{"byteStart":0,"byteEnd":40},"text":"lo prenu cu lebna lo cukta gi'e tcidu ri","construct":"compound-bridi-formula"}},"entity:1":{"type":"referent","category":"indexical","sort":"entity","indexical":"speaker"},"entity:2":{"type":"referent","category":"indexical","sort":"entity","indexical":"audience"},"entity:4":{"type":"referent","category":"indexical","sort":"entity","indexical":"here"},"entity:7":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1","body":"formula:13"},"source":{"span":{"byteStart":18,"byteEnd":26},"text":"lo cukta","construct":"description"}},"entity:8":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:9":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:10":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:11":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:14":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1","body":"formula:16"},"source":{"span":{"byteStart":0,"byteEnd":8},"text":"lo prenu","construct":"description"}},"entity:17":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:21":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"eventuality:3":{"type":"referent","denotation":"referential","category":"indexical","sort":"eventuality","indexical":"now"},"eventuality:6":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":12,"byteEnd":17},"text":"lebna","construct":"predication"}},"eventuality:20":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":32,"byteEnd":37},"text":"tcidu","construct":"predication"}},"eventuality/locution:25":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":0,"byteEnd":40},"text":"lo prenu cu lebna lo cukta gi'e tcidu ri","construct":"bridi"}}}} +{"version":"lojban-semantics-json-1","root":"utterance:5","objects":{"utterance:5":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:25","content":"formula:24","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":0,"byteEnd":40},"text":"lo prenu cu lebna lo cukta gi'e tcidu ri","construct":"bridi"}},"predication:12":{"type":"predication","relation":"cukta","arguments":{"x1":{"kind":"filled","value":"entity:7"},"x2":{"kind":"elided","value":"entity:8","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:9","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:10","introducedBy":"zo'e"},"x5":{"kind":"elided","value":"entity:11","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":21,"byteEnd":26},"text":"cukta","construct":"restrictive-predication"}},"predication:15":{"type":"predication","relation":"prenu","arguments":{"x1":{"kind":"filled","value":"entity:14"}},"mode":"restrictive","source":{"span":{"byteStart":3,"byteEnd":8},"text":"prenu","construct":"restrictive-predication"}},"predication:18":{"type":"predication","eventuality":"eventuality:6","relation":"lebna","arguments":{"x1":{"kind":"filled","value":"entity:14","source":{"span":{"byteStart":0,"byteEnd":8},"text":"lo prenu","construct":"shared-head-term"}},"x2":{"kind":"filled","value":"entity:7"},"x3":{"kind":"elided","value":"entity:17","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":12,"byteEnd":17},"text":"lebna","construct":"predication"}},"predication:22":{"type":"predication","eventuality":"eventuality:20","relation":"tcidu","arguments":{"x1":{"kind":"filled","value":"entity:14","source":{"span":{"byteStart":0,"byteEnd":8},"text":"lo prenu","construct":"shared-head-term"}},"x2":{"kind":"filled","value":"entity:7"},"x3":{"kind":"elided","value":"entity:21","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":32,"byteEnd":37},"text":"tcidu","construct":"predication"}},"formula:13":{"type":"formula","operator":"atom","predication":"predication:12","source":{"span":{"byteStart":21,"byteEnd":26},"text":"cukta","construct":"restrictive-formula"}},"formula:16":{"type":"formula","operator":"atom","predication":"predication:15","source":{"span":{"byteStart":3,"byteEnd":8},"text":"prenu","construct":"restrictive-formula"}},"formula:19":{"type":"formula","operator":"atom","predication":"predication:18","boundEventualities":["eventuality:6"],"source":{"span":{"byteStart":12,"byteEnd":17},"text":"lebna","construct":"bridi-tail-formula"}},"formula:23":{"type":"formula","operator":"atom","predication":"predication:22","boundEventualities":["eventuality:20"],"source":{"span":{"byteStart":32,"byteEnd":37},"text":"tcidu","construct":"bridi-tail-formula"}},"formula:24":{"type":"formula","operator":"and","children":["formula:19","formula:23"],"connector":{"source":{"kind":"surfaceWord","word":"gi'e"},"locus":"predicatePhrase","truthTable":"TFFF"},"source":{"span":{"byteStart":0,"byteEnd":40},"text":"lo prenu cu lebna lo cukta gi'e tcidu ri","construct":"compound-bridi-formula"}},"entity:1":{"type":"referent","category":"indexical","sort":"entity","indexical":"speaker"},"entity:2":{"type":"referent","category":"indexical","sort":"entity","indexical":"audience"},"entity:4":{"type":"referent","category":"indexical","sort":"entity","indexical":"here"},"entity:7":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1","body":"formula:13"},"source":{"span":{"byteStart":18,"byteEnd":26},"text":"lo cukta","construct":"description"}},"entity:8":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:9":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:10":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:11":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:14":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1","body":"formula:16"},"source":{"span":{"byteStart":0,"byteEnd":8},"text":"lo prenu","construct":"description"}},"entity:17":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:21":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"eventuality:3":{"type":"referent","denotation":"referential","category":"indexical","sort":"eventuality","indexical":"now"},"eventuality:6":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":12,"byteEnd":17},"text":"lebna","construct":"predication"}},"eventuality:20":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":32,"byteEnd":37},"text":"tcidu","construct":"predication"}},"eventuality/locution:25":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":0,"byteEnd":40},"text":"lo prenu cu lebna lo cukta gi'e tcidu ri","construct":"bridi"}}}} diff --git a/crates/jbotci-semantics/tests/xml_corpus/b21.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b21.xml.txt index aa7ae1cd45..c8bb77f8c6 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b21.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b21.xml.txt @@ -1,93 +1,111 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (17 records: spans, witness text, construct labels) - descriptor *.word provenance (2 fields) - *.introducedBy provenance (6 fields) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/crates/jbotci-semantics/tests/xml_corpus/b22.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b22.xml.txt index de83ff9bfd..5cd06e132e 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b22.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b22.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (9 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (2 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b23.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b23.xml.txt index ef2fb7173a..3c0369800d 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b23.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b23.xml.txt @@ -1,34 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (19 records: spans, witness text, construct labels) - *.introducedBy provenance (1 field) - quantity value text provenance (2 fields) - bound-variable surface word provenance (2 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b24.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b24.xml.txt index d02f6c9416..158e47b5c8 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b24.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b24.xml.txt @@ -1,34 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (18 records: spans, witness text, construct labels) - *.introducedBy provenance (1 field) - quantity value text provenance (2 fields) - bound-variable surface word provenance (2 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b25.frozen.json b/crates/jbotci-semantics/tests/xml_corpus/b25.frozen.json index bc52320ae1..79adcb7f3c 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b25.frozen.json +++ b/crates/jbotci-semantics/tests/xml_corpus/b25.frozen.json @@ -1 +1 @@ -{"version":"lojban-semantics-json-1","root":"utterance:5","objects":{"utterance:5":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:19","content":"formula:18","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":0,"byteEnd":26},"text":"ganai do klama gi mi gleki","construct":"bridi"}},"predication:11":{"type":"predication","eventuality":"eventuality:6","relation":"klama","arguments":{"x1":{"kind":"filled","value":"entity:2"},"x2":{"kind":"elided","value":"entity:7","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:8","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:9","introducedBy":"zo'e"},"x5":{"kind":"elided","value":"entity:10","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":6,"byteEnd":14},"text":"do klama","construct":"predication"}},"predication:15":{"type":"predication","eventuality":"eventuality:13","relation":"gleki","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"elided","value":"entity:14","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":18,"byteEnd":26},"text":"mi gleki","construct":"predication"}},"formula:12":{"type":"formula","operator":"atom","predication":"predication:11","boundEventualities":["eventuality:6"],"source":{"span":{"byteStart":6,"byteEnd":14},"text":"do klama","construct":"bridi-formula"}},"formula:16":{"type":"formula","operator":"atom","predication":"predication:15","boundEventualities":["eventuality:13"],"source":{"span":{"byteStart":18,"byteEnd":26},"text":"mi gleki","construct":"bridi-formula"}},"formula:17":{"type":"formula","operator":"not","children":["formula:12"]},"formula:18":{"type":"formula","operator":"or","children":["formula:17","formula:16"],"connector":{"source":"ga nai gi","locus":"bridi","truthTable":"TFTT"}},"entity:1":{"type":"referent","category":"indexical","sort":"entity","indexical":"speaker"},"entity:2":{"type":"referent","category":"indexical","sort":"entity","indexical":"audience"},"entity:4":{"type":"referent","category":"indexical","sort":"entity","indexical":"here"},"entity:7":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:8":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:9":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:10":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:14":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"eventuality:3":{"type":"referent","denotation":"referential","category":"indexical","sort":"eventuality","indexical":"now"},"eventuality:6":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":6,"byteEnd":14},"text":"do klama","construct":"predication"}},"eventuality:13":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":18,"byteEnd":26},"text":"mi gleki","construct":"predication"}},"eventuality/locution:19":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":0,"byteEnd":26},"text":"ganai do klama gi mi gleki","construct":"bridi"}}}} +{"version":"lojban-semantics-json-1","root":"utterance:5","objects":{"utterance:5":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:19","content":"formula:18","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":0,"byteEnd":26},"text":"ganai do klama gi mi gleki","construct":"bridi"}},"predication:11":{"type":"predication","eventuality":"eventuality:6","relation":"klama","arguments":{"x1":{"kind":"filled","value":"entity:2"},"x2":{"kind":"elided","value":"entity:7","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:8","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:9","introducedBy":"zo'e"},"x5":{"kind":"elided","value":"entity:10","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":6,"byteEnd":14},"text":"do klama","construct":"predication"}},"predication:15":{"type":"predication","eventuality":"eventuality:13","relation":"gleki","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"elided","value":"entity:14","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":18,"byteEnd":26},"text":"mi gleki","construct":"predication"}},"formula:12":{"type":"formula","operator":"atom","predication":"predication:11","boundEventualities":["eventuality:6"],"source":{"span":{"byteStart":6,"byteEnd":14},"text":"do klama","construct":"bridi-formula"}},"formula:16":{"type":"formula","operator":"atom","predication":"predication:15","boundEventualities":["eventuality:13"],"source":{"span":{"byteStart":18,"byteEnd":26},"text":"mi gleki","construct":"bridi-formula"}},"formula:17":{"type":"formula","operator":"not","children":["formula:12"]},"formula:18":{"type":"formula","operator":"or","children":["formula:17","formula:16"],"connector":{"source":{"kind":"surfaceWord","word":"ga nai gi"},"locus":"clause","truthTable":"TFTT"}},"entity:1":{"type":"referent","category":"indexical","sort":"entity","indexical":"speaker"},"entity:2":{"type":"referent","category":"indexical","sort":"entity","indexical":"audience"},"entity:4":{"type":"referent","category":"indexical","sort":"entity","indexical":"here"},"entity:7":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:8":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:9":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:10":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:14":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"eventuality:3":{"type":"referent","denotation":"referential","category":"indexical","sort":"eventuality","indexical":"now"},"eventuality:6":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":6,"byteEnd":14},"text":"do klama","construct":"predication"}},"eventuality:13":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":18,"byteEnd":26},"text":"mi gleki","construct":"predication"}},"eventuality/locution:19":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":0,"byteEnd":26},"text":"ganai do klama gi mi gleki","construct":"bridi"}}}} diff --git a/crates/jbotci-semantics/tests/xml_corpus/b25.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b25.xml.txt index 70f644ddf9..ea515cb855 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b25.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b25.xml.txt @@ -1,71 +1,90 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (8 records: spans, witness text, construct labels) - *.introducedBy provenance (5 fields) - - - - - - - - - - - - - - - - - - + + - + - - - + + + + + + - - - - - - + + + + + + + + + + + + diff --git a/crates/jbotci-semantics/tests/xml_corpus/b26.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b26.xml.txt index da3437e634..1e9b57dfaf 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b26.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b26.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (11 records: spans, witness text, construct labels) - *.introducedBy provenance (4 fields) - quantity value text provenance (1 field) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b27.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b27.xml.txt index e916d04d03..3537a85450 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b27.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b27.xml.txt @@ -1,32 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (5 records: spans, witness text, construct labels) - *.introducedBy provenance (1 field) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b28.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b28.xml.txt index ea54de5d99..c5ce5dcab5 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b28.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b28.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (8 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (5 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b29.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b29.xml.txt index a85ad0a25f..cfdccb9cf3 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b29.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b29.xml.txt @@ -1,32 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (5 records: spans, witness text, construct labels) - *.introducedBy provenance (2 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b30.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b30.xml.txt index dcfa23c4ab..facc2d3253 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b30.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b30.xml.txt @@ -1,32 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (6 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b31.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b31.xml.txt index c7909acd54..ae9cc99f8a 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b31.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b31.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (8 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (7 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b32.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b32.xml.txt index 1a2dc40b6a..b802754571 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b32.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b32.xml.txt @@ -1,32 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (10 records: spans, witness text, construct labels) - *.introducedBy provenance (2 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b33.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b33.xml.txt index fc7d41ed52..bb482ddb9c 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b33.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b33.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (9 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (1 field) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b34.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b34.xml.txt index dc54d6252d..91e925db68 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b34.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b34.xml.txt @@ -1,32 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (10 records: spans, witness text, construct labels) - descriptor *.word provenance (2 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b35.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b35.xml.txt index 6ed64d152b..74b1332e16 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b35.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b35.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (8 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (5 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b36.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b36.xml.txt index 836e2da754..b139a3995d 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b36.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b36.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (9 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (5 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b37.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b37.xml.txt index ed43329a90..ac22aa1f78 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b37.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b37.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (12 records: spans, witness text, construct labels) - descriptor *.word provenance (3 fields) - *.introducedBy provenance (4 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b38.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b38.xml.txt index 6f4634778f..b51396450b 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b38.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b38.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (10 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (5 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b39.frozen.json b/crates/jbotci-semantics/tests/xml_corpus/b39.frozen.json index 61880f67c7..c6756ef4c9 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b39.frozen.json +++ b/crates/jbotci-semantics/tests/xml_corpus/b39.frozen.json @@ -1 +1 @@ -{"version":"lojban-semantics-json-1","root":"utterance:5","objects":{"utterance:5":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:35","content":"formula:34","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":0,"byteEnd":29},"text":"lo sutra bajra prenu cu tavla","construct":"bridi"}},"parameter:10":{"type":"parameter","sort":"entity","role":"propertySlot","introducedBy":"ce'u","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"parameter:17":{"type":"parameter","sort":"entity","role":"propertySlot","introducedBy":"ce'u","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"predication:8":{"type":"predication","relation":"prenu","arguments":{"x1":{"kind":"filled","value":"entity:7"}},"mode":"restrictive","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-predication"}},"predication:15":{"type":"predication","eventuality":"eventuality:11","relation":"bajra","arguments":{"x1":{"kind":"filled","value":"parameter:10"},"x2":{"kind":"elided","value":"entity:12","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:13","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:14","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"predication:20":{"type":"predication","eventuality":"eventuality:18","relation":"sutra","arguments":{"x1":{"kind":"filled","value":"parameter:17"},"x2":{"kind":"elided","value":"entity:19","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"predication:23":{"type":"predication","relation":"tanru","tanruLink":{"head":"predication:15","modifier":"relation:22","relationLabel":"sutra-bajra"},"arguments":{"x1":{"kind":"filled","value":"parameter:10"},"x2":{"kind":"filled","value":"relation:22"}},"mode":"restrictive","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"predication:27":{"type":"predication","relation":"tanru","tanruLink":{"head":"predication:8","modifier":"relation:26","relationLabel":"sutra-bajra-prenu"},"arguments":{"x1":{"kind":"filled","value":"entity:7"},"x2":{"kind":"filled","value":"relation:26"}},"mode":"restrictive","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"predication:33":{"type":"predication","eventuality":"eventuality:6","relation":"tavla","arguments":{"x1":{"kind":"filled","value":"entity:7"},"x2":{"kind":"elided","value":"entity:30","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:31","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:32","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":0,"byteEnd":29},"text":"lo sutra bajra prenu cu tavla","construct":"predication"}},"formula:9":{"type":"formula","operator":"atom","predication":"predication:8","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-predication"}},"formula:16":{"type":"formula","operator":"atom","predication":"predication:15","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"formula:21":{"type":"formula","operator":"atom","predication":"predication:20","boundEventualities":["eventuality:18"],"source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"formula:24":{"type":"formula","operator":"atom","predication":"predication:23","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"formula:25":{"type":"formula","operator":"and","children":["formula:16","formula:24"],"connector":{"source":"tanru","locus":"property-abstraction"},"boundEventualities":["eventuality:11"],"source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"formula:28":{"type":"formula","operator":"atom","predication":"predication:27","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"formula:29":{"type":"formula","operator":"and","children":["formula:9","formula:28"],"connector":{"source":"tanru","locus":"description"},"source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"formula:34":{"type":"formula","operator":"atom","predication":"predication:33","boundEventualities":["eventuality:6"],"source":{"span":{"byteStart":0,"byteEnd":29},"text":"lo sutra bajra prenu cu tavla","construct":"bridi-formula"}},"entity:1":{"type":"referent","category":"indexical","sort":"entity","indexical":"speaker"},"entity:2":{"type":"referent","category":"indexical","sort":"entity","indexical":"audience"},"entity:4":{"type":"referent","category":"indexical","sort":"entity","indexical":"here"},"entity:7":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1","body":"formula:29"},"source":{"span":{"byteStart":0,"byteEnd":20},"text":"lo sutra bajra prenu","construct":"description"}},"entity:12":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:10"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:13":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:10"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:14":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:10"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:19":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:10","parameter:17"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:30":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:31":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:32":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"eventuality:3":{"type":"referent","denotation":"referential","category":"indexical","sort":"eventuality","indexical":"now"},"eventuality:6":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":0,"byteEnd":29},"text":"lo sutra bajra prenu cu tavla","construct":"predication"}},"eventuality:11":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"eventuality:18":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"eventuality/locution:35":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":0,"byteEnd":29},"text":"lo sutra bajra prenu cu tavla","construct":"bridi"}},"relation:22":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:10"]},"sort":"relation","body":"formula:21","parameters":["parameter:17"],"arity":1,"source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"relation:26":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"relation","body":"formula:25","parameters":["parameter:10"],"arity":1,"source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}}}} +{"version":"lojban-semantics-json-1","root":"utterance:5","objects":{"utterance:5":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:35","content":"formula:34","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":0,"byteEnd":29},"text":"lo sutra bajra prenu cu tavla","construct":"bridi"}},"parameter:10":{"type":"parameter","sort":"entity","role":"propertySlot","introducedBy":"ce'u","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"parameter:17":{"type":"parameter","sort":"entity","role":"propertySlot","introducedBy":"ce'u","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"predication:8":{"type":"predication","relation":"prenu","arguments":{"x1":{"kind":"filled","value":"entity:7"}},"mode":"restrictive","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-predication"}},"predication:15":{"type":"predication","eventuality":"eventuality:11","relation":"bajra","arguments":{"x1":{"kind":"filled","value":"parameter:10"},"x2":{"kind":"elided","value":"entity:12","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:13","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:14","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"predication:20":{"type":"predication","eventuality":"eventuality:18","relation":"sutra","arguments":{"x1":{"kind":"filled","value":"parameter:17"},"x2":{"kind":"elided","value":"entity:19","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"predication:23":{"type":"predication","tanruLink":{"head":"predication:15","modifier":"relation:22","relationLabel":"sutra-bajra"},"arguments":{"x1":{"kind":"filled","value":"parameter:10"},"x2":{"kind":"filled","value":"relation:22"}},"mode":"restrictive","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"predication:27":{"type":"predication","tanruLink":{"head":"predication:8","modifier":"relation:26","relationLabel":"sutra-bajra-prenu"},"arguments":{"x1":{"kind":"filled","value":"entity:7"},"x2":{"kind":"filled","value":"relation:26"}},"mode":"restrictive","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"predication:33":{"type":"predication","eventuality":"eventuality:6","relation":"tavla","arguments":{"x1":{"kind":"filled","value":"entity:7"},"x2":{"kind":"elided","value":"entity:30","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:31","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:32","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":0,"byteEnd":29},"text":"lo sutra bajra prenu cu tavla","construct":"predication"}},"formula:9":{"type":"formula","operator":"atom","predication":"predication:8","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-predication"}},"formula:16":{"type":"formula","operator":"atom","predication":"predication:15","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"formula:21":{"type":"formula","operator":"atom","predication":"predication:20","boundEventualities":["eventuality:18"],"source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"formula:24":{"type":"formula","operator":"atom","predication":"predication:23","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"formula:25":{"type":"formula","operator":"and","children":["formula:16","formula:24"],"connector":{"source":{"kind":"implicitJuxtaposition"},"locus":"propertyAbstraction"},"boundEventualities":["eventuality:11"],"source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"formula:28":{"type":"formula","operator":"atom","predication":"predication:27","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"formula:29":{"type":"formula","operator":"and","children":["formula:9","formula:28"],"connector":{"source":{"kind":"implicitJuxtaposition"},"locus":"description"},"source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"formula:34":{"type":"formula","operator":"atom","predication":"predication:33","boundEventualities":["eventuality:6"],"source":{"span":{"byteStart":0,"byteEnd":29},"text":"lo sutra bajra prenu cu tavla","construct":"bridi-formula"}},"entity:1":{"type":"referent","category":"indexical","sort":"entity","indexical":"speaker"},"entity:2":{"type":"referent","category":"indexical","sort":"entity","indexical":"audience"},"entity:4":{"type":"referent","category":"indexical","sort":"entity","indexical":"here"},"entity:7":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1","body":"formula:29"},"source":{"span":{"byteStart":0,"byteEnd":20},"text":"lo sutra bajra prenu","construct":"description"}},"entity:12":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:10"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:13":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:10"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:14":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:10"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:19":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:10","parameter:17"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:30":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:31":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:32":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"eventuality:3":{"type":"referent","denotation":"referential","category":"indexical","sort":"eventuality","indexical":"now"},"eventuality:6":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":0,"byteEnd":29},"text":"lo sutra bajra prenu cu tavla","construct":"predication"}},"eventuality:11":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"eventuality:18":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"eventuality/locution:35":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":0,"byteEnd":29},"text":"lo sutra bajra prenu cu tavla","construct":"bridi"}},"relation:22":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:10"]},"sort":"relation","body":"formula:21","parameters":["parameter:17"],"arity":1,"source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}},"relation:26":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"relation","body":"formula:25","parameters":["parameter:10"],"arity":1,"source":{"span":{"byteStart":3,"byteEnd":20},"text":"sutra bajra prenu","construct":"restrictive-tanru-formula"}}}} diff --git a/crates/jbotci-semantics/tests/xml_corpus/b39.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b39.xml.txt index 94dbe12407..a55fe4a98b 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b39.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b39.xml.txt @@ -1,34 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (24 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (9 fields) - kind-composition relation-label provenance (2 fields) - @@ -43,93 +66,20 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + - - + + - - - - - - - + + + + + diff --git a/crates/jbotci-semantics/tests/xml_corpus/b40.frozen.json b/crates/jbotci-semantics/tests/xml_corpus/b40.frozen.json index 68247f7ad6..3a9ce7b855 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b40.frozen.json +++ b/crates/jbotci-semantics/tests/xml_corpus/b40.frozen.json @@ -1 +1 @@ -{"version":"lojban-semantics-json-1","root":"utterance:5","objects":{"utterance:5":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:23","content":"formula:22","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":0,"byteEnd":23},"text":"mi nelci lo cmalu mlatu","construct":"bridi"}},"parameter:11":{"type":"parameter","sort":"entity","role":"propertySlot","introducedBy":"ce'u","source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-tanru-formula"}},"predication:9":{"type":"predication","relation":"mlatu","arguments":{"x1":{"kind":"filled","value":"entity:7"},"x2":{"kind":"elided","value":"entity:8","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-predication"}},"predication:15":{"type":"predication","eventuality":"eventuality:12","relation":"cmalu","arguments":{"x1":{"kind":"filled","value":"parameter:11"},"x2":{"kind":"elided","value":"entity:13","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:14","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-tanru-formula"}},"predication:18":{"type":"predication","relation":"tanru","tanruLink":{"head":"predication:9","modifier":"relation:17","relationLabel":"cmalu-mlatu"},"arguments":{"x1":{"kind":"filled","value":"entity:7"},"x2":{"kind":"filled","value":"relation:17"}},"mode":"restrictive","source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-tanru-formula"}},"predication:21":{"type":"predication","eventuality":"eventuality:6","relation":"nelci","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"filled","value":"entity:7"}},"mode":"asserted","source":{"span":{"byteStart":0,"byteEnd":23},"text":"mi nelci lo cmalu mlatu","construct":"predication"}},"formula:10":{"type":"formula","operator":"atom","predication":"predication:9","source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-predication"}},"formula:16":{"type":"formula","operator":"atom","predication":"predication:15","boundEventualities":["eventuality:12"],"source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-tanru-formula"}},"formula:19":{"type":"formula","operator":"atom","predication":"predication:18","source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-tanru-formula"}},"formula:20":{"type":"formula","operator":"and","children":["formula:10","formula:19"],"connector":{"source":"tanru","locus":"description"},"source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-tanru-formula"}},"formula:22":{"type":"formula","operator":"atom","predication":"predication:21","boundEventualities":["eventuality:6"],"source":{"span":{"byteStart":0,"byteEnd":23},"text":"mi nelci lo cmalu mlatu","construct":"bridi-formula"}},"entity:1":{"type":"referent","category":"indexical","sort":"entity","indexical":"speaker"},"entity:2":{"type":"referent","category":"indexical","sort":"entity","indexical":"audience"},"entity:4":{"type":"referent","category":"indexical","sort":"entity","indexical":"here"},"entity:7":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1","body":"formula:20"},"source":{"span":{"byteStart":9,"byteEnd":23},"text":"lo cmalu mlatu","construct":"description"}},"entity:8":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:13":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:11"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:14":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:11"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"eventuality:3":{"type":"referent","denotation":"referential","category":"indexical","sort":"eventuality","indexical":"now"},"eventuality:6":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":0,"byteEnd":23},"text":"mi nelci lo cmalu mlatu","construct":"predication"}},"eventuality:12":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-tanru-formula"}},"eventuality/locution:23":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":0,"byteEnd":23},"text":"mi nelci lo cmalu mlatu","construct":"bridi"}},"relation:17":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"relation","body":"formula:16","parameters":["parameter:11"],"arity":1,"source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-tanru-formula"}}}} +{"version":"lojban-semantics-json-1","root":"utterance:5","objects":{"utterance:5":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:23","content":"formula:22","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":0,"byteEnd":23},"text":"mi nelci lo cmalu mlatu","construct":"bridi"}},"parameter:11":{"type":"parameter","sort":"entity","role":"propertySlot","introducedBy":"ce'u","source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-tanru-formula"}},"predication:9":{"type":"predication","relation":"mlatu","arguments":{"x1":{"kind":"filled","value":"entity:7"},"x2":{"kind":"elided","value":"entity:8","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-predication"}},"predication:15":{"type":"predication","eventuality":"eventuality:12","relation":"cmalu","arguments":{"x1":{"kind":"filled","value":"parameter:11"},"x2":{"kind":"elided","value":"entity:13","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:14","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-tanru-formula"}},"predication:18":{"type":"predication","tanruLink":{"head":"predication:9","modifier":"relation:17","relationLabel":"cmalu-mlatu"},"arguments":{"x1":{"kind":"filled","value":"entity:7"},"x2":{"kind":"filled","value":"relation:17"}},"mode":"restrictive","source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-tanru-formula"}},"predication:21":{"type":"predication","eventuality":"eventuality:6","relation":"nelci","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"filled","value":"entity:7"}},"mode":"asserted","source":{"span":{"byteStart":0,"byteEnd":23},"text":"mi nelci lo cmalu mlatu","construct":"predication"}},"formula:10":{"type":"formula","operator":"atom","predication":"predication:9","source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-predication"}},"formula:16":{"type":"formula","operator":"atom","predication":"predication:15","boundEventualities":["eventuality:12"],"source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-tanru-formula"}},"formula:19":{"type":"formula","operator":"atom","predication":"predication:18","source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-tanru-formula"}},"formula:20":{"type":"formula","operator":"and","children":["formula:10","formula:19"],"connector":{"source":{"kind":"implicitJuxtaposition"},"locus":"description"},"source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-tanru-formula"}},"formula:22":{"type":"formula","operator":"atom","predication":"predication:21","boundEventualities":["eventuality:6"],"source":{"span":{"byteStart":0,"byteEnd":23},"text":"mi nelci lo cmalu mlatu","construct":"bridi-formula"}},"entity:1":{"type":"referent","category":"indexical","sort":"entity","indexical":"speaker"},"entity:2":{"type":"referent","category":"indexical","sort":"entity","indexical":"audience"},"entity:4":{"type":"referent","category":"indexical","sort":"entity","indexical":"here"},"entity:7":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1","body":"formula:20"},"source":{"span":{"byteStart":9,"byteEnd":23},"text":"lo cmalu mlatu","construct":"description"}},"entity:8":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:13":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:11"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:14":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:11"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"eventuality:3":{"type":"referent","denotation":"referential","category":"indexical","sort":"eventuality","indexical":"now"},"eventuality:6":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":0,"byteEnd":23},"text":"mi nelci lo cmalu mlatu","construct":"predication"}},"eventuality:12":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-tanru-formula"}},"eventuality/locution:23":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":0,"byteEnd":23},"text":"mi nelci lo cmalu mlatu","construct":"bridi"}},"relation:17":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"relation","body":"formula:16","parameters":["parameter:11"],"arity":1,"source":{"span":{"byteStart":12,"byteEnd":23},"text":"cmalu mlatu","construct":"restrictive-tanru-formula"}}}} diff --git a/crates/jbotci-semantics/tests/xml_corpus/b40.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b40.xml.txt index 526f5fe1d7..8369a42152 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b40.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b40.xml.txt @@ -1,34 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (16 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (4 fields) - kind-composition relation-label provenance (1 field) - @@ -43,52 +66,14 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + diff --git a/crates/jbotci-semantics/tests/xml_corpus/b41.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b41.xml.txt index 7c7bdf2c99..1a4d1abae9 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b41.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b41.xml.txt @@ -1,32 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (15 records: spans, witness text, construct labels) - *.introducedBy provenance (2 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b42.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b42.xml.txt index 1beb06614c..4d26d3bda2 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b42.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b42.xml.txt @@ -1,32 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (6 records: spans, witness text, construct labels) - *.introducedBy provenance (2 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b43.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b43.xml.txt index dd7606b544..fed65ba935 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b43.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b43.xml.txt @@ -1,32 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (6 records: spans, witness text, construct labels) - *.introducedBy provenance (2 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b44.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b44.xml.txt index 76d00219f1..8470a31fbc 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b44.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b44.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (12 records: spans, witness text, construct labels) - descriptor *.word provenance (2 fields) - *.introducedBy provenance (9 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b45.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b45.xml.txt index 6dea5a04b4..4585862ad4 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b45.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b45.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (7 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (5 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b46.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b46.xml.txt index 5f810fc5df..cd34dbd0e9 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b46.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b46.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (9 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (4 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b47.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b47.xml.txt index b42723fe6c..4e14de9877 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b47.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b47.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (9 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (8 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b48.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b48.xml.txt index 01f31e0df7..ff7afdeb0a 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b48.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b48.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (7 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (3 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b49.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b49.xml.txt index b754c3ab55..70639ba2d6 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b49.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b49.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (13 records: spans, witness text, construct labels) - descriptor *.word provenance (2 fields) - *.introducedBy provenance (16 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b50.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b50.xml.txt index c3405acd1b..98121d6f92 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b50.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b50.xml.txt @@ -1,35 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (15 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (3 fields) - quantity value text provenance (1 field) - bound-variable surface word provenance (1 field) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b51.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b51.xml.txt index 0386f0ae2a..57921b8792 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b51.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b51.xml.txt @@ -1,34 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (19 records: spans, witness text, construct labels) - *.introducedBy provenance (2 fields) - quantity value text provenance (2 fields) - bound-variable surface word provenance (2 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b52.frozen.json b/crates/jbotci-semantics/tests/xml_corpus/b52.frozen.json index 96572d47aa..e8fd428579 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b52.frozen.json +++ b/crates/jbotci-semantics/tests/xml_corpus/b52.frozen.json @@ -1 +1 @@ -{"version":"lojban-semantics-json-1","root":"sequence:29","objects":{"utterance:5":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:17","content":"formula:16","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":0,"byteEnd":17},"text":"mi klama lo zarci","construct":"bridi"}},"utterance:18":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:25","content":"formula:24","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":27,"byteEnd":31},"text":"go'i","construct":"bridi"}},"sequence:29":{"type":"sequence","items":["utterance:5","utterance:18"],"connectionClaims":["formula:28"],"boundEventualities":["eventuality:6","eventuality:19"],"relation":"same-topic-continuation","nonlogicalConnection":{"operator":"nonlogical:ba bo","connector":{"source":"ba bo","locus":"statement","truthTable":"TFFF"}},"source":{"span":{"byteStart":0,"byteEnd":31},"text":"mi klama lo zarci .i ba bo go'i","construct":"statement-connection"}},"predication:10":{"type":"predication","relation":"zarci","arguments":{"x1":{"kind":"filled","value":"entity:7"},"x2":{"kind":"elided","value":"entity:8","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:9","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":12,"byteEnd":17},"text":"zarci","construct":"restrictive-predication"}},"predication:15":{"type":"predication","eventuality":"eventuality:6","relation":"klama","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"filled","value":"entity:7"},"x3":{"kind":"elided","value":"entity:12","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:13","introducedBy":"zo'e"},"x5":{"kind":"elided","value":"entity:14","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":0,"byteEnd":17},"text":"mi klama lo zarci","construct":"predication"}},"predication:23":{"type":"predication","eventuality":"eventuality:19","relation":"klama","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"filled","value":"entity:7"},"x3":{"kind":"elided","value":"entity:20","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:21","introducedBy":"zo'e"},"x5":{"kind":"elided","value":"entity:22","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":27,"byteEnd":31},"text":"go'i","construct":"predication"}},"predication:27":{"type":"predication","eventuality":"eventuality:26","introducedBy":"ba","relation":"after","arguments":{"x1":{"kind":"filled","value":"eventuality:19"},"x2":{"kind":"filled","value":"eventuality:6"}},"mode":"asserted","source":{"span":{"byteStart":0,"byteEnd":31},"text":"mi klama lo zarci .i ba bo go'i","construct":"statement-connection"}},"formula:11":{"type":"formula","operator":"atom","predication":"predication:10","source":{"span":{"byteStart":12,"byteEnd":17},"text":"zarci","construct":"restrictive-formula"}},"formula:16":{"type":"formula","operator":"atom","predication":"predication:15","source":{"span":{"byteStart":0,"byteEnd":17},"text":"mi klama lo zarci","construct":"bridi-formula"}},"formula:24":{"type":"formula","operator":"atom","predication":"predication:23","source":{"span":{"byteStart":27,"byteEnd":31},"text":"go'i","construct":"bridi-formula"}},"formula:28":{"type":"formula","operator":"atom","predication":"predication:27","boundEventualities":["eventuality:26"],"source":{"span":{"byteStart":0,"byteEnd":31},"text":"mi klama lo zarci .i ba bo go'i","construct":"statement-connection"}},"entity:1":{"type":"referent","category":"indexical","sort":"entity","indexical":"speaker"},"entity:2":{"type":"referent","category":"indexical","sort":"entity","indexical":"audience"},"entity:4":{"type":"referent","category":"indexical","sort":"entity","indexical":"here"},"entity:7":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1","body":"formula:11"},"source":{"span":{"byteStart":9,"byteEnd":17},"text":"lo zarci","construct":"description"}},"entity:8":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:9":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:12":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:13":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:14":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:20":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:21":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:22":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"eventuality:3":{"type":"referent","denotation":"referential","category":"indexical","sort":"eventuality","indexical":"now"},"eventuality:6":{"type":"referent","denotation":"generated-bound","content":"formula:16","sort":"eventuality","source":{"span":{"byteStart":0,"byteEnd":17},"text":"mi klama lo zarci","construct":"predication"}},"eventuality:19":{"type":"referent","denotation":"generated-bound","content":"formula:24","sort":"eventuality","source":{"span":{"byteStart":27,"byteEnd":31},"text":"go'i","construct":"predication"}},"eventuality:26":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":0,"byteEnd":31},"text":"mi klama lo zarci .i ba bo go'i","construct":"statement-connection"}},"eventuality/locution:17":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":0,"byteEnd":17},"text":"mi klama lo zarci","construct":"bridi"}},"eventuality/locution:25":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":27,"byteEnd":31},"text":"go'i","construct":"bridi"}}}} +{"version":"lojban-semantics-json-1","root":"sequence:29","objects":{"utterance:5":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:17","content":"formula:16","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":0,"byteEnd":17},"text":"mi klama lo zarci","construct":"bridi"}},"utterance:18":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:25","content":"formula:24","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":27,"byteEnd":31},"text":"go'i","construct":"bridi"}},"sequence:29":{"type":"sequence","items":["utterance:5","utterance:18"],"connectionClaims":["formula:28"],"boundEventualities":["eventuality:6","eventuality:19"],"relation":"same-topic-continuation","nonlogicalConnection":{"operator":"nonlogical:ba bo","connector":{"source":{"kind":"surfaceWord","word":"ba bo"},"locus":"statement","truthTable":"TFFF"}},"source":{"span":{"byteStart":0,"byteEnd":31},"text":"mi klama lo zarci .i ba bo go'i","construct":"statement-connection"}},"predication:10":{"type":"predication","relation":"zarci","arguments":{"x1":{"kind":"filled","value":"entity:7"},"x2":{"kind":"elided","value":"entity:8","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:9","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":12,"byteEnd":17},"text":"zarci","construct":"restrictive-predication"}},"predication:15":{"type":"predication","eventuality":"eventuality:6","relation":"klama","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"filled","value":"entity:7"},"x3":{"kind":"elided","value":"entity:12","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:13","introducedBy":"zo'e"},"x5":{"kind":"elided","value":"entity:14","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":0,"byteEnd":17},"text":"mi klama lo zarci","construct":"predication"}},"predication:23":{"type":"predication","eventuality":"eventuality:19","relation":"klama","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"filled","value":"entity:7"},"x3":{"kind":"elided","value":"entity:20","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:21","introducedBy":"zo'e"},"x5":{"kind":"elided","value":"entity:22","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":27,"byteEnd":31},"text":"go'i","construct":"predication"}},"predication:27":{"type":"predication","eventuality":"eventuality:26","introducedBy":"ba","relation":"after","arguments":{"x1":{"kind":"filled","value":"eventuality:19"},"x2":{"kind":"filled","value":"eventuality:6"}},"mode":"asserted","source":{"span":{"byteStart":0,"byteEnd":31},"text":"mi klama lo zarci .i ba bo go'i","construct":"statement-connection"}},"formula:11":{"type":"formula","operator":"atom","predication":"predication:10","source":{"span":{"byteStart":12,"byteEnd":17},"text":"zarci","construct":"restrictive-formula"}},"formula:16":{"type":"formula","operator":"atom","predication":"predication:15","source":{"span":{"byteStart":0,"byteEnd":17},"text":"mi klama lo zarci","construct":"bridi-formula"}},"formula:24":{"type":"formula","operator":"atom","predication":"predication:23","source":{"span":{"byteStart":27,"byteEnd":31},"text":"go'i","construct":"bridi-formula"}},"formula:28":{"type":"formula","operator":"atom","predication":"predication:27","boundEventualities":["eventuality:26"],"source":{"span":{"byteStart":0,"byteEnd":31},"text":"mi klama lo zarci .i ba bo go'i","construct":"statement-connection"}},"entity:1":{"type":"referent","category":"indexical","sort":"entity","indexical":"speaker"},"entity:2":{"type":"referent","category":"indexical","sort":"entity","indexical":"audience"},"entity:4":{"type":"referent","category":"indexical","sort":"entity","indexical":"here"},"entity:7":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1","body":"formula:11"},"source":{"span":{"byteStart":9,"byteEnd":17},"text":"lo zarci","construct":"description"}},"entity:8":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:9":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:12":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:13":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:14":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:20":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:21":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:22":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"eventuality:3":{"type":"referent","denotation":"referential","category":"indexical","sort":"eventuality","indexical":"now"},"eventuality:6":{"type":"referent","denotation":"generated-bound","content":"formula:16","sort":"eventuality","source":{"span":{"byteStart":0,"byteEnd":17},"text":"mi klama lo zarci","construct":"predication"}},"eventuality:19":{"type":"referent","denotation":"generated-bound","content":"formula:24","sort":"eventuality","source":{"span":{"byteStart":27,"byteEnd":31},"text":"go'i","construct":"predication"}},"eventuality:26":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":0,"byteEnd":31},"text":"mi klama lo zarci .i ba bo go'i","construct":"statement-connection"}},"eventuality/locution:17":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":0,"byteEnd":17},"text":"mi klama lo zarci","construct":"bridi"}},"eventuality/locution:25":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":27,"byteEnd":31},"text":"go'i","construct":"bridi"}}}} diff --git a/crates/jbotci-semantics/tests/xml_corpus/b52.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b52.xml.txt index 21af0d239a..6107faae92 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b52.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b52.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (17 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (9 fields) - @@ -95,12 +119,7 @@ - - - - - - + diff --git a/crates/jbotci-semantics/tests/xml_corpus/b53.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b53.xml.txt index b895c38c21..01e37e9d5c 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b53.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b53.xml.txt @@ -1,35 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (23 records: spans, witness text, construct labels) - descriptor *.word provenance (2 fields) - *.introducedBy provenance (5 fields) - quantity value text provenance (1 field) - bound-variable surface word provenance (1 field) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b54.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b54.xml.txt index a2d2f55598..da268e6999 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b54.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b54.xml.txt @@ -1,34 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (15 records: spans, witness text, construct labels) - *.assignedNames provenance (2 records) - descriptor *.word provenance (2 fields) - *.introducedBy provenance (2 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b55.frozen.json b/crates/jbotci-semantics/tests/xml_corpus/b55.frozen.json index 4809377d3b..c2708b8c9d 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b55.frozen.json +++ b/crates/jbotci-semantics/tests/xml_corpus/b55.frozen.json @@ -1 +1 @@ -{"version":"lojban-semantics-json-1","root":"utterance:5","objects":{"utterance:5":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:41","content":"formula:40","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi"}},"parameter:17":{"type":"parameter","sort":"entity","role":"propertySlot","introducedBy":"ce'u","source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-tanru-formula"}},"parameter:30":{"type":"parameter","sort":"entity","role":"propertySlot","introducedBy":"ce'u","source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"predication:10":{"type":"predication","relation":"li'imdu","arguments":{"x1":{"kind":"filled","value":"entity:7"},"x2":{"kind":"elided","value":"entity:8","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:9","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":3,"byteEnd":10},"text":"li'imdu","construct":"restrictive-predication"}},"predication:15":{"type":"predication","relation":"gusni","arguments":{"x1":{"kind":"elided","value":"entity:13","introducedBy":"zo'e"},"x2":{"kind":"filled","value":"entity:12"},"x3":{"kind":"elided","value":"entity:14","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-predication"}},"predication:21":{"type":"predication","eventuality":"eventuality:18","relation":"nalmucti","arguments":{"x1":{"kind":"filled","value":"parameter:17"},"x2":{"kind":"elided","value":"entity:19","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:20","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-tanru-formula"}},"predication:24":{"type":"predication","relation":"tanru","tanruLink":{"head":"predication:15","modifier":"relation:23","relationLabel":"nalmucti-gusni"},"arguments":{"x1":{"kind":"filled","value":"entity:12"},"x2":{"kind":"filled","value":"relation:23"}},"mode":"restrictive","source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-tanru-formula"}},"predication:28":{"type":"predication","eventuality":"eventuality:6","relation":"gusni","arguments":{"x1":{"kind":"elided","value":"entity:27","introducedBy":"zo'e"},"x2":{"kind":"filled","value":"entity:7"},"x3":{"kind":"filled","value":"entity:12"}},"mode":"asserted","source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"predication:34":{"type":"predication","eventuality":"eventuality:31","relation":"mulno","arguments":{"x1":{"kind":"filled","value":"parameter:30"},"x2":{"kind":"elided","value":"entity:32","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:33","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"predication:37":{"type":"predication","relation":"tanru","tanruLink":{"head":"predication:28","modifier":"relation:36","relationLabel":"mulno-gusni"},"arguments":{"x1":{"kind":"filled","value":"entity:7"},"x2":{"kind":"filled","value":"relation:36"}},"mode":"asserted","source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"formula:11":{"type":"formula","operator":"atom","predication":"predication:10","source":{"span":{"byteStart":3,"byteEnd":10},"text":"li'imdu","construct":"restrictive-formula"}},"formula:16":{"type":"formula","operator":"atom","predication":"predication:15","source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-predication"}},"formula:22":{"type":"formula","operator":"atom","predication":"predication:21","boundEventualities":["eventuality:18"],"source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-tanru-formula"}},"formula:25":{"type":"formula","operator":"atom","predication":"predication:24","source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-tanru-formula"}},"formula:26":{"type":"formula","operator":"and","children":["formula:16","formula:25"],"connector":{"source":"tanru","locus":"description"},"source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-tanru-formula"}},"formula:29":{"type":"formula","operator":"atom","predication":"predication:28","source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"formula:35":{"type":"formula","operator":"atom","predication":"predication:34","boundEventualities":["eventuality:31"],"source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"formula:38":{"type":"formula","operator":"atom","predication":"predication:37","source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"formula:39":{"type":"formula","operator":"and","children":["formula:29","formula:38"],"connector":{"source":"tanru","locus":"selbri"},"boundEventualities":["eventuality:6"],"source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"formula:40":{"type":"formula","operator":"not","children":["formula:39"],"source":{"span":{"byteStart":11,"byteEnd":28},"text":"na mulno se gusni","construct":"bridi-negation"}},"entity:1":{"type":"referent","category":"indexical","sort":"entity","indexical":"speaker"},"entity:2":{"type":"referent","category":"indexical","sort":"entity","indexical":"audience"},"entity:4":{"type":"referent","category":"indexical","sort":"entity","indexical":"here"},"entity:7":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1","body":"formula:11"},"source":{"span":{"byteStart":0,"byteEnd":10},"text":"lo li'imdu","construct":"description"}},"entity:8":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:9":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:12":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1","body":"formula:26"},"source":{"span":{"byteStart":32,"byteEnd":52},"text":"lo nalmucti se gusni","construct":"description"}},"entity:13":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:14":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:19":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:17"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:20":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:17"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:27":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:32":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:30"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:33":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:30"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"eventuality:3":{"type":"referent","denotation":"referential","category":"indexical","sort":"eventuality","indexical":"now"},"eventuality:6":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"eventuality:18":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-tanru-formula"}},"eventuality:31":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"eventuality/locution:41":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi"}},"relation:23":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"relation","body":"formula:22","parameters":["parameter:17"],"arity":1,"source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-tanru-formula"}},"relation:36":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"relation","body":"formula:35","parameters":["parameter:30"],"arity":1,"source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}}}} +{"version":"lojban-semantics-json-1","root":"utterance:5","objects":{"utterance:5":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:41","content":"formula:40","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi"}},"parameter:17":{"type":"parameter","sort":"entity","role":"propertySlot","introducedBy":"ce'u","source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-tanru-formula"}},"parameter:30":{"type":"parameter","sort":"entity","role":"propertySlot","introducedBy":"ce'u","source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"predication:10":{"type":"predication","relation":"li'imdu","arguments":{"x1":{"kind":"filled","value":"entity:7"},"x2":{"kind":"elided","value":"entity:8","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:9","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":3,"byteEnd":10},"text":"li'imdu","construct":"restrictive-predication"}},"predication:15":{"type":"predication","relation":"gusni","arguments":{"x1":{"kind":"elided","value":"entity:13","introducedBy":"zo'e"},"x2":{"kind":"filled","value":"entity:12"},"x3":{"kind":"elided","value":"entity:14","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-predication"}},"predication:21":{"type":"predication","eventuality":"eventuality:18","relation":"nalmucti","arguments":{"x1":{"kind":"filled","value":"parameter:17"},"x2":{"kind":"elided","value":"entity:19","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:20","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-tanru-formula"}},"predication:24":{"type":"predication","tanruLink":{"head":"predication:15","modifier":"relation:23","relationLabel":"nalmucti-gusni"},"arguments":{"x1":{"kind":"filled","value":"entity:12"},"x2":{"kind":"filled","value":"relation:23"}},"mode":"restrictive","source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-tanru-formula"}},"predication:28":{"type":"predication","eventuality":"eventuality:6","relation":"gusni","arguments":{"x1":{"kind":"elided","value":"entity:27","introducedBy":"zo'e"},"x2":{"kind":"filled","value":"entity:7"},"x3":{"kind":"filled","value":"entity:12"}},"mode":"asserted","source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"predication:34":{"type":"predication","eventuality":"eventuality:31","relation":"mulno","arguments":{"x1":{"kind":"filled","value":"parameter:30"},"x2":{"kind":"elided","value":"entity:32","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:33","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"predication:37":{"type":"predication","tanruLink":{"head":"predication:28","modifier":"relation:36","relationLabel":"mulno-gusni"},"arguments":{"x1":{"kind":"filled","value":"entity:7"},"x2":{"kind":"filled","value":"relation:36"}},"mode":"asserted","source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"formula:11":{"type":"formula","operator":"atom","predication":"predication:10","source":{"span":{"byteStart":3,"byteEnd":10},"text":"li'imdu","construct":"restrictive-formula"}},"formula:16":{"type":"formula","operator":"atom","predication":"predication:15","source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-predication"}},"formula:22":{"type":"formula","operator":"atom","predication":"predication:21","boundEventualities":["eventuality:18"],"source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-tanru-formula"}},"formula:25":{"type":"formula","operator":"atom","predication":"predication:24","source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-tanru-formula"}},"formula:26":{"type":"formula","operator":"and","children":["formula:16","formula:25"],"connector":{"source":{"kind":"implicitJuxtaposition"},"locus":"description"},"source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-tanru-formula"}},"formula:29":{"type":"formula","operator":"atom","predication":"predication:28","source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"formula:35":{"type":"formula","operator":"atom","predication":"predication:34","boundEventualities":["eventuality:31"],"source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"formula:38":{"type":"formula","operator":"atom","predication":"predication:37","source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"formula:39":{"type":"formula","operator":"and","children":["formula:29","formula:38"],"connector":{"source":{"kind":"implicitJuxtaposition"},"locus":"predicate"},"boundEventualities":["eventuality:6"],"source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"formula:40":{"type":"formula","operator":"not","children":["formula:39"],"source":{"span":{"byteStart":11,"byteEnd":28},"text":"na mulno se gusni","construct":"bridi-negation"}},"entity:1":{"type":"referent","category":"indexical","sort":"entity","indexical":"speaker"},"entity:2":{"type":"referent","category":"indexical","sort":"entity","indexical":"audience"},"entity:4":{"type":"referent","category":"indexical","sort":"entity","indexical":"here"},"entity:7":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1","body":"formula:11"},"source":{"span":{"byteStart":0,"byteEnd":10},"text":"lo li'imdu","construct":"description"}},"entity:8":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:9":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:12":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1","body":"formula:26"},"source":{"span":{"byteStart":32,"byteEnd":52},"text":"lo nalmucti se gusni","construct":"description"}},"entity:13":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:14":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:19":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:17"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:20":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:17"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:27":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:32":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:30"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:33":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:30"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"eventuality:3":{"type":"referent","denotation":"referential","category":"indexical","sort":"eventuality","indexical":"now"},"eventuality:6":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"eventuality:18":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-tanru-formula"}},"eventuality:31":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}},"eventuality/locution:41":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi"}},"relation:23":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"relation","body":"formula:22","parameters":["parameter:17"],"arity":1,"source":{"span":{"byteStart":35,"byteEnd":52},"text":"nalmucti se gusni","construct":"restrictive-tanru-formula"}},"relation:36":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"relation","body":"formula:35","parameters":["parameter:30"],"arity":1,"source":{"span":{"byteStart":0,"byteEnd":52},"text":"lo li'imdu na mulno se gusni fi lo nalmucti se gusni","construct":"bridi-formula"}}}} diff --git a/crates/jbotci-semantics/tests/xml_corpus/b55.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b55.xml.txt index 5123dc28d9..9f67ab91d9 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b55.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b55.xml.txt @@ -1,34 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (28 records: spans, witness text, construct labels) - descriptor *.word provenance (2 fields) - *.introducedBy provenance (11 fields) - kind-composition relation-label provenance (2 fields) - @@ -40,116 +63,44 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/crates/jbotci-semantics/tests/xml_corpus/b57.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b57.xml.txt index 90a3bea5b2..f5da5451a6 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b57.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b57.xml.txt @@ -1,32 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (11 records: spans, witness text, construct labels) - bound-variable surface word provenance (1 field) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/b58.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/b58.xml.txt index 30370b441d..50543ada7d 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/b58.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/b58.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (8 records: spans, witness text, construct labels) - descriptor *.word provenance (1 field) - *.introducedBy provenance (2 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/medium-quantified.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/medium-quantified.xml.txt index 7e544c8b10..46be1a52fa 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/medium-quantified.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/medium-quantified.xml.txt @@ -1,34 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (28 records: spans, witness text, construct labels) - descriptor *.word provenance (4 fields) - *.introducedBy provenance (4 fields) - quantity value text provenance (2 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/numeral-price.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/numeral-price.xml.txt index 791aa559ba..4c076f161d 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/numeral-price.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/numeral-price.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (18 records: spans, witness text, construct labels) - descriptor *.word provenance (2 fields) - *.introducedBy provenance (7 fields) - diff --git a/crates/jbotci-semantics/tests/xml_corpus/paragraph-narrative.frozen.json b/crates/jbotci-semantics/tests/xml_corpus/paragraph-narrative.frozen.json index fcb2c207b5..445ee70250 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/paragraph-narrative.frozen.json +++ b/crates/jbotci-semantics/tests/xml_corpus/paragraph-narrative.frozen.json @@ -1 +1 @@ -{"version":"lojban-semantics-json-1","root":"sequence:81","objects":{"utterance:5":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:20","content":"formula:19","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":0,"byteEnd":20},"text":"mi pu klama lo zarci","construct":"bridi"}},"utterance:6":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:42","content":"formula:41","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":24,"byteEnd":71},"text":"le nanmu poi mi viska ke'a cu dunda lo cukta mi","construct":"bridi"}},"utterance:7":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:66","content":"formula:65","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":75,"byteEnd":109},"text":"mi jinvi lo du'u le cukta cu melbi","construct":"bridi"}},"utterance:8":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:79","content":"formula:78","deicticGround":{"time":"eventuality:3","place":"entity:4"},"asides":["display:80"],"source":{"span":{"byteStart":118,"byteEnd":144},"text":"mi na djica lo nu mi cilre","construct":"bridi"}},"sequence:81":{"type":"sequence","items":["utterance:5","utterance:6","utterance:7","utterance:8"],"relation":"same-topic-continuation","source":{"span":{"byteStart":0,"byteEnd":144},"text":"mi pu klama lo zarci .i le nanmu poi mi viska ke'a cu dunda lo cukta mi .i mi jinvi lo du'u le cukta cu melbi .i ku'i mi na djica lo nu mi cilre","construct":"text"}},"parameter:23":{"type":"parameter","sort":"entity","role":"propertySlot","introducedBy":"ce'u","source":{"span":{"byteStart":27,"byteEnd":32},"text":"nanmu","construct":"speaker-description-property"}},"parameter:46":{"type":"parameter","sort":"entity","role":"propertySlot","introducedBy":"ce'u","source":{"span":{"byteStart":95,"byteEnd":100},"text":"cukta","construct":"speaker-description-property"}},"predication:13":{"type":"predication","relation":"zarci","arguments":{"x1":{"kind":"filled","value":"entity:10"},"x2":{"kind":"elided","value":"entity:11","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:12","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":15,"byteEnd":20},"text":"zarci","construct":"restrictive-predication"}},"predication:18":{"type":"predication","eventuality":"eventuality:9","relation":"klama","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"filled","value":"entity:10"},"x3":{"kind":"elided","value":"entity:15","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:16","introducedBy":"zo'e"},"x5":{"kind":"elided","value":"entity:17","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":0,"byteEnd":20},"text":"mi pu klama lo zarci","construct":"predication"}},"predication:24":{"type":"predication","relation":"nanmu","arguments":{"x1":{"kind":"filled","value":"parameter:23"}},"mode":"restrictive","source":{"span":{"byteStart":27,"byteEnd":32},"text":"nanmu","construct":"restrictive-predication"}},"predication:27":{"type":"predication","relation":"skicu","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"filled","value":"entity:22"},"x3":{"kind":"filled","value":"entity:2"},"x4":{"kind":"filled","value":"relation:26"}},"mode":"incidental","source":{"span":{"byteStart":24,"byteEnd":50},"text":"le nanmu poi mi viska ke'a","construct":"speaker-description"}},"predication:31":{"type":"predication","eventuality":"eventuality:29","relation":"viska","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"filled","value":"entity:22"},"x3":{"kind":"elided","value":"entity:30","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":37,"byteEnd":50},"text":"mi viska ke'a","construct":"predication"}},"predication:38":{"type":"predication","relation":"cukta","arguments":{"x1":{"kind":"filled","value":"entity:33"},"x2":{"kind":"elided","value":"entity:34","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:35","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:36","introducedBy":"zo'e"},"x5":{"kind":"elided","value":"entity:37","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":63,"byteEnd":68},"text":"cukta","construct":"restrictive-predication"}},"predication:40":{"type":"predication","eventuality":"eventuality:21","relation":"dunda","arguments":{"x1":{"kind":"filled","value":"entity:22"},"x2":{"kind":"filled","value":"entity:33"},"x3":{"kind":"filled","value":"entity:1"}},"mode":"asserted","source":{"span":{"byteStart":24,"byteEnd":71},"text":"le nanmu poi mi viska ke'a cu dunda lo cukta mi","construct":"predication"}},"predication:51":{"type":"predication","relation":"cukta","arguments":{"x1":{"kind":"filled","value":"parameter:46"},"x2":{"kind":"elided","value":"entity:47","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:48","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:49","introducedBy":"zo'e"},"x5":{"kind":"elided","value":"entity:50","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":95,"byteEnd":100},"text":"cukta","construct":"restrictive-predication"}},"predication:54":{"type":"predication","relation":"skicu","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"filled","value":"entity:45"},"x3":{"kind":"filled","value":"entity:2"},"x4":{"kind":"filled","value":"relation:53"}},"mode":"incidental","source":{"span":{"byteStart":92,"byteEnd":100},"text":"le cukta","construct":"speaker-description"}},"predication:59":{"type":"predication","eventuality":"eventuality:44","relation":"melbi","arguments":{"x1":{"kind":"filled","value":"entity:45"},"x2":{"kind":"elided","value":"entity:56","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:57","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:58","introducedBy":"zo'e"}},"mode":"inert","source":{"span":{"byteStart":92,"byteEnd":109},"text":"le cukta cu melbi","construct":"predication"}},"predication:64":{"type":"predication","eventuality":"eventuality:43","relation":"jinvi","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"filled","value":"proposition:61"},"x3":{"kind":"elided","value":"entity:62","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:63","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":75,"byteEnd":109},"text":"mi jinvi lo du'u le cukta cu melbi","construct":"predication"}},"predication:73":{"type":"predication","eventuality":"eventuality:68","relation":"cilre","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"elided","value":"entity:69","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:70","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:71","introducedBy":"zo'e"},"x5":{"kind":"elided","value":"entity:72","introducedBy":"zo'e"}},"mode":"inert","source":{"span":{"byteStart":136,"byteEnd":144},"text":"mi cilre","construct":"predication"}},"predication:76":{"type":"predication","eventuality":"eventuality:67","relation":"djica","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"filled","value":"eventuality:68"},"x3":{"kind":"elided","value":"entity:75","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":118,"byteEnd":144},"text":"mi na djica lo nu mi cilre","construct":"bridi-formula"}},"formula:14":{"type":"formula","operator":"atom","predication":"predication:13","source":{"span":{"byteStart":15,"byteEnd":20},"text":"zarci","construct":"restrictive-formula"}},"formula:19":{"type":"formula","operator":"atom","predication":"predication:18","boundEventualities":["eventuality:9"],"source":{"span":{"byteStart":0,"byteEnd":20},"text":"mi pu klama lo zarci","construct":"bridi-formula"}},"formula:25":{"type":"formula","operator":"atom","predication":"predication:24","source":{"span":{"byteStart":27,"byteEnd":32},"text":"nanmu","construct":"restrictive-formula"}},"formula:28":{"type":"formula","operator":"atom","predication":"predication:27","source":{"span":{"byteStart":24,"byteEnd":50},"text":"le nanmu poi mi viska ke'a","construct":"speaker-description"}},"formula:32":{"type":"formula","operator":"atom","predication":"predication:31","boundEventualities":["eventuality:29"],"source":{"span":{"byteStart":37,"byteEnd":50},"text":"mi viska ke'a","construct":"bridi-formula"}},"formula:39":{"type":"formula","operator":"atom","predication":"predication:38","source":{"span":{"byteStart":63,"byteEnd":68},"text":"cukta","construct":"restrictive-formula"}},"formula:41":{"type":"formula","operator":"atom","predication":"predication:40","boundEventualities":["eventuality:21"],"source":{"span":{"byteStart":24,"byteEnd":71},"text":"le nanmu poi mi viska ke'a cu dunda lo cukta mi","construct":"bridi-formula"}},"formula:52":{"type":"formula","operator":"atom","predication":"predication:51","source":{"span":{"byteStart":95,"byteEnd":100},"text":"cukta","construct":"restrictive-formula"}},"formula:55":{"type":"formula","operator":"atom","predication":"predication:54","source":{"span":{"byteStart":92,"byteEnd":100},"text":"le cukta","construct":"speaker-description"}},"formula:60":{"type":"formula","operator":"atom","predication":"predication:59","boundEventualities":["eventuality:44"],"source":{"span":{"byteStart":92,"byteEnd":109},"text":"le cukta cu melbi","construct":"bridi-formula"}},"formula:65":{"type":"formula","operator":"atom","predication":"predication:64","boundEventualities":["eventuality:43"],"source":{"span":{"byteStart":75,"byteEnd":109},"text":"mi jinvi lo du'u le cukta cu melbi","construct":"bridi-formula"}},"formula:74":{"type":"formula","operator":"atom","predication":"predication:73","source":{"span":{"byteStart":136,"byteEnd":144},"text":"mi cilre","construct":"bridi-formula"}},"formula:77":{"type":"formula","operator":"atom","predication":"predication:76","boundEventualities":["eventuality:67"],"source":{"span":{"byteStart":118,"byteEnd":144},"text":"mi na djica lo nu mi cilre","construct":"bridi-formula"}},"formula:78":{"type":"formula","operator":"not","children":["formula:77"],"source":{"span":{"byteStart":121,"byteEnd":129},"text":"na djica","construct":"bridi-negation"}},"display:80":{"type":"displayedContent","relation":"ku'i","family":"metalinguistic","polarity":"positive","assertionEffect":"none","experiencer":"entity:1","target":"formula:78","targetFocus":"bridi","anchor":"utterance:8","source":{"span":{"byteStart":113,"byteEnd":117},"text":"ku'i","construct":"indicator"}},"entity:1":{"type":"referent","category":"indexical","sort":"entity","indexical":"speaker"},"entity:2":{"type":"referent","category":"indexical","sort":"entity","indexical":"audience"},"entity:4":{"type":"referent","category":"indexical","sort":"entity","indexical":"here"},"entity:10":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1","body":"formula:14"},"source":{"span":{"byteStart":12,"byteEnd":20},"text":"lo zarci","construct":"description"}},"entity:11":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:12":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:15":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:16":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:17":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:22":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"speakerDescription","word":"le","speaker":"entity:1","body":"formula:28","relativeClauses":[{"kind":"restrictive","body":"formula:32","source":{"span":{"byteStart":37,"byteEnd":50},"text":"mi viska ke'a","construct":"relative-clause"}}]},"source":{"span":{"byteStart":24,"byteEnd":50},"text":"le nanmu poi mi viska ke'a","construct":"description"}},"entity:30":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:33":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1","body":"formula:39"},"source":{"span":{"byteStart":60,"byteEnd":68},"text":"lo cukta","construct":"description"}},"entity:34":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:35":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:36":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:37":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:45":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"speakerDescription","word":"le","speaker":"entity:1","body":"formula:55"},"source":{"span":{"byteStart":92,"byteEnd":100},"text":"le cukta","construct":"description"}},"entity:47":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:46"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:48":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:46"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:49":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:46"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:50":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:46"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:56":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:57":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:58":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:62":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:63":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:69":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:70":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:71":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:72":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:75":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"eventuality:3":{"type":"referent","denotation":"referential","category":"indexical","sort":"eventuality","indexical":"now"},"eventuality:9":{"type":"referent","denotation":"generated-bound","time":{"relation":"before","anchor":"eventuality:3"},"sort":"eventuality","source":{"span":{"byteStart":0,"byteEnd":20},"text":"mi pu klama lo zarci","construct":"predication"}},"eventuality:21":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":24,"byteEnd":71},"text":"le nanmu poi mi viska ke'a cu dunda lo cukta mi","construct":"predication"}},"eventuality:29":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":37,"byteEnd":50},"text":"mi viska ke'a","construct":"predication"}},"eventuality:43":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":75,"byteEnd":109},"text":"mi jinvi lo du'u le cukta cu melbi","construct":"predication"}},"eventuality:44":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":92,"byteEnd":109},"text":"le cukta cu melbi","construct":"predication"}},"eventuality:67":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":118,"byteEnd":144},"text":"mi na djica lo nu mi cilre","construct":"bridi-formula"}},"eventuality:68":{"type":"referent","denotation":"referential","content":"formula:74","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1"},"source":{"span":{"byteStart":130,"byteEnd":144},"text":"lo nu mi cilre","construct":"description"}},"eventuality/locution:20":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":0,"byteEnd":20},"text":"mi pu klama lo zarci","construct":"bridi"}},"eventuality/locution:42":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":24,"byteEnd":71},"text":"le nanmu poi mi viska ke'a cu dunda lo cukta mi","construct":"bridi"}},"eventuality/locution:66":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":75,"byteEnd":109},"text":"mi jinvi lo du'u le cukta cu melbi","construct":"bridi"}},"eventuality/locution:79":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":118,"byteEnd":144},"text":"mi na djica lo nu mi cilre","construct":"bridi"}},"proposition:61":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"proposition","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1"},"body":"formula:60","source":{"span":{"byteStart":84,"byteEnd":109},"text":"lo du'u le cukta cu melbi","construct":"description"}},"relation:26":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"relation","body":"formula:25","parameters":["parameter:23"],"arity":1,"source":{"span":{"byteStart":27,"byteEnd":32},"text":"nanmu","construct":"speaker-description-property"}},"relation:53":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"relation","body":"formula:52","parameters":["parameter:46"],"arity":1,"source":{"span":{"byteStart":95,"byteEnd":100},"text":"cukta","construct":"speaker-description-property"}}}} +{"version":"lojban-semantics-json-1","root":"sequence:81","objects":{"utterance:5":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:20","content":"formula:19","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":0,"byteEnd":20},"text":"mi pu klama lo zarci","construct":"bridi"}},"utterance:6":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:42","content":"formula:41","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":24,"byteEnd":71},"text":"le nanmu poi mi viska ke'a cu dunda lo cukta mi","construct":"bridi"}},"utterance:7":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:66","content":"formula:65","deicticGround":{"time":"eventuality:3","place":"entity:4"},"source":{"span":{"byteStart":75,"byteEnd":109},"text":"mi jinvi lo du'u le cukta cu melbi","construct":"bridi"}},"utterance:8":{"type":"utterance","force":"assert","speaker":"entity:1","audience":"entity:2","eventuality":"eventuality/locution:79","content":"formula:78","deicticGround":{"time":"eventuality:3","place":"entity:4"},"asides":["display:80"],"source":{"span":{"byteStart":118,"byteEnd":144},"text":"mi na djica lo nu mi cilre","construct":"bridi"}},"sequence:81":{"type":"sequence","items":["utterance:5","utterance:6","utterance:7","utterance:8"],"relation":"same-topic-continuation","source":{"span":{"byteStart":0,"byteEnd":144},"text":"mi pu klama lo zarci .i le nanmu poi mi viska ke'a cu dunda lo cukta mi .i mi jinvi lo du'u le cukta cu melbi .i ku'i mi na djica lo nu mi cilre","construct":"text"}},"parameter:23":{"type":"parameter","sort":"entity","role":"propertySlot","introducedBy":"ce'u","source":{"span":{"byteStart":27,"byteEnd":32},"text":"nanmu","construct":"speaker-description-property"}},"parameter:46":{"type":"parameter","sort":"entity","role":"propertySlot","introducedBy":"ce'u","source":{"span":{"byteStart":95,"byteEnd":100},"text":"cukta","construct":"speaker-description-property"}},"predication:13":{"type":"predication","relation":"zarci","arguments":{"x1":{"kind":"filled","value":"entity:10"},"x2":{"kind":"elided","value":"entity:11","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:12","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":15,"byteEnd":20},"text":"zarci","construct":"restrictive-predication"}},"predication:18":{"type":"predication","eventuality":"eventuality:9","relation":"klama","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"filled","value":"entity:10"},"x3":{"kind":"elided","value":"entity:15","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:16","introducedBy":"zo'e"},"x5":{"kind":"elided","value":"entity:17","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":0,"byteEnd":20},"text":"mi pu klama lo zarci","construct":"predication"}},"predication:24":{"type":"predication","relation":"nanmu","arguments":{"x1":{"kind":"filled","value":"parameter:23"}},"mode":"restrictive","source":{"span":{"byteStart":27,"byteEnd":32},"text":"nanmu","construct":"restrictive-predication"}},"predication:27":{"type":"predication","relation":"skicu","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"filled","value":"entity:22"},"x3":{"kind":"filled","value":"entity:2"},"x4":{"kind":"filled","value":"relation:26"}},"mode":"incidental","source":{"span":{"byteStart":24,"byteEnd":50},"text":"le nanmu poi mi viska ke'a","construct":"speaker-description"}},"predication:31":{"type":"predication","eventuality":"eventuality:29","relation":"viska","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"filled","value":"entity:22"},"x3":{"kind":"elided","value":"entity:30","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":37,"byteEnd":50},"text":"mi viska ke'a","construct":"predication"}},"predication:38":{"type":"predication","relation":"cukta","arguments":{"x1":{"kind":"filled","value":"entity:33"},"x2":{"kind":"elided","value":"entity:34","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:35","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:36","introducedBy":"zo'e"},"x5":{"kind":"elided","value":"entity:37","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":63,"byteEnd":68},"text":"cukta","construct":"restrictive-predication"}},"predication:40":{"type":"predication","eventuality":"eventuality:21","relation":"dunda","arguments":{"x1":{"kind":"filled","value":"entity:22"},"x2":{"kind":"filled","value":"entity:33"},"x3":{"kind":"filled","value":"entity:1"}},"mode":"asserted","source":{"span":{"byteStart":24,"byteEnd":71},"text":"le nanmu poi mi viska ke'a cu dunda lo cukta mi","construct":"predication"}},"predication:51":{"type":"predication","relation":"cukta","arguments":{"x1":{"kind":"filled","value":"parameter:46"},"x2":{"kind":"elided","value":"entity:47","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:48","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:49","introducedBy":"zo'e"},"x5":{"kind":"elided","value":"entity:50","introducedBy":"zo'e"}},"mode":"restrictive","source":{"span":{"byteStart":95,"byteEnd":100},"text":"cukta","construct":"restrictive-predication"}},"predication:54":{"type":"predication","relation":"skicu","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"filled","value":"entity:45"},"x3":{"kind":"filled","value":"entity:2"},"x4":{"kind":"filled","value":"relation:53"}},"mode":"incidental","source":{"span":{"byteStart":92,"byteEnd":100},"text":"le cukta","construct":"speaker-description"}},"predication:59":{"type":"predication","eventuality":"eventuality:44","relation":"melbi","arguments":{"x1":{"kind":"filled","value":"entity:45"},"x2":{"kind":"elided","value":"entity:56","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:57","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:58","introducedBy":"zo'e"}},"mode":"inert","source":{"span":{"byteStart":92,"byteEnd":109},"text":"le cukta cu melbi","construct":"predication"}},"predication:64":{"type":"predication","eventuality":"eventuality:43","relation":"jinvi","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"filled","value":"proposition:61"},"x3":{"kind":"elided","value":"entity:62","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:63","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":75,"byteEnd":109},"text":"mi jinvi lo du'u le cukta cu melbi","construct":"predication"}},"predication:73":{"type":"predication","eventuality":"eventuality:68","relation":"cilre","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"elided","value":"entity:69","introducedBy":"zo'e"},"x3":{"kind":"elided","value":"entity:70","introducedBy":"zo'e"},"x4":{"kind":"elided","value":"entity:71","introducedBy":"zo'e"},"x5":{"kind":"elided","value":"entity:72","introducedBy":"zo'e"}},"mode":"inert","source":{"span":{"byteStart":136,"byteEnd":144},"text":"mi cilre","construct":"predication"}},"predication:76":{"type":"predication","eventuality":"eventuality:67","relation":"djica","arguments":{"x1":{"kind":"filled","value":"entity:1"},"x2":{"kind":"filled","value":"eventuality:68"},"x3":{"kind":"elided","value":"entity:75","introducedBy":"zo'e"}},"mode":"asserted","source":{"span":{"byteStart":118,"byteEnd":144},"text":"mi na djica lo nu mi cilre","construct":"bridi-formula"}},"formula:14":{"type":"formula","operator":"atom","predication":"predication:13","source":{"span":{"byteStart":15,"byteEnd":20},"text":"zarci","construct":"restrictive-formula"}},"formula:19":{"type":"formula","operator":"atom","predication":"predication:18","boundEventualities":["eventuality:9"],"source":{"span":{"byteStart":0,"byteEnd":20},"text":"mi pu klama lo zarci","construct":"bridi-formula"}},"formula:25":{"type":"formula","operator":"atom","predication":"predication:24","source":{"span":{"byteStart":27,"byteEnd":32},"text":"nanmu","construct":"restrictive-formula"}},"formula:28":{"type":"formula","operator":"atom","predication":"predication:27","source":{"span":{"byteStart":24,"byteEnd":50},"text":"le nanmu poi mi viska ke'a","construct":"speaker-description"}},"formula:32":{"type":"formula","operator":"atom","predication":"predication:31","boundEventualities":["eventuality:29"],"source":{"span":{"byteStart":37,"byteEnd":50},"text":"mi viska ke'a","construct":"bridi-formula"}},"formula:39":{"type":"formula","operator":"atom","predication":"predication:38","source":{"span":{"byteStart":63,"byteEnd":68},"text":"cukta","construct":"restrictive-formula"}},"formula:41":{"type":"formula","operator":"atom","predication":"predication:40","boundEventualities":["eventuality:21"],"source":{"span":{"byteStart":24,"byteEnd":71},"text":"le nanmu poi mi viska ke'a cu dunda lo cukta mi","construct":"bridi-formula"}},"formula:52":{"type":"formula","operator":"atom","predication":"predication:51","source":{"span":{"byteStart":95,"byteEnd":100},"text":"cukta","construct":"restrictive-formula"}},"formula:55":{"type":"formula","operator":"atom","predication":"predication:54","source":{"span":{"byteStart":92,"byteEnd":100},"text":"le cukta","construct":"speaker-description"}},"formula:60":{"type":"formula","operator":"atom","predication":"predication:59","boundEventualities":["eventuality:44"],"source":{"span":{"byteStart":92,"byteEnd":109},"text":"le cukta cu melbi","construct":"bridi-formula"}},"formula:65":{"type":"formula","operator":"atom","predication":"predication:64","boundEventualities":["eventuality:43"],"source":{"span":{"byteStart":75,"byteEnd":109},"text":"mi jinvi lo du'u le cukta cu melbi","construct":"bridi-formula"}},"formula:74":{"type":"formula","operator":"atom","predication":"predication:73","source":{"span":{"byteStart":136,"byteEnd":144},"text":"mi cilre","construct":"bridi-formula"}},"formula:77":{"type":"formula","operator":"atom","predication":"predication:76","boundEventualities":["eventuality:67"],"source":{"span":{"byteStart":118,"byteEnd":144},"text":"mi na djica lo nu mi cilre","construct":"bridi-formula"}},"formula:78":{"type":"formula","operator":"not","children":["formula:77"],"source":{"span":{"byteStart":121,"byteEnd":129},"text":"na djica","construct":"bridi-negation"}},"display:80":{"type":"displayedContent","relation":"ku'i","family":"metalinguistic","polarity":"positive","assertionEffect":"none","experiencer":"entity:1","target":"formula:78","targetFocus":"clause","anchor":"utterance:8","source":{"span":{"byteStart":113,"byteEnd":117},"text":"ku'i","construct":"indicator"}},"entity:1":{"type":"referent","category":"indexical","sort":"entity","indexical":"speaker"},"entity:2":{"type":"referent","category":"indexical","sort":"entity","indexical":"audience"},"entity:4":{"type":"referent","category":"indexical","sort":"entity","indexical":"here"},"entity:10":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1","body":"formula:14"},"source":{"span":{"byteStart":12,"byteEnd":20},"text":"lo zarci","construct":"description"}},"entity:11":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:12":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:15":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:16":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:17":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:22":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"speakerDescription","word":"le","speaker":"entity:1","body":"formula:28","relativeClauses":[{"kind":"restrictive","body":"formula:32","source":{"span":{"byteStart":37,"byteEnd":50},"text":"mi viska ke'a","construct":"relative-clause"}}]},"source":{"span":{"byteStart":24,"byteEnd":50},"text":"le nanmu poi mi viska ke'a","construct":"description"}},"entity:30":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:33":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1","body":"formula:39"},"source":{"span":{"byteStart":60,"byteEnd":68},"text":"lo cukta","construct":"description"}},"entity:34":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:35":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:36":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:37":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:45":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"speakerDescription","word":"le","speaker":"entity:1","body":"formula:55"},"source":{"span":{"byteStart":92,"byteEnd":100},"text":"le cukta","construct":"description"}},"entity:47":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:46"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:48":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:46"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:49":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:46"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:50":{"type":"referent","category":"constant","scopeDependence":{"kind":"underspecified","mayDependOn":["parameter:46"]},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:56":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:57":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:58":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:62":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:63":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:69":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:70":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:71":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:72":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"entity:75":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"entity","descriptor":{"kind":"elided","word":"zo'e"}},"eventuality:3":{"type":"referent","denotation":"referential","category":"indexical","sort":"eventuality","indexical":"now"},"eventuality:9":{"type":"referent","denotation":"generated-bound","time":{"relation":"before","anchor":"eventuality:3"},"sort":"eventuality","source":{"span":{"byteStart":0,"byteEnd":20},"text":"mi pu klama lo zarci","construct":"predication"}},"eventuality:21":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":24,"byteEnd":71},"text":"le nanmu poi mi viska ke'a cu dunda lo cukta mi","construct":"predication"}},"eventuality:29":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":37,"byteEnd":50},"text":"mi viska ke'a","construct":"predication"}},"eventuality:43":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":75,"byteEnd":109},"text":"mi jinvi lo du'u le cukta cu melbi","construct":"predication"}},"eventuality:44":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":92,"byteEnd":109},"text":"le cukta cu melbi","construct":"predication"}},"eventuality:67":{"type":"referent","denotation":"generated-bound","sort":"eventuality","source":{"span":{"byteStart":118,"byteEnd":144},"text":"mi na djica lo nu mi cilre","construct":"bridi-formula"}},"eventuality:68":{"type":"referent","denotation":"referential","content":"formula:74","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1"},"source":{"span":{"byteStart":130,"byteEnd":144},"text":"lo nu mi cilre","construct":"description"}},"eventuality/locution:20":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":0,"byteEnd":20},"text":"mi pu klama lo zarci","construct":"bridi"}},"eventuality/locution:42":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":24,"byteEnd":71},"text":"le nanmu poi mi viska ke'a cu dunda lo cukta mi","construct":"bridi"}},"eventuality/locution:66":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":75,"byteEnd":109},"text":"mi jinvi lo du'u le cukta cu melbi","construct":"bridi"}},"eventuality/locution:79":{"type":"referent","denotation":"referential","actuality":{"kind":"actual"},"category":"constant","scopeDependence":{"kind":"fixed"},"sort":"eventuality/locution","source":{"span":{"byteStart":118,"byteEnd":144},"text":"mi na djica lo nu mi cilre","construct":"bridi"}},"proposition:61":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"proposition","descriptor":{"kind":"veridicalDescription","word":"lo","speaker":"entity:1"},"body":"formula:60","source":{"span":{"byteStart":84,"byteEnd":109},"text":"lo du'u le cukta cu melbi","construct":"description"}},"relation:26":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"relation","body":"formula:25","parameters":["parameter:23"],"arity":1,"source":{"span":{"byteStart":27,"byteEnd":32},"text":"nanmu","construct":"speaker-description-property"}},"relation:53":{"type":"referent","category":"constant","scopeDependence":{"kind":"fixed"},"sort":"relation","body":"formula:52","parameters":["parameter:46"],"arity":1,"source":{"span":{"byteStart":95,"byteEnd":100},"text":"cukta","construct":"speaker-description-property"}}}} diff --git a/crates/jbotci-semantics/tests/xml_corpus/paragraph-narrative.xml.txt b/crates/jbotci-semantics/tests/xml_corpus/paragraph-narrative.xml.txt index f2ec874a52..33ab4ffd3c 100644 --- a/crates/jbotci-semantics/tests/xml_corpus/paragraph-narrative.xml.txt +++ b/crates/jbotci-semantics/tests/xml_corpus/paragraph-narrative.xml.txt @@ -1,33 +1,57 @@ + - - ID= marks the definition of a shared graph node except a speech-situation referent; DEICTIC-GROUND SPEAKER-REF=/AUDIENCE-REF=/TIME-REF=/PLACE-REF= values are the sole definition sites for those referent ids. REF= and named *-REF= attributes point to discourse referents. GROUND= points to a deictic-ground unit and is the sole suffix exception. Later REF= occurrences are exact-node reuse. Graph-node ids are opaque and JSON-aligned; distinct ids assert neither identity (=) nor non-identity (≠). - UPPERCASE = structural keywords (element and attribute names); PascalCase = sorts; lowercase = content words as data values only; quoted attribute strings = names. - SORT= values are flat PascalCase sort names. Subtype facts derived from encountered JSON sort paths: Locution ⊂ Eventuality. LOCUTION implies sort Locution and therefore omits SORT=. - EMBEDDED-QUESTIONS preserves typed QUESTION metadata attached to the abstraction formula named by QUESTION/BODY. KIND, MODE, and DOMAIN classify the question; ASKER, RESPONDENT, SLOTS, FOCUS, and PRESUPPOSED-ANSWER preserve its participants. SLOT parameters bind only the question BODY. - KIND-COMPOSITION is first-class predication content: MODIFIER A of KIND B denotes an A-modified kind of B while retaining B's place structure. The exact modifier-to-kind relation remains unspecified; nesting preserves the semantic graph's grouping. RELATION-LABEL is derivational provenance and appears only in provenance mode. - Each semantic diagnostic is one repeatable WARNING text element; its character content is the diagnostic message. - REF="SOME" denotes a distinct elided node per occurrence; distinct nodes assert neither identity (=) nor non-identity (≠). - DEICTIC-GROUND is the shared speech-situation unit selected by UTTERANCE GROUND=. Its g-prefixed ID is a notation-level rendering id because the JSON has no ground object id; if the graph gains context ids, the rendering must align. Ground units share one definition ⇔ their SPEAKER-REF/AUDIENCE-REF/TIME-REF/PLACE-REF graph referents are pairwise identical. - EXISTS, FORALL, and CARDINALITY are binder elements; VARIABLE defines its variable ID=/SORT= at the binder site; use sites carry REF=. RESTRICTION and BODY are loud sibling elements; EXISTS writes RESTRICTION exactly when the graph supplies one; FORALL and CARDINALITY always write RESTRICTION explicitly, empty as RESTRICTION/. - Scope-dependence markers compare a referent's scopeDependence with the semantic graph derivation's authoritative first-visit binder universe, which is not a lexical-enclosure set. Silence means that the referent may depend on the full first-visit universe. SAME-FOR-ALL means that it is fixed despite a nonempty first-visit universe. - POSSIBLY-DIFFERENT-PER= is a space-separated strict nonempty subset of the first-visit quantifier-variable or abstraction/question-parameter ids on which a referent may depend. - References are number-neutral: a reference may denote one or several individuals; the only number commitments are explicit quantities on descriptions, cardinality binders, or mass restrictions. - PERSONAL-MASS-MEMBERSHIP states whether SPEAKER and AUDIENCE are INCLUDED or EXCLUDED and points to any additional included OTHERS. DEICTIC-REFERENCE states PROXIMITY to a discourse-referent GROUND-REF. These structures carry the semantics; no pro-sumti label is implied. - A description is anchored to its enclosing utterance's speaker. SPEAKER-REF= on a description, or BY inside NAMED, appears only when the anchor differs from that enclosing speaker. - Absent facet attribute ⇒ UNSPECIFIED (no commitment). Facet attributes: TIME, ACTUALITY, ASPECT, RECURRENCE, SPACE, SPATIAL-ASPECT, SPATIAL-RECURRENCE, DETAILS. - EVENT is the reserved first child of a PREDICATION, its Eventuality referent, never a numbered ARG. - ADJUNCT introduces a predicate-keyed optional participant of the host predication; PREDICATE= with flat ARG children is the compact single-lexical-predicate place map; without PREDICATE=, BODY carries the composite predicate subtree; ARG FILL="true" marks the unique explicit non-host filled place; a non-unique graph stays complete and carries FILL-STATUS; APPLIES-TO links the host component. - UNRESOLVED-REFERENT WORD= is a word-only stopgap only for referents that remain unresolved after the jbotci#690 KOhA audit; the quoted WORD value is the stopgap's whole content. Bound-variable surface words are provenance-only. - MODE vocabulary: ASSERTED=main claim; RESTRICTIVE=restriction; INCIDENTAL=side claim; INERT=embedded nonclaim; DEFINITIONAL=identity definition; PERFORMATIVE=speech act. MODE is a required attribute on PREDICATION. - Every non-binder graph-node definition and every DEICTIC-GROUND definition sits in DEFS in the smallest graph scope strictly containing all uses; an attribute reference on element X is a use at X's position. Quantifier VARIABLE precedes its scope's DEFS; all graph-node uses outside their definition site are references. - A list of simple ids or numbers is a space-separated NMTOKENS attribute, never a sequence of child elements; semantic structure remains element-valued. - Child order is fixed per element; CONNECTIVE child order is semantically significant; childless elements self-close. - - - *.source provenance (54 records: spans, witness text, construct labels) - descriptor *.word provenance (6 fields) - *.introducedBy provenance (26 fields) - @@ -36,7 +60,7 @@