def permuted_length
import bendtorch-core@0.1.0.0/src/tensor/permute_values.bend as PermuteValuesimport Base
import bendtorch-core@0.1.0.0/src/shape/core.bend as Shape
import bendtorch-core@0.1.0.0/src/tensor/lifecycle.bend as Lifecycle
import bendtorch-core@0.1.0.0/src/tensor/layout.bend as Layout
import bendtorch-core@0.1.0.0/src/tensor/from_values_contract.bend as FromValues
import bendtorch-core@0.1.0.0/src/tensor/contracts/replayed.bend as Replayed
import bendtorch-core@0.1.0.0/src/tensor/index_map.bend as IndexMap
import bendtorch-core@0.1.0.0/src/tensor/transform_observation.bend as Observation
import bendtorch-core@0.1.0.0/src/tensor/permute_build_proof.bend as PermuteProof
324def permuted_length(+input: Shape.Shape, +values: List<&2, F32>, +axes: List<&2, U32>, +valid: {True{} == Layout.bijective(input, axes) : Bool},
325 -fits: {Lifecycle.logical_length(Replayed.storage(input, 0.0, FromValues.writes(values, 0n))) == Shape.logical_numel(Shape.dimensions(input)) : Nat}) ->
326 Permuted(input, values, axes, fits, pair => {Observation.applied_length_pair(input, pair) ==
327 Some{Shape.logical_numel(Shape.dimensions(input))} : Maybe<&2, Nat>}):
328 permute_lift(input, values, axes, valid, pair => {Observation.applied_length_pair(input, pair) ==
329 Some{Shape.logical_numel(Shape.dimensions(input))} : Maybe<&2, Nat>},
330 plan => source_fits => target_fits =>
331 +output = Layout.output(input, axes, plan)
332 +total = Shape.logical_numel(Shape.dimensions(output))
333 -made = written(input, axes, plan, 0.0, FromValues.writes(values, 0n), total)
334 Equal.cong(Nat, Maybe<&2, Nat>, number => Some{number}, Lifecycle.logical_length(made), Shape.logical_numel(Shape.dimensions(input)),
335 Equal.trans(Nat, Lifecycle.logical_length(made), total, Shape.logical_numel(Shape.dimensions(input)),
336 Replayed.fits(output, 0.0, IndexMap.writes(~Request, ~source_of, total, Request{input, axes}, input, 0.0, FromValues.writes(values, 0n))),
337 PermuteProof.plan_numel(input, axes, plan))), fits)