Core tensor datatype (TorchLean.Tensor) #
TorchLean has one shape-indexed tensor representation for proofs and execution:
Tensor α shape.
Every tensor owns one contiguous row-major buffer. The scalar type selects the
physical buffer through Storage: arbitrary proof scalar types such as
Real use Array, while executable types with specialized instances use
packed storage (FloatArray for Float, ByteArray for UInt8).
The scalar and dim functions preserve TorchLean's proof-facing construction
API. They are smart constructors over packed storage, not physical recursive
constructors. Proofs eliminate tensors through typed lookup, scalarEquiv,
dimEquiv, and extensionality.
The single tensor representation used by TorchLean proofs and execution.
The public shape is Spec.Shape, which is the same type as the shape carried by the buffer, so
this alias only reorders arguments. The implementation is one certified contiguous row-major buffer
selected by Storage.
Instances For
Render executable internal tensors with explicit dimensions through the
canonical public type name in editor information and #check output.
Universe-polymorphic proof tensors and genuinely computed shape expressions retain their exact internal spelling.
Instances For
Construct a rank-zero tensor from one scalar value.
Instances For
Construct an outer dimension from its shape-indexed entries.
Instances For
Return the value stored in a scalar tensor.
Instances For
A scalar tensor evaluates to its sole scalar value.
Select one leading-axis slice from a tensor.
Instances For
Tensors with equal row-major data arrays are equal.
The packed representation is a storage buffer together with a size proof, and buffers are
determined by their array observation (Storage.toArray_injective).
Restacking every slice of a tensor returns the tensor.
Together with unstack_dim this is what makes dim and unstack an isomorphism rather than merely
a pair of functions, which is why proofs can eliminate a tensor by rw [← dim_unstack] and then
reason slice by slice.
Default tensor value for any shape.
Instances For
Every shape is inhabited when the scalar type is: take the all-default tensor.
Rebuilding a scalar tensor from its item returns the original tensor.
Two scalar tensors agreeing on their item are equal.
Scalar tensors and scalar values are equivalent.
Instances For
An outer axis is equivalent to a finite family of inner tensors.
Instances For
Proof-facing eliminator for the familiar scalar/dimension cases.
View does not own tensor data and is not a second tensor representation. It
only exposes the outer shape of an already packed tensor.
- scalar {α : Type} [Storage α] (value : α) : View α Spec.Shape.scalar
- dim {α : Type} [Storage α] {n : ℕ} {shape : Spec.Shape} (values : Fin n → Tensor α shape) : View α (Spec.Shape.dim n shape)
Instances For
Observe the outer constructor of a packed tensor for shape-recursive proofs.
Instances For
Pointwise algebra #
Every algebraic operation on tensors is the corresponding scalar operation applied coordinatewise.
The instances (Zero, Add, Neg, Sub, SMul, AddCommMonoid, AddCommGroup, Module) live
on the native representation in NN.Tensor.Internal.Representation.Basic.Pointwise, so they apply
uniformly to Tensor α shape whether the shape is a variable or a literal such as [n]. The
coordinate lemmas below are the simp normal forms; add_apply is restated here under the public
tensor namespace.
Tensor addition is coordinatewise scalar addition.
Cast a tensor along an equality of shapes.
Instances For
Casting along any proof of shape = shape is the identity.
cast_shape_rfl does not cover this: after Shape.ofList normalization the proof in hand is often
some derived term rather than the literal rfl, and simp needs to discharge those too.
The cast does not depend on which proof of the shape equality is used.
Shape equalities are proofs in a subsingleton, so this is provable rather than an axiom, and it is what lets two developments that derived the same equality differently share a lemma.
The ▸ rewrite and castShape are the same function.
Lean inserts ▸ on its own when a shape is rewritten in a tactic block, so without this bridge the
castShape simp set would silently fail to fire on goals the elaborator produced.
cast_shape_proof_irrel in ▸ form, for goals the elaborator produced.
Recover the statically known shape from a tensor value.
Instances For
Indexing #
Try to read a scalar using a runtime list of coordinates.
Instances For
The empty coordinate list reads the item of a rank-zero tensor.
A rank-zero tensor has no axis to index, so any nonempty coordinate list fails.
A tensor with an axis is not a scalar, so the empty coordinate list fails.
One step of runtime lookup: check the leading index against the axis, then recurse into the
slice. This is the equation that turns getSpec on a literal coordinate list into a chain of
unstacks, which is how the executable and proof-facing readings are kept in step.
A shape cast does not move any data, so runtime lookup sees straight through it.
Select one coordinate along an arbitrary axis and remove that axis.
Instances For
Selecting along axis zero is exactly the outer-axis slice.
Select one entry from the outermost tensor axis.
Instances For
Indexing a stacked tensor returns the entry that was stacked.
Vector indexing returns a scalar directly.
This higher-priority instance also makes chained indexing natural:
matrix[row][column] returns an entry, while the first lookup still returns
the statically shaped row tensor.
Natural-number indexing of a vector returns one scalar and asks GetElem to
discharge the static bound.
Natural-number indexing selects one slice along the outermost tensor axis.
Literal indices are checked during elaboration, so ordinary code can write
matrix[0] without constructing a Fin value explicitly.
Runtime-list lookup is extensional.
Compile scalar lookup without allocating the intermediate rank-zero slice.
Reading a vector filled by the packed constant constructor returns that constant.
The Tensor α [n] ≃ (Fin n → α) equivalence is scalar lookup on the nose.
Stating it keeps vectorEquiv usable in proofs without unfolding the two equivalences it is built
from, and it is why a vector can be handed to Mathlib lemmas about functions on Fin n.
Matrix access is a row slice followed by a scalar read.
True by rfl, but worth a name: it is the rewrite that lets a matrix proof reuse every vector lemma
about getScalar instead of duplicating them at rank two.
Matrix scalar lookup is one read at the corresponding two-axis coordinate.
Direct storage read used when compiling matrix scalar lookup.
Instances For
Compile matrix lookup without allocating an intermediate row or scalar tensor.
Reading back a matrix built from a two-argument function returns the function.
Total indexing and shape operations #
Return zero when a runtime coordinate list is invalid.
Instances For
On a rank-zero tensor the empty coordinate list reads the item, no fallback needed.
An over-long coordinate list on a rank-zero tensor falls back to zero.
A too-short coordinate list falls back to zero.
One step of total lookup, with the out-of-range branch returning zero rather than failing.
The zero is what makes this function total, and it is also the reason the Zero α hypothesis is
there: no shape argument can rule out a bad runtime coordinate list.
Cast a tensor along a shape equality.
Instances For
tensorCast is castShape with the target shape written first.
Replicate a scalar tensor to any shape.
Instances For
Every coordinate of a replicated tensor holds the source item.
Replicating to rank zero returns the original scalar tensor.
Every slice of a replicated tensor is the replication of the same item.
Scalar lookup into a replicated vector returns the source item.
Map an output coordinate of an axis slice back to its source coordinate.
Instances For
Keep a contiguous coordinate range along an arbitrary axis.
The coordinate recursion above runs once per output element. The tensor itself is materialized in one packed pass, rather than recursively constructing and then restacking every outer slice.
Instances For
An axis slice reads the source coordinate selected by its checked range map.
Slice a contiguous range along the first axis.
Instances For
First slice along the outer axis, or none when that axis is empty.
The Option is what an empty axis costs: n is a variable here, so no shape argument can promise
there is a first slice, and returning none keeps the function total.
Instances For
Everything after the first slice, or none when the outer axis is empty.
Instances For
Pointwise operations and predicates #
Apply a scalar function pointwise while preserving the shape.
Instances For
Slicing after a map is mapping after a slice.
Every scalar entry satisfies predicate.
Instances For
Corresponding scalar entries satisfy relation.
Instances For
The trivial predicate holds of every tensor, at every shape.
Forall transports along map when the function respects the two predicates.
This is the workhorse for the numeric layers: a bound proved entrywise for the input survives an elementwise activation as long as the activation maps the input bound into the output one.
A predicate true of one value is true entrywise of the tensor replicating it.
Render a tensor recursively using the scalar ToString instance.