fn branching_bisim_sigref_impl<L: LTS>(preprocessed_lts: &L, timing: &Timing) -> BlockPartition {
branching_bisim_signature_inductive(state_index, preprocessed_lts, partition, state_to_key, builder);
fn branching_bisim_sigref_naive_impl<L: LTS>(preprocessed_lts: &L, timing: &Timing) -> IndexedPartition {
branching_bisim_signature_sorted(state_index, preprocessed_lts, partition, state_to_signature, builder);
/// Computes a branching bisimulation partitioning using signature refinement without dirty blocks.
/// Implementation of [weak_bisim_sigref_inductive_naive] that deals with both preprocessed and regular LTSs.
/// Computes a branching bisimulation partitioning using signature refinement without dirty blocks.
weak_bisim_signature_sorted(state_index, &preprocessed_lts, partition, state_to_signature, builder)
let id: &mut FxHashMap<Signature<'_>, BlockIndex> = unsafe { std::mem::transmute(&mut id) };
let key_to_signature: &'_ mut Vec<Signature<'_>> = unsafe { std::mem::transmute(&mut key_to_signature) };
partition.partition_marked_with(block_index, &mut split_builder, |state_index, partition| {
let state_to_signature: &'_ mut Vec<Option<usize>> = unsafe { std::mem::transmute(&mut state_to_signature) };
let id: &'_ mut FxHashMap<Signature<'_>, BlockIndex> = unsafe { std::mem::transmute(&mut id) };
let key_to_signature: &'_ mut Vec<Signature<'_>> = unsafe { std::mem::transmute(&mut key_to_signature) };
let state_to_taus: &'_ mut Vec<Signature<'_>> = unsafe { std::mem::transmute(&mut state_to_taus) };
"There can never be more splits than number of states, but at least two iterations for stability"
fn signature_refinement_naive<F, L: LTS, const WEAK: bool>(lts: &L, mut signature: F) -> IndexedPartition
let id: &'_ mut FxHashMap<Signature<'_>, BlockIndex> = unsafe { std::mem::transmute(&mut id) };
let state_to_signature: &mut Vec<Signature<'_>> = unsafe { std::mem::transmute(&mut state_to_signature) };
weak_bisim_signature_sorted_taus(state_index, lts, &partition, state_to_signature, &mut builder);
// Keep track of the index for every state, either use the arena to allocate space or simply borrow the value.
// Keep track of the index for every state, either use the arena to allocate space or simply borrow the value.
std::mem::transmute::<Signature<'_>, Signature<'_>>(Signature::new(signature.as_slice()))
"There can never be more splits than number of states, but at least two iterations for stability"
pub fn is_valid_refinement<F, P, L>(lts: &L, partition: &P, mut compute_signature: F) -> bool
let mut block_to_signature: Vec<Option<SignatureBuilder>> = vec![None; partition.num_of_blocks()];
"State {state_index} has a different signature {signature:?} then the block {block} which has signature {block_signature:?}"
.map(|signature: &Option<SignatureBuilder>| signature.as_ref().expect("Signature should be defined"))
/// Checks that the strong bisimulation partition is a refinement of the branching bisimulation partition.
fn is_refinement<L: LTS, P: Partition, Q: Partition>(lts: &L, strong_partition: &P, branching_partition: &Q) {
if strong_partition.block_number(state_index) == strong_partition.block_number(other_state_index) {
// If the states are together according to strong bisimilarity, then they should also be together according to branching bisimilarity.
"The strong partition should be a refinement of the branching partition, but states {state_index} and {other_state_index} are in different strong blocks"
branching_bisim_sigref_naive(preprocessed_lts.clone(), StateIndex::new(0), false, &mut timing);