Language

From relations to tensor equations

This page groups the syntax, tensor-logic primitives, static checks, and algebraic semantics. Read it as the specification layer: what a TensorLang program can say before we discuss evidence, backends, or model workflows.

Language surface

A small S-expression core

TensorLang programs are S-expressions describing modules, domains, typed tensors, sparse COO tensors, named-axis equations, semirings, joins, projections, fixed points, properties, trainable tensor fragments, and dynamical systems. The surface is intentionally minimal so that semantics and tooling stay legible.

examples/family.tl — finite domains and tensorstensorlang
(module examples.family
  (tensorlang "1.5")

  (domain Person
    (size 4)
    (labels "alice" "bob" "carol" "dave"))

  (tensor parent
    (type Bool)
    (shape Person Person)
    (data
      (row 0 1 0 0)
      (row 0 0 1 0)
      (row 0 0 0 1)
      (row 0 0 0 0))))
examples/ancestor.tl — fixed-point relationtensorlang
(semiring bool-or-and
  (type Bool)
  (zero false)
  (one true)
  (add or)
  (mul and)
  (order subset))

(def ancestor
  (type Bool)
  (shape Person Person)
  (expr
    (fixpoint A
      (type Bool)
      (shape Person Person)
      (semiring bool-or-and)
      (init parent)
      (step (or parent
                (semiring-einsum bool-or-and
                  "Src Mid, Mid Dst -> Src Dst"
                  A parent)))
      (max-steps 8))))
examples/32_tensor_logic_primitives.tl — tensor logic primitivestensorlang
(sparse-tensor user_role
  (type Bool)
  (shape User Role)
  (coords
    (row "alice" "reviewer")
    (row "bob" "admin")))

(def user_role_action
  (type Bool)
  (shape User Role Action)
  (expr
    (join "User Role, Role Action -> User Role Action"
      user_role role_action)))

(def can_do
  (type Bool)
  (shape User Action)
  (expr (project user_role_action "User" "Action")))

(def gathered_embedding
  (type F64)
  (shape Sample Feature)
  (expr (embedding entity_embedding entity_ids)))

(def accumulated_updates
  (type F64)
  (shape Entity Feature)
  (expr (scatter-add entity_ids sample_updates Entity)))
examples/reservoir.tl — discrete dynamical systemtensorlang
(module examples.dynamics
  (tensorlang "1.5")

  (domain State (size 2) (labels "r0" "r1"))
  (domain Input (size 1) (labels "u0"))

  (system TinyReservoir
    (time continuous (dt 0.1) (steps 3))
    (state x (type F64) (shape State) (init (data 0.1 -0.1)))
    (input u (type F64) (shape Input) (data 1.0))
    (param W (type F64) (shape State State)
      (data (row 0.0 1.0) (row -1.0 0.0)))
    (dynamics
      (= dx/dt
        (tanh (+ (einsum "ij,j->i" W x) u))))))
v1.5

Tensor-logic primitives

TensorLang now has a direct language layer for the tensor-logic idea: relations as sparse Boolean tensors, Datalog-like rules as joins and projections, and embedding workflows as gather/scatter tensor operations.

primitive

Named-axis einsum

Readable specs such as "Sample Feature, Entity Feature -> Sample Entity" normalize to compact einsum labels while preserving declared output shapes.

primitive

Sparse COO tensors

Relations and embeddings can be declared by coordinates, with domain labels accepted in coordinate rows.

primitive

Join

Finite Bool relation joins are explicit tensor expressions and also lower into relational-algebra plans.

primitive

Project

Projection existentially OR-reduces omitted Bool axes, matching the relation view of Datalog-style rules.

primitive

Embedding / gather

I64 ID tensors select rows or slices from numeric tables while keeping TensorLang shape metadata.

primitive

Scatter-add

Numeric updates accumulate into an output domain, connecting indexed examples back to tensor state.

v1.5 tensor-logic smoke checkstensorlang
tl check examples/32_tensor_logic_primitives.tl
tl eval examples/32_tensor_logic_primitives.tl can_do --pretty
tl lower-relalg examples/32_tensor_logic_primitives.tl user_role_action
tl infer examples/32_tensor_logic_primitives.tl accumulated_updates
scope boundary

This is TensorLang's independent tensor-logic-inspired surface, not a compatibility claim for the Tensor Logic paper. The implemented subset is intentionally concrete: named axes, finite Bool relations, sparse COO literals, joins, projections, gather, and scatter-add in the reference evaluator and static checker.

Static semantics

What the compiler checks before you run

TensorLang's front-end performs structural and algebraic checks ahead of any backend lowering. The intent is to catch shape, dtype, semiring, and recursion mistakes statically.

shape
Static rank and dimension checks per equation
dtype
Boolean / integer / real propagation through einsum
domain
Index sets are first-class, referenced by name
sparse
COO coordinate rank, labels, values, and materialized dense shape
named axes
Named-axis einsum specs normalize to compact execution labels
join/project
Bool relation joins and existential projections preserve tensor shapes
semiring
Each tensor binds to a declared algebraic structure
dependency
Definitions form a DAG; cycles allowed only via fixpoint
monotonicity
Fixed points checked as monotone over the chosen lattice
Algebra

Semirings and relational algebra

The same einsum expression can mean matrix multiplication, a join, a shortest path, or a max-product computation, depending on the declared semiring.

Semiring (⊕, ⊗, 0, 1)
Carrier
Reading
(+, ×, 0, 1)
Real
standard matrix multiplication / neural layers
(∨, ∧, false, true)
Bool
relational join, transitive closure
(min, +, +∞, 0)
Real
shortest paths
(max, +, -∞, 0)
Real
Viterbi / longest path
(max, ×, 0, 1)
Real
max-product inference
Join · project diagram

Relational algebra lowering reuses the same einsum machinery. In the v1.6 finite Bool subset, both semiring-einsum and explicit named-axis join/project lower into plans that can run through in-memory or SQLite reference backends and export to SQL, Datalog, or TypeDB/TypeQL-style text.