bench_index2/
bench_index2.rs1use std::time::Instant;
2use vampire_prover::{Function, Options, Predicate, Problem, ProofRes, Term, exists, forall};
3
4fn main() {
5 println!("Running index-2 subgroup normality proof benchmark");
6 println!(
7 "This will run the proof repeatedly to detect memory leaks or performance degradation\n"
8 );
9
10 const NUM_ITERATIONS: usize = 1000;
11 let mut times = Vec::with_capacity(NUM_ITERATIONS);
12
13 for i in 0..NUM_ITERATIONS {
14 waste_symbols(i);
15 unsafe {
16 vampire_sys::vampire_reset();
17 }
18
19 let start = Instant::now();
20 let result = run_proof(i);
21 let elapsed = start.elapsed();
22
23 times.push(elapsed.as_micros());
24
25 print!("Iteration {:3}: {:6} µs ", i + 1, elapsed.as_micros());
26
27 match result {
28 ProofRes::Proved => print!("[PROVED]"),
29 ProofRes::Unprovable => print!("[UNPROVABLE]"),
30 ProofRes::Unknown(reason) => print!("[UNKNOWN: {:?}]", reason),
31 }
32
33 if (i + 1) % 10 == 0 {
35 let avg = times.iter().sum::<u128>() / times.len() as u128;
36 let min = *times.iter().min().unwrap();
37 let max = *times.iter().max().unwrap();
38 println!(" (avg: {} µs, min: {} µs, max: {} µs)", avg, min, max);
39 } else {
40 println!();
41 }
42 }
43
44 println!("\n{}", "=".repeat(60));
46 println!("Final Statistics:");
47 println!("{}", "=".repeat(60));
48
49 let avg = times.iter().sum::<u128>() / times.len() as u128;
50 let min = *times.iter().min().unwrap();
51 let max = *times.iter().max().unwrap();
52
53 let variance = times
55 .iter()
56 .map(|&t| {
57 let diff = t as i128 - avg as i128;
58 (diff * diff) as u128
59 })
60 .sum::<u128>()
61 / times.len() as u128;
62 let std_dev = (variance as f64).sqrt();
63
64 println!("Total runs: {}", NUM_ITERATIONS);
65 println!(
66 "Average time: {} µs ({:.2} ms)",
67 avg,
68 avg as f64 / 1000.0
69 );
70 println!(
71 "Min time: {} µs ({:.2} ms)",
72 min,
73 min as f64 / 1000.0
74 );
75 println!(
76 "Max time: {} µs ({:.2} ms)",
77 max,
78 max as f64 / 1000.0
79 );
80 println!(
81 "Std deviation: {:.2} µs ({:.2} ms)",
82 std_dev,
83 std_dev / 1000.0
84 );
85
86 let first_10_avg = times[0..10].iter().sum::<u128>() / 10;
88 let last_10_avg = times[times.len() - 10..].iter().sum::<u128>() / 10;
89 let degradation_percent =
90 ((last_10_avg as f64 - first_10_avg as f64) / first_10_avg as f64) * 100.0;
91
92 println!("\nFirst 10 avg: {} µs", first_10_avg);
93 println!("Last 10 avg: {} µs", last_10_avg);
94 println!("Degradation: {:.2}%", degradation_percent);
95
96 if degradation_percent > 10.0 {
97 println!("\n⚠️ WARNING: Significant performance degradation detected!");
98 println!(" This may indicate a memory leak or resource accumulation.");
99 } else if degradation_percent < -10.0 {
100 println!("\n✓ Performance improved over time (likely JIT/cache effects)");
101 } else {
102 println!("\n✓ Performance stable across iterations");
103 }
104}
105
106fn waste_symbols(i: usize) {
107 for j in 0..1000 {
108 Function::new(&format!("p{i}-{j}"), 2);
109 Predicate::new(&format!("f{i}-{j}"), 2);
110 }
111}
112
113fn run_proof(i: usize) -> ProofRes {
114 let mult = Function::new(&format!("mult{i}"), 2);
116 let inv = Function::new(&format!("inv{i}"), 1);
117 let one = Function::constant(&format!("1{i}"));
118
119 let mul = |x: Term, y: Term| -> Term { mult.with(&[x, y]) };
121
122 let right_identity = forall(|x| mul(x, one).eq(x));
124
125 let right_inverse = forall(|x| {
127 let inv_x = inv.with(&[x]);
128 mul(x, inv_x).eq(one)
129 });
130
131 let associativity = forall(|x| forall(|y| forall(|z| mul(mul(x, y), z).eq(mul(x, mul(y, z))))));
133
134 let h = Predicate::new("h", 1);
136
137 let h_ident = h.with(&[one]);
139
140 let h_mul_closed =
142 forall(|x| forall(|y| (h.with(&[x]) & h.with(&[y])) >> h.with(&[mul(x, y)])));
143
144 let h_inv_closed = forall(|x| h.with(&[x]) >> h.with(&[inv.with(&[x])]));
146
147 let h_index_2 = exists(|x| {
149 let not_in_h = !h.with(&[x]);
151 let class = forall(|y| h.with(&[y]) | h.with(&[mul(inv.with(&[x]), y)]));
153
154 not_in_h & class
155 });
156
157 let h_normal = forall(|x| {
159 let h_x = h.with(&[x]);
160 let conj_x = forall(|y| {
161 let y_inv = inv.with(&[y]);
162 h.with(&[mul(mul(y, x), y_inv)])
163 });
164 h_x.iff(conj_x)
165 });
166
167 Problem::new(Options::new())
168 .with_axiom(right_identity)
169 .with_axiom(right_inverse)
170 .with_axiom(associativity)
171 .with_axiom(h_ident)
172 .with_axiom(h_mul_closed)
173 .with_axiom(h_inv_closed)
174 .with_axiom(h_index_2)
175 .conjecture(h_normal)
176 .solve()
177}