#![cfg(kani)]
use crate::{BcsrNativeHypergraph, BcsrSections, BcsrValidation};
#[kani::proof]
#[kani::unwind(4)]
fn validate_layout_total() {
let head_offsets: [u32; 2] = kani::any();
let tail_offsets: [u32; 2] = kani::any();
let head_participants: [u32; 1] = kani::any();
let tail_participants: [u32; 1] = kani::any();
let vertex_outgoing_offsets: [u32; 2] = kani::any();
let vertex_outgoing_hyperedges: [u32; 1] = kani::any();
let vertex_incoming_offsets: [u32; 2] = kani::any();
let vertex_incoming_hyperedges: [u32; 1] = kani::any();
let sections = BcsrSections::for_kani(
&head_offsets,
&head_participants,
&tail_offsets,
&tail_participants,
&vertex_outgoing_offsets,
&vertex_outgoing_hyperedges,
&vertex_incoming_offsets,
&vertex_incoming_hyperedges,
);
let _ = BcsrNativeHypergraph::<u32, u32, u32>::open(sections);
}
#[kani::proof]
#[kani::unwind(4)]
fn validate_strict_total() {
let head_offsets: [u32; 2] = kani::any();
let tail_offsets: [u32; 2] = kani::any();
let head_participants: [u32; 1] = kani::any();
let tail_participants: [u32; 1] = kani::any();
let vertex_outgoing_offsets: [u32; 2] = kani::any();
let vertex_outgoing_hyperedges: [u32; 1] = kani::any();
let vertex_incoming_offsets: [u32; 2] = kani::any();
let vertex_incoming_hyperedges: [u32; 1] = kani::any();
let sections = BcsrSections::for_kani(
&head_offsets,
&head_participants,
&tail_offsets,
&tail_participants,
&vertex_outgoing_offsets,
&vertex_outgoing_hyperedges,
&vertex_incoming_offsets,
&vertex_incoming_hyperedges,
);
let _ = BcsrNativeHypergraph::<u32, u32, u32>::open_with(sections, BcsrValidation::Strict);
}
#[kani::proof]
fn participant_id_arithmetic_no_overflow() {
let p_head: u32 = kani::any();
let p_tail: u32 = kani::any();
let total = p_head.checked_add(p_tail);
if let Some(total) = total {
kani::assume(total > 0);
let i: u32 = kani::any();
kani::assume(i < total);
if i >= p_head {
let local = i - p_head;
assert!(local < p_tail);
} else {
assert!(i < p_head);
}
}
}
#[kani::proof]
fn u32_to_usize_safe_on_target_platforms() {
const _: () = assert!(usize::BITS >= 32);
let value: u32 = kani::any();
let _converted = match usize::try_from(value) {
Ok(converted) => converted,
Err(_) => unreachable!(),
};
}
#[kani::proof]
#[kani::unwind(8)]
fn validated_traversal_in_bounds_h2_v2() {
use oxgraph_hyper::{
DirectedHyperedgeParticipants, ElementPredecessors, ElementSuccessors,
HyperedgeParticipants, IncidentHyperedges,
};
use crate::{BcsrHyperedgeId, BcsrVertexId};
let head_offsets: [u32; 3] = kani::any();
let tail_offsets: [u32; 3] = kani::any();
let head_participants: [u32; 2] = kani::any();
let tail_participants: [u32; 2] = kani::any();
let vertex_outgoing_offsets: [u32; 3] = kani::any();
let vertex_outgoing_hyperedges: [u32; 2] = kani::any();
let vertex_incoming_offsets: [u32; 3] = kani::any();
let vertex_incoming_hyperedges: [u32; 2] = kani::any();
let sections = BcsrSections::for_kani(
&head_offsets,
&head_participants,
&tail_offsets,
&tail_participants,
&vertex_outgoing_offsets,
&vertex_outgoing_hyperedges,
&vertex_incoming_offsets,
&vertex_incoming_hyperedges,
);
let view = match BcsrNativeHypergraph::<u32, u32, u32>::open(sections) {
Ok(value) => value,
Err(_) => return,
};
for h in 0..2u32 {
let hid = BcsrHyperedgeId(h);
let mut count = 0u32;
for _ in view.hyperedge_participants(hid) {
count = count.wrapping_add(1);
}
let _ = count;
let mut count = 0u32;
for _ in view.source_participants(hid) {
count = count.wrapping_add(1);
}
let _ = count;
let mut count = 0u32;
for _ in view.target_participants(hid) {
count = count.wrapping_add(1);
}
let _ = count;
}
for v in 0..2u32 {
let vid = BcsrVertexId(v);
let mut count = 0u32;
for _ in view.incident_hyperedges(vid) {
count = count.wrapping_add(1);
}
let _ = count;
let mut count = 0u32;
for _ in view.element_successors(vid) {
count = count.wrapping_add(1);
}
let _ = count;
let mut count = 0u32;
for _ in view.element_predecessors(vid) {
count = count.wrapping_add(1);
}
let _ = count;
}
}
#[kani::proof]
#[kani::unwind(8)]
fn strict_implies_count_symmetry_h2_v2() {
use oxgraph_hyper::{HyperedgeParticipants, IncidentHyperedges};
use crate::{BcsrHyperedgeId, BcsrVertexId};
let head_offsets: [u32; 3] = kani::any();
let tail_offsets: [u32; 3] = kani::any();
let head_participants: [u32; 2] = kani::any();
let tail_participants: [u32; 2] = kani::any();
let vertex_outgoing_offsets: [u32; 3] = kani::any();
let vertex_outgoing_hyperedges: [u32; 2] = kani::any();
let vertex_incoming_offsets: [u32; 3] = kani::any();
let vertex_incoming_hyperedges: [u32; 2] = kani::any();
let sections = BcsrSections::for_kani(
&head_offsets,
&head_participants,
&tail_offsets,
&tail_participants,
&vertex_outgoing_offsets,
&vertex_outgoing_hyperedges,
&vertex_incoming_offsets,
&vertex_incoming_hyperedges,
);
let view =
match BcsrNativeHypergraph::<u32, u32, u32>::open_with(sections, BcsrValidation::Strict) {
Ok(value) => value,
Err(_) => return,
};
let mut hyperedge_side_total = 0u32;
for h in 0..2u32 {
for _ in view.hyperedge_participants(BcsrHyperedgeId(h)) {
hyperedge_side_total = hyperedge_side_total.wrapping_add(1);
}
}
let mut vertex_side_total = 0u32;
for v in 0..2u32 {
for _ in view.incident_hyperedges(BcsrVertexId(v)) {
vertex_side_total = vertex_side_total.wrapping_add(1);
}
}
assert_eq!(hyperedge_side_total, vertex_side_total);
}