Usage¶
The core classes of the citoolkit
are broken into two packages: Specifications and Improvisers.
Specifications¶
Specifications provide ways of defining languages of words over an alphabet of symbols. In this library any string can be a symbol and a word is simply an ordered collection of words, typically a tuple. All specifications extend from the Spec class, which has 3 abstract functions must be implemented:
accepts
: Theaccepts
function is how a specification defines a language. A word is in the language of a specification if and only ifaccepts
returns true for that word.language_size
: Thelanguage_size
function allows one to determine the size of a specification’s language. One can provide lower and upper bounds on words to count, by passing themin_length
andmax_length
parameters respectively.sample
: Thesample
function allows one to sample uniformly at random from the language of a specification. One can provide lower and upper bounds on words to count, by passing themin_length
andmax_length
parameters respectively.
As long as a specification can support these operations and extend the Spec base class, it can be used as in control improvisation. However, the library primarily implements specifications that support these operations efficiently, so as to produce an efficient improviser.
The specifications provided natively by this library are:
Deterministic Finite Automaton (DFA):
citoolkit.specifications.dfa.Dfa
In addition, support the standard union, intersection, negation and difference operations. This is done primarily through the use of the AbstractSpec
class, which creates logical trees of specifications. This allows to run the accepts
function any combination of specs with any of the 4 supported operations. The AbstractSpec
class also has an explicit
method, which allows one to attempt to collapse a tree of abstract specifications into a single concrete Spec subclass. To implement the language_size
and sample
methods, the AbstractSpec
class first tries to compute its explicit form. If this fails, sometimes we can still implement these methods through a more specialized approach. Otherwise, a NotImplementedError
is raised. All of this logic is handled in the AbstractSpec
class, and must be augmented to support new specifications.
Improvisers¶
The improviser classes are implementations of the algorithms to solve the Control Improvisation problem and its extensions. The Improviser base class has two abstract methods: improvise
and generator
. improvise
returns a single improvised word while generator
returns an iterable object that continually generates words. Some improvisers provide also additional information about the distribution of words they are generating.
The improvisers provided natively by this library are:
Control Improvisation (CI): Outlined in detail in [Fremont et al. 2017]. Allows for an explicit hard constraint, a soft constraint that can be violated within a provided tolerance, and explicit randomness bounds on the probability of generating each word.