Skip to content
35 changes: 16 additions & 19 deletions examples/adder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
//! logically-and values in the hypergraph.
//! - An example of an n-bit ripple carry adder
//!
use open_hypergraphs::lax::var;
use open_hypergraphs::lax::*;
use open_hypergraphs::lax::{var, *};

// There is a single generating object in the category: the bit.
#[derive(PartialEq, Clone, Debug)]
Expand All @@ -27,38 +26,36 @@ pub enum Gate {
}

impl var::HasVar for Gate {
fn var() -> Gate {
Gate::Copy
fn var() -> Self {
Self::Copy
}
}

impl var::HasBitXor<Bit, Gate> for Gate {
fn bitxor(_: Bit, _: Bit) -> (Bit, Gate) {
(Bit, Gate::Xor)
impl var::HasBitXor<Bit, Self> for Gate {
fn bitxor(_: Bit, _: Bit) -> (Bit, Self) {
(Bit, Self::Xor)
}
}

impl var::HasBitAnd<Bit, Gate> for Gate {
fn bitand(_: Bit, _: Bit) -> (Bit, Gate) {
(Bit, Gate::And)
impl var::HasBitAnd<Bit, Self> for Gate {
fn bitand(_: Bit, _: Bit) -> (Bit, Self) {
(Bit, Self::And)
}
}

impl var::HasBitOr<Bit, Gate> for Gate {
fn bitor(_: Bit, _: Bit) -> (Bit, Gate) {
(Bit, Gate::Or)
impl var::HasBitOr<Bit, Self> for Gate {
fn bitor(_: Bit, _: Bit) -> (Bit, Self) {
(Bit, Self::Or)
}
}

impl var::HasNot<Bit, Gate> for Gate {
fn not(_: Bit) -> (Bit, Gate) {
(Bit, Gate::Not)
use std::{cell::RefCell, rc::Rc};
impl var::HasNot<Bit, Self> for Gate {
fn not(_: Bit) -> (Bit, Self) {
(Bit, Self::Not)
}
}

use std::cell::RefCell;
use std::rc::Rc;

type Term = OpenHypergraph<Bit, Gate>;
type Builder = Rc<RefCell<Term>>;
type Var = var::Var<Bit, Gate>;
Expand Down
17 changes: 10 additions & 7 deletions examples/polycirc.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
use open_hypergraphs::eval::eval;
use open_hypergraphs::prelude::*;
use open_hypergraphs::{eval::eval, prelude::*};

use core::ops::{Add, Mul};
use num_traits::{One, Zero};
use std::iter::{Product, Sum};
use {
core::ops::{Add, Mul},
num_traits::{One, Zero},
std::iter::{Product, Sum},
};

////////////////////////////////////////////////////////////////////////////////
// Define the theory of polynomial circuits
Expand Down Expand Up @@ -118,8 +119,10 @@ fn square() -> Option<Term> {
// Test programs (imperative interface)

mod imperative {
use super::{Arr, Obj};
use open_hypergraphs::lax::*;
use {
super::{Arr, Obj},
open_hypergraphs::lax::*,
};
type Term = open_hypergraphs::lax::OpenHypergraph<Obj, Arr>;

/// Creates a non-typed-annotated binary operation, and unpacks its variables.
Expand Down
1 change: 1 addition & 0 deletions rustfmt.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
imports_granularity = "One"
7 changes: 4 additions & 3 deletions src/array/traits.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//! The operations which an array type must support to implement open hypergraphs
use core::fmt::Debug;
use core::ops::{Add, Sub};
use core::ops::{Bound, Range, RangeBounds};
use core::{
fmt::Debug,
ops::{Add, Bound, Range, RangeBounds, Sub},
};

use num_traits::{One, Zero};

Expand Down
6 changes: 4 additions & 2 deletions src/array/vec/connected_components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,10 @@ pub fn to_dense(sparse: &[usize]) -> (Vec<usize>, usize) {

#[cfg(test)]
mod test {
use proptest::prelude::{Just, Strategy};
use proptest::{prop_assert_eq, proptest};
use proptest::{
prelude::{Just, Strategy},
prop_assert_eq, proptest,
};

use super::{connected_components, to_dense};

Expand Down
3 changes: 1 addition & 2 deletions src/array/vec/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
mod connected_components;
mod vec_array;

pub use connected_components::*;
pub use vec_array::*;
pub use {connected_components::*, vec_array::*};
78 changes: 40 additions & 38 deletions src/array/vec/vec_array.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
//! [`Vec<T>`]-backed arrays
use super::connected_components::connected_components;
use crate::array::*;
use core::ops::{Add, Deref, DerefMut, Index, RangeBounds, Sub};
use {
super::connected_components::connected_components,
crate::array::*,
core::ops::{Add, Deref, DerefMut, Index, RangeBounds, Sub},
};

/// Arrays backed by a [`Vec<T>`].
#[derive(PartialEq, Eq, Clone, Debug)]
Expand Down Expand Up @@ -48,7 +50,7 @@ impl<T> DerefMut for VecArray<T> {

impl<T: Clone + PartialEq> Array<VecKind, T> for VecArray<T> {
fn empty() -> Self {
VecArray(Vec::default())
Self(Vec::default())
}

fn len(&self) -> usize {
Expand All @@ -59,11 +61,11 @@ impl<T: Clone + PartialEq> Array<VecKind, T> for VecArray<T> {
let mut result: Vec<T> = Vec::with_capacity(self.len() + other.len());
result.extend_from_slice(self);
result.extend_from_slice(other);
VecArray(result)
Self(result)
}

fn fill(x: T, n: usize) -> Self {
VecArray(vec![x; n])
Self(vec![x; n])
}

fn get(&self, i: usize) -> T {
Expand All @@ -87,7 +89,7 @@ impl<T: Clone + PartialEq> Array<VecKind, T> for VecArray<T> {
}

fn gather(&self, idx: &[usize]) -> Self {
VecArray(idx.iter().map(|i| self.0[*i].clone()).collect())
Self(idx.iter().map(|i| self.0[*i].clone()).collect())
}

/// Scatter values over the specified indices `self[idx[i]] = v[i]`.
Expand All @@ -102,11 +104,11 @@ impl<T: Clone + PartialEq> Array<VecKind, T> for VecArray<T> {
/// let actual = v.scatter(idx.get_range(..), 3);
/// assert_eq!(actual, expected);
/// ```
fn scatter(&self, idx: &[usize], n: usize) -> VecArray<T> {
fn scatter(&self, idx: &[usize], n: usize) -> Self {
// If self is empty, we return the empty array because there can be no valid indices
if self.is_empty() {
assert!(idx.is_empty());
return VecArray(vec![]);
return Self(vec![]);
}

// Otherwise, we fill the result with an arbitrary value ...
Expand All @@ -116,11 +118,11 @@ impl<T: Clone + PartialEq> Array<VecKind, T> for VecArray<T> {
for (i, x) in self.iter().enumerate() {
y[idx[i]] = x.clone();
}
VecArray(y)
Self(y)
}

fn from_slice(slice: &[T]) -> Self {
VecArray(slice.into())
Self(slice.into())
}

fn scatter_assign_constant(&mut self, ixs: &VecArray<usize>, arg: T) {
Expand All @@ -136,20 +138,20 @@ impl<T: Clone + PartialEq> Array<VecKind, T> for VecArray<T> {
}
}

impl Add<&VecArray<usize>> for usize {
type Output = VecArray<usize>;
impl Add<&VecArray<Self>> for usize {
type Output = VecArray<Self>;

fn add(self, rhs: &VecArray<usize>) -> Self::Output {
fn add(self, rhs: &VecArray<Self>) -> Self::Output {
VecArray(rhs.iter().map(|x| x + self).collect())
}
}

impl<T: Clone + Add<Output = T>> Add<VecArray<T>> for VecArray<T> {
type Output = VecArray<T>;
impl<T: Clone + Add<Output = T>> Add for VecArray<T> {
type Output = Self;

fn add(self, rhs: VecArray<T>) -> VecArray<T> {
fn add(self, rhs: Self) -> Self {
assert_eq!(self.len(), rhs.len());
VecArray(
Self(
self.iter()
.zip(rhs.iter())
.map(|(x, y)| x.clone() + y.clone())
Expand All @@ -158,12 +160,12 @@ impl<T: Clone + Add<Output = T>> Add<VecArray<T>> for VecArray<T> {
}
}

impl<T: Clone + Sub<Output = T>> Sub<VecArray<T>> for VecArray<T> {
type Output = VecArray<T>;
impl<T: Clone + Sub<Output = T>> Sub for VecArray<T> {
type Output = Self;

fn sub(self, rhs: VecArray<T>) -> VecArray<T> {
fn sub(self, rhs: Self) -> Self {
assert_eq!(self.len(), rhs.len());
VecArray(
Self(
self.iter()
.zip(rhs.iter())
.map(|(x, y)| x.clone() - y.clone())
Expand Down Expand Up @@ -217,7 +219,7 @@ impl NaturalArray<VecKind> for VecArray<usize> {
q.push(x / d);
r.push(x % d);
}
(VecArray(q), VecArray(r))
(Self(q), Self(r))
}

fn mul_constant_add(&self, c: usize, x: &Self) -> Self {
Expand All @@ -226,7 +228,7 @@ impl NaturalArray<VecKind> for VecArray<usize> {
for (s, x) in self.iter().zip(x.iter()) {
r.push(s * c + x)
}
VecArray(r)
Self(r)
}

/// ```rust
Expand All @@ -244,7 +246,7 @@ impl NaturalArray<VecKind> for VecArray<usize> {
a += x;
}
v.push(a); // don't forget the total sum!
VecArray(v)
Self(v)
}

fn arange(start: &usize, stop: &usize) -> Self {
Expand All @@ -254,7 +256,7 @@ impl NaturalArray<VecKind> for VecArray<usize> {
for i in 0..n {
v.push(start + i);
}
VecArray(v)
Self(v)
}

/// ```rust
Expand All @@ -266,13 +268,13 @@ impl NaturalArray<VecKind> for VecArray<usize> {
/// let expected = VecArray::<usize>(vec![5, 6, 6, 8, 8, 8]);
/// assert_eq!(actual, expected);
/// ```
fn repeat(&self, x: &[usize]) -> VecArray<usize> {
fn repeat(&self, x: &[usize]) -> Self {
assert_eq!(self.len(), x.len());
let mut v: Vec<usize> = Vec::new();
let mut v: Vec<usize> = vec![];
for (k, xi) in self.iter().zip(x) {
v.extend(std::iter::repeat(xi).take(*k))
v.extend(std::iter::repeat_n(xi, *k))
}
VecArray(v)
Self(v)
}

fn connected_components(
Expand All @@ -281,28 +283,28 @@ impl NaturalArray<VecKind> for VecArray<usize> {
n: usize,
) -> (Self, <VecKind as ArrayKind>::I) {
let (cc_ix, c) = connected_components(sources, targets, n);
(VecArray(cc_ix), c)
(Self(cc_ix), c)
}

fn bincount(&self, size: usize) -> VecArray<usize> {
fn bincount(&self, size: usize) -> Self {
let mut counts = vec![0; size];
for &idx in self.iter() {
counts[idx] += 1;
}
VecArray(counts)
Self(counts)
}

fn zero(&self) -> VecArray<usize> {
fn zero(&self) -> Self {
let mut zero_indices = Vec::with_capacity(self.len());
for (i, &val) in self.iter().enumerate() {
if val == 0 {
zero_indices.push(i);
}
}
VecArray(zero_indices)
Self(zero_indices)
}

fn sparse_bincount(&self) -> (VecArray<usize>, VecArray<usize>) {
fn sparse_bincount(&self) -> (Self, Self) {
use std::collections::HashMap;

// Count occurrences using a HashMap
Expand All @@ -318,10 +320,10 @@ impl NaturalArray<VecKind> for VecArray<usize> {
// Gather counts in the same order as unique indices
let counts: Vec<_> = unique_indices.iter().map(|&idx| counts_map[&idx]).collect();

(VecArray(unique_indices), VecArray(counts))
(Self(unique_indices), Self(counts))
}

fn scatter_sub_assign(&mut self, ixs: &VecArray<usize>, rhs: &VecArray<usize>) {
fn scatter_sub_assign(&mut self, ixs: &Self, rhs: &Self) {
for i in 0..ixs.len() {
self[ixs[i]] -= rhs[i];
}
Expand Down
7 changes: 4 additions & 3 deletions src/category/spider.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::traits::*;
use crate::array::*;
use crate::finite_function::*;
use {
super::traits::*,
crate::{array::*, finite_function::*},
};

/// Categories with [hypergraph structure](https://ncatlab.org/nlab/show/hypergraph+category).
/// We call this `Spider` to avoid confusion with the [crate::hypergraph::Hypergraph] struct.
Expand Down
17 changes: 9 additions & 8 deletions src/eval.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
//! An array-backend-agnostic evaluator
//!
use crate::array::*;
use crate::finite_function::*;
use crate::indexed_coproduct::*;
use crate::layer::{converse, layer};
use crate::open_hypergraph::*;
use crate::semifinite::*;
use crate::{
array::*,
finite_function::*,
indexed_coproduct::*,
layer::{converse, layer},
open_hypergraph::*,
semifinite::*,
};

use num_traits::Zero;
use std::default::Default;
use {num_traits::Zero, std::default::Default};

// Given a "layering function" `f : N → K` which maps each operation `n ∈ N` into some layer `k ∈
// K`,
Expand Down
Loading