@@ -5,14 +5,57 @@ import (
55 "strings"
66)
77
8+ // constrainer is a reusable accumulator of constraint clause terms.
9+ type constrainer struct {
10+ pos []Identifier
11+ neg []Identifier
12+ }
13+
14+ func (x * constrainer ) Add (id Identifier ) {
15+ x .pos = append (x .pos , id )
16+ }
17+
18+ func (x * constrainer ) AddNot (id Identifier ) {
19+ x .neg = append (x .neg , id )
20+ }
21+
22+ // Reset clears the receiver's internal state so that it can be
23+ // reused.
24+ func (x * constrainer ) Reset () {
25+ x .pos = x .pos [:0 ]
26+ x .neg = x .neg [:0 ]
27+ }
28+
29+ // Empty returns true if and only if the receiver has accumulated no
30+ // positive or negative terms.
31+ func (x * constrainer ) Empty () bool {
32+ return len (x .pos ) == 0 && len (x .neg ) == 0
33+ }
34+
835// Constraint implementations limit the circumstances under which a
936// particular Installable can appear in a solution.
1037type Constraint interface {
1138 String (subject Identifier ) string
12- apply (x constrainer , subject Identifier )
39+ apply (x * constrainer , subject Identifier )
1340 order () []Identifier
1441}
1542
43+ // zeroConstraint is returned by ConstraintOf in error cases.
44+ type zeroConstraint struct {}
45+
46+ var _ Constraint = zeroConstraint {}
47+
48+ func (zeroConstraint ) String (subject Identifier ) string {
49+ return ""
50+ }
51+
52+ func (zeroConstraint ) apply (x * constrainer , subject Identifier ) {
53+ }
54+
55+ func (zeroConstraint ) order () []Identifier {
56+ return nil
57+ }
58+
1659// AppliedConstraint values compose a single Constraint with the
1760// Installable it applies to.
1861type AppliedConstraint struct {
@@ -26,25 +69,13 @@ func (a AppliedConstraint) String() string {
2669 return a .Constraint .String (a .Installable .Identifier ())
2770}
2871
29- // constrainer is the set of operations available to Constraint
30- // implementations.
31- type constrainer interface {
32- // Add appends the Installable identified by the given
33- // Identifier to the clause representing a Constraint.
34- Add (Identifier )
35- // Add appends the negation of the Installable identified by
36- // the given Identifier to the clause representing a
37- // Constraint.
38- AddNot (Identifier )
39- }
40-
4172type mandatory struct {}
4273
4374func (c mandatory ) String (subject Identifier ) string {
4475 return fmt .Sprintf ("%s is mandatory" , subject )
4576}
4677
47- func (c mandatory ) apply (x constrainer , subject Identifier ) {
78+ func (c mandatory ) apply (x * constrainer , subject Identifier ) {
4879 x .Add (subject )
4980}
5081
@@ -64,7 +95,7 @@ func (c prohibited) String(subject Identifier) string {
6495 return fmt .Sprintf ("%s is prohibited" , subject )
6596}
6697
67- func (c prohibited ) apply (x constrainer , subject Identifier ) {
98+ func (c prohibited ) apply (x * constrainer , subject Identifier ) {
6899 x .AddNot (subject )
69100}
70101
@@ -90,7 +121,7 @@ func (c dependency) String(subject Identifier) string {
90121 return fmt .Sprintf ("%s requires at least one of %s" , subject , strings .Join (s , ", " ))
91122}
92123
93- func (c dependency ) apply (x constrainer , subject Identifier ) {
124+ func (c dependency ) apply (x * constrainer , subject Identifier ) {
94125 if len (c ) == 0 {
95126 return
96127 }
@@ -119,7 +150,7 @@ func (c conflict) String(subject Identifier) string {
119150 return fmt .Sprintf ("%s conflicts with %s" , subject , c )
120151}
121152
122- func (c conflict ) apply (x constrainer , subject Identifier ) {
153+ func (c conflict ) apply (x * constrainer , subject Identifier ) {
123154 x .AddNot (subject )
124155 x .AddNot (Identifier (c ))
125156}
0 commit comments