Lucas Stadler лет назад: 10
Родитель
Сommit
4fdf121d23
1 измененных файлов с 12 добавлено и 10 удалено
  1. 12 10
      rust/solve/src/dpll.rs

+ 12 - 10
rust/solve/src/dpll.rs

128
}
128
}
129
129
130
pub fn dpll(clauses: Vec<Clause>) -> Option<BoundVars> {
130
pub fn dpll(clauses: Vec<Clause>) -> Option<BoundVars> {
131
    fn dpll_inner(stack: &mut Vec<(Var, BoundVars)>, vars: &mut BoundVars, clauses: Vec<Clause>) -> Option<BoundVars> {
131
    let stack: &mut Vec<(Var, BoundVars)> = &mut Vec::new();
132
    let mut vars = &mut empty_vars();
133
    
134
    loop {
132
        if clauses.iter().all(|c| is_clause_satisfied(&vars, c.clone())) { // all clauses satisfied, success
135
        if clauses.iter().all(|c| is_clause_satisfied(&vars, c.clone())) { // all clauses satisfied, success
133
            Some(vars.clone())
136
            return Some(vars.clone())
134
        } else if clauses.iter().any(|c| is_clause_conflict(&vars, c.clone())) { // a conflict exists, backtrack
137
        } else if clauses.iter().any(|c| is_clause_conflict(&vars, c.clone())) { // a conflict exists, backtrack
135
            match stack.pop() {
138
            match stack.pop() {
136
                None => None, // nothing to backtrack, no solution found
139
                None => return None, // nothing to backtrack, no solution found
137
                Some((v, b)) => {
140
                Some((v, b)) => {
138
                    let bv = &mut b.clone();
139
                    bv.insert(v);
140
                    dpll_inner(stack, bv, clauses)
141
                    vars.clone_from(&b);
142
                    vars.insert(v);
141
                }
143
                }
142
            }
144
            }
143
        } else if clauses.iter().any(|c| is_clause_unit(&vars, c.clone())) { // a unit clause exists, propagate
145
        } else if clauses.iter().any(|c| is_clause_unit(&vars, c.clone())) { // a unit clause exists, propagate
145
            let clause = cs.iter().find(|&c| is_clause_unit(&vars, c.clone())).unwrap();
147
            let clause = cs.iter().find(|&c| is_clause_unit(&vars, c.clone())).unwrap();
146
            let unknown = *clause.iter().find(|&v| is_unknown(&vars, *v)).unwrap();
148
            let unknown = *clause.iter().find(|&v| is_unknown(&vars, *v)).unwrap();
147
            vars.insert(unknown);
149
            vars.insert(unknown);
148
            dpll_inner(stack, vars, clauses)
149
        } else { // none of the above, decide (guess) an unknown variable
150
        } else { // none of the above, decide (guess) an unknown variable
150
            let mut unknown: Var = 0;
151
            let mut unknown: Var = 0;
151
            for c in clauses.clone() {
152
            for c in clauses.clone() {
155
                        break;
156
                        break;
156
                    }
157
                    }
157
                }
158
                }
159
                
160
                if unknown != 0 {
161
                    break;
162
                }
158
            }
163
            }
159
            assert!(unknown != 0);
164
            assert!(unknown != 0);
160
            stack.push((unknown, vars.clone()));
165
            stack.push((unknown, vars.clone()));
161
            vars.insert(-unknown);
166
            vars.insert(-unknown);
162
            dpll_inner(stack, vars, clauses)
163
        }
167
        }
164
    }
168
    }
165
166
    dpll_inner(&mut Vec::new(), &mut empty_vars(), clauses)
167
}
169
}
168
170
169
#[test]
171
#[test]