Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
doug-q committed May 2, 2024
1 parent 9431230 commit 855f1bb
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 71 deletions.
1 change: 1 addition & 0 deletions hugr-py/src/hugr/serialization/tys.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ class TypeParam(RootModel):
# --------------- TypeArg ------------------
# ------------------------------------------


class TypeTypeArg(ConfiguredBaseModel):
tya: Literal["Type"] = "Type"
ty: "Type"
Expand Down
45 changes: 13 additions & 32 deletions hugr/src/extension/op_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -466,7 +466,7 @@ impl Extension {
#[cfg(test)]
mod test {
use proptest::prelude::*;
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use std::num::NonZeroU64;

use smol_str::SmolStr;
Expand All @@ -488,38 +488,19 @@ mod test {
const EXT_ID: ExtensionId = "MyExt";
}

impl Arbitrary for OpDef {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
use proptest::collection::vec;
// /// The unique Extension owning this OpDef (of which this OpDef is a member)
// extension: ExtensionId,
// /// Unique identifier of the operation. Used to look up OpDefs in the registry
// /// when deserializing nodes (which store only the name).
// name: SmolStr,
// /// Human readable description of the operation.
// description: String,
// /// Miscellaneous data associated with the operation.
// #[serde(default, skip_serializing_if = "HashMap::is_empty")]
// misc: HashMap<String, serde_yaml::Value>,

// #[serde(flatten)]
// signature_func: SignatureFunc,
// // Some operations cannot lower themselves and tools that do not understand them
// // can only treat them as opaque/black-box ops.
// #[serde(flatten)]
// lower_funcs: Vec<LowerFunc>,

// /// Operations can optionally implement [`ConstFold`] to implement constant folding.
// #[serde(skip)]
// constant_folder: Option<Box<dyn ConstFold>>,
let signature_func: BoxedStrategy<SignatureFunc> = todo!();
(signature_func, vec(todo!(), 0..2)).prop_flat_map(|(signature_func, lower_funcs)|
(any::<ExtensionId>(), crate::hugr::test::proptest::ArbStringKind::non_empty(), any::<HashMap<String,serde_yaml::Value>>).prop_map(|(extension,name, description, misc)| OpDef { extension, name, description, misc, signature_func, lower_funcs, constant_folder: None} ))
}
// impl Arbitrary for OpDef {
// type Parameters = ();
// type Strategy = BoxedStrategy<Self>;
// fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
// use proptest::collection::{vec, hash_map};
// use crate::hugr::test::proptest::{any_string,any_serde_yaml_value};
// let signature_func: BoxedStrategy<SignatureFunc> = todo!();
// let lower_funcs: BoxedStrategy<LowerFunc> = todo!();
// let misc = hash_map(any_string(), any_serde_yaml_value(), 0..3);
// (any::<ExtensionId>(), any_string(), any_string(), misc, signature_func, vec(lower_funcs, 0..2)).prop_map(|(extension, name, description, misc, signature_func, lower_funcs)| OpDef { extension, name, description, misc, signature_func, lower_funcs, constant_folder: None} )
// }

}
// }

#[test]
fn op_def_with_type_scheme() -> Result<(), Box<dyn std::error::Error>> {
Expand Down
38 changes: 28 additions & 10 deletions hugr/src/hugr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,42 +352,41 @@ pub(crate) mod test {
pub(crate) mod proptest {
use lazy_static::lazy_static;
use proptest::strategy::Strategy;


use proptest::prelude::*;

use proptest::prelude::*;
use smol_str::SmolStr;

pub enum ArbStringKind {
NonEmpty,
Ident,
}

lazy_static! {
pub static ref ANY_IDENT_STRING_STRAT: SBoxedStrategy<String> = {
static ref ANY_IDENT_STRING: SBoxedStrategy<String> = {
use proptest::string::string_regex;
prop_oneof![
string_regex(crate::hugr::ident::PATH_COMPONENT_NICE_REGEX_STR).unwrap(),
string_regex(crate::hugr::ident::PATH_COMPONENT_REGEX_STR).unwrap(),
].sboxed()
};

pub static ref ANY_NONEMPTY_STRING_STRAT: SBoxedStrategy<String> = {
static ref ANY_NONEMPTY_STRING: SBoxedStrategy<String> = {
use proptest::string::string_regex;
prop_oneof![
string_regex(r".+").unwrap(),
string_regex(r"[[:alpha:]]+").unwrap(),
].sboxed()
};

pub static ref ANY_STRING_STRAT: SBoxedStrategy<String> = {
static ref ANY_STRING: SBoxedStrategy<String> = {
use proptest::string::string_regex;
prop_oneof![
string_regex(r"[[:alpha:]]*").unwrap(),
string_regex(r".*").unwrap(),
].sboxed()
};

pub static ref ANY_SERDE_YAML_VALUE: SBoxedStrategy<serde_yaml::Value> = {
static ref ANY_SERDE_YAML_VALUE: SBoxedStrategy<serde_yaml::Value> = {
use serde_yaml::value::{Tag, TaggedValue, Value};
proptest::collection::vec;
prop_oneof![
Expand All @@ -397,19 +396,38 @@ pub(crate) mod test {
any::<i64>().prop_map_into(),
any::<f64>().prop_map_into(),
Just(Value::Number(3.into())),
ANY_STRING_STRAT.clone().prop_map_into(),
ANY_STRING.clone().prop_map_into(),
].prop_recursive(
3, // No more than 3 branch levels deep
32, // Target around 32 total elements
3, // Each collection is up to 3 elements long
|element| prop_oneof![
(ANY_STRING_STRAT.clone().prop_map(serde_yaml::value::Tag::new), element.clone()).prop_map(|(tag, value)| Value::TaggedValue { tag, value }),
(ANY_STRING.clone().prop_map(Tag::new), element.clone()).prop_map(|(tag, value)| Value::Tagged(Box::new(TaggedValue { tag, value }))),
proptest::collection::vec(element.clone(), 0..3).prop_map_into(),
]

).sboxed()
};
}

pub fn any_nonempty_string() -> impl Strategy<Value = String> + Sync {
ANY_NONEMPTY_STRING.clone()
}

pub fn any_nonempty_smolstr() -> impl Strategy<Value = SmolStr> + Sync {
ANY_NONEMPTY_STRING.clone().prop_map_into()
}

pub fn any_ident_string() -> impl Strategy<Value = String> + Sync {
ANY_IDENT_STRING.clone()
}

pub fn any_string() -> impl Strategy<Value = String> + Sync {
ANY_STRING.clone()
}

pub fn any_serde_yaml_value() -> impl Strategy<Value = serde_yaml::Value> {
ANY_SERDE_YAML_VALUE.clone()
}
}

#[test]
Expand Down
17 changes: 12 additions & 5 deletions hugr/src/hugr/ident.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ pub static PATH_COMPONENT_REGEX_STR: &str = r"[\w--\d]\w*";
#[cfg(test)]
pub static PATH_COMPONENT_NICE_REGEX_STR: &str = r"[[:alpha:]][[[:alpha:]]0-9]*";
lazy_static! {
pub static ref PATH_REGEX: Regex = Regex::new(&format!(r"^{0}(\.{0})*$", PATH_COMPONENT_REGEX_STR)).unwrap();
pub static ref PATH_REGEX: Regex =
Regex::new(&format!(r"^{0}(\.{0})*$", PATH_COMPONENT_REGEX_STR)).unwrap();
}

#[derive(
Expand Down Expand Up @@ -102,13 +103,19 @@ mod test {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
use crate::hugr::test::proptest;
use crate::hugr::test::proptest::any_ident_string;
use proptest::collection::vec;
// we shrink to more readable (i.e. :alpha:) names
vec(proptest::ANY_IDENT_STRING_STRAT, 1..2)
vec(any_ident_string(), 1..2)
.prop_map(|vs| {
IdentList::new(itertools::intersperse(vs.into_iter().map(Into::<String>::into), ".".into()).collect::<String>())
.unwrap()
IdentList::new(
itertools::intersperse(
vs.into_iter().map(Into::<String>::into),
".".into(),
)
.collect::<String>(),
)
.unwrap()
})
.boxed()
}
Expand Down
1 change: 0 additions & 1 deletion hugr/src/hugr/serialize/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ use portgraph::{
};
use proptest::prelude::*;


const NAT: Type = crate::extension::prelude::USIZE_T;
const QB: Type = crate::extension::prelude::QB_T;

Expand Down
14 changes: 7 additions & 7 deletions hugr/src/ops/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -420,14 +420,14 @@ mod test {
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
use proptest::collection::vec;
let leaf_strat =
let leaf_strat = prop_oneof![
any::<ExtensionValue>().prop_map(|e| Self::Extension { e }),
prop_oneof![
any::<ExtensionValue>().prop_map(|e| Self::Extension { e }),
prop_oneof![
// TODO we need an example of each legal root, in particular FuncDe{fn,cl}
Just(crate::builder::test::simple_dfg_hugr()),
].prop_map(|x| Value::function(x).unwrap())
];
// TODO we need an example of each legal root, in particular FuncDe{fn,cl}
Just(crate::builder::test::simple_dfg_hugr()),
]
.prop_map(|x| Value::function(x).unwrap())
];
leaf_strat
.prop_recursive(
3, // No more than 3 branch levels deep
Expand Down
25 changes: 19 additions & 6 deletions hugr/src/ops/custom.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Extensible operations.
use smol_str::SmolStr;
use std::sync::Arc;
use thiserror::Error;
use smol_str::SmolStr;

use crate::extension::{ConstFoldResult, ExtensionId, ExtensionRegistry, OpDef, SignatureError};
use crate::hugr::hugrmut::sealed::HugrMutInternals;
Expand All @@ -24,7 +24,6 @@ use super::{NamedOp, OpName, OpNameRef, OpTrait, OpType};
/// [`OpaqueOp`]: crate::ops::custom::OpaqueOp
/// [`ExtensionOp`]: crate::ops::custom::ExtensionOp
#[derive(Clone, Debug, Eq, serde::Serialize, serde::Deserialize)]
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
#[serde(into = "OpaqueOp", from = "OpaqueOp")]
pub enum CustomOp {
/// When we've found (loaded) the [Extension] definition and identified the [OpDef]
Expand Down Expand Up @@ -167,7 +166,7 @@ impl From<ExtensionOp> for CustomOp {
///
/// [Extension]: crate::Extension
#[derive(Clone, Debug)]
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
// #[cfg_attr(test, derive(proptest_derive::Arbitrary))]
pub struct ExtensionOp {
def: Arc<OpDef>,
args: Vec<TypeArg>,
Expand Down Expand Up @@ -271,9 +270,15 @@ impl DataflowOpTrait for ExtensionOp {
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
pub struct OpaqueOp {
extension: ExtensionId,
#[cfg_attr(test, proptest(strategy = "crate::hugr::test::proptest::ANY_NONEMPTY_STRING_STRAT.prop_map_into()"))]
#[cfg_attr(
test,
proptest(strategy = "crate::hugr::test::proptest::any_nonempty_smolstr()")
)]
op_name: SmolStr,
#[cfg_attr(test, proptest(strategy = "crate::hugr::test::proptest::ArbStringKind::non_empty()"))]
#[cfg_attr(
test,
proptest(strategy = "crate::hugr::test::proptest::any_nonempty_string()")
)]
description: String, // cache in advance so description() can return &str
args: Vec<TypeArg>,
signature: FunctionType,
Expand Down Expand Up @@ -420,10 +425,18 @@ pub enum CustomOpError {

#[cfg(test)]
mod test {

use crate::extension::prelude::{QB_T, USIZE_T};

use super::*;
use proptest::prelude::*;

impl Arbitrary for CustomOp {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
any::<OpaqueOp>().prop_map_into().boxed()
}
}

#[test]
fn new_opaque_op() {
Expand Down
20 changes: 14 additions & 6 deletions hugr/src/ops/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ impl OpTrait for Module {
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
pub struct FuncDefn {
/// Name of function
#[cfg_attr(test, proptest(strategy = "crate::hugr::test::proptest::ANY_NONEMPTY_STRING_STRAT.prop_map_into()"))]
#[cfg_attr(
test,
proptest(strategy = "crate::hugr::test::proptest::any_nonempty_string()")
)]
pub name: String,
/// Signature of the function
pub signature: PolyFuncType,
Expand Down Expand Up @@ -73,7 +76,10 @@ impl OpTrait for FuncDefn {
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
pub struct FuncDecl {
/// Name of function
#[cfg_attr(test, proptest(strategy = "crate::hugr::test::proptest::ArbStringKind::non_empty()"))]
#[cfg_attr(
test,
proptest(strategy = "crate::hugr::test::proptest::any_nonempty_string()")
)]
pub name: String,
/// Signature of the function
pub signature: PolyFuncType,
Expand Down Expand Up @@ -103,7 +109,10 @@ impl OpTrait for FuncDecl {
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
pub struct AliasDefn {
/// Alias name
#[cfg_attr(test, proptest(strategy = "crate::hugr::test::proptest::ArbStringKind::non_empty().prop_map_into()"))]
#[cfg_attr(
test,
proptest(strategy = "crate::hugr::test::proptest::any_nonempty_smolstr()")
)]
pub name: SmolStr,
/// Aliased type
pub definition: Type,
Expand Down Expand Up @@ -169,10 +178,9 @@ mod test {
type Parameters = ();
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
use crate::hugr::test::proptest::ArbStringKind;
let name = ArbStringKind::non_empty();
use crate::hugr::test::proptest::any_ident_string;
let bound = any::<TypeBound>();
(name, bound)
(any_ident_string(), bound)
.prop_map(|(name, bound)| Self::new(name, bound))
.boxed()
}
Expand Down
5 changes: 2 additions & 3 deletions hugr/src/types/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,17 +157,16 @@ mod test {
type Parameters = crate::types::test::TypeDepth;
type Strategy = BoxedStrategy<Self>;
fn arbitrary_with(depth: Self::Parameters) -> Self::Strategy {
use crate::hugr::test::proptest::ArbStringKind;
use crate::hugr::test::proptest::any_nonempty_string;
use proptest::collection::vec;
let extension = any::<ExtensionId>();
let id = ArbStringKind::non_empty().prop_map(Into::<TypeName>::into);
let args = if depth.leaf() {
Just(vec![]).boxed()
} else {
vec(any_with::<TypeArg>(depth.descend()), 0..3).boxed()
};
let bound = any::<TypeBound>();
(id, args, extension, bound)
(any_nonempty_string(), args, extension, bound)
.prop_map(|(id, args, extension, bound)| Self::new(id, args, extension, bound))
.boxed()
}
Expand Down
3 changes: 2 additions & 1 deletion hugr/src/types/type_param.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,8 @@ mod test {
.prop_map(|arg| Self::Opaque { arg })
.boxed(),
any_with::<TypeArgVariable>(depth)
.prop_map(|v| Self::Variable { v }).boxed()
.prop_map(|v| Self::Variable { v })
.boxed(),
]);
if !depth.leaf() {
strat = strat.or(vec(any_with::<Self>(depth.descend()), 0..3)
Expand Down

0 comments on commit 855f1bb

Please sign in to comment.