MLIR: lib/Analysis/Presburger/PresburgerRelation.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

15 #include "llvm/ADT/STLExtras.h"

16 #include "llvm/ADT/SmallBitVector.h"

17 #include "llvm/ADT/SmallVector.h"

18 #include "llvm/Support/LogicalResult.h"

19 #include "llvm/Support/raw_ostream.h"

20 #include

21 #include

22 #include

23 #include

24 #include

25

26 using namespace mlir;

27 using namespace presburger;

28

30 : space(disjunct.getSpaceWithoutLocals()) {

32 }

33

38 disjunct.setSpaceExceptLocals(space);

39 }

40

42 unsigned num) {

44 cs.insertVar(kind, pos, num);

46 }

47

49 unsigned num, VarKind dstKind,

50 unsigned dstPos) {

52 "srcKind/dstKind cannot be local");

53 assert(srcKind != dstKind && "cannot convert variables to the same kind");

55 "invalid range for source variables");

57 "invalid position for destination variables");

58

60

62 disjunct.convertVarKind(srcKind, srcPos, srcPos + num, dstKind, dstPos);

63 }

64

67 }

68

71 }

72

74 assert(index < disjuncts.size() && "index out of bounds!");

76 }

77

78

79

83 }

84

85

86

87

88

91

93 return;

94

97 return;

98 }

100 return;

101

103 return;

106 return;

107 }

108

111 }

112

113

119 return result;

120 }

121

122

126 });

127 }

128

133 return result;

134 }

135

138 }

139

140

141

142

143

144

145

146

150

151

152

154 return *this;

155

157 return set;

158

163 if (!intersection.isEmpty())

165 }

166 }

167 return result;

168 }

169

173 "Range of `this` must be compatible with range of `set`");

174

178 }

179

183 "Domain of `this` must be compatible with range of `set`");

184

189 }

190

195 return result;

196 }

197

202 return result;

203 }

204

207 cs.inverse();

208

211 }

212

214 assert(getSpace().getRangeSpace().isCompatible(

216 "Range of `this` should be compatible with domain of `rel`");

217

224 composition.compose(csB);

225 if (!composition.isEmpty())

227 }

228 }

229 *this = result;

230 }

231

233 assert(getSpace().getDomainSpace().isCompatible(

235 "Domain of `this` should be compatible with domain of `rel`");

236

240 }

241

244 }

245

247 bool isMin) {

253 if (isMin) {

254 s = cs.findSymbolicIntegerLexMin();

256 } else {

257 s = cs.findSymbolicIntegerLexMax();

259 }

261 }

262 return result;

263 }

264

267 }

268

271 }

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

290 "idx out of bounds!");

292 return llvm::to_vector<8>(rel.getInequality(idx));

293

296

297 if (idx % 2 == 0)

298 return llvm::to_vector<8>(eqCoeffs);

300 }

301

304 return *this;

305

306

309 result.unionInPlace(disjunct.computeReprWithOnlyDivLocals());

310 return result;

311 }

312

313

314

315

316

317

318

319

320

321

322

323

324

325

326

327

328

329

330

331

332

333

334

335

336

337

338

339

340

341

342

343

344

350

353

354

355

357

361

362

363

364

365

366 struct Frame {

367

368 unsigned simplexSnapshot;

369

371

373

374

376

377

378 std::optional lastIneqProcessed;

379

380

381 Frame(unsigned simplexSnapshot,

384 std::optional lastIneqProcessed = std::nullopt)

385 : simplexSnapshot(simplexSnapshot), bCounts(bCounts), sI(sI),

386 ineqsToProcess(ineqsToProcess), lastIneqProcessed(lastIneqProcessed) {

387 }

388 };

390

391

392

393 unsigned level = 1;

394 while (level > 0) {

396

398 level = frames.size();

399 continue;

400 }

401

402 if (level > frames.size()) {

403

405

406

408

409

410

411

412

414

415 unsigned initialSnapshot = simplex.getSnapshot();

416

417

418

419

420

422

423

424

425

426

427

430

431

432

437 i < e; ++i) {

438 assert(

439 repr[i] &&

440 "Subtraction is not supported when a representation of the local "

441 "variables of the subtrahend cannot be found!");

442

444 unsigned lb = repr[i].repr.inequalityPair.lowerBoundIdx;

445 unsigned ub = repr[i].repr.inequalityPair.upperBoundIdx;

446

449

450 assert(lb != ub &&

451 "Upper and lower bounds must be different inequalities!");

452 canIgnoreIneq[lb] = true;

453 canIgnoreIneq[ub] = true;

454 } else {

456 "ReprKind isn't inequality so should be equality");

457

458

459

460

461

462

463

464

465

466

467

468

469

470

471

472

479 }

480 }

481

483 unsigned numLocalsAdded =

486

487 unsigned snapshotBeforeIntersect = simplex.getSnapshot();

489

491

492

493

495 simplex.rollback(initialSnapshot);

496

497

498

499

500

501 frames.emplace_back(Frame{initialSnapshot, initBCounts, sI});

502 ++level;

503 continue;

504 }

505

506

507 unsigned totalNewSimplexInequalities =

509

510

511

512

513

514

515

516

517

518

519

520

521

522 simplex.detectRedundant(offset, totalNewSimplexInequalities);

523 for (unsigned j = 0; j < totalNewSimplexInequalities; j++)

525 simplex.rollback(snapshotBeforeIntersect);

526

528 ineqsToProcess.reserve(totalNewSimplexInequalities);

529 for (unsigned i = 0; i < totalNewSimplexInequalities; ++i)

530 if (!canIgnoreIneq[i])

531 ineqsToProcess.emplace_back(i);

532

533 if (ineqsToProcess.empty()) {

534

535 level = frames.size();

536 continue;

537 }

538

539 unsigned simplexSnapshot = simplex.getSnapshot();

541 frames.emplace_back(Frame{simplexSnapshot, bCounts, sI, ineqsToProcess});

542

543

544 }

545

546

547

548

549 if (level == frames.size()) {

550 Frame &frame = frames.back();

551 if (frame.lastIneqProcessed) {

552

553

554

555

556

557

558

559 simplex.rollback(frame.simplexSnapshot);

565 }

566

567 if (frame.ineqsToProcess.empty()) {

568

569 frames.pop_back();

570 level = frames.size();

571 continue;

572 }

573

574

576 frame.simplexSnapshot = simplex.getSnapshot();

577

578 unsigned idx = frame.ineqsToProcess.back();

583

584 frame.ineqsToProcess.pop_back();

585 frame.lastIneqProcessed = idx;

586 ++level;

587 continue;

588 }

589 }

590

591

593

594 return result;

595 }

596

597

600 }

601

602

603

608

609

610

612 return result;

613

614

617 return result;

618 }

619

620

621

622

625 }

626

627

631 }

632

635 return false;

636

638 return false;

639

640

641

642 for (unsigned int i = 0, n = getNumDisjuncts(); i < n; ++i) {

644 return false;

645 }

646 return true;

647 }

648

649

650

651

652

655 if (disjunct.getNumConstraints() == 0)

656 return true;

657 }

658 return false;

659 }

660

663 }

664

665

668 }

669

670

671

673

675 }

676

679

682 disjunct.findIntegerSample()) {

683 sample = std::move(*opt);

684 return true;

685 }

686 }

687 return false;

688 }

689

691 assert(getNumSymbolVars() == 0 && "Symbols are not yet supported!");

692

693

694 DynamicAPInt result(0);

696 std::optional volume = disjunct.computeVolume();

697 if (!volume)

698 return {};

699 result += *volume;

700 }

701 return result;

702 }

703

704

705

706

707

708

709

711

712 public:

713

715

716

718

719 private:

720

722

723

724

726

728

729

730

732

733

734

737

740

741

742

743

745

746

747

748

749 void addCoalescedDisjunct(unsigned i, unsigned j,

751

752

753

754

755

756

757

758

759

760

761

762

763 LogicalResult coalescePairCutCase(unsigned i, unsigned j);

764

765

766

767

769

770

771

772

773

775

776

777

778 void eraseDisjunct(unsigned i);

779

780

781

782

783

784

785 LogicalResult coalescePair(unsigned i, unsigned j);

786 };

787

788

789

791

793

795

796 for (unsigned i = 0; i < disjuncts.size();) {

797 disjuncts[i].removeRedundantConstraints();

798 Simplex simp(disjuncts[i]);

800 disjuncts[i] = disjuncts[disjuncts.size() - 1];

801 disjuncts.pop_back();

802 continue;

803 }

804 ++i;

805 simplices.emplace_back(simp);

806 }

807 }

808

809

811

812

813

814

815 for (unsigned i = 0; i < disjuncts.size();) {

816

817

818

819 bool broken = false;

820 for (unsigned j = 0, e = disjuncts.size(); j < e; ++j) {

821 negEqs.clear();

822 redundantIneqsA.clear();

823 redundantIneqsB.clear();

824 cuttingIneqsA.clear();

825 cuttingIneqsB.clear();

826 if (i == j)

827 continue;

828 if (coalescePair(i, j).succeeded()) {

829 broken = true;

830 break;

831 }

832 }

833

834

835

836

837 if (!broken)

838 ++i;

839 }

840

844

845 return newSet;

846 }

847

848

849

850

857 });

858 }

859

860 void SetCoalescer::addCoalescedDisjunct(unsigned i, unsigned j,

862 assert(i != j && "The indices must refer to different disjuncts");

863 unsigned n = disjuncts.size();

864 if (j == n - 1) {

865

866

867

868 disjuncts[i] = disjuncts[n - 2];

869 disjuncts.pop_back();

870 disjuncts[n - 2] = disjunct;

871 disjuncts[n - 2].removeRedundantConstraints();

872

873 simplices[i] = simplices[n - 2];

874 simplices.pop_back();

875 simplices[n - 2] = Simplex(disjuncts[n - 2]);

876

877 } else {

878

879

880

881

882

883 disjuncts[i] = disjuncts[n - 1];

884 disjuncts[j] = disjuncts[n - 2];

885 disjuncts.pop_back();

886 disjuncts[n - 2] = disjunct;

887 disjuncts[n - 2].removeRedundantConstraints();

888

889 simplices[i] = simplices[n - 1];

890 simplices[j] = simplices[n - 2];

891 simplices.pop_back();

892 simplices[n - 2] = Simplex(disjuncts[n - 2]);

893 }

894 }

895

896

897

898

899

900

901

902

903

904

905

906

907

908

909

910

911

912 LogicalResult SetCoalescer::coalescePairCutCase(unsigned i, unsigned j) {

913

914

915 Simplex &simp = simplices[i];

918 return !isFacetContained(curr, simp);

919 }))

920 return failure();

922

924 newSet.addInequality(curr);

925

927 newSet.addInequality(curr);

928

929 addCoalescedDisjunct(i, j, newSet);

930 return success();

931 }

932

936 if (type == Simplex::IneqType::Redundant)

937 redundantIneqsB.emplace_back(ineq);

938 else if (type == Simplex::IneqType::Cut)

939 cuttingIneqsB.emplace_back(ineq);

940 else

941 return failure();

942 return success();

943 }

944

947 if (typeInequality(eq, simp).failed())

948 return failure();

951 return typeInequality(inv, simp);

952 }

953

954 void SetCoalescer::eraseDisjunct(unsigned i) {

955 assert(simplices.size() == disjuncts.size() &&

956 "simplices and disjuncts must be equally as long");

957 disjuncts[i] = disjuncts.back();

958 disjuncts.pop_back();

959 simplices[i] = simplices.back();

960 simplices.pop_back();

961 }

962

963 LogicalResult SetCoalescer::coalescePair(unsigned i, unsigned j) {

964

967

968

969

971 return failure();

972 Simplex &simpA = simplices[i];

973 Simplex &simpB = simplices[j];

974

975

976

977

978

979

981 if (typeInequality(a.getInequality(k), simpB).failed())

982 return failure();

983

985 if (typeEquality(a.getEquality(k), simpB).failed())

986 return failure();

987

988 std::swap(redundantIneqsA, redundantIneqsB);

989 std::swap(cuttingIneqsA, cuttingIneqsB);

990

992 if (typeInequality(b.getInequality(k), simpA).failed())

993 return failure();

994

996 if (typeEquality(b.getEquality(k), simpA).failed())

997 return failure();

998

999

1000

1001 if (cuttingIneqsA.empty()) {

1002 eraseDisjunct(j);

1003 return success();

1004 }

1005

1006

1007 if (coalescePairCutCase(i, j).succeeded())

1008 return success();

1009

1010

1011 std::swap(redundantIneqsA, redundantIneqsB);

1012 std::swap(cuttingIneqsA, cuttingIneqsB);

1013

1014

1015

1016 if (cuttingIneqsA.empty()) {

1017 eraseDisjunct(i);

1018 return success();

1019 }

1020

1021

1022 return coalescePairCutCase(j, i);

1023 }

1024

1027 }

1028

1032 });

1033 }

1034

1042 }

1043 return result;

1044 }

1045

1049 });

1050 }

1051

1053 os << "Number of Disjuncts: " << getNumDisjuncts() << "\n";

1055 disjunct.print(os);

1056 os << '\n';

1057 }

1058 }

1059

1061

1065 return result;

1066 }

1067

1070 }

1071

1074

1077

1080 }

1081

1084 }

1085

1088 }

1089

1092 }

1093

1096 }

union mlir::linalg::@1203::ArityGroupAndKind::Kind kind

static SymbolicLexOpt findSymbolicIntegerLexOpt(const PresburgerRelation &rel, bool isMin)

static SmallVector< DynamicAPInt, 8 > getIneqCoeffsFromIdx(const IntegerRelation &rel, unsigned idx)

Return the coefficients of the ineq in rel specified by idx.

static PresburgerRelation getSetDifference(IntegerRelation b, const PresburgerRelation &s)

Return the set difference b \ s.

Class storing division representation of local variables of a constraint system.

DynamicAPInt & getDenom(unsigned i)

MutableArrayRef< DynamicAPInt > getDividend(unsigned i)

An IntegerPolyhedron represents the set of points from a PresburgerSpace that satisfy a list of affin...

static IntegerPolyhedron getUniverse(const PresburgerSpace &space)

Return a system with no constraints, i.e., one which is satisfied by all points.

An IntegerRelation represents the set of points from a PresburgerSpace that satisfy a list of affine ...

void compose(const IntegerRelation &rel)

Let the relation this be R1, and the relation rel be R2.

PresburgerSpace getSpaceWithoutLocals() const

Returns a copy of the space without locals.

void truncate(const CountsSnapshot &counts)

CountsSnapshot getCounts() const

std::optional< SmallVector< DynamicAPInt, 8 > > containsPointNoLocal(ArrayRef< DynamicAPInt > point) const

Given the values of non-local vars, return a satisfying assignment to the local if one exists,...

ArrayRef< DynamicAPInt > getInequality(unsigned idx) const

bool isEmptyByGCDTest() const

Runs the GCD test on all equality constraints.

void simplify()

Simplify the constraint system by removing canonicalizing constraints and removing redundant constrai...

void removeDuplicateDivs()

void print(raw_ostream &os) const

bool isIntegerEmpty() const

Returns true if the set of constraints is found to have no solution, false if a solution exists.

IntegerRelation intersect(IntegerRelation other) const

Return the intersection of the two relations.

static IntegerRelation getUniverse(const PresburgerSpace &space)

Return a system with no constraints, i.e., one which is satisfied by all points.

unsigned getNumLocalVars() const

bool isObviouslyEmpty() const

Performs GCD checks and invalid constraint checks.

bool isEmpty() const

Checks for emptiness by performing variable elimination on all variables, running the GCD test on eac...

DivisionRepr getLocalReprs(std::vector< MaybeLocalRepr > *repr=nullptr) const

Returns a DivisonRepr representing the division representation of local variables in the constraint s...

bool hasOnlyDivLocals() const

Check whether all local ids have a division representation.

void addInequality(ArrayRef< DynamicAPInt > inEq)

Adds an inequality (>= 0) from the coefficients specified in inEq.

unsigned mergeLocalVars(IntegerRelation &other)

Adds additional local vars to the sets such that they both have the union of the local vars in each s...

ArrayRef< DynamicAPInt > getEquality(unsigned idx) const

unsigned getNumInequalities() const

const PresburgerSpace & getSpace() const

Returns a reference to the underlying space.

unsigned getNumEqualities() const

unsigned getVarKindOffset(VarKind kind) const

Return the index at which the specified kind of vars starts.

This class represents a piece-wise MultiAffineFunction.

PWMAFunction unionLexMax(const PWMAFunction &func)

PWMAFunction unionLexMin(const PWMAFunction &func)

Return a function defined on the union of the domains of this and func, such that when only one of th...

A PresburgerRelation represents a union of IntegerRelations that live in the same PresburgerSpace wit...

unsigned getNumSymbolVars() const

void setSpace(const PresburgerSpace &oSpace)

Set the space to oSpace.

unsigned getNumRangeVars() const

PresburgerRelation intersect(const PresburgerRelation &set) const

Return the intersection of this set and the given set.

bool hasOnlyDivLocals() const

Check whether all local ids in all disjuncts have a div representation.

bool containsPoint(ArrayRef< DynamicAPInt > point) const

Return true if the set contains the given point, and false otherwise.

PresburgerRelation subtract(const PresburgerRelation &set) const

Return the set difference of this set and the given set, i.e., return this \ set.

friend class SetCoalescer

PresburgerRelation(const IntegerRelation &disjunct)

PresburgerSet getRangeSet() const

Return a set corresponding to the range of the relation.

bool isConvexNoLocals() const

Return true if the set is consist of a single disjunct, without any local variables,...

PresburgerRelation computeReprWithOnlyDivLocals() const

Compute an equivalent representation of the same relation, such that all local ids in all disjuncts h...

bool isSubsetOf(const PresburgerRelation &set) const

Return true if this set is a subset of the given set, and false otherwise.

unsigned getNumDomainVars() const

bool isIntegerEmpty() const

Return true if all the sets in the union are known to be integer empty false otherwise.

PresburgerRelation intersectRange(const PresburgerSet &set) const

Return the range intersection of the given set with this relation.

void unionInPlace(const IntegerRelation &disjunct)

Mutate this set, turning it into the union of this set and the given disjunct.

std::optional< DynamicAPInt > computeVolume() const

Compute an overapproximation of the number of integer points in the disjunct.

void convertVarKind(VarKind srcKind, unsigned srcPos, unsigned num, VarKind dstKind, unsigned dstPos)

Converts variables of the specified kind in the column range [srcPos, srcPos + num) to variables of t...

PresburgerRelation intersectDomain(const PresburgerSet &set) const

Return the domain intersection of the given set with this relation.

bool isEqual(const PresburgerRelation &set) const

Return true if this set is equal to the given set, and false otherwise.

static PresburgerRelation getEmpty(const PresburgerSpace &space)

Return an empty set of the specified type that contains no points.

void applyDomain(const PresburgerRelation &rel)

Apply the domain of given relation rel to this relation.

unsigned getNumDisjuncts() const

Return the number of disjuncts in the union.

void applyRange(const PresburgerRelation &rel)

Same as compose, provided for uniformity with applyDomain.

bool findIntegerSample(SmallVectorImpl< DynamicAPInt > &sample)

Find an integer sample from the given set.

bool isObviouslyEmpty() const

Return true if there is no disjunct, false otherwise.

bool isObviouslyUniverse() const

Return true if the set is known to have one unconstrained disjunct, false otherwise.

PresburgerRelation coalesce() const

Simplifies the representation of a PresburgerRelation.

static PresburgerRelation getUniverse(const PresburgerSpace &space)

Return a universe set of the specified type that contains all points.

const IntegerRelation & getDisjunct(unsigned index) const

Return the disjunct at the specified index.

ArrayRef< IntegerRelation > getAllDisjuncts() const

Return a reference to the list of disjuncts.

SmallVector< IntegerRelation, 2 > disjuncts

The list of disjuncts that this set is the union of.

PresburgerRelation simplify() const

Simplify each disjunct, canonicalizing each disjunct and removing redundencies.

void compose(const PresburgerRelation &rel)

Compose this relation with the given relation rel in-place.

const PresburgerSpace & getSpace() const

void print(raw_ostream &os) const

Print the set's internal state.

void inverse()

Invert the relation, i.e.

PresburgerSet getDomainSet() const

Return a set corresponding to the domain of the relation.

SymbolicLexOpt findSymbolicIntegerLexMax() const

Compute the symbolic integer lexmax of the relation, i.e.

void insertVarInPlace(VarKind kind, unsigned pos, unsigned num=1)

PresburgerRelation unionSet(const PresburgerRelation &set) const

Return the union of this set and the given set.

bool isObviouslyEqual(const PresburgerRelation &set) const

Perform a quick equality check on this and other.

SymbolicLexOpt findSymbolicIntegerLexMin() const

Compute the symbolic integer lexmin of the relation, i.e.

bool isFullDim() const

Return whether the given PresburgerRelation is full-dimensional.

PresburgerRelation complement() const

Return the complement of this set.

PresburgerSet intersect(const PresburgerRelation &set) const

PresburgerSet(const IntegerPolyhedron &disjunct)

Create a set from a relation.

PresburgerSet unionSet(const PresburgerRelation &set) const

These operations are the same as the ones in PresburgeRelation, they just forward the arguement and r...

PresburgerSet subtract(const PresburgerRelation &set) const

static PresburgerSet getEmpty(const PresburgerSpace &space)

Return an empty set of the specified type that contains no points.

static PresburgerSet getUniverse(const PresburgerSpace &space)

Return a universe set of the specified type that contains all points.

PresburgerSet coalesce() const

PresburgerSet complement() const

PresburgerSpace is the space of all possible values of a tuple of integer valued variables/variables.

PresburgerSpace getRangeSpace() const

unsigned getNumVarKind(VarKind kind) const

Get the number of vars of the specified kind.

PresburgerSpace getDomainSpace() const

Get the domain/range space of this space.

void convertVarKind(VarKind srcKind, unsigned srcPos, unsigned num, VarKind dstKind, unsigned dstPos)

Converts variables of the specified kind in the column range [srcPos, srcPos + num) to variables of t...

unsigned getNumLocalVars() const

bool isCompatible(const PresburgerSpace &other) const

Returns true if both the spaces are compatible i.e.

static PresburgerSpace getRelationSpace(unsigned numDomain=0, unsigned numRange=0, unsigned numSymbols=0, unsigned numLocals=0)

unsigned insertVar(VarKind kind, unsigned pos, unsigned num=1)

Insert num variables of the specified kind at position pos.

bool isEmpty() const

Returns true if the tableau is empty (has conflicting constraints), false otherwise.

void appendVariable(unsigned count=1)

Add new variables to the end of the list of variables.

void intersectIntegerRelation(const IntegerRelation &rel)

Add all the constraints from the given IntegerRelation.

unsigned getSnapshot() const

Get a snapshot of the current state.

void addEquality(ArrayRef< DynamicAPInt > coeffs)

Add an equality to the tableau.

void rollback(unsigned snapshot)

Rollback to a snapshot. This invalidates all later snapshots.

unsigned getNumConstraints() const

Returns the number of constraints in the tableau.

Takes a snapshot of the simplex state on construction and rolls back to the snapshot on destruction.

The Simplex class uses the Normal pivot rule and supports integer emptiness checks as well as detecti...

bool isMarkedRedundant(unsigned constraintIndex) const

Returns whether the specified constraint has been marked as redundant.

IneqType findIneqType(ArrayRef< DynamicAPInt > coeffs)

Returns the type of the inequality with coefficients coeffs.

bool isRedundantInequality(ArrayRef< DynamicAPInt > coeffs)

Check if the specified inequality already holds in the polytope.

void addInequality(ArrayRef< DynamicAPInt > coeffs) final

Add an inequality to the tableau.

void detectRedundant(unsigned offset, unsigned count)

Finds a subset of constraints that is redundant, i.e., such that the set of solutions does not change...

The SetCoalescer class contains all functionality concerning the coalesce heuristic.

SetCoalescer(const PresburgerRelation &s)

Construct a SetCoalescer from a PresburgerSet.

PresburgerRelation coalesce()

Simplifies the representation of a PresburgerSet.

SmallVector< DynamicAPInt, 8 > getNegatedCoeffs(ArrayRef< DynamicAPInt > coeffs)

Return coeffs with all the elements negated.

SmallVector< DynamicAPInt, 8 > getDivUpperBound(ArrayRef< DynamicAPInt > dividend, const DynamicAPInt &divisor, unsigned localVarIdx)

If q is defined to be equal to expr floordiv d, this equivalent to saying that q is an integer and q ...

SmallVector< DynamicAPInt, 8 > getDivLowerBound(ArrayRef< DynamicAPInt > dividend, const DynamicAPInt &divisor, unsigned localVarIdx)

SmallVector< DynamicAPInt, 8 > getComplementIneq(ArrayRef< DynamicAPInt > ineq)

Return the complement of the given inequality.

Include the generated interface declarations.

The struct CountsSnapshot stores the count of each VarKind, and also of each constraint type.

const PresburgerSpace & getSpace() const

Represents the result of a symbolic lexicographic optimization computation.

PWMAFunction lexopt

This maps assignments of symbols to the corresponding lexopt.

PresburgerSet unboundedDomain

Contains all assignments to the symbols that made the lexopt unbounded.

Eliminates variable at the specified position using Fourier-Motzkin variable elimination.