diff --git a/ir/src/env.rs b/ir/src/env.rs index c8ff82b..340ab23 100644 --- a/ir/src/env.rs +++ b/ir/src/env.rs @@ -5,10 +5,7 @@ use imctk_ids::{id_vec::IdVec, Id, Id32}; use imctk_transparent::{NewtypeCast, SubtypeCast}; use imctk_util::give_take::Take; -use crate::{ - index::{DefsIndex, UsesIndex}, - var::VarOrLit, -}; +use crate::index::{DefsIndex, UsesIndex}; use super::{ index::{DynamicIndex, StructuralHashIndex}, diff --git a/ir/src/env/node_builders.rs b/ir/src/env/node_builders.rs index bde358e..f78a3c7 100644 --- a/ir/src/env/node_builders.rs +++ b/ir/src/env/node_builders.rs @@ -236,8 +236,8 @@ impl RawEnvNodes { .find_term(&self.0.nodes, &term) { if def_mode.is_when_acyclic() { - let output_var = - ::process_var_or_lit(output, |var| var, |lit| lit.var()); + let output_var = output.into().var(); + let encoded_var_repr = &self.0.var_defs.var_defs[output_var]; let old_level_bound = encoded_var_repr.level_bound(); @@ -257,7 +257,7 @@ impl RawEnvNodes { } let (new_var, _) = self.0.var_defs.var_defs.push(EncodedVarDef::default()); - let output = ::build_var_or_lit(new_var, |var| var, |var| var.as_lit()); + let output = T::Output::from(new_var); let (node_id, _) = self.insert_unique_irreducible_node(def_mode, TermNode { output, term }); @@ -483,12 +483,16 @@ impl NodeBuilder for Env { let pol = term.apply_var_map(|var| self.var_defs.update_lit_repr(var.as_lit())); if let Some(output) = term.reduce(self) { - return output ^ pol; + return T::Output::try_from(output.into() ^ pol).unwrap(); } - self.raw_nodes() - .insert_irreducible_term(DefMode::WhenMissing, term) - ^ pol + T::Output::try_from( + self.raw_nodes() + .insert_irreducible_term(DefMode::WhenMissing, term) + .into() + ^ pol, + ) + .unwrap() } fn node(&mut self, mut node: T) { @@ -571,13 +575,17 @@ impl NodeBuilder for DefBuilder { let pol = term.apply_var_map(|var| self.0.var_defs.update_lit_repr(var.as_lit())); if let Some(output) = term.reduce(self) { - return output ^ pol; + return T::Output::try_from(output.into() ^ pol).unwrap(); } - self.0 - .raw_nodes() - .insert_irreducible_term(DefMode::WhenAcyclic, term) - ^ pol + T::Output::try_from( + self.0 + .raw_nodes() + .insert_irreducible_term(DefMode::WhenAcyclic, term) + .into() + ^ pol, + ) + .unwrap() } fn node(&mut self, mut node: T) { diff --git a/ir/src/node/builder.rs b/ir/src/node/builder.rs index 7450166..274734a 100644 --- a/ir/src/node/builder.rs +++ b/ir/src/node/builder.rs @@ -1,6 +1,6 @@ //! Generic interface for adding equivalences, nodes and terms. -use crate::var::{Lit, VarOrLit}; +use crate::var::Lit; use imctk_util::give_take::{give, Take}; use super::generic::{DynNode, DynTerm, Node, Term}; @@ -14,7 +14,7 @@ pub trait NodeBuilder: NodeBuilderDyn { /// variable or literal. fn term(&mut self, term: T) -> T::Output { give!(term: DynTerm = term); - ::build_var_or_lit(self.dyn_term(term), |lit| lit.var(), |lit| lit) + self.dyn_term(term).try_into().unwrap() } /// Ensure the presence of the given node. fn node(&mut self, node: T) { @@ -62,7 +62,7 @@ impl NodeBuilder for DynNodeBuilder { let lit = self.dyn_term(term); - ::build_var_or_lit(lit, |lit| lit.var(), |lit| lit) + T::Output::try_from(lit).unwrap() } fn node(&mut self, node: T) { diff --git a/ir/src/node/collections/buf.rs b/ir/src/node/collections/buf.rs index 012bfce..30ea4f4 100644 --- a/ir/src/node/collections/buf.rs +++ b/ir/src/node/collections/buf.rs @@ -14,7 +14,7 @@ use crate::{ vtables::{DynNodeType, DynTermType, GenericNodeType, GenericTermType}, NodeId, }, - var::{Lit, Var, VarOrLit}, + var::{Lit, Var}, }; #[derive(Clone, Copy, Debug)] @@ -120,7 +120,7 @@ impl NodeBuilder for NodeBuf { self.nodes.insert(TermWrapper { term }).0, )); - ::build_var_or_lit(lit, |lit| lit.var(), |lit| lit) + T::Output::try_from(lit).unwrap() } fn node(&mut self, node: T) { diff --git a/ir/src/node/fine/circuit.rs b/ir/src/node/fine/circuit.rs index db401d0..cc13208 100644 --- a/ir/src/node/fine/circuit.rs +++ b/ir/src/node/fine/circuit.rs @@ -129,10 +129,7 @@ impl Term for Xor { self.inputs.into_iter() } - fn apply_var_map( - &mut self, - mut var_map: impl FnMut(Var) -> Lit, - ) -> ::Pol { + fn apply_var_map(&mut self, mut var_map: impl FnMut(Var) -> Lit) -> Pol { let mut composed_pol = Pol::Pos; self.inputs = self.inputs.map(|var| { let mapped = var_map(var); diff --git a/ir/src/node/generic.rs b/ir/src/node/generic.rs index e0e476c..cb885d7 100644 --- a/ir/src/node/generic.rs +++ b/ir/src/node/generic.rs @@ -10,7 +10,7 @@ use zwohash::ZwoHasher; use crate::{ env::Env, - var::{Lit, Pol, Var, VarOrLit}, + var::{Lit, Pol, Var}, }; use super::{ @@ -298,7 +298,15 @@ impl DynNode { /// Everything that is object-safe is part of the [`TermDyn`] supertrait. pub trait Term: Debug + Clone + Eq + Hash + TermDyn + 'static { /// Whether the output can be represented as a variable or can require a literal. - type Output: VarOrLit + 'static; + type Output: Into + + From + + TryFrom + + Copy + + Ord + + Hash + + Debug + + Default + + 'static; /// A short name identifying the operation. const NAME: &'static str; @@ -319,8 +327,7 @@ pub trait Term: Debug + Clone + Eq + Hash + TermDyn + 'static { /// Rewrites all variables in the term using a given mapping. #[must_use] - fn apply_var_map(&mut self, var_map: impl FnMut(Var) -> Lit) - -> ::Pol; + fn apply_var_map(&mut self, var_map: impl FnMut(Var) -> Lit) -> Pol; /// Returns whether two [`Term`]s define the same value. /// @@ -383,9 +390,7 @@ pub fn default_reduce_node( }; if new_output != output { - builder.equiv( - [output, new_output].map(|x| x.process_var_or_lit(|var| var.as_lit(), |lit| lit)), - ); + builder.equiv([output, new_output].map(|x| x.into())); } true @@ -545,13 +550,11 @@ impl TermDynAuto for T { #[must_use] fn dyn_apply_var_map(&mut self, var_repr: &mut dyn FnMut(Var) -> Lit) -> Pol { - ::process_pol(self.apply_var_map(var_repr), || Pol::Pos, |pol| pol) + self.apply_var_map(var_repr) } fn dyn_reduce_into_buf(&mut self, buf: &mut NodeBuf) -> Option { - self.reduce(buf).map(|output| { - ::process_var_or_lit(output, |var| var.as_lit(), |lit| lit) - }) + self.reduce(buf).map(|output| output.into()) } fn dyn_add_to_buf_with_var_map( @@ -560,14 +563,8 @@ impl TermDynAuto for T { var_map: &mut dyn FnMut(Var) -> Lit, ) -> Lit { let mut clone = self.clone(); - let pol = <::Output>::process_pol( - clone.apply_var_map(var_map), - || Pol::Pos, - |pol| pol, - ); - buf.term(clone) - .process_var_or_lit(|var| var.as_lit(), |lit| lit) - ^ pol + let pol = clone.apply_var_map(var_map); + buf.term(clone).into() ^ pol } fn dyn_add_to_env_with_var_map( @@ -576,15 +573,9 @@ impl TermDynAuto for T { var_map: &mut dyn FnMut(Var) -> Lit, ) -> Lit { let mut clone = self.clone(); - let pol = <::Output>::process_pol( - clone.apply_var_map(var_map), - || Pol::Pos, - |pol| pol, - ); + let pol = clone.apply_var_map(var_map); - env.term(clone) - .process_var_or_lit(|var| var.as_lit(), |lit| lit) - ^ pol + env.term(clone).into() ^ pol } } @@ -733,26 +724,14 @@ impl Node for TermNode { } fn apply_var_map(&mut self, mut var_map: impl FnMut(Var) -> Lit) { - let mut new_output_lit = self - .output - .process_var_or_lit(|var| var.as_lit(), |lit| lit) - .lookup(&mut var_map); + let mut new_output_lit = self.output.into().lookup(&mut var_map); let term_pol = self.term.apply_var_map(var_map); - new_output_lit ^= term_pol.into(); + new_output_lit ^= term_pol; - let new_output = ::build_var_or_lit( - new_output_lit, - |lit| { - assert!( - lit.is_pos(), - "Term output of non-Boolean type mapped to negative literal" - ); - lit.var() - }, - |lit| lit, - ); + let new_output = T::Output::try_from(new_output_lit) + .expect("Term output of non-Boolean type mapped to negative literal"); self.output = new_output } @@ -772,20 +751,15 @@ impl NodeDyn for TermNode { } fn output_var(&self) -> Option { - Some(self.output.process_var_or_lit(|var| var, |lit| lit.var())) + Some(self.output.into().var()) } fn output_lit(&self) -> Option { - Some( - self.output - .process_var_or_lit(|var| var.as_lit(), |lit| lit), - ) + Some(self.output.into()) } fn max_var(&self) -> Var { - self.output - .process_var_or_lit(|var| var, |lit| lit.var()) - .max(self.term.max_var()) + self.output.into().var().max(self.term.max_var()) } fn dyn_term(&self) -> Option<&DynTerm> { @@ -811,10 +785,8 @@ mod tests { [].into_iter() } - fn apply_var_map( - &mut self, - _var_map: impl FnMut(Var) -> Lit, - ) -> ::Pol { + fn apply_var_map(&mut self, _var_map: impl FnMut(Var) -> Lit) -> Pol { + Pol::Pos } } @@ -832,13 +804,11 @@ mod tests { [self.0].into_iter() } - fn apply_var_map( - &mut self, - mut var_map: impl FnMut(Var) -> Lit, - ) -> ::Pol { + fn apply_var_map(&mut self, mut var_map: impl FnMut(Var) -> Lit) -> Pol { let var = var_map(self.0); assert!(var.is_pos()); self.0 = var.var(); + Pol::Pos } } diff --git a/ir/src/node/vtables.rs b/ir/src/node/vtables.rs index e8ad976..acfa648 100644 --- a/ir/src/node/vtables.rs +++ b/ir/src/node/vtables.rs @@ -6,10 +6,7 @@ use std::{ ops::Deref, }; -use crate::{ - var::{Lit, VarOrLit}, - wide_ptr::WidePtr, -}; +use crate::{var::Lit, wide_ptr::WidePtr}; use super::{ collections::nodes::Nodes, @@ -177,7 +174,7 @@ impl TermTypeVTable { |output: Lit, term_ptr: *mut u8, callback: &mut dyn FnMut(*mut u8)| { let term_ptr = term_ptr as *mut T; let mut term_node = ManuallyDrop::new(TermNode { - output: VarOrLit::build_var_or_lit(output, |lit| lit.var(), |lit| lit), + output: output.try_into().unwrap(), term: term_ptr.read(), }); callback(&mut term_node as *mut ManuallyDrop> as *mut u8); diff --git a/ir/src/var.rs b/ir/src/var.rs index f19e59c..4166839 100644 --- a/ir/src/var.rs +++ b/ir/src/var.rs @@ -1,4 +1,2 @@ //! Numeric identifiers for variables and Boolean literals pub use imctk_lit::{lit::Lit, pol::Pol, var::Var}; - -pub use imctk_lit::var_or_lit::VarOrLit; diff --git a/lit/src/lib.rs b/lit/src/lib.rs index ee100e7..cb78b9f 100644 --- a/lit/src/lib.rs +++ b/lit/src/lib.rs @@ -4,133 +4,3 @@ pub mod lit; pub mod pol; pub mod var; - -pub mod var_or_lit { - // FIXME get rid of this trait - - use std::{fmt::Debug, hash::Hash, ops}; - - use super::{lit::Lit, pol::Pol, var::Var}; - - mod seal_var_or_lit { - pub trait Sealed {} - - impl Sealed for super::Var {} - impl Sealed for super::Lit {} - } - - /// Unified handling of variables and literals. - /// - /// This trait is only implemented by [`Var`] and [`Lit`]. - #[deprecated] - pub trait VarOrLit: - Copy - + Debug - + Default - + Eq - + Ord - + Hash - + seal_var_or_lit::Sealed - + ops::BitXor - + ops::BitXorAssign - { - /// This is [`Pol`] for [`Lit`] and `()` for [`Var`]. - type Pol: Copy + Debug + Into; - - /// Returns a variable or a literal by selecting among closures for constructing either. - fn build_var_or_lit( - input: T, - build_var: impl FnOnce(T) -> Var, - build_lit: impl FnOnce(T) -> Lit, - ) -> Self; - - /// Produces a value from a variable or a literal by selecting among closure consuming either. - fn process_var_or_lit( - self, - from_var: impl FnOnce(Var) -> T, - from_lit: impl FnOnce(Lit) -> T, - ) -> T; - - /// Produces a value from a default value for variables or from a polarity for literals. - fn process_pol( - pol: Self::Pol, - from_var_pol: impl FnOnce() -> T, - from_lit_pol: impl FnOnce(Pol) -> T, - ) -> T; - } - - impl From<()> for Pol { - fn from(_: ()) -> Self { - Pol::Pos - } - } - - impl ops::BitXor<()> for Var { - type Output = Self; - - #[inline(always)] - fn bitxor(self, _: ()) -> Self::Output { - self - } - } - - impl ops::BitXorAssign<()> for Var { - #[inline(always)] - fn bitxor_assign(&mut self, _: ()) {} - } - - impl VarOrLit for Var { - type Pol = (); - - fn build_var_or_lit( - input: T, - build_var: impl FnOnce(T) -> Var, - _build_lit: impl FnOnce(T) -> Lit, - ) -> Self { - build_var(input) - } - - fn process_var_or_lit( - self, - from_var: impl FnOnce(Var) -> T, - _from_lit: impl FnOnce(Lit) -> T, - ) -> T { - from_var(self) - } - - fn process_pol( - (): Self::Pol, - from_var_pol: impl FnOnce() -> T, - _from_lit_pol: impl FnOnce(Pol) -> T, - ) -> T { - from_var_pol() - } - } - - impl VarOrLit for Lit { - type Pol = Pol; - fn build_var_or_lit( - input: T, - _build_var: impl FnOnce(T) -> Var, - build_lit: impl FnOnce(T) -> Lit, - ) -> Self { - build_lit(input) - } - - fn process_var_or_lit( - self, - _from_var: impl FnOnce(Var) -> T, - from_lit: impl FnOnce(Lit) -> T, - ) -> T { - from_lit(self) - } - - fn process_pol( - pol: Self::Pol, - _from_var_pol: impl FnOnce() -> T, - from_lit_pol: impl FnOnce(Pol) -> T, - ) -> T { - from_lit_pol(pol) - } - } -}