Variable
Contents
- 1 Intro
- 2 Solution
- 3 Assumptions
- 4 Standard model
- 5 Standard modelling in Layer0
- 6 Frequent cases
- 7 Varible space modelling
- 8 Modelling of related concepts
- 9 Standard variables
- 10 Experiment modelling
- 11 Validation scenario
Intro
This interface is the most important abstraction in Simantics between the user and the implementation. Variable interfaces addresses
- Browsing of the model structure (see Model Browser)
- Browsing and manipulation of objects (see Selection View)
- Tabular data (see Spreadsheets)
The implementation of Simantics variables combines data from ontological definitions, modelled structures and custom implementation in integrated software plugins. The interface needs to address
- Ontological data
- Modelled reusable and procedural structures (see Structural)
- Runtime data of solvers (see Experiments)
- Historical data stored in the database
The solution includes
- Establishing the concept of a context which represents a unique structure and valuation for a model.
- Establishing a contextual varible identity for referencing the same variable in different contexts.
Identified technical issues include
- On-demand generation of semantic representation
- Textual and semantic variable identities with conversions for user manipulation and database persistence
- Unit conversions
- Value formatting
- Textual user input parsing and validation
- Modelling and evaluation of expressions
- Representation of time series values
Solution
The following concepts are identifier
- A model is a container for all data related to some user task e.g. simulation model.
- A variable is an interface with means for producing children, properties and value
- A context is an entity under a model which spans a set of variables specified by paths
- A path is an identifier which can be used to retrieve a variable from given context
- A path separator which identifies traversal of parents based on role. Specified separators are '.', '/', '#'
The specified roles are defined as
- Parent variable is denoted by the '.' separator
- Children are denoted by the '/' separator.
- Properties are denoted by the '#' separator. All properties contain a value.
Procedural children and variables are used with large data sets. E.g. query-based views can be exposed. Procedural properties also enable efficient slicing of arrays e.g. URI#Array_Property/0-99
A model typically contains a number of contexts which are browsed using the Variable interface. Typical contexts are//
- The base context, which can be used to browse the structure and configuration values of the model
- Configuration value contexts with e.g. set point values for some variables
- Experiment contexts with structure and values retrieved from simulator using Databoard Accessor interface
Generic tools such as Model Browser, Selection View, Diagram, Chart, Spreadsheet, OperationUI use the the path identifiers to refer to their data. Once a desired Variable has been obtained its value can be accessed using direct database requests or Databoard Accessor.
The variable system processes two kinds of textual identifiers
- A URI is a complete reference to a variable
- Examples:
- Models and contexts are identified by URIs
- A path is a relative reference to a variable based on another variable
- A path can contain a number of leading parent steps denoted by '.'
- Examples:
- /Diagram/PI_X#PI_MASS_FLOW
- ./Diagram2/PI_X#PI_MASS_FLOW#HasDatatype
Path identifiers can also be serialized into graph representation, which is name-independent and survives export/import. In e.g. structural this is an ordered set of path separators and configuration resources.
Assumptions
- §1 Everything after '#' has a value
- §2 For all realization resources a variable can be obtained by graph.adapt(r, Variable.class)
- §3 For all realization resources the variable URI equals graph.getURI(r)
- §4 A variable can be part of at most one Context
- §5 A variable can be part of at most one Model
- $6 All values can be accessed using either Variable.getValue or Variable.getInterface(Accessor.class)
- $7 All properties retrieved using Variable.browseProperties shall be available using Variable.getProperty
Standard model
Standard modelling in Layer0
Standard required properties
For all variables
- NAME: String
The name of the resource exactly as in the URI.
- LABEL: String
The standard textual representation for the variable.
- TYPE: Resource
A single type related to the variable.
- URI: String
The variable URI, see Implementations
- SERIALIZED: String
An immutable string identified for this part
- PARENT: Variable
The parent variable
- ROLE: Role
Is Role.Property if URI contains '#', else is Role.Child. If role is Role.Property, then the variable has a value.
- CONTEXT : Variable
The context variable of this variable. The URI of the context variable is a prefix of the URI of this variable.
- CHILD_COUNT: Integer
The amount of children.
- PROPERTY_COUNT: Integer
The amount of properties.
For variables, where Role is Role.Child
- REPRESENTS: Resource
The configuration resource related to this variable.
For variables, where Role is Role.Property
- REPRESENTS: Resource
The literal resource related to this variable.
- EXPRESSION: String
The expression for determining the value of the property. Null if there is no expression.
- PROPERTY_RESOURCE: Resource
The property ( <R L0.HasProperty) resource related to this variable.
- CONTAINER_RESOURCE: Resource
The subject of the property statement.
- DATATYPE: Datatype
The data type of the property.
- VALUE_LABEL: String
A descriptive representation of the value. Applies all modelled formatting. Used in user interface.
Standard adapters
- org.simantics.db.layer0.variable.VariableSpaceManipulator: for modifying the variable space
- org.simantics.db.layer0.variable.InputValidator: for validating user input
- org.simantics.db.layer0.variable.Formatter: for representing values
- org.simantics.databoard.units.IUnitConverter: for representing values according to user needs
Standard implementation
org.simantics.db.layer0.variable.StandardRealizationVariable(resource)
- Children with ChildMapOfResource(resource) + adapt(child, Variable.class)
- Literal-valued properties with PropertyMapOfResource(resource) + adapt(resource, PropertyFactory.class)
- Resource-valued properties with FunctionalRelationMapOfResource(resource)
org.simantics.db.layer0.variable.StandardPropertyVariable(variable, resource)
- Children with ChildMapOfResource + adapt(Variable.class)
- Properties with PropertyMapOfResource + adapt(PropertyFactory.class)
org.simantics.db.layer0.variable.StandardPropertyFactory
The standard implementations are ResourceVariable and PropertyVariable. ResourceVariable is based on a single resource with a named PartOf chain to RootLibrary. PropertyVariable is based on a pair of Variable and Resource <R HasProperty.
In the standard implementation
- getChild returns all named children of the associated resource linked with ConsistsOf and adapted to Variable
- getProperty collects all p so that there exists (s, p <R L0.HasProperty, o) and adapts them to PropertyVariableFactory which is used to create the Variable
- PropertyVariable additionally also includes all p <R L0.HasProperty browsed from the object of its corresponding statement
- getValue for PropertyVariable first searches for L0.HasExpression from the object of its corresponding statement and tries to adapt org.simantics.db.layer0.variable.Expression from its object. If this fails PropertyVariable tries ReadGraph.getValue from the object of its corresponding statement
- browse(ReadGraph, Resource) uses getChild with URIStringUtils.escape(graph.getRelatedValue(resource, b.HasName))
- browse(ReadGraph, String) uses getChild and getProperty for browsing segments starting with '#' and '/' and browse(ReadGraph, String) from RootLibrary for the RVI with the last segment removed
- getURI uses ReadGraph.getURI for ResourceVariable and variable.getURI + "#" + URIStringUtils.escape(graph.getRelatedValue(resource, b.HasName)) for PropertyVariable
Frequent cases
1. Given variable v, obtain model
Procedure: call Variables.getModel(graph, v)
2. Given variable v, obtain realization
Procedure: call Variables.getRealization(graph, v)
3. Given Variable URI, obtain Variable
Procedure: call Variables.getVariable(graph, uri)
4. Given Variable URI, obtain textual RVI
Procedure: call Variables.getRVI(graph, v)
5. Given a configuration resource r and context variable obtain variable
Procedure: call Variable.browse(graph, r)
6. Given two variables v1 and v2, obtain RVI of second based on first
call Variables.getRVI(graph, v1, v2)
7. Given Realization URI and RVI, obtain Variable
call Variables.getVariable(graph, uri, rvi)
8. Obtain string representation for value of Variable v
-Obtain value val (Object) by v.getValue() -Obtain converter c by v.getInterface(IUnitConverter.class) -Obtain converted value cval (Object) by c.convert(val) -Obtain formatter f by v.getInterface(Formatter.class) -Obtain String representation by f.format(cval)
Varible space modelling
Cases
Datatypes
Record
- All named fields are '/name'
- Tuples are named after position e.g. '/11'
Union
- Union does not show in URI
Array
- Elements are named after position e.g. '/11'
Map
- Items are named after key
Take for example http://www.asd.org/Project/AprosModel1/BaseRealization/a/TA_1#TA11_POINT_ELEV
Property sets
Two alternatives
Set is also a value
http://www.asd.org/Project/BalasModel1/BaseRealization/Valve1/FSET#Set1/Flowrate
Set1 is now a Databoard record.
Only items are values
http://www.asd.org/Project/BalasModel1/BaseRealization/Valve1/FSET/Set1#Flowrate
Units
Formatting
Standard variables
Cases
Inferred configuration values from structural
Expressions
Variable syntax in SCL
- Implement variable interface methods as normal functions
- Example:
browse entrypoint "./Out#sdf"
- Example:
- Use . and #-for browsing
- How to browse parent? Explicit function
- Example:
(parent entrypoint).Out#sdf
- Special operator for parents (binds stronger than . or #):
- Example:
!entrypoint.Out#sdf
- Resolve entrypoints in the context
- Example:
Out#sdf
- Local variable definitions may shadow context
- Example:
Experiment modelling
Each running or stored historical experiment in Simantics is modelled as a realization under the Model. Realizations have URIs as defined by ReadGraph.getURI. Some realizations are entirely backed by the semantic graph and some are backed by an Accessor provided by a running simulator or a time series stored as a file in the semantic graph. The structure of the Variable tree under the realization is generated from the semantic model configuration and can be implemented in different ways ranging from persistent graph to lazily produced transient virtual graph. The realizations are browsed using Variable interface methods and variable values can be obtained using Variable methods or by obtaining Databoard Accessor using Variable.getInterface. Each variable serves an instantaneous value and each variable can also contain a property which serves a time series associated to the variable such as in historical data or sampled history of a running experiment.
Validation scenario
The standard model is validated in a headless structural-based setup with
- Structural configuration with joined diagrams and reusable component types
- Procedural children provided by simulator
- Accessor-backed simulator