Pārlūkot izejas kodu

move cnf code to a separate file

Lucas Stadler 10 gadi atpakaļ
vecāks
revīzija
406918f813
2 mainītis faili ar 69 papildinājumiem un 70 dzēšanām
  1. 68 0
      rust/dpll/src/cnf.rs
  2. 1 70
      rust/dpll/src/main.rs

+ 68 - 0
rust/dpll/src/cnf.rs

@ -0,0 +1,68 @@
1
 pub struct CNF {
2
	  pub num_vars: u32,
3
	  pub num_clauses: u32,
4
	  pub clauses: Vec<Vec<i32>>
5
 }
6
7
 /// Parses a CNF formula in DIMAC format.
8
 ///
9
 /// # Examples
10
 ///
11
 /// A simple example for a formula in DIMAC format is below:
12
 ///
13
 /// ```text
14
 /// p cnf 5 3
15
 /// 1 2 3 0
16
 /// -2 3 4 0
17
 /// 4 5 0
18
 /// ```
19
 ///
20
 /// The above represents a formula with 5 variables and 3 clauses.  The first
21
 /// line specifies this.  Each following line represents a clause with possibly
22
 /// negated literals, terminated by 0 and a newline.
23
 pub fn parse_dimac(dimac: &str) -> Result<CNF, String> {
24
	  let mut lines = dimac.lines();
25
	  let mut num_vars;
26
	  let mut num_clauses;
27
	  
28
	  match lines.next() {
29
			None => { return Err("expected cnf description".to_string()) }
30
			Some(line) => {
31
				 let desc: Vec<&str> = line.split(" ").collect();
32
				 if desc.len() != 4 || desc[0] != "p" || desc[1] != "cnf" {
33
					  return Err("cnf description must be of the form 'p cnf <num vars> <num clauses>'".to_string())
34
				 }
35
				 match desc[2].parse::<u32>() {
36
					  Ok(n) => { num_vars = n }
37
					  Err(e) => { return Err(format!("<num vars> must be a positive integer: {}", e)) }
38
				 }
39
				 
40
				 match desc[3].parse::<u32>() {
41
					  Ok(n) => { num_clauses = n }
42
					  Err(e) => { return Err(format!("<num clauses> must be a positive integer: {}", e)) }
43
				 }
44
			}
45
	  }
46
47
	  let clause_lines: Vec<&str> = lines.collect();
48
	  if clause_lines.len() as u32 != num_clauses {
49
			return Err(format!("Wrong number of clauses: Expected {}, but got {}", num_clauses, clause_lines.len()))
50
	  }
51
52
	  let mut clauses: Vec<Vec<i32>> = Vec::with_capacity(num_clauses as usize);
53
	  for clause_line in clause_lines {
54
			let mut vars: Vec<i32> = clause_line.split(" ").map(|x| x.parse::<i32>().unwrap()).collect();
55
			if vars.is_empty() {
56
				 return Err("empty clause".to_string())
57
			}
58
			if vars[vars.len()-1] != 0 {
59
				 return Err("clause must be terminated with 0".to_string())
60
			}
61
			let l = vars.len();
62
			vars.truncate(l - 1);
63
			clauses.push(vars)
64
	  }
65
66
	  let cnf = CNF { num_vars: num_vars, num_clauses: num_clauses, clauses: clauses };
67
	  return Ok(cnf)
68
 }

+ 1 - 70
rust/dpll/src/main.rs

@ -10,76 +10,7 @@
10 10
use std::io;
11 11
use std::io::Read;
12 12
13
mod cnf {
14
    pub struct CNF {
15
        pub num_vars: u32,
16
        pub num_clauses: u32,
17
        pub clauses: Vec<Vec<i32>>
18
    }
19
20
    /// Parses a CNF formula in DIMAC format.
21
    ///
22
    /// # Examples
23
    ///
24
    /// A simple example for a formula in DIMAC format is below:
25
    ///
26
    /// ```text
27
    /// p cnf 5 3
28
    /// 1 2 3 0
29
    /// -2 3 4 0
30
    /// 4 5 0
31
    /// ```
32
    ///
33
    /// The above represents a formula with 5 variables and 3 clauses.  The first
34
    /// line specifies this.  Each following line represents a clause with possibly
35
    /// negated literals, terminated by 0 and a newline.
36
    pub fn parse_dimac(dimac: &str) -> Result<CNF, String> {
37
        let mut lines = dimac.lines();
38
        let mut num_vars;
39
        let mut num_clauses;
40
        
41
        match lines.next() {
42
            None => { return Err("expected cnf description".to_string()) }
43
            Some(line) => {
44
                let desc: Vec<&str> = line.split(" ").collect();
45
                if desc.len() != 4 || desc[0] != "p" || desc[1] != "cnf" {
46
                    return Err("cnf description must be of the form 'p cnf <num vars> <num clauses>'".to_string())
47
                }
48
                match desc[2].parse::<u32>() {
49
                    Ok(n) => { num_vars = n }
50
                    Err(e) => { return Err(format!("<num vars> must be a positive integer: {}", e)) }
51
                }
52
                
53
                match desc[3].parse::<u32>() {
54
                    Ok(n) => { num_clauses = n }
55
                    Err(e) => { return Err(format!("<num clauses> must be a positive integer: {}", e)) }
56
                }
57
            }
58
        }
59
60
        let clause_lines: Vec<&str> = lines.collect();
61
        if clause_lines.len() as u32 != num_clauses {
62
            return Err(format!("Wrong number of clauses: Expected {}, but got {}", num_clauses, clause_lines.len()))
63
        }
64
65
        let mut clauses: Vec<Vec<i32>> = Vec::with_capacity(num_clauses as usize);
66
        for clause_line in clause_lines {
67
            let mut vars: Vec<i32> = clause_line.split(" ").map(|x| x.parse::<i32>().unwrap()).collect();
68
            if vars.is_empty() {
69
                return Err("empty clause".to_string())
70
            }
71
            if vars[vars.len()-1] != 0 {
72
                return Err("clause must be terminated with 0".to_string())
73
            }
74
            let l = vars.len();
75
            vars.truncate(l - 1);
76
            clauses.push(vars)
77
        }
78
79
        let cnf = CNF { num_vars: num_vars, num_clauses: num_clauses, clauses: clauses };
80
        return Ok(cnf)
81
    }
82
}
13
mod cnf;
83 14
84 15
fn main() {
85 16
    let input: &mut String = &mut String::new();