Skip to content
378 changes: 372 additions & 6 deletions src/v4/extdeps/languages/typescript.dag
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
// src/v4/extdeps/languages/typescript.dag
// Scope: TypeScript 5.9 + ECMA-262 ES2025 primitive D2 resolver slice (T-4 typescript).
// Owns: TsEcma262NumericPrimitiveKind, TsEcma262PrimitiveOperationSemantics, ts_bool_grounding
// Consumes: v4.std.logic (Bool, bool_boolean_algebra); v4.std.algebra (BooleanAlgebra).
// Status: ts_bool_grounding decl-ref present + v2-parse-verified — 🟡 P2/E-6 STAGING (no same-PR consumer; canonical fold specified-not-realized); non-bool numeric primitives 🟡 gated D2→fact-bundle debt (T-4 Phase-3 rework, node://adhoc-71ec74f4-080).
// Scope: TypeScript 5.9 + ECMA-262 ES2025 numeric primitive fact-bundles and ModelCore wave-1.
// Owns: TsEcma262NumericPrimitiveKind, TsEcma262PrimitiveOperationSemantics, TsNumberPrimitiveFacts, TsBigIntPrimitiveFacts, TsLanguageModel, ts_*_facts, ts_*_inhabitant_node, ts_declared_inhabitants_root, ts_wave1_* ModelCore, ts_bool_grounding.
// Consumes: v4.std.collection, v4.std.node, v4.std.logic, v4.std.algebra, v4.std.model_core.
// Status: T-4 typescript slice — ECMA `number` (IEEE-754 binary64) + `bigint` (exact unbounded ℤ) fact-bundles; `core: ModelCore` primitives from `ts_numeric_facts_catalog` via fold; canonical_symbols = catalog surface spellings; bool canonical-B decl-ref — 🟡 E-6(b) staging; wave-1 lex/grammar deferred.
// Anchor: https://www.typescriptlang.org/docs/handbook/2/everyday-types.html — ECMA-262 https://tc39.es/ecma262/2025/multipage/
// Ledger: CP-3229-GREEN-TERMINAL.
// 🟡

module v4.extdeps.languages.typescript

import v4.std.collection { List, Set }
import v4.std.model_core {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BLOCKING: The new v4.std.model_core import names a module absent from the provided diff and from origin/main, so the v4 parse/resolve gate cannot resolve this PR’s ModelCore boundary.

EffectSemanticsDecl,
ModelCore,
PartialitySemanticsDecl,
PrimitiveFactAxisBinding,
PrimitiveFactBundle,
primitive_fact_axis_encoding,
primitive_fact_axis_surface_spelling,
primitive_fact_axis_width
}
import v4.std.node {
Atom,
Conj,
Edge,
Named,
Node,
Symbol,
TypeNode
}
import v4.std.logic { Bool, bool_boolean_algebra }
import v4.std.algebra { BooleanAlgebra }
import v4.std.algebra { BooleanAlgebra, free_monoid_fold }

// 🟢 coproduct dissolution · CP-3229-GREEN-TERMINAL.
type TsEcma262NumericPrimitiveKind
Expand All @@ -23,4 +42,351 @@ type TsEcma262PrimitiveOperationSemantics
| TsNumberBitwiseInt32Uint32Semantics
| TsBigIntExactUnboundedSemantics

type TsNumberPrimitiveFacts {
surface_spelling: Symbol
kind: TsEcma262NumericPrimitiveKind

This comment was marked as resolved.

arithmetic_semantics: TsEcma262PrimitiveOperationSemantics

This comment was marked as resolved.

bitwise_semantics: TsEcma262PrimitiveOperationSemantics
ieee754_binary: Symbol
std_projection: Symbol

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BLOCKING: std_projection: Symbol claims a std grounding through an opaque symbol instead of a typed std carrier or coincidence proof, violating T-4 fact-bundle grounding and MODELING M9.

}

type TsBigIntPrimitiveFacts {
surface_spelling: Symbol
kind: TsEcma262NumericPrimitiveKind
operation_semantics: TsEcma262PrimitiveOperationSemantics
std_projection: Symbol
encoding: Symbol
}

// 🟢 coproduct dissolution — catalog row tags number vs bigint fact carriers.
type TsEcma262NumericPrimitiveFactsUnion
= TsNumericFactsNumber { facts: TsNumberPrimitiveFacts }
| TsNumericFactsBigInt { facts: TsBigIntPrimitiveFacts }

type TsLanguageModel {
language_identity: Symbol
canonical_symbols: Set<Symbol>
core: ModelCore
}

data ts_language_model_surface_id: Symbol = ts_language_model_surface_id

data ts_std_projection_float64: Symbol = ts_std_projection_float64
data ts_std_projection_bigint: Symbol = ts_std_projection_bigint

data ts_surface_spelling_number: Symbol = ts_surface_spelling_number
data ts_surface_spelling_bigint: Symbol = ts_surface_spelling_bigint

data ts_ieee754_binary64: Symbol = ts_ieee754_binary64
data ts_repr_bigint_exact_unbounded: Symbol = ts_repr_bigint_exact_unbounded

data ts_inhabitant_number: Symbol = ts_inhabitant_number
data ts_inhabitant_bigint: Symbol = ts_inhabitant_bigint

data ts_inhabitant_field_number: Symbol = ts_inhabitant_field_number
data ts_inhabitant_field_bigint: Symbol = ts_inhabitant_field_bigint

data ts_inhabitant_field_atom: Symbol = ts_inhabitant_field_atom
data ts_inhabitant_field_facts: Symbol = ts_inhabitant_field_facts

data ts_facts_field_surface_spelling: Symbol = ts_facts_field_surface_spelling
data ts_facts_field_kind: Symbol = ts_facts_field_kind
data ts_facts_field_arithmetic_semantics: Symbol = ts_facts_field_arithmetic_semantics
data ts_facts_field_bitwise_semantics: Symbol = ts_facts_field_bitwise_semantics
data ts_facts_field_operation_semantics: Symbol = ts_facts_field_operation_semantics
data ts_facts_field_width: Symbol = ts_facts_field_width
data ts_facts_field_ieee754_binary: Symbol = ts_facts_field_ieee754_binary
data ts_facts_field_std_projection: Symbol = ts_facts_field_std_projection
data ts_facts_field_encoding: Symbol = ts_facts_field_encoding

data ts_tag_number_primitive: Symbol = ts_tag_number_primitive
data ts_tag_bigint_primitive: Symbol = ts_tag_bigint_primitive
data ts_tag_bits64: Symbol = ts_tag_bits64
data ts_tag_number_ieee754_binary64: Symbol = ts_tag_number_ieee754_binary64
data ts_tag_number_bitwise_int32_uint32: Symbol = ts_tag_number_bitwise_int32_uint32
data ts_tag_bigint_exact_unbounded: Symbol = ts_tag_bigint_exact_unbounded

data ts_facts_number: TsNumberPrimitiveFacts = TsNumberPrimitiveFacts {
surface_spelling: ts_surface_spelling_number,
kind: TsNumberPrimitive,
arithmetic_semantics: TsNumberIeee754Binary64Semantics,
bitwise_semantics: TsNumberBitwiseInt32Uint32Semantics,
ieee754_binary: ts_ieee754_binary64,
std_projection: ts_std_projection_float64,
}

data ts_facts_bigint: TsBigIntPrimitiveFacts = TsBigIntPrimitiveFacts {
surface_spelling: ts_surface_spelling_bigint,
kind: TsBigIntPrimitive,
operation_semantics: TsBigIntExactUnboundedSemantics,
std_projection: ts_std_projection_bigint,
encoding: ts_repr_bigint_exact_unbounded,
}

// Sole numeric primitive-fact list authority — ModelCore.primitives derives via fold.
data ts_numeric_facts_catalog: List<TsEcma262NumericPrimitiveFactsUnion> = [
TsNumericFactsNumber { facts: ts_facts_number },
TsNumericFactsBigInt { facts: ts_facts_bigint }
]

// 🟡 canonical-B decl-ref · E-6(b) bounded-exception · scaffold feature:canonical-b-grounding-consumer · dissolve-on: B1-CANON+zip-fold consume (ledger: B1·T-9/C1 · grounding-worked-examples.md §0)
data ts_bool_grounding: BooleanAlgebra<Bool> = bool_boolean_algebra

fn ts_inhabitant_atom(id: Symbol) -> Node {
Node {
kind: TypeNode { connective: Atom { identity: id } },
children: []
}
}

fn ts_named_edge(name: Symbol, target: Node) -> Edge {
Edge { label: Named { name: name }, target: target }
}

fn ts_numeric_kind_node(kind: TsEcma262NumericPrimitiveKind) -> Node {
match kind {
TsNumberPrimitive => ts_inhabitant_atom(id: ts_tag_number_primitive)
TsBigIntPrimitive => ts_inhabitant_atom(id: ts_tag_bigint_primitive)
}
}

fn ts_operation_semantics_node(sem: TsEcma262PrimitiveOperationSemantics) -> Node {
match sem {
TsNumberIeee754Binary64Semantics =>
ts_inhabitant_atom(id: ts_tag_number_ieee754_binary64)
TsNumberBitwiseInt32Uint32Semantics =>
ts_inhabitant_atom(id: ts_tag_number_bitwise_int32_uint32)
TsBigIntExactUnboundedSemantics =>
ts_inhabitant_atom(id: ts_tag_bigint_exact_unbounded)
}
}

fn ts_number_facts_node(facts: TsNumberPrimitiveFacts) -> Node {
Node {
kind: TypeNode { connective: Conj },
children: [
ts_named_edge(
name: ts_facts_field_surface_spelling,
target: ts_inhabitant_atom(id: facts.surface_spelling)
),
ts_named_edge(
name: ts_facts_field_kind,
target: ts_numeric_kind_node(kind: facts.kind)
),
ts_named_edge(
name: ts_facts_field_arithmetic_semantics,
target: ts_operation_semantics_node(sem: facts.arithmetic_semantics)
),
ts_named_edge(
name: ts_facts_field_bitwise_semantics,
target: ts_operation_semantics_node(sem: facts.bitwise_semantics)
),
ts_named_edge(
name: ts_facts_field_width,
target: ts_inhabitant_atom(id: ts_tag_bits64)
),
ts_named_edge(
name: ts_facts_field_ieee754_binary,
target: ts_inhabitant_atom(id: facts.ieee754_binary)
),
ts_named_edge(
name: ts_facts_field_std_projection,
target: ts_inhabitant_atom(id: facts.std_projection)
)
]
}
}

fn ts_bigint_facts_node(facts: TsBigIntPrimitiveFacts) -> Node {
Node {
kind: TypeNode { connective: Conj },
children: [
ts_named_edge(
name: ts_facts_field_surface_spelling,
target: ts_inhabitant_atom(id: facts.surface_spelling)
),
ts_named_edge(
name: ts_facts_field_kind,
target: ts_numeric_kind_node(kind: facts.kind)
),
ts_named_edge(
name: ts_facts_field_operation_semantics,
target: ts_operation_semantics_node(sem: facts.operation_semantics)
),
ts_named_edge(
name: ts_facts_field_std_projection,
target: ts_inhabitant_atom(id: facts.std_projection)
),
ts_named_edge(
name: ts_facts_field_encoding,
target: ts_inhabitant_atom(id: facts.encoding)
)
]
}
}

fn ts_number_inhabitant_node(id: Symbol, facts: TsNumberPrimitiveFacts) -> Node {
Node {
kind: TypeNode { connective: Conj },
children: [
ts_named_edge(name: ts_inhabitant_field_atom, target: ts_inhabitant_atom(id: id)),
ts_named_edge(
name: ts_inhabitant_field_facts,
target: ts_number_facts_node(facts: facts)
)
]
}
}

fn ts_bigint_inhabitant_node(id: Symbol, facts: TsBigIntPrimitiveFacts) -> Node {
Node {
kind: TypeNode { connective: Conj },
children: [
ts_named_edge(name: ts_inhabitant_field_atom, target: ts_inhabitant_atom(id: id)),
ts_named_edge(
name: ts_inhabitant_field_facts,
target: ts_bigint_facts_node(facts: facts)
)
]
}
}

fn ts_inhabitant_number_node() -> Node {
ts_number_inhabitant_node(id: ts_inhabitant_number, facts: ts_facts_number)
}

fn ts_inhabitant_bigint_node() -> Node {
ts_bigint_inhabitant_node(id: ts_inhabitant_bigint, facts: ts_facts_bigint)
}

fn ts_declared_inhabitants_root() -> Node {
Node {
kind: TypeNode { connective: Conj },
children: [
ts_named_edge(name: ts_inhabitant_field_number, target: ts_inhabitant_number_node()),
ts_named_edge(name: ts_inhabitant_field_bigint, target: ts_inhabitant_bigint_node())
]
}
}

fn ts_list_snoc_item<T>(xs: List<T>, item: T) -> List<T> {
free_monoid_fold(
xs: xs,
empty: Cons { head: item, tail: Empty },
cons: fn(rest, existing) {
Cons { head: existing, tail: rest }
}
)
}

fn ts_catalog_surface_symbol_step(sym: Symbol, acc: Bool, row: TsEcma262NumericPrimitiveFactsUnion) -> Bool {
match row {
TsNumericFactsNumber { facts: f } => acc || sym == f.surface_spelling
TsNumericFactsBigInt { facts: f } => acc || sym == f.surface_spelling
}
}

fn ts_catalog_surface_symbol(sym: Symbol) -> Bool {
free_monoid_fold(
xs: ts_numeric_facts_catalog,
empty: false,
cons: fn(acc, row) {
ts_catalog_surface_symbol_step(sym: sym, acc: acc, row: row)
}
)
}

fn ts_language_model_canonical_symbols() -> Set<Symbol> {
Set {
member: fn(sym) {
ts_catalog_surface_symbol(sym: sym)
}
}
}

fn ts_primitive_axis_binding(axis: Symbol, fact: Node) -> PrimitiveFactAxisBinding {
PrimitiveFactAxisBinding { axis: axis, fact: fact }
}

fn ts_primitive_bundle_from_number_facts(facts: TsNumberPrimitiveFacts) -> PrimitiveFactBundle {
PrimitiveFactBundle {
substrate_carrier: ts_number_facts_node(facts: facts),
spec_facts: [
ts_primitive_axis_binding(
axis: primitive_fact_axis_surface_spelling,
fact: ts_inhabitant_atom(id: facts.surface_spelling)
),
ts_primitive_axis_binding(
axis: primitive_fact_axis_width,
fact: ts_inhabitant_atom(id: ts_tag_bits64)
),
ts_primitive_axis_binding(
axis: primitive_fact_axis_encoding,
fact: ts_inhabitant_atom(id: facts.ieee754_binary)
)
]
}
}

fn ts_primitive_bundle_from_bigint_facts(facts: TsBigIntPrimitiveFacts) -> PrimitiveFactBundle {
PrimitiveFactBundle {
substrate_carrier: ts_bigint_facts_node(facts: facts),
spec_facts: [
ts_primitive_axis_binding(
axis: primitive_fact_axis_surface_spelling,
fact: ts_inhabitant_atom(id: facts.surface_spelling)
),
ts_primitive_axis_binding(
axis: primitive_fact_axis_encoding,
fact: ts_inhabitant_atom(id: facts.encoding)
)
]
}
}

fn ts_primitive_bundles_from_catalog_step(
acc: List<PrimitiveFactBundle>,
row: TsEcma262NumericPrimitiveFactsUnion
) -> List<PrimitiveFactBundle> {
match row {
TsNumericFactsNumber { facts: f } =>
ts_list_snoc_item(
xs: acc,
item: ts_primitive_bundle_from_number_facts(facts: f)
)
TsNumericFactsBigInt { facts: f } =>
ts_list_snoc_item(
xs: acc,
item: ts_primitive_bundle_from_bigint_facts(facts: f)
)
}
}

fn ts_wave1_primitive_fact_bundles() -> List<PrimitiveFactBundle> {
free_monoid_fold(
xs: ts_numeric_facts_catalog,
empty: Empty,
cons: fn(acc, row) {
ts_primitive_bundles_from_catalog_step(acc: acc, row: row)
}
)
}

fn ts_model_core_wave1() -> ModelCore {
ModelCore {
primitives: ts_wave1_primitive_fact_bundles(),
inhabitance: [],

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BLOCKING: ts_model_core_wave1 leaves inhabitance empty while the PR separately declares number/bigint inhabitant nodes, so those facts do not flow into the advertised ModelCore surface.

laws: [],
effects: EffectSemanticsDecl { operations: [] },
partiality: PartialitySemanticsDecl { operations: [] }
}
}

fn ts_language_model_wave1() -> TsLanguageModel {
TsLanguageModel {
language_identity: ts_language_model_surface_id,
canonical_symbols: ts_language_model_canonical_symbols(),
core: ts_model_core_wave1()
}
}
Loading