Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Export solver and related interfaces #72

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions cmd/dimacs/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,9 @@ import (

"github.com/spf13/cobra"

"github.com/operator-framework/deppy/internal/constraints"
"github.com/operator-framework/deppy/internal/entitysource"
"github.com/operator-framework/deppy/internal/solver"
constraintsfactory "github.com/operator-framework/deppy/pkg/constraints/factory"
entitysourcefactory "github.com/operator-framework/deppy/pkg/entitysource/factory"
"github.com/operator-framework/deppy/pkg/solver/factory"
)

func NewDimacsCommand() *cobra.Command {
Expand Down Expand Up @@ -55,7 +55,7 @@ func solve(path string) error {
}

// build solver
so, err := solver.NewDeppySolver(entitysource.NewGroup(NewDimacsEntitySource(dimacs)), constraints.NewConstraintAggregator(NewDimacsConstraintGenerator(dimacs)))
so, err := factory.NewDeppySolver(entitysourcefactory.NewGroup(NewDimacsEntitySource(dimacs)), constraintsfactory.NewConstraintAggregator(NewDimacsConstraintGenerator(dimacs)))
if err != nil {
return err
}
Expand Down
17 changes: 8 additions & 9 deletions cmd/dimacs/dimacs_constraints.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import (
"context"
"strings"

"github.com/operator-framework/deppy/internal/constraints"
"github.com/operator-framework/deppy/internal/entitysource"
"github.com/operator-framework/deppy/internal/sat"
"github.com/operator-framework/deppy/pkg/constraints"
"github.com/operator-framework/deppy/pkg/entitysource"
)

var _ constraints.ConstraintGenerator = &ConstraintGenerator{}
Expand All @@ -21,11 +20,11 @@ func NewDimacsConstraintGenerator(dimacs *Dimacs) *ConstraintGenerator {
}
}

func (d *ConstraintGenerator) GetVariables(ctx context.Context, querier entitysource.EntityQuerier) ([]sat.Variable, error) {
func (d *ConstraintGenerator) GetVariables(ctx context.Context, querier entitysource.EntityQuerier) ([]constraints.IVariable, error) {
varMap := make(map[entitysource.EntityID]*constraints.Variable, len(d.dimacs.variables))
variables := make([]sat.Variable, 0, len(d.dimacs.variables))
variables := make([]constraints.IVariable, 0, len(d.dimacs.variables))
if err := querier.Iterate(ctx, func(entity *entitysource.Entity) error {
variable := constraints.NewVariable(sat.Identifier(entity.ID()))
variable := constraints.NewVariable(constraints.Identifier(entity.ID()))
variables = append(variables, variable)
varMap[entity.ID()] = variable
return nil
Expand All @@ -45,10 +44,10 @@ func (d *ConstraintGenerator) GetVariables(ctx context.Context, querier entityso
// TODO: check constraints haven't already been added to the variable
variable := varMap[entitysource.EntityID(strings.TrimPrefix(first, "-"))]
if strings.HasPrefix(first, "-") {
variable.AddConstraint(sat.Not())
variable.AddConstraint(constraints.Not())
} else {
// TODO: is this the right constraint here? (given that its an achoring constraint?)
variable.AddConstraint(sat.Mandatory())
variable.AddConstraint(constraints.Mandatory())
}
continue
}
Expand All @@ -59,7 +58,7 @@ func (d *ConstraintGenerator) GetVariables(ctx context.Context, querier entityso
negOperand := strings.HasPrefix(second, "-")

// TODO: this Or constraint is hacky as hell
variable.AddConstraint(sat.Or(sat.Identifier(strings.TrimPrefix(second, "-")), negSubject, negOperand))
variable.AddConstraint(constraints.Or(constraints.Identifier(strings.TrimPrefix(second, "-")), negSubject, negOperand))
first = second
}
}
Expand Down
7 changes: 4 additions & 3 deletions cmd/dimacs/dimacs_source.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package dimacs

import (
"github.com/operator-framework/deppy/internal/entitysource"
"github.com/operator-framework/deppy/pkg/entitysource"
"github.com/operator-framework/deppy/pkg/entitysource/factory"
)

var _ entitysource.EntitySource = &EntitySource{}

type EntitySource struct {
*entitysource.CacheQuerier
entitysource.EntityQuerier
entitysource.EntityContentGetter
}

Expand All @@ -19,7 +20,7 @@ func NewDimacsEntitySource(dimacs *Dimacs) *EntitySource {
}

return &EntitySource{
CacheQuerier: entitysource.NewCacheQuerier(entities),
EntityQuerier: factory.NewCacheQuerier(entities),
EntityContentGetter: entitysource.NoContentSource(),
}
}
8 changes: 4 additions & 4 deletions cmd/sudoku/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import (

"github.com/spf13/cobra"

"github.com/operator-framework/deppy/internal/constraints"
"github.com/operator-framework/deppy/internal/entitysource"
"github.com/operator-framework/deppy/internal/solver"
constraintsfactory "github.com/operator-framework/deppy/pkg/constraints/factory"
entitysourcefactory "github.com/operator-framework/deppy/pkg/entitysource/factory"
"github.com/operator-framework/deppy/pkg/solver/factory"
)

func NewSudokuCommand() *cobra.Command {
Expand All @@ -24,7 +24,7 @@ func NewSudokuCommand() *cobra.Command {
func solve() error {
// build solver
sudoku := NewSudoku()
so, err := solver.NewDeppySolver(entitysource.NewGroup(sudoku), constraints.NewConstraintAggregator(sudoku))
so, err := factory.NewDeppySolver(entitysourcefactory.NewGroup(sudoku), constraintsfactory.NewConstraintAggregator(sudoku))
if err != nil {
return err
}
Expand Down
41 changes: 21 additions & 20 deletions cmd/sudoku/sudoku.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,17 @@ import (
"strconv"
"time"

"github.com/operator-framework/deppy/internal/constraints"
"github.com/operator-framework/deppy/internal/entitysource"
"github.com/operator-framework/deppy/internal/sat"
"github.com/operator-framework/deppy/pkg/constraints"
"github.com/operator-framework/deppy/pkg/entitysource"
"github.com/operator-framework/deppy/pkg/entitysource/factory"
)

var _ entitysource.EntitySource = &Sudoku{}

var _ constraints.ConstraintGenerator = &Sudoku{}

type Sudoku struct {
*entitysource.CacheQuerier
entitysource.EntityQuerier
entitysource.EntityContentGetter
}

Expand All @@ -42,22 +43,22 @@ func NewSudoku() *Sudoku {
}
}
return &Sudoku{
CacheQuerier: entitysource.NewCacheQuerier(entities),
EntityQuerier: factory.NewCacheQuerier(entities),
EntityContentGetter: entitysource.NoContentSource(),
}
}

func (s Sudoku) GetVariables(ctx context.Context, querier entitysource.EntityQuerier) ([]sat.Variable, error) {
func (s Sudoku) GetVariables(ctx context.Context, querier entitysource.EntityQuerier) ([]constraints.IVariable, error) {
// adapted from: https://github.com/go-air/gini/blob/871d828a26852598db2b88f436549634ba9533ff/sudoku_test.go#L10
variables := make(map[sat.Identifier]*constraints.Variable, 0)
inorder := make([]sat.Variable, 0)
variables := make(map[constraints.Identifier]*constraints.Variable, 0)
inorder := make([]constraints.IVariable, 0)
rand.Seed(time.Now().UnixNano())

// create variables for all number in all positions of the board
for row := 0; row < 9; row++ {
for col := 0; col < 9; col++ {
for n := 0; n < 9; n++ {
variable := constraints.NewVariable(sat.Identifier(GetID(row, col, n)))
variable := constraints.NewVariable(constraints.Identifier(GetID(row, col, n)))
variables[variable.Identifier()] = variable
inorder = append(inorder, variable)
}
Expand All @@ -67,16 +68,16 @@ func (s Sudoku) GetVariables(ctx context.Context, querier entitysource.EntityQue
// add a clause stating that every position on the board has a number
for row := 0; row < 9; row++ {
for col := 0; col < 9; col++ {
ids := make([]sat.Identifier, 9)
ids := make([]constraints.Identifier, 9)
for n := 0; n < 9; n++ {
ids[n] = sat.Identifier(GetID(row, col, n))
ids[n] = constraints.Identifier(GetID(row, col, n))
}
// randomize order to create new sudoku boards every run
rand.Shuffle(len(ids), func(i, j int) { ids[i], ids[j] = ids[j], ids[i] })

// create clause that the particular position has a number
varID := sat.Identifier(fmt.Sprintf("%d-%d has a number", row, col))
variable := constraints.NewVariable(varID, sat.Mandatory(), sat.Dependency(ids...))
varID := constraints.Identifier(fmt.Sprintf("%d-%d has a number", row, col))
variable := constraints.NewVariable(varID, constraints.Mandatory(), constraints.Dependency(ids...))
variables[varID] = variable
inorder = append(inorder, variable)
}
Expand All @@ -86,10 +87,10 @@ func (s Sudoku) GetVariables(ctx context.Context, querier entitysource.EntityQue
for n := 0; n < 9; n++ {
for row := 0; row < 9; row++ {
for colA := 0; colA < 9; colA++ {
idA := sat.Identifier(GetID(row, colA, n))
idA := constraints.Identifier(GetID(row, colA, n))
variable := variables[idA]
for colB := colA + 1; colB < 9; colB++ {
variable.AddConstraint(sat.Conflict(sat.Identifier(GetID(row, colB, n))))
variable.AddConstraint(constraints.Conflict(constraints.Identifier(GetID(row, colB, n))))
}
}
}
Expand All @@ -99,10 +100,10 @@ func (s Sudoku) GetVariables(ctx context.Context, querier entitysource.EntityQue
for n := 0; n < 9; n++ {
for col := 0; col < 9; col++ {
for rowA := 0; rowA < 9; rowA++ {
idA := sat.Identifier(GetID(rowA, col, n))
idA := constraints.Identifier(GetID(rowA, col, n))
variable := variables[idA]
for rowB := rowA + 1; rowB < 9; rowB++ {
variable.AddConstraint(sat.Conflict(sat.Identifier(GetID(rowB, col, n))))
variable.AddConstraint(constraints.Conflict(constraints.Identifier(GetID(rowB, col, n))))
}
}
}
Expand All @@ -116,12 +117,12 @@ func (s Sudoku) GetVariables(ctx context.Context, querier entitysource.EntityQue
// all numbers
for n := 0; n < 9; n++ {
for i, offA := range offs {
idA := sat.Identifier(GetID(x+offA.x, y+offA.y, n))
idA := constraints.Identifier(GetID(x+offA.x, y+offA.y, n))
variable := variables[idA]
for j := i + 1; j < len(offs); j++ {
offB := offs[j]
idB := sat.Identifier(GetID(x+offB.x, y+offB.y, n))
variable.AddConstraint(sat.Conflict(idB))
idB := constraints.Identifier(GetID(x+offB.x, y+offB.y, n))
variable.AddConstraint(constraints.Conflict(idB))
}
}
}
Expand Down
19 changes: 7 additions & 12 deletions internal/constraints/constraint_generator.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,27 @@ package constraints
import (
"context"

"github.com/operator-framework/deppy/internal/entitysource"
"github.com/operator-framework/deppy/internal/sat"
pkgconstraints "github.com/operator-framework/deppy/pkg/constraints"
"github.com/operator-framework/deppy/pkg/entitysource"
)

// ConstraintGenerator generates solver constraints given an entity querier interface
type ConstraintGenerator interface {
GetVariables(ctx context.Context, querier entitysource.EntityQuerier) ([]sat.Variable, error)
}

var _ ConstraintGenerator = &ConstraintAggregator{}
var _ pkgconstraints.ConstraintGenerator = &ConstraintAggregator{}

// ConstraintAggregator is a simple structure that aggregates different constraint generators
// and collects all generated solver constraints
type ConstraintAggregator struct {
constraintGenerators []ConstraintGenerator
constraintGenerators []pkgconstraints.ConstraintGenerator
}

func NewConstraintAggregator(constraintGenerators ...ConstraintGenerator) *ConstraintAggregator {
func NewConstraintAggregator(constraintGenerators []pkgconstraints.ConstraintGenerator) *ConstraintAggregator {
return &ConstraintAggregator{
constraintGenerators: constraintGenerators,
}
}

func (b *ConstraintAggregator) GetVariables(ctx context.Context, entityQuerier entitysource.EntityQuerier) ([]sat.Variable, error) {
func (b *ConstraintAggregator) GetVariables(ctx context.Context, entityQuerier entitysource.EntityQuerier) ([]pkgconstraints.IVariable, error) {
// TODO: refactor to scatter cather through go routines
variables := make([]sat.Variable, 0)
variables := make([]pkgconstraints.IVariable, 0)
for _, constraintGenerator := range b.constraintGenerators {
vars, err := constraintGenerator.GetVariables(ctx, entityQuerier)
if err != nil {
Expand Down
30 changes: 0 additions & 30 deletions internal/constraints/variable.go

This file was deleted.

24 changes: 14 additions & 10 deletions internal/entitysource/cache_querier.go
Original file line number Diff line number Diff line change
@@ -1,29 +1,33 @@
package entitysource

import "context"
import (
"context"

var _ EntityQuerier = &CacheQuerier{}
pkgentitysource "github.com/operator-framework/deppy/pkg/entitysource"
)

var _ pkgentitysource.EntityQuerier = &CacheQuerier{}

type CacheQuerier struct {
// TODO: separate out a cache
entities map[EntityID]Entity
entities map[pkgentitysource.EntityID]pkgentitysource.Entity
}

func NewCacheQuerier(entities map[EntityID]Entity) *CacheQuerier {
func NewCacheQuerier(entities map[pkgentitysource.EntityID]pkgentitysource.Entity) *CacheQuerier {
return &CacheQuerier{
entities: entities,
}
}

func (c CacheQuerier) Get(_ context.Context, id EntityID) *Entity {
func (c CacheQuerier) Get(_ context.Context, id pkgentitysource.EntityID) *pkgentitysource.Entity {
if entity, ok := c.entities[id]; ok {
return &entity
}
return nil
}

func (c CacheQuerier) Filter(_ context.Context, filter Predicate) (EntityList, error) {
resultSet := EntityList{}
func (c CacheQuerier) Filter(_ context.Context, filter pkgentitysource.Predicate) (pkgentitysource.EntityList, error) {
resultSet := pkgentitysource.EntityList{}
for _, entity := range c.entities {
if filter(&entity) {
resultSet = append(resultSet, entity)
Expand All @@ -32,8 +36,8 @@ func (c CacheQuerier) Filter(_ context.Context, filter Predicate) (EntityList, e
return resultSet, nil
}

func (c CacheQuerier) GroupBy(_ context.Context, fn GroupByFunction) (EntityListMap, error) {
resultSet := EntityListMap{}
func (c CacheQuerier) GroupBy(_ context.Context, fn pkgentitysource.GroupByFunction) (pkgentitysource.EntityListMap, error) {
resultSet := pkgentitysource.EntityListMap{}
for _, entity := range c.entities {
keys := fn(&entity)
for _, key := range keys {
Expand All @@ -43,7 +47,7 @@ func (c CacheQuerier) GroupBy(_ context.Context, fn GroupByFunction) (EntityList
return resultSet, nil
}

func (c CacheQuerier) Iterate(_ context.Context, fn IteratorFunction) error {
func (c CacheQuerier) Iterate(_ context.Context, fn pkgentitysource.IteratorFunction) error {
for _, entity := range c.entities {
if err := fn(&entity); err != nil {
return err
Expand Down
Loading