Skip to content

Commit

Permalink
Merge branch 'main' into refactor/drop-value
Browse files Browse the repository at this point in the history
  • Loading branch information
aborgna-q committed Mar 18, 2024
2 parents 5fecc9c + 9ef7808 commit 1b6faa5
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 46 deletions.
16 changes: 5 additions & 11 deletions quantinuum-hugr/src/extension/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,6 @@ pub fn infer_extensions(
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
struct Meta(u32);

impl Meta {
pub fn new(m: u32) -> Self {
Meta(m)
}
}

#[derive(Clone, Debug, Eq, PartialEq, Hash)]
/// Things we know about metavariables
enum Constraint {
Expand Down Expand Up @@ -190,7 +184,7 @@ struct UnificationContext {
impl UnificationContext {
/// Create a new unification context, and populate it with constraints from
/// traversing the hugr which is passed in.
pub fn new(hugr: &impl HugrView) -> Self {
fn new(hugr: &impl HugrView) -> Self {
let mut ctx = Self {
constraints: HashMap::new(),
extensions: HashMap::new(),
Expand All @@ -206,7 +200,7 @@ impl UnificationContext {

/// Create a fresh metavariable, and increment `fresh_name` for next time
fn fresh_meta(&mut self) -> Meta {
let fresh = Meta::new(self.fresh_name);
let fresh = Meta(self.fresh_name);
self.fresh_name += 1;
self.constraints.insert(fresh, HashSet::new());
fresh
Expand Down Expand Up @@ -544,7 +538,7 @@ impl UnificationContext {
/// available. When there are variables, we should leave the graph as it is,
/// but make sure that no matter what they're instantiated to, the graph
/// still makes sense (should pass the extension validation check)
pub fn results(&self) -> Result<ExtensionSolution, InferExtensionError> {
fn results(&self) -> Result<ExtensionSolution, InferExtensionError> {
// Check that all of the metavariables associated with nodes of the
// graph are solved
let depended_upon = {
Expand Down Expand Up @@ -612,7 +606,7 @@ impl UnificationContext {
/// where it was possible to infer them. If it wasn't possible to infer a
/// *concrete* `ExtensionSet`, e.g. if the ExtensionSet relies on an open
/// variable in the toplevel graph, don't include that location in the map
pub fn main_loop(&mut self) -> Result<ExtensionSolution, InferExtensionError> {
fn main_loop(&mut self) -> Result<ExtensionSolution, InferExtensionError> {
let mut remaining = HashSet::<Meta>::from_iter(self.constraints.keys().cloned());

// Keep going as long as we're making progress (= merging and solving nodes)
Expand Down Expand Up @@ -674,7 +668,7 @@ impl UnificationContext {
/// 2 = 1 + x, ...
/// then 1 and 2 both definitely contain X, even if we don't know what else.
/// So instead of instantiating to the empty set, we'll instantiate to `{X}`
pub fn instantiate_variables(&mut self) {
fn instantiate_variables(&mut self) {
// A directed graph to keep track of `Plus` constraint relationships
let mut relations = GraphContainer::<Directed>::new();
let mut solutions: HashMap<Meta, ExtensionSet> = HashMap::new();
Expand Down
38 changes: 32 additions & 6 deletions quantinuum-hugr/src/hugr/views.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ use super::{Hugr, HugrError, NodeMetadata, NodeMetadataMap, NodeType, DEFAULT_NO
use crate::ops::handle::NodeHandle;
use crate::ops::{OpParent, OpTag, OpTrait, OpType};

use crate::types::Type;
use crate::types::{EdgeKind, FunctionType};
use crate::types::{PolyFuncType, Type};
use crate::{Direction, IncomingPort, Node, OutgoingPort, Port};

use itertools::Either;
Expand Down Expand Up @@ -327,11 +327,37 @@ pub trait HugrView: sealed::HugrInternals {
}
}

/// For HUGRs with a [`DataflowParent`][crate::ops::DataflowParent] root operation, report the
/// signature of the inner dataflow sibling graph. Otherwise return None.
fn get_function_type(&self) -> Option<FunctionType> {
let op = self.get_nodetype(self.root());
op.op.inner_function_type()
/// Returns the function type defined by this dataflow HUGR.
///
/// If the root of the Hugr is a
/// [`DataflowParent`][crate::ops::DataflowParent] operation, report the
/// signature corresponding to the input and output node of its sibling
/// graph. Otherwise, returns `None`.
///
/// In contrast to [`get_function_type`][HugrView::get_function_type], this
/// method always return a concrete [`FunctionType`].
fn get_df_function_type(&self) -> Option<FunctionType> {
let op = self.get_optype(self.root());
op.inner_function_type()
}

/// Returns the function type defined by this HUGR.
///
/// For HUGRs with a [`DataflowParent`][crate::ops::DataflowParent] root
/// operation, report the signature of the inner dataflow sibling graph.
///
/// For HUGRS with a [`FuncDecl`][crate::ops::FuncDecl] or
/// [`FuncDefn`][crate::ops::FuncDefn] root operation, report the signature
/// of the function.
///
/// Otherwise, returns `None`.
fn get_function_type(&self) -> Option<PolyFuncType> {
let op = self.get_optype(self.root());
match op {
OpType::FuncDecl(decl) => Some(decl.signature.clone()),
OpType::FuncDefn(defn) => Some(defn.signature.clone()),
_ => op.inner_function_type().map(PolyFuncType::from),
}
}

/// Return a wrapper over the view that can be used in petgraph algorithms.
Expand Down
4 changes: 2 additions & 2 deletions quantinuum-hugr/src/hugr/views/descendants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,12 +261,12 @@ pub(super) mod test {

assert_eq!(
region.get_function_type(),
Some(FunctionType::new_endo(type_row![NAT, QB]))
Some(FunctionType::new_endo(type_row![NAT, QB]).into())
);
let inner_region: DescendantsGraph = DescendantsGraph::try_new(&hugr, inner)?;
assert_eq!(
inner_region.get_function_type(),
Some(FunctionType::new(type_row![NAT], type_row![NAT]))
Some(FunctionType::new(type_row![NAT], type_row![NAT]).into())
);

Ok(())
Expand Down
2 changes: 1 addition & 1 deletion quantinuum-hugr/src/hugr/views/sibling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ mod test {
fn flat_mut(mut simple_dfg_hugr: Hugr) {
simple_dfg_hugr.update_validate(&PRELUDE_REGISTRY).unwrap();
let root = simple_dfg_hugr.root();
let signature = simple_dfg_hugr.get_function_type().unwrap();
let signature = simple_dfg_hugr.get_df_function_type().unwrap().clone();

let sib_mut = SiblingMut::<CfgID>::try_new(&mut simple_dfg_hugr, root);
assert_eq!(
Expand Down
31 changes: 5 additions & 26 deletions quantinuum-hugr/src/ops/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
mod custom;

use super::{OpName, OpParent, OpTrait, StaticTag};
use super::{OpName, OpTrait, StaticTag};
use super::{OpTag, OpType};
use crate::extension::ExtensionSet;
use crate::types::{CustomType, EdgeKind, PolyFuncType, SumType, SumTypeError, Type};
use crate::types::{CustomType, EdgeKind, SumType, SumTypeError, Type};
use crate::{Hugr, HugrView};

use itertools::Itertools;
Expand Down Expand Up @@ -118,7 +118,7 @@ impl Const {
Self::Tuple { vs } => Type::new_tuple(vs.iter().map(Self::const_type).collect_vec()),
Self::Sum { sum_type, .. } => sum_type.clone().into(),
Self::Function { hugr } => {
let func_type = get_const_function_type(hugr).unwrap_or_else(|| {
let func_type = hugr.get_function_type().unwrap_or_else(|| {
panic!(
"{}",
ConstTypeError::FunctionTypeMissing {
Expand Down Expand Up @@ -161,7 +161,7 @@ impl Const {
/// Returns an error if the Hugr root node does not define a function.
pub fn function(hugr: impl Into<Hugr>) -> Result<Self, ConstTypeError> {
let hugr = hugr.into();
if get_const_function_type(&hugr).is_none() {
if hugr.get_function_type().is_none() {
Err(ConstTypeError::FunctionTypeMissing {
hugr_root_type: hugr.get_optype(hugr.root()).clone(),
})?;
Expand Down Expand Up @@ -228,7 +228,7 @@ impl OpName for Const {
match self {
Self::Extension { e } => format!("const:custom:{}", e.0.name()),
Self::Function { hugr: h } => {
let Some(t) = get_const_function_type(h) else {
let Some(t) = h.get_function_type() else {
panic!("HUGR root node isn't a valid function parent.");
};
format!("const:function:[{}]", t)
Expand Down Expand Up @@ -272,27 +272,6 @@ impl OpTrait for Const {
}
}

/// Returns the function type defined by the HUGR. In contrast to
/// [`Hugr::get_function_type`], this function also returns function types for
/// `FuncDecl` and `FuncDefn` operations.
///
/// For HUGRs with a [`DataflowParent`][crate::ops::DataflowParent] root
/// operation, report the signature of the inner dataflow sibling graph.
///
/// For HUGRS with a [`FuncDecl`][crate::ops::FuncDecl] or
/// [`FuncDefn`][crate::ops::FuncDefn] root operation, report the signature of
/// the function.
///
/// Otherwise, returns `None`.
fn get_const_function_type(hugr: &impl HugrView) -> Option<PolyFuncType> {
let op = hugr.get_optype(hugr.root());
match op {
OpType::FuncDecl(decl) => Some(decl.signature.clone()),
OpType::FuncDefn(defn) => Some(defn.signature.clone()),
_ => op.inner_function_type().map(PolyFuncType::from),
}
}

// [KnownTypeConst] is guaranteed to be the right type, so can be constructed
// without initial type check.
impl<T> From<T> for Const
Expand Down

0 comments on commit 1b6faa5

Please sign in to comment.