debug!("merge_transitions requires full-domain transition relations; enabling relation extension");
let preprocessed_lts = preprocess_lts(manager_ref, lts, use_extended_relations, merge_transitions)?;
.sat_count::<u64, FxBuildHasher>(lts.state_variables().len() as u32, &mut SatCountCache::default());
// In the sigref algorithm, the partition is defined over the next state. When we compute the signature
// we then get (s, a, b), since in the signature we need to consider the block of the next state.
.map(|group| -> Result<_, MercError> { Ok(compute_vars_bdd(manager_ref, group.write_variables())?.1) })
let group_signature = variable_rename(manager_ref, &group_signature, &state_substitution)?;
/// Computes a partitioning of the transition groups for the given LTS based on the split signature option.
/// Two transition groups are combined if they share action labels, this ensures that in split signature mode
fn combine_transition_groups(manager_ref: &BDDManagerRef, lts: &SymbolicLtsBdd) -> Result<Vec<Vec<usize>>, MercError> {
// In split signature mode we must ensure that the action labels of all transition groups are disjoint. We do this by merging
let state_and_next_state_vars = manager_ref.with_manager_shared(|manager| -> Result<_, OutOfMemory> {
if let Some(result) = cache.get(&BDDFunction::from_edge(manager, manager.clone_edge(&bdd))) {
// There are variables in the range that are not in the domain, so this cannot be a function from domain to range.
/// Checks if the given BDD is a cube, i.e., it represents a single bitvector over the given variables.
for (state_var, next_state_var) in state_variables.iter().zip(next_state_variables.iter()).rev() {
eq = EdgeDropGuard::new(manager, reduce(manager, *state_var, low.into_edge(), high.into_edge())?);
/// Display helper that prints all vectors represented by the given signature BDD as numbers, by decoding
/// Display helper that prints all vectors represented by the given signature BDD as numbers, by decoding
fn new(signature: &'a BDDFunction, variables: &'a Vec<VarNo>, num_of_bits: &'a [u32], block_bits: u32) -> Self {
let block_variable_names = (0..num_of_bits).map(|i| format!("b_{}", i)).collect::<Vec<String>>();
// sigref_symbolic(&manager_ref, <s_bdd, &Timing::new(), false, false, false, false).unwrap();
// let lts_bdd_split = SymbolicLtsBdd::from_symbolic_lts(&mut storage, &manager_ref_split, <s).unwrap();
// let lts_bdd = SymbolicLtsBdd::from_symbolic_lts(&mut storage, &manager_ref, <s_bdd).unwrap();
// sigref_symbolic(&manager_ref, <s_bdd, &Timing::new(), false, false, false, false).unwrap();
let lts = read_symbolic_lts(&mut storage, include_bytes!("../../../examples/lts/abp.sym") as &[u8]).unwrap();
sigref_symbolic(&manager_ref, <s_bdd, &mut Timing::new(), false, false, false, false).unwrap();
!bdd.satisfiable() || is_bdd_cube_edge(&manager, bdd.as_edge(manager).borrowed()).unwrap(),
let lts_bdd = SymbolicLtsBdd::from_symbolic_lts(&mut storage, &manager_ref, <s).unwrap();
sigref_symbolic(&manager_ref, <s_bdd, &mut Timing::new(), false, false, false, false).unwrap();
let quotient_lts = quotient_symbolic(&manager_ref, <s_bdd, &partition, &block_vars).unwrap();
let symbolic_lts_reduced = convert_symbolic_lts_bdd(&manager_ref, &mut builder, "ient_lts).unwrap();