xo

package
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 18, 2021 License: MIT Imports: 13 Imported by: 0

Documentation

Overview

Package xo is the main gini internal package for (single core) sat solving.

Sincerest apologies to newcomers, as successfully editing this package for all but simple incidental changes likely requires a fairly deep understanding of CDCL sat solvers; this fact is probablly largely unavoidable.

For an introduction to SAT, see The Handbook of satisfiability.

That said, this solver is organised as follows.

Variables and Literals

Variables (type Var) are uint32, starting at offset 1 ending at 2^30 - 1. Each variable can either have value true or false, represented by sign {+1,-1}, or by an associated literal.

Literals (type Lit) are uint32, starting at 2, ending at 2^31 - 1. Literals are either variables or their negation.

Clauses

Clauses are constraints in the form of disjunctions of literals.

Clauses have a complicated representation for efficiency reasons clauses have an underlying data store, (type CDat in cdat.go), which is one big slice of 32bit values, most of which are Lits. A compact header (32bit, type Chd) contains some metadata for each clause.

  • whether the clause is learnt
  • the literal block distance of the clause (number of non deterministic branches it spanned when created, if learnt)
  • an abstraction of the size of the clause
  • "heat", a heuristic score of activity in solving.

Each clause is also associated with a z.C, which is a 32bit offset into the data store slice of lits. This is the identifier for a clause, which can change over time due to clause garbage collection during the solving process.

Each z.C p points to data layed out as follows.

[... Chd lit0 lit1 ... litn LitNull]
         p

Solving

Solving is a depth first search over the (exponential) space of variable assignments. As the search takes place the value of the clauses in the assignment stack may imply other values. For example, if we search for an assignment for variables {x,y}, and we guess x=1, and there is a clause (not(x) or not(y)), then not(y) must be part of any extension of the assignment. Identifying such necessary assignment extensions is called (Boolean) constraint propagation / BCP

During BPC, it is possible to find a clause in which every literal is false. Such a clause is called a "conflict". Also the event of identifying such a clause is called a conflict..

Conflicts are resolved by backtracking and choosing a new branch. Additionally, a new clause is derived which prevents the search from arriving at the same partial assignment, irrespective of the order in which the search applies (at least as long as that clause is kept in the solving process...). Such a clause is called a "learnt" clause and the process of adding such clauses is called "learning".

As conflicts are encountered and new clauses are learned, it becomes necessary to remove learned clauses in such a way as to guarantee progress of the search algorithm. This is because lots of clauses can have a high ratio of irrelevant clauses to the future search over time, and the more clauses managed by the solver, the more expensive BCP becomes.

Since BCP is the bottlneck in the algorithm, some balance must be achieved by removing learned clauses. This is where "compaction" or "clause garbage collection" comes into play. This is implemented in cgc.go and is based on some heuristics from the literature.

This depth first search has the following major components, in term of code organisation.

  • Guess (type Guess, in guess.go) guessing variables and associated values during the search (for example, guessing x=1 in the search above).

  • Trail manages the assignment stack and propagation of constraints.

  • Derive learns new clauses whenever the search reaches a point which cannot be extended because some clause is false. The new clauses prune the future search space more than just backtracking.

Constraint propagation

Constraint propagation is the most optimised and difficult to manage part of the code. It uses "watch lists", which associates 2 literals with every clause (except 1 literal clauses). Whenever one of those literals is falsified in the search, the clause is examined to see whether or not it implies a new value for a variable or if it is false.

Important Heuristics

Variable ordering in Guess is extremely important to solving time. Variables are re-ordered dynamically according to an approximation of their proximity to/involvement with conflicts

Clause Garbage Collection is also extremely important. We use a hyper-aggressive strategy which multiplexes the CGC frequency using the luby series and removes approximately half of the learnted clauses in each CGC.

Variable naming

Gini uses regular succint variable naming where possible to aid in readability and succintness

  • Lit; m,n,o
  • Var: u,v
  • z.C: p,q,r
  • Watch: w -
  • Slices ([]): add an s on the end of underlying type
  • Slice indices: i,j,k
  • Chd: h

Index

Constants

View Source
const (
	CNull z.C = 0
	CInf      = 0xffffffff
)
View Source
const (
	// for each Solve() call don't restart until this many conflicts.
	// good for incremental solving.
	RestartAfter  uint  = 1000
	RestartFactor       = 768
	PropTick      int64 = 20000
	CancelTicks   int64 = 1
)

Variables

This section is empty.

Functions

This section is empty.

Types

type Active added in v1.1.0

type Active struct {
	Free     []z.Lit
	Occs     [][]z.C
	IsActive []bool
	Ms       []z.Lit
}

func (*Active) ActivateWith added in v1.1.0

func (a *Active) ActivateWith(act z.Lit, s *S)

func (*Active) CRemap added in v1.1.0

func (a *Active) CRemap(rlm map[z.C]z.C)

func (*Active) Copy added in v1.1.0

func (a *Active) Copy() *Active

func (*Active) Deactivate added in v1.1.0

func (a *Active) Deactivate(cdb *Cdb, m z.Lit)

func (*Active) Lit added in v1.1.0

func (a *Active) Lit(s *S) z.Lit

type CDat

type CDat struct {
	D      []z.Lit // contains Chds as well, same underlying type
	Len    int
	Cap    int
	ClsLen int
	// contains filtered or unexported fields
}

Type CDat: basic operations for storing all the literals (and Chds) in a CNF

func NewCDat

func NewCDat(cap int) *CDat

The Layout is as follows

Each clause is indexed by a z.C, which is a uint32 index into CDat.D.  The location is
the beginning of the list of literals in the clause, which is terminated by z.LitNull.
Each location is preceded by a Chd giving clause metadata.  Since the underlying type of
Chd and z.Lit are uint32, this is fine.

Rather than allocate lots of bits in the Chd to the size, we only allocate 5 bits (max size
of 31).  For each actual size s, we store

  s & 31

To find the end of a clause at a given location, we iterate through the possible sizes
with the same modulus, which is usually 1 operation.

func (*CDat) AddLits

func (c *CDat) AddLits(hdr Chd, ms []z.Lit) z.C

func AddLits adds literals to the underlying data. The clause header hdr must be consistent.

func (*CDat) Bump

func (c *CDat) Bump(p z.C) bool

Bump increases a score for the clause with location p.

func (*CDat) Chd

func (c *CDat) Chd(loc z.C) Chd

func Chd retrieves the Chd associated with a z.C

func (*CDat) Compact

func (c *CDat) Compact(rm []z.C) (map[z.C]z.C, int)

Compact the storage by removing clauses with locations in rm pre: rm is sorted in ascending z.C order

this just compacts the data and returns a map of the locations which need to be remapped in higher level data structures (watch lists, etc).

the returned map behaves as follows:

1. remap every removed clause in rm to CNull 2. remap every moved clause

func (*CDat) CompactReady

func (c *CDat) CompactReady(nc, nl int) bool

ComactReady returns whether a compaction of the data is ready.

func (*CDat) Copy

func (c *CDat) Copy() *CDat

Copy makes a copy of c.

func (*CDat) CopyTo

func (c *CDat) CopyTo(other *CDat)

func (*CDat) Decay

func (c *CDat) Decay()

func (*CDat) Dimacs

func (c *CDat) Dimacs(w io.Writer) error

func Dimacs writes a dimacs file (no header)

func (*CDat) Forall

func (c *CDat) Forall(f func(i int, p z.C, ms []z.Lit))

Func Forall applies f to every clause in the store.

func (*CDat) Load

func (c *CDat) Load(p z.C, ms []z.Lit) []z.Lit

Function Load loads a clause with location p to the lit slice ms

func (*CDat) Next

func (c *CDat) Next(loc z.C) z.C

compute the next location

func (*CDat) SetChd

func (c *CDat) SetChd(loc z.C, hd Chd)

func SetChd sets the Chd associated with a z.C if the size is wrong, everything will break.

func (*CDat) String

func (c *CDat) String() string

Dimacs representation

type Cdb

type Cdb struct {
	Vars   *Vars
	Active *Active
	CDat   CDat

	AddLits []z.Lit
	AddVals []int8

	Bot     z.C
	Added   []z.C
	Learnts []z.C

	Tracer Tracer
	// contains filtered or unexported fields
}

Type Cdb is the main interface to clauses.

func NewCdb

func NewCdb(v *Vars, capHint int) *Cdb

func (*Cdb) Add

func (c *Cdb) Add(m z.Lit) (z.C, z.Lit)

func (*Cdb) Bump

func (c *Cdb) Bump(p z.C)

func (*Cdb) Chd

func (c *Cdb) Chd(p z.C) Chd

func (*Cdb) CheckModel

func (c *Cdb) CheckModel() []error

by default, called when sat as a sanity check.

func (*Cdb) CheckWatches

func (c *Cdb) CheckWatches() []error

Debug self check code, not used in any production entrypoint.

func (*Cdb) CopyWith

func (c *Cdb) CopyWith(ov *Vars) *Cdb

NB also Active is copied in S.Copy and placed in resulting copied cdb, so we don't copy Active here.

func (*Cdb) Decay

func (c *Cdb) Decay()

func (*Cdb) Forall

func (c *Cdb) Forall(f func(p z.C, h Chd, ms []z.Lit))

func (*Cdb) ForallAdded

func (c *Cdb) ForallAdded(f func(p z.C, h Chd, ms []z.Lit))

func (*Cdb) ForallLearnts

func (c *Cdb) ForallLearnts(f func(p z.C, h Chd, ms []z.Lit))

func (*Cdb) ForallSlice

func (c *Cdb) ForallSlice(f func(p z.C, h Chd, ms []z.Lit), ps []z.C)

func (*Cdb) InUse

func (c *Cdb) InUse(o z.C) bool

func (*Cdb) IsBinary

func (c *Cdb) IsBinary(p z.C) bool

func (*Cdb) IsUnit

func (c *Cdb) IsUnit(p z.C) bool

func (*Cdb) Learn

func (c *Cdb) Learn(ms []z.Lit, lbd int) z.C

func (*Cdb) Lits

func (c *Cdb) Lits(p z.C, ms []z.Lit) []z.Lit

func (*Cdb) MaybeCompact

func (c *Cdb) MaybeCompact() (int, int, int)

func (*Cdb) Remove added in v1.1.0

func (c *Cdb) Remove(cs ...z.C)

func (*Cdb) SetTracer

func (c *Cdb) SetTracer(t Tracer)

func (*Cdb) Size

func (c *Cdb) Size(p z.C) int

func (*Cdb) String

func (c *Cdb) String() string
func (c *Cdb) Unlink(rms []z.C)

unlinks all the clauses in rms from watchlists nb supposes c.Learnts does not have any locs in "rms" or will not before return to normal solving, outside of clause garbage collection.

func (*Cdb) Write

func (c *Cdb) Write(w io.Writer) error

type Cgc

type Cgc struct {
	// contains filtered or unexported fields
}

Type Cgc encapsulates clause compaction/garbage collection.

This is separate from, and sometimes calls CDat compaction which is another issue.

func NewCgc

func NewCgc() *Cgc

NewCgc creates a new Cgc object

func (*Cgc) Compact

func (c *Cgc) Compact(cdb *Cdb) (int, int, int)

Compact runs a clause gc, which in turn sometimes compacts the underlying CDat. Compact returns

(num clauses removed, num clauses cdat removed, num freed uint32s)

func (*Cgc) CompactCDat

func (c *Cgc) CompactCDat(cdb *Cdb) (int, int)

NB this is only from cgc.Compact

func (*Cgc) Copy

func (c *Cgc) Copy() *Cgc

Copy makes a copy of c.

func (*Cgc) Ready

func (c *Cgc) Ready() bool

Ready tests whether a clause gc is ready to occur.

func (*Cgc) Remove added in v1.1.0

func (gc *Cgc) Remove(cdb *Cdb, cs ...z.C)

func (*Cgc) Tick

func (c *Cgc) Tick()

Tick is called every time there is a learned clause. it keeps track of virtual time for the gc.

type Chd

type Chd uint32

A lot of info packed into 32 bit header

func MakeChd

func MakeChd(learnt bool, lbd, sz int) Chd

func (Chd) Bump

func (c Chd) Bump(n uint32) (Chd, bool)

func (Chd) Decay

func (c Chd) Decay() Chd

func (Chd) Heat

func (c Chd) Heat() uint32

func (Chd) Lbd

func (c Chd) Lbd() uint32

func (Chd) Learnt

func (c Chd) Learnt() bool

func (Chd) Size

func (c Chd) Size() uint32

func (Chd) String

func (c Chd) String() string

type Ctl

type Ctl struct {
	// contains filtered or unexported fields
}

Type Ctl encapsulates low level asynchronous control over a Solve. Ctl is used to implement inter.S and concur.U and concur.S

func NewCtl

func NewCtl(s *S) *Ctl

NewCtl creates a new controller.

func (*Ctl) Pause

func (c *Ctl) Pause() (res int, ok bool)

Pause tries to pause the underlying Solve(). If not sucessfule, it returns the result of Solve() together with false. If successful, it returns (0, true).

When successful, Pause should always be followed by Unpause before any other usage of c. Pause is not re-entrant, Pausing a paused Solve will block indefinitely. This is in line with the not-safe for multiple goroutines nature of the Solve API.

func (*Ctl) Stop

func (c *Ctl) Stop() int

Stop stops the current call to solve and returns the solve result.

Stop should not be called more than once, and if it is called, then Test should not be called subsequently.

func (*Ctl) Test

func (c *Ctl) Test() (result int, done bool)

Test tests whether a result is a available and returns it together with whether the underlying Solve() has terminated. Test returns

  • 1 for SAT
  • -1 for UNSAT
  • 0 for UNKNOWN

func (*Ctl) Tick

func (c *Ctl) Tick() bool

Tick checks if the solver must stop or pause and if it must stop, it stops it and returns false otherwise, if the solver was paused, then tick blocks until unpause and returns true otherwise it just returns true.

func (*Ctl) Try

func (c *Ctl) Try(d time.Duration) int

Try tries to get the result within d time, returning 0 by default if no result is available within d time.

func (*Ctl) TryStats

func (c *Ctl) TryStats(timeout, stFreq time.Duration) <-chan StatsResult

TryStats outputs stats and result for at most timeout duration with stat requests occuring every stFreq.

func (*Ctl) Unpause

func (c *Ctl) Unpause()

Unpause resumes the solving process from a previous pause. Unpause will block indefinitely if the conn is not paused.

func (*Ctl) Wait

func (c *Ctl) Wait() int

Wait just waits until the Solve finishes and returns the result. Beware, NP-complete problem...

type Derived

type Derived struct {
	P           z.C
	Unit        z.Lit
	Size        int
	TargetLevel int
}

type Deriver

type Deriver struct {
	Cdb   *Cdb
	Vars  *Vars
	Guess *Guess
	Trail *Trail

	CLits []z.Lit
	SLits []z.Lit
	RLits []z.Lit
	Lvls  []bool
	Rdnt  []int8
	Seen  []bool

	Conflicts  int64
	Learnt     int64
	LearntLits int64
	RedLits    int64
}

func NewDeriver

func NewDeriver(cdb *Cdb, g *Guess, t *Trail) *Deriver

func (*Deriver) CopyWith

func (d *Deriver) CopyWith(cdb *Cdb, g *Guess, t *Trail) *Deriver

func (*Deriver) Derive

func (d *Deriver) Derive(x z.C) *Derived

func (*Deriver) String

func (d *Deriver) String() string

type DimacsVis

type DimacsVis struct {
	// contains filtered or unexported fields
}

Type DimacsVis implements dimacs.Vis for constructing solvers from dimacs cnf files.

func (*DimacsVis) Add

func (d *DimacsVis) Add(m z.Lit)

func (*DimacsVis) Eof

func (d *DimacsVis) Eof()

func (*DimacsVis) Init

func (d *DimacsVis) Init(v, c int)

func (*DimacsVis) S

func (d *DimacsVis) S() *S

type Guess

type Guess struct {
	// contains filtered or unexported fields
}

func NewGuessCdb

func NewGuessCdb(cdb *Cdb) *Guess

func (*Guess) At

func (g *Guess) At(i int) z.Var

At returns the i'th element of the underlying heap.

func (*Guess) Bump

func (g *Guess) Bump(m z.Lit) bool

Bump increases the heat of the variable associated with m

func (*Guess) Copy

func (g *Guess) Copy() *Guess

Copy makes a copy of g.

func (*Guess) Decay

func (g *Guess) Decay()

Decay increases the bump quantity geometrically.

func (*Guess) Guess

func (g *Guess) Guess(vals []int8) z.Lit

Guess finds the first unassigned variable and returns its cached value.

func (*Guess) Heat

func (g *Guess) Heat() float64

func (*Guess) Len

func (g *Guess) Len() int

Len returns how many candidate variables are in the heap. Note the heap may contain assigned variables.

func (*Guess) Push

func (g *Guess) Push(m z.Lit)

type Luby

type Luby struct {
	// contains filtered or unexported fields
}

func NewLuby

func NewLuby() *Luby

func (*Luby) Next

func (l *Luby) Next() uint

type S

type S struct {
	Vars   *Vars
	Cdb    *Cdb
	Trail  *Trail
	Guess  *Guess
	Driver *Deriver
	Active *Active
	// contains filtered or unexported fields
}

Solver implements a CDCL like solver with some performance bells and whistles

func NewS

func NewS() *S

NewS creates a new Solver with default (relatively small) capacity

func NewSCdb

func NewSCdb(cdb *Cdb) *S

Func NewSCdb creates a new Solver from a Cdb

func NewSDimacs

func NewSDimacs(r io.Reader) (*S, error)

NewSDimacs creates a new S from a dimacs file.

func NewSV

func NewSV(vCapHint int) *S

NewSV creates a new Solver with specified capacity hint for the number of variables.

func NewSVc

func NewSVc(vCapHint, cCapHint int) *S

NewSVc creates a new solver using specified capacity hints for number of variables (vCapHint) and number of clauses (cCapHint).

func (*S) Activate added in v1.1.0

func (s *S) Activate() z.Lit

func (*S) ActivateWith added in v1.1.0

func (s *S) ActivateWith(act z.Lit)

func (*S) ActivationLit added in v1.1.0

func (s *S) ActivationLit() z.Lit

func (*S) Add

func (s *S) Add(m z.Lit)

Add implements inter.S

func (*S) Assume

func (s *S) Assume(ms ...z.Lit)

Assume causes the solver to Assume the literal m to be true for the next call to Solve() or Test().

This may be called multiple times, indicating to make multiple assumptions. The assumptions hold for the next call to Solve() or Test(). Afterwards, if the result is unsat, then s.Why() gives a subset of inconsistent assumptions.

When used with sequences of Test/Untest and Solves, S makes a distinction between tested and untested assumptions. Solve always forgets/consumes untested assumptions; but Solve never forgets/consumes tested assumptions. Forgetting tested assumptions is accomplished with s.Untest().

func (*S) Copy

func (s *S) Copy() *S

func (*S) Deactivate added in v1.1.0

func (s *S) Deactivate(m z.Lit)

func (*S) GoSolve

func (s *S) GoSolve() inter.Solve

GoSolve provides a connection to Solve() running in another goroutine.

func (*S) Lit added in v0.9.0

func (s *S) Lit() z.Lit

Lit returns the positive literal of a fresh variable.

func (*S) MaxVar

func (s *S) MaxVar() z.Var

MaxVar returns the maximum variable added or assumed.

func (*S) ReadStats

func (s *S) ReadStats(st *Stats)

ReadStats reads data from the solver into st. The solver values are reset if they are cumulative. The duration and start time attributes of st are not touched.

func (*S) Reasons

func (s *S) Reasons(dst []z.Lit, m z.Lit) []z.Lit

Reasons returns the Reasons for a propagated literal returned from test.

Reasons takes 2 arguments,

dst a z.Lit slice in which to place the reasons
m the literal for which to supply reasons.

Reasons returns the reasons for m appended to dst.

If m is not a propagated literal returned from Test() (without Untest() in between), the result is undefined and may panic.

func (*S) SCopy

func (s *S) SCopy() inter.S

func (*S) Solve

func (s *S) Solve() int

Method Solve solves the problem added to the solver under assumptions specified by Assume.

Solve returns -1 if unsat and 1 if sat

func (*S) String

func (s *S) String() string

func (*S) Test

func (s *S) Test(ms []z.Lit) (res int, ns []z.Lit)

Test checks if the solver is consistent under unit propagation for the current assumptions and clauses and Test opens a scope for subsequent assumptions. Test takes one argument, which is a slice of literals in which to put propagated literals or failed assumptions.

Test returns a pair

(res, ns)

where

  • If res == 1, then the problem is SAT and a full model is found.
  • If res == 0, then the problem is unknown (but consistent under unit propagation).
  • If res == -1 then the problem is UNSAT.

Additionally if ns is not nil, then

  • If res in {0,1}, then ns contains all literals assigned under BCP since last Test(), including assumptions.
  • If res = -1, then ns contains the literals in a clause which is false under unit propagation, or an assumed false literal, whichever we happen upon first. (This is distinct from Why which gives failed literals).
  • ns is stored in ms if possible

Test operates under the following caveat.

If Test() or Solve() returns unsat, then Test() should not
be called subsequently until Untest() is called and returns 0.  Note
That it can be that Untest() will never return 0 if the problem is unsat
without assumptions.

If this does not hold, Test panics.

func (*S) Try added in v1.1.0

func (s *S) Try(dur time.Duration) int

func (*S) Untest

func (s *S) Untest() int

Untest removes assumptions since last test and returns -1 if the solver is inconsistent under unit propagation after removing assumptions, 0 otherwise. If Untest is called and there is no corresponding Test(), then Untest panics.

Note that when interleaving Solve,Test,and Untest, the following sequences are possible:

Assume(A1)
Test()     ->   0, []
Assume(A2)
Test()     ->   0
Assume(A3)
Solve()        -1
Untest()   ->  -1, [] // problem is unsat with A1 and A2
Untest()   ->  -1, [] // problem is unsat with A1 under BCP, even though it wasn't before

Assume(A1)
Test()     ->   0, [...]
Solve()    ->  -1 // unsat under A1
Untest()   ->   0
Assume(A2) ->
Test()     ->   1  // sat under A2
Untest()   ->   0
Assume(A1)
Test()     ->  -1, [] // problem is unsat with A1 under BCP, even though it wasn't before

func (*S) Value

func (s *S) Value(m z.Lit) bool

Value retrieves the value of the literal m

func (*S) Who

func (s *S) Who() string

Who identifies the solver and configuration.

func (*S) Why

func (s *S) Why(ms []z.Lit) []z.Lit

Why appends to ms a minimized list of assumptions which together caused previous call to be unsat.

If previous call was not unsat, then Why() returns ms

type Stats

type Stats struct {
	Start         time.Time
	Dur           time.Duration
	Vars          int
	Added         int64
	AddedLits     int64
	AddedUnits    int64
	AddedBinary   int64
	AddedTernary  int64
	Props         int64
	Sat           int64
	Unsat         int64
	Ended         int64
	Assumptions   int64
	Failed        int64
	Guesses       int64
	GuessRescales int64
	Conflicts     int64
	Learnts       int
	LearntLits    int64
	MinLits       int64
	Restarts      int64
	Compactions   int64
	Removed       int64
	RemovedLits   int64
	CDatGcs       int64
	CHeatRescales int64
	AddedBig      int64
	MaxTrail      int
	Pinned        int
	IncPinned     int
}

func NewStats

func NewStats() *Stats

func (*Stats) Accumulate

func (s *Stats) Accumulate(t *Stats)

func (*Stats) Reset

func (s *Stats) Reset()

func (*Stats) String

func (s *Stats) String() string

type StatsResult

type StatsResult struct {
	Result int
	Stats  *Stats
}

Type StatsResult encapsulates a pair of stats and a solve result.

type Tracer

type Tracer interface {
	Add(m int)
	Remove(i int)
}

type Trail

type Trail struct {
	Cdb   *Cdb
	Vars  *Vars
	Guess *Guess
	Head  int
	Tail  int
	Level int
	D     []z.Lit

	Props   int64
	MaxTail int
	// contains filtered or unexported fields
}

func NewTrail

func NewTrail(cdb *Cdb, guess *Guess) *Trail

func (*Trail) Assign

func (t *Trail) Assign(m z.Lit, c z.C)

func (*Trail) Back

func (t *Trail) Back(trgLevel int)

func (*Trail) CopyWith

func (t *Trail) CopyWith(cdb *Cdb, guess *Guess) *Trail

func (*Trail) Prop

func (t *Trail) Prop() z.C

func (*Trail) String

func (t *Trail) String() string

type Vars

type Vars struct {
	Max     z.Var // maximum value of a used variable
	Top     z.Var // number of allocated variables, 1-indexed
	Vals    []int8
	Reasons []z.C
	Levels  []int
	Watches [][]Watch
}

func NewVars

func NewVars(capHint int) *Vars

func (*Vars) Copy

func (v *Vars) Copy() *Vars

func (*Vars) Set

func (v *Vars) Set(m z.Lit)

func (*Vars) Sign

func (v *Vars) Sign(m z.Lit) int8

func (*Vars) String

func (vars *Vars) String() string

type Watch

type Watch uint64

Watch holds other blocking literal, clause location ( and 1 bit for whether binary

func MakeWatch

func MakeWatch(loc z.C, o z.Lit, isBin bool) Watch

MakeWatch creates a watch object for clause location loc blocking literal o, and isBin indicating whether the referred to clause is binary (comprised of 2 literals)

func (Watch) C added in v1.1.0

func (w Watch) C() z.C

the location of the null-terminated literals in the clause

func (Watch) IsBinary

func (w Watch) IsBinary() bool

whether clause is binary

func (Watch) Other

func (w Watch) Other() z.Lit

return the other blocking literal

func (Watch) Relocate

func (w Watch) Relocate(o z.C) Watch

return a watch with all info the same, but the z.C updated to o.

func (Watch) String

func (w Watch) String() string

a human readable representation

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL