Skip to content

Commit

Permalink
change 'trait Substitution' into its only impl (SubstValues)
Browse files Browse the repository at this point in the history
inline apply_typevar
  • Loading branch information
acl-cqc committed Apr 2, 2024
1 parent 6dee540 commit ec78a49
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 46 deletions.
2 changes: 1 addition & 1 deletion quantinuum-hugr/src/extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -492,7 +492,7 @@ impl ExtensionSet {
.try_for_each(|var_idx| check_typevar_decl(params, var_idx, &TypeParam::Extensions))
}

pub(crate) fn substitute(&self, t: &impl Substitution) -> Self {
pub(crate) fn substitute(&self, t: &Substitution) -> Self {
Self::from_iter(self.0.iter().flat_map(|e| match as_typevar(e) {
None => vec![e.clone()],
Some(i) => match t.apply_var(i, &TypeParam::Extensions) {
Expand Down
42 changes: 24 additions & 18 deletions quantinuum-hugr/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub mod type_param;
pub mod type_row;

pub use crate::ops::constant::{ConstTypeError, CustomCheckFailure};
use crate::types::type_param::check_type_arg;
use crate::utils::display_list_with_separator;
pub use check::SumTypeError;
pub use custom::CustomType;
Expand Down Expand Up @@ -357,10 +358,15 @@ impl Type {
}
}

pub(crate) fn substitute(&self, t: &impl Substitution) -> Self {
pub(crate) fn substitute(&self, t: &Substitution) -> Self {
match &self.0 {
TypeEnum::Alias(_) | TypeEnum::Sum(SumType::Unit { .. }) => self.clone(),
TypeEnum::Variable(idx, bound) => t.apply_typevar(*idx, *bound),
TypeEnum::Variable(idx, bound) => {
let TypeArg::Type { ty } = t.apply_var(*idx, &((*bound).into())) else {
panic!("Variable was not a type - try validate() first")
};
ty
}
TypeEnum::Extension(cty) => Type::new_extension(cty.substitute(t)),
TypeEnum::Function(bf) => Type::new_function(bf.substitute(t)),
TypeEnum::Sum(SumType::General { rows }) => {
Expand All @@ -370,26 +376,26 @@ impl Type {
}
}

/// A function that replaces type variables with values.
/// (The values depend upon the implementation, to allow dynamic computation;
/// and [Substitution] deals only with type variables, other/containing types/typeargs
/// are handled by [Type::substitute], [TypeArg::substitute] and friends.)
pub(crate) trait Substitution {
/// Apply to a variable of kind [TypeParam::Type]
fn apply_typevar(&self, idx: usize, bound: TypeBound) -> Type {
let TypeArg::Type { ty } = self.apply_var(idx, &bound.into()) else {
panic!("Variable was not a type - try validate() first")
};
ty
/// Details a replacement of type variables with a finite list of known values.
/// (Variables out of the range of the list will result in a panic)
pub(crate) struct Substitution<'a>(&'a [TypeArg], &'a ExtensionRegistry);

impl<'a> Substitution<'a> {
pub(crate) fn apply_var(&self, idx: usize, decl: &TypeParam) -> TypeArg {
let arg = self
.0
.get(idx)
.expect("Undeclared type variable - call validate() ?");
debug_assert_eq!(check_type_arg(arg, decl), Ok(()));
arg.clone()
}

/// Apply to a variable whose kind is any given [TypeParam]
fn apply_var(&self, idx: usize, decl: &TypeParam) -> TypeArg;

fn extension_registry(&self) -> &ExtensionRegistry;
fn extension_registry(&self) -> &ExtensionRegistry {
self.1
}
}

fn subst_row(row: &TypeRow, tr: &impl Substitution) -> TypeRow {
fn subst_row(row: &TypeRow, tr: &Substitution) -> TypeRow {
let res = row
.iter()
.map(|ty| ty.substitute(tr))
Expand Down
2 changes: 1 addition & 1 deletion quantinuum-hugr/src/types/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ impl CustomType {
})
}

pub(super) fn substitute(&self, tr: &impl Substitution) -> Self {
pub(super) fn substitute(&self, tr: &Substitution) -> Self {
let args = self
.args
.iter()
Expand Down
26 changes: 2 additions & 24 deletions quantinuum-hugr/src/types/poly_func.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
//! Polymorphic Function Types
use crate::{
extension::{ExtensionRegistry, SignatureError},
types::type_param::check_type_arg,
};
use crate::extension::{ExtensionRegistry, SignatureError};
use itertools::Itertools;

use super::type_param::{check_type_args, TypeArg, TypeParam};
Expand Down Expand Up @@ -111,26 +108,7 @@ impl PolyFuncType {
// Check that args are applicable, and that we have a value for each binder,
// i.e. each possible free variable within the body.
check_type_args(args, &self.params)?;
Ok(self.body.substitute(&SubstValues(args, ext_reg)))
}
}

/// A [Substitution] with a finite list of known values.
/// (Variables out of the range of the list will result in a panic)
struct SubstValues<'a>(&'a [TypeArg], &'a ExtensionRegistry);

impl<'a> Substitution for SubstValues<'a> {
fn apply_var(&self, idx: usize, decl: &TypeParam) -> TypeArg {
let arg = self
.0
.get(idx)
.expect("Undeclared type variable - call validate() ?");
debug_assert_eq!(check_type_arg(arg, decl), Ok(()));
arg.clone()
}

fn extension_registry(&self) -> &ExtensionRegistry {
self.1
Ok(self.body.substitute(&Substitution(args, ext_reg)))
}
}

Expand Down
2 changes: 1 addition & 1 deletion quantinuum-hugr/src/types/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl FunctionType {
self.extension_reqs.validate(var_decls)
}

pub(crate) fn substitute(&self, tr: &impl Substitution) -> Self {
pub(crate) fn substitute(&self, tr: &Substitution) -> Self {
FunctionType {
input: subst_row(&self.input, tr),
output: subst_row(&self.output, tr),
Expand Down
2 changes: 1 addition & 1 deletion quantinuum-hugr/src/types/type_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ impl TypeArg {
}
}

pub(crate) fn substitute(&self, t: &impl Substitution) -> Self {
pub(crate) fn substitute(&self, t: &Substitution) -> Self {
match self {
TypeArg::Type { ty } => TypeArg::Type {
ty: ty.substitute(t),
Expand Down

0 comments on commit ec78a49

Please sign in to comment.