model

package
v0.21.1-dev.20 Latest Latest
Warning

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

Go to latest
Published: Feb 24, 2023 License: Apache-2.0 Imports: 4 Imported by: 0

README

Model

Package model provides modeling components, such as domains and ranges. A domain is a data structure which allows to efficiently store and access a finite number of integers. It does this by storing ranges of integer values.

See godocs for package docs.

Documentation

Overview

Package model provides modeling components, such as domains and ranges.

Create individual integer domains.

d1 := model.NewDomain() // empty domain
d2 := model.NewDomain(model.NewRange(1, 10))
d3 := model.NewDomain(model.NewRange(1, 10), model.MewRange(21, 30))
d4 := model.Singleton(42)
d5 := model.Multiple(2, 4, 6, 8)

Create sequences of domains.

domains1 := model.NewDomains(d1, d2, d3, d4, d5)
domains2 := model.Repeat(5, d1) // 5 empty domains

Index

Examples

Constants

View Source
const (
	// MaxInt is the maximum value for an integer.
	MaxInt int = (1<<bits.UintSize)/2 - 1
	// MinInt is the minimum value for an integer.
	MinInt = (1 << bits.UintSize) / -2
)

Constants for integer bounds.

Variables

This section is empty.

Functions

This section is empty.

Types

type Domain

type Domain interface {
	// Add values to a domain.
	Add(v ...int) Domain
	// AtLeast updates the domain to the subdomain of at least some value.
	AtLeast(int) Domain
	// AtMost updates the domain to the subdomain of at most some value.
	AtMost(int) Domain
	// Cmp lexically compares two integer domains. It returns a negative value
	// if the receiver is less, 0 if they are equal, and a positive value if
	// the receiver domain is greater.
	Cmp(Domain) int
	// Contains returns true if a domain contains a given value.
	Contains(int) bool
	// Empty is true if a domain is empty.
	Empty() bool
	// Iterator over a domain.
	Iterator() Iterator
	// Len of a domain, counting all values within ranges.
	Len() int
	// Max of a domain and a boolean indicating it is nonempty.
	Max() (int, bool)
	// Min of a domain and a boolean indicating it is nonempty.
	Min() (int, bool)
	// Overlaps returns true if a domain overlaps another domain.
	Overlaps(other Domain) bool
	// Remove values from a domain.
	Remove([]int) Domain
	// Slice representation of a domain.
	Slice() []int
	// Value returns an int and true if a domain is singleton.
	Value() (int, bool)
}

A Domain of integers.

Example (Add)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d1 := model.Multiple(1, 3, 5)
	d2 := d1.Add(2, 4)
	fmt.Println(d1)
	fmt.Println(d2)
}
Output:

{[{1 1} {3 3} {5 5}]}
{[{1 5}]}
Example (AtLeast)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d1 := model.NewDomain(
		model.NewRange(1, 10),
		model.NewRange(101, 110),
	)
	d2 := d1.AtLeast(50)
	fmt.Println(d1)
	fmt.Println(d2)
}
Output:

{[{1 10} {101 110}]}
{[{101 110}]}
Example (AtMost)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d1 := model.NewDomain(
		model.NewRange(1, 10),
		model.NewRange(101, 110),
	)
	d2 := d1.AtMost(50)
	fmt.Println(d1)
	fmt.Println(d2)
}
Output:

{[{1 10} {101 110}]}
{[{1 10}]}
Example (Cmp)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d1 := model.NewDomain(
		model.NewRange(1, 5),
		model.NewRange(8, 10),
	)
	d2 := model.Multiple(-1, 1)
	fmt.Println(d1.Cmp(d2))
}
Output:

1
Example (Contains)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d := model.NewDomain(model.NewRange(1, 10))
	fmt.Println(d.Contains(5))
	fmt.Println(d.Contains(15))
}
Output:

true
false
Example (Empty)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d1 := model.NewDomain()
	d2 := model.Singleton(42)
	fmt.Println(d1.Empty())
	fmt.Println(d2.Empty())
}
Output:

true
false
Example (Iterator)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d := model.NewDomain(model.NewRange(1, 3))
	iter := d.Iterator()
	for iter.Next() {
		fmt.Println(iter.Value())
	}
}
Output:

1
2
3
Example (Len)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d := model.NewDomain(
		model.NewRange(1, 10),
		model.NewRange(-5, -1),
	)
	fmt.Println(d.Len())
}
Output:

15
Example (Max)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d1 := model.NewDomain()
	d2 := model.NewDomain(
		model.NewRange(1, 10),
		model.NewRange(-5, -1),
	)
	fmt.Println(d1.Max())
	fmt.Println(d2.Max())
}
Output:

9223372036854775807 false
10 true
Example (Min)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d1 := model.NewDomain()
	d2 := model.NewDomain(
		model.NewRange(1, 10),
		model.NewRange(-5, -1),
	)
	fmt.Println(d1.Min())
	fmt.Println(d2.Min())
}
Output:

-9223372036854775808 false
-5 true
Example (Remove)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	domain := model.NewDomain(model.NewRange(0, 3))
	domain = domain.Remove([]int{2})
	fmt.Println(domain.Min())
	fmt.Println(domain.Contains(2))
	fmt.Println(domain.Max())
}
Output:

0 true
false
3 true
Example (Slice)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d := model.NewDomain(model.NewRange(1, 5))
	fmt.Println(d.Slice())
}
Output:

[1 2 3 4 5]
Example (Value)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d1 := model.NewDomain()
	d2 := model.Singleton(42)
	d3 := model.Multiple(1, 3, 5)
	fmt.Println(d1.Value())
	fmt.Println(d2.Value())
	fmt.Println(d3.Value())
}
Output:

0 false
42 true
0 false

func Multiple

func Multiple(values ...int) Domain

Multiple creates a domain containing multiple integer values.

Example
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	domain := model.Multiple(3, 5, 1)
	fmt.Println(domain.Min())
	fmt.Println(domain.Max())
	fmt.Println(domain.Len())
	fmt.Println(domain.Contains(3))
}
Output:

1 true
5 true
3
true

func NewDomain

func NewDomain(ranges ...Range) Domain

NewDomain creates a domain of integers.

Example
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	domain := model.NewDomain(
		model.NewRange(0, 1),
		model.NewRange(3, 4),
	)
	fmt.Println(domain.Min())
	fmt.Println(domain.Max())
	fmt.Println(domain.Contains(2))
}
Output:

0 true
4 true
false

func Singleton

func Singleton(value int) Domain

Singleton creates a domain containing one integer value.

Example
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	domain := model.Singleton(1)
	fmt.Println(domain.Value())
}
Output:

1 true

type Domains

type Domains interface {
	// Add values to a domain by index.
	Add(int, ...int) Domains
	// Assign a singleton value to a domain by index.
	Assign(int, int) Domains
	// AtLeast updates the domain to the subdomain of at least some value.
	AtLeast(int, int) Domains
	// AtMost updates the domain to the subdomain of at most some value.
	AtMost(int, int) Domains
	// Cmp lexically compares two sequences of integer domains.
	Cmp(Domains) int
	// Domain by index.
	Domain(int) Domain
	// Empty is true if all domains are empty.
	Empty() bool
	// Len returns the number of domains.
	Len() int
	// Remove values from a domain by index.
	Remove(int, []int) Domains
	// Singleton is true if all domains are Singleton.
	Singleton() bool
	// Slices convert domains to a slice of int slices.
	Slices() [][]int
	// Values returns the values of a sequence of singleton domains/
	Values() ([]int, bool)

	// First returns the first domain index with length above 1.
	First() (int, bool)
	// Largest returns the index of the largest domain with length above 1 by
	// number of elements.
	Largest() (int, bool)
	// Last returns the last domain index with length above 1.
	Last() (int, bool)
	// Maximum returns the index of the domain containing the maximum value with
	// length above 1.
	Maximum() (int, bool)
	// Minimum returns the index of the domain containing the minimum value with
	// length above 1.
	Minimum() (int, bool)
	// Smallest returns the index of the smallest domain with length above 1 by
	// number of elements.
	Smallest() (int, bool)
}

Domains of integers.

Example (Add)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d1 := model.Repeat(3, model.Singleton(42))
	d2 := d1.Add(1, 41, 43)
	fmt.Println(d2)
}
Output:

[{[{42 42}]} {[{41 43}]} {[{42 42}]}]
Example (Assign)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d1 := model.Repeat(3, model.Singleton(42))
	d2 := d1.Assign(0, 10)
	fmt.Println(d2)
}
Output:

[{[{10 10}]} {[{42 42}]} {[{42 42}]}]
Example (AtLeast)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d1 := model.Repeat(2, model.NewDomain(model.NewRange(1, 100)))
	d2 := d1.AtLeast(1, 50)
	fmt.Println(d2)
}
Output:

[{[{1 100}]} {[{50 100}]}]
Example (AtMost)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d1 := model.Repeat(2, model.NewDomain(model.NewRange(1, 100)))
	d2 := d1.AtMost(1, 50)
	fmt.Println(d2)
}
Output:

[{[{1 100}]} {[{1 50}]}]
Example (Cmp)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d1 := model.Repeat(2, model.Singleton(42))
	d2 := model.Repeat(3, model.Singleton(43))
	fmt.Println(d1.Cmp(d2))
}
Output:

-1
Example (Domain)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d := model.NewDomains(model.NewDomain(), model.Singleton(42))
	fmt.Println(d.Domain(0))
	fmt.Println(d.Domain(1))
}
Output:

{[]}
{[{42 42}]}
Example (Empty)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d := model.NewDomains(model.NewDomain())
	fmt.Println(d.Empty())
}
Output:

true
Example (First)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d := model.NewDomains(
		model.Singleton(88),
		model.Multiple(1, 3),
		model.Multiple(4, 76),
	)
	fmt.Println(d.First())
}
Output:

1 true
Example (Largest)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d := model.NewDomains(
		model.Singleton(88),
		model.Multiple(1, 3),
		model.Multiple(4, 76, 97),
	)
	fmt.Println(d.Largest())
}
Output:

2 true
Example (Last)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d := model.NewDomains(
		model.Singleton(88),
		model.Multiple(1, 3),
		model.Multiple(4, 76, 97),
		model.Singleton(45),
	)
	fmt.Println(d.Last())
}
Output:

2 true
Example (Len)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d := model.Repeat(5, model.NewDomain())
	fmt.Println(d.Len())
}
Output:

5
Example (Maximum)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d := model.NewDomains(
		model.Singleton(88),
		model.Multiple(4, 76, 97),
		model.Multiple(1, 3),
		model.Singleton(45),
	)
	fmt.Println(d.Maximum())
}
Output:

1 true
Example (Minimum)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d := model.NewDomains(
		model.Singleton(88),
		model.Multiple(4, 76, 97),
		model.Multiple(1, 3),
		model.Singleton(45),
	)
	fmt.Println(d.Minimum())
}
Output:

2 true
Example (Remove)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d1 := model.NewDomains(model.Multiple(42, 13))
	d2 := d1.Remove(0, []int{13})
	fmt.Println(d2)
}
Output:

[{[{42 42}]}]
Example (Singleton)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d := model.Repeat(5, model.Singleton(42))
	fmt.Println(d.Singleton())
}
Output:

true
Example (Slices)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d := model.NewDomains(model.NewDomain(), model.Multiple(1, 3))
	fmt.Println(d.Slices())
}
Output:

[[] [1 3]]
Example (Smallest)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d := model.NewDomains(
		model.Singleton(88),
		model.Multiple(1, 3),
		model.Multiple(4, 76, 97),
	)
	fmt.Println(d.Smallest())
}
Output:

1 true
Example (Values)
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d1 := model.Repeat(3, model.Singleton(42))
	d2 := d1.Add(0, 41)
	fmt.Println(d1.Values())
	fmt.Println(d2.Values())
}
Output:

[42 42 42] true
[] false

func NewDomains

func NewDomains(domains ...Domain) Domains

NewDomains creates a sequence of domains.

Example
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d := model.NewDomains( // [1 to 10, 42, odds]
		model.NewDomain(model.NewRange(1, 10)),
		model.Singleton(42),
		model.Multiple(1, 3, 5, 7),
	)
	fmt.Println(d)
}
Output:

[{[{1 10}]} {[{42 42}]} {[{1 1} {3 3} {5 5} {7 7}]}]

func Repeat

func Repeat(n int, d Domain) Domains

Repeat a domain n times.

Example
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	d := model.Repeat(3, model.NewDomain(model.NewRange(1, 10)))
	fmt.Println(d)
}
Output:

[{[{1 10}]} {[{1 10}]} {[{1 10}]}]

type Identifier added in v0.20.0

type Identifier interface {
	ID() string
}

Identifier needs to be implemented by any type to be used with MultiMap. The value returned by ID() needs to be unique for every instance of Identifier.

type Iterator

type Iterator interface {
	Next() bool
	Value() int
}

An Iterator allows one to iterate over a range or a domain.

it := model.Domain(model.Range(1, 10)).Iterator()
for it.Next() {
    fmt.Println(it.Value()) // 1, ..., 10
}

type MultiMap added in v0.20.0

type MultiMap[T any, T2 Identifier] interface {
	// Get an element from the MultiMap, given an n-dimensional index or
	// adds it by using the create function if it hasn't been created previously.
	Get(identifiers ...T2) T
	// Length of the elements in the MultiMap.
	Length() int
}

MultiMap is a map with an n-dimensional index.

func NewMultiMap added in v0.20.0

func NewMultiMap[T any, T2 Identifier](
	create func(...T2) T,
	sets ...[]T2,
) MultiMap[T, T2]

NewMultiMap creates a new MultiMap. It takes a create function that is responsible for creating a new entity of T based on a given n-dimensional index. The second argument is a variable number of sets, one set per dimension of the index.

type Range

type Range interface {
	Min() int
	Max() int
}

A Range of integers.

func NewRange

func NewRange(min, max int) Range

NewRange create a new integer range.

Example
package main

import (
	"fmt"

	"github.com/nextmv-io/sdk/model"
)

func main() {
	r1 := model.NewRange(0, 1)
	fmt.Println(r1)
}
Output:

{0 1}

Jump to

Keyboard shortcuts

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