1use super::functions::*;
6use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
7
8pub struct DpllSolver {
11 n_vars: usize,
12 clauses: Vec<Vec<i32>>,
13}
14impl DpllSolver {
15 pub fn new(n_vars: usize) -> Self {
17 Self {
18 n_vars,
19 clauses: vec![],
20 }
21 }
22 pub fn add_clause(&mut self, clause: Vec<i32>) {
24 self.clauses.push(clause);
25 }
26 pub fn solve(&self) -> Option<Vec<bool>> {
28 let mut assignment = vec![None::<bool>; self.n_vars + 1];
29 if self.dpll(&mut assignment) {
30 Some(
31 assignment
32 .into_iter()
33 .skip(1)
34 .map(|v| v.unwrap_or(false))
35 .collect(),
36 )
37 } else {
38 None
39 }
40 }
41 fn dpll(&self, assignment: &mut Vec<Option<bool>>) -> bool {
42 let mut changed = true;
43 while changed {
44 changed = false;
45 for clause in &self.clauses {
46 let (unset, sat, unit_lit) = self.clause_status(clause, assignment);
47 if sat {
48 continue;
49 }
50 if unset == 0 {
51 return false;
52 }
53 if unset == 1 {
54 let lit = unit_lit.expect(
55 "unit_lit is Some: unset == 1 means exactly one unset literal was tracked",
56 );
57 let var = lit.unsigned_abs() as usize;
58 let val = lit > 0;
59 if assignment[var] == Some(!val) {
60 return false;
61 }
62 assignment[var] = Some(val);
63 changed = true;
64 }
65 }
66 }
67 if self
68 .clauses
69 .iter()
70 .all(|c| self.clause_status(c, assignment).1)
71 {
72 return true;
73 }
74 let var = match (1..=self.n_vars).find(|&v| assignment[v].is_none()) {
75 Some(v) => v,
76 None => return false,
77 };
78 assignment[var] = Some(true);
79 if self.dpll(assignment) {
80 return true;
81 }
82 assignment[var] = Some(false);
83 if self.dpll(assignment) {
84 return true;
85 }
86 assignment[var] = None;
87 false
88 }
89 fn clause_status(
91 &self,
92 clause: &[i32],
93 assignment: &[Option<bool>],
94 ) -> (usize, bool, Option<i32>) {
95 let mut unset = 0;
96 let mut last_unset = None;
97 for &lit in clause {
98 let var = lit.unsigned_abs() as usize;
99 match assignment[var] {
100 None => {
101 unset += 1;
102 last_unset = Some(lit);
103 }
104 Some(val) => {
105 if (lit > 0) == val {
106 return (0, true, None);
107 }
108 }
109 }
110 }
111 (unset, false, last_unset)
112 }
113}
114#[allow(dead_code)]
116pub struct CircuitEvaluator {
117 pub gates: Vec<CircuitGate>,
118}
119impl CircuitEvaluator {
120 pub fn new() -> Self {
122 Self { gates: vec![] }
123 }
124 pub fn add_gate(&mut self, kind: GateKind, left: Option<usize>, right: Option<usize>) -> usize {
126 let idx = self.gates.len();
127 self.gates.push(CircuitGate { kind, left, right });
128 idx
129 }
130 pub fn evaluate(&self, inputs: &[bool]) -> bool {
132 let output_gate = self.gates.len().saturating_sub(1);
133 self.eval_gate(output_gate, inputs)
134 }
135 fn eval_gate(&self, idx: usize, inputs: &[bool]) -> bool {
136 let gate = &self.gates[idx];
137 match gate.kind {
138 GateKind::Input(i) => inputs.get(i).copied().unwrap_or(false),
139 GateKind::Const(b) => b,
140 GateKind::And => {
141 let l = gate.left.map(|i| self.eval_gate(i, inputs)).unwrap_or(true);
142 let r = gate
143 .right
144 .map(|i| self.eval_gate(i, inputs))
145 .unwrap_or(true);
146 l && r
147 }
148 GateKind::Or => {
149 let l = gate
150 .left
151 .map(|i| self.eval_gate(i, inputs))
152 .unwrap_or(false);
153 let r = gate
154 .right
155 .map(|i| self.eval_gate(i, inputs))
156 .unwrap_or(false);
157 l || r
158 }
159 GateKind::Not => {
160 let l = gate
161 .left
162 .map(|i| self.eval_gate(i, inputs))
163 .unwrap_or(false);
164 !l
165 }
166 }
167 }
168}
169pub struct SudokuSolver {
171 pub grid: [u8; 81],
173}
174impl SudokuSolver {
175 pub fn new(grid: [u8; 81]) -> Self {
177 Self { grid }
178 }
179 pub fn solve(&mut self) -> bool {
181 for pos in 0..81 {
182 if self.grid[pos] == 0 {
183 let row = pos / 9;
184 let col = pos % 9;
185 for digit in 1u8..=9 {
186 if self.is_valid(row, col, digit) {
187 self.grid[pos] = digit;
188 if self.solve() {
189 return true;
190 }
191 self.grid[pos] = 0;
192 }
193 }
194 return false;
195 }
196 }
197 true
198 }
199 fn is_valid(&self, row: usize, col: usize, digit: u8) -> bool {
200 for c in 0..9 {
201 if self.grid[row * 9 + c] == digit {
202 return false;
203 }
204 }
205 for r in 0..9 {
206 if self.grid[r * 9 + col] == digit {
207 return false;
208 }
209 }
210 let br = (row / 3) * 3;
211 let bc = (col / 3) * 3;
212 for r in br..br + 3 {
213 for c in bc..bc + 3 {
214 if self.grid[r * 9 + c] == digit {
215 return false;
216 }
217 }
218 }
219 true
220 }
221}
222#[derive(Clone, Copy, PartialEq, Eq)]
225pub enum GateKind {
226 And,
227 Or,
228 Not,
229 Input(usize),
230 Const(bool),
231}
232#[allow(dead_code)]
235pub struct CommunicationMatrixAnalyzer {
236 pub matrix: Vec<Vec<u8>>,
238}
239impl CommunicationMatrixAnalyzer {
240 pub fn new(matrix: Vec<Vec<u8>>) -> Self {
242 Self { matrix }
243 }
244 pub fn rank_gf2(&self) -> usize {
246 let rows = self.matrix.len();
247 if rows == 0 {
248 return 0;
249 }
250 let cols = self.matrix[0].len();
251 let mut mat: Vec<Vec<u8>> = self.matrix.iter().map(|r| r.clone()).collect();
252 let mut rank = 0;
253 let mut pivot_row = 0;
254 for col in 0..cols {
255 let mut found = None;
256 for row in pivot_row..rows {
257 if mat[row][col] == 1 {
258 found = Some(row);
259 break;
260 }
261 }
262 if let Some(r) = found {
263 mat.swap(pivot_row, r);
264 for row in 0..rows {
265 if row != pivot_row && mat[row][col] == 1 {
266 let pivot = mat[pivot_row].clone();
267 let target = &mut mat[row];
268 for j in 0..cols {
269 target[j] ^= pivot[j];
270 }
271 }
272 }
273 rank += 1;
274 pivot_row += 1;
275 }
276 }
277 rank
278 }
279 pub fn log_rank_lower_bound(&self) -> usize {
282 let r = self.rank_gf2();
283 if r == 0 {
284 return 0;
285 }
286 (usize::BITS - 1 - r.leading_zeros()) as usize
287 }
288}
289#[allow(dead_code)]
290pub struct CircuitGate {
291 pub kind: GateKind,
292 pub left: Option<usize>,
293 pub right: Option<usize>,
294}
295#[allow(dead_code)]
298pub struct ParameterizedAlgorithmChecker {
299 pub param_name: String,
301}
302impl ParameterizedAlgorithmChecker {
303 pub fn new(param_name: &str) -> Self {
305 Self {
306 param_name: param_name.to_string(),
307 }
308 }
309 pub fn check(&self, observed: u64, k: u64, n: u64, f: impl Fn(u64) -> u64, c: u32) -> bool {
311 let fk = f(k);
312 let nc = n.saturating_pow(c);
313 observed <= fk.saturating_mul(nc)
314 }
315 pub fn check_2k_n(&self, observed: u64, k: u64, n: u64) -> bool {
317 let fk = 1u64.checked_shl(k as u32).unwrap_or(u64::MAX);
318 observed <= fk.saturating_mul(n)
319 }
320}
321#[allow(dead_code)]
324pub struct SensitivityChecker {
325 pub table: Vec<bool>,
327 pub n: usize,
329}
330impl SensitivityChecker {
331 pub fn new(table: Vec<bool>) -> Self {
333 let n = if table.is_empty() {
334 0
335 } else {
336 usize::BITS as usize - table.len().leading_zeros() as usize - 1
337 };
338 Self { table, n }
339 }
340 pub fn sensitivity_at(&self, x: usize) -> usize {
342 let fx = self.table.get(x).copied().unwrap_or(false);
343 (0..self.n)
344 .filter(|&i| {
345 let xp = x ^ (1 << i);
346 self.table.get(xp).copied().unwrap_or(false) != fx
347 })
348 .count()
349 }
350 pub fn max_sensitivity(&self) -> usize {
352 (0..self.table.len())
353 .map(|x| self.sensitivity_at(x))
354 .max()
355 .unwrap_or(0)
356 }
357 pub fn block_sensitivity_at(&self, x: usize) -> usize {
359 let fx = self.table.get(x).copied().unwrap_or(false);
360 let mut used = vec![false; self.n];
361 let mut count = 0;
362 for size in 1..=self.n {
363 for mask in 0..(1usize << self.n) {
364 if mask.count_ones() as usize != size {
365 continue;
366 }
367 let all_unused = (0..self.n).all(|i| !used[i] || (mask >> i) & 1 == 0);
368 if !all_unused {
369 continue;
370 }
371 let xp = x ^ mask;
372 if self.table.get(xp).copied().unwrap_or(false) != fx {
373 for i in 0..self.n {
374 if (mask >> i) & 1 == 1 {
375 used[i] = true;
376 }
377 }
378 count += 1;
379 break;
380 }
381 }
382 }
383 count
384 }
385 pub fn max_block_sensitivity(&self) -> usize {
387 (0..self.table.len())
388 .map(|x| self.block_sensitivity_at(x))
389 .max()
390 .unwrap_or(0)
391 }
392 pub fn check_huang_theorem(&self) -> bool {
394 let s = self.max_sensitivity();
395 let bs = self.max_block_sensitivity();
396 s * s >= bs
397 }
398}
399pub struct TwoSatSolver {
402 n: usize,
403 adj: Vec<Vec<usize>>,
405 radj: Vec<Vec<usize>>,
407}
408impl TwoSatSolver {
409 pub fn new(n: usize) -> Self {
411 Self {
412 n,
413 adj: vec![vec![]; 2 * n],
414 radj: vec![vec![]; 2 * n],
415 }
416 }
417 pub fn add_clause(&mut self, a: usize, b: usize) {
419 let na = a ^ 1;
420 let nb = b ^ 1;
421 self.adj[na].push(b);
422 self.adj[nb].push(a);
423 self.radj[b].push(na);
424 self.radj[a].push(nb);
425 }
426 pub fn solve(&self) -> Option<Vec<bool>> {
428 let n2 = 2 * self.n;
429 let mut order: Vec<usize> = Vec::with_capacity(n2);
430 let mut visited = vec![false; n2];
431 for i in 0..n2 {
432 if !visited[i] {
433 self.dfs1(i, &mut visited, &mut order);
434 }
435 }
436 let mut comp = vec![usize::MAX; n2];
437 let mut c = 0;
438 for &v in order.iter().rev() {
439 if comp[v] == usize::MAX {
440 self.dfs2(v, c, &mut comp);
441 c += 1;
442 }
443 }
444 let mut assignment = vec![false; self.n];
445 for i in 0..self.n {
446 if comp[2 * i] == comp[2 * i + 1] {
447 return None;
448 }
449 assignment[i] = comp[2 * i] > comp[2 * i + 1];
450 }
451 Some(assignment)
452 }
453 fn dfs1(&self, v: usize, visited: &mut Vec<bool>, order: &mut Vec<usize>) {
454 visited[v] = true;
455 for &u in &self.adj[v] {
456 if !visited[u] {
457 self.dfs1(u, visited, order);
458 }
459 }
460 order.push(v);
461 }
462 fn dfs2(&self, v: usize, c: usize, comp: &mut Vec<usize>) {
463 comp[v] = c;
464 for &u in &self.radj[v] {
465 if comp[u] == usize::MAX {
466 self.dfs2(u, c, comp);
467 }
468 }
469 }
470}
471#[allow(dead_code)]
475pub struct ResolutionProverSmall {
476 clauses: Vec<Vec<i32>>,
477}
478impl ResolutionProverSmall {
479 pub fn new() -> Self {
481 Self { clauses: vec![] }
482 }
483 pub fn add_clause(&mut self, clause: Vec<i32>) {
485 let mut c = clause;
486 c.sort_unstable();
487 c.dedup();
488 self.clauses.push(c);
489 }
490 pub fn refute(&self, max_steps: usize) -> bool {
493 use std::collections::HashSet;
494 let normalize = |c: &Vec<i32>| -> Vec<i32> {
495 let mut v = c.clone();
496 v.sort_unstable();
497 v.dedup();
498 v
499 };
500 let mut known: HashSet<Vec<i32>> = HashSet::new();
501 let mut all_clauses: Vec<Vec<i32>> = vec![];
502 for c in &self.clauses {
503 let n = normalize(c);
504 if n.is_empty() {
505 return true;
506 }
507 if known.insert(n.clone()) {
508 all_clauses.push(n);
509 }
510 }
511 let mut steps = 0;
512 let mut new_start = 0;
513 loop {
514 if steps >= max_steps {
515 break;
516 }
517 let end = all_clauses.len();
518 if new_start >= end {
519 break;
520 }
521 let mut added = vec![];
522 for i in new_start..end {
523 for j in 0..end {
524 if i == j {
525 continue;
526 }
527 if let Some(resolved) = Self::resolve(&all_clauses[i], &all_clauses[j]) {
528 let n = normalize(&resolved);
529 if n.is_empty() {
530 return true;
531 }
532 if known.insert(n.clone()) {
533 added.push(n);
534 }
535 }
536 steps += 1;
537 if steps >= max_steps {
538 break;
539 }
540 }
541 if steps >= max_steps {
542 break;
543 }
544 }
545 if added.is_empty() {
546 break;
547 }
548 new_start = end;
549 all_clauses.extend(added);
550 }
551 false
552 }
553 fn resolve(c1: &[i32], c2: &[i32]) -> Option<Vec<i32>> {
555 for &lit in c1 {
556 if c2.contains(&-lit) {
557 let mut result: Vec<i32> = c1
558 .iter()
559 .filter(|&&l| l != lit)
560 .copied()
561 .chain(c2.iter().filter(|&&l| l != -lit).copied())
562 .collect();
563 result.sort_unstable();
564 result.dedup();
565 for &l in &result {
566 if result.contains(&-l) {
567 return None;
568 }
569 }
570 return Some(result);
571 }
572 }
573 None
574 }
575}