5.6. The PermDraws Tactic
-
Definition 5.2Blueprint label
-
perm_draws_findApp
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.3Blueprint label
-
perm_draws_matchProbOutput
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.4Blueprint label
-
perm_draws_matchProbEvent
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.5Blueprint label
-
perm_draws_parseProbEqSides
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.6Blueprint label
-
perm_draws_extractBindChain
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.7Blueprint label
-
perm_draws_collectBVarPairs
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.8Blueprint label
-
perm_draws_computePermutation
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.9Blueprint label
-
perm_draws_bubbleSortSwaps
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.10Blueprint label
-
perm_draws_mkSwapProofTerm
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.11Blueprint label
-
perm_draws_emitLhsSwap
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.12Blueprint label
-
perm_draws_emitInsertUnusedDraw
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
perm_draws_findApp
- Custom tactic for automatic distributional equivalence proofs.
-
PQXDHLean.Tactics.permDrawsImpl[complete]
A custom Lean 4 tactic for automatically proving distributional
equivalences between probability computations that differ only in
the order of independent uniform draws. Invoked as perm_draws
in tactic mode.
Code for Definition5.1●1 definition
Associated Lean declarations
-
PQXDHLean.Tactics.permDrawsImpl[complete]
-
PQXDHLean.Tactics.permDrawsImpl[complete]
-
def PQXDHLean.Tactics.permDrawsImpl : Lean.Elab.Tactic.TacticM
Lean.Elab.Tactic.TacticM (α : Type) : TypeThe tactic monad, which extends the term elaboration monad `TermElabM` with state that contains the current goals (`Lean.Elab.Tactic.State`, accessible via `MonadStateOf`) and local information about the current tactic's name and whether error recovery is enabled (`Lean.Elab.Tactic.Context`, accessible via `MonadReaderOf`).UnitUnit : TypeThe canonical type with one element. This element is written `()`. `Unit` has a number of uses: * It can be used to model control flow that returns from a function call without providing other information. * Monadic actions that return `Unit` have side effects without computing values. * In polymorphic types, it can be used to indicate that no data is to be stored in a particular field.def PQXDHLean.Tactics.permDrawsImpl : Lean.Elab.Tactic.TacticM
Lean.Elab.Tactic.TacticM (α : Type) : TypeThe tactic monad, which extends the term elaboration monad `TermElabM` with state that contains the current goals (`Lean.Elab.Tactic.State`, accessible via `MonadStateOf`) and local information about the current tactic's name and whether error recovery is enabled (`Lean.Elab.Tactic.Context`, accessible via `MonadReaderOf`).UnitUnit : TypeThe canonical type with one element. This element is written `()`. `Unit` has a number of uses: * It can be used to model control flow that returns from a function call without providing other information. * Monadic actions that return `Unit` have side effects without computing values. * In polymorphic types, it can be used to indicate that no data is to be stored in a particular field.`perm_draws` automatically proves probability equality goals of the form `Pr[= z | LHS] = Pr[= z | RHS]` where both sides are sequences of independent uniform draws followed by the same body expression, possibly differing in draw order and unused draws. All rewrites target the LHS only (via `conv_lhs`).
5.6.1. Motivation
In game-based cryptographic proofs, security reductions often
require showing that two probabilistic computations produce the
same distribution. After unfolding definitions and simplifying
oracle implementations, these goals reduce to: both sides sample
the same uniform draws but in different order, possibly with
extra unused draws on one side. Proving this by hand requires
computing the permutation between draw orders and emitting a
sequence of adjacent transpositions, which is tedious and error-prone.
The perm_draws tactic automates this entirely.
5.6.2. Usage
After normalizing both sides of a distributional equality to
bind chains of uniform draws (typically via simp and simp_all),
a single call to perm_draws closes the goal.
The tactic is used in the distributional equivalence proofs that underpin the passive secrecy theorem.
5.6.3. Design decision
All rewrites target the LHS only via conv_lhs. This avoids the
unpredictability of VCV-io's rewrite tactics, which use
first | conv_lhs | conv_rhs and can modify either side of the
equation when both sides have matching structure.
5.6.4. Scope
The tactic handles goals where all draws are independent uniform samples, the bodies are identical modulo variable permutation, and the only structural difference is draw order and unused draws.
It does not handle dependent draws, conditional branches, different body structures, or computational indistinguishability arguments.
5.6.5. Implementation
The tactic is implemented in six modules, each handling a distinct phase of the proof automation pipeline.
5.6.5.1. Expression utilities
-
Definition 5.1Blueprint label
-
perm_draws_tactic
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.3Blueprint label
-
perm_draws_matchProbOutput
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.4Blueprint label
-
perm_draws_matchProbEvent
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.5Blueprint label
-
perm_draws_parseProbEqSides
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.6Blueprint label
-
perm_draws_extractBindChain
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.7Blueprint label
-
perm_draws_collectBVarPairs
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.8Blueprint label
-
perm_draws_computePermutation
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.9Blueprint label
-
perm_draws_bubbleSortSwaps
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.10Blueprint label
-
perm_draws_mkSwapProofTerm
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.11Blueprint label
-
perm_draws_emitLhsSwap
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.12Blueprint label
-
perm_draws_emitInsertUnusedDraw
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
perm_draws_tactic
- Custom tactic for automatic distributional equivalence proofs.
-
PQXDHLean.Tactics.findApp?[complete]
Search for an application of a given constant anywhere inside an
expression tree, used by the goal parser to locate probOutput
and probEvent subexpressions.
Code for Definition5.2●1 definition
Associated Lean declarations
-
PQXDHLean.Tactics.findApp?[complete]
-
PQXDHLean.Tactics.findApp?[complete]
-
opaque PQXDHLean.Tactics.findApp? (name
Lean.Name: Lean.NameLean.Name : TypeHierarchical names consist of a sequence of components, each of which is either a string or numeric, that are written separated by dots (`.`). Hierarchical names are used to name declarations and for creating unique identifiers for free variables and metavariables. You can create hierarchical names using a backtick: ``` `Lean.Meta.whnf ``` It is short for `.str (.str (.str .anonymous "Lean") "Meta") "whnf"`. You can use double backticks to request Lean to statically check whether the name corresponds to a Lean declaration in scope. ``` ``Lean.Meta.whnf ``` If the name is not in scope, Lean will report an error. There are two ways to convert a `String` to a `Name`: 1. `Name.mkSimple` creates a name with a single string component. 2. `String.toName` first splits the string into its dot-separated components, and then creates a hierarchical name.) (eLean.Expr: Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.) : OptionOption.{u} (α : Type u) : Type uOptional values, which are either `some` around a value from the underlying type or `none`. `Option` can represent nullable types or computations that might fail. In the codomain of a function type, it can also represent partiality.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.opaque PQXDHLean.Tactics.findApp? (name
Lean.Name: Lean.NameLean.Name : TypeHierarchical names consist of a sequence of components, each of which is either a string or numeric, that are written separated by dots (`.`). Hierarchical names are used to name declarations and for creating unique identifiers for free variables and metavariables. You can create hierarchical names using a backtick: ``` `Lean.Meta.whnf ``` It is short for `.str (.str (.str .anonymous "Lean") "Meta") "whnf"`. You can use double backticks to request Lean to statically check whether the name corresponds to a Lean declaration in scope. ``` ``Lean.Meta.whnf ``` If the name is not in scope, Lean will report an error. There are two ways to convert a `String` to a `Name`: 1. `Name.mkSimple` creates a name with a single string component. 2. `String.toName` first splits the string into its dot-separated components, and then creates a hierarchical name.) (eLean.Expr: Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.) : OptionOption.{u} (α : Type u) : Type uOptional values, which are either `some` around a value from the underlying type or `none`. `Option` can represent nullable types or computations that might fail. In the codomain of a function type, it can also represent partiality.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.Find an application of `name` anywhere in `e`.
5.6.5.2. Goal parsing
-
Definition 5.1Blueprint label
-
perm_draws_tactic
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.2Blueprint label
-
perm_draws_findApp
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.4Blueprint label
-
perm_draws_matchProbEvent
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.5Blueprint label
-
perm_draws_parseProbEqSides
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.6Blueprint label
-
perm_draws_extractBindChain
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.7Blueprint label
-
perm_draws_collectBVarPairs
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.8Blueprint label
-
perm_draws_computePermutation
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.9Blueprint label
-
perm_draws_bubbleSortSwaps
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.10Blueprint label
-
perm_draws_mkSwapProofTerm
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.11Blueprint label
-
perm_draws_emitLhsSwap
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.12Blueprint label
-
perm_draws_emitInsertUnusedDraw
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
perm_draws_tactic
- Custom tactic for automatic distributional equivalence proofs.
-
PQXDHLean.Tactics.matchProbOutput?[complete]
Extract the computation from a probOutput comp z expression.
Code for Definition5.3●1 definition
Associated Lean declarations
-
PQXDHLean.Tactics.matchProbOutput?[complete]
-
PQXDHLean.Tactics.matchProbOutput?[complete]
-
def PQXDHLean.Tactics.matchProbOutput? (e
Lean.Expr: Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.) : OptionOption.{u} (α : Type u) : Type uOptional values, which are either `some` around a value from the underlying type or `none`. `Option` can represent nullable types or computations that might fail. In the codomain of a function type, it can also represent partiality.(Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.×Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.)Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.def PQXDHLean.Tactics.matchProbOutput? (e
Lean.Expr: Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.) : OptionOption.{u} (α : Type u) : Type uOptional values, which are either `some` around a value from the underlying type or `none`. `Option` can represent nullable types or computations that might fail. In the codomain of a function type, it can also represent partiality.(Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.×Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.)Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Extract the computation from a `probOutput comp z` expression. Returns `(comp, z)`.
-
Definition 5.1Blueprint label
-
perm_draws_tactic
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.2Blueprint label
-
perm_draws_findApp
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.3Blueprint label
-
perm_draws_matchProbOutput
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.5Blueprint label
-
perm_draws_parseProbEqSides
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.6Blueprint label
-
perm_draws_extractBindChain
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.7Blueprint label
-
perm_draws_collectBVarPairs
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.8Blueprint label
-
perm_draws_computePermutation
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.9Blueprint label
-
perm_draws_bubbleSortSwaps
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.10Blueprint label
-
perm_draws_mkSwapProofTerm
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.11Blueprint label
-
perm_draws_emitLhsSwap
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.12Blueprint label
-
perm_draws_emitInsertUnusedDraw
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
perm_draws_tactic
- Custom tactic for automatic distributional equivalence proofs.
-
PQXDHLean.Tactics.matchProbEvent?[complete]
Extract the computation from a probEvent comp p expression.
Code for Definition5.4●1 definition
Associated Lean declarations
-
PQXDHLean.Tactics.matchProbEvent?[complete]
-
PQXDHLean.Tactics.matchProbEvent?[complete]
-
def PQXDHLean.Tactics.matchProbEvent? (e
Lean.Expr: Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.) : OptionOption.{u} (α : Type u) : Type uOptional values, which are either `some` around a value from the underlying type or `none`. `Option` can represent nullable types or computations that might fail. In the codomain of a function type, it can also represent partiality.(Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.×Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.)Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.def PQXDHLean.Tactics.matchProbEvent? (e
Lean.Expr: Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.) : OptionOption.{u} (α : Type u) : Type uOptional values, which are either `some` around a value from the underlying type or `none`. `Option` can represent nullable types or computations that might fail. In the codomain of a function type, it can also represent partiality.(Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.×Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.)Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Extract the computation from a `probEvent comp p` expression. Returns `(comp, p)`.
-
Definition 5.1Blueprint label
-
perm_draws_tactic
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.2Blueprint label
-
perm_draws_findApp
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.3Blueprint label
-
perm_draws_matchProbOutput
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.4Blueprint label
-
perm_draws_matchProbEvent
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.6Blueprint label
-
perm_draws_extractBindChain
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.7Blueprint label
-
perm_draws_collectBVarPairs
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.8Blueprint label
-
perm_draws_computePermutation
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.9Blueprint label
-
perm_draws_bubbleSortSwaps
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.10Blueprint label
-
perm_draws_mkSwapProofTerm
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.11Blueprint label
-
perm_draws_emitLhsSwap
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.12Blueprint label
-
perm_draws_emitInsertUnusedDraw
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
perm_draws_tactic
- Custom tactic for automatic distributional equivalence proofs.
-
PQXDHLean.Tactics.parseProbEqSides[complete]
Parse the goal Pr[= z | LHS] = Pr[= z | RHS], supporting both
probOutput and probEvent variants.
Code for Definition5.5●1 definition
Associated Lean declarations
-
PQXDHLean.Tactics.parseProbEqSides[complete]
-
PQXDHLean.Tactics.parseProbEqSides[complete]
-
def PQXDHLean.Tactics.parseProbEqSides (target
Lean.Expr: Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.) : Lean.MetaMLean.Meta.MetaM (α : Type) : TypeThe `MetaM` monad is a core component of Lean's metaprogramming framework, facilitating the construction and manipulation of expressions (`Lean.Expr`) within Lean. It builds on top of `CoreM` and additionally provides: - A `LocalContext` for managing free variables. - A `MetavarContext` for managing metavariables. - A `Cache` for caching results of the key `MetaM` operations. The key operations provided by `MetaM` are: - `inferType`, which attempts to automatically infer the type of a given expression. - `whnf`, which reduces an expression to the point where the outermost part is no longer reducible but the inside may still contain unreduced expression. - `isDefEq`, which determines whether two expressions are definitionally equal, possibly assigning meta variables in the process. - `forallTelescope` and `lambdaTelescope`, which make it possible to automatically move into (nested) binders while updating the local context. The following is a small example that demonstrates how to obtain and manipulate the type of a `Fin` expression: ``` public import Lean open Lean Meta def getFinBound (e : Expr) : MetaM (Option Expr) := do let type ← whnf (← inferType e) let_expr Fin bound := type | return none return bound def a : Fin 100 := 42 run_meta match ← getFinBound (.const ``a []) with | some limit => IO.println (← ppExpr limit) | none => IO.println "no limit found" ```(OptionOption.{u} (α : Type u) : Type uOptional values, which are either `some` around a value from the underlying type or `none`. `Option` can represent nullable types or computations that might fail. In the codomain of a function type, it can also represent partiality.(Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.×Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.×Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.)Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.)def PQXDHLean.Tactics.parseProbEqSides (target
Lean.Expr: Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.) : Lean.MetaMLean.Meta.MetaM (α : Type) : TypeThe `MetaM` monad is a core component of Lean's metaprogramming framework, facilitating the construction and manipulation of expressions (`Lean.Expr`) within Lean. It builds on top of `CoreM` and additionally provides: - A `LocalContext` for managing free variables. - A `MetavarContext` for managing metavariables. - A `Cache` for caching results of the key `MetaM` operations. The key operations provided by `MetaM` are: - `inferType`, which attempts to automatically infer the type of a given expression. - `whnf`, which reduces an expression to the point where the outermost part is no longer reducible but the inside may still contain unreduced expression. - `isDefEq`, which determines whether two expressions are definitionally equal, possibly assigning meta variables in the process. - `forallTelescope` and `lambdaTelescope`, which make it possible to automatically move into (nested) binders while updating the local context. The following is a small example that demonstrates how to obtain and manipulate the type of a `Fin` expression: ``` public import Lean open Lean Meta def getFinBound (e : Expr) : MetaM (Option Expr) := do let type ← whnf (← inferType e) let_expr Fin bound := type | return none return bound def a : Fin 100 := 42 run_meta match ← getFinBound (.const ``a []) with | some limit => IO.println (← ppExpr limit) | none => IO.println "no limit found" ```(OptionOption.{u} (α : Type u) : Type uOptional values, which are either `some` around a value from the underlying type or `none`. `Option` can represent nullable types or computations that might fail. In the codomain of a function type, it can also represent partiality.(Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.×Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.×Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.)Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.)Parse goal `Pr[= z | lhs] = Pr[= z | rhs]`. Returns `(lhsComp, rhsComp, z)`.
5.6.5.3. Bind chain extraction
-
Definition 5.1Blueprint label
-
perm_draws_tactic
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.2Blueprint label
-
perm_draws_findApp
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.3Blueprint label
-
perm_draws_matchProbOutput
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.4Blueprint label
-
perm_draws_matchProbEvent
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.5Blueprint label
-
perm_draws_parseProbEqSides
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.7Blueprint label
-
perm_draws_collectBVarPairs
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.8Blueprint label
-
perm_draws_computePermutation
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.9Blueprint label
-
perm_draws_bubbleSortSwaps
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.10Blueprint label
-
perm_draws_mkSwapProofTerm
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.11Blueprint label
-
perm_draws_emitLhsSwap
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.12Blueprint label
-
perm_draws_emitInsertUnusedDraw
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
perm_draws_tactic
- Custom tactic for automatic distributional equivalence proofs.
-
PQXDHLean.Tactics.extractBindChain[complete]
Walk a computation's right-associated bind chain, collecting the
sequence of draw computations and the residual body expression.
The body has loose bound variable references where bvar 0 is the
innermost (last) draw and bvar (n-1) is the outermost (first) draw.
Code for Definition5.6●1 definition
Associated Lean declarations
-
PQXDHLean.Tactics.extractBindChain[complete]
-
PQXDHLean.Tactics.extractBindChain[complete]
-
opaque PQXDHLean.Tactics.extractBindChain (e
Lean.Expr: Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.) : Lean.MetaMLean.Meta.MetaM (α : Type) : TypeThe `MetaM` monad is a core component of Lean's metaprogramming framework, facilitating the construction and manipulation of expressions (`Lean.Expr`) within Lean. It builds on top of `CoreM` and additionally provides: - A `LocalContext` for managing free variables. - A `MetavarContext` for managing metavariables. - A `Cache` for caching results of the key `MetaM` operations. The key operations provided by `MetaM` are: - `inferType`, which attempts to automatically infer the type of a given expression. - `whnf`, which reduces an expression to the point where the outermost part is no longer reducible but the inside may still contain unreduced expression. - `isDefEq`, which determines whether two expressions are definitionally equal, possibly assigning meta variables in the process. - `forallTelescope` and `lambdaTelescope`, which make it possible to automatically move into (nested) binders while updating the local context. The following is a small example that demonstrates how to obtain and manipulate the type of a `Fin` expression: ``` public import Lean open Lean Meta def getFinBound (e : Expr) : MetaM (Option Expr) := do let type ← whnf (← inferType e) let_expr Fin bound := type | return none return bound def a : Fin 100 := 42 run_meta match ← getFinBound (.const ``a []) with | some limit => IO.println (← ppExpr limit) | none => IO.println "no limit found" ```(Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.ArrayArray.{u} (α : Type u) : Type u`Array α` is the type of [dynamic arrays](https://en.wikipedia.org/wiki/Dynamic_array) with elements from `α`. This type has special support in the runtime. Arrays perform best when unshared. As long as there is never more than one reference to an array, all updates will be performed _destructively_. This results in performance comparable to mutable arrays in imperative programming languages. An array has a size and a capacity. The size is the number of elements present in the array, while the capacity is the amount of memory currently allocated for elements. The size is accessible via `Array.size`, but the capacity is not observable from Lean code. `Array.emptyWithCapacity n` creates an array which is equal to `#[]`, but internally allocates an array of capacity `n`. When the size exceeds the capacity, allocation is required to grow the array. From the point of view of proofs, `Array α` is just a wrapper around `List α`.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.×Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.)Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.opaque PQXDHLean.Tactics.extractBindChain (e
Lean.Expr: Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.) : Lean.MetaMLean.Meta.MetaM (α : Type) : TypeThe `MetaM` monad is a core component of Lean's metaprogramming framework, facilitating the construction and manipulation of expressions (`Lean.Expr`) within Lean. It builds on top of `CoreM` and additionally provides: - A `LocalContext` for managing free variables. - A `MetavarContext` for managing metavariables. - A `Cache` for caching results of the key `MetaM` operations. The key operations provided by `MetaM` are: - `inferType`, which attempts to automatically infer the type of a given expression. - `whnf`, which reduces an expression to the point where the outermost part is no longer reducible but the inside may still contain unreduced expression. - `isDefEq`, which determines whether two expressions are definitionally equal, possibly assigning meta variables in the process. - `forallTelescope` and `lambdaTelescope`, which make it possible to automatically move into (nested) binders while updating the local context. The following is a small example that demonstrates how to obtain and manipulate the type of a `Fin` expression: ``` public import Lean open Lean Meta def getFinBound (e : Expr) : MetaM (Option Expr) := do let type ← whnf (← inferType e) let_expr Fin bound := type | return none return bound def a : Fin 100 := 42 run_meta match ← getFinBound (.const ``a []) with | some limit => IO.println (← ppExpr limit) | none => IO.println "no limit found" ```(Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.ArrayArray.{u} (α : Type u) : Type u`Array α` is the type of [dynamic arrays](https://en.wikipedia.org/wiki/Dynamic_array) with elements from `α`. This type has special support in the runtime. Arrays perform best when unshared. As long as there is never more than one reference to an array, all updates will be performed _destructively_. This results in performance comparable to mutable arrays in imperative programming languages. An array has a size and a capacity. The size is the number of elements present in the array, while the capacity is the amount of memory currently allocated for elements. The size is accessible via `Array.size`, but the capacity is not observable from Lean code. `Array.emptyWithCapacity n` creates an array which is equal to `#[]`, but internally allocates an array of capacity `n`. When the size exceeds the capacity, allocation is required to grow the array. From the point of view of proofs, `Array α` is just a wrapper around `List α`.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.×Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.)Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Extract a right-associated bind chain from a computation expression. Returns `(draws, body)` where `draws[0]` is the outermost draw. The body has loose bvar references: bvar 0 = innermost (last) draw, bvar (n-1) = outermost (first) draw.
5.6.5.4. De Bruijn analysis
-
Definition 5.1Blueprint label
-
perm_draws_tactic
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.2Blueprint label
-
perm_draws_findApp
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.3Blueprint label
-
perm_draws_matchProbOutput
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.4Blueprint label
-
perm_draws_matchProbEvent
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.5Blueprint label
-
perm_draws_parseProbEqSides
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.6Blueprint label
-
perm_draws_extractBindChain
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.8Blueprint label
-
perm_draws_computePermutation
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.9Blueprint label
-
perm_draws_bubbleSortSwaps
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.10Blueprint label
-
perm_draws_mkSwapProofTerm
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.11Blueprint label
-
perm_draws_emitLhsSwap
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.12Blueprint label
-
perm_draws_emitInsertUnusedDraw
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
perm_draws_tactic
- Custom tactic for automatic distributional equivalence proofs.
-
PQXDHLean.Tactics.collectBVarPairs[complete]
Traverse the LHS and RHS bodies in parallel, collecting pairs of de Bruijn indices at corresponding positions. Each pair (i, j) means LHS draw i fills the same role as RHS draw j. Draws that appear in one body but not the other are classified as unused.
Code for Definition5.7●1 definition
Associated Lean declarations
-
PQXDHLean.Tactics.collectBVarPairs[complete]
-
PQXDHLean.Tactics.collectBVarPairs[complete]
-
opaque PQXDHLean.Tactics.collectBVarPairs : Lean.Expr
Lean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.→ Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.→ ArrayArray.{u} (α : Type u) : Type u`Array α` is the type of [dynamic arrays](https://en.wikipedia.org/wiki/Dynamic_array) with elements from `α`. This type has special support in the runtime. Arrays perform best when unshared. As long as there is never more than one reference to an array, all updates will be performed _destructively_. This results in performance comparable to mutable arrays in imperative programming languages. An array has a size and a capacity. The size is the number of elements present in the array, while the capacity is the amount of memory currently allocated for elements. The size is accessible via `Array.size`, but the capacity is not observable from Lean code. `Array.emptyWithCapacity n` creates an array which is equal to `#[]`, but internally allocates an array of capacity `n`. When the size exceeds the capacity, allocation is required to grow the array. From the point of view of proofs, `Array α` is just a wrapper around `List α`.(Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.×Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.)Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.→ ArrayArray.{u} (α : Type u) : Type u`Array α` is the type of [dynamic arrays](https://en.wikipedia.org/wiki/Dynamic_array) with elements from `α`. This type has special support in the runtime. Arrays perform best when unshared. As long as there is never more than one reference to an array, all updates will be performed _destructively_. This results in performance comparable to mutable arrays in imperative programming languages. An array has a size and a capacity. The size is the number of elements present in the array, while the capacity is the amount of memory currently allocated for elements. The size is accessible via `Array.size`, but the capacity is not observable from Lean code. `Array.emptyWithCapacity n` creates an array which is equal to `#[]`, but internally allocates an array of capacity `n`. When the size exceeds the capacity, allocation is required to grow the array. From the point of view of proofs, `Array α` is just a wrapper around `List α`.(Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.×Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.)Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.opaque PQXDHLean.Tactics.collectBVarPairs : Lean.Expr
Lean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.→ Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.→ ArrayArray.{u} (α : Type u) : Type u`Array α` is the type of [dynamic arrays](https://en.wikipedia.org/wiki/Dynamic_array) with elements from `α`. This type has special support in the runtime. Arrays perform best when unshared. As long as there is never more than one reference to an array, all updates will be performed _destructively_. This results in performance comparable to mutable arrays in imperative programming languages. An array has a size and a capacity. The size is the number of elements present in the array, while the capacity is the amount of memory currently allocated for elements. The size is accessible via `Array.size`, but the capacity is not observable from Lean code. `Array.emptyWithCapacity n` creates an array which is equal to `#[]`, but internally allocates an array of capacity `n`. When the size exceeds the capacity, allocation is required to grow the array. From the point of view of proofs, `Array α` is just a wrapper around `List α`.(Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.×Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.)Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.→ ArrayArray.{u} (α : Type u) : Type u`Array α` is the type of [dynamic arrays](https://en.wikipedia.org/wiki/Dynamic_array) with elements from `α`. This type has special support in the runtime. Arrays perform best when unshared. As long as there is never more than one reference to an array, all updates will be performed _destructively_. This results in performance comparable to mutable arrays in imperative programming languages. An array has a size and a capacity. The size is the number of elements present in the array, while the capacity is the amount of memory currently allocated for elements. The size is accessible via `Array.size`, but the capacity is not observable from Lean code. `Array.emptyWithCapacity n` creates an array which is equal to `#[]`, but internally allocates an array of capacity `n`. When the size exceeds the capacity, allocation is required to grow the array. From the point of view of proofs, `Array α` is just a wrapper around `List α`.(Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.×Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.)Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.Parallel traversal of two expressions to collect `(bvar_L, bvar_R)` pairs at corresponding positions. Both expressions should be structurally identical except for bvar indices.
5.6.5.5. Permutation computation and bubble sort
-
Definition 5.1Blueprint label
-
perm_draws_tactic
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.2Blueprint label
-
perm_draws_findApp
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.3Blueprint label
-
perm_draws_matchProbOutput
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.4Blueprint label
-
perm_draws_matchProbEvent
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.5Blueprint label
-
perm_draws_parseProbEqSides
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.6Blueprint label
-
perm_draws_extractBindChain
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.7Blueprint label
-
perm_draws_collectBVarPairs
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.9Blueprint label
-
perm_draws_bubbleSortSwaps
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.10Blueprint label
-
perm_draws_mkSwapProofTerm
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.11Blueprint label
-
perm_draws_emitLhsSwap
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.12Blueprint label
-
perm_draws_emitInsertUnusedDraw
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
perm_draws_tactic
- Custom tactic for automatic distributional equivalence proofs.
-
PQXDHLean.Tactics.computePermutation[complete]
Given bvar pairs and draw counts, compute the permutation mapping each LHS draw position to the corresponding RHS position. Unused LHS draws (newly inserted) are mapped to unused RHS positions.
Code for Definition5.8●1 definition
Associated Lean declarations
-
PQXDHLean.Tactics.computePermutation[complete]
-
PQXDHLean.Tactics.computePermutation[complete]
-
def PQXDHLean.Tactics.computePermutation (pairs
Array (ℕ × ℕ): ArrayArray.{u} (α : Type u) : Type u`Array α` is the type of [dynamic arrays](https://en.wikipedia.org/wiki/Dynamic_array) with elements from `α`. This type has special support in the runtime. Arrays perform best when unshared. As long as there is never more than one reference to an array, all updates will be performed _destructively_. This results in performance comparable to mutable arrays in imperative programming languages. An array has a size and a capacity. The size is the number of elements present in the array, while the capacity is the amount of memory currently allocated for elements. The size is accessible via `Array.size`, but the capacity is not observable from Lean code. `Array.emptyWithCapacity n` creates an array which is equal to `#[]`, but internally allocates an array of capacity `n`. When the size exceeds the capacity, allocation is required to grow the array. From the point of view of proofs, `Array α` is just a wrapper around `List α`.(Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.×Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.)Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.) (nLℕnRℕ: ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.) : Lean.MetaMLean.Meta.MetaM (α : Type) : TypeThe `MetaM` monad is a core component of Lean's metaprogramming framework, facilitating the construction and manipulation of expressions (`Lean.Expr`) within Lean. It builds on top of `CoreM` and additionally provides: - A `LocalContext` for managing free variables. - A `MetavarContext` for managing metavariables. - A `Cache` for caching results of the key `MetaM` operations. The key operations provided by `MetaM` are: - `inferType`, which attempts to automatically infer the type of a given expression. - `whnf`, which reduces an expression to the point where the outermost part is no longer reducible but the inside may still contain unreduced expression. - `isDefEq`, which determines whether two expressions are definitionally equal, possibly assigning meta variables in the process. - `forallTelescope` and `lambdaTelescope`, which make it possible to automatically move into (nested) binders while updating the local context. The following is a small example that demonstrates how to obtain and manipulate the type of a `Fin` expression: ``` public import Lean open Lean Meta def getFinBound (e : Expr) : MetaM (Option Expr) := do let type ← whnf (← inferType e) let_expr Fin bound := type | return none return bound def a : Fin 100 := 42 run_meta match ← getFinBound (.const ``a []) with | some limit => IO.println (← ppExpr limit) | none => IO.println "no limit found" ```(ArrayArray.{u} (α : Type u) : Type u`Array α` is the type of [dynamic arrays](https://en.wikipedia.org/wiki/Dynamic_array) with elements from `α`. This type has special support in the runtime. Arrays perform best when unshared. As long as there is never more than one reference to an array, all updates will be performed _destructively_. This results in performance comparable to mutable arrays in imperative programming languages. An array has a size and a capacity. The size is the number of elements present in the array, while the capacity is the amount of memory currently allocated for elements. The size is accessible via `Array.size`, but the capacity is not observable from Lean code. `Array.emptyWithCapacity n` creates an array which is equal to `#[]`, but internally allocates an array of capacity `n`. When the size exceeds the capacity, allocation is required to grow the array. From the point of view of proofs, `Array α` is just a wrapper around `List α`.ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.)def PQXDHLean.Tactics.computePermutation (pairs
Array (ℕ × ℕ): ArrayArray.{u} (α : Type u) : Type u`Array α` is the type of [dynamic arrays](https://en.wikipedia.org/wiki/Dynamic_array) with elements from `α`. This type has special support in the runtime. Arrays perform best when unshared. As long as there is never more than one reference to an array, all updates will be performed _destructively_. This results in performance comparable to mutable arrays in imperative programming languages. An array has a size and a capacity. The size is the number of elements present in the array, while the capacity is the amount of memory currently allocated for elements. The size is accessible via `Array.size`, but the capacity is not observable from Lean code. `Array.emptyWithCapacity n` creates an array which is equal to `#[]`, but internally allocates an array of capacity `n`. When the size exceeds the capacity, allocation is required to grow the array. From the point of view of proofs, `Array α` is just a wrapper around `List α`.(Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.×Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.)Prod.{u, v} (α : Type u) (β : Type v) : Type (max u v)The product type, usually written `α × β`. Product types are also called pair or tuple types. Elements of this type are pairs in which the first element is an `α` and the second element is a `β`. Products nest to the right, so `(x, y, z) : α × β × γ` is equivalent to `(x, (y, z)) : α × (β × γ)`. Conventions for notations in identifiers: * The recommended spelling of `×` in identifiers is `Prod`.) (nLℕnRℕ: ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.) : Lean.MetaMLean.Meta.MetaM (α : Type) : TypeThe `MetaM` monad is a core component of Lean's metaprogramming framework, facilitating the construction and manipulation of expressions (`Lean.Expr`) within Lean. It builds on top of `CoreM` and additionally provides: - A `LocalContext` for managing free variables. - A `MetavarContext` for managing metavariables. - A `Cache` for caching results of the key `MetaM` operations. The key operations provided by `MetaM` are: - `inferType`, which attempts to automatically infer the type of a given expression. - `whnf`, which reduces an expression to the point where the outermost part is no longer reducible but the inside may still contain unreduced expression. - `isDefEq`, which determines whether two expressions are definitionally equal, possibly assigning meta variables in the process. - `forallTelescope` and `lambdaTelescope`, which make it possible to automatically move into (nested) binders while updating the local context. The following is a small example that demonstrates how to obtain and manipulate the type of a `Fin` expression: ``` public import Lean open Lean Meta def getFinBound (e : Expr) : MetaM (Option Expr) := do let type ← whnf (← inferType e) let_expr Fin bound := type | return none return bound def a : Fin 100 := 42 run_meta match ← getFinBound (.const ``a []) with | some limit => IO.println (← ppExpr limit) | none => IO.println "no limit found" ```(ArrayArray.{u} (α : Type u) : Type u`Array α` is the type of [dynamic arrays](https://en.wikipedia.org/wiki/Dynamic_array) with elements from `α`. This type has special support in the runtime. Arrays perform best when unshared. As long as there is never more than one reference to an array, all updates will be performed _destructively_. This results in performance comparable to mutable arrays in imperative programming languages. An array has a size and a capacity. The size is the number of elements present in the array, while the capacity is the amount of memory currently allocated for elements. The size is accessible via `Array.size`, but the capacity is not observable from Lean code. `Array.emptyWithCapacity n` creates an array which is equal to `#[]`, but internally allocates an array of capacity `n`. When the size exceeds the capacity, allocation is required to grow the array. From the point of view of proofs, `Array α` is just a wrapper around `List α`.ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.)Given bvar pairs and draw counts, compute the permutation. `perm[lhsPos] = rhsPos` for each LHS draw position. Unused LHS draws (newly inserted) are mapped to unused RHS positions.
-
Definition 5.1Blueprint label
-
perm_draws_tactic
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.2Blueprint label
-
perm_draws_findApp
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.3Blueprint label
-
perm_draws_matchProbOutput
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.4Blueprint label
-
perm_draws_matchProbEvent
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.5Blueprint label
-
perm_draws_parseProbEqSides
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.6Blueprint label
-
perm_draws_extractBindChain
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.7Blueprint label
-
perm_draws_collectBVarPairs
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.8Blueprint label
-
perm_draws_computePermutation
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.10Blueprint label
-
perm_draws_mkSwapProofTerm
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.11Blueprint label
-
perm_draws_emitLhsSwap
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.12Blueprint label
-
perm_draws_emitInsertUnusedDraw
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
perm_draws_tactic
- Custom tactic for automatic distributional equivalence proofs.
-
PQXDHLean.Tactics.bubbleSortSwaps[complete]
Decompose a permutation into adjacent transpositions via bubble sort, producing a minimal swap sequence.
Code for Definition5.9●1 definition
Associated Lean declarations
-
PQXDHLean.Tactics.bubbleSortSwaps[complete]
-
PQXDHLean.Tactics.bubbleSortSwaps[complete]
-
def PQXDHLean.Tactics.bubbleSortSwaps (targetIndices
Array ℕ: ArrayArray.{u} (α : Type u) : Type u`Array α` is the type of [dynamic arrays](https://en.wikipedia.org/wiki/Dynamic_array) with elements from `α`. This type has special support in the runtime. Arrays perform best when unshared. As long as there is never more than one reference to an array, all updates will be performed _destructively_. This results in performance comparable to mutable arrays in imperative programming languages. An array has a size and a capacity. The size is the number of elements present in the array, while the capacity is the amount of memory currently allocated for elements. The size is accessible via `Array.size`, but the capacity is not observable from Lean code. `Array.emptyWithCapacity n` creates an array which is equal to `#[]`, but internally allocates an array of capacity `n`. When the size exceeds the capacity, allocation is required to grow the array. From the point of view of proofs, `Array α` is just a wrapper around `List α`.ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.) : ArrayArray.{u} (α : Type u) : Type u`Array α` is the type of [dynamic arrays](https://en.wikipedia.org/wiki/Dynamic_array) with elements from `α`. This type has special support in the runtime. Arrays perform best when unshared. As long as there is never more than one reference to an array, all updates will be performed _destructively_. This results in performance comparable to mutable arrays in imperative programming languages. An array has a size and a capacity. The size is the number of elements present in the array, while the capacity is the amount of memory currently allocated for elements. The size is accessible via `Array.size`, but the capacity is not observable from Lean code. `Array.emptyWithCapacity n` creates an array which is equal to `#[]`, but internally allocates an array of capacity `n`. When the size exceeds the capacity, allocation is required to grow the array. From the point of view of proofs, `Array α` is just a wrapper around `List α`.ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.def PQXDHLean.Tactics.bubbleSortSwaps (targetIndices
Array ℕ: ArrayArray.{u} (α : Type u) : Type u`Array α` is the type of [dynamic arrays](https://en.wikipedia.org/wiki/Dynamic_array) with elements from `α`. This type has special support in the runtime. Arrays perform best when unshared. As long as there is never more than one reference to an array, all updates will be performed _destructively_. This results in performance comparable to mutable arrays in imperative programming languages. An array has a size and a capacity. The size is the number of elements present in the array, while the capacity is the amount of memory currently allocated for elements. The size is accessible via `Array.size`, but the capacity is not observable from Lean code. `Array.emptyWithCapacity n` creates an array which is equal to `#[]`, but internally allocates an array of capacity `n`. When the size exceeds the capacity, allocation is required to grow the array. From the point of view of proofs, `Array α` is just a wrapper around `List α`.ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.) : ArrayArray.{u} (α : Type u) : Type u`Array α` is the type of [dynamic arrays](https://en.wikipedia.org/wiki/Dynamic_array) with elements from `α`. This type has special support in the runtime. Arrays perform best when unshared. As long as there is never more than one reference to an array, all updates will be performed _destructively_. This results in performance comparable to mutable arrays in imperative programming languages. An array has a size and a capacity. The size is the number of elements present in the array, while the capacity is the amount of memory currently allocated for elements. The size is accessible via `Array.size`, but the capacity is not observable from Lean code. `Array.emptyWithCapacity n` creates an array which is equal to `#[]`, but internally allocates an array of capacity `n`. When the size exceeds the capacity, allocation is required to grow the array. From the point of view of proofs, `Array α` is just a wrapper around `List α`.ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.Decompose a permutation into adjacent transpositions via bubble sort. Input: `targetIndices[i]` = where element at position `i` should go. Output: sequence of depths (swap positions `depth` and `depth+1`).
5.6.5.6. Tactic emission
-
Definition 5.1Blueprint label
-
perm_draws_tactic
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.2Blueprint label
-
perm_draws_findApp
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.3Blueprint label
-
perm_draws_matchProbOutput
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.4Blueprint label
-
perm_draws_matchProbEvent
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.5Blueprint label
-
perm_draws_parseProbEqSides
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.6Blueprint label
-
perm_draws_extractBindChain
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.7Blueprint label
-
perm_draws_collectBVarPairs
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.8Blueprint label
-
perm_draws_computePermutation
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.9Blueprint label
-
perm_draws_bubbleSortSwaps
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.11Blueprint label
-
perm_draws_emitLhsSwap
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.12Blueprint label
-
perm_draws_emitInsertUnusedDraw
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
perm_draws_tactic
- Custom tactic for automatic distributional equivalence proofs.
-
PQXDHLean.Tactics.mkSwapProofTerm[complete]
Build proof term for swapping adjacent draws at given depth.
Depth 0 uses probEvent_bind_bind_swap, depth n+1 wraps in
probEvent_bind_congr.
Code for Definition5.10●1 definition
Associated Lean declarations
-
PQXDHLean.Tactics.mkSwapProofTerm[complete]
-
PQXDHLean.Tactics.mkSwapProofTerm[complete]
-
def PQXDHLean.Tactics.mkSwapProofTerm (depth
ℕ: ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.) : Lean.Elab.Tactic.TacticMLean.Elab.Tactic.TacticM (α : Type) : TypeThe tactic monad, which extends the term elaboration monad `TermElabM` with state that contains the current goals (`Lean.Elab.Tactic.State`, accessible via `MonadStateOf`) and local information about the current tactic's name and whether error recovery is enabled (`Lean.Elab.Tactic.Context`, accessible via `MonadReaderOf`).(Lean.TSyntax (ks : Lean.SyntaxNodeKinds) : TypeTyped syntax, which tracks the potential kinds of the `Syntax` it contains. While syntax quotations produce or expect `TSyntax` values of the correct kinds, this is not otherwise enforced; it can easily be circumvented by direct use of the constructor.Lean.TSyntaxLean.TSyntax (ks : Lean.SyntaxNodeKinds) : TypeTyped syntax, which tracks the potential kinds of the `Syntax` it contains. While syntax quotations produce or expect `TSyntax` values of the correct kinds, this is not otherwise enforced; it can easily be circumvented by direct use of the constructor.`term)Lean.TSyntax (ks : Lean.SyntaxNodeKinds) : TypeTyped syntax, which tracks the potential kinds of the `Syntax` it contains. While syntax quotations produce or expect `TSyntax` values of the correct kinds, this is not otherwise enforced; it can easily be circumvented by direct use of the constructor.def PQXDHLean.Tactics.mkSwapProofTerm (depth
ℕ: ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.) : Lean.Elab.Tactic.TacticMLean.Elab.Tactic.TacticM (α : Type) : TypeThe tactic monad, which extends the term elaboration monad `TermElabM` with state that contains the current goals (`Lean.Elab.Tactic.State`, accessible via `MonadStateOf`) and local information about the current tactic's name and whether error recovery is enabled (`Lean.Elab.Tactic.Context`, accessible via `MonadReaderOf`).(Lean.TSyntax (ks : Lean.SyntaxNodeKinds) : TypeTyped syntax, which tracks the potential kinds of the `Syntax` it contains. While syntax quotations produce or expect `TSyntax` values of the correct kinds, this is not otherwise enforced; it can easily be circumvented by direct use of the constructor.Lean.TSyntaxLean.TSyntax (ks : Lean.SyntaxNodeKinds) : TypeTyped syntax, which tracks the potential kinds of the `Syntax` it contains. While syntax quotations produce or expect `TSyntax` values of the correct kinds, this is not otherwise enforced; it can easily be circumvented by direct use of the constructor.`term)Lean.TSyntax (ks : Lean.SyntaxNodeKinds) : TypeTyped syntax, which tracks the potential kinds of the `Syntax` it contains. While syntax quotations produce or expect `TSyntax` values of the correct kinds, this is not otherwise enforced; it can easily be circumvented by direct use of the constructor.Build proof term for swapping adjacent draws at given depth. Depth 0: `probEvent_bind_bind_swap _ _ _ _` Depth n+1: `probEvent_bind_congr fun _ _ => (inner)`
-
Definition 5.1Blueprint label
-
perm_draws_tactic
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.2Blueprint label
-
perm_draws_findApp
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.3Blueprint label
-
perm_draws_matchProbOutput
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.4Blueprint label
-
perm_draws_matchProbEvent
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.5Blueprint label
-
perm_draws_parseProbEqSides
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.6Blueprint label
-
perm_draws_extractBindChain
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.7Blueprint label
-
perm_draws_collectBVarPairs
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.8Blueprint label
-
perm_draws_computePermutation
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.9Blueprint label
-
perm_draws_bubbleSortSwaps
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.10Blueprint label
-
perm_draws_mkSwapProofTerm
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.12Blueprint label
-
perm_draws_emitInsertUnusedDraw
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
perm_draws_tactic
- Custom tactic for automatic distributional equivalence proofs.
-
PQXDHLean.Tactics.emitLhsSwap[complete]
Emit a single adjacent transposition at a given depth, targeting
LHS only. Handles the probOutput to probEvent conversion.
Code for Definition5.11●1 definition
Associated Lean declarations
-
PQXDHLean.Tactics.emitLhsSwap[complete]
-
PQXDHLean.Tactics.emitLhsSwap[complete]
-
def PQXDHLean.Tactics.emitLhsSwap (depth
ℕ: ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.) : Lean.Elab.Tactic.TacticMLean.Elab.Tactic.TacticM (α : Type) : TypeThe tactic monad, which extends the term elaboration monad `TermElabM` with state that contains the current goals (`Lean.Elab.Tactic.State`, accessible via `MonadStateOf`) and local information about the current tactic's name and whether error recovery is enabled (`Lean.Elab.Tactic.Context`, accessible via `MonadReaderOf`).UnitUnit : TypeThe canonical type with one element. This element is written `()`. `Unit` has a number of uses: * It can be used to model control flow that returns from a function call without providing other information. * Monadic actions that return `Unit` have side effects without computing values. * In polymorphic types, it can be used to indicate that no data is to be stored in a particular field.def PQXDHLean.Tactics.emitLhsSwap (depth
ℕ: ℕNat : TypeThe natural numbers, starting at zero. This type is special-cased by both the kernel and the compiler, and overridden with an efficient implementation. Both use a fast arbitrary-precision arithmetic library (usually [GMP](https://gmplib.org/)); at runtime, `Nat` values that are sufficiently small are unboxed.) : Lean.Elab.Tactic.TacticMLean.Elab.Tactic.TacticM (α : Type) : TypeThe tactic monad, which extends the term elaboration monad `TermElabM` with state that contains the current goals (`Lean.Elab.Tactic.State`, accessible via `MonadStateOf`) and local information about the current tactic's name and whether error recovery is enabled (`Lean.Elab.Tactic.Context`, accessible via `MonadReaderOf`).UnitUnit : TypeThe canonical type with one element. This element is written `()`. `Unit` has a number of uses: * It can be used to model control flow that returns from a function call without providing other information. * Monadic actions that return `Unit` have side effects without computing values. * In polymorphic types, it can be used to indicate that no data is to be stored in a particular field.Emit a single adjacent transposition at `depth`, targeting LHS only. Handles the `probOutput`↔`probEvent` conversion.
-
Definition 5.1Blueprint label
-
perm_draws_tactic
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.2Blueprint label
-
perm_draws_findApp
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.3Blueprint label
-
perm_draws_matchProbOutput
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.4Blueprint label
-
perm_draws_matchProbEvent
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.5Blueprint label
-
perm_draws_parseProbEqSides
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.6Blueprint label
-
perm_draws_extractBindChain
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.7Blueprint label
-
perm_draws_collectBVarPairs
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.8Blueprint label
-
perm_draws_computePermutation
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.9Blueprint label
-
perm_draws_bubbleSortSwaps
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.10Blueprint label
-
perm_draws_mkSwapProofTerm
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
Definition 5.11Blueprint label
-
perm_draws_emitLhsSwap
Group- Custom tactic for automatic distributional equivalence proofs.
-
-
perm_draws_tactic
- Custom tactic for automatic distributional equivalence proofs.
-
PQXDHLean.Tactics.emitInsertUnusedDraw[complete]
Insert one unused draw at position 0 in LHS via
probOutput_bind_const.
Code for Definition5.12●1 definition
Associated Lean declarations
-
PQXDHLean.Tactics.emitInsertUnusedDraw[complete]
-
PQXDHLean.Tactics.emitInsertUnusedDraw[complete]
-
def PQXDHLean.Tactics.emitInsertUnusedDraw (sampleExpr
Lean.ExprzLean.Expr: Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.) : Lean.Elab.Tactic.TacticMLean.Elab.Tactic.TacticM (α : Type) : TypeThe tactic monad, which extends the term elaboration monad `TermElabM` with state that contains the current goals (`Lean.Elab.Tactic.State`, accessible via `MonadStateOf`) and local information about the current tactic's name and whether error recovery is enabled (`Lean.Elab.Tactic.Context`, accessible via `MonadReaderOf`).UnitUnit : TypeThe canonical type with one element. This element is written `()`. `Unit` has a number of uses: * It can be used to model control flow that returns from a function call without providing other information. * Monadic actions that return `Unit` have side effects without computing values. * In polymorphic types, it can be used to indicate that no data is to be stored in a particular field.def PQXDHLean.Tactics.emitInsertUnusedDraw (sampleExpr
Lean.ExprzLean.Expr: Lean.ExprLean.Expr : TypeLean expressions. This data structure is used in the kernel and elaborator. However, expressions sent to the kernel should not contain metavariables. Remark: we use the `E` suffix (short for `Expr`) to avoid collision with keywords. We considered using «...», but it is too inconvenient to use.) : Lean.Elab.Tactic.TacticMLean.Elab.Tactic.TacticM (α : Type) : TypeThe tactic monad, which extends the term elaboration monad `TermElabM` with state that contains the current goals (`Lean.Elab.Tactic.State`, accessible via `MonadStateOf`) and local information about the current tactic's name and whether error recovery is enabled (`Lean.Elab.Tactic.Context`, accessible via `MonadReaderOf`).UnitUnit : TypeThe canonical type with one element. This element is written `()`. `Unit` has a number of uses: * It can be used to model control flow that returns from a function call without providing other information. * Monadic actions that return `Unit` have side effects without computing values. * In polymorphic types, it can be used to indicate that no data is to be stored in a particular field.Insert one unused draw at position 0 in LHS. `sampleExpr` is the draw computation to prepend (e.g., `$ᵗ F`). `z` is the output value from the `Pr[= z | ...]` goal.