clang: lib/Analysis/FlowSensitive/CNFFormula.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

14#include "llvm/ADT/DenseSet.h"

15

16#include

17

20

21namespace {

22

23

24

25

26

27

28

29

30

31

32

33

34struct CNFFormulaBuilder {

35

36 explicit CNFFormulaBuilder(CNFFormula &CNF) : Formula(CNF) {}

37

38

39

40

41

42

43

44

45

46 void addClause(ArrayRef Literals) {

47

48 assert(!Literals.empty() && Literals.size() <= 3);

49

50 llvm::SmallVector Simplified;

51 for (auto L : Literals) {

52 assert(L != NullLit && !llvm::is_contained(Simplified, L));

53 auto X = var(L);

54 if (trueVars.contains(X)) {

56 return;

57 else

58 continue;

59 }

60 if (falseVars.contains(X)) {

62 return;

63 else

64 continue;

65 }

66 Simplified.push_back(L);

67 }

68 if (Simplified.empty()) {

69

70

71 Formula.addClause(Simplified);

72 return;

73 }

74 if (Simplified.size() == 1) {

75

76 const Literal lit = Simplified.front();

79 trueVars.insert(v);

80 else

81 falseVars.insert(v);

82 }

83 Formula.addClause(Simplified);

84 }

85

86

87

88 bool isKnownContradictory() { return Formula.knownContradictory(); }

89

90private:

91 CNFFormula &Formula;

92 llvm::DenseSet trueVars;

93 llvm::DenseSet falseVars;

94};

95

96}

97

99 : LargestVar(LargestVar), KnownContradictory(false) {

100 Clauses.push_back(0);

101 ClauseStarts.push_back(0);

102}

103

105 assert(!llvm::is_contained(lits, NullLit));

106

107 if (lits.empty())

108 KnownContradictory = true;

109

110 const size_t S = Clauses.size();

111 ClauseStarts.push_back(S);

112 llvm::append_range(Clauses, lits);

113}

114

116 llvm::DenseMap<Variable, Atom> &Atomics) {

117

118

119

120

121

122

123

124 llvm::DenseMap<const Formula *, Variable> FormulaToVar;

125

127 {

128 std::queue<const Formula *> UnprocessedFormulas;

129 for (const Formula *F : Formulas)

130 UnprocessedFormulas.push(F);

131 while (!UnprocessedFormulas.empty()) {

133 const Formula *F = UnprocessedFormulas.front();

134 UnprocessedFormulas.pop();

135

136 if (!FormulaToVar.try_emplace(F, Var).second)

137 continue;

138 ++NextVar;

139

141 UnprocessedFormulas.push(Op);

143 Atomics[Var] = F->getAtom();

144 }

145 }

146

147 auto GetVar = [&FormulaToVar](const Formula *F) {

148 auto ValIt = FormulaToVar.find(F);

149 assert(ValIt != FormulaToVar.end());

150 return ValIt->second;

151 };

152

154 std::vector ProcessedSubVals(NextVar, false);

155 CNFFormulaBuilder builder(CNF);

156

157

158

159 for (const Formula *F : Formulas)

160 builder.addClause(posLit(GetVar(F)));

161

162

163

164 std::queue<const Formula *> UnprocessedFormulas;

165 for (const Formula *F : Formulas)

166 UnprocessedFormulas.push(F);

167 while (!UnprocessedFormulas.empty()) {

168 const Formula *F = UnprocessedFormulas.front();

169 UnprocessedFormulas.pop();

170 const Variable Var = GetVar(F);

171

172 if (ProcessedSubVals[Var])

173 continue;

174 ProcessedSubVals[Var] = true;

175

176 switch (F->kind()) {

178 break;

181 break;

185

186 if (LHS == RHS) {

187

188

189

190 builder.addClause({negLit(Var), posLit(LHS)});

191 builder.addClause({posLit(Var), negLit(LHS)});

192 } else {

193

194

195

196 builder.addClause({negLit(Var), posLit(LHS)});

197 builder.addClause({negLit(Var), posLit(RHS)});

199 }

200 break;

201 }

205

206 if (LHS == RHS) {

207

208

209

210 builder.addClause({negLit(Var), posLit(LHS)});

211 builder.addClause({posLit(Var), negLit(LHS)});

212 } else {

213

214

215

217 builder.addClause({posLit(Var), negLit(LHS)});

218 builder.addClause({posLit(Var), negLit(RHS)});

219 }

220 break;

221 }

224

225

226

227

228 builder.addClause({negLit(Var), negLit(Operand)});

229 builder.addClause({posLit(Var), posLit(Operand)});

230 break;

231 }

235

236

237

238

239

240 builder.addClause({posLit(Var), posLit(LHS)});

241 builder.addClause({posLit(Var), negLit(RHS)});

243 break;

244 }

248

249 if (LHS == RHS) {

250

251

252

253 builder.addClause(posLit(Var));

254

255

256 continue;

257 }

258

259

260

261

266 break;

267 }

268 }

269 if (builder.isKnownContradictory()) {

270 return CNF;

271 }

273 UnprocessedFormulas.push(Child);

274 }

275

276

277

278

280 CNFFormulaBuilder FinalBuilder(FinalCNF);

281

282

286 }

287 }

288

289

292 if (FinalBuilder.isKnownContradictory()) {

293 break;

294 }

295 }

296

297

298 return FinalCNF;

299}

300

301}

302}

A boolean formula in 3-CNF (conjunctive normal form with at most 3 literals per clause).

size_t clauseSize(ClauseID C) const

Returns the number of literals in clause C.

CNFFormula(Variable LargestVar)

Definition CNFFormula.cpp:98

llvm::ArrayRef< Literal > clauseLiterals(ClauseID C) const

Returns the literals of clause C.

ClauseID numClauses() const

Returns the number of clauses in the formula.

void addClause(ArrayRef< Literal > lits)

Adds the L1 v ... v Ln clause to the formula.

Definition CNFFormula.cpp:104

ArrayRef< const Formula * > operands() const

@ Equal

True if LHS is false or RHS is true.

@ Implies

True if either LHS or RHS is true.

@ AtomRef

A reference to an atomic boolean variable.

@ Literal

Constant true or false.

@ Or

True if LHS and RHS are both true.

@ And

True if its only operand is false.

Dataflow Directional Tag Classes.

uint32_t ClauseID

Clause identifiers are represented as positive integers.

constexpr Literal posLit(Variable V)

Returns the positive literal V.

constexpr bool isNegLit(Literal L)

Returns whether L is a negative literal.

uint32_t Literal

Literals are represented as positive integers.

uint32_t Variable

Boolean variables are represented as positive integers.

CNFFormula buildCNF(const llvm::ArrayRef< const Formula * > &Formulas, llvm::DenseMap< Variable, Atom > &Atomics)

Converts the conjunction of Vals into a formula in conjunctive normal form where each clause has at l...

Definition CNFFormula.cpp:115

constexpr Literal NullLit

A null literal is used as a placeholder in various data structures and algorithms.

constexpr Variable var(Literal L)

Returns the variable of L.

constexpr Literal negLit(Variable V)

Returns the negative literal !V.

constexpr bool isPosLit(Literal L)

Returns whether L is a positive literal.

The JSON file list parser is used to communicate input to InstallAPI.

const half4 lit(half NDotL, half NDotH, half M)