Quellcode durchsuchen

it says dpll, but i don't believe it yet

Lucas Stadler vor 10 Jahren
Ursprung
Commit
914f3a7877
1 geänderte Dateien mit 45 neuen und 0 gelöschten Zeilen
  1. 45 0
      rust/solve/src/dpll.rs

+ 45 - 0
rust/solve/src/dpll.rs

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