Skip to content

Commit

Permalink
[refactor] Rename Alias/Func Def/Decl nodes (#232)
Browse files Browse the repository at this point in the history
* Def => FuncDefn
* Declare => FuncDecl
* AliasDef => AliasDefn
* AliasDeclare => AliasDecl

Also update spec
  • Loading branch information
acl-cqc committed Jun 30, 2023
1 parent 161adae commit e6abc02
Show file tree
Hide file tree
Showing 12 changed files with 82 additions and 82 deletions.
40 changes: 20 additions & 20 deletions specification/hugr.md
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ source node, to an incoming port of the target node.
A `Static` edge represents dataflow that is statically knowable - i.e.
the source is a compile-time constant defined in the program. Hence, the types on these edges
do not include a resource specification. Only a few nodes may be
sources (`Def`, `Declare` and `Const`) and targets (`Call` and `LoadConstant`) of
sources (`FuncDefn`, `FuncDecl` and `Const`) and targets (`Call` and `LoadConstant`) of
these edges; see
[operations](#node-operations).

Expand Down Expand Up @@ -245,36 +245,36 @@ operations have value ports, but some have Static or other
edges. The following operations are *only* valid as immediate children of a
`Module` node.

- `Declare`: an external function declaration. The name of the function
- `FuncDecl`: an external function declaration. The name of the function
and function attributes (relevant for compilation)
define the node weight. The node has an outgoing `Static<Graph>`
edge for each use of the function. The function name is used at link time to
look up definitions in linked
modules (other hugr instances specified to the linker).

- `AliasDeclare`: an external type alias declaration. At link time this can be
replaced with the definition. An alias declared with `AliasDeclare` is equivalent to a
- `AliasDecl`: an external type alias declaration. At link time this can be
replaced with the definition. An alias declared with `AliasDecl` is equivalent to a
named opaque type.

The following operations are valid at the module level, but *also* in dataflow
regions:

- `Const<T>` : a static constant value of type T stored in the node
weight. Like `Declare` and `Def` this has one `Static<T>` out-edge per use.
weight. Like `FuncDecl` and `FuncDefn` this has one `Static<T>` out-edge per use.

- `Def` : a function definition. Like `Declare` but with a function body.
- `FuncDefn` : a function definition. Like `FuncDecl` but with a function body.
The function body is defined by the sibling graph formed by its children.
At link time `Declare` nodes are replaced by `Def`.
At link time `FuncDecl` nodes are replaced by `FuncDefn`.

- `AliasDef`: type alias definition. At link time `AliasDeclare` can be replaced with
`AliasDef`.
- `AliasDefn`: type alias definition. At link time `AliasDecl` can be replaced with
`AliasDefn`.


A **loadable HUGR** is a module HUGR where all input ports are connected and there are
no `Declare/AliasDeclare` nodes.
no `FuncDecl/AliasDecl` nodes.

An **executable HUGR** or **executable module** is a loadable HUGR where the
root Module node has a `Def` child with function name
root Module node has a `FuncDefn` child with function name
“main”, that is the designated entry point. Modules that act as libraries need
not be executable.

Expand Down Expand Up @@ -450,10 +450,10 @@ has no parent).
| Conditional | " | `Conditional` | **C** | `Case` | No edges |
| **C:** Dataflow container | " | `TailLoop` | **C** | **D** | First(second) is `Input`(`Output`) |
| " | " | `DFG` | **C** | " | " |
| " | Static | `Def` | **C** | " | " |
| " | Static | `FuncDefn` | **C** | " | " |
| " | ControlFlow | `DFB` | CFG | " | " |
| " | \- | `Case` | `Conditional` | " | " |
| Root | \- | `Module` | none | " | Contains main `Def` for executable HUGR. |
| Root | \- | `Module` | none | " | Contains main `FuncDefn` for executable HUGR. |

These relationships allow to define two common varieties of sibling
graph:
Expand All @@ -466,7 +466,7 @@ cycles. The common parent is a CFG-node.
`Conditional`, `TailLoop` and `DFG` nodes; edges are `Value`, `Order` and `Static`;
and must be acyclic. There is a unique Input node and Output node. All nodes must be
reachable from the Input node, and must reach the Output node. The common parent
may be a `Def`, `TailLoop`, `DFG`, `Case` or `DFB` node.
may be a `FuncDefn`, `TailLoop`, `DFG`, `Case` or `DFB` node.

| **Edge Kind** | **Locality** |
| -------------- | ------------ |
Expand Down Expand Up @@ -1748,11 +1748,11 @@ an edge weight.
Conditional or TailLoop node. All incoming and outgoing edges are
value edges.

- **Declare node**: child of a module, indicates that an external
- **FuncDecl node**: child of a module, indicates that an external
function exists but without giving a definition. May be the source
of Static-edges to Call nodes and others.

- **Def node**: child of a module node, defines a function (by being
- **FuncDefn node**: child of a module node, defines a function (by being
parent to the function’s body). May be the source of Static-edges to
Call nodes and others.

Expand Down Expand Up @@ -1950,10 +1950,10 @@ including `Module`.
| Node type | `Value` | `Order` | `Static` | `ControlFlow` | `Hierarchy` | Children |
| -------------- | ------- | ------- |--------- | ------------- | ----------- | -------- |
| Root | 0, 0 | 0, 0 | 0, 0 | 0, 0 | 0, ✱ | |
| `Def` | 0, 0 | 0, 0 | 0, ✱ | 0, 0 | 1, + | DSG |
| `Declare` | 0, 0 | 0, 0 | 0, ✱ | 0, 0 | 1, 0 | |
| `AliasDef` | 0, 0 | 0, 0 | 0, 0 | 0, 0 | 1, 0 | |
| `AliasDeclare` | 0, 0 | 0, 0 | 0, 0 | 0, 0 | 1, 0 | |
| `FuncDefn` | 0, 0 | 0, 0 | 0, ✱ | 0, 0 | 1, + | DSG |
| `FuncDecl` | 0, 0 | 0, 0 | 0, ✱ | 0, 0 | 1, 0 | |
| `AliasDefn` | 0, 0 | 0, 0 | 0, 0 | 0, 0 | 1, 0 | |
| `AliasDecl` | 0, 0 | 0, 0 | 0, 0 | 0, 0 | 1, 0 | |
| `Const` | 0, 0 | 0, 0 | 0, ✱ | 0, 0 | 1, 0 | |
| `LoadConstant` | 0, 1 | +, ✱ | 1, 0 | 0, 0 | 1, 0 | |
| `Input` | 0, ✱ | 0, ✱ | 0, 0 | 0, 0 | 1, 0 | |
Expand Down
16 changes: 8 additions & 8 deletions src/builder/build_traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,19 @@ pub trait Container {
Ok((const_n, typ).into())
}

/// Add a [`ops::Def`] node and returns a builder to define the function
/// Add a [`ops::FuncDefn`] node and returns a builder to define the function
/// body graph.
///
/// # Errors
///
/// This function will return an error if there is an error in adding the
/// [`ops::Def`] node.
/// [`ops::FuncDefn`] node.
fn define_function(
&mut self,
name: impl Into<String>,
signature: Signature,
) -> Result<FunctionBuilder<&mut Hugr>, BuildError> {
let f_node = self.add_child_op(ops::Def {
let f_node = self.add_child_op(ops::FuncDefn {
name: name.into(),
signature: signature.clone(),
})?;
Expand Down Expand Up @@ -508,8 +508,8 @@ pub trait Dataflow: Container {
/// # Errors
///
/// This function will return an error if there is an error adding the Call
/// node, or if `function` does not refer to a [`ops::Declare`] or
/// [`ops::Def`] node.
/// node, or if `function` does not refer to a [`ops::FuncDecl`] or
/// [`ops::FuncDefn`] node.
fn call<const DEFINED: bool>(
&mut self,
function: &FuncID<DEFINED>,
Expand All @@ -518,12 +518,12 @@ pub trait Dataflow: Container {
let hugr = self.hugr();
let def_op = hugr.get_optype(function.node());
let signature = match def_op {
OpType::Def(ops::Def { signature, .. })
| OpType::Declare(ops::Declare { signature, .. }) => signature.clone(),
OpType::FuncDefn(ops::FuncDefn { signature, .. })
| OpType::FuncDecl(ops::FuncDecl { signature, .. }) => signature.clone(),
_ => {
return Err(BuildError::UnexpectedType {
node: function.node(),
op_desc: "Declare/Def",
op_desc: "FuncDecl/FuncDefn",
})
}
};
Expand Down
6 changes: 3 additions & 3 deletions src/builder/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -125,16 +125,16 @@ impl<B, T> DFGWrapper<B, T> {
}
}

/// Builder for a [`ops::Def`] node
/// Builder for a [`ops::FuncDefn`] node
pub type FunctionBuilder<B> = DFGWrapper<B, BuildHandle<FuncID<true>>>;

impl FunctionBuilder<Hugr> {
/// Initialize a builder for a Def rooted HUGR
/// Initialize a builder for a FuncDefn rooted HUGR
/// # Errors
///
/// Error in adding DFG child nodes.
pub fn new(name: impl Into<String>, signature: Signature) -> Result<Self, BuildError> {
let op = ops::Def {
let op = ops::FuncDefn {
signature: signature.clone(),
name: name.into(),
};
Expand Down
28 changes: 14 additions & 14 deletions src/builder/module_builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,31 +62,31 @@ impl HugrBuilder for ModuleBuilder<Hugr> {
}

impl<T: AsMut<Hugr> + AsRef<Hugr>> ModuleBuilder<T> {
/// Replace a [`ops::Declare`] with [`ops::Def`] and return a builder for
/// Replace a [`ops::FuncDecl`] with [`ops::FuncDefn`] and return a builder for
/// the defining graph.
///
/// # Errors
///
/// This function will return an error if there is an error in adding the
/// [`OpType::Def`] node.
/// [`OpType::FuncDefn`] node.
pub fn define_declaration(
&mut self,
f_id: &FuncID<false>,
) -> Result<FunctionBuilder<&mut Hugr>, BuildError> {
let f_node = f_id.node();
let (signature, name) = if let OpType::Declare(ops::Declare { signature, name }) =
let (signature, name) = if let OpType::FuncDecl(ops::FuncDecl { signature, name }) =
self.hugr().get_optype(f_node)
{
(signature.clone(), name.clone())
} else {
return Err(BuildError::UnexpectedType {
node: f_node,
op_desc: "OpType::Declare",
op_desc: "OpType::FuncDecl",
});
};
self.hugr_mut().replace_op(
f_node,
ops::Def {
ops::FuncDefn {
name,
signature: signature.clone(),
},
Expand All @@ -101,57 +101,57 @@ impl<T: AsMut<Hugr> + AsRef<Hugr>> ModuleBuilder<T> {
/// # Errors
///
/// This function will return an error if there is an error in adding the
/// [`OpType::Declare`] node.
/// [`OpType::FuncDecl`] node.
pub fn declare(
&mut self,
name: impl Into<String>,
signature: Signature,
) -> Result<FuncID<false>, BuildError> {
// TODO add param names to metadata
let declare_n = self.add_child_op(ops::Declare {
let declare_n = self.add_child_op(ops::FuncDecl {
signature,
name: name.into(),
})?;

Ok(declare_n.into())
}

/// Add a [`OpType::AliasDef`] node and return a handle to the Alias.
/// Add a [`OpType::AliasDefn`] node and return a handle to the Alias.
///
/// # Errors
///
/// Error in adding [`OpType::AliasDef`] child node.
/// Error in adding [`OpType::AliasDefn`] child node.
pub fn add_alias_def(
&mut self,
name: impl Into<SmolStr>,
typ: SimpleType,
) -> Result<AliasID<true>, BuildError> {
// TODO: add AliasDef in other containers
// TODO: add AliasDefn in other containers
// This is currently tricky as they are not connected to anything so do
// not appear in topological traversals.
// Could be fixed by removing single-entry requirement and sorting from
// every 0-input node.
let name: SmolStr = name.into();
let linear = typ.is_linear();
let node = self.add_child_op(ops::AliasDef {
let node = self.add_child_op(ops::AliasDefn {
name: name.clone(),
definition: typ,
})?;

Ok(AliasID::new(node, name, linear))
}

/// Add a [`OpType::AliasDeclare`] node and return a handle to the Alias.
/// Add a [`OpType::AliasDecl`] node and return a handle to the Alias.
/// # Errors
///
/// Error in adding [`OpType::AliasDeclare`] child node.
/// Error in adding [`OpType::AliasDecl`] child node.
pub fn add_alias_declare(
&mut self,
name: impl Into<SmolStr>,
linear: bool,
) -> Result<AliasID<false>, BuildError> {
let name: SmolStr = name.into();
let node = self.add_child_op(ops::AliasDeclare {
let node = self.add_child_op(ops::AliasDecl {
name: name.clone(),
linear,
})?;
Expand Down
2 changes: 1 addition & 1 deletion src/hugr/hugrmut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ mod test {
let f: Node = builder
.add_op_with_parent(
module,
ops::Def {
ops::FuncDefn {
name: "main".into(),
signature: Signature::new_df(type_row![NAT], type_row![NAT, NAT]),
},
Expand Down
8 changes: 4 additions & 4 deletions src/hugr/validate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ impl<'a> ValidationContext<'a> {
return typecheck_const(&typ, val).map_err(ValidationError::from);
} else {
// If const edges aren't coming from const nodes, they're graph
// edges coming from Declare or Def
// edges coming from FuncDecl or FuncDefn
return if OpTag::Function.contains(from_optype.tag()) {
Ok(())
} else {
Expand Down Expand Up @@ -746,7 +746,7 @@ mod test {
///
/// Returns the hugr and the node index of the definition.
fn make_simple_hugr(copies: usize) -> (Hugr, Node) {
let def_op: OpType = ops::Def {
let def_op: OpType = ops::FuncDefn {
name: "main".into(),
signature: Signature::new_df(type_row![B], vec![B; copies]),
}
Expand Down Expand Up @@ -827,7 +827,7 @@ mod test {

#[test]
fn invalid_root() {
let declare_op: OpType = ops::Declare {
let declare_op: OpType = ops::FuncDecl {
name: "main".into(),
signature: Default::default(),
}
Expand Down Expand Up @@ -906,7 +906,7 @@ mod test {
let new_def = b
.add_op_with_parent(
root,
ops::Def {
ops::FuncDefn {
signature: def_sig,
name: "main".into(),
},
Expand Down
10 changes: 5 additions & 5 deletions src/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub use constant::{Const, ConstValue};
pub use controlflow::{BasicBlock, Case, Conditional, TailLoop, CFG};
pub use dataflow::{Call, CallIndirect, Input, LoadConstant, Output, DFG};
pub use leaf::LeafOp;
pub use module::{AliasDeclare, AliasDef, Declare, Def, Module};
pub use module::{AliasDecl, AliasDefn, FuncDecl, FuncDefn, Module};

#[enum_dispatch(OpTrait, OpName, ValidateOp)]
#[derive(Clone, Debug, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
Expand All @@ -35,10 +35,10 @@ pub use module::{AliasDeclare, AliasDef, Declare, Def, Module};
#[serde(tag = "op")]
pub enum OpType {
Module,
Def,
Declare,
AliasDeclare,
AliasDef,
FuncDefn,
FuncDecl,
AliasDecl,
AliasDefn,
Const,
Input,
Output,
Expand Down
8 changes: 4 additions & 4 deletions src/ops/handle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,16 @@ pub struct ModuleRootID(Node);
pub struct ModuleID(Node);

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, DerFrom, Debug)]
/// Handle to a [def](crate::ops::OpType::Def)
/// or [declare](crate::ops::OpType::Declare) node.
/// Handle to a [def](crate::ops::OpType::FuncDefn)
/// or [declare](crate::ops::OpType::FuncDecl) node.
///
/// The `DEF` const generic is used to indicate whether the function is
/// defined or just declared.
pub struct FuncID<const DEF: bool>(Node);

#[derive(Debug, Clone, PartialEq, Eq)]
/// Handle to an [AliasDef](crate::ops::OpType::AliasDef)
/// or [AliasDeclare](crate::ops::OpType::AliasDeclare) node.
/// Handle to an [AliasDefn](crate::ops::OpType::AliasDefn)
/// or [AliasDecl](crate::ops::OpType::AliasDecl) node.
///
/// The `DEF` const generic is used to indicate whether the function is
/// defined or just declared.
Expand Down
Loading

0 comments on commit e6abc02

Please sign in to comment.