1/***********************************************************************************[SolverTypes.h]
2MiniSat -- Copyright (c) 2003-2005, Niklas Een, Niklas Sorensson
3
4Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
5associated documentation files (the "Software"), to deal in the Software without restriction,
6including without limitation the rights to use, copy, modify, merge, publish, distribute,
7sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
8furnished to do so, subject to the following conditions:
9
10The above copyright notice and this permission notice shall be included in all copies or
11substantial portions of the Software.
12
13THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
14NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
16DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
17OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
18**************************************************************************************************/
19
20
21#ifndef SolverTypes_h
22#define SolverTypes_h
23
24#ifndef Global_h
25#include "Global.h"
26#endif
27
28
29//=================================================================================================
30// Variables, literals, clause IDs:
31
32
33// NOTE! Variables are just integers. No abstraction here. They should be chosen from 0..N,
34// so that they can be used as array indices.
35
36typedef int Var;
37#define var_Undef (-1)
38
39
40class Lit {
41    int     x;
42public:
43    Lit() : x(2*var_Undef) {}   // (lit_Undef)
44    explicit Lit(Var var, bool sgn = false) : x((var+var) + (int)sgn) {}
45    friend Lit operator ~ (Lit p);
46
47    friend bool sign  (Lit p);
48    friend int  var   (Lit p);
49    friend int  index (Lit p);
50    friend Lit  toLit (int i);
51    friend Lit  unsign(Lit p);
52    friend Lit  id    (Lit p, bool sgn);
53
54    friend bool operator == (Lit p, Lit q);
55    friend bool operator <  (Lit p, Lit q);
56
57    uint hash() const { return (uint)x; }
58};
59inline Lit operator ~ (Lit p) { Lit q; q.x = p.x ^ 1; return q; }
60inline bool sign  (Lit p) { return p.x & 1; }
61inline int  var   (Lit p) { return p.x >> 1; }
62inline int  index (Lit p) { return p.x; }                // A "toInt" method that guarantees small, positive integers suitable for array indexing.
63inline Lit  toLit (int i) { Lit p; p.x = i; return p; }  // Inverse of 'index()'.
64inline Lit  unsign(Lit p) { Lit q; q.x = p.x & ~1; return q; }
65inline Lit  id    (Lit p, bool sgn) { Lit q; q.x = p.x ^ (int)sgn; return q; }
66inline bool operator == (Lit p, Lit q) { return index(p) == index(q); }
67inline bool operator <  (Lit p, Lit q) { return index(p)  < index(q); }  // '<' guarantees that p, ~p are adjacent in the ordering.
68
69const Lit lit_Undef(var_Undef, false);  // }- Useful special constants.
70const Lit lit_Error(var_Undef, true );  // }
71
72inline int toDimacs(Lit p) { return sign(p) ? -var(p) - 1 : var(p) + 1; }
73
74
75//=================================================================================================
76// Clause -- a simple class for representing a clause:
77
78
79typedef int ClauseId;     // (might have to use uint64 one day...)
80const   int ClauseId_NULL = INT_MIN;
81
82//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
83
84class Clause {
85    uint    size_learnt;
86    Lit     data[1];
87public:
88    // NOTE: This constructor cannot be used directly (doesn't allocate enough memory).
89    Clause(bool learnt, const vec<Lit>& ps, ClauseId id_ = ClauseId_NULL) {
90        size_learnt = (ps.size() << 1) | (int)learnt;
91        for (int i = 0; i < ps.size(); i++) data[i] = ps[i];
92        if (learnt) activity() = 0;
93        if (id_ != ClauseId_NULL) id() = id_; }
94
95    // -- use this function instead:
96    friend Clause* Clause_new(bool, const vec<Lit>&, ClauseId);
97
98    int       size        ()      const { return size_learnt >> 1; }
99    bool      learnt      ()      const { return size_learnt & 1; }
100    Lit       operator [] (int i) const { return data[i]; }
101    Lit&      operator [] (int i)       { return data[i]; }
102    float&    activity    ()      const { return *((float*)&data[size()]); }
103    ClauseId& id          ()      const { return *((ClauseId*)&data[size() + (int)learnt()]); }
104};
105
106inline Clause* Clause_new(bool learnt, const vec<Lit>& ps, ClauseId id = ClauseId_NULL) {
107    assert(sizeof(Lit)      == sizeof(uint));
108    assert(sizeof(float)    == sizeof(uint));
109    assert(sizeof(ClauseId) == sizeof(uint));
110    void*   mem = xmalloc<char>(sizeof(Clause) + sizeof(uint)*(ps.size() + (int)learnt + (int)(id != ClauseId_NULL)));
111    return new (mem) Clause(learnt, ps, id); }
112
113
114//=================================================================================================
115// GClause -- Generalize clause:
116
117
118// Either a pointer to a clause or a literal.
119class GClause {
120    void*   data;
121    GClause(void* d) : data(d) {}
122public:
123    friend GClause GClause_new(Lit p);
124    friend GClause GClause_new(Clause* c);
125
126    bool        isLit    () const { return ((uintp)data & 1) == 1; }
127    Lit         lit      () const { return toLit(((intp)data) >> 1); }
128    Clause*     clause   () const { return (Clause*)data; }
129    bool        operator == (GClause c) const { return data == c.data; }
130    bool        operator != (GClause c) const { return data != c.data; }
131};
132inline GClause GClause_new(Lit p)     { return GClause((void*)(((intp)index(p) << 1) + 1)); }
133inline GClause GClause_new(Clause* c) { assert(((uintp)c & 1) == 0); return GClause((void*)c); }
134
135#define GClause_NULL GClause_new((Clause*)NULL)
136
137
138//=================================================================================================
139#endif
140