Skip to content

Commit

Permalink
restore non-proptest test cases for serialisation
Browse files Browse the repository at this point in the history
  • Loading branch information
doug-q committed May 16, 2024
1 parent ec79951 commit 86e5e11
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 58 deletions.
90 changes: 85 additions & 5 deletions hugr/src/hugr/serialize/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,27 @@ use crate::builder::{
test::closed_dfg_root_hugr, Container, DFGBuilder, Dataflow, DataflowHugr,
DataflowSubContainer, HugrBuilder, ModuleBuilder,
};
use crate::extension::prelude::{BOOL_T, USIZE_T};
use crate::extension::prelude::{BOOL_T, PRELUDE_ID, QB_T, USIZE_T};
use crate::extension::simple_op::MakeRegisteredOp;
use crate::extension::{EMPTY_REG, PRELUDE_REGISTRY};
use crate::hugr::hugrmut::sealed::HugrMutInternals;
use crate::ops::custom::{ExtensionOp, OpaqueOp};
use crate::ops::{dataflow::IOTrait, Input, Module, Noop, Output, DFG};
use crate::ops::{self, dataflow::IOTrait, Input, Module, Noop, Output, Value, DFG};
use crate::std_extensions::arithmetic::float_ops::FLOAT_OPS_REGISTRY;
use crate::std_extensions::arithmetic::float_types::{ConstF64, FLOAT64_TYPE};

use crate::std_extensions::arithmetic::int_types::{int_custom_type, ConstInt, INT_TYPES};
use crate::std_extensions::logic::NotOp;

use crate::types::{FunctionType, Type};
use crate::types::{
type_param::TypeParam, FunctionType, PolyFuncType, SumType, Type, TypeArg, TypeBound,
};
use crate::{type_row, OutgoingPort};

use itertools::Itertools;
use jsonschema::{Draft, JSONSchema};
use lazy_static::lazy_static;
use portgraph::LinkView;
use portgraph::{multiportgraph::MultiPortGraph, Hierarchy, LinkMut, PortMut, UnmanagedDenseMap};
use rstest::rstest;

const NAT: Type = crate::extension::prelude::USIZE_T;
const QB: Type = crate::extension::prelude::QB_T;
Expand Down Expand Up @@ -376,6 +379,83 @@ fn serialize_types_roundtrip() {
assert_eq!(ser_roundtrip(&t), t);
}

#[rstest]
#[case(BOOL_T)]
#[case(USIZE_T)]
#[case(INT_TYPES[2].clone())]
#[case(Type::new_alias(crate::ops::AliasDecl::new("t", TypeBound::Any)))]
#[case(Type::new_var_use(2, TypeBound::Copyable))]
#[case(Type::new_tuple(type_row![BOOL_T,QB_T]))]
#[case(Type::new_sum([type_row![BOOL_T,QB_T], type_row![Type::new_unit_sum(4)]]))]
#[case(Type::new_function(FunctionType::new_endo(type_row![QB_T,BOOL_T,USIZE_T])))]
fn roundtrip_type(#[case] typ: Type) {
check_testing_roundtrip(typ);
}

#[rstest]
#[case(SumType::new_unary(2))]
#[case(SumType::new([type_row![USIZE_T, QB_T], type_row![]]))]
fn roundtrip_sumtype(#[case] sum_type: SumType) {
check_testing_roundtrip(sum_type);
}

#[rstest]
#[case(Value::unit())]
#[case(Value::true_val())]
#[case(Value::unit_sum(3,5).unwrap())]
#[case(Value::extension(ConstF64::new(-1.5)))]
#[case(Value::extension(ConstF64::new(0.0)))]
#[case(Value::extension(ConstF64::new(-0.0)))]
// These cases fail
// #[case(Value::extension(ConstF64::new(std::f64::NAN)))]
// #[case(Value::extension(ConstF64::new(std::f64::INFINITY)))]
// #[case(Value::extension(ConstF64::new(std::f64::NEG_INFINITY)))]
#[case(Value::extension(ConstF64::new(f64::MIN_POSITIVE)))]
#[case(Value::sum(1,[Value::extension(ConstInt::new_u(2,1).unwrap())], SumType::new([vec![], vec![INT_TYPES[2].clone()]])).unwrap())]
#[case(Value::tuple([Value::false_val(), Value::extension(ConstInt::new_s(2,1).unwrap())]))]
#[case(Value::function(crate::builder::test::simple_dfg_hugr()).unwrap())]
fn roundtrip_value(#[case] value: Value) {
check_testing_roundtrip(value);
}

fn polyfunctype1() -> PolyFuncType {
let mut extension_set = ExtensionSet::new();
extension_set.insert_type_var(1);
let function_type = FunctionType::new_endo(type_row![]).with_extension_delta(extension_set);
PolyFuncType::new([TypeParam::max_nat(), TypeParam::Extensions], function_type)
}

#[rstest]
#[case(FunctionType::new_endo(type_row![]).into())]
#[case(polyfunctype1())]
#[case(PolyFuncType::new([TypeParam::Opaque { ty: int_custom_type(TypeArg::BoundedNat { n: 1 }) }], FunctionType::new_endo(type_row![Type::new_var_use(0, TypeBound::Copyable)])))]
#[case(PolyFuncType::new([TypeBound::Eq.into()], FunctionType::new_endo(type_row![Type::new_var_use(0, TypeBound::Eq)])))]
#[case(PolyFuncType::new([TypeParam::List { param: Box::new(TypeBound::Any.into()) }], FunctionType::new_endo(type_row![])))]
#[case(PolyFuncType::new([TypeParam::Tuple { params: [TypeBound::Any.into(), TypeParam::bounded_nat(2.try_into().unwrap())].into() }], FunctionType::new_endo(type_row![])))]
fn roundtrip_polyfunctype(#[case] poly_func_type: PolyFuncType) {
check_testing_roundtrip(poly_func_type)
}

#[rstest]
#[case(ops::Module)]
#[case(ops::FuncDefn { name: "polyfunc1".into(), signature: polyfunctype1()})]
#[case(ops::FuncDecl { name: "polyfunc2".into(), signature: polyfunctype1()})]
#[case(ops::AliasDefn { name: "aliasdefn".into(), definition: Type::new_unit_sum(4)})]
#[case(ops::AliasDecl { name: "aliasdecl".into(), bound: TypeBound::Any})]
#[case(ops::Const::new(Value::false_val()))]
#[case(ops::Const::new(Value::function(crate::builder::test::simple_dfg_hugr()).unwrap()))]
#[case(ops::Input::new(type_row![Type::new_var_use(3,TypeBound::Eq)]))]
#[case(ops::Output::new(vec![Type::new_function(FunctionType::new_endo(type_row![]))]))]
#[case(ops::Call::try_new(polyfunctype1(), [TypeArg::BoundedNat{n: 1}, TypeArg::Extensions{ es: ExtensionSet::singleton(&PRELUDE_ID)} ], &EMPTY_REG).unwrap())]
#[case(ops::CallIndirect { signature : FunctionType::new_endo(type_row![BOOL_T]) })]
fn roundtrip_optype(#[case] optype: impl Into<OpType> + std::fmt::Debug) {
check_testing_roundtrip(NodeSer {
parent: portgraph::NodeIndex::new(0).into(),
input_extensions: None,
op: optype.into(),
});
}

mod proptest {
use super::super::NodeSer;
use super::check_testing_roundtrip;
Expand Down
10 changes: 2 additions & 8 deletions hugr/src/ops/custom.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,15 +271,9 @@ impl DataflowOpTrait for ExtensionOp {
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
pub struct OpaqueOp {
extension: ExtensionId,
#[cfg_attr(
test,
proptest(strategy = "crate::proptest::any_nonempty_smolstr()")
)]
#[cfg_attr(test, proptest(strategy = "crate::proptest::any_nonempty_smolstr()"))]
op_name: SmolStr,
#[cfg_attr(
test,
proptest(strategy = "crate::proptest::any_nonempty_string()")
)]
#[cfg_attr(test, proptest(strategy = "crate::proptest::any_nonempty_string()"))]
description: String, // cache in advance so description() can return &str
args: Vec<TypeArg>,
signature: FunctionType,
Expand Down
20 changes: 4 additions & 16 deletions hugr/src/ops/module.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,7 @@ impl OpTrait for Module {
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
pub struct FuncDefn {
/// Name of function
#[cfg_attr(
test,
proptest(strategy = "crate::proptest::any_nonempty_string()")
)]
#[cfg_attr(test, proptest(strategy = "crate::proptest::any_nonempty_string()"))]
pub name: String,
/// Signature of the function
pub signature: PolyFuncType,
Expand Down Expand Up @@ -76,10 +73,7 @@ impl OpTrait for FuncDefn {
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
pub struct FuncDecl {
/// Name of function
#[cfg_attr(
test,
proptest(strategy = "crate::proptest::any_nonempty_string()")
)]
#[cfg_attr(test, proptest(strategy = "crate::proptest::any_nonempty_string()"))]
pub name: String,
/// Signature of the function
pub signature: PolyFuncType,
Expand Down Expand Up @@ -109,10 +103,7 @@ impl OpTrait for FuncDecl {
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
pub struct AliasDefn {
/// Alias name
#[cfg_attr(
test,
proptest(strategy = "crate::proptest::any_nonempty_smolstr()")
)]
#[cfg_attr(test, proptest(strategy = "crate::proptest::any_nonempty_smolstr()"))]
pub name: SmolStr,
/// Aliased type
pub definition: Type,
Expand All @@ -136,10 +127,7 @@ impl OpTrait for AliasDefn {
#[cfg_attr(test, derive(proptest_derive::Arbitrary))]
pub struct AliasDecl {
/// Alias name
#[cfg_attr(
test,
proptest(strategy = "crate::proptest::any_nonempty_smolstr()")
)]
#[cfg_attr(test, proptest(strategy = "crate::proptest::any_nonempty_smolstr()"))]
pub name: SmolStr,
/// Flag to signify type is classical
pub bound: TypeBound,
Expand Down
18 changes: 5 additions & 13 deletions hugr/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,7 @@ pub enum TypeEnum {
// or some static version of this?
#[allow(missing_docs)]
Extension(
#[cfg_attr(
test,
proptest(strategy = "any_with::<CustomType>(params.into())")
)]
CustomType,
#[cfg_attr(test, proptest(strategy = "any_with::<CustomType>(params.into())"))] CustomType,
),
#[allow(missing_docs)]
#[display(fmt = "Alias({})", "_0.name()")]
Expand All @@ -232,13 +228,7 @@ pub enum TypeEnum {
Variable(usize, TypeBound),
#[allow(missing_docs)]
#[display(fmt = "{}", "_0")]
Sum(
#[cfg_attr(
test,
proptest(strategy = "any_with::<SumType>(params)")
)]
SumType,
),
Sum(#[cfg_attr(test, proptest(strategy = "any_with::<SumType>(params)"))] SumType),
}
impl TypeEnum {
/// The smallest type bound that covers the whole type.
Expand Down Expand Up @@ -521,7 +511,9 @@ pub(crate) mod test {
if depth.leaf() {
any::<u8>().prop_map(Self::new_unary).boxed()
} else {
vec(any_with::<TypeRow>(depth), 0..3).prop_map(SumType::new).boxed()
vec(any_with::<TypeRow>(depth), 0..3)
.prop_map(SumType::new)
.boxed()
}
}
}
Expand Down
10 changes: 2 additions & 8 deletions hugr/src/types/poly_func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,10 @@ pub struct PolyFuncType {
/// The declared type parameters, i.e., these must be instantiated with
/// the same number of [TypeArg]s before the function can be called. This
/// defines the indices used by variables inside the body.
#[cfg_attr(
test,
proptest(strategy = "vec(any_with::<TypeParam>(params), 0..3)")
)]
#[cfg_attr(test, proptest(strategy = "vec(any_with::<TypeParam>(params), 0..3)"))]
params: Vec<TypeParam>,
/// Template for the function. May contain variables up to length of [Self::params]
#[cfg_attr(
test,
proptest(strategy = "any_with::<FunctionType>(params)")
)]
#[cfg_attr(test, proptest(strategy = "any_with::<FunctionType>(params)"))]
body: FunctionType,
}

Expand Down
10 changes: 2 additions & 8 deletions hugr/src/types/signature.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,10 @@ use {crate::proptest::RecursionDepth, ::proptest::prelude::*};
/// [Graph]: crate::ops::constant::Value::Function
pub struct FunctionType {
/// Value inputs of the function.
#[cfg_attr(
test,
proptest(strategy = "any_with::<TypeRow>(params)")
)]
#[cfg_attr(test, proptest(strategy = "any_with::<TypeRow>(params)"))]
pub input: TypeRow,
/// Value outputs of the function.
#[cfg_attr(
test,
proptest(strategy = "any_with::<TypeRow>(params)")
)]
#[cfg_attr(test, proptest(strategy = "any_with::<TypeRow>(params)"))]
pub output: TypeRow,
/// The extension requirements which are added by the operation
pub extension_reqs: ExtensionSet,
Expand Down

0 comments on commit 86e5e11

Please sign in to comment.