Progress with cdcl

This commit is contained in:
hal8174 2024-10-29 18:45:23 +01:00
parent cdb1e893ab
commit 63b1350b3b

View file

@ -10,6 +10,13 @@ enum StateItem {
Unknown, Unknown,
} }
#[derive(Debug, Clone, Copy)]
enum ClauseState {
Satisfied,
UnitPropagate(Index),
Unknown,
}
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct State { struct State {
map: Vec<StateItem>, map: Vec<StateItem>,
@ -36,12 +43,79 @@ impl State {
self.set_literal(l); self.set_literal(l);
} }
fn add_literal_propagate(&mut self, l: Index, cnf: &NormalForm) -> Result<(), Vec<Index>> { fn add_literal_propagate(
&mut self,
l: Index,
source_slice: &[Index],
cnf: &NormalForm,
) -> Result<(), Vec<Index>> {
for &i in source_slice.iter().filter(|&&i| i != l) {
self.graph.push((i, l));
}
if let Some(NormalFormIteratorItem {
slice,
len: _,
index: _,
}) = cnf.iter().find(
|&NormalFormIteratorItem {
slice,
len: _,
index: _,
}| {
match self.get_clause_state(slice) {
ClauseState::UnitPropagate(other) => other == -l,
_ => false,
}
},
) {
let mut conflict: Vec<_> = source_slice
.iter()
.copied()
.filter(|&i| i != l)
.chain(slice.iter().copied().filter(|&i| i != -l))
.collect();
conflict.sort();
conflict.dedup();
return Err(conflict);
}
self.set_literal(l); self.set_literal(l);
Ok(()) Ok(())
} }
fn get_clause_state(&self, s: &[Index]) -> ClauseState {
let mut unknown_literal = None;
for &l in s {
match self.get_literal(l) {
StateItem::True => {
if l > 0 {
return ClauseState::Satisfied;
}
}
StateItem::False => {
if l < 0 {
return ClauseState::Satisfied;
}
}
StateItem::Unknown => {
if unknown_literal.is_some() {
return ClauseState::Unknown;
} else {
unknown_literal = Some(l);
}
}
}
}
match unknown_literal {
Some(l) => ClauseState::UnitPropagate(l),
None => panic!("Fully false clause."),
}
}
fn get_literal(&self, l: Index) -> StateItem { fn get_literal(&self, l: Index) -> StateItem {
self.map[l.unsigned_abs() as usize - 1] self.map[l.unsigned_abs() as usize - 1]
} }
@ -84,28 +158,25 @@ impl State {
} }
fn unit_propagate(cnf: &NormalForm, state: &mut State) -> Result<(), Vec<Index>> { fn unit_propagate(cnf: &NormalForm, state: &mut State) -> Result<(), Vec<Index>> {
if let Some(nfii) = cnf.iter().find( if let Some(NormalFormIteratorItem {
slice,
len: _,
index: _,
}) = cnf.iter().find(
|NormalFormIteratorItem { |NormalFormIteratorItem {
slice, slice,
len: _, len: _,
index: _, index: _,
}| { }| { matches!(state.get_clause_state(slice), ClauseState::UnitPropagate(_)) },
slice
.iter()
.filter(|&&l| state.is_unknown_literal(l))
.count()
== 1
},
) { ) {
let i = nfii let i = slice
.slice
.iter() .iter()
.position(|&i| state.is_unknown_literal(i)) .position(|&i| state.is_unknown_literal(i))
.unwrap(); .unwrap();
let l = nfii.slice[i]; let l = slice[i];
state.add_literal_propagate(l, cnf)?; state.add_literal_propagate(l, slice, cnf)?;
unit_propagate(cnf, state) unit_propagate(cnf, state)
} else { } else {
@ -116,36 +187,34 @@ fn unit_propagate(cnf: &NormalForm, state: &mut State) -> Result<(), Vec<Index>>
fn cdcl_internal(cnf: &mut NormalForm, mut state: State) -> Result<State, Vec<Index>> { fn cdcl_internal(cnf: &mut NormalForm, mut state: State) -> Result<State, Vec<Index>> {
unit_propagate(cnf, &mut state)?; unit_propagate(cnf, &mut state)?;
dbg!(&state); let l = match state.get_arbitrary_literal() {
Some(l) => l,
if state.is_complete() { None => return Ok(state),
return Ok(state); };
}
let l = state.get_arbitrary_literal().unwrap();
let mut state_clone = state.clone(); let mut state_clone = state.clone();
state_clone.add_literal_arbitrary(l); state_clone.add_literal_arbitrary(l);
match cdcl_internal(cnf, state_clone) { match cdcl_internal(cnf, state_clone) {
Ok(_) => todo!(), Ok(s) => Ok(s),
Err(_) => todo!(), Err(c) => {
}; let count_unknown_literals =
c.iter().filter(|&&i| !state.is_unknown_literal(i)).count();
let mut state_clone = state.clone(); if count_unknown_literals >= 2 || (count_unknown_literals == c.len()) {
state_clone.add_literal_arbitrary(-l); cnf.add_clause(&c);
match cdcl_internal(cnf, state_clone) { cdcl_internal(cnf, state)
Ok(_) => todo!(), } else {
Err(_) => todo!(), Err(c)
}; }
}
Ok(state) }
} }
pub fn cdcl(mut cnf: &mut NormalForm) -> Option<Vec<Index>> { pub fn cdcl(cnf: &mut NormalForm) -> Option<Vec<Index>> {
let num_literals = cnf.get_num_literals(); let num_literals = cnf.get_num_literals();
match cdcl_internal(&mut cnf, State::new(num_literals)) { match cdcl_internal(cnf, State::new(num_literals)) {
Ok(state) => { Ok(state) => {
if state.is_complete() { if state.is_complete() {
Some(state.get_solution()) Some(state.get_solution())