Tensor constructors (spec layer) #
These are small, total constructors for building TorchLean.Tensor values directly.
They are used heavily inside the spec layer (models/layers) and in proofs, where we want:
- straightforward definitional unfolding, and
- no dependence on
IOor dynamic shape checks.
For ordinary literals, in-memory conversion, reshape, and scalar casts, import NN.Tensor.
Design choice (why these are "total"):
- In the spec layer we would rather make edge cases explicit than throw runtime exceptions.
- If something is shape-invalid, we want Lean to reject it at elaboration time.
- Existing in-memory collections enter through the total
Tensor.fromconversion boundary. - External parsers validate untrusted dimensions before constructing a tensor.
Constant tensors #
Fill a tensor of arbitrary shape with one value.
PyTorch analogy: torch.full(shape, value).
Instances For
Construct an all-zero tensor of arbitrary shape. Reducible, so lemmas about full apply.
Instances For
Construct an all-one tensor of arbitrary shape. Reducible, so lemmas about full apply.
Instances For
Every coordinate of a filled tensor contains its fill value.
Reading a scalar filled tensor returns its fill value.
The item of an internally constant scalar tensor is the constant.
Every entry of an internally constant vector is the constant.
Replicating a scalar tensor observes that scalar at every target coordinate.
Every outer coordinate of a filled tensor is the corresponding filled subtensor.
Every coordinate of a filled matrix contains its fill value.
Construct an arbitrary-rank tensor from a coordinate function.
At each coordinate, f receives one natural-number index per dimension,
outermost first. The indices are in bounds by construction.
For example, Tensor.generate [2, 3] f has shape [2, 3], and its entry at row i and column j
is f [i, j].
Instances For
The buffer is filled directly from the index function, without building one scalar tensor per entry.
PyTorch analogy: torch.tensor([...]) with shape (n,), but our input is a function, not a list.
Example:
-- `torch.tensor([0.0, 1.0, 2.0, 3.0])`, except the entries arrive from a function on `Fin n` and
-- the length is part of the type.
def ramp : Tensor Float [4] := Tensor.ofFn fun index => index.val.toFloat
Instances For
Evaluating ofFn at a coordinate returns the value supplied at its index.
Reading a scalar entry of an internally generated vector evaluates the generator.
The item of an internally generated scalar tensor is the generator's value.
Slicing an internally generated tensor fixes the leading coordinate of the generator.
Every coordinate of a filled vector contains the fill value.
A singleton vector.
PyTorch analogy: x.unsqueeze(0) for a scalar x.
Instances For
Pad a tensor with n leading dimensions of size 1.
This is the tensor-level companion of Shape.padLeft. The row-major buffer is unchanged, so the
padding is a zero-copy reinterpretation of the static shape. Broadcasting uses it to align ranks
before expanding singleton axes.
PyTorch analogy: repeated unsqueeze(0).
Instances For
Padding with zero axes is the identity.
Padding one more axis stacks the padded tensor along a new singleton axis.
Stack an array of equal-shaped tensors along a new leading dimension.
The explicit size proof prevents silent truncation or padding. Taking tensors as array elements makes this constructor independent of rank: use scalar tensors for a vector, vectors for a matrix, or arbitrary inner tensors for higher-rank values.
Instances For
A filled tensor satisfies every pointwise property satisfied by its value.
Build a matrix when every row has the same length; reject ragged input.