One of the more important points in the beginnings of Math.NET Symbolics was extensibility and a dynamic behavior. You should be able to define your own operations and data structures. To put this to an extreme, the framework core should be separated and independent from any data types and operations.
The classic symbolics implementation solved this by reflection. All data types and operations were marked with attributes. The core then analyzed the assembly and built a symbol table dynamically. Yttrium still supports dynamic assembly analysis, but uses it as a fallback solution only. In yttrium you define all your extensions in terms of a package. Every package has a name, called the domain, and a package manager class that knows all about the package. To load an external package you hand over an instance of the package manager, and yttrium uses it to update its internal symbol tables. If you don't have an instance but know the assembly, yttrium may look for it by reflection. Only if it doesn't find a package manager it falls back to the old analysis mentioned above. To hand over a package manager use the LoadPackageManager method:
A package manager is a simple class implementing the IPackageManager interface. Beside of defining a domain, it only provides references to several servers which finally provide useful information about the packages. Usually the package manager implements all those servers itself:
- Entities (IEntityServer): Lists all entities of the package
- Architectures (IArchitectureServer): Lists all architecture factories for constructing architectures implementing any entities defined in this or other packages.
- Structures (IStructureServer): Extends the data structures table. This is important for the automatic conversion routing (I'll introduce this in a later post)
- Theorems (ITheoremServer): Lists all theorems the package provides.
The Standard Package
Yttrium defines a standard package (domain "Std<") with very basic data structures and operations in the StdPackage namespace. Usually a package also provides a static class for convenience, with the same name as the domain. Except some shortcuts for convenience (e.g. some overloaded operators on the signal class) the framework core and backend neither refer to nor know anything about this package. If you instantiate a project this package is loaded automatically. However, if you work with the core classes directly (Context, Signal, etc.) you have to load it yourself if you intend to use it (you don't have to):
The standard package defines the following data structures at the moment:
- Logic (3-value logic, extensible to IEEE1164 9-value logic as used in VHDL)
- Toggle (useful e.g. for clocks)