1 module satd.assignment;
2 
3 import satd.cnf;
4 import std.container : redBlackTree, RedBlackTree;
5 import std.range : iota, front, array, empty;
6 import std.array : array;
7 import std.conv : to;
8 import std.algorithm : map, sort;
9 import std.string : format;
10 import std.math : abs;
11 import std.stdio : stderr;
12 
13 debug import std.stdio;
14 
15 public:
16 alias Variable = string;
17 
18 struct Assignment
19 {
20     bool[Literal] _assignment;
21     RedBlackTree!Literal unassigned;
22 
23     this(size_t variableNum)
24     {
25         this.unassigned = redBlackTree!Literal(iota(1, variableNum + 1).array.to!(Literal[]));
26     }
27 
28     this(Assignment rhs)
29     {
30         _assignment = rhs._assignment.dup;
31         unassigned = rhs.unassigned.dup;
32     }
33 
34     void clear()
35     {
36         _assignment.clear();
37     }
38 
39     void assign(Literal literal)
40     {
41         assert(abs(literal) !in this._assignment);
42         this._assignment[abs(literal)] = literal > 0;
43         if (abs(literal) !in unassigned)
44         {
45             debug stderr.writefln("not found: %s", literal);
46         }
47         unassigned.removeKey(abs(literal));
48     }
49 
50     Literal getUnassignedLiteral()
51     {
52         return this.unassigned.array.front;
53     }
54 
55     bool getTruthOfVariable(Literal id)
56     {
57         return this._assignment[id];
58     }
59 
60     string toString() const
61     {
62         return this._assignment.to!string;
63     }
64 
65     void fillUnassignedLiterals()
66     {
67         foreach (literal; unassigned.array)
68         {
69             this.assign(literal);
70         }
71     }
72 
73     string toDIMACSFormat() const
74     {
75         Literal[] arr;
76         foreach (key; _assignment.keys.sort)
77             arr ~= (_assignment[key] ? key : -key);
78         return format("v%( %d%) 0", arr);
79     }
80 }