├── .github └── workflows │ └── build.yml ├── .gitignore ├── .idea ├── .gitignore ├── .name ├── codeStyles │ ├── Project.xml │ └── codeStyleConfig.xml ├── compiler.xml ├── gradle.xml ├── jarRepositories.xml ├── kotlinc.xml ├── libraries │ └── antlr_4_8_complete.xml ├── misc.xml ├── sbt.xml ├── scala_compiler.xml └── vcs.xml ├── Dockerfile ├── DockerfileFuseki ├── LICENSE.txt ├── README.md ├── SMOL_Logo_transparent.png ├── build.gradle ├── domain.pdf ├── editor-support ├── atom │ ├── README.md │ └── language-smol │ │ ├── grammars │ │ └── smol.cson │ │ ├── package.json │ │ ├── settings │ │ └── language-smol.cson │ │ ├── snippets │ │ └── language-smol.cson │ │ └── spec │ │ └── language-smol-spec.coffee └── emacs │ ├── README.md │ ├── smol-mode.el │ └── snippets │ └── smol-mode │ └── class ├── eval ├── TTT_class_schema.smol ├── TTT_rule_schema.smol ├── eval_class.imo ├── eval_rule.imo └── generate.sh ├── examples ├── Cosim.smol ├── Deprecated │ ├── OvenTwin │ │ ├── Connector.smol │ │ ├── just.imo │ │ └── ovens.owl │ ├── README.md │ ├── geo.back │ ├── geo.imo │ └── geo.smol ├── DummyFMUs │ ├── Clock.fmu │ ├── Controller.fmu │ ├── FMUDummiesTotal.mo │ ├── InnerWall.fmu │ ├── NewRoom.fmu │ ├── OuterWall.fmu │ └── Room.fmu ├── Geological │ ├── alternative.smol │ ├── microex.ttl │ ├── simulate_onto.smol │ └── total_mini.ttl ├── House │ ├── README.txt │ ├── osphouse.smol │ ├── osphouseV2.smol │ ├── osphouseV3.smol │ ├── rooms.owl │ └── shape.ttl ├── Orchestrate │ ├── Gauss.smol │ └── Jacobi.smol ├── Shadow │ ├── Realsys.fmu │ ├── Sim.fmu │ ├── detect.smol │ ├── series.smol │ └── shadow.smol ├── SimulationDemo │ ├── Linear.fmu │ ├── Linear.smol │ ├── LinearObjects.smol │ ├── Predator.fmu │ ├── Predator.mo │ ├── Prey.fmu │ ├── Prey.mo │ ├── Tank.fmu │ ├── Tank.smol │ ├── Test.mo │ ├── lotka-volterra.smol │ ├── lv-plus.smol │ └── lv-simple.smol ├── TTT.imo ├── Tutorial │ ├── Controller.fmu │ ├── README.md │ ├── Room.fmu │ ├── Wall.fmu │ ├── demo1.smol │ ├── demo2.owl │ ├── demo2.smol │ ├── demo3.owl │ ├── demo3.smol │ ├── demo_cloud.owl │ ├── demo_cloud.smol │ └── demo_semantic.smol ├── TwoThreeTree.back ├── University │ ├── university.imo │ ├── university.smol │ └── university.ttl ├── Virtualization │ ├── virtualization.imo │ ├── virtualization.smol │ └── virtualization.ttl ├── adder.fmu ├── bug.smol ├── construct.smol ├── destroy.smol ├── double.imo ├── double.rq ├── double.ttl ├── external.ttl ├── influx.smol ├── models.smol ├── newbackgeo.rule ├── newgeo.owl ├── newgeo.rule ├── newgeo.smol ├── overload.back ├── overload.imo ├── persons.back ├── scene.imo ├── shape.ttl ├── simulate.imo ├── translatescene.smol ├── tree_shapes.ttl ├── tutorial_day1.pdf ├── tutorial_day2.pdf ├── tutorialfiles.zip └── type_query.smol ├── execute_case.sh ├── fuseki_server_test.sh ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── settings.gradle ├── src ├── main │ ├── antlr │ │ └── While.g4 │ ├── kotlin │ │ └── no │ │ │ └── uio │ │ │ └── microobject │ │ │ ├── ast │ │ │ ├── AST.kt │ │ │ ├── Translate.kt │ │ │ ├── expr │ │ │ │ ├── ArithExpr.kt │ │ │ │ ├── ConversionExpr.kt │ │ │ │ ├── LiteralExpr.kt │ │ │ │ ├── LocalVar.kt │ │ │ │ ├── OthersVar.kt │ │ │ │ └── OwnVar.kt │ │ │ └── stmt │ │ │ │ ├── AccessStmt.kt │ │ │ │ ├── AdaptStmt.kt │ │ │ │ ├── AssignStmt.kt │ │ │ │ ├── CallStmt.kt │ │ │ │ ├── ClassifyStmt.kt │ │ │ │ ├── ConstructStmt.kt │ │ │ │ ├── CreateStmt.kt │ │ │ │ ├── DebugStmt.kt │ │ │ │ ├── DestroyStmt.kt │ │ │ │ ├── IfStmt.kt │ │ │ │ ├── OwlStmt.kt │ │ │ │ ├── PrintStmt.kt │ │ │ │ ├── ReturnStmt.kt │ │ │ │ ├── SequenceStmt.kt │ │ │ │ ├── SimulationStmt.kt │ │ │ │ ├── SkipStmt.kt │ │ │ │ ├── StoreReturnStmt.kt │ │ │ │ ├── SuperStmt.kt │ │ │ │ ├── TickStmt.kt │ │ │ │ ├── ValidateStmt.kt │ │ │ │ └── WhileStmt.kt │ │ │ ├── data │ │ │ └── TripleManager.kt │ │ │ ├── main │ │ │ └── MainKt.kt │ │ │ ├── runtime │ │ │ ├── Interpreter.kt │ │ │ ├── REPL.kt │ │ │ ├── Simulation.kt │ │ │ └── State.kt │ │ │ └── type │ │ │ ├── QueryChecker.kt │ │ │ ├── TypeChecker.kt │ │ │ ├── TypeErrors.kt │ │ │ └── Types.kt │ └── resources │ │ ├── StdLib.smol │ │ └── vocab.owl └── test │ ├── kotlin │ └── no │ │ └── uio │ │ └── microobject │ │ └── test │ │ ├── MicroObjectTest.kt │ │ ├── RegressionTests.kt │ │ ├── ast │ │ └── stmt │ │ │ ├── AdaptationTest.kt │ │ │ └── ClassificationTest.kt │ │ ├── basic │ │ ├── BasicTest.kt │ │ └── ExtraPrefixTest.kt │ │ ├── data │ │ └── TripleManagerTest.kt │ │ ├── execution │ │ ├── AdaptTest.kt │ │ ├── FMOLExecutionTest.kt │ │ ├── MOLExecutionTest.kt │ │ └── SMOLExecutionTest.kt │ │ ├── runtime │ │ └── Interpreter.kt │ │ ├── triples │ │ ├── OWLQueryTest.kt │ │ └── SparqlCountTest.kt │ │ └── type │ │ ├── FMOLTypeTest.kt │ │ ├── MOLTypeTest.kt │ │ ├── MicroObjectTypeTest.kt │ │ └── SMOLTypeTest.kt │ └── resources │ ├── Jacobi.smol │ ├── TwoThreeTree.smol │ ├── adder.fmu │ ├── bug_10.smol │ ├── bug_33.smol │ ├── classification.smol │ ├── classification_example.ttl │ ├── const.ttl │ ├── conversion.smol │ ├── destroy.smol │ ├── docker_fuseki_config.ttl │ ├── double.smol │ ├── eval-params.smol │ ├── innerField1.smol │ ├── innerField2.smol │ ├── linear.fmu │ ├── literalQuery.smol │ ├── models.owl │ ├── models.smol │ ├── overload.smol │ ├── persons.smol │ ├── poly.smol │ ├── reclassification.smol │ ├── reclassification │ ├── Tree.smol │ ├── Tree_union.smol │ └── tree.ttl │ ├── scene.smol │ ├── selfadapt │ ├── GreenHouse.smol │ ├── Greenhouse_data.smol │ ├── Greenhouse_health.smol │ ├── Greenhouse_plants.smol │ ├── Greenhouse_pots.smol │ ├── Greenhouse_pumps.smol │ └── greenhouse.ttl │ ├── strings.smol │ ├── test_assign.smol │ ├── test_call.smol │ ├── test_construct.smol │ ├── test_fmu.smol │ ├── test_generic.smol │ ├── test_override.smol │ ├── tree_shapes.ttl │ ├── type_query.smol │ └── types.smol └── website ├── .envrc ├── Makefile ├── Pipfile ├── Pipfile.lock ├── README.md ├── make.bat ├── smol.ebnf └── source ├── conf.py ├── files └── tutorial_ictac2022 │ ├── demo_day1.pdf │ └── demo_day2.pdf ├── getting-started.rst ├── glossary.rst ├── images ├── SMOL_Circular_Small.png ├── SMOL_Logo_transparent.png ├── alone.pdf ├── alone.png ├── conceptual-layers.svg ├── drawio │ ├── conceptual-layers.drawio │ ├── house-asset-use-case.drawio │ ├── owl-example.drawio │ └── rdf-example.drawio ├── house-asset-use-case.svg ├── house-asset-use-case_2.svg ├── owl-example.svg └── rdf-example.svg ├── index.rst ├── internals.rst ├── introduction.rst ├── lab.rst ├── language.rst ├── language ├── classes.rst ├── datatypes.rst ├── expressions.rst ├── fmos.rst ├── lexical-structure.rst ├── semantic-access.rst └── statements.rst ├── publications.rst ├── tutorial.rst └── tutorial ├── digital-twins.rst ├── knowledge-modelling.rst ├── modelling-physical-systems.rst └── semantical-reflection.rst /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Build SMOL 2 | 3 | on: 4 | push: 5 | 6 | jobs: 7 | build-smol: 8 | runs-on: ubuntu-latest 9 | steps: 10 | - name: Checkout project sources 11 | uses: actions/checkout@v2 12 | - name: Setup Gradle 13 | uses: gradle/gradle-build-action@v2 14 | - name: Run build with Gradle Wrapper 15 | run: ./gradlew build 16 | 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Project exclude paths 2 | .vscode/ 3 | /.gradle/ 4 | /build/ 5 | /build/classes/java/main/ 6 | *.elc 7 | # paranoia: ignore data files that might contain API tokens 8 | /examples/**/*.yml 9 | /src/test/**/*.yml 10 | .DS_Store 11 | /bin/ 12 | /website/build/ 13 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | /.name 5 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | MicroObjects -------------------------------------------------------------------------------- /.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 10 | 12 | 13 | -------------------------------------------------------------------------------- /.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 20 | 21 | -------------------------------------------------------------------------------- /.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | -------------------------------------------------------------------------------- /.idea/kotlinc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/libraries/antlr_4_8_complete.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /.idea/sbt.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /.idea/scala_compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1.3-labs 2 | 3 | # To build the container: 4 | # docker build -t smol . 5 | # To run smol in the current directory: 6 | # docker run -it --rm -v "$PWD":/root/smol smol 7 | FROM ubuntu:latest 8 | RUN < 2 | 3 |

4 | 5 | This repository contains an interactive interpreter for **SMOL**, a 6 | minimal object-oriented language with integrated semantic state 7 | access. The interpreter can be used to examine the state with SPARQL, 8 | SHACL and OWL queries. 9 | 10 | The language is in development, for a general description, examples and tutorial to SMOL, we refer to [its webpage](https://smolang.org). 11 | 12 | 13 | To compile and run the SMOL REPL, run 14 | ``` 15 | ./gradlew build 16 | java -jar build/libs/smol.jar --help 17 | ``` 18 | 19 | To run the SMOL REPL pre-compiled using docker, run the following command: 20 | ``` 21 | docker run -it --rm -v "$PWD":/root/smol ghcr.io/smolang/smol:latest 22 | ``` 23 | 24 | To compile and run the SMOL REPL inside docker, run the following commands: 25 | ``` 26 | docker build -t smol . 27 | docker run -it --rm -v "$PWD":/root/smol smol 28 | ``` 29 | -------------------------------------------------------------------------------- /SMOL_Logo_transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/SMOL_Logo_transparent.png -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'org.jetbrains.kotlin.jvm' version '1.6.21' 3 | id 'com.github.johnrengelman.shadow' version '5.2.0' 4 | id 'antlr' 5 | id "kr.motd.sphinx" version "2.10.0" 6 | id 'scala' 7 | } 8 | 9 | group = 'org.smolang' 10 | version = '0.4' 11 | 12 | java { 13 | toolchain { 14 | languageVersion.set(JavaLanguageVersion.of(11)) 15 | } 16 | } 17 | 18 | repositories { 19 | mavenCentral() 20 | maven { url "https://overture.au.dk/artifactory/libs-release/" } 21 | } 22 | 23 | test { 24 | useJUnitPlatform() 25 | } 26 | sourceSets { 27 | main { 28 | java.srcDirs += 'build/generated-src/main' 29 | kotlin.srcDirs += 'build/generated-src/main' 30 | antlr.srcDirs += 'src/main/antlr' 31 | } 32 | } 33 | dependencies { 34 | implementation 'com.google.guava:guava:22.0' 35 | testImplementation 'io.kotest:kotest-runner-junit5:5.2.3' 36 | testImplementation 'org.jetbrains.kotlin:kotlin-test-junit' 37 | testImplementation 'org.apache.commons:commons-lang3:3.12.0' 38 | testImplementation 'org.apache.jena:jena-fuseki-main:3.16.0' 39 | implementation 'com.github.ajalt.clikt:clikt:3.4.2' 40 | implementation 'org.antlr:antlr4:4.8' 41 | antlr 'org.antlr:antlr4:4.8' 42 | implementation 'net.sourceforge.owlapi:org.semanticweb.hermit:1.4.5.519' 43 | implementation 'org.slf4j:slf4j-simple:1.7.25' 44 | implementation 'org.apache.jena:apache-jena-libs:3.16.0' 45 | implementation 'org.apache.jena:jena-core:3.16.0' 46 | implementation 'org.siani.javafmi:fmu-wrapper:2.26.3' 47 | implementation "com.influxdb:influxdb-client-kotlin:2.3.0" 48 | implementation 'com.sksamuel.hoplite:hoplite-core:1.4.1' 49 | implementation 'com.sksamuel.hoplite:hoplite-yaml:1.4.1' 50 | implementation 'com.github.owlcs:ontapi:2.1.0' 51 | implementation 'org.jline:jline:3.21.0' 52 | } 53 | 54 | 55 | generateGrammarSource { 56 | outputDirectory = file("build/generated-src/main/no/uio/microobject/antlr") 57 | arguments += ["-visitor"] 58 | } 59 | 60 | compileKotlin { 61 | kotlinOptions.jvmTarget = project.sourceCompatibility 62 | } 63 | compileKotlin.dependsOn generateGrammarSource 64 | 65 | compileTestKotlin.dependsOn generateTestGrammarSource 66 | 67 | jar { 68 | archiveFileName='smol.jar' 69 | manifest { 70 | attributes 'Main-Class': 'no.uio.microobject.main.MainKtKt' 71 | } 72 | } 73 | shadowJar { 74 | archiveFileName='smol.jar' 75 | } 76 | assemble.dependsOn shadowJar 77 | 78 | sphinx { 79 | // Documentation at 80 | // https://trustin.github.io/sphinx-gradle-plugin/index.html 81 | sourceDirectory = "${projectDir}/website/source" 82 | configDirectory = "${projectDir}/website/source" 83 | outputDirectory = "${projectDir}/website/build/html" 84 | builder = "html" 85 | } 86 | clean { 87 | delete files("${projectDir}/website/build") 88 | } 89 | -------------------------------------------------------------------------------- /domain.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/domain.pdf -------------------------------------------------------------------------------- /editor-support/atom/README.md: -------------------------------------------------------------------------------- 1 | Title: Atom Editor Support for SMOL 2 | 3 | This directory contains files to add SMOL support to the Atom editor. 4 | 5 | # Installation 6 | 7 | To activate it, issue the following shell commands: 8 | 9 | ```shell 10 | cd ~/.atom/packages 11 | ln -s /path/to/SemanticObjects/editor-support/atom/language-smol language-smol 12 | ``` 13 | 14 | Afterwards, files with the extension `.smol` will be opened in `smol-mode`. 15 | 16 | # Random Development Notes 17 | 18 | `Ctrl-Shift-Cmd-R`: live reload themes, packages (package `dev-live-reload`) 19 | 20 | 21 | Good sample grammar: [GitHub - JeremyHeleine/language-scilab: Scilab 22 | language support in 23 | Atom](https://github.com/JeremyHeleine/language-scilab) 24 | 25 | Tutorial-in-progress: [Creating a 26 | Grammar](https://flight-manual.atom.io/hacking-atom/sections/creating-a-grammar/) 27 | 28 | Regex documentation: [oniguruma/RE at master · kkos/oniguruma · 29 | GitHub](https://github.com/kkos/oniguruma/blob/master/doc/RE) 30 | -------------------------------------------------------------------------------- /editor-support/atom/language-smol/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "language-smol", 3 | "version": "0.0.0", 4 | "description": "Atom support for the SMOL language (http://abs-models.org)", 5 | "keywords": [ 6 | "language", 7 | "grammar" 8 | ], 9 | "repository": "https://github.com/Edkamb/SemanticObjects", 10 | "license": "MIT", 11 | "engines": { 12 | "atom": ">=1.0.0 <2.0.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /editor-support/atom/language-smol/settings/language-smol.cson: -------------------------------------------------------------------------------- 1 | # If you want some examples of settings, check out: 2 | # https://github.com/atom/language-gfm/blob/master/settings/gfm.cson 3 | 4 | '.source.smol': 5 | 'editor': 6 | 'commentStart': '// ' 7 | -------------------------------------------------------------------------------- /editor-support/atom/language-smol/snippets/language-smol.cson: -------------------------------------------------------------------------------- 1 | # If you want some example snippets, check out: 2 | # https://github.com/atom/language-javascript/blob/master/snippets/javascript.cson 3 | 4 | '.source.smol': 5 | 'Method documentation': 6 | 'prefix': 'doc' 7 | 'body': '// ${1:method} - ${2:description}' 8 | -------------------------------------------------------------------------------- /editor-support/atom/language-smol/spec/language-smol-spec.coffee: -------------------------------------------------------------------------------- 1 | # If you want an example of language specs, check out: 2 | # https://github.com/atom/language-javascript/blob/master/spec/javascript-spec.coffee 3 | 4 | describe "Smol grammar", -> 5 | grammar = null 6 | 7 | beforeEach -> 8 | waitsForPromise -> 9 | atom.packages.activatePackage("language-smol") 10 | 11 | runs -> 12 | grammar = atom.syntax.grammarForScopeName("source.smol") 13 | 14 | it "parses the grammar", -> 15 | expect(grammar).toBeTruthy() 16 | expect(grammar.scopeName).toBe "source.smol" 17 | -------------------------------------------------------------------------------- /editor-support/emacs/README.md: -------------------------------------------------------------------------------- 1 | Title: Emacs Editor Support for SMOL 2 | 3 | This directory contains files to add SMOL support to the Emacs editor. 4 | 5 | # Installation 6 | 7 | To activate it, add the following command to your Emacs init file (typically 8 | `~/.emacs.d/init.el`): 9 | 10 | ```elisp 11 | (load "/path/to/SemanticObjects/editor-support/emacs/smol-mode") 12 | ``` 13 | 14 | Afterwards, files with the extension `.smol` will be opened in `smol-mode`. 15 | 16 | # Running a SMOL REPL inside Emacs 17 | 18 | To run a SMOL REPL inside Emacs, set the variable `smol-jar-file` to the path 19 | of the SMOL jar file, e.g. via 20 | 21 | ```elisp 22 | (setq smol-jar-file "/path/to/SemanticObjects/build/libs/smol.jar") 23 | ``` 24 | -------------------------------------------------------------------------------- /editor-support/emacs/snippets/smol-mode/class: -------------------------------------------------------------------------------- 1 | # -*- mode: snippet; -*- 2 | # name: class 3 | # key: class 4 | # -- 5 | ${1:abstract }class ${2:ClassName} ${3:<${4:ClassParam}> }${5:extends ${6:Superclass} }(${7:type fieldname}) 6 | $0 7 | end 8 | -------------------------------------------------------------------------------- /eval/eval_class.imo: -------------------------------------------------------------------------------- 1 | auto 2 | class ( value ) 3 | -------------------------------------------------------------------------------- /eval/eval_rule.imo: -------------------------------------------------------------------------------- 1 | auto 2 | -------------------------------------------------------------------------------- /eval/generate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | cp TTT_class_schema.smol TTT_class_$1.smol 4 | cp TTT_rule_schema.smol TTT_rule_$1.smol 5 | sed -i 's/VAR/'$1'/g' TTT_class_$1.smol 6 | sed -i 's/VAR/'$1'/g' TTT_rule_$1.smol 7 | -------------------------------------------------------------------------------- /examples/Cosim.smol: -------------------------------------------------------------------------------- 1 | main 2 | //beware: path is relative to interpreter instance, not this file 3 | FMO[Int integer_a, Int integer_b; Int integer_c] de = simulate("examples/adder.fmu", integer_a=1, integer_b=2); 4 | Int i = de.integer_c; 5 | print(i); 6 | de.tick(1); 7 | de.integer_a = i; 8 | i = de.integer_c; 9 | print(i); 10 | end 11 | -------------------------------------------------------------------------------- /examples/Deprecated/OvenTwin/just.imo: -------------------------------------------------------------------------------- 1 | auto 2 | dump 3 | exit 4 | -------------------------------------------------------------------------------- /examples/Deprecated/README.md: -------------------------------------------------------------------------------- 1 | This directory contains some older examples that are not updated because they are not compatible with new features (`construct` and types). -------------------------------------------------------------------------------- /examples/Deprecated/geo.back: -------------------------------------------------------------------------------- 1 | :HasAnyNullNext rdf:type owl:Class ; 2 | owl:equivalentClass [ rdf:type owl:Restriction ; 3 | owl:onProperty prog:List_next ; 4 | owl:hasValue smol:null 5 | ] . 6 | -------------------------------------------------------------------------------- /examples/Deprecated/geo.imo: -------------------------------------------------------------------------------- 1 | auto 2 | query SELECT ?obj WHERE { ?obj a prog:GeoUnit. ?obj :GeoElement_sealing :1} 3 | query SELECT ?obj ?dir ?elem WHERE { ?obj a :GeoUnit. ?obj ?dir ?elem. ?elem a prog:Fault} 4 | query SELECT ?obj ?elem WHERE { ?obj a prog:LeftHydrocarbonMigration. ?obj prog:LeftHydrocarbonMigration_gu ?elem. ?elem a prog:GeoUnit} 5 | query SELECT ?obj WHERE { ?obj a prog:GeoUnit. ?obj prog:GeoElement_migration ?elem. ?elem a prog:LeftHydrocarbonMigration} 6 | -------------------------------------------------------------------------------- /examples/DummyFMUs/Clock.fmu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/DummyFMUs/Clock.fmu -------------------------------------------------------------------------------- /examples/DummyFMUs/Controller.fmu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/DummyFMUs/Controller.fmu -------------------------------------------------------------------------------- /examples/DummyFMUs/FMUDummiesTotal.mo: -------------------------------------------------------------------------------- 1 | package FMUDummies 2 | /* These FMUs do nothing, but can be loaded for type checking */ 3 | block Clock 4 | output Real clock; 5 | equation 6 | clock = 1; 7 | end Clock; 8 | 9 | block InnerWall 10 | input Real t_areaLeft; 11 | input Real t_areaRight; 12 | output Real h_wall; 13 | equation 14 | h_wall = t_areaLeft + t_areaRight; 15 | end InnerWall; 16 | 17 | block OuterWall 18 | input Real t_areaLeft; 19 | input Real t_areaRight; 20 | output Real h_wall; 21 | equation 22 | h_wall = t_areaLeft + t_areaRight * 0.5; 23 | end OuterWall; 24 | 25 | block Room 26 | input Real h_wallLeft; 27 | input Real h_wallRight; 28 | input Real h_powerHeater; 29 | output Real t_room; 30 | equation 31 | t_room = h_wallLeft + h_wallRight; 32 | end Room; 33 | 34 | block NewRoom 35 | input Real h_wallLeft; 36 | input Real h_wallRight; 37 | input Real h_powerHeater; 38 | output Real t_room; 39 | equation 40 | t_room = h_wallLeft + h_wallRight + 1; 41 | end NewRoom; 42 | 43 | block Controller 44 | input Real t_roomLeft; 45 | input Real t_roomRight; 46 | output Real h_roomLeft; 47 | output Real h_roomRight; 48 | equation 49 | h_roomLeft = t_roomLeft + t_roomRight + 1; 50 | h_roomRight = t_roomLeft + t_roomRight - 1; 51 | end Controller; 52 | 53 | /* These FMUs do nothing, but can be loaded for type checking */ 54 | end FMUDummies; -------------------------------------------------------------------------------- /examples/DummyFMUs/InnerWall.fmu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/DummyFMUs/InnerWall.fmu -------------------------------------------------------------------------------- /examples/DummyFMUs/NewRoom.fmu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/DummyFMUs/NewRoom.fmu -------------------------------------------------------------------------------- /examples/DummyFMUs/OuterWall.fmu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/DummyFMUs/OuterWall.fmu -------------------------------------------------------------------------------- /examples/DummyFMUs/Room.fmu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/DummyFMUs/Room.fmu -------------------------------------------------------------------------------- /examples/House/README.txt: -------------------------------------------------------------------------------- 1 | These examples need to run on Linux or in docker. 2 | 3 | To run these examples, start the SMOL REPL at the root directory of the 4 | project so that the paths to the FMUs and ttl file resolve: 5 | 6 | $ docker run -it --rm -v "$PWD":/root/smol smol 7 | Interactive shell started. 8 | MO> read examples/House/osphouseV2.smol 9 | 10 | To prepare the docker image, run the following command in the root directory of the project: 11 | 12 | $ docker build -t smol . 13 | -------------------------------------------------------------------------------- /examples/House/shape.ttl: -------------------------------------------------------------------------------- 1 | @prefix schema: . 2 | @prefix sh: . 3 | 4 | schema:RWLeftShape 5 | a sh:NodeShape ; 6 | sh:targetClass prog:Room ; 7 | sh:property [ 8 | sh:path (prog:Room_wallLeft prog:Wall_areaRight) ; 9 | sh:value sh:this ; 10 | sh:name "Connection left" ; 11 | ] 12 | . 13 | 14 | schema:RWRightShape 15 | a sh:NodeShape ; 16 | sh:targetClass prog:Room ; 17 | sh:property [ 18 | sh:path (prog:Room_wallRight prog:Wall_areaLeft) ; 19 | sh:value sh:this ; 20 | sh:name "Connection right" ; 21 | ] 22 | . 23 | 24 | 25 | schema:FirstShape 26 | a sh:NodeShape ; 27 | sh:targetClass prog:House ; 28 | sh:property [ 29 | sh:path (prog:House_firstRoom prog:Room_wallLeft prog:Wall_areaLeft) ; 30 | sh:class prog:Outside; 31 | sh:name "Connection first" ; 32 | ] 33 | . 34 | schema:LastShape 35 | a sh:NodeShape ; 36 | sh:targetClass prog:House ; 37 | sh:property [ 38 | sh:path (prog:House_lastRoom prog:Room_wallRight prog:Wall_areaRight) ; 39 | sh:class prog:Outside; 40 | sh:name "Connection last" ; 41 | ] 42 | . 43 | -------------------------------------------------------------------------------- /examples/Orchestrate/Gauss.smol: -------------------------------------------------------------------------------- 1 | 2 | 3 | //Wrapper for simulators: each simulator can have multiple ports 4 | abstract class OutPort() 5 | abstract T2 get() 6 | end 7 | abstract class InPort() 8 | abstract Boolean write(T3 t) 9 | end 10 | 11 | //Co-sim connection 12 | abstract class Connection() 13 | abstract Int propagate() 14 | end 15 | 16 | class ImplConnection extends Connection (OutPort from, InPort to) 17 | override Int propagate() 18 | Double val = this.from.get(); 19 | this.to.write(val); 20 | return 0; 21 | end 22 | end 23 | 24 | //Gauss master algorithm: propagate through all FMUs, advance time for all FMUs at once 25 | class CoSim(List list, List sims, Double stepSize) 26 | Int round() 27 | Int i = 0; 28 | if this.list == null then return i; end 29 | if this.sims == null then return i; end 30 | Int length = this.list.length(); 31 | while i < length do 32 | Connection c = this.list.get(i); 33 | c.propagate(); 34 | FMO[] de = this.sims.get(i); //note: we do check here that we do not advance twice if an FMU has two output connections 35 | de.tick(this.stepSize); 36 | i = i+1; 37 | end 38 | return i; 39 | end 40 | 41 | Int execute(Int steps) 42 | Int i = 1; 43 | while( i <= steps ) do 44 | this.round(); 45 | i = i+1; 46 | end 47 | return i; 48 | end 49 | end 50 | 51 | //example 52 | class PreyOutPort extends OutPort(FMO[in Double y, out Double x] x) 53 | override Double get() return this.x.x; end 54 | end 55 | class PredatorOutPort extends OutPort(FMO[in Double x, out Double y] y) 56 | override Double get() return this.y.y; end 57 | end 58 | class PreyInPort extends InPort(FMO[in Double y, out Double x] y) 59 | override Boolean write(Double t) this.y.y = t; return True; end 60 | end 61 | class PredatorInPort extends InPort(FMO[in Double x, out Double y] x) 62 | override Boolean write(Double t) print(t); this.x.x = t; return True; end 63 | end 64 | 65 | main 66 | FMO[in Double y, out Double x] prey = simulate("examples/SimulationDemo/Prey.fmu", y = 10); 67 | FMO[in Double x, out Double y] predator = simulate("examples/SimulationDemo/Predator.fmu", x = 10); 68 | PreyOutPort preyOut = new PreyOutPort(prey); 69 | PredatorOutPort predOut = new PredatorOutPort(predator); 70 | PreyInPort preyIn = new PreyInPort(prey); 71 | PredatorInPort predIn = new PredatorInPort(predator); 72 | Connection c1 = new ImplConnection(preyOut, predIn); 73 | Connection c2 = new ImplConnection(predOut, preyIn); 74 | List fmus = new List(prey, null); 75 | fmus = new List(predator, fmus); 76 | List cons = new List(c1, null); 77 | cons = new List(c2, cons); 78 | CoSim sim = new CoSim(cons, fmus, 0.05); 79 | sim.execute(4000); 80 | 81 | List> ll = access("SELECT ?obj WHERE {?con a prog:ImplConnection. ?con prog:ImplConnection_to ?obj}"); 82 | while ll != null do 83 | InPort inp = ll.content; 84 | ll = ll.next; 85 | print(inp); 86 | end 87 | end 88 | -------------------------------------------------------------------------------- /examples/Orchestrate/Jacobi.smol: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | //Wrapper for simulators: each simulator can have multiple ports 5 | abstract class OutPort () 6 | abstract T2 get() 7 | end 8 | abstract class InPort () 9 | abstract Boolean write(T3 t) 10 | end 11 | 12 | //Co-sim connection 13 | abstract class Connection() 14 | abstract Int propagate() 15 | end 16 | 17 | class ImplConnection extends Connection (OutPort from, InPort to) 18 | override Int propagate() 19 | Double val = this.from.get(); 20 | this.to.write(val); 21 | return 0; 22 | end 23 | end 24 | 25 | //Jacobi master algorithm: propagate through all connections, advance time for all FMUs at once 26 | class CoSim(List list, List sims, Double stepSize) 27 | Int round() 28 | Int i = 0; 29 | if this.list == null then return i; end 30 | Int length = this.list.length(); 31 | while i < length do 32 | Connection c = this.list.get(i); 33 | c.propagate(); 34 | i = i+1; 35 | end 36 | i = 0; 37 | if this.sims == null then return i; end 38 | length = this.sims.length(); 39 | while i < length do 40 | FMO[] de = this.sims.get(i); 41 | de.tick(this.stepSize); 42 | i = i + 1; 43 | end 44 | return i; 45 | end 46 | 47 | Int execute(Int steps) 48 | Int i = 1; 49 | while( i <= steps ) do 50 | this.round(); 51 | i = i+1; 52 | end 53 | return i; 54 | end 55 | end 56 | 57 | //example 58 | class PreyOutPort extends OutPort(FMO[in Double y, out Double x] x) 59 | override Double get() return this.x.x; end 60 | end 61 | class PredatorOutPort extends OutPort(FMO[in Double x, out Double y] y) 62 | override Double get() return this.y.y; end 63 | end 64 | class PreyInPort extends InPort(FMO[in Double y, out Double x] y) 65 | override Boolean write(Double t) this.y.y = t; return True; end 66 | end 67 | class PredatorInPort extends InPort(FMO[in Double x, out Double y] x) 68 | override Boolean write(Double t) print(t); this.x.x = t; return True; end 69 | end 70 | 71 | main 72 | FMO[in Double y, out Double x] prey = simulate("examples/SimulationDemo/Prey.fmu", y = 10); 73 | FMO[in Double x, out Double y] predator = simulate("examples/SimulationDemo/Predator.fmu", x = 10); 74 | PreyOutPort preyOut = new PreyOutPort(prey); 75 | PredatorOutPort predOut = new PredatorOutPort(predator); 76 | PreyInPort preyIn = new PreyInPort(prey); 77 | PredatorInPort predIn = new PredatorInPort(predator); 78 | Connection c1 = new ImplConnection(preyOut, predIn); 79 | Connection c2 = new ImplConnection(predOut, preyIn); 80 | List fmus = new List(prey, null); 81 | fmus = new List(predator, fmus); 82 | List cons = new List(c1, null); 83 | cons = new List(c2, cons); 84 | CoSim sim = new CoSim(cons, fmus, 0.01); 85 | sim.execute(20000); 86 | 87 | List> ll = access("SELECT ?obj WHERE {?con a prog:ImplConnection. ?con prog:ImplConnection_to ?obj}"); 88 | while ll != null do 89 | InPort inp = ll.content; 90 | ll = ll.next; 91 | print(inp); 92 | end 93 | end 94 | -------------------------------------------------------------------------------- /examples/Shadow/Realsys.fmu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/Shadow/Realsys.fmu -------------------------------------------------------------------------------- /examples/Shadow/Sim.fmu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/Shadow/Sim.fmu -------------------------------------------------------------------------------- /examples/Shadow/detect.smol: -------------------------------------------------------------------------------- 1 | class Shadow(Double value, Double assumedSlope) 2 | 3 | FMO[out Double value] findNewShadow(Double lastVal, Double sysVal) 4 | print("Anomaly detected, searching for new shadow."); 5 | Double step = 0.0; 6 | FMO[out Double value] shadow = null; 7 | while step <= 5 do 8 | Double assumedSlope = this.assumedSlope + step * 0.2; 9 | shadow = simulate("examples/Shadow/Sim.fmu", iValue = lastVal, slope = assumedSlope); 10 | shadow.tick(1.0); 11 | Double result = shadow.value; 12 | Double diff = sysVal - result; 13 | if(diff <= 0.1) then 14 | print("New shadow found."); 15 | return shadow; 16 | end 17 | step = step + 1.0; 18 | end 19 | print("No new shadow found."); 20 | return null; 21 | end 22 | 23 | Int run() 24 | FMO[out Double value] system = simulate("examples/Shadow/Realsys.fmu", iValue = this.value, slope = this.assumedSlope); 25 | FMO[out Double value] shadow = simulate("examples/Shadow/Sim.fmu", iValue = this.value, slope = this.assumedSlope); 26 | 27 | Int i = 0; 28 | Double lastDiff = 0.0; 29 | Double lastVal = 2.0; 30 | while i <= 200 do 31 | lastVal = system.value; 32 | system.tick(1.0); 33 | shadow.tick(1.0); 34 | Double sysVal = system.value; 35 | Double shaVal = shadow.value; 36 | Double diff = system.value - shadow.value; 37 | if(diff >= 0.1) then 38 | shadow = this.findNewShadow(lastVal, sysVal); 39 | end 40 | i = i + 1; 41 | end 42 | return i; 43 | end 44 | end 45 | 46 | main 47 | Shadow shadow = new Shadow(2.0, 1.0); 48 | shadow.run(); 49 | end 50 | -------------------------------------------------------------------------------- /examples/Shadow/shadow.smol: -------------------------------------------------------------------------------- 1 | main 2 | 3 | FMO[out Double value] system = simulate("examples/Shadow/Realsys.fmu", iValue = 2, slope = 1); 4 | FMO[out Double value] shadow = simulate("examples/Shadow/Sim.fmu", iValue = 2, slope = 1); 5 | 6 | Int i = 0; 7 | while i <= 200 do 8 | system.tick(1.0); 9 | shadow.tick(1.0); 10 | Double sysVal = system.value; 11 | Double shaVal = shadow.value; 12 | Double diff = system.value - shadow.value; 13 | print(diff); 14 | i = i + 1; 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /examples/SimulationDemo/Linear.fmu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/SimulationDemo/Linear.fmu -------------------------------------------------------------------------------- /examples/SimulationDemo/Linear.smol: -------------------------------------------------------------------------------- 1 | main 2 | FMO[out Int outPort, out Int leak] de1 = simulate("examples/SimulationDemo/Linear.fmu", inPort = 2); 3 | FMO[in Int inPort, out Int outPort, out Int leak] de2 = simulate("examples/SimulationDemo/Linear.fmu", inPort = 0); 4 | Int i = 0; 5 | while(i <= 50) do 6 | Int leak = de1.leak; 7 | if leak >= 10 then 8 | de1.inPort = 0; 9 | de2.inPort = 2; 10 | else 11 | if leak >= 1 then 12 | de1.inPort = 1; 13 | de2.inPort = 1; 14 | end 15 | end 16 | 17 | Int df1 = de1.outPort; 18 | Int df2 = de2.outPort; 19 | print("---"); 20 | print(df1); 21 | print(df2); 22 | de1.tick(1); 23 | de2.tick(1); 24 | i = i + 1; 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /examples/SimulationDemo/LinearObjects.smol: -------------------------------------------------------------------------------- 1 | 2 | 3 | class WrappedSimulator(FMO[in Int inPort, out Int outPort, out Int leak] content) end 4 | 5 | class Connection(WrappedSimulator from, WrappedSimulator to) 6 | Int propagate() 7 | Int leak = this.from.content.leak; 8 | if leak >= 10 then 9 | print("big leak"); 10 | this.from.content.inPort = 0; 11 | this.to.content.inPort = 2; 12 | else 13 | if leak >= 1 then 14 | print("small leak"); 15 | this.from.content.inPort = 1; 16 | this.to.content.inPort = 1; 17 | end 18 | end 19 | return leak; 20 | end 21 | end 22 | 23 | class CoSim(List list, List sims) 24 | Int round(Int t) 25 | Int i = 0; 26 | if this.list == null then return i; end 27 | Int length = this.list.length(); 28 | while i < length do 29 | Connection c = this.list.get(i); 30 | c.propagate(); 31 | i = i+1; 32 | end 33 | i = 0; 34 | if this.sims == null then return i; end 35 | length = this.sims.length(); 36 | while i < length do 37 | WrappedSimulator s = this.sims.get(i); 38 | FMO[] de = s.content; 39 | de.tick(t); 40 | i = i + 1; 41 | end 42 | return i; 43 | end 44 | end 45 | 46 | main 47 | FMO[in Int inPort, out Int outPort, out Int leak] de1 = simulate("examples/SimulationDemo/Linear.fmu", inPort = 2); 48 | FMO[in Int inPort, out Int outPort, out Int leak] de2 = simulate("examples/SimulationDemo/Linear.fmu", inPort = 0); 49 | WrappedSimulator s1 = new WrappedSimulator(de1); 50 | WrappedSimulator s2 = new WrappedSimulator(de2); 51 | Connection c = new Connection(s1, s2); 52 | List l = new List(c, null); 53 | List sl = new List(s1, null); 54 | List sl2 = new List(s2, null); 55 | sl.append(sl2); 56 | CoSim sim = new CoSim(l, sl); 57 | Int i = 0; 58 | while(i <= 50) do 59 | sim.round(1); 60 | Int df1 = de1.outPort; 61 | Int df2 = de2.outPort; 62 | print("---"); 63 | print(df1); 64 | print(df2); 65 | i = i + 1; 66 | end 67 | end 68 | 69 | -------------------------------------------------------------------------------- /examples/SimulationDemo/Predator.fmu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/SimulationDemo/Predator.fmu -------------------------------------------------------------------------------- /examples/SimulationDemo/Predator.mo: -------------------------------------------------------------------------------- 1 | block Predator 2 | input Real y(start = y0) "Prey"; 3 | output Real x(start = x0) "Predator"; 4 | parameter Real x0 = 10; 5 | parameter Real y0 = 10; 6 | parameter Real alpha = 0.1; 7 | parameter Real beta = 0.4; 8 | equation 9 | der(x) = x*(alpha-beta*y); 10 | end Predator; -------------------------------------------------------------------------------- /examples/SimulationDemo/Prey.fmu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/SimulationDemo/Prey.fmu -------------------------------------------------------------------------------- /examples/SimulationDemo/Prey.mo: -------------------------------------------------------------------------------- 1 | block Prey 2 | input Real x(start = x0) "Predator"; 3 | output Real y(start = y0) "Prey"; 4 | parameter Real x0 = 10; 5 | parameter Real y0 = 10; 6 | parameter Real alpha = 0.4; 7 | parameter Real beta = 0.02; 8 | equation 9 | der(y) = y*(beta*x - alpha); 10 | end Prey; -------------------------------------------------------------------------------- /examples/SimulationDemo/Tank.fmu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/SimulationDemo/Tank.fmu -------------------------------------------------------------------------------- /examples/SimulationDemo/Tank.smol: -------------------------------------------------------------------------------- 1 | main 2 | //beware: path is relative to interpreter instance, not this file 3 | FMO[out Int filling] de = simulate("examples/SimulationDemo/Tank.fmu"); 4 | Int i = de.filling; 5 | print(i); 6 | de.tick(1); 7 | i = de.filling; 8 | print(i); 9 | tick(de, 1); 10 | i = de.filling; 11 | print(i); 12 | end 13 | -------------------------------------------------------------------------------- /examples/SimulationDemo/Test.mo: -------------------------------------------------------------------------------- 1 | model Tank 2 | "Simple tank model (based on the one in Isolde Dressler's master thesis project)" 3 | type Flow=Real(unit="l/s"); 4 | type Uniting=Real(unit="l/s"); 5 | 6 | Flow outFlow; 7 | parameter Flow inFlow=1; 8 | input Boolean afterOpen = false; 9 | output Integer filling; 10 | 11 | protected Real level; 12 | constant Real A=1; 13 | constant Real a=0.2; 14 | constant Real hmax=1; 15 | constant Real g=-9.81; 16 | equation 17 | der(level) = (inFlow - outFlow)/(hmax*A); 18 | filling = integer(level*100); 19 | if afterOpen then 20 | outFlow = sqrt(max(0,2*g*hmax*level))*a; 21 | else 22 | outFlow = 0; 23 | end if; 24 | end Tank; -------------------------------------------------------------------------------- /examples/SimulationDemo/lotka-volterra.smol: -------------------------------------------------------------------------------- 1 | class UnitObject() 2 | Double get() return 0.0; end 3 | Double set(Double v) return v; end 4 | Double doStep(Double step) return step; end 5 | end 6 | class PreyObject extends UnitObject (FMO[in Double y, out Double x] prey) 7 | override Double get() return this.prey.x; end 8 | override Double set(Double v) this.prey.y = v; return v; end 9 | override Double doStep(Double step) this.prey.tick(step); return step; end 10 | end 11 | class PredatorObject extends UnitObject (FMO[in Double x, out Double y] predator) 12 | override Double get() return this.predator.y; end 13 | override Double set(Double v) this.predator.x = v; return v; end 14 | override Double doStep(Double step) this.predator.tick(step); return step; end 15 | end 16 | class CoupledPair(UnitObject a, UnitObject b, Double step) 17 | Int step() 18 | this.a.doStep(this.step); 19 | this.b.doStep(this.step); 20 | Double fromA = this.a.get(); 21 | Double fromB = this.b.get(); 22 | this.a.set(fromB); 23 | this.b.set(fromA); 24 | return 0; 25 | end 26 | end 27 | main 28 | 29 | //beware: path is relative to interpreter instance, not this file 30 | //fmus are not uploaded, download them from the MasterSim examples: https://sourceforge.net/projects/mastersim/ 31 | FMO[in Double y, out Double x] prey = simulate("examples/SimulationDemo/Prey.fmu", y = 10); 32 | FMO[in Double x, out Double y] predator = simulate("examples/SimulationDemo/Predator.fmu", x = 10); 33 | PreyObject preyObj = new PreyObject(prey); 34 | PredatorObject predObj = new PredatorObject(predator); 35 | CoupledPair pair = new CoupledPair(preyObj, predObj, 0.1); 36 | Int i = 0; 37 | while (i <= 1000) do 38 | pair.step(); 39 | print(predator.y); 40 | i = i+1; 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /examples/SimulationDemo/lv-plus.smol: -------------------------------------------------------------------------------- 1 | main 2 | //beware: path is relative to interpreter instance, not this file 3 | //fmus are not uploaded, download them from the MasterSim examples: https://sourceforge.net/projects/mastersim/ 4 | FMO[in Double y, out Double x] prey = simulate("examples/SimulationDemo/Prey.fmu", y = 10); 5 | prey.role = "prey"; 6 | FMO[in Double x, out Double y] predator = simulate("examples/SimulationDemo/Predator.fmu", x = 10); 7 | Int i = 0; 8 | while (i <= 1000) do 9 | prey.tick(0.1); 10 | predator.tick(0.1); 11 | prey.y = predator.y; 12 | predator.x = prey.x; 13 | i = i+1; 14 | end 15 | Double adv = prey.time; 16 | prey = simulate("examples/SimulationDemo/Prey.fmu", y = predator.y, x = prey.x); 17 | prey.role = "prey"; 18 | prey.pseudoOffset = adv; 19 | i = 0; 20 | while (i <= 1000) do 21 | prey.y = predator.y; 22 | predator.x = prey.x; 23 | prey.tick(0.1); 24 | predator.tick(0.1); 25 | i = i+1; 26 | end 27 | print("Finished"); 28 | end 29 | /* 30 | query SELECT ?at ?val WHERE { ?m smol:roleName "prey"; 31 | smol:ofPort [smol:withName "x"]; 32 | smol:withValue ?val; 33 | smol:atTime ?at. 34 | FILTER (?at >= 90 && ?at <= 110) } ORDER BY ASC(?at) 35 | */ 36 | -------------------------------------------------------------------------------- /examples/SimulationDemo/lv-simple.smol: -------------------------------------------------------------------------------- 1 | main 2 | //beware: path is relative to interpreter instance, not this file 3 | //fmus are not uploaded, download them from the MasterSim examples: https://sourceforge.net/projects/mastersim/ 4 | FMO[in Double y, out Double x] prey = simulate("examples/SimulationDemo/Prey.fmu", y = 10); 5 | FMO[in Double x, out Double y] predator = simulate("examples/SimulationDemo/Predator.fmu", x = 10); 6 | Int i = 0; 7 | while (i <= 2000) do 8 | prey.tick(0.1); 9 | predator.tick(0.1); 10 | prey.y = predator.y; 11 | predator.x = prey.x; 12 | print(predator.y); 13 | i = i+1; 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /examples/TTT.imo: -------------------------------------------------------------------------------- 1 | auto 2 | query SELECT ?obj WHERE {?obj a :TwoNode} 3 | class value 4 | -------------------------------------------------------------------------------- /examples/Tutorial/Controller.fmu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/Tutorial/Controller.fmu -------------------------------------------------------------------------------- /examples/Tutorial/README.md: -------------------------------------------------------------------------------- 1 | ## Tutorial Examples 2 | To run the first example, use the following parameters 3 | ``` 4 | -e -i examples/Tutorial/demo_cloud.smol -b examples/Tutorial/demo_cloud.owl 5 | -l -i examples/Tutorial/demo1.smol 6 | -l -i examples/Tutorial/demo2.smol -b examples/Tutorial/demo2.owl -p asset=https://www.smolang.org/lab/tutorial# 7 | -e -i examples/Tutorial/demo3.smol -b examples/Tutorial/demo3.owl -p asset=https://www.smolang.org/lab/tutorial# 8 | ``` -------------------------------------------------------------------------------- /examples/Tutorial/Room.fmu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/Tutorial/Room.fmu -------------------------------------------------------------------------------- /examples/Tutorial/Wall.fmu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/Tutorial/Wall.fmu -------------------------------------------------------------------------------- /examples/Tutorial/demo1.smol: -------------------------------------------------------------------------------- 1 | class C(Int i) 2 | Unit inc() breakpoint; this.i = this.i + 1; end 3 | end 4 | 5 | main 6 | C c = new C(5); 7 | c.inc(); 8 | end 9 | 10 | /* 11 | Get everything 12 | query SELECT * WHERE { ?a a ?b } 13 | Get all objects of class C 14 | query SELECT * WHERE { ?a a prog:C} 15 | Get all objects and its fields 16 | query SELECT * WHERE { ?a a prog:C. ?a prog:C_i ?b } 17 | Get all objects of class C with value 5 18 | query SELECT * WHERE { ?a a prog:C. ?a prog:C_i 5 } 19 | */ -------------------------------------------------------------------------------- /examples/Tutorial/demo2.smol: -------------------------------------------------------------------------------- 1 | abstract class Twin(Int id) end 2 | 3 | 4 | class Room extends Twin 5 | (FMO[in Double left, 6 | in Double right, 7 | in Double target, 8 | out Double val] fmu, 9 | Wall toLeft, 10 | Wall toRight) end 11 | 12 | class Wall extends Twin 13 | (FMO[in Double left, 14 | in Double right, 15 | out Double val] fmu, 16 | Room toLeft, 17 | Room toRight) end 18 | 19 | class Controller(FMO[in Double left, 20 | in Double right, 21 | out Double target] fmu, 22 | Room left, 23 | Room right) end 24 | 25 | 26 | class DigitalTwin(Wall wall1, Room room1, Wall wall2, Room room2, Wall wall3, Controller ctrl) 27 | 28 | Int lengthOfList(List l) 29 | if l == null then return 0; end 30 | Int lg = l.length(); 31 | return lg; 32 | end 33 | 34 | /* Demo setup for internal consistency */ 35 | Unit setupOne() 36 | this.wall1 = new Wall(0, null, null, null); 37 | this.wall2 = new Wall(1, null, null, null); 38 | this.wall3 = new Wall(2, null, null, null); 39 | this.room1 = new Room(10, null, this.wall1, this.wall2); 40 | this.room2 = new Room(11, null, this.wall2, this.wall3); 41 | 42 | this.wall1.toRight = this.room1; 43 | this.wall2.toLeft = this.room1; 44 | this.wall2.toRight = this.room2; 45 | this.wall3.toLeft = this.room2; 46 | 47 | this.ctrl = new Controller(null, this.room1, this.room2); //bug! 48 | //this.ctrl = new Controller(null, this.room1, this.room2); //fix 49 | end 50 | 51 | Unit consistencyOne() 52 | List r = access("SELECT ?obj WHERE { ?obj a prog:Controller. ?obj prog:Controller_left ?room. ?obj prog:Controller_right ?room }"); 53 | Int faults = this.lengthOfList(r); 54 | print("Number of faulty rooms: "); 55 | print(faults); 56 | end 57 | 58 | /* Demo setup for twinning */ 59 | Unit setupTwo() 60 | this.wall1 = new Wall(0, null, null, null); 61 | this.wall2 = new Wall(1, null, null, null); 62 | this.wall3 = new Wall(2, null, null, null); 63 | this.room1 = new Room(10, null, this.wall1, this.wall2); 64 | this.room2 = new Room(11, null, this.wall2, this.wall3); 65 | 66 | this.wall1.toRight = this.room1; 67 | this.wall2.toLeft = this.room1; 68 | this.wall2.toRight = this.room2; 69 | this.wall3.toLeft = this.room2; 70 | 71 | this.ctrl = new Controller(null, this.room1, this.room2); //bug! 72 | //this.ctrl = new Controller(null, this.room2, this.room1); //fix 73 | breakpoint; 74 | /* 75 | get asset view 76 | SELECT ?id1 ?id2 WHERE { ?h1 asset:id ?id1. ?h2 asset:id ?id2. ?h1 asset:left ?a. ?h2 asset:right ?a } 77 | get program view 78 | SELECT ?id1 ?id2 WHERE { ?o1 prog:Room_id ?id1. ?o2 prog:Room_id ?id2. ?c a prog:Controller. ?c prog:Controller_right ?o1. ?c prog:Controller_left ?o2 } 79 | get combined view 80 | SELECT ?id1 ?id2 WHERE { ?o1 prog:Room_id ?id1. ?h1 asset:id ?id1. ?o2 prog:Room_id ?id2. ?h2 asset:id ?id2. ?h1 asset:left ?a. ?h2 asset:right ?a. ?c a prog:Controller. ?c prog:Controller_right ?o1. ?c prog:Controller_left ?o2 } 81 | */ 82 | end 83 | 84 | end 85 | 86 | main 87 | DigitalTwin dt = new DigitalTwin(null, null, null, null, null, null); 88 | //dt.setupOne(); 89 | //dt.consistencyOne(); 90 | 91 | dt.setupTwo(); 92 | end 93 | -------------------------------------------------------------------------------- /examples/Tutorial/demo_cloud.owl: -------------------------------------------------------------------------------- 1 | 2 | domain:ZeroServer rdf:type owl:Class ; 3 | owl:equivalentClass [ 4 | rdf:type owl:Restriction ; 5 | owl:onProperty prog:Server_taskList ; 6 | owl:hasValue smol:null 7 | ]. 8 | 9 | domain:OneList rdf:type owl:Class ; 10 | owl:equivalentClass [ 11 | rdf:type owl:Restriction ; 12 | owl:onProperty prog:ExplList_next ; 13 | owl:hasValue smol:null 14 | ]. 15 | 16 | domain:OneServer rdf:type owl:Class ; 17 | owl:equivalentClass [ 18 | rdf:type owl:Restriction ; 19 | owl:onProperty prog:Server_taskList ; 20 | owl:someValuesFrom domain:OneList; 21 | ]. 22 | 23 | domain:TwoList rdf:type owl:Class ; 24 | owl:equivalentClass [ 25 | rdf:type owl:Restriction ; 26 | owl:onProperty prog:ExplList_next ; 27 | owl:someValuesFrom domain:OneList 28 | ]. 29 | 30 | domain:TwoServer rdf:type owl:Class ; 31 | owl:equivalentClass [ 32 | rdf:type owl:Restriction ; 33 | owl:onProperty prog:Server_taskList ; 34 | owl:someValuesFrom domain:TwoList; 35 | ]. 36 | 37 | 38 | 39 | 40 | 41 | domain:ThreeList rdf:type owl:Class ; 42 | owl:equivalentClass [ 43 | rdf:type owl:Restriction ; 44 | owl:onProperty prog:ExplList_next ; 45 | owl:someValuesFrom domain:TwoList 46 | ]. 47 | 48 | 49 | 50 | 51 | 52 | 53 | domain:ThreeServer rdf:type owl:Class ; 54 | owl:equivalentClass [ 55 | rdf:type owl:Restriction ; 56 | owl:onProperty prog:Server_taskList ; 57 | owl:someValuesFrom domain:ThreeList; 58 | ]. 59 | 60 | domain:Overloaded rdf:type owl:Class ; 61 | owl:equivalentClass domain:ThreeServer. 62 | -------------------------------------------------------------------------------- /examples/Tutorial/demo_semantic.smol: -------------------------------------------------------------------------------- 1 | main 2 | List results = access("SELECT ?obj {?a a asset:Room. ?a asset:id ?obj}"); 3 | while results != null do 4 | Int current = results.content; 5 | results = results.next; 6 | print(current); 7 | end 8 | end -------------------------------------------------------------------------------- /examples/University/university.imo: -------------------------------------------------------------------------------- 1 | auto 2 | 3 | # various queries 4 | # query SELECT (count(*) as ?count) WHERE {?a ?b ?c. } 5 | # query SELECT * WHERE {?a ?b ?c. } 6 | # query SELECT * WHERE {{?obj ?name. ?obj domain:models ?model. ?model ?modelP ?modelO.} UNION {?obj ?name. ?obj domain:models ?model. ?obj ?p ?o.} } 7 | # query SELECT * WHERE {?obj ?name. ?obj domain:models ?model. ?model ?modelP ?modelO.} 8 | # query SELECT * WHERE {?obj ?name. ?obj domain:models ?model. ?obj ?p ?o.} 9 | # query SELECT (count(*) as ?count) WHERE {?a ?b ?c. } 10 | # query SELECT * WHERE {?a ?b ?c. } 11 | # query SELECT * WHERE {?a a owl:Class. } 12 | # query SELECT * WHERE { a prog:Person. } 13 | 14 | 15 | # Dump state to output.ttl 16 | # dump 17 | 18 | # Check if our ontology/triples are consistent 19 | # consistency 20 | 21 | # Listing instances of given classes. Uses reasoning 22 | # class not 23 | # class 24 | # class and 25 | # class SOME 26 | 27 | query SELECT * WHERE {?p prog:Person_name ?name. ?p a prog:Person. ?p ?b ?c. } 28 | # query SELECT * WHERE {?A ?B ?C.} 29 | 30 | # query SELECT * WHERE {?obj prog:Student_name ?name. ?obj domain:models ?model. ?obj ?p ?o.} 31 | 32 | exit 33 | -------------------------------------------------------------------------------- /examples/University/university.ttl: -------------------------------------------------------------------------------- 1 | @prefix schema: . 2 | @prefix sh: . 3 | @prefix prog: . 4 | 5 | # Every lecturer must be an employee 6 | schema:CourseLecturerIsEmployeeShape 7 | a sh:NodeShape ; 8 | sh:targetClass prog:Course ; 9 | sh:property [ 10 | sh:path prog:Course_lecturer ; 11 | sh:class prog:Employee ; 12 | ]. 13 | -------------------------------------------------------------------------------- /examples/Virtualization/virtualization.imo: -------------------------------------------------------------------------------- 1 | auto 2 | 3 | reasoner rdfs 4 | reasoner owl 5 | reasoner off 6 | 7 | guards heap true 8 | guards staticTable true 9 | 10 | virtual heap true 11 | virtual staticTable true 12 | 13 | source staticTable false 14 | source heap false 15 | source externalOntology false 16 | source vocabularyFile true 17 | 18 | # return three triples from heap 19 | # query SELECT * WHERE {run:obj1 ?b ?c.} 20 | 21 | # return something from static table 22 | 23 | # query SELECT * WHERE {?a rdf:type ?c.} 24 | # query SELECT (count(*) as ?count) WHERE {?a rdf:type ?c.} 25 | # query SELECT (count(*) as ?count) WHERE {?a ?b ?c.} 26 | # query SELECT * WHERE {?a ?b ?c.} 27 | 28 | exit -------------------------------------------------------------------------------- /examples/Virtualization/virtualization.smol: -------------------------------------------------------------------------------- 1 | class Person(Int id, String name) end 2 | 3 | class Student extends Person(Int studentId) end 4 | 5 | main 6 | Person p1 := new Person(12, "Alice"); 7 | Student s1 := new Student(13, "Bob", 1001); 8 | end -------------------------------------------------------------------------------- /examples/Virtualization/virtualization.ttl: -------------------------------------------------------------------------------- 1 | @prefix owl: . 2 | @prefix rdf: . 3 | @prefix run: . 4 | 5 | run:test rdf:type owl:Class . 6 | 7 | prog:Student rdfs:subClassOf prog:Person . 8 | 9 | domain:triggeredBy rdf:type owl:ObjectProperty ; 10 | rdfs:subPropertyOf owl:topObjectProperty ; 11 | rdfs:domain domain:Process ; 12 | rdfs:range domain:Stratigraphic_Layer . 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /examples/adder.fmu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/adder.fmu -------------------------------------------------------------------------------- /examples/bug.smol: -------------------------------------------------------------------------------- 1 | main 2 | Int lengthPots = 0; 3 | Int i = 0; 4 | 5 | AssetModel assetModel = new AssetModel(); 6 | print("--------------------------------------------------- Pots from asset model"); 7 | List pots = assetModel.getPots(config); 8 | lengthPots = pots.length(); 9 | while i < lengthPots do 10 | Pot pot = pots.get(i); 11 | print("shelfFloor: "); 12 | print(pot.shelfFloor); 13 | print(" groupPosition: "); 14 | print(pot.groupPosition); 15 | print(" potPosition: "); 16 | print(pot.potPosition); 17 | i = i+1; 18 | end 19 | 20 | assetModel.getPots(config); 21 | print("l"); 22 | end 23 | 24 | class Pot(Int shelfFloor, String groupPosition, String potPosition) 25 | models "rdf:type domain:Pot."; 26 | end 27 | 28 | class AssetModel() 29 | // get pot instances from the asset model 30 | List getPots() 31 | List pots = construct(" 32 | PREFIX ast: 33 | SELECT ?shelfFloor ?groupPosition ?potPosition 34 | WHERE { 35 | ?pot rdf:type ast:Pot ; 36 | ast:hasShelfFloor ?shelfFloor ; 37 | ast:hasGroupPosition ?groupPosition ; 38 | ast:hasPotPosition ?potPosition . 39 | }"); 40 | return pots; 41 | end 42 | end -------------------------------------------------------------------------------- /examples/construct.smol: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | class A(Int i1) end 6 | 7 | class B(A a, Int i2) end 8 | 9 | class C(Int j1, Int j2) end 10 | 11 | main 12 | A a1 = new A(1); 13 | A a2 = new A(2); 14 | A a3 = new A(1); 15 | A a4 = new A(2); 16 | B b0 = new B(null, 3); 17 | B b1 = new B(a1, 4); 18 | B b2 = new B(a2, 5); 19 | B b3 = new B(a3, 6); 20 | B b4 = new B(a4, 7); 21 | 22 | List v = construct("SELECT ?j1 ?j2 WHERE { ?y a prog:B. ?y prog:B_i2 ?j2.?y prog:B_a ?x.?x a prog:A. ?x prog:A_i1 ?j1 }"); 23 | Int i = 0; 24 | Int size = v.length(); 25 | while( i < size) do 26 | C next = v.get(i); 27 | print(next.j1); 28 | print(next.j2); 29 | print("___"); 30 | i = i + 1; 31 | end 32 | print(size); 33 | end 34 | -------------------------------------------------------------------------------- /examples/destroy.smol: -------------------------------------------------------------------------------- 1 | 2 | class A(Int i1) end 3 | 4 | main 5 | 6 | A a = new A(1); 7 | List list = access("SELECT ?obj WHERE {?obj a prog:A}"); 8 | print(list); 9 | print(list.content); 10 | destroy(a); 11 | print(list.content); 12 | list = access("SELECT ?obj WHERE {?obj a prog:A}"); 13 | print(list); 14 | end 15 | -------------------------------------------------------------------------------- /examples/double.imo: -------------------------------------------------------------------------------- 1 | auto 2 | examine 3 | class 4 | query SELECT ?obj WHERE { ?obj a prog:List } 5 | query SELECT ?obj WHERE { ?obj rdf:type smol:Field } 6 | auto 7 | -------------------------------------------------------------------------------- /examples/double.rq: -------------------------------------------------------------------------------- 1 | PREFIX : 2 | 3 | SELECT ?obj WHERE { ?obj a prog:C } 4 | -------------------------------------------------------------------------------- /examples/double.ttl: -------------------------------------------------------------------------------- 1 | @prefix schema: . 2 | @prefix sh: . 3 | 4 | schema:TestShape 5 | a sh:NodeShape ; 6 | sh:targetClass schema:Object ; 7 | sh:property [ 8 | sh:path schema:instanceOf ; 9 | sh:class schema:Class ; 10 | sh:name "Everything implements" ; 11 | ]. 12 | -------------------------------------------------------------------------------- /examples/external.ttl: -------------------------------------------------------------------------------- 1 | @prefix owl: . 2 | @prefix rdf: . 3 | @prefix xml: . 4 | @prefix xsd: . 5 | @prefix rdfs: . 6 | @prefix domain: . 7 | 8 | 9 | domain:P rdf:type owl:ObjectProperty. 10 | domain:C rdf:type owl:Class. -------------------------------------------------------------------------------- /examples/influx.smol: -------------------------------------------------------------------------------- 1 | 2 | main 3 | List list = access( 4 | "from(bucket: \"petwin\") 5 | |> range(start: -1h, stop: -1m) 6 | |> filter(fn: (r) => r[\"_measurement\"] == \"chili\") 7 | |> filter(fn: (r) => r[\"_field\"] == \"temperature\") 8 | |> filter(fn: (r) => r[\"name\"] == \"faarikaal1\") 9 | |> aggregateWindow(every: 5m, fn: mean, createEmpty: false) 10 | |> yield(name: \"mean\")", 11 | INFLUXDB("petwin.yml")); 12 | print(list.content); 13 | end 14 | -------------------------------------------------------------------------------- /examples/models.smol: -------------------------------------------------------------------------------- 1 | 2 | class M(Int i) 3 | models( this.i == 0 ) "rdf:type domain:zero."; 4 | models( this.i == 1 ) "rdf:type domain:single."; 5 | models "rdf:type domain:any."; 6 | end 7 | 8 | main 9 | M v0 = new M(0); 10 | M v1 = new M(1); 11 | M v2 = new M(2); 12 | List acc = access("SELECT ?obj WHERE {?obj rdf:type prog:M}"); 13 | end 14 | -------------------------------------------------------------------------------- /examples/newbackgeo.rule: -------------------------------------------------------------------------------- 1 | [(?X domain:models ?Y), (?X prog:Shale_thickness ?Z) -> (?Y domain:thickness ?Z)] 2 | [(?X domain:models ?Y), (?X prog:Sand_thickness ?Z) -> (?Y domain:thickness ?Z)] 3 | [(?X domain:models ?Y), (?X prog:GeoLayer_depth_builtin_res ?Z) -> (?Y domain:depth ?Z)] 4 | [(?X prog:Sand_hasHC run:True), (?X domain:models ?Q), makeTemp(?l1), makeTemp(?l2) -> (?Q domain:constitutedBy ?l1), (?l1 domain:contains ?l2), (?l2 rdf:type domain:Kerogen)] 5 | [(?X prog:Shale_dinoStatus 1), (?X domain:models ?Q), makeTemp(?l1), makeTemp(?l2) -> (?Q domain:constitutedBy ?l1), (?l1 domain:contains ?l2), (?l2 rdf:type domain:Kerogen)] 6 | [(?X prog:Shale_dinoStatus 2), (?X domain:models ?Q), makeTemp(?l1), makeTemp(?l2) -> (?Q domain:constitutedBy ?l1), (?l1 domain:contains ?l2), (?l2 rdf:type domain:Kerogen)] -------------------------------------------------------------------------------- /examples/newgeo.rule: -------------------------------------------------------------------------------- 1 | [(?X domain:models ?Y), (?X prog:GeoLayer_depth_builtin_res ?Z) -> (?Y domain:depth ?Z)] -------------------------------------------------------------------------------- /examples/overload.back: -------------------------------------------------------------------------------- 1 | 2 | domain:ZeroServer rdf:type owl:Class ; 3 | owl:equivalentClass [ 4 | rdf:type owl:Restriction ; 5 | owl:onProperty prog:Server_taskList ; 6 | owl:hasValue smol:null 7 | ]. 8 | 9 | domain:OneList rdf:type owl:Class ; 10 | owl:equivalentClass [ 11 | rdf:type owl:Restriction ; 12 | owl:onProperty prog:ExplList_next ; 13 | owl:hasValue smol:null 14 | ]. 15 | 16 | domain:OneServer rdf:type owl:Class ; 17 | owl:equivalentClass [ 18 | rdf:type owl:Restriction ; 19 | owl:onProperty prog:Server_taskList ; 20 | owl:someValuesFrom domain:OneList; 21 | ]. 22 | 23 | domain:TwoList rdf:type owl:Class ; 24 | owl:equivalentClass [ 25 | rdf:type owl:Restriction ; 26 | owl:onProperty prog:ExplList_next ; 27 | owl:someValuesFrom domain:OneList 28 | ]. 29 | 30 | domain:TwoServer rdf:type owl:Class ; 31 | owl:equivalentClass [ 32 | rdf:type owl:Restriction ; 33 | owl:onProperty prog:Server_taskList ; 34 | owl:someValuesFrom domain:TwoList; 35 | ]. 36 | 37 | 38 | 39 | 40 | 41 | domain:ThreeList rdf:type owl:Class ; 42 | owl:equivalentClass [ 43 | rdf:type owl:Restriction ; 44 | owl:onProperty prog:ExplList_next ; 45 | owl:someValuesFrom domain:TwoList 46 | ]. 47 | 48 | 49 | 50 | 51 | 52 | 53 | domain:ThreeServer rdf:type owl:Class ; 54 | owl:equivalentClass [ 55 | rdf:type owl:Restriction ; 56 | owl:onProperty prog:Server_taskList ; 57 | owl:someValuesFrom domain:ThreeList; 58 | ]. 59 | 60 | domain:Overloaded rdf:type owl:Class ; 61 | owl:equivalentClass domain:ThreeServer. 62 | -------------------------------------------------------------------------------- /examples/overload.imo: -------------------------------------------------------------------------------- 1 | auto 2 | query SELECT ?obj WHERE {?obj a domain:Overloaded } 3 | auto 4 | query SELECT ?obj WHERE {?obj a domain:Overloaded } 5 | -------------------------------------------------------------------------------- /examples/persons.back: -------------------------------------------------------------------------------- 1 | 2 | 3 | domain:Man a owl:Class . 4 | domain:Woman a owl:Class . 5 | 6 | domain:hasWife rdfs:domain domain:Man ; 7 | rdfs:range domain:Woman . 8 | 9 | domain:bob domain:hasWife domain:alice . 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /examples/scene.imo: -------------------------------------------------------------------------------- 1 | auto 2 | query SELECT ?obj ?name WHERE { ?sth prog:Rectangle_area_builtin_res ?obj. ?sth prog:Rectangle_name ?name } 3 | -------------------------------------------------------------------------------- /examples/shape.ttl: -------------------------------------------------------------------------------- 1 | @prefix schema: . 2 | @prefix sh: . 3 | 4 | schema:TestShape 5 | a sh:NodeShape ; 6 | sh:targetClass schema:Object ; 7 | sh:property [ 8 | sh:path schema:instanceOf ; 9 | sh:class schema:Class ; 10 | sh:name "Everything implements" ; 11 | ]. 12 | -------------------------------------------------------------------------------- /examples/simulate.imo: -------------------------------------------------------------------------------- 1 | auto 2 | query SELECT ?obj WHERE { ?sth prog:D_n_builtin_res ?obj } -------------------------------------------------------------------------------- /examples/translatescene.smol: -------------------------------------------------------------------------------- 1 | class Scene(Int scaling) 2 | Int getScale() 3 | return this.scaling; 4 | end 5 | end 6 | 7 | class Rectangle(Scene scene, Int w, Int h, String name) 8 | Int area() 9 | Int s = this.scene.getScale(); 10 | return s*this.w*this.h; 11 | end 12 | end 13 | 14 | main 15 | Scene sc = new Scene(2); 16 | Rectangle r = new Rectangle(sc, 5, 1, "rect1"); 17 | Int res = r.area(); 18 | print(res); 19 | end 20 | -------------------------------------------------------------------------------- /examples/tree_shapes.ttl: -------------------------------------------------------------------------------- 1 | @prefix schema: . 2 | @prefix sh: . 3 | 4 | schema:TestShape 5 | a sh:NodeShape ; 6 | sh:targetClass schema:Object ; 7 | sh:property [ 8 | sh:path schema:instanceOf ; 9 | sh:class schema:Class ; 10 | sh:name "Every smol-object states its smol-class" ; 11 | ]. 12 | -------------------------------------------------------------------------------- /examples/tutorial_day1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/tutorial_day1.pdf -------------------------------------------------------------------------------- /examples/tutorial_day2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/tutorial_day2.pdf -------------------------------------------------------------------------------- /examples/tutorialfiles.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/examples/tutorialfiles.zip -------------------------------------------------------------------------------- /examples/type_query.smol: -------------------------------------------------------------------------------- 1 | 2 | class A (protected Int f1, private Int f2, Int f3) 3 | Int m1(A a, B b, C c) 4 | Int v1 = this.f1 + this.f2 + this.f3; 5 | Int v2 = b.f4; //fail 6 | Int v3 = b.f5; //fail 7 | Int v4 = b.f6; 8 | Int v5 = b.f1; 9 | Int v6 = b.f2; 10 | Int v7 = b.f3; 11 | Int w5 = a.f1; 12 | Int w6 = a.f2; 13 | Int w7 = a.f3; 14 | Int v8 = c.f7; //fail 15 | Int v9 = c.f8; //fail 16 | Int v0 = c.f9; 17 | return 0; 18 | end 19 | end 20 | 21 | class B extends A (protected Int f4, private Int f5, Int f6) 22 | Int m2(A a, B b, C c) 23 | Int v1 = this.f4 + this.f5 + this.f6; 24 | Int v2 = b.f4; 25 | Int v3 = b.f5; 26 | Int v4 = b.f6; 27 | Int v5 = b.f1; 28 | Int v6 = b.f2; //fail 29 | Int v7 = b.f3; 30 | Int w5 = a.f1; 31 | Int w6 = a.f2; //fail 32 | Int w7 = a.f3; 33 | Int v8 = c.f7; //fail 34 | Int v9 = c.f8; //fail 35 | Int v0 = c.f9; 36 | return 0; 37 | end 38 | end 39 | 40 | class C extends A(protected Int f7, private Int f8, Int f9) 41 | Int m3(A a, B b, C c) 42 | Int v1 = this.f7 + this.f8 + this.f9; 43 | Int v2 = b.f4; //fail 44 | Int v3 = b.f5; //fail 45 | Int v4 = b.f6; 46 | Int v5 = b.f1; 47 | Int v6 = b.f2; //fail 48 | Int v7 = b.f3; 49 | Int w5 = a.f1; 50 | Int w6 = a.f2; //fail 51 | Int w7 = a.f3; 52 | Int v8 = c.f7; 53 | Int v9 = c.f8; 54 | Int v0 = c.f9; 55 | return 0; 56 | end 57 | end 58 | 59 | class D extends A() 60 | Int m4(A a, B b, C c) 61 | a.f1 = 1; 62 | a.f2 = 1; //fail 63 | a.f3 = 1; 64 | b.f4 = 1; //fail 65 | b.f5 = 1; //fail 66 | b.f6 = 1; 67 | c.f7 = 1; //fail 68 | c.f8 = 1; //fail 69 | c.f9 = 1; 70 | return 0; 71 | end 72 | end 73 | 74 | 75 | main 76 | skip; 77 | end 78 | -------------------------------------------------------------------------------- /execute_case.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ./gradlew shadowJar 3 | java -jar build/libs/smol.jar -i examples/Geological/simulate_onto.smol -v -e -b examples/Geological/total_mini.ttl -p UFRGS1=https://www.inf.ufrgs.br/bdi/ontologies/geocoreontology#UFRGS -p obo=http://purl.obolibrary.org/obo/ -d http://www.semanticweb.org/quy/ontologies/2023/2/untitled-ontology-38# 4 | -------------------------------------------------------------------------------- /fuseki_server_test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Build the fuseki image 4 | docker build -f DockerfileFuseki -t fuseki . 5 | 6 | # Run the fuseki image 7 | docker run -d --name fuseki_container -it --rm -v "$PWD":/root/smol -p 3030:3030 fuseki 8 | 9 | # Define the FUSEKI_SERVER environment variable 10 | export FUSEKI_DOCKER=true 11 | 12 | # Execute the test 13 | ./gradlew --stop 14 | ./gradlew test --tests no.uio.microobject.test.data.TripleManagerTest 15 | 16 | # Stop the fuseki server 17 | kill $(ps aux | grep '[f]useki' | awk '{print $2}') 18 | 19 | # Stop the Docker container when done testing (optional) 20 | docker stop fuseki_container 21 | docker kill fuseki_container # to kill the container if docker stop doesn't work 22 | docker rm fuseki_container 23 | 24 | # Delete the fuseki image 25 | docker rmi fuseki 26 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | kotlin.code.style=official 2 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6-bin.zip 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @rem 2 | @rem Copyright 2015 the original author or authors. 3 | @rem 4 | @rem Licensed under the Apache License, Version 2.0 (the "License"); 5 | @rem you may not use this file except in compliance with the License. 6 | @rem You may obtain a copy of the License at 7 | @rem 8 | @rem https://www.apache.org/licenses/LICENSE-2.0 9 | @rem 10 | @rem Unless required by applicable law or agreed to in writing, software 11 | @rem distributed under the License is distributed on an "AS IS" BASIS, 12 | @rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | @rem See the License for the specific language governing permissions and 14 | @rem limitations under the License. 15 | @rem 16 | 17 | @if "%DEBUG%" == "" @echo off 18 | @rem ########################################################################## 19 | @rem 20 | @rem Gradle startup script for Windows 21 | @rem 22 | @rem ########################################################################## 23 | 24 | @rem Set local scope for the variables with windows NT shell 25 | if "%OS%"=="Windows_NT" setlocal 26 | 27 | set DIRNAME=%~dp0 28 | if "%DIRNAME%" == "" set DIRNAME=. 29 | set APP_BASE_NAME=%~n0 30 | set APP_HOME=%DIRNAME% 31 | 32 | @rem Resolve any "." and ".." in APP_HOME to make it shorter. 33 | for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi 34 | 35 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 36 | set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" 37 | 38 | @rem Find java.exe 39 | if defined JAVA_HOME goto findJavaFromJavaHome 40 | 41 | set JAVA_EXE=java.exe 42 | %JAVA_EXE% -version >NUL 2>&1 43 | if "%ERRORLEVEL%" == "0" goto execute 44 | 45 | echo. 46 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 47 | echo. 48 | echo Please set the JAVA_HOME variable in your environment to match the 49 | echo location of your Java installation. 50 | 51 | goto fail 52 | 53 | :findJavaFromJavaHome 54 | set JAVA_HOME=%JAVA_HOME:"=% 55 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 56 | 57 | if exist "%JAVA_EXE%" goto execute 58 | 59 | echo. 60 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 61 | echo. 62 | echo Please set the JAVA_HOME variable in your environment to match the 63 | echo location of your Java installation. 64 | 65 | goto fail 66 | 67 | :execute 68 | @rem Setup the command line 69 | 70 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 71 | 72 | 73 | @rem Execute Gradle 74 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* 75 | 76 | :end 77 | @rem End local scope for the variables with windows NT shell 78 | if "%ERRORLEVEL%"=="0" goto mainEnd 79 | 80 | :fail 81 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 82 | rem the _cmd.exe /c_ return code! 83 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 84 | exit /b 1 85 | 86 | :mainEnd 87 | if "%OS%"=="Windows_NT" endlocal 88 | 89 | :omega 90 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | 2 | rootProject.name = 'MicroObjects' 3 | 4 | -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/AST.kt: -------------------------------------------------------------------------------- 1 | @file:Suppress("unused") 2 | 3 | package no.uio.microobject.ast 4 | 5 | import no.uio.microobject.ast.expr.FALSEEXPR 6 | import no.uio.microobject.ast.expr.LiteralExpr 7 | import no.uio.microobject.ast.expr.LocalVar 8 | import no.uio.microobject.ast.expr.TRUEEXPR 9 | import no.uio.microobject.ast.stmt.SequenceStmt 10 | import no.uio.microobject.ast.stmt.SkipStmt 11 | import no.uio.microobject.runtime.* 12 | import no.uio.microobject.type.* 13 | 14 | 15 | /* Top-level data structures for the AST, the implementations are in their own files in data.expr.* and data.stmt.* */ 16 | 17 | interface ProgramElement{ 18 | fun getRDF() : String 19 | } 20 | 21 | 22 | interface Statement : ProgramElement { 23 | fun getLast(): Statement = this 24 | fun eval(heapObj: Memory, stackFrame : StackEntry, interpreter: Interpreter) : EvalResult 25 | 26 | fun replaceStmt(stmt: Statement, stackFrame : StackEntry) : EvalResult 27 | = EvalResult(StackEntry(stmt, stackFrame.store, stackFrame.obj, stackFrame.id), listOf()) 28 | } 29 | 30 | interface Expression : ProgramElement { 31 | fun eval(stack: Memory, heap: GlobalMemory, simMemory: SimulationMemory, obj: LiteralExpr): LiteralExpr 32 | } 33 | 34 | interface Location : Expression { 35 | fun getType() : Type 36 | fun setType(targetType: Type) 37 | } 38 | 39 | /* This is a special construct for the simulate statement that assigns to the input variables/parameters */ 40 | data class VarInit(val name : String, val expr: Expression) : ProgramElement { 41 | override fun toString(): String = "$name : $expr" 42 | override fun getRDF(): String { 43 | //TODO: extend ontology 44 | return "" 45 | } 46 | 47 | } 48 | 49 | /* Access modes for different backends for `access`. May be refactored into their own statements. */ 50 | abstract class AccessMode 51 | data class InfluxDBMode(val expr: Expression) : AccessMode() 52 | object SparqlMode : AccessMode() 53 | 54 | 55 | /* helpers */ 56 | fun evalBool(bool : Boolean) : LiteralExpr= if (bool) TRUEEXPR else FALSEEXPR 57 | 58 | fun appendStmt (a : Statement, b: Statement) : Statement { 59 | if(b is SkipStmt) return a 60 | if(a is SkipStmt) return b 61 | return if(a !is SequenceStmt) SequenceStmt(a, b) else SequenceStmt(a.first, appendStmt(a.second,b)) 62 | } 63 | 64 | /* Handles generation of fresh names*/ 65 | object Names{ 66 | private var i = 0 67 | private var j = 0 68 | private var k = 0 69 | fun getObjName(className : String) : LiteralExpr = LiteralExpr("obj${i++}", BaseType(className)) 70 | fun getVarName(tag : Type = ERRORTYPE) : LocalVar = LocalVar("_v${i++}", tag) 71 | fun getStackId() : Int = j++ 72 | fun getNodeName() : String = "domain:model${k++}" 73 | } 74 | -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/expr/ConversionExpr.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.expr 2 | 3 | import no.uio.microobject.ast.Expression 4 | import no.uio.microobject.ast.ProgramElement 5 | import no.uio.microobject.runtime.GlobalMemory 6 | import no.uio.microobject.runtime.Memory 7 | import no.uio.microobject.runtime.SimulationMemory 8 | import no.uio.microobject.type.BOOLEANTYPE 9 | import no.uio.microobject.type.DOUBLETYPE 10 | import no.uio.microobject.type.INTTYPE 11 | import no.uio.microobject.type.STRINGTYPE 12 | import kotlin.math.roundToInt 13 | 14 | data class ConversionExpr(val c : Conversion, val inner : Expression) : Expression { 15 | override fun eval(stack: Memory, heap: GlobalMemory, simMemory: SimulationMemory, obj: LiteralExpr): LiteralExpr { 16 | val i = inner.eval(stack, heap, simMemory, obj); 17 | when (c){ 18 | Conversion.DOUBLETOINT -> 19 | if (i.tag == DOUBLETYPE){ 20 | return LiteralExpr(i.literal.toDouble().roundToInt().toString(), INTTYPE) 21 | } else { 22 | throw Exception("Conversion.DOUBLETOINT requires a Double value as its parameter") 23 | } 24 | Conversion.DOUBLETOSTRING -> 25 | if (i.tag == DOUBLETYPE){ 26 | return LiteralExpr(i.literal, STRINGTYPE) 27 | } else { 28 | throw Exception("Conversion.DOUBLETOSTRING requires a Double value as its parameter") 29 | } 30 | Conversion.INTTOSTRING -> 31 | if (i.tag == INTTYPE){ 32 | return LiteralExpr(i.literal, STRINGTYPE) 33 | } else { 34 | throw Exception("Conversion.INTTOSTRING requires an Int value as its parameter") 35 | } 36 | Conversion.INTTODOUBLE -> 37 | if (i.tag == INTTYPE){ 38 | return LiteralExpr(i.literal.toInt().toDouble().toString(), DOUBLETYPE) 39 | } else { 40 | throw Exception("Conversion.INTTODOUBLE requires an Int value as its parameter") 41 | } 42 | Conversion.BOOLEANTOSTRING -> 43 | if (i.tag == BOOLEANTYPE){ 44 | return LiteralExpr(i.literal, STRINGTYPE) 45 | } else { 46 | throw Exception("Conversion.BOOLEANTOSTRING requires a Boolean value as its parameter") 47 | } 48 | } 49 | } 50 | 51 | override fun getRDF(): String { 52 | return inner.getRDF() //TODO: once the AST lifting is being fixed, this must be included 53 | } 54 | 55 | } 56 | 57 | enum class Conversion : ProgramElement{ 58 | INTTOSTRING { 59 | override fun getRDF(): String { 60 | TODO("Not yet implemented") 61 | } 62 | }, 63 | INTTODOUBLE{ 64 | override fun getRDF(): String { 65 | TODO("Not yet implemented") 66 | } 67 | }, 68 | DOUBLETOINT{ 69 | override fun getRDF(): String { 70 | TODO("Not yet implemented") 71 | } 72 | }, 73 | DOUBLETOSTRING{ 74 | override fun getRDF(): String { 75 | TODO("Not yet implemented") 76 | } 77 | }, 78 | BOOLEANTOSTRING{ 79 | override fun getRDF(): String { 80 | TODO("Not yet implemented") 81 | } 82 | }, 83 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/expr/LiteralExpr.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.expr 2 | 3 | import no.uio.microobject.ast.Expression 4 | import no.uio.microobject.runtime.GlobalMemory 5 | import no.uio.microobject.runtime.Memory 6 | import no.uio.microobject.runtime.SimulationMemory 7 | import no.uio.microobject.type.BOOLEANTYPE 8 | import no.uio.microobject.type.ERRORTYPE 9 | import no.uio.microobject.type.Type 10 | import no.uio.microobject.type.UNITTYPE 11 | 12 | data class LiteralExpr(val literal : String, val tag : Type = ERRORTYPE) : Expression { 13 | override fun toString(): String = literal 14 | override fun eval(stack: Memory, heap: GlobalMemory, simMemory: SimulationMemory, obj: LiteralExpr): LiteralExpr = this 15 | 16 | override fun getRDF(): String { 17 | return """ 18 | prog:expr${this.hashCode()} rdf:type smol:LiteralExpression. 19 | prog:expr${this.hashCode()} smol:hasLiteral '${literal.removePrefix("\"").removeSuffix("\"")}'. 20 | prog:expr${this.hashCode()} smol:hasTag '${tag}'. 21 | """.trimIndent() 22 | } 23 | 24 | override fun equals(other: Any?): Boolean { 25 | if(other == null) return false 26 | if(other !is LiteralExpr) return false 27 | return literal == other.literal 28 | } 29 | 30 | override fun hashCode(): Int { 31 | var result = literal.hashCode() 32 | result = 31 * result + tag.hashCode() 33 | return result 34 | } 35 | } 36 | 37 | val FALSEEXPR = LiteralExpr("False", BOOLEANTYPE) 38 | val TRUEEXPR = LiteralExpr("True", BOOLEANTYPE) 39 | val UNITEXPR = LiteralExpr("unit", UNITTYPE) -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/expr/LocalVar.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.expr 2 | 3 | import no.uio.microobject.ast.Location 4 | import no.uio.microobject.runtime.GlobalMemory 5 | import no.uio.microobject.runtime.Memory 6 | import no.uio.microobject.runtime.SimulationMemory 7 | import no.uio.microobject.type.ERRORTYPE 8 | import no.uio.microobject.type.Type 9 | 10 | /** Expressions **/ 11 | 12 | 13 | data class LocalVar(val name : String, var tag : Type = ERRORTYPE) : Location { // local variable 14 | override fun toString(): String = name 15 | override fun getType(): Type = tag 16 | override fun setType(targetType: Type) { tag = targetType } 17 | override fun eval(stack: Memory, heap: GlobalMemory, simMemory: SimulationMemory, obj: LiteralExpr): LiteralExpr { 18 | return stack.getOrDefault(name, LiteralExpr("ERROR")) 19 | } 20 | 21 | override fun getRDF(): String { 22 | return """ 23 | prog:loc${this.hashCode()} rdf:type smol:LocalVarLocation. 24 | prog:loc${this.hashCode()} smol:hasName '${name}'. 25 | 26 | """.trimIndent() 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/expr/OthersVar.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.expr 2 | 3 | import no.uio.microobject.ast.Expression 4 | import no.uio.microobject.ast.Location 5 | import no.uio.microobject.runtime.GlobalMemory 6 | import no.uio.microobject.runtime.Memory 7 | import no.uio.microobject.runtime.SimulationMemory 8 | import no.uio.microobject.type.ERRORTYPE 9 | import no.uio.microobject.type.Type 10 | 11 | data class OthersVar(val expr: Expression, val name : String, var tag : Type = ERRORTYPE) : Location { // field of (possibly) other object 12 | override fun toString(): String = "$expr.$name" 13 | override fun getType(): Type = tag 14 | override fun setType(targetType: Type) { tag = targetType } 15 | override fun eval(stack: Memory, heap: GlobalMemory, simMemory: SimulationMemory, obj: LiteralExpr): LiteralExpr { 16 | val oObj = expr.eval(stack, heap, simMemory, obj) 17 | if(heap.containsKey(oObj)) return heap[oObj]!!.getOrDefault(name, LiteralExpr("ERROR")) 18 | if(simMemory.containsKey(oObj)) return simMemory[oObj]!!.read(name) 19 | throw Exception("Unknown object $oObj stored in $expr") 20 | } 21 | 22 | override fun getRDF(): String { 23 | return """ 24 | prog:loc${this.hashCode()} rdf:type smol:OthersVarLocation. 25 | prog:loc${this.hashCode()} smol:hasExpr prog:expr${expr.hashCode()}. 26 | prog:loc${this.hashCode()} smol:hasName '${name}'. 27 | 28 | """.trimIndent() 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/expr/OwnVar.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.expr 2 | 3 | import no.uio.microobject.ast.Location 4 | import no.uio.microobject.runtime.GlobalMemory 5 | import no.uio.microobject.runtime.Memory 6 | import no.uio.microobject.runtime.SimulationMemory 7 | import no.uio.microobject.type.ERRORTYPE 8 | import no.uio.microobject.type.Type 9 | 10 | data class OwnVar(val name : String, var tag : Type = ERRORTYPE) : Location { // field of own object 11 | override fun toString(): String = "this.$name" 12 | override fun getType(): Type = tag 13 | override fun setType(targetType: Type) { tag = targetType } 14 | override fun eval(stack: Memory, heap: GlobalMemory, simMemory: SimulationMemory, obj: LiteralExpr): LiteralExpr { 15 | if(heap[obj] == null) throw Exception("This object is unknown: $obj$") 16 | val heapObj: Memory = heap.getOrDefault(obj, mutableMapOf()) 17 | return heapObj.getOrDefault(name, LiteralExpr("ERROR")) 18 | } 19 | 20 | override fun getRDF(): String { 21 | return """ 22 | prog:loc${this.hashCode()} rdf:type smol:OwnVarLocation. 23 | prog:loc${this.hashCode()} smol:hasName '${name}'. 24 | 25 | """.trimIndent() 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/stmt/AssignStmt.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.stmt 2 | 3 | import no.uio.microobject.ast.* 4 | import no.uio.microobject.ast.expr.LocalVar 5 | import no.uio.microobject.ast.expr.OthersVar 6 | import no.uio.microobject.ast.expr.OwnVar 7 | import no.uio.microobject.runtime.EvalResult 8 | import no.uio.microobject.runtime.Interpreter 9 | import no.uio.microobject.runtime.Memory 10 | import no.uio.microobject.runtime.StackEntry 11 | import no.uio.microobject.type.BaseType 12 | import no.uio.microobject.type.Type 13 | 14 | // Assignment, where value cannot refer to calls or object creations. 15 | data class AssignStmt(val target : Location, val value : Expression, val pos : Int = -1, val declares: Type?) : 16 | Statement { 17 | override fun toString(): String = "$target := $value" 18 | override fun getRDF(): String { 19 | return """ 20 | prog:stmt${this.hashCode()} rdf:type smol:AssignStatement. 21 | prog:stmt${this.hashCode()} smol:hasTarget prog:loc${target.hashCode()}. 22 | prog:stmt${this.hashCode()} smol:hasValue prog:expr${value.hashCode()}. 23 | prog:stmt${this.hashCode()} smol:Line '$pos'^^xsd:integer. 24 | 25 | """.trimIndent() 26 | } 27 | 28 | override fun eval(heapObj: Memory, stackFrame : StackEntry, interpreter: Interpreter) : EvalResult { 29 | val res = interpreter.eval(value, stackFrame) 30 | when (target) { 31 | is LocalVar -> stackFrame.store[target.name] = res 32 | is OwnVar -> { 33 | val got = interpreter.staticInfo.fieldTable[(stackFrame.obj.tag as BaseType).name] ?: throw Exception("Cannot find class ${stackFrame.obj.tag.name}") 34 | if (!got.map {it.name} .contains(target.name)) 35 | throw Exception("This field is unknown: ${target.name}") 36 | heapObj[target.name] = res 37 | } 38 | is OthersVar -> { 39 | val key = interpreter.eval(target.expr, stackFrame) 40 | 41 | when { 42 | interpreter.heap.containsKey(key) -> { 43 | val otherHeap = interpreter.heap[key] 44 | ?: throw Exception("This object is unknown: $key") 45 | if (!(interpreter.staticInfo.fieldTable[(key.tag as BaseType).name] 46 | ?: error("")).any{ it.name == target.name} 47 | ) throw Exception("This field is unknown: $key") 48 | otherHeap[target.name] = res 49 | } 50 | interpreter.simMemory.containsKey(key) -> { 51 | interpreter.simMemory[key]!!.write(target.name, res) 52 | } 53 | else -> throw Exception("This object is unknown: $key") 54 | } 55 | } 56 | } 57 | return EvalResult(null, emptyList()) 58 | } 59 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/stmt/CallStmt.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.stmt 2 | 3 | import no.uio.microobject.ast.* 4 | import no.uio.microobject.runtime.EvalResult 5 | import no.uio.microobject.runtime.Interpreter 6 | import no.uio.microobject.runtime.Memory 7 | import no.uio.microobject.runtime.StackEntry 8 | import no.uio.microobject.type.BaseType 9 | import no.uio.microobject.type.Type 10 | 11 | // Method call. We have the ABS-style split between calls and expressions to make the rules more simple 12 | data class CallStmt(val target : Location, val callee : Location, val method : String, val params : List, val pos : Int = -1, val declares : Type?) : 13 | Statement { 14 | override fun toString(): String = "$target := $callee.$method(${params.joinToString(",")})" 15 | override fun getRDF(): String { 16 | var s = """ 17 | prog:stmt${this.hashCode()} rdf:type smol:CallStatement. 18 | prog:stmt${this.hashCode()} smol:hasTarget prog:loc${target.hashCode()}. 19 | prog:stmt${this.hashCode()} smol:hasCallee prog:loc${callee.hashCode()}. 20 | prog:stmt${this.hashCode()} smol:hasMethodName '${method}'. 21 | prog:stmt${this.hashCode()} smol:Line '$pos'^^xsd:integer. 22 | 23 | """.trimIndent() 24 | for (i in params.indices){ 25 | s += "prog:stmt${this.hashCode()} smol:hasParameter [smol:hasParameterIndex $i ; smol:hasParameterValue prog:expr${params[i].hashCode()}; ].\n" 26 | s += params[i].getRDF() 27 | } 28 | return s + target.getRDF() + callee.getRDF() 29 | } 30 | 31 | override fun eval(heapObj: Memory, stackFrame: StackEntry, interpreter: Interpreter): EvalResult { 32 | val newObj = interpreter.eval(callee, stackFrame) 33 | val mt = interpreter.staticInfo.methodTable[(newObj.tag as BaseType).name] 34 | ?: throw Exception("This class is unknown: ${newObj.tag} when executing $this at l. pos") 35 | val m = mt[method] 36 | ?: throw Exception("This method is unknown: $method") 37 | val newMemory: Memory = mutableMapOf() 38 | newMemory["this"] = newObj 39 | for (i in m.params.indices) { 40 | newMemory[m.params[i]] = interpreter.eval(params[i], stackFrame) 41 | } 42 | return EvalResult( 43 | StackEntry(StoreReturnStmt(target), stackFrame.store, stackFrame.obj, stackFrame.id), 44 | listOf(StackEntry(m.stmt, newMemory, newObj, Names.getStackId())) 45 | ) 46 | } 47 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/stmt/CreateStmt.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.stmt 2 | 3 | import no.uio.microobject.ast.* 4 | import no.uio.microobject.ast.expr.LiteralExpr 5 | import no.uio.microobject.ast.expr.LocalVar 6 | import no.uio.microobject.runtime.EvalResult 7 | import no.uio.microobject.runtime.Interpreter 8 | import no.uio.microobject.runtime.Memory 9 | import no.uio.microobject.runtime.StackEntry 10 | import no.uio.microobject.type.STRINGTYPE 11 | import no.uio.microobject.type.Type 12 | 13 | data class CreateStmt(val target : Location, val className: String, val params : List, val pos : Int = -1, val declares: Type?, val modeling : List) : 14 | Statement { 15 | override fun toString(): String = "$target := new $className(${params.joinToString(",")})" 16 | override fun getRDF(): String { 17 | var s = """ 18 | prog:stmt${this.hashCode()} rdf:type smol:CreateStatement. 19 | prog:stmt${this.hashCode()} smol:hasTarget prog:loc${target.hashCode()}. 20 | prog:stmt${this.hashCode()} smol:hasClassName '${className}'. 21 | prog:stmt${this.hashCode()} smol:Line '$pos'^^xsd:integer. 22 | 23 | """.trimIndent() 24 | for (i in params.indices){ 25 | s += "prog:stmt${this.hashCode()} smol:hasParameter [smol:hasParameterIndex $i ; smol:hasParameterValue prog:expr${params[i].hashCode()}; ].\n" 26 | s += params[i].getRDF() 27 | } 28 | return s + target.getRDF() 29 | } 30 | 31 | override fun eval(heapObj: Memory, stackFrame: StackEntry, interpreter: Interpreter): EvalResult { 32 | val name = Names.getObjName(className) 33 | val n = 34 | interpreter.staticInfo.fieldTable[className] ?: throw Exception("This class is unknown: $className") 35 | val m = n.filter { it.internalInit == null } 36 | val newMemory: Memory = mutableMapOf() 37 | if (m.size != params.size) throw Exception( 38 | "Creation of an instance of class $className failed, mismatched number of parameters: $this. Requires: ${m.size}" 39 | ) 40 | for (i in m.indices) { 41 | if(!m[i].name.startsWith("__")) 42 | newMemory[m[i].name] = interpreter.eval(params[i], stackFrame) 43 | } 44 | if(modeling.isNotEmpty()) { 45 | val rdfName = Names.getNodeName() 46 | newMemory["__models"] = LiteralExpr(rdfName, STRINGTYPE) 47 | val evals = modeling.map { rdfName + " " + interpreter.eval(it, stackFrame).literal.removeSurrounding("\"") } 48 | newMemory["__describe"] = LiteralExpr(evals.joinToString(" "), STRINGTYPE) 49 | } 50 | interpreter.heap[name] = newMemory 51 | val localFrame = StackEntry(SkipStmt(), mutableMapOf(Pair("this", name)),name,0) 52 | n.filter { it.internalInit != null }.forEach { newMemory[it.name] = interpreter.eval(it.internalInit!!, localFrame) } 53 | return replaceStmt(AssignStmt(target, name, declares = declares), stackFrame) 54 | } 55 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/stmt/DebugStmt.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.stmt 2 | 3 | import no.uio.microobject.ast.Statement 4 | import no.uio.microobject.runtime.EvalResult 5 | import no.uio.microobject.runtime.Interpreter 6 | import no.uio.microobject.runtime.Memory 7 | import no.uio.microobject.runtime.StackEntry 8 | 9 | // Stops automatic execution 10 | data class DebugStmt(val pos : Int = -1) : Statement { 11 | override fun toString(): String = "breakpoint" 12 | override fun getRDF(): String = "prog:stmt${this.hashCode()} rdf:type smol:DebugStatement.\nprog:stmt${this.hashCode()} smol:Line '$pos'^^xsd:integer.\n" 13 | 14 | override fun eval(heapObj: Memory, stackFrame : StackEntry, interpreter: Interpreter) : EvalResult { 15 | return EvalResult(null, emptyList(), true) 16 | } 17 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/stmt/DestroyStmt.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.stmt 2 | 3 | import no.uio.microobject.ast.Expression 4 | import no.uio.microobject.ast.expr.LiteralExpr 5 | import no.uio.microobject.ast.Statement 6 | import no.uio.microobject.runtime.EvalResult 7 | import no.uio.microobject.runtime.Interpreter 8 | import no.uio.microobject.runtime.Memory 9 | import no.uio.microobject.runtime.StackEntry 10 | 11 | data class DestroyStmt(val expr: Expression, val pos : Int = -1): Statement { 12 | override fun toString(): String = "destroy($expr)" 13 | override fun getRDF(): String { 14 | return """ 15 | prog:stmt${this.hashCode()} rdf:type smol:DestroyStatement. 16 | prog:stmt${this.hashCode()} smol:hasStmtExpr prog:expr${expr.hashCode()}. 17 | prog:stmt${this.hashCode()} smol:Line '$pos'^^xsd:integer. 18 | 19 | """.trimIndent() + expr.getRDF() 20 | } 21 | 22 | override fun eval(heapObj: Memory, stackFrame: StackEntry, interpreter: Interpreter): EvalResult { 23 | val res = interpreter.eval(expr, stackFrame) 24 | if(!interpreter.heap.containsKey(res) || res.literal == "null") 25 | throw Exception("Trying to destroy null or an unknown object: $res") 26 | interpreter.heap.remove(res) 27 | //Replace name with ERROR. This is needed so the RDF dump does have dangling pointers and we cna derive weird things in the open world 28 | for( mem in interpreter.heap.values ){ 29 | var rem :String? = null 30 | for( kv in mem ){ 31 | if (kv.value == res) { 32 | rem = kv.key 33 | break 34 | } 35 | } 36 | if(rem != null) mem[rem] = LiteralExpr("null") 37 | } 38 | for( entry in interpreter.stack ){ 39 | var rem :String? = null 40 | for( kv in entry.store ){ 41 | if (kv.value == res) { 42 | rem = kv.key 43 | break 44 | } 45 | } 46 | if(rem != null) entry.store[rem] = LiteralExpr("null") 47 | } 48 | return EvalResult(null, emptyList()) 49 | } 50 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/stmt/IfStmt.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.stmt 2 | 3 | import no.uio.microobject.ast.Expression 4 | import no.uio.microobject.ast.Statement 5 | import no.uio.microobject.ast.expr.TRUEEXPR 6 | import no.uio.microobject.runtime.EvalResult 7 | import no.uio.microobject.runtime.Interpreter 8 | import no.uio.microobject.runtime.Memory 9 | import no.uio.microobject.runtime.StackEntry 10 | 11 | // Standard control flow 12 | data class IfStmt(val guard : Expression, val thenBranch : Statement, val elseBranch : Statement, val pos : Int = -1) : 13 | Statement { 14 | override fun toString(): String = "if($guard) then $thenBranch else $elseBranch fi" 15 | override fun getRDF(): String { 16 | return """ 17 | prog:stmt${this.hashCode()} rdf:type smol:IfStatement. 18 | prog:stmt${this.hashCode()} smol:hasGuard prog:expr${guard.hashCode()}. 19 | prog:stmt${this.hashCode()} smol:hasThenBranch prog:stmt${thenBranch.hashCode()}. 20 | prog:stmt${this.hashCode()} smol:hasElseBranch prog:stmt${elseBranch.hashCode()}. 21 | prog:stmt${this.hashCode()} smol:Line '$pos'^^xsd:integer. 22 | 23 | """.trimIndent() + guard.getRDF() + thenBranch.getRDF() + elseBranch.getRDF() 24 | } 25 | 26 | override fun eval(heapObj: Memory, stackFrame: StackEntry, interpreter: Interpreter): EvalResult { 27 | val res = interpreter.eval(guard, stackFrame) 28 | return if (res == TRUEEXPR) replaceStmt(thenBranch, stackFrame) 29 | else replaceStmt(elseBranch, stackFrame) 30 | } 31 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/stmt/OwlStmt.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.stmt 2 | 3 | import no.uio.microobject.ast.* 4 | import no.uio.microobject.ast.expr.LiteralExpr 5 | import no.uio.microobject.runtime.EvalResult 6 | import no.uio.microobject.runtime.Interpreter 7 | import no.uio.microobject.runtime.Memory 8 | import no.uio.microobject.runtime.StackEntry 9 | import no.uio.microobject.type.DOUBLETYPE 10 | import no.uio.microobject.type.INTTYPE 11 | import no.uio.microobject.type.STRINGTYPE 12 | import no.uio.microobject.type.Type 13 | import org.semanticweb.owlapi.model.OWLNamedIndividual 14 | import org.semanticweb.owlapi.reasoner.NodeSet 15 | 16 | data class OwlStmt(val target : Location, val query: Expression, val pos : Int = -1, val declares: Type?) : Statement { 17 | override fun toString(): String = "$target := member($query)" 18 | override fun getRDF(): String { 19 | return """ 20 | prog:stmt${this.hashCode()} rdf:type smol:OwlStatement. 21 | prog:stmt${this.hashCode()} smol:hasTarget prog:loc${target.hashCode()}. 22 | prog:stmt${this.hashCode()} smol:hasQuery prog:expr${query.hashCode()}. 23 | prog:stmt${this.hashCode()} smol:Line '$pos'^^xsd:integer. 24 | 25 | """.trimIndent() + target.getRDF() + query.getRDF() 26 | } 27 | 28 | override fun eval(heapObj: Memory, stackFrame: StackEntry, interpreter: Interpreter): EvalResult { 29 | if (query !is LiteralExpr || query.tag != STRINGTYPE) { 30 | throw Exception("Please provide a string as the input to a derive statement") 31 | } 32 | 33 | val res : NodeSet = interpreter.owlQuery(query.literal) 34 | var list = LiteralExpr("null") 35 | for (r in res) { 36 | val name = Names.getObjName("List") 37 | val newMemory: Memory = mutableMapOf() 38 | val found = r.toString().removePrefix("Node( <").split("#")[1].removeSuffix("> )") 39 | 40 | val foundAny = interpreter.heap.keys.firstOrNull { it.literal == found } 41 | if(foundAny != null) newMemory["content"] = LiteralExpr(found, foundAny.tag) 42 | else { 43 | if(found.startsWith("\"")) newMemory["content"] = LiteralExpr(found, STRINGTYPE) 44 | else if(found.matches("\\d+".toRegex())) newMemory["content"] = LiteralExpr(found, INTTYPE) 45 | else if(found.matches("\\d+.\\d+".toRegex())) newMemory["content"] = LiteralExpr(found, DOUBLETYPE) 46 | else throw Exception("Concept returned unknown object/literal: $found") 47 | } 48 | 49 | newMemory["next"] = list 50 | interpreter.heap[name] = newMemory 51 | list = name 52 | } 53 | return replaceStmt(AssignStmt(target, list, declares = declares), stackFrame) 54 | } 55 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/stmt/PrintStmt.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.stmt 2 | 3 | import no.uio.microobject.ast.Expression 4 | import no.uio.microobject.ast.Statement 5 | import no.uio.microobject.runtime.EvalResult 6 | import no.uio.microobject.runtime.Interpreter 7 | import no.uio.microobject.runtime.Memory 8 | import no.uio.microobject.runtime.StackEntry 9 | import no.uio.microobject.type.STRINGTYPE 10 | 11 | //for output 12 | data class PrintStmt(val expr: Expression, val pos : Int = -1): Statement { 13 | override fun toString(): String = "println($expr)" 14 | override fun getRDF(): String { 15 | return """ 16 | prog:stmt${this.hashCode()} rdf:type smol:PrintStatement. 17 | prog:stmt${this.hashCode()} smol:hasStmtExpr prog:expr${expr.hashCode()}. 18 | prog:stmt${this.hashCode()} smol:Line '$pos'^^xsd:integer. 19 | 20 | """.trimIndent() + expr.getRDF() 21 | } 22 | 23 | override fun eval(heapObj: Memory, stackFrame: StackEntry, interpreter: Interpreter): EvalResult { 24 | val res = interpreter.eval(expr, stackFrame) 25 | if(res.tag == STRINGTYPE) println(res.literal.removeSurrounding("\"")) 26 | else println(res) 27 | return EvalResult(null, emptyList()) 28 | } 29 | 30 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/stmt/ReturnStmt.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.stmt 2 | 3 | import no.uio.microobject.ast.* 4 | import no.uio.microobject.runtime.EvalResult 5 | import no.uio.microobject.runtime.Interpreter 6 | import no.uio.microobject.runtime.Memory 7 | import no.uio.microobject.runtime.StackEntry 8 | 9 | // Return statement 10 | data class ReturnStmt(var value : Expression, val pos : Int = -1) : Statement { 11 | override fun toString(): String = "return $value" 12 | override fun getRDF(): String { 13 | return """ 14 | prog:stmt${this.hashCode()} rdf:type smol:ReturnStatement. 15 | prog:stmt${this.hashCode()} smol:hasValue prog:expr${value.hashCode()}. 16 | prog:stmt${this.hashCode()} smol:Line '$pos'^^xsd:integer. 17 | 18 | """.trimIndent() + value.getRDF() 19 | } 20 | 21 | override fun eval(heapObj: Memory, stackFrame: StackEntry, interpreter: Interpreter): EvalResult { 22 | val over = interpreter.stack.pop() 23 | if (over.active is StoreReturnStmt) { 24 | val res = interpreter.eval(value, stackFrame) 25 | return EvalResult( 26 | StackEntry( 27 | AssignStmt(over.active.target, res, declares = null), 28 | over.store, 29 | over.obj, 30 | over.id 31 | ), listOf() 32 | ) 33 | } 34 | if (over.active is SequenceStmt && over.active.first is StoreReturnStmt) { 35 | val active = over.active.first 36 | val next = over.active.second 37 | val res = interpreter.eval(value, stackFrame) 38 | return replaceStmt(appendStmt(AssignStmt(active.target, res, declares = null), next), over) 39 | } 40 | throw Exception("Malformed heap") 41 | } 42 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/stmt/SequenceStmt.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.stmt 2 | 3 | import no.uio.microobject.ast.Statement 4 | import no.uio.microobject.ast.appendStmt 5 | import no.uio.microobject.runtime.EvalResult 6 | import no.uio.microobject.runtime.Interpreter 7 | import no.uio.microobject.runtime.Memory 8 | import no.uio.microobject.runtime.StackEntry 9 | 10 | // We use a binary tree instead of a list to make the interpreter more simple. 11 | // The value of first is NOT allowed to be another SequenceStmt. Use appendStmt below to build trees. 12 | data class SequenceStmt(val first: Statement, val second : Statement) : Statement { 13 | override fun getLast(): Statement = second 14 | override fun toString(): String = "$first; $second" 15 | override fun getRDF(): String { 16 | return """ 17 | prog:stmt${this.hashCode()} rdf:type smol:SequenceStatement. 18 | prog:stmt${this.hashCode()} smol:first prog:stmt${first.hashCode()}. 19 | prog:stmt${this.hashCode()} smol:second prog:stmt${second.hashCode()}. 20 | 21 | """.trimIndent() + first.getRDF() + second.getRDF() 22 | } 23 | 24 | override fun eval(heapObj: Memory, stackFrame: StackEntry, interpreter: Interpreter): EvalResult { 25 | if (first is ReturnStmt) return first.eval(heapObj, stackFrame, interpreter) 26 | val res = first.eval(heapObj, stackFrame, interpreter) 27 | if (res.current != null) { 28 | val newStmt = appendStmt(res.current.active, second) 29 | return EvalResult( 30 | StackEntry(newStmt, res.current.store, res.current.obj, stackFrame.id), 31 | res.spawns, 32 | res.debug 33 | ) 34 | } else return EvalResult( 35 | StackEntry(second, stackFrame.store, stackFrame.obj, stackFrame.id), 36 | res.spawns, 37 | res.debug 38 | ) 39 | } 40 | 41 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/stmt/SimulationStmt.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.stmt 2 | 3 | import no.uio.microobject.ast.Location 4 | import no.uio.microobject.ast.Names 5 | import no.uio.microobject.ast.Statement 6 | import no.uio.microobject.ast.VarInit 7 | import no.uio.microobject.runtime.* 8 | import no.uio.microobject.type.Type 9 | 10 | // For simulation interface 11 | data class SimulationStmt(val target : Location, val path: String, val params : List, val pos : Int = -1, val declares: Type?) : 12 | Statement { 13 | override fun toString(): String = "$target := simulate($path, ${params.joinToString(",")})" 14 | override fun getRDF(): String { 15 | //TODO: extend ontology 16 | return "" 17 | } 18 | 19 | override fun eval(heapObj: Memory, stackFrame: StackEntry, interpreter: Interpreter): EvalResult { 20 | val simObj = SimulatorObject(path, params.associate { 21 | Pair(it.name, interpreter.eval(it.expr, stackFrame)) 22 | }.toMutableMap()) 23 | val name = Names.getObjName("CoSimulation") 24 | interpreter.simMemory[name] = simObj 25 | return replaceStmt(AssignStmt(target, name, declares = declares), stackFrame) 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/stmt/SkipStmt.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.stmt 2 | 3 | import no.uio.microobject.ast.Statement 4 | import no.uio.microobject.runtime.EvalResult 5 | import no.uio.microobject.runtime.Interpreter 6 | import no.uio.microobject.runtime.Memory 7 | import no.uio.microobject.runtime.StackEntry 8 | 9 | /** Statement **/ 10 | 11 | // Empty statement. Handy for unrolling of loops. 12 | data class SkipStmt(val pos : Int = -1) : Statement { 13 | override fun toString(): String = "skip" 14 | override fun getRDF(): String = "prog:stmt${this.hashCode()} rdf:type smol:SkipStatement.\nprog:stmt${this.hashCode()} smol:Line '$pos'^^xsd:integer.\n" 15 | 16 | override fun eval(heapObj: Memory, stackFrame : StackEntry, interpreter: Interpreter) : EvalResult { 17 | return EvalResult(null, emptyList()) 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/stmt/StoreReturnStmt.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.stmt 2 | 3 | import no.uio.microobject.ast.Location 4 | import no.uio.microobject.ast.Statement 5 | import no.uio.microobject.runtime.EvalResult 6 | import no.uio.microobject.runtime.Interpreter 7 | import no.uio.microobject.runtime.Memory 8 | import no.uio.microobject.runtime.StackEntry 9 | 10 | // This is a runtime-syntax only statement which models that we will write the return value of the next method in the stack into target 11 | data class StoreReturnStmt(val target : Location, val pos : Int = -1) : Statement { 12 | override fun toString(): String = "$target <- stack" 13 | override fun getRDF(): String { 14 | return """ 15 | prog:stmt${this.hashCode()} rdf:type smol:StoreReturnStatement. 16 | prog:stmt${this.hashCode()} smol:hasTarget prog:loc${target.hashCode()}. 17 | prog:stmt${this.hashCode()} smol:Line '$pos'^^xsd:integer. 18 | 19 | """.trimIndent() + target.getRDF() 20 | } 21 | 22 | override fun eval(heapObj: Memory, stackFrame: StackEntry, interpreter: Interpreter): EvalResult { 23 | throw Exception("StoreReturnStmt found on top of stack") 24 | } 25 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/stmt/SuperStmt.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.stmt 2 | 3 | import no.uio.microobject.ast.* 4 | import no.uio.microobject.runtime.EvalResult 5 | import no.uio.microobject.runtime.Interpreter 6 | import no.uio.microobject.runtime.Memory 7 | import no.uio.microobject.runtime.StackEntry 8 | import no.uio.microobject.type.BaseType 9 | import no.uio.microobject.type.Type 10 | 11 | // Super call. MethodName is merely saved for easier access for the interpreter 12 | data class SuperStmt(val target : Location, val methodName : String, val params : List, val pos : Int = -1, val declares: Type?) : 13 | Statement { 14 | override fun toString(): String = "$target := super(${params.joinToString(",")})" 15 | override fun getRDF(): String { 16 | var s = """ 17 | prog:stmt${this.hashCode()} rdf:type smol:SuperStatement. 18 | prog:stmt${this.hashCode()} smol:hasTarget prog:loc${target.hashCode()}. 19 | prog:stmt${this.hashCode()} smol:Line '$pos'^^xsd:integer. 20 | 21 | """.trimIndent() 22 | for (i in params.indices){ 23 | s += "prog:stmt${this.hashCode()} smol:hasParameter [smol:hasParameterIndex $i ; smol:hasParameterValue prog:expr${params[i].hashCode()}; ].\n" 24 | s += params[i].getRDF() 25 | } 26 | return s + target.getRDF() 27 | } 28 | 29 | override fun eval(heapObj: Memory, stackFrame: StackEntry, interpreter: Interpreter): EvalResult { 30 | if(stackFrame.obj.tag !is BaseType) throw Exception("This object is unknown: ${stackFrame.obj}") 31 | val m = interpreter.staticInfo.getSuperMethod(stackFrame.obj.tag.name, methodName) ?: throw Exception("super call impossible, no super method found.") 32 | val newMemory: Memory = mutableMapOf() 33 | newMemory["this"] = stackFrame.obj 34 | for (i in m.params.indices) { 35 | newMemory[m.params[i]] = interpreter.eval(params[i], stackFrame) 36 | } 37 | return EvalResult( 38 | StackEntry(StoreReturnStmt(target), stackFrame.store, stackFrame.obj, stackFrame.id), 39 | listOf(StackEntry(m.stmt, newMemory, stackFrame.obj, Names.getStackId())) 40 | ) 41 | } 42 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/stmt/TickStmt.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.stmt 2 | 3 | import no.uio.microobject.ast.Expression 4 | import no.uio.microobject.ast.Statement 5 | import no.uio.microobject.runtime.EvalResult 6 | import no.uio.microobject.runtime.Interpreter 7 | import no.uio.microobject.runtime.Memory 8 | import no.uio.microobject.runtime.StackEntry 9 | 10 | data class TickStmt(val fmu: Expression, val tick : Expression, val pos : Int = -1) : Statement { 11 | override fun toString(): String = "tick($fmu, $tick)" 12 | override fun getRDF(): String { 13 | //TODO: extend ontology 14 | return "" 15 | } 16 | 17 | override fun eval(heapObj: Memory, stackFrame: StackEntry, interpreter: Interpreter): EvalResult { 18 | val target = interpreter.eval(fmu, stackFrame) 19 | if(!interpreter.simMemory.containsKey(target)) throw Exception("Object $target is no a simulation object") 20 | val tickTime = interpreter.eval(tick, stackFrame) 21 | interpreter.simMemory[target]!!.tick(tickTime.literal.toDouble()) 22 | return EvalResult(null, emptyList()) 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/stmt/ValidateStmt.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.stmt 2 | 3 | import no.uio.microobject.ast.* 4 | import no.uio.microobject.ast.expr.FALSEEXPR 5 | import no.uio.microobject.ast.expr.LiteralExpr 6 | import no.uio.microobject.ast.expr.TRUEEXPR 7 | import no.uio.microobject.runtime.EvalResult 8 | import no.uio.microobject.runtime.Interpreter 9 | import no.uio.microobject.runtime.Memory 10 | import no.uio.microobject.runtime.StackEntry 11 | import no.uio.microobject.type.Type 12 | import org.apache.jena.riot.RDFDataMgr 13 | import org.apache.jena.shacl.ShaclValidator 14 | import org.apache.jena.shacl.Shapes 15 | import java.io.File 16 | 17 | data class ValidateStmt(val target : Location, val query: Expression, val pos : Int = -1, val declares: Type?) : 18 | Statement { 19 | override fun toString(): String = "$target := validate($query)" 20 | override fun getRDF(): String { 21 | return """ 22 | prog:stmt${this.hashCode()} rdf:type smol:ShaclStatement. 23 | prog:stmt${this.hashCode()} smol:hasTarget prog:loc${target.hashCode()}. 24 | prog:stmt${this.hashCode()} smol:hasQuery prog:expr${query.hashCode()}. 25 | prog:stmt${this.hashCode()} smol:Line '$pos'^^xsd:integer. 26 | 27 | """.trimIndent() + target.getRDF() + query.getRDF() 28 | } 29 | 30 | override fun eval(heapObj: Memory, stackFrame: StackEntry, interpreter: Interpreter): EvalResult { 31 | if(query !is LiteralExpr) throw Exception("validate takes a file path in a String as a parameter") 32 | val fileName = query.literal.removeSurrounding("\"") 33 | val file = File(fileName) 34 | if(!file.exists()) throw Exception("file $fileName does not exist") 35 | val newFile = File("${interpreter.settings.outdir}/shape.ttl") 36 | if(!newFile.exists()) { 37 | File(interpreter.settings.outdir).mkdirs() 38 | newFile.createNewFile() 39 | } 40 | newFile.writeText(interpreter.settings.prefixes() + "\n"+ interpreter.settings.getHeader() + "\n@prefix sh: .\n") 41 | newFile.appendText(file.readText()) 42 | val shapesGraph = RDFDataMgr.loadGraph("${interpreter.settings.outdir}/shape.ttl") 43 | val dataGraph = interpreter.tripleManager.getModel().graph 44 | 45 | val shapes: Shapes = Shapes.parse(shapesGraph) 46 | 47 | val report = ShaclValidator.get().validate(shapes, dataGraph) 48 | val resLit = if(report.conforms()) TRUEEXPR else FALSEEXPR 49 | return replaceStmt(AssignStmt(target, resLit, declares = declares), stackFrame) 50 | } 51 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/ast/stmt/WhileStmt.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.ast.stmt 2 | 3 | import no.uio.microobject.ast.Expression 4 | import no.uio.microobject.ast.Statement 5 | import no.uio.microobject.ast.appendStmt 6 | import no.uio.microobject.runtime.EvalResult 7 | import no.uio.microobject.runtime.Interpreter 8 | import no.uio.microobject.runtime.Memory 9 | import no.uio.microobject.runtime.StackEntry 10 | 11 | data class WhileStmt(val guard : Expression, val loopBody : Statement, val pos : Int = -1) : Statement { 12 | override fun toString(): String = "while $guard do $loopBody end" 13 | override fun getRDF(): String { 14 | return """ 15 | prog:stmt${this.hashCode()} rdf:type smol:WhileStatement. 16 | prog:stmt${this.hashCode()} smol:hasGuard prog:expr${guard.hashCode()}. 17 | prog:stmt${this.hashCode()} smol:hasLoopBody prog:stmt${loopBody.hashCode()}. 18 | prog:stmt${this.hashCode()} smol:Line '$pos'^^xsd:integer. 19 | 20 | """.trimIndent() + guard.getRDF() + loopBody.getRDF() 21 | } 22 | 23 | override fun eval(heapObj: Memory, stackFrame: StackEntry, interpreter: Interpreter): EvalResult { 24 | return replaceStmt(IfStmt(guard, appendStmt(loopBody, this), SkipStmt()), stackFrame) 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/runtime/State.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.runtime 2 | 3 | import no.uio.microobject.ast.Expression 4 | import no.uio.microobject.ast.expr.LiteralExpr 5 | import no.uio.microobject.ast.Statement 6 | import no.uio.microobject.type.Type 7 | import org.apache.jena.query.ResultSet 8 | 9 | /* 10 | We use the term "heap" NOT in the sense of C and other low-level here. 11 | Heap memory is barely the opposite of local memory, we have no assumptions about the memory. 12 | */ 13 | typealias Memory = MutableMap // Maps variable names to values 14 | typealias GlobalMemory = MutableMap // Maps object name literals to local memories 15 | typealias SimulationMemory = MutableMap // Maps object name literals to local memories 16 | typealias FieldEntry = List //list of fields 17 | typealias ModelsEntry = Pair //guard expression and models string 18 | typealias QueryCache = MutableMap //query cache 19 | 20 | enum class Visibility { DEFAULT, HIDE } 21 | 22 | data class FieldInfo(val name: String, val type: Type, val computationVisibility : Visibility, val declaredIn : Type, val isDomain : Boolean, val internalInit : Expression? = null) 23 | data class MethodInfo(val stmt: Statement, val params: List, val isRule : Boolean, val isDomain: Boolean, val declaringClass: String, val retType : Type) 24 | data class StaticTable( 25 | val fieldTable: Map, // This maps class names to their fields 26 | val methodTable: Map>, // This maps class names to a map that maps method names to their definition 27 | val hierarchy: MutableMap> = mutableMapOf(), // DOWNWARDS class hierarchy 28 | val modelsTable: Map>, // This maps class names to complex models blocks 29 | val hiddenSet: Set,//This set of classes is skipped by the lifting 30 | val owldescr: MutableMap, // This maps class names to the default models block 31 | val checkClassifiesTable: MutableMap>> = mutableMapOf(), // Queries for classification 32 | val contextTable: MutableMap 33 | 34 | ) { 35 | override fun toString(): String = 36 | """ 37 | Class Hierarchy : $hierarchy 38 | FieldTable : $fieldTable 39 | MethodTable : $methodTable 40 | """.trimIndent() 41 | 42 | private fun getSuper(name : String) : String?{ 43 | for(obj in hierarchy.entries){ 44 | for(obj2 in obj.value){ 45 | if(obj2 == name) return obj.key 46 | } 47 | } 48 | return null 49 | } 50 | 51 | fun getSuperMethod(className : String, methodName : String) : MethodInfo?{ 52 | var current = getSuper(className) 53 | while(current != null && current != "Object"){ 54 | if(!methodTable.containsKey(current)) return null 55 | if(methodTable[current]!!.containsKey(methodName)) return methodTable[current]!![methodName] 56 | current = getSuper(current) 57 | } 58 | return null 59 | } 60 | } 61 | 62 | data class StackEntry(val active: Statement, val store: Memory, val obj: LiteralExpr, val id: Int) 63 | -------------------------------------------------------------------------------- /src/main/kotlin/no/uio/microobject/type/TypeErrors.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.type 2 | 3 | import org.antlr.v4.runtime.ParserRuleContext 4 | 5 | //Error Messages 6 | enum class Severity { WARNING, ERROR } 7 | data class TypeError(val msg: String, val line: Int, val severity: Severity) 8 | 9 | open class TypeErrorLogger { 10 | //Final output: collected errors 11 | internal var error : List = listOf() 12 | 13 | /* interface: prints all errors and returns whether one of them is an error */ 14 | open fun report(silent : Boolean = false) : Boolean { 15 | var ret = true 16 | for( e in error ){ 17 | if(e.severity == Severity.ERROR) ret = false 18 | if(!silent) println("Line ${e.line}, ${e.severity}: ${e.msg}") 19 | } 20 | return ret 21 | } 22 | 23 | /* adds new error/warning */ 24 | fun log(msg: String, node : ParserRuleContext?, severity: Severity = Severity.ERROR){ 25 | 26 | error = error + TypeError(msg, (node?.getStart()?.line ?: 0 ), severity) 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/test/kotlin/no/uio/microobject/test/RegressionTests.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.test 2 | 3 | import no.uio.microobject.test.type.MicroObjectTypeTest 4 | import kotlin.test.assertFalse 5 | 6 | class RegressionTests : MicroObjectTypeTest() { 7 | init{ 8 | "Issue10" { 9 | assertFalse(checkMet("Hello", "say_hello", "bug_10").report(false)) 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/test/kotlin/no/uio/microobject/test/ast/stmt/ClassificationTest.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.test.ast.stmt 2 | 3 | import io.kotest.matchers.shouldBe 4 | import no.uio.microobject.test.MicroObjectTest 5 | import no.uio.microobject.type.BaseType 6 | 7 | class ClassificationTest : MicroObjectTest() { 8 | private fun classifyTest() { 9 | loadBackground("src/test/resources/classification_example.ttl", "http://www.smolang.org/ex#") 10 | val (interpreter, _) = initInterpreter("classification", StringLoad.RES, hashMapOf("ast" to "http://www.smolang.org/ex#")) 11 | 12 | executeUntilBreak(interpreter) 13 | val keys = interpreter.heap.keys 14 | 15 | // Check if the tag of one of the keys (speficially it will be the run obj) is C 16 | keys.any { it.tag == BaseType("C") } shouldBe true 17 | } 18 | 19 | init { 20 | "eval" { 21 | classifyTest() 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/kotlin/no/uio/microobject/test/basic/BasicTest.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.test.basic 2 | 3 | import io.kotest.core.spec.style.StringSpec 4 | import no.uio.microobject.antlr.WhileLexer 5 | import no.uio.microobject.antlr.WhileParser 6 | import no.uio.microobject.ast.Translate 7 | import no.uio.microobject.main.Settings 8 | import no.uio.microobject.type.Severity 9 | import no.uio.microobject.type.TypeChecker 10 | import org.antlr.v4.runtime.CharStreams 11 | import org.antlr.v4.runtime.CommonTokenStream 12 | import java.io.File 13 | import kotlin.test.assertEquals 14 | import no.uio.microobject.data.TripleManager 15 | import org.apache.commons.lang3.SystemUtils.IS_OS_MAC 16 | import org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS 17 | import org.junit.Assume 18 | 19 | class BasicTest : StringSpec() { 20 | private fun load(path : String) : Int { 21 | val localPath = if(IS_OS_WINDOWS) path.removePrefix("/") else path 22 | val stdLib = this::class.java.classLoader.getResource("StdLib.smol").readText() + "\n\n" 23 | val program = File(localPath).readText(Charsets.UTF_8) 24 | val lexer = WhileLexer(CharStreams.fromString(stdLib + program)) 25 | val tokens = CommonTokenStream(lexer) 26 | val parser = WhileParser(tokens) 27 | val tree = parser.program() 28 | 29 | val visitor = Translate() 30 | val pair = visitor.generateStatic(tree) 31 | 32 | 33 | val settings = Settings(false,false, "/tmp/mo", "","","urn:", "", extraPrefixes = hashMapOf()) 34 | val tripleManager = TripleManager(settings, pair.second, null) 35 | 36 | val tC = TypeChecker(tree, settings, tripleManager) 37 | 38 | tC.check() 39 | tC.report() 40 | return tC.error.filter { it.severity == Severity.ERROR }.size 41 | } 42 | 43 | init { 44 | "parsing Jacobi".config(enabled = !IS_OS_MAC) { 45 | Assume.assumeTrue("FMUs not found", 46 | File("examples/SimulationDemo/Prey.fmu").exists() 47 | && File("examples/SimulationDemo/Predator.fmu").exists()) 48 | assertEquals(load(this::class.java.classLoader.getResource("Jacobi.smol").file), 0) 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/test/kotlin/no/uio/microobject/test/basic/ExtraPrefixTest.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.test.basic 2 | 3 | import io.kotest.matchers.shouldBe 4 | import no.uio.microobject.test.MicroObjectTest 5 | 6 | class ExtraPrefixTest: MicroObjectTest() { 7 | fun prefixTest() { 8 | val (interpreter,_) = initInterpreter("persons", StringLoad.RES) 9 | 10 | interpreter.settings.prefixMap().containsKey("ast") shouldBe false 11 | interpreter.settings.addPrefixes(hashMapOf("ast" to "http://www.smolang.org/ast#")) 12 | interpreter.settings.prefixMap().containsKey("ast") shouldBe true 13 | } 14 | init { 15 | prefixTest() 16 | } 17 | } -------------------------------------------------------------------------------- /src/test/kotlin/no/uio/microobject/test/data/TripleManagerTest.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.test.data 2 | 3 | import io.kotest.matchers.shouldBe 4 | import no.uio.microobject.ast.expr.LiteralExpr 5 | import no.uio.microobject.ast.expr.LocalVar 6 | import no.uio.microobject.main.testModel 7 | import no.uio.microobject.test.MicroObjectTest 8 | import no.uio.microobject.type.DOUBLETYPE 9 | import org.apache.jena.fuseki.main.FusekiServer 10 | import org.apache.jena.query.DatasetFactory 11 | import org.apache.jena.query.QueryFactory 12 | import org.apache.jena.query.ResultSet 13 | import org.apache.jena.rdf.model.ModelFactory 14 | import org.apache.jena.rdfconnection.RDFConnection 15 | import org.apache.jena.rdfconnection.RDFConnectionFactory 16 | 17 | class TripleManagerTest: MicroObjectTest() { 18 | private fun fusekiTest() { 19 | testModel = ModelFactory.createDefaultModel() 20 | testModel!!.read("src/test/resources/tree_shapes.ttl") 21 | val (interpreter,_) = initTripleStoreInterpreter("persons", StringLoad.RES) 22 | 23 | interpreter.tripleManager.getModel().containsAny(testModel!!) shouldBe true 24 | } 25 | 26 | private fun fusekiServerTest() { 27 | 28 | val model = ModelFactory.createDefaultModel() 29 | model.read("src/test/resources/tree_shapes.ttl") 30 | 31 | val ds = DatasetFactory.createTxnMem() 32 | ds.defaultModel.add(model) 33 | 34 | // Execute the Fuseki triplestore with model 35 | val fusekiServer = FusekiServer.create().add("/ds", ds).build() ; 36 | fusekiServer.start() ; 37 | 38 | val (interpreter,_) = initTripleStoreInterpreter("persons", StringLoad.RES) 39 | fusekiServer.stop() 40 | interpreter.tripleManager.getModel().containsAny(model) shouldBe true 41 | } 42 | 43 | init { 44 | "triple store".config(enabledOrReasonIf = tripleStoreToTest) { 45 | // The triple store is initialised with this url, but we'll also test that we can get something 46 | val queryUrl = "http://localhost:3030/ds/query" 47 | val queryConn: RDFConnection = RDFConnectionFactory.connect(queryUrl) 48 | 49 | val query = QueryFactory.create("SELECT * WHERE { ?s ?p ?o } LIMIT 1") 50 | val qexec = queryConn.query(query) 51 | val result: ResultSet = qexec.execSelect() 52 | 53 | queryConn.close() 54 | 55 | result.hasNext() shouldBe true 56 | } 57 | "eval" { 58 | fusekiTest() 59 | fusekiServerTest() 60 | } 61 | } 62 | } -------------------------------------------------------------------------------- /src/test/kotlin/no/uio/microobject/test/execution/AdaptTest.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.test.execution 2 | 3 | import no.uio.microobject.ast.expr.LiteralExpr 4 | import no.uio.microobject.ast.expr.LocalVar 5 | import no.uio.microobject.test.MicroObjectTest 6 | import no.uio.microobject.type.INTTYPE 7 | import kotlin.test.assertEquals 8 | 9 | class AdaptTest : MicroObjectTest() { 10 | 11 | init { 12 | "adapt"{ 13 | 14 | loadBackground("src/test/resources/selfadapt/greenhouse.ttl","urn:") 15 | val (a,_) = initInterpreter(listOf("selfadapt/Greenhouse_data","selfadapt/Greenhouse_health","selfadapt/Greenhouse_plants", 16 | "selfadapt/Greenhouse_pots","selfadapt/Greenhouse_pumps","selfadapt/GreenHouse")) 17 | executeUntilBreak(a) 18 | assertEquals(1, a.stack.size) 19 | assertEquals(LiteralExpr("3", INTTYPE), a.evalTopMost(LocalVar("l1", INTTYPE))) 20 | assertEquals(LiteralExpr("4", INTTYPE), a.evalTopMost(LocalVar("l2", INTTYPE))) 21 | assertEquals(LiteralExpr("4", INTTYPE), a.evalTopMost(LocalVar("l3", INTTYPE))) 22 | assertEquals(LiteralExpr("4", INTTYPE), a.evalTopMost(LocalVar("l4", INTTYPE))) 23 | } 24 | } 25 | } -------------------------------------------------------------------------------- /src/test/kotlin/no/uio/microobject/test/execution/FMOLExecutionTest.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.test.execution 2 | 3 | import no.uio.microobject.ast.expr.LiteralExpr 4 | import no.uio.microobject.ast.expr.LocalVar 5 | import no.uio.microobject.test.MicroObjectTest 6 | import no.uio.microobject.type.DOUBLETYPE 7 | import no.uio.microobject.type.INTTYPE 8 | import kotlin.test.assertEquals 9 | 10 | class FMOLExecutionTest: MicroObjectTest() { 11 | init { 12 | "adder 1".config(enabledOrReasonIf = fmuNeedsWindows) { 13 | val stmt = """ 14 | FMO[in Double ra, in Double rb, out Double rc] fmu1 = simulate("src/test/resources/adder.fmu", ra = 1.0, rb = 1.0); 15 | Double res = fmu1.rc; 16 | breakpoint; 17 | print(res); 18 | """.trimIndent() 19 | val (a,t) = initInterpreter(stmt,StringLoad.STMT) 20 | assert(t.report()) 21 | executeUntilBreak(a) 22 | assertEquals(LiteralExpr("2.0", DOUBLETYPE), a.evalTopMost(LocalVar("res", DOUBLETYPE))) 23 | } 24 | "linear 1".config(enabledOrReasonIf = fmuNeedsLinux) { 25 | val stmt = """ 26 | FMO[out Int outPort] fmu1 = simulate("src/test/resources/linear.fmu", inPort = 1); 27 | fmu1.tick(1.0); 28 | Int res = fmu1.outPort; 29 | breakpoint; 30 | print(outPort); 31 | """.trimIndent() 32 | val (a,t) = initInterpreter(stmt,StringLoad.STMT) 33 | assert(t.report()) 34 | executeUntilBreak(a) 35 | assertEquals(LiteralExpr("1", INTTYPE), a.evalTopMost(LocalVar("res", DOUBLETYPE))) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/test/kotlin/no/uio/microobject/test/runtime/Interpreter.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.test.runtime 2 | 3 | import io.kotest.matchers.shouldBe 4 | import no.uio.microobject.ast.expr.LiteralExpr 5 | import no.uio.microobject.test.MicroObjectTest 6 | import no.uio.microobject.type.* 7 | import org.apache.jena.rdf.model.impl.LiteralImpl 8 | import kotlin.test.assertEquals 9 | 10 | class Interpreter : MicroObjectTest() { 11 | private fun evalTest() { 12 | val (interpreter,_) = initInterpreter("persons", StringLoad.RES) 13 | val expr = LiteralExpr("50.0") 14 | val result = interpreter.eval(expr, interpreter.stack.peek()) 15 | result shouldBe LiteralExpr("50.0") 16 | } 17 | 18 | private fun getObjectNamesTest() { 19 | val (interpreter,_) = initInterpreter("persons", StringLoad.RES) 20 | 21 | executeUntilBreak(interpreter) 22 | val marriage = interpreter.getObjectNames("Marriage") 23 | val person = interpreter.getObjectNames("Person") 24 | 25 | marriage.size shouldBe 1 26 | person.size shouldBe 2 27 | } 28 | 29 | private fun evalParamsTest() { 30 | val (interpreter, _) = initInterpreter("eval-params", StringLoad.RES) 31 | executeUntilBreak(interpreter) 32 | 33 | interpreter.evalCall(interpreter.getObjectNames("A")[0].toString(), "A", "setX", mapOf("newX" to LiteralExpr("1", INTTYPE))) 34 | val queryRes = interpreter.query("SELECT * WHERE { ?obj a prog:A . ?obj prog:A_x ?x }") 35 | queryRes!!.hasNext() shouldBe true 36 | 37 | val x = queryRes.next() 38 | assertEquals(1, (x["x"] as LiteralImpl).int) 39 | } 40 | 41 | init { 42 | "eval" { 43 | evalTest() 44 | getObjectNamesTest() 45 | evalParamsTest() 46 | } 47 | } 48 | } -------------------------------------------------------------------------------- /src/test/kotlin/no/uio/microobject/test/triples/OWLQueryTest.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.test.triples 2 | 3 | import no.uio.microobject.test.MicroObjectTest 4 | import org.semanticweb.HermiT.Reasoner 5 | import org.semanticweb.owlapi.reasoner.OWLReasoner 6 | import kotlin.test.assertEquals 7 | 8 | class OWLQueryTest: MicroObjectTest() { 9 | init { 10 | val (interpreter,_) = initInterpreter("persons", StringLoad.RES) 11 | 12 | val q1 = "" 13 | val q2 = "" 14 | val q3 = "" 15 | val q4 = "" 16 | executeUntilBreak(interpreter) 17 | 18 | "OWL query 1" { 19 | val s = interpreter.owlQuery(q1) 20 | assertEquals(s.count(), 8) 21 | } 22 | "OWL query 2" { 23 | val s = interpreter.owlQuery(q2) 24 | assertEquals(s.count(), 0) 25 | } 26 | "OWL query 3" { 27 | val s = interpreter.owlQuery(q3) 28 | assertEquals(s.count(), 2) // No steps, so no persons yet 29 | } 30 | "OWL query 4" { 31 | val s = interpreter.owlQuery(q4) 32 | assertEquals(s.count(), 1) // No steps, so no marriages yet. 33 | } 34 | 35 | "OWL consistency" { 36 | val ontology = interpreter.tripleManager.getOntology() 37 | val reasoner : OWLReasoner = Reasoner.ReasonerFactory().createReasoner(ontology) 38 | assertEquals(reasoner.isConsistent, true) 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/test/kotlin/no/uio/microobject/test/type/FMOLTypeTest.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.test.type 2 | 3 | import kotlin.test.assertFalse 4 | 5 | class FMOLTypeTest : MicroObjectTypeTest() { 6 | init{ 7 | "Simulate success 1".config(enabledOrReasonIf = fmuNeedsWindows) { 8 | val tC = checkMet("SuccessClass", "start", "test_fmu") 9 | assert(tC.report(false)) 10 | } 11 | "Simulate success 2".config(enabledOrReasonIf = fmuNeedsWindows) { 12 | val tC = checkMet("SuccessClass", "assign", "test_fmu") 13 | assert(tC.report(false)) 14 | } 15 | "Simulate success 3".config(enabledOrReasonIf = fmuNeedsWindows) { 16 | val tC = checkMet("SuccessClass", "portTest", "test_fmu") 17 | assert(tC.report(false)) 18 | } 19 | for( i in 1..6 ) 20 | "Simulate fail $i".config(enabledOrReasonIf = fmuNeedsWindows) { 21 | val tC = checkMet("FailClass", "fail$i", "test_fmu") 22 | assertFalse(tC.report(false)) 23 | } 24 | for( i in 1..6 ) 25 | "fields $i".config(enabledOrReasonIf = fmuNeedsWindows) { 26 | val tC = checkMet("SuccessClass", "fieldfail$i", "test_fmu") 27 | assertFalse(tC.report(false)) 28 | } 29 | "extra fields".config(enabledOrReasonIf = fmuNeedsWindows) { 30 | val tC = checkMet("SuccessClass", "extra", "test_fmu") 31 | assert(tC.report(false)) 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/kotlin/no/uio/microobject/test/type/MicroObjectTypeTest.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.test.type 2 | 3 | import no.uio.microobject.test.MicroObjectTest 4 | import no.uio.microobject.type.TypeChecker 5 | 6 | open class MicroObjectTypeTest : MicroObjectTest() { 7 | 8 | protected fun checkMet(className : String, metName : String, filename: String) : TypeChecker{ 9 | val pair = initTc(filename, StringLoad.RES) 10 | val classes = retrieveClass(className, pair.second) 11 | assert(classes.size == 1) 12 | val methods = retrieveMethod(metName, classes[0]) 13 | assert(methods.size == 1) 14 | val met = methods[0] 15 | pair.first.checkMet(met, className) 16 | return pair.first 17 | } 18 | 19 | protected fun checkClass(className : String, filename: String) : TypeChecker{ 20 | val pair = initTc(filename, StringLoad.RES) 21 | val classes = retrieveClass(className, pair.second) 22 | assert(classes.size == 1) 23 | val classDef = classes[0] 24 | pair.first.checkClass(classDef) 25 | return pair.first 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/test/kotlin/no/uio/microobject/test/type/SMOLTypeTest.kt: -------------------------------------------------------------------------------- 1 | package no.uio.microobject.test.type 2 | 3 | import no.uio.microobject.type.Severity 4 | import kotlin.test.assertFalse 5 | 6 | class SMOLTypeTest : MicroObjectTypeTest() { 7 | init{ 8 | for(i in 1..5) 9 | "Query check success $i"{ 10 | val tC = checkMet("Test", "mSuccess$i", "type_query") 11 | assert(tC.report(false)) 12 | assert(tC.queryCheckers.all { it.error.none { it.severity == Severity.ERROR } }) 13 | } 14 | 15 | "Query check fail 1"{ 16 | val tC = checkMet("Test", "mFail1", "type_query") 17 | assertFalse(tC.report(false)) 18 | } 19 | 20 | "Query check fail 2"{ 21 | val tC = checkMet("Test", "mFail2", "type_query") 22 | assertFalse(tC.report(false)) 23 | } 24 | 25 | "Query check fail 3"{ 26 | val tC = checkMet("Test", "mFail3", "type_query") 27 | assert(tC.report(false)) //%parameters are a warning now 28 | assert(!tC.queryCheckers.all { it.error.isEmpty() }) 29 | } 30 | "Query rule success"{ 31 | val tC = checkMet("F", "getI", "type_query") 32 | assert(tC.report(false)) 33 | } 34 | 35 | "Query rule fail"{ 36 | val tC = checkMet("F", "errorGet", "type_query") 37 | assertFalse(tC.report(false)) 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/test/resources/Jacobi.smol: -------------------------------------------------------------------------------- 1 | 2 | 3 | //Wrapper for simulators: each simulator can have multiple ports 4 | abstract class OutPort() 5 | abstract T2 get() 6 | end 7 | abstract class InPort() 8 | abstract Boolean write(T3 t) 9 | end 10 | 11 | //Co-sim connection 12 | abstract class Connection() 13 | abstract Int propagate() 14 | end 15 | 16 | class ImplConnection extends Connection (OutPort from, InPort to) 17 | override Int propagate() 18 | Double val = this.from.get(); 19 | this.to.write(val); 20 | return 0; 21 | end 22 | end 23 | 24 | //Jacobi master algorithm: propagate through all connections, advance time for all FMUs at once 25 | class CoSim(List list, List sims, Double stepSize) 26 | Int round() 27 | Int i = 0; 28 | if this.list == null then return i; end 29 | Int length = this.list.length(); 30 | while i < length do 31 | Connection c = this.list.get(i); 32 | c.propagate(); 33 | i = i+1; 34 | end 35 | i = 0; 36 | if this.sims == null then return i; end 37 | length = this.sims.length(); 38 | while i < length do 39 | FMO[] de = this.sims.get(i); 40 | de.tick(this.stepSize); 41 | i = i + 1; 42 | end 43 | return i; 44 | end 45 | 46 | Int execute(Int steps) 47 | Int i = 1; 48 | while( i <= steps ) do 49 | this.round(); 50 | i = i+1; 51 | end 52 | return i; 53 | end 54 | end 55 | 56 | //example 57 | class PreyOutPort extends OutPort(FMO[in Double y, out Double x] prey) 58 | override Double get() return this.prey.x; end 59 | end 60 | class PredatorOutPort extends OutPort(FMO[in Double x, out Double y] predator) 61 | override Double get() return this.predator.y; end 62 | end 63 | class PreyInPort extends InPort(FMO[in Double y, out Double x] prey) 64 | override Boolean write(Double t) this.prey.y = t; return True; end 65 | end 66 | class PredatorInPort extends InPort(FMO[in Double x, out Double y] predator) 67 | override Boolean write(Double t) print(t); this.predator.x = t; return True; end 68 | end 69 | 70 | main 71 | FMO[in Double y, out Double x] prey = simulate("examples/SimulationDemo/Prey.fmu", y = 10); 72 | FMO[in Double x, out Double y] predator = simulate("examples/SimulationDemo/Predator.fmu", x = 10); 73 | PreyOutPort preyOut = new PreyOutPort(prey); 74 | PredatorOutPort predOut = new PredatorOutPort(predator); 75 | PreyInPort preyIn = new PreyInPort(prey); 76 | PredatorInPort predIn = new PredatorInPort(predator); 77 | Connection c1 = new ImplConnection(preyOut, predIn); 78 | Connection c2 = new ImplConnection(predOut, preyIn); 79 | List fmus = new List(prey, null); 80 | fmus = new List(predator, fmus); 81 | List cons = new List(c1, null); 82 | cons = new List(c2, cons); 83 | CoSim sim = new CoSim(cons, fmus, 0.2); 84 | sim.execute(200); 85 | end 86 | -------------------------------------------------------------------------------- /src/test/resources/adder.fmu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/src/test/resources/adder.fmu -------------------------------------------------------------------------------- /src/test/resources/bug_10.smol: -------------------------------------------------------------------------------- 1 | class Hello(String message) 2 | Unit say_hello() 3 | print(message); //error, should be this.message 4 | end 5 | end 6 | 7 | main 8 | Hello hello = new Hello("Hello world!"); 9 | hello.say_hello(); 10 | end -------------------------------------------------------------------------------- /src/test/resources/bug_33.smol: -------------------------------------------------------------------------------- 1 | class Plant(String str, String str2, Int i, Int i2, Double d, Double d2, Boolean b, Boolean b2, Object o) end 2 | 3 | 4 | 5 | main 6 | List pl = construct("SELECT ?str ?i ?d ?b {?x domain:str ?str; domain:i ?i; domain:d ?d; domain:b ?b.}"); 7 | Int l = 0; 8 | if pl != null then 9 | l = pl.length(); 10 | end 11 | print(l); 12 | breakpoint; 13 | breakpoint; 14 | end -------------------------------------------------------------------------------- /src/test/resources/classification.smol: -------------------------------------------------------------------------------- 1 | class A() 2 | models "a ast:C"; 3 | Unit printVal() 4 | print("A"); 5 | end 6 | end 7 | 8 | class B extends A() 9 | models "a ast:A"; 10 | classifies "ASK WHERE { 11 | %this domain:models [a ast:B] . 12 | }"; 13 | override Unit printVal() 14 | print("B"); 15 | end 16 | end 17 | 18 | class C extends A() 19 | models "a ast:B"; 20 | classifies " some "; 21 | override Unit printVal() 22 | print("C"); 23 | end 24 | end 25 | 26 | 27 | main 28 | A a = new B(); 29 | classify(a); 30 | breakpoint; 31 | a.printVal(); 32 | end 33 | -------------------------------------------------------------------------------- /src/test/resources/classification_example.ttl: -------------------------------------------------------------------------------- 1 | @prefix : . 2 | @prefix owl: . 3 | @prefix rdf: . 4 | @prefix xml: . 5 | @prefix xsd: . 6 | @prefix rdfs: . 7 | @base . 8 | 9 | rdf:type owl:Ontology . 10 | 11 | ################################################################# 12 | # Classes 13 | ################################################################# 14 | 15 | ### http://www.smolang.org/ex#A 16 | :A rdf:type owl:Class . 17 | 18 | 19 | ### http://www.smolang.org/ex#B 20 | :B rdf:type owl:Class ; 21 | rdfs:subClassOf :A . 22 | 23 | 24 | ### http://www.smolang.org/ex#C 25 | :C rdf:type owl:Class ; 26 | rdfs:subClassOf :A . 27 | 28 | 29 | ### Generated by the OWL API (version 4.5.26.2023-07-17T20:34:13Z) https://github.com/owlcs/owlapi 30 | -------------------------------------------------------------------------------- /src/test/resources/const.ttl: -------------------------------------------------------------------------------- 1 | @prefix domain: . 2 | 3 | domain:p1 rdf:type domain:Pot ; 4 | domain:str "asd" ; 5 | domain:i 1 ; 6 | domain:b "true"^^xsd:boolean ; 7 | domain:d 1.0 . -------------------------------------------------------------------------------- /src/test/resources/conversion.smol: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | class Conv() 5 | Unit success() 6 | Int i = 5; 7 | Double d = 0.2; 8 | Int i2 = doubleToInt(d); 9 | Int i3 = doubleToInt(0.4); 10 | Double d2 = intToDouble(i); 11 | Double d3 = intToDouble(3); 12 | String s1 = intToString(i); 13 | String s2 = intToString(12); 14 | String s3 = doubleToString(d); 15 | String s4 = doubleToString(0.6); 16 | String s5 = intToString(doubleToInt(0.6) + doubleToInt(intToDouble(i))); 17 | print(i); 18 | print(i2); 19 | print(i3); 20 | print(d); 21 | print(d2); 22 | print(d3); 23 | print(s1); 24 | print(s2); 25 | print(s3); 26 | print(s4); 27 | print(s5); 28 | end 29 | Unit fail() 30 | Int i = 5; 31 | Double d = 0.2; 32 | Int i2 = doubleToInt(i); 33 | String s2 = doubleToString(12); 34 | Int s3 = doubleToString(d); 35 | String s4 = doubleToString(0.6); 36 | String s5 = intToString(doubleToInt(0.6) + intToDouble(doubleToInt(i))); 37 | end 38 | end 39 | main skip; end -------------------------------------------------------------------------------- /src/test/resources/destroy.smol: -------------------------------------------------------------------------------- 1 | 2 | class A(Int i1) end 3 | 4 | main 5 | 6 | A a = new A(1); 7 | List list = access("SELECT ?obj WHERE {?obj a prog:A}"); 8 | print(list); 9 | print(list.content); 10 | destroy(a); 11 | print(list.content); 12 | List list2 = access("SELECT ?obj WHERE {?obj a prog:A}"); 13 | breakpoint; 14 | print(list); 15 | end 16 | -------------------------------------------------------------------------------- /src/test/resources/docker_fuseki_config.ttl: -------------------------------------------------------------------------------- 1 | PREFIX fuseki: 2 | PREFIX rdf: 3 | PREFIX rdfs: 4 | PREFIX tdb1: 5 | PREFIX tdb2: 6 | PREFIX ja: 7 | PREFIX : <#> 8 | 9 | <#service1> rdf:type fuseki:Service ; 10 | fuseki:name "ds" ; # http://host:port/ds 11 | fuseki:endpoint [ 12 | # SPARQL query service 13 | fuseki:operation fuseki:query ; 14 | fuseki:name "sparql" 15 | ] ; 16 | fuseki:endpoint [ 17 | # SPARQL query service (alt name) 18 | fuseki:operation fuseki:query ; 19 | fuseki:name "query" 20 | ] ; 21 | 22 | fuseki:endpoint [ 23 | # SPARQL update service 24 | fuseki:operation fuseki:update ; 25 | fuseki:name "update" 26 | ] ; 27 | 28 | fuseki:endpoint [ 29 | # HTML file upload service 30 | fuseki:operation fuseki:update ; 31 | fuseki:name "update" 32 | ] ; 33 | 34 | fuseki:endpoint [ 35 | # SPARQL Graph Store Protocol (read) 36 | fuseki:operation fuseki:gsp_r ; 37 | fuseki:name "get" 38 | ] ; 39 | fuseki:endpoint [ 40 | # SPARQL Graph Store Protcol (read and write) 41 | fuseki:operation fuseki:gsp_rw ; 42 | fuseki:name "data" 43 | ] ; 44 | 45 | fuseki:dataset <#dataset> ; 46 | . 47 | 48 | <#dataset> rdf:type ja:RDFDataset; 49 | tdb2:location "tree_shapes.ttl" ; 50 | ja:defaultGraph <#inferenceModel> ; 51 | tdb2:unionDefaultGraph true ; 52 | . 53 | 54 | <#inferenceModel> rdf:type ja:InfModel; 55 | ja:reasoner [ ja:reasonerURL ]; 56 | . 57 | 58 | -------------------------------------------------------------------------------- /src/test/resources/double.smol: -------------------------------------------------------------------------------- 1 | class DList (DList next, T content, DList previous) 2 | DList append(DList node) 3 | if this.next == null then 4 | this.next = node; 5 | node.previous = this; 6 | else 7 | this.next.append(node); 8 | end 9 | return this; 10 | end 11 | 12 | DList insert_after(DList node) 13 | node.next = this.next; 14 | node.previous = this; 15 | if this.next != null then 16 | this.next.previous = node; 17 | this.next = node; 18 | else skip; end 19 | return this; 20 | end 21 | 22 | 23 | DList remove() 24 | if this.next != null then 25 | this.next.previous = this.previous; 26 | else skip; end 27 | if this.previous != null then 28 | this.previous.next = this.next; 29 | else skip; end 30 | this.next = null; 31 | this.previous = null; 32 | return this; 33 | end 34 | 35 | 36 | DList remove_unclean() 37 | if this.next != null then 38 | this.next.previous = this.previous; 39 | else skip; end 40 | if this.previous != null then 41 | this.previous.next = this.next; 42 | else skip; end 43 | this.next = null; 44 | return this; 45 | end 46 | end 47 | 48 | 49 | main 50 | DList a = new DList(null, 1, null); 51 | DList b = new DList(null, 2, null); 52 | DList c = new DList(null, 4, null); 53 | DList d = new DList(null, 3, null); 54 | a.append(b); 55 | a.append(c); 56 | b.insert_after(d); 57 | c.remove(); 58 | breakpoint; 59 | print(a.next.next.content); 60 | Boolean val = validate("examples/double.ttl"); 61 | breakpoint; 62 | print(val); 63 | end 64 | -------------------------------------------------------------------------------- /src/test/resources/eval-params.smol: -------------------------------------------------------------------------------- 1 | class A(Int x) 2 | Unit setX(Int newX) 3 | this.x = newX; 4 | end 5 | end 6 | 7 | main 8 | A a = new A(5); 9 | breakpoint; 10 | end -------------------------------------------------------------------------------- /src/test/resources/innerField1.smol: -------------------------------------------------------------------------------- 1 | class C (Int i) 2 | Int j = this.i + 2; 3 | end 4 | 5 | main 6 | C c = new C(5); 7 | Int k = c.j; 8 | breakpoint; 9 | breakpoint; 10 | end -------------------------------------------------------------------------------- /src/test/resources/innerField2.smol: -------------------------------------------------------------------------------- 1 | class C (Int i) 2 | Int j = this.i + 2; 3 | Int k = this.j + 2; 4 | end 5 | 6 | class D (Int i2) 7 | Int j2 = this.i2 + 2; 8 | end 9 | 10 | main 11 | skip; 12 | end -------------------------------------------------------------------------------- /src/test/resources/linear.fmu: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/src/test/resources/linear.fmu -------------------------------------------------------------------------------- /src/test/resources/literalQuery.smol: -------------------------------------------------------------------------------- 1 | main 2 | Int i = 5; 3 | Double d = 0.2; 4 | String s = "str"; 5 | 6 | List l = access("SELECT ?obj { ?obj domain:sthI %1; domain:sthD %2; domain:sthS %3.}",i, d, s); 7 | print(l); 8 | end 9 | -------------------------------------------------------------------------------- /src/test/resources/models.owl: -------------------------------------------------------------------------------- 1 | domain:A rdf:type owl:Class. 2 | domain:B rdf:type owl:Class. -------------------------------------------------------------------------------- /src/test/resources/models.smol: -------------------------------------------------------------------------------- 1 | class C() models "a domain:A."; end 2 | 3 | main 4 | C c = new C() models "a domain:B."; 5 | c = new C(); 6 | c = new C(); 7 | List test1 = member(" some "); 8 | List test2 = member(" some "); 9 | Int l1 = test1.length(); 10 | Int l2 = test2.length(); 11 | breakpoint; 12 | breakpoint; 13 | end 14 | -------------------------------------------------------------------------------- /src/test/resources/overload.smol: -------------------------------------------------------------------------------- 1 | 2 | 3 | class Task(String name) end 4 | 5 | class Server(ExplList taskList) 6 | Task excessive() 7 | Task ret = this.taskList.content; 8 | this.taskList = this.taskList.next; 9 | return ret; 10 | end 11 | Int add(Task task) 12 | this.taskList = new ExplList(task, this.taskList); 13 | return 0; 14 | end 15 | end 16 | class Scheduler(List serverList) 17 | Int reschedule() 18 | List over = access("SELECT ?obj WHERE{?obj a domain:Overloaded }"); 19 | //breakpoint; 20 | List tasks = this.collectExcessiveTasks(over); 21 | //breakpoint; 22 | tasks = this.rescheduleTasks(tasks, over); 23 | //breakpoint; 24 | while tasks != null do 25 | ExplList l = new ExplList(tasks.content, null); 26 | Server n = new Server(l); 27 | this.serverList = new List(n, this.serverList); 28 | tasks = tasks.next; 29 | end 30 | return 0; 31 | end 32 | 33 | List collectExcessiveTasks(List overloaded) 34 | List plats = this.serverList; 35 | List exc = null; 36 | while plats != null do 37 | Boolean b = overloaded.contains(plats.content); 38 | //breakpoint; 39 | if b then 40 | Task localExc = plats.content.excessive(); 41 | exc = new List(localExc, exc); 42 | end 43 | plats = plats.next; 44 | end 45 | return exc; 46 | end 47 | 48 | List rescheduleTasks(List tasks, List overloaded) 49 | List plats = this.serverList; 50 | while plats != null do 51 | Boolean b = overloaded.contains(plats.content); 52 | if b then 53 | skip; 54 | else 55 | plats.content.add(tasks.content); 56 | tasks = tasks.next; 57 | end 58 | plats = plats.next; 59 | if tasks == null then return null; end 60 | end 61 | return tasks; 62 | end 63 | end 64 | 65 | main 66 | Task task1 = new Task("t1"); 67 | Task task2 = new Task("t2"); 68 | Task task3 = new Task("t3"); 69 | Task task4 = new Task("t4"); 70 | Task task5 = new Task("t5"); 71 | Task task6 = new Task("t6"); 72 | 73 | ExplList l1 = new ExplList(task1, null); 74 | ExplList l2 = new ExplList(task2, null); 75 | ExplList l3 = new ExplList(task3, l2); 76 | ExplList l4 = new ExplList(task4, null); 77 | ExplList l5 = new ExplList(task5, l4); 78 | ExplList l6 = new ExplList(task6, l5); 79 | 80 | Server dummy = new Server(null); 81 | Server server1 = new Server(l1); 82 | Server server2 = new Server(l3); 83 | Server server3 = new Server(l6); 84 | List sl1 = new List(server3, null); 85 | List sl2 = new List(server2, sl1); 86 | List sl3 = new List(server1, sl2); 87 | 88 | Scheduler sch = new Scheduler(sl3); 89 | breakpoint; 90 | List pre = access("SELECT ?obj WHERE{?obj a domain:Overloaded }"); 91 | sch.reschedule(); 92 | List post = access("SELECT ?obj WHERE{?obj a domain:Overloaded }"); 93 | breakpoint; 94 | print(sch); 95 | end 96 | -------------------------------------------------------------------------------- /src/test/resources/persons.smol: -------------------------------------------------------------------------------- 1 | class Person (Int personId, String name, Int birthYear, Double height, Boolean ownsCar) 2 | Int getPersonId() 3 | return this.personId; 4 | end 5 | String getName() 6 | return this.name; 7 | end 8 | Int getBirthYear() 9 | return this.birthYear; 10 | end 11 | String toString() 12 | return this.name; 13 | end 14 | end 15 | 16 | class Marriage(Person p1, Person p2) 17 | end 18 | 19 | 20 | main 21 | // The first Person 22 | Person annie = new Person(21392, "Annie", 1952, 1.75, True); 23 | Person bernie = new Person(29391, "Bernie", 1952, 1.83, False); 24 | Marriage m1 = new Marriage(annie, bernie); 25 | 26 | end 27 | -------------------------------------------------------------------------------- /src/test/resources/poly.smol: -------------------------------------------------------------------------------- 1 | class C() 2 | Int m() 3 | return 1; 4 | end 5 | end 6 | 7 | class D extends C () 8 | override Int m() 9 | Int s = super(); 10 | C v = new D(); 11 | return 2 + s ; 12 | end 13 | end 14 | 15 | main 16 | C v = new D(); 17 | Int w = v.m(); 18 | print(w); 19 | end 20 | -------------------------------------------------------------------------------- /src/test/resources/reclassification.smol: -------------------------------------------------------------------------------- 1 | class A() 2 | models "a ast:C"; 3 | Unit printVal() 4 | print("A"); 5 | end 6 | end 7 | 8 | class B extends A() 9 | models "a ast:A"; 10 | classifies "ASK WHERE { 11 | %this domain:models [a ast:B] . 12 | }"; 13 | override Unit printVal() 14 | print("B"); 15 | end 16 | end 17 | 18 | class C extends A() 19 | models "a ast:B"; 20 | classifies " some "; 21 | override Unit printVal() 22 | print("C"); 23 | end 24 | end 25 | 26 | main 27 | A a = new B(); 28 | classify(a); 29 | adapt(a); 30 | breakpoint; 31 | a.printVal(); 32 | end 33 | -------------------------------------------------------------------------------- /src/test/resources/scene.smol: -------------------------------------------------------------------------------- 1 | class Scene(Int scaling) 2 | rule Int getScale() 3 | return this.scaling; 4 | end 5 | end 6 | 7 | class Rectangle(Scene scene, Int w, Int h, String name) 8 | rule Int area() 9 | Int s = this.scene.getScale(); 10 | return s*this.w*this.h; 11 | end 12 | end 13 | 14 | main 15 | Scene sc = new Scene(2); 16 | Rectangle r = new Rectangle(sc, 5, 1, "rect1"); 17 | end 18 | -------------------------------------------------------------------------------- /src/test/resources/selfadapt/GreenHouse.smol: -------------------------------------------------------------------------------- 1 | abstract class KindModel (String name) 2 | Unit adaptModel() 3 | print("RECONFIG> Reconfiguring the "++ this.name); 4 | this.adaptDefect(); 5 | this.adaptAddition(); 6 | this.adaptRemoval(); 7 | end 8 | 9 | abstract Unit adaptAddition() 10 | abstract Unit adaptRemoval() 11 | abstract Unit adaptDefect() 12 | end 13 | 14 | /* 15 | * This class implements the twinning logic and is responsible to implement decision making 16 | * and the adaptation cycle. The connections between assets remain implicit as they are not used explicitly, 17 | * but twinning is still established w.r.t. having the right assets. 18 | * 19 | * Field this.decisions contains the control decision made by the last cycle. 20 | */ 21 | class AssetModel extends Twin (List decisions, List mods) 22 | 23 | Unit register(KindModel m) 24 | this.mods = new List(m, this.mods); 25 | end 26 | 27 | Unit reconfigure() 28 | print("RECONFIG> Reconfiguring the asset model..."); 29 | 30 | List ms = this.mods; 31 | while ms != null do 32 | ms.content.adaptModel(); 33 | ms = ms.next; 34 | end 35 | 36 | print("RECONFIG> Reconfiguring DONE..."); 37 | end 38 | end 39 | 40 | main 41 | //MBC Start 42 | // to enable MBC, uncomment the following lines and comment out the line marked with NON-MBC 43 | /* 44 | ModelControl dc = new ModelControl(0.0, null); 45 | dc.reconfigureModel(60.0); //this actually instantiated the FMU 46 | */ 47 | //MBC End 48 | AssetModel assetModel = new AssetModel(null, null); 49 | 50 | PotModel m1 = new PotModel("pots"); 51 | PlantModel m2 = new PlantModel("plants"); 52 | PumpModel m3 = new PumpModel("pumps"); 53 | 54 | assetModel.register(m1); 55 | assetModel.register(m2); 56 | assetModel.register(m3); 57 | 58 | //NDVI START 59 | HealthModel m4 = new HealthModel("health states"); 60 | assetModel.register(m4); 61 | //NDVI STOP 62 | 63 | 64 | assetModel.reconfigure(); 65 | List ll1 = access("SELECT ?x {?x a prog:HealthState}"); 66 | List ll2 = access("SELECT ?x {?x a prog:Pot}"); 67 | List ll3 = access("SELECT ?x {?x a prog:Plant}"); 68 | List ll4 = access("SELECT ?x {?x a prog:Pump}"); 69 | Int l1 = ll1.length(); 70 | Int l2 = ll2.length(); 71 | Int l3 = ll3.length(); 72 | Int l4 = ll4.length(); 73 | breakpoint; 74 | breakpoint; 75 | end 76 | -------------------------------------------------------------------------------- /src/test/resources/selfadapt/Greenhouse_data.smol: -------------------------------------------------------------------------------- 1 | abstract class Twin() end 2 | 3 | /** 4 | * Models a physical plant. It is initially retrieved by 5 | * the asset model, but it can be reconfigured by the program model. 6 | * Each plant is associated with a pot. 7 | */ 8 | class Plant extends Twin (String plantId, Double idealMoisture, String healthState) 9 | 10 | Double getPotMoisture() 11 | Double moisture = 100.0; 12 | List influxReturn = access( 13 | "from(bucket: \"GreenHouseDemo\") 14 | |> range(start: -30d) 15 | |> filter(fn: (r) => r[\"_measurement\"] == \"ast:pot\") 16 | |> filter(fn: (r) => r[\"_field\"] == \"moisture\") 17 | |> filter(fn: (r) => r[\"plant_id\"] == %1) 18 | |> keep(columns: [\"_value\"]) 19 | |> last()", 20 | INFLUXDB("config_local.yml"), 21 | this.plantId); 22 | 23 | if influxReturn != null then 24 | moisture = influxReturn.content; 25 | end 26 | 27 | return moisture; 28 | end 29 | 30 | 31 | // NDVI START 32 | Double getNdvi() 33 | Double healthState = 0.0; 34 | List influxReturn = access( 35 | "from(bucket: \"GreenHouseDemo\") 36 | |> range(start: -30d) 37 | |> filter(fn: (r) => r[\"_measurement\"] == \"ast:plant\") 38 | |> filter(fn: (r) => r[\"_field\"] == \"ndvi\") 39 | |> filter(fn: (r) => r[\"plant_id\"] == %1) 40 | |> keep(columns: [\"_value\"]) 41 | |> last()", 42 | INFLUXDB("config_local.yml"), 43 | this.plantId); 44 | 45 | if influxReturn != null then 46 | healthState = influxReturn.content; 47 | end 48 | 49 | return healthState; 50 | end 51 | // NDVI END 52 | end 53 | 54 | 55 | /* Models a physical pot. It is initially retrieved by the asset model. Each pot is associated with a moisture sensor. */ 56 | class Pot extends Twin (String shelfFloor, String potPosition, String pumpId, String plantId) end 57 | 58 | 59 | /** The following classes represent instances of assets that we currently not using directly but that are twinned for possible extensions */ 60 | /* Models a physical shelf. It is initially retrieved by the asset model. */ 61 | class Shelf extends Twin (String shelfFloor) end 62 | 63 | /* Models a physical pump. It is initially retrieved by the asset model. */ 64 | class Pump extends Twin (Int pumpGpioPin, String pumpId) end 65 | 66 | 67 | // NDVI START 68 | /* Models the health state of a plant via NDVI */ 69 | class HealthState extends Twin (String name, Double minNdvi, Double maxNdvi) end 70 | // NDVI END 71 | 72 | /* The following classes are used to store results of CONSTRUCT queries */ 73 | class PumpDefect (Pump obj, Int pumpGpioPinNew) end 74 | class PlantDefect (Plant obj, Double idealMoistureNew) end 75 | class PotDefectShelf (Pot obj, String shelfFloorNew) end 76 | class PotDefectPosition (Pot obj, String potPositionNew) end 77 | class PotDefectPump (Pot obj, String pumpIdNew) end 78 | class PotDefectPlant (Pot obj, String plantIdNew) end 79 | 80 | /* 81 | * The follow class is used to store results that are read from the simulation driver. 82 | * Every instance is representing on decision to water a specific plant and pump. 83 | */ 84 | class Decision (String plantId, Int pumpGpioPin, String pumpId) end -------------------------------------------------------------------------------- /src/test/resources/selfadapt/Greenhouse_health.smol: -------------------------------------------------------------------------------- 1 | //NDVI START 2 | class HealthModel extends KindModel() 3 | override Unit adaptAddition() 4 | List newHealthStates = construct(" 5 | PREFIX ast: 6 | SELECT ?name ?maxNdvi ?minNdvi { 7 | ?healthState a ast:HealthState ; 8 | ast:name ?name ; 9 | ast:maxNdvi ?maxNdvi ; 10 | ast:minNdvi ?minNdvi . 11 | FILTER NOT EXISTS { 12 | ?y a prog:HealthState; prog:HealthState_name ?name. 13 | } 14 | }"); 15 | 16 | if newHealthStates != null then 17 | print("RECONFIG> New Health State(s) detected: repairing the model"); 18 | 19 | while newHealthStates != null do 20 | HealthState newHealthState = newHealthStates.content; 21 | List lx = newHealthStates; 22 | newHealthStates = newHealthStates.next; 23 | destroy(lx); 24 | 25 | print("RECONFIG> New Health State detected: "); 26 | print(" Name: " ++ newHealthState.name); 27 | print(" Max Ndvi: " ++ doubleToString(newHealthState.maxNdvi)); 28 | print(" Min Ndvi: " ++ doubleToString(newHealthState.minNdvi)); 29 | 30 | end 31 | 32 | print("RECONFIG> Health State(s) added"); 33 | else print("RECONFIG> No Health State(s) added"); end 34 | end 35 | 36 | 37 | override Unit adaptRemoval() 38 | List wrongHealthStates = access(" 39 | PREFIX ast: 40 | SELECT DISTINCT ?obj { 41 | ?obj a prog:HealthState; prog:HealthState_name ?name. 42 | FILTER NOT EXISTS { 43 | ?y a ast:HealthState; ast:name ?name. 44 | } 45 | }"); 46 | 47 | if wrongHealthStates != null then 48 | print("RECONFIG> Misconfigured Health State(s) detected: repairing the model"); 49 | 50 | while wrongHealthStates != null do 51 | HealthState wrongHealthState = wrongHealthStates.content; 52 | List lx = wrongHealthStates; 53 | wrongHealthStates = wrongHealthStates.next; 54 | destroy(lx); 55 | 56 | print("RECONFIG> Misconfigured plant to remove: "); 57 | print(" Name: " ++ wrongHealthState.name); 58 | print(" Max Ndvi: " ++ doubleToString(wrongHealthState.maxNdvi)); 59 | print(" Min Ndvi: " ++ doubleToString(wrongHealthState.minNdvi)); 60 | 61 | destroy(wrongHealthState); 62 | end 63 | end 64 | end 65 | 66 | 67 | override Unit adaptDefect() skip; end 68 | end 69 | //NDVI STOP -------------------------------------------------------------------------------- /src/test/resources/strings.smol: -------------------------------------------------------------------------------- 1 | class C() 2 | Boolean success() 3 | String s = "foo"; 4 | String v = "bar"; 5 | String x1 = s ++ v; 6 | String x2 = s ++ "bar"; 7 | String x3 = "foo" ++ "bar"; 8 | String x4 = "foo" ++ v; 9 | return x1 == x2 & x2 == x3 & x3 == x4; 10 | end 11 | Unit fail1() 12 | String s = "foo"; 13 | Int v = 1; 14 | String x1 = s ++ v; 15 | end 16 | Unit fail2() 17 | String s = "foo"; 18 | String x1 = s ++ 1; 19 | end 20 | Unit fail3() 21 | String s = "foo"; 22 | String x1 = 1 ++ s; 23 | end 24 | Unit fail4() 25 | String x1 = 1 ++ "foo"; 26 | end 27 | end 28 | 29 | 30 | main 31 | C c = new C(); 32 | Boolean res = c.success(); 33 | breakpoint; 34 | breakpoint; 35 | end -------------------------------------------------------------------------------- /src/test/resources/test_assign.smol: -------------------------------------------------------------------------------- 1 | class C(Int i) end 2 | class D extends C (Object o) end 3 | class Wrapper(U content) end 4 | 5 | class Test() 6 | Int assignSuccess1() 7 | C c = new D(1, null); 8 | C c2 = new D(1, c); 9 | C c3 = new D(1, 1); 10 | return 0; 11 | end 12 | 13 | Int opsuccess() 14 | Boolean b1 = True; 15 | Boolean b2 = False; 16 | Double d1 = 1.0; 17 | Double d2 = 2.0; 18 | if(!(d1 != d2) & b2) then d2 = d1/d2; end 19 | if(!(d1 > d2) | b1 | (d1 < d2)) then d2 = d1/d2; end 20 | return 0; 21 | end 22 | 23 | Int opfail() 24 | Boolean b1 = True; 25 | Boolean b2 = False; 26 | Double d1 = 1.0; 27 | Double d2 = 2.0; 28 | Int i1 = 1; 29 | if(!d1) then d2 = d1/d2; end 30 | if(d1 != b1) then d2 = d1/d2; end 31 | if(b2 < b1) then d2 = i1/d2; end 32 | return 0; 33 | end 34 | 35 | Int assignSuccess2() 36 | C c = new D(1, null); 37 | Wrapper v = new Wrapper(c); 38 | D d = new D(1, null); 39 | Wrapper w = new Wrapper(d); 40 | return 0; 41 | end 42 | 43 | Int fail1() 44 | D d = new C(1); 45 | return 0; 46 | end 47 | 48 | Int fail2() 49 | C c = new C("hi"); 50 | return 0; 51 | end 52 | 53 | Int fail3() 54 | C c = new C(1); 55 | Wrapper w = new Wrapper(c); 56 | return 0; 57 | end 58 | 59 | Boolean fail4() 60 | return 1; 61 | end 62 | 63 | Int fail5() 64 | if( 1 == "hi") then skip; end 65 | return 0; 66 | end 67 | 68 | Int fail6() 69 | while( 1 == "hi") do skip; end 70 | return 0; 71 | end 72 | 73 | Int fail7() 74 | Int i = "hi"; 75 | return 0; 76 | end 77 | end 78 | 79 | 80 | class TestGen (A a, B b, Wrapper wa, Wrapper wb) 81 | Int success() 82 | this.a = this.wa.content; 83 | this.b = this.wb.content; 84 | this.wa = new Wrapper(this.a); 85 | this.wb = new Wrapper(this.b); 86 | return 0; 87 | end 88 | 89 | Int fail1() 90 | this.a = this.wb.content; 91 | return 0; 92 | end 93 | 94 | Int fail2() 95 | this.wb = new Wrapper(this.a); 96 | return 0; 97 | end 98 | 99 | Int fail3() 100 | this.a = this.b; 101 | return 0; 102 | end 103 | 104 | Int fail4() 105 | this.wa = this.b; 106 | return 0; 107 | end 108 | end 109 | 110 | main 111 | skip; 112 | end 113 | -------------------------------------------------------------------------------- /src/test/resources/test_call.smol: -------------------------------------------------------------------------------- 1 | class C(Int i) 2 | Int m1(Int i) return i; end 3 | end 4 | class D extends C (Object o) 5 | Object m2(Int i) return i; end 6 | end 7 | class Wrapper(U content) end 8 | 9 | class Test(C c, D d, Wrapper cw, Wrapper dw) 10 | 11 | Int success() 12 | Int i = this.cw.content.m1(1); 13 | Object o = this.dw.content.m2(1); 14 | o = i; 15 | D d = new D(i, o); 16 | d.m2(i); 17 | return 1; 18 | end 19 | 20 | Int fail1() //no return 21 | skip; 22 | end 23 | 24 | Int fail2() //no return 25 | if( 1 == 2 ) then 26 | skip; 27 | else 28 | return 1; 29 | end 30 | end 31 | 32 | Int fail3() //wrong method 33 | Int i = this.cw.content.m2(1); 34 | return 1; 35 | end 36 | 37 | Int fail4() //method does not exist 38 | Int i = this.cw.content.m3(1); 39 | return 1; 40 | end 41 | 42 | Int fail5() //wrong parameter 43 | Int i = this.cw.content.m1(this.d); 44 | return 1; 45 | end 46 | 47 | Int fail6() //wrong number of parameters 48 | Int i = this.cw.content.m1(1,1); 49 | return 1; 50 | end 51 | 52 | Int fail7() //wrong return type 53 | D i = this.cw.content.m1(1); 54 | return 1; 55 | end 56 | end 57 | 58 | main skip; end 59 | -------------------------------------------------------------------------------- /src/test/resources/test_construct.smol: -------------------------------------------------------------------------------- 1 | class C(Int i) end 2 | class R(C c, Int j) end 3 | 4 | main 5 | C c = new C(5); 6 | List res = construct("SELECT ?c ?j {?c a prog:C. ?c prog:C_i ?j}"); 7 | Boolean found = res != null; 8 | breakpoint; 9 | breakpoint; 10 | end -------------------------------------------------------------------------------- /src/test/resources/test_generic.smol: -------------------------------------------------------------------------------- 1 | class C () end 2 | class D extends C() end 3 | class E extends C() end 4 | class F extends C() end 5 | class G extends C() end 6 | class H() end 7 | class I(Q i) end 8 | class J() Int m() return Y.i; end end 9 | 10 | abstract class A() 11 | abstract Int m() 12 | end 13 | class B extends A() end 14 | 15 | main skip; end -------------------------------------------------------------------------------- /src/test/resources/test_override.smol: -------------------------------------------------------------------------------- 1 | class C() end 2 | class D extends C() end 3 | 4 | class E() 5 | C m(C c) return null; end 6 | end 7 | 8 | class Success1 extends E () 9 | override C m(C c) return c; end 10 | end 11 | class Success2 extends E () 12 | override C m(C c) C ret = super(c); return ret; end 13 | end 14 | class Fail1 extends E () //lacks modifier 15 | C m(C c) C ret = super(c); return ret; end 16 | end 17 | class Fail2 extends E () //changes signature 18 | override C m(E c) C ret = super(c); return ret; end 19 | end 20 | class Fail3 extends E () //changes signature 21 | override C m(C d) C ret = super(d); return ret; end 22 | end 23 | class Fail4 extends E () //changes signature 24 | override C m(C c, D d) C ret = super(c); return ret; end 25 | end 26 | class Fail5 extends E () //wrong modifier 27 | override C n(C c) C ret = super(c); return ret; end 28 | end 29 | class Fail6 extends E () //ill-typed super call 30 | override C m(C c) C ret = super(1); return ret; end 31 | end 32 | class Fail7 extends E () //ill-typed super call 33 | override C m(C c) C ret = super(null, null); return ret; end 34 | end 35 | 36 | main 37 | skip; 38 | end 39 | -------------------------------------------------------------------------------- /src/test/resources/tree_shapes.ttl: -------------------------------------------------------------------------------- 1 | @prefix schema: . 2 | @prefix sh: . 3 | 4 | schema:TestShape 5 | a sh:NodeShape ; 6 | sh:targetClass schema:Object ; 7 | sh:property [ 8 | sh:path schema:instanceOf ; 9 | sh:class schema:Class ; 10 | sh:name "Every smol-object states its smol-class" ; 11 | ]. 12 | -------------------------------------------------------------------------------- /src/test/resources/type_query.smol: -------------------------------------------------------------------------------- 1 | class A (Int sealing) end 2 | 3 | class B extends A (A aB) end 4 | 5 | class C extends A(A aCB, A aC) end 6 | 7 | class D() end 8 | 9 | class E extends C () end 10 | 11 | class Test() 12 | 13 | Int mSuccess1() 14 | List l = access("SELECT ?obj WHERE {?obj prog:C_aCB ?b. ?b prog:B_aB ?a. ?a prog:A_sealing 1 }"); 15 | return 1; 16 | end 17 | 18 | Int mSuccess2() 19 | List l = access("SELECT ?obj WHERE {?obj prog:C_aCB ?b. ?b prog:B_aB ?a. ?a prog:A_sealing 1 }"); 20 | return 1; 21 | end 22 | 23 | Int mSuccess3() 24 | List l = access("SELECT ?obj WHERE {?obj prog:C_aCB ?b. ?b prog:B_aB ?a. ?a prog:A_sealing 1 }"); 25 | return 1; 26 | end 27 | 28 | Int mSuccess4() 29 | List l = access("SELECT ?obj WHERE {?obj prog:C_aCB [ prog:B_aB [ prog:A_sealing 1 ]]}"); 30 | return 1; 31 | end 32 | 33 | Int mSuccess5() 34 | List l = access("SELECT ?obj WHERE {?obj prog:C_aCB [ prog:B_aB [ prog:A_sealing %1 ]]}", 1); 35 | return 1; 36 | end 37 | 38 | Int mFail1() 39 | List l = access("SELECT ?obj WHERE {?obj prog:C_aCB ?b. ?b prog:B_aB ?a. ?a prog:A_sealing 1 }"); 40 | return 1; 41 | end 42 | 43 | Int mFail2() 44 | List ld = access("SELECT ?obj WHERE {?obj prog:C_aCB ?b. ?b prog:B_aB ?a. ?a prog:A_sealing 1 }"); 45 | return 1; 46 | end 47 | Int mFail3() 48 | List> ld = access("SELECT ?obj WHERE {?obj prog:List_head %1}", 42); 49 | return 1; 50 | end 51 | end 52 | 53 | class F(Int i) 54 | rule Int getI() return this.i; end 55 | Int nonRule() return this.i; end 56 | rule Int errorGet() Int v = this.nonRule(); return v; end 57 | end 58 | 59 | main 60 | skip; 61 | end 62 | -------------------------------------------------------------------------------- /src/test/resources/types.smol: -------------------------------------------------------------------------------- 1 | class C(Int i, Wrapper list) 2 | Int getI() return this.i; end 3 | T id(T t) return t; end 4 | S idTwo(S s) return s; end 5 | Int sum(Int i1, Int i2) 6 | Int get = this.list.content; 7 | Int another = this.sum(get, i2); 8 | this.i = this.i; 9 | return i1+another; 10 | end 11 | end 12 | 13 | class Wrapper(U content) 14 | 15 | end 16 | 17 | main 18 | skip; 19 | end 20 | -------------------------------------------------------------------------------- /website/.envrc: -------------------------------------------------------------------------------- 1 | layout pipenv 2 | -------------------------------------------------------------------------------- /website/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /website/Pipfile: -------------------------------------------------------------------------------- 1 | [[source]] 2 | url = "https://pypi.org/simple" 3 | verify_ssl = true 4 | name = "pypi" 5 | 6 | [packages] 7 | sphinx = "*" 8 | piccolo-theme = "*" 9 | sphinxcontrib-mermaid = "*" 10 | 11 | [dev-packages] 12 | 13 | [requires] 14 | python_version = "3.10" 15 | -------------------------------------------------------------------------------- /website/README.md: -------------------------------------------------------------------------------- 1 | # Building the HTML files 2 | 3 | 1. (One time) install dependencies 4 | - Check that Python 3 is installed 5 | - Install `pipenv` (see https://pipenv.pypa.io/en/latest/) 6 | - Run `pipenv install` (this install sphinx and the piccolo theme) in this 7 | directory (`website/`) 8 | 2. Run `pipenv shell` 9 | 3. Run `make html` in this directory (`website/`) 10 | 11 | # Deploying to `smolang.org` 12 | 13 | 1. Build the website 14 | 2. Check out https://github.com/smolang/smolang.github.io.git 15 | 3. Copy the contents of `build/html/` to the root of the directory created in 16 | Step 2 17 | 4. Commit the changes in the checkout of `smolang.github.io` created in Step 18 | 2; take care to also `git add` all newly-created files and `git rm` all 19 | vanished files.. 20 | 21 | # Headline Structure 22 | 23 | Use the following punctuation characters in the section titles: 24 | 25 | - `#` for Parts 26 | - `*` for Chapters 27 | - `=` for sections (“Heading 1”) 28 | - `-` for subsections (“Heading 2”) 29 | - `^` for subsubsections (“Heading 3”) 30 | - `"` for paragraphs (“Heading 4”) 31 | 32 | # Static files 33 | 34 | Static files, such as pdfs of presentations, are placed below `source/files/`, 35 | and linked with a sphinx `:download:` link, for example: 36 | 37 | :download:`Slides for day one ` 38 | 39 | # Basic rst info 40 | 41 | https://chiplicity.readthedocs.io/en/latest/Using_Sphinx/OnReStructuredText.html 42 | 43 | # Theme documentation 44 | 45 | https://piccolo-theme.readthedocs.io/en/latest/ 46 | 47 | # Automatically rebuild with entr 48 | 49 | [eradman/entr: Run arbitrary commands when files change](https://github.com/eradman/entr) 50 | 51 | find source -name '*.rst' | entr -d make html 52 | 53 | # Citations 54 | 55 | https://chiplicity.readthedocs.io/en/latest/Using_Sphinx/UsingBibTeXCitationsInSphinx.html 56 | 57 | # Railroad diagrams from EBNF 58 | 59 | (EBNF spec is linked inside the documentation) 60 | 61 | Use GrammKit: https://github.com/dundalek/GrammKit 62 | 63 | npm install -g grammkit 64 | grammkit -t md smol.ebnf # generates separate SVG files 65 | 66 | Online playground at https://github.com/dundalek/GrammKit 67 | 68 | ## Other railroad diagram generators 69 | 70 | https://bottlecaps.de/rr/ui 71 | 72 | https://github.com/tabatkins/railroad-diagrams 73 | 74 | https://github.com/katef/kgt 75 | 76 | # Embed svg pictures 77 | 78 | https://stackoverflow.com/questions/34777943/insert-clickable-svg-image-into-sphinx-documentation 79 | 80 | `.. image:: myfile.svg` 81 | -------------------------------------------------------------------------------- /website/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.https://www.sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /website/smol.ebnf: -------------------------------------------------------------------------------- 1 | Program ::= ClassDef* 'main' Statement* 'end' 2 | 3 | ClassDef ::= 'abstract'? 'class' Id ( '<' '>')? 4 | 5 | Id ::= [a-zA-Z_] [a-zA-Z_0-9]* 6 | -------------------------------------------------------------------------------- /website/source/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | # 13 | # import os 14 | # import sys 15 | # sys.path.insert(0, os.path.abspath('.')) 16 | 17 | 18 | # -- Project information ----------------------------------------------------- 19 | 20 | project = 'The SMOL Language' 21 | html_short_title = "SMOL" 22 | copyright = '2022-2024, Eduard Kamburjan, Rudolf Schlatte' 23 | author = 'Eduard Kamburjan, Rudolf Schlatte' 24 | 25 | 26 | # -- General configuration --------------------------------------------------- 27 | 28 | # Add any Sphinx extension module names here, as strings. They can be 29 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 30 | # ones. 31 | extensions = [ 'sphinx.ext.mathjax', 32 | 'sphinxcontrib.mermaid' ] 33 | 34 | # Add any paths that contain templates here, relative to this directory. 35 | templates_path = ['_templates'] 36 | 37 | # List of patterns, relative to source directory, that match files and 38 | # directories to ignore when looking for source files. 39 | # This pattern also affects html_static_path and html_extra_path. 40 | exclude_patterns = [] 41 | 42 | 43 | # -- Options for HTML output ------------------------------------------------- 44 | 45 | # The theme to use for HTML and HTML Help pages. See the documentation for 46 | # a list of builtin themes. 47 | # 48 | html_theme = 'piccolo_theme' 49 | 50 | html_theme_options = { 51 | "source_url": 'https://github.com/smolang/SemanticObjects/' 52 | } 53 | 54 | 55 | # Add any paths that contain custom static files (such as style sheets) here, 56 | # relative to this directory. They are copied after the builtin static files, 57 | # so a file named "default.css" will overwrite the builtin "default.css". 58 | html_static_path = ['_static'] 59 | -------------------------------------------------------------------------------- /website/source/files/tutorial_ictac2022/demo_day1.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/website/source/files/tutorial_ictac2022/demo_day1.pdf -------------------------------------------------------------------------------- /website/source/files/tutorial_ictac2022/demo_day2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/website/source/files/tutorial_ictac2022/demo_day2.pdf -------------------------------------------------------------------------------- /website/source/glossary.rst: -------------------------------------------------------------------------------- 1 | Glossary 2 | ======== 3 | 4 | .. glossary:: 5 | :sorted: 6 | 7 | EBNF 8 | Extended Backus-Naur Form, a notation for formally specifying syntax. We use the definition found at https://www.w3.org/TR/2006/REC-xml11-20060816/#sec-notation. 9 | 10 | FMU 11 | Functional Mock-up Unit, a simulation model following the `FMI standard `_ for multi-model simulation. 12 | 13 | FMO 14 | Functional Mock-up Object, a SMOL object encapsulating an instance of an FMU. 15 | 16 | RDF 17 | Resource Description Framework, a standard model for data interchange on the web. See https://www.w3.org/RDF/. 18 | 19 | REPL 20 | Read-Eval-Print Loop, a way to interact with a running system via 21 | entering commands on a keyboard. 22 | 23 | SPARQL 24 | A query language for RDF data. See https://www.w3.org/TR/sparql11-query/. 25 | -------------------------------------------------------------------------------- /website/source/images/SMOL_Circular_Small.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/website/source/images/SMOL_Circular_Small.png -------------------------------------------------------------------------------- /website/source/images/SMOL_Logo_transparent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/website/source/images/SMOL_Logo_transparent.png -------------------------------------------------------------------------------- /website/source/images/alone.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/website/source/images/alone.pdf -------------------------------------------------------------------------------- /website/source/images/alone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/smolang/SemanticObjects/9b684fedbb58dbd4b46e74589ca4a79bede06eb9/website/source/images/alone.png -------------------------------------------------------------------------------- /website/source/images/drawio/conceptual-layers.drawio: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /website/source/index.rst: -------------------------------------------------------------------------------- 1 | .. SMOL documentation master file, created by 2 | sphinx-quickstart on Wed Mar 2 16:05:25 2022. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | Semantic Micro Object Language 6 | ============================== 7 | 8 | .. figure:: /images/SMOL_Logo_transparent.png 9 | 10 | SMOL is an imperative, object-oriented research language. SMOL integrates 11 | semantic web technologies and numerical simulation blocks, and can serve as a 12 | test bed for creating digital twins. See :ref:`introduction` for more details. 13 | 14 | SMOL and its website are under active development. 15 | 16 | SMOL is released under the terms of the 3-clause BSD license, the source is 17 | available at https://github.com/smolang/SemanticObjects. 18 | 19 | .. toctree:: 20 | :hidden: 21 | 22 | Introduction 23 | Getting Started 24 | Language Manual 25 | Tutorial 26 | Internals 27 | Publications 28 | Digital Twin Lab 29 | 30 | .. 31 | Indices and tables 32 | ****************** 33 | 34 | * :ref:`genindex` 35 | * :ref:`modindex` 36 | * :ref:`search` 37 | -------------------------------------------------------------------------------- /website/source/internals.rst: -------------------------------------------------------------------------------- 1 | Internals 2 | ========= 3 | 4 | This page contains a sketch of the SMOL implementation internals. 5 | 6 | Parsing and Typechecking Program Flow 7 | ------------------------------------- 8 | 9 | - SMOL input files are parsed via antlr; the antlr grammar can be found in `src/main/antlr/While.g4 `_. 10 | 11 | - Parsing, typechecking and preparation to run a SMOL program are done by the method `REPL.initInterpreter `_, which calls methods according to Figure :ref:`Parsing Flow `. 12 | 13 | 14 | .. _parsing-flow-ref: 15 | 16 | .. mermaid:: 17 | :caption: The program flow of smol program text inside ``REPL.initInterpreter`` 18 | 19 | flowchart TB 20 | input([ `-i` argument or REPL `read` command]) 21 | antlr[[WhileParser.program]] 22 | translate[[Translate.generateStatic]] 23 | typecheck[TypeChecker] 24 | interpret[Interpreter] 25 | 26 | click antlr "https://github.com/smolang/SemanticObjects/blob/master/src/main/antlr/While.g4" _blank 27 | click translate "https://github.com/smolang/SemanticObjects/blob/master/src/main/kotlin/no/uio/microobject/ast/Translate.kt" _blank 28 | click interpret "https://github.com/smolang/SemanticObjects/blob/master/src/main/kotlin/no/uio/microobject/runtime/Interpreter.kt" _blank 29 | click typecheck "https://github.com/smolang/SemanticObjects/blob/master/src/main/kotlin/no/uio/microobject/type/TypeChecker.kt" _blank 30 | 31 | input-- smol filename -->antlr 32 | 33 | subgraph REPL.initInterpreter 34 | direction TB 35 | antlr -- antlr tree -->translate 36 | antlr -- antlr tree -->typecheck 37 | translate -- StaticTable -->interpret 38 | translate -- StaticTable -->typecheck 39 | end 40 | 41 | 42 | Statement Execution 43 | ------------------- 44 | 45 | Executing a smol program is controlled by the `REPL `_ class. An ``Interpreter`` object keeps track of the execution state, which consists of a stack of `StackEntry `_ objects and a `GlobalMemory `_ instance, which in turn maps object names to their `Memory `_. 46 | 47 | A single statement is executed by the method `Interpreter.makeStep `_. 48 | -------------------------------------------------------------------------------- /website/source/introduction.rst: -------------------------------------------------------------------------------- 1 | .. _introduction: 2 | 3 | Introduction 4 | ============ 5 | 6 | Our Vision 7 | ---------- 8 | 9 | The SMOL language can be used as a framework for developing digital twins. For 10 | digital twins, the knowledge graphs can be used to capture asset models. SMOL 11 | programs can then *seamlessly interact with asset models and domain knowledge* 12 | to configure and adapt, e.g., simulators. SMOL uses Functional Mock-Up Objects 13 | (FMOs) as a programming layer to encapsulate simulators compliant with the FMI 14 | standard into OO structures and integrates FMOs into the class and type 15 | systems. By means of the semantic lifting, the FMOs can be integrated into 16 | knowledge graphs and used to ensure structural correctness properties for 17 | cyber-physical applications. 18 | 19 | SMOL features 20 | ------------- 21 | 22 | * Imperative, object-oriented language 23 | * Seamless integration of programs and knowledge bases 24 | * Built-in reflection of program state in the knowledge base 25 | * Knowledge bases can be queried from SMOL programs 26 | * Encapsulation of simulators in objects based on the FMI standard 27 | 28 | **Open source**. SMOL is released under the terms of the 3-clause BSD licence, 29 | the source is available at https://github.com/smolang/SemanticObjects. 30 | 31 | Digital Twins and SMOL 32 | ---------------------- 33 | 34 | Digital Twins and similar applications typically connect simulators with 35 | data-rich components and domain knowledge, both commonly formalised as 36 | knowledge graphs. Engineering such applications poses challenges to 37 | developers, which we address using a language-based approach to enable their 38 | efficient development, as well as explore analysis and design: **SMOL** is an 39 | imperative, object-oriented research language which integrates semantic web 40 | technologies and numerical simulation blocks, and can serve as a test bed for 41 | creating digital twins. 42 | 43 | 44 | Semantic Web Technologies and SMOL 45 | ---------------------------------- 46 | 47 | SMOL supports *semantic lifting* of program state: objects and their fields 48 | are represented as :term:`RDF` triples and can be processed via standard semantic web 49 | technologies like :term:`SPARQL`. An external ontology can be used to give additional 50 | semantics to the lifted program state. Section :ref:`semantic-access` describes this in detail. 51 | 52 | SMOL proposes a *language-based integration of knowledge graphs and 53 | object-oriented programs*. SMOL programs can contain queries to external 54 | knowledge graphs that contain, e.g., domain knowledge about an application 55 | domain. SMOL further proposes *semantic reflection* of programs into knowledge 56 | graphs by lifting the runtime state of the program into an associated 57 | knowledge graph, which enables programs to directly query this semantic 58 | representation of itself at runtime. This way, programs can make use of domain 59 | knowledge in the knowledge graph. Semantic reflection in SMOL can be used in 60 | interesting ways by giving the program access to formalised domain knowledge 61 | about its own runtime state, for example for debugging but also for system 62 | reconfiguration. 63 | 64 | Co-Simulation and SMOL 65 | ---------------------- 66 | 67 | Dynamic simulation model components (:term:`FMU`\ s) that follow the `FMI 68 | standard `_ can be directly integrated into SMOL 69 | code. A SMOL program can drive the dynamic model inputs and controls the 70 | advancement of time for all FMUs, and can access the dynamic model outputs, 71 | making them available for semantic lifting. This is discussed further in 72 | Section :ref:`fmos`. 73 | -------------------------------------------------------------------------------- /website/source/lab.rst: -------------------------------------------------------------------------------- 1 | Digital Twin Lab 2 | ================ 3 | 4 | The SMOL team is managing the Digital Twin lab at the University of Oslo (Lab Room 8270, OJD), a laboratory for exploring software for Digital Twins directly on physical setups, financed by the Institute of Informatics. 5 | 6 | The laboratory is currently containing one greenhouse, which contains several basilikum plants, which are pair-wise connected to water pumps. 7 | A SMOL controller software, connected to the sensors of the plants through InfluxDB, and using an asset model as the underlying knowledge graph is used to ensure 8 | correct watering of the plants. An article describing the greenhouse is accepted for publication at `SEAMS 2024 `_. 9 | 10 | You can find a detailed description `here `_ . 11 | The used VM for the greenhouse can be downloaded `here `_, the used images for the Raspberry Pi's `here (collector) `_ and here `here (actuator) `_. 12 | 13 | This page will be and extended updated as the laboratory grows: 14 | We are currently extending the laboratory with a `mirte robot `_, a fermentation station and an `incubator `_ 15 | 16 | 17 | For questions, contact the lab managing team 18 | * Eduard Kamburjan 19 | * Chinmayi Baramashetru -------------------------------------------------------------------------------- /website/source/language.rst: -------------------------------------------------------------------------------- 1 | .. SMOL documentation master file, created by 2 | sphinx-quickstart on Wed Mar 2 16:05:25 2022. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | The SMOL Language Manual 7 | ======================== 8 | 9 | SMOL is an imperative, object-oriented research language. SMOL integrates 10 | semantic web technologies and numerical simulation blocks, and can serve as a 11 | test bed for creating digital twins. 12 | 13 | SMOL is released under the terms of the 3-clause BSD license, the source is 14 | available at https://github.com/smolang/SemanticObjects. 15 | 16 | .. toctree:: 17 | :maxdepth: 2 18 | :caption: Contents: 19 | 20 | language/lexical-structure 21 | language/datatypes 22 | language/expressions 23 | language/statements 24 | language/classes 25 | language/semantic-access 26 | language/fmos 27 | glossary 28 | -------------------------------------------------------------------------------- /website/source/language/classes.rst: -------------------------------------------------------------------------------- 1 | Classes 2 | ======= 3 | 4 | .. highlight:: BNF 5 | 6 | All code to be executed in SMOL, with the exception of the main block, is 7 | contained in classes. Classes define fields and methods. Classes are 8 | instantiated in objects via the ``new`` expression, all objects of a class 9 | share the same methods and fields. Each object's fields hold different state 10 | that can change over time. 11 | 12 | .. _class_declaration_ref: 13 | 14 | Class Declarations 15 | ------------------ 16 | A class can have generic type parameters, field declarations, methods and a modelling bridge. 17 | Additionally a class may be abstract and contain abstract methods. An abstract class may containt non-abstract methods. 18 | :: 19 | 20 | ClassDeclaration ::= 'abstract'? 21 | 'class' Identifier ( '<' Identifier (',' Identifier)* '>')? 22 | ('extends' Type )? 23 | '(' (FieldDeclaration (',' FieldDeclaration)* )? ')' 24 | ModelsDeclaration? 25 | MethodDefinition* 26 | 'end' 27 | 28 | A field is declared using a type and a name. 29 | The ``hidden`` modifier disables semantic lifting for this field. 30 | The ``domain`` modifier moves the generated triples to the modelled node. 31 | A field cannot be ``domain`` and ``hidden``. 32 | 33 | :: 34 | 35 | FieldDeclaration ::= 'hidden'? 'domain'? 36 | Type Identifier 37 | 38 | 39 | 40 | *models* 41 | 42 | The ``models`` declarations are used to connect object structure to semantic 43 | reflection; see Section :ref:`modeling-bridge`. 44 | 45 | :: 46 | 47 | ModelsDeclaration ::= ('models' '(' Expression ')' StringLiteral ';')* 48 | 'models' StringLiteral ';' 49 | 50 | *classifies* 51 | 52 | The ``classifies`` declarations are used to handle the classification and 53 | reclassification process of objects; see Section :ref:`classification`. 54 | 55 | :: 56 | 57 | ClassifiesDeclaration ::= 'classifies' StringLiteral ';' 58 | 59 | *retrieves* 60 | 61 | The ``classiretrievesfies`` declarations are used to handle the retrieval of 62 | values of reclassified classes; see Section :ref:`classification`. 63 | 64 | :: 65 | 66 | RetrievesDeclaration ::= 'retrieves' StringLiteral ';' 67 | 68 | *methods* 69 | 70 | A ``rule`` method cannot have side-effects (no object creation, no writing field access), no parameters and can only call other ``rule`` methods. 71 | 72 | :: 73 | 74 | MethodDefinition ::= ConcreteMethod | AbstractMethod 75 | 76 | ConcreteMethod ::= 'rule'? 'domain'? 'override'? 77 | Type Identifier '(' (Type Identifier (',' Type Identifier)* )? ')' 78 | Statement* 79 | 'end' 80 | 81 | AbstractMethod ::= 'abstract' 'rule'? 'domain'? 'override'? 82 | Type Identifier '(' (Type Identifier (',' Type Identifier)* )? ')' 83 | -------------------------------------------------------------------------------- /website/source/language/datatypes.rst: -------------------------------------------------------------------------------- 1 | Datatypes 2 | ========= 3 | 4 | .. highlight:: Java 5 | 6 | This chapter describes the datatypes of SMOL. 7 | 8 | Booleans 9 | -------- 10 | 11 | The name for the Boolean (true or false) datatype is ``Boolean``. 12 | 13 | :: 14 | 15 | Boolean falsity = True; 16 | 17 | Integers 18 | -------- 19 | 20 | The name for the integer datatype is ``Int``. 21 | 22 | :: 23 | 24 | Int counter = 0; 25 | 26 | Floating Point Numbers 27 | ---------------------- 28 | 29 | The name for the floating-point datatype is ``Double``. 30 | 31 | :: 32 | 33 | Double approximately_pi = 3.1415927; 34 | 35 | Strings 36 | ------- 37 | 38 | The name for the string datatype is ``String``. 39 | 40 | :: 41 | 42 | String language_name = "SMOL"; 43 | 44 | Objects 45 | ------- 46 | 47 | Classes are datatypes, objects of that class have the type defined by the class. 48 | 49 | :: 50 | 51 | class Person (String name, Int age) 52 | end 53 | 54 | main 55 | Person p = new Person("SMOL", 1); 56 | end 57 | 58 | FMUs 59 | ---- 60 | 61 | FMUs, instantiated via the ``simulate`` expression, have a type ``FMO[...]``, 62 | with the square brackets listing the ``modelDescription.xml`` file as 63 | contained in the FMU. 64 | 65 | :: 66 | 67 | FMO[in Int j, out Int i] cont = simulate("path/to/fmu", j=1, k=1); 68 | cont.j = 5; 69 | 70 | 71 | Lists 72 | ----- 73 | 74 | The ``List`` datatype holds a list of values of type ``C``, where ``C`` can 75 | be any SMOL datatype. Currently lists are implemented as objects and are 76 | built incrementally. 77 | 78 | :: 79 | 80 | List l1 = new List(5, null); 81 | List l2 = new List(3, l1); 82 | 83 | .. NOTE:: 84 | Lists are ``hidden`` by default and not lifted. If you need to lift a list, use ``ExplList``. 85 | -------------------------------------------------------------------------------- /website/source/language/lexical-structure.rst: -------------------------------------------------------------------------------- 1 | Lexical Structure 2 | ================= 3 | 4 | .. highlight:: BNF 5 | 6 | This section describes the lexical structure of SMOL. We define the grammar 7 | using a simple :term:`EBNF` notation as defined by `the W3C 8 | `_. 9 | 10 | Line Terminators and Whitespace 11 | ------------------------------- 12 | 13 | :: 14 | 15 | Whitespace ::= #x20 | #x09 | #x0D | #x0A | #x0C 16 | EOL ::= #x0A | #x0C 17 | 18 | The following characters count as whitespace: 19 | 20 | .. list-table:: Whitespace 21 | :header-rows: 1 22 | :align: left 23 | 24 | * - Code 25 | - Name 26 | * - 0x20 27 | - Space 28 | * - 0x09 29 | - Tab 30 | * - 0x0D 31 | - Carriage Return 32 | * - 0x0A 33 | - Line Feed 34 | * - 0x0C 35 | - Form Feed 36 | 37 | Whitespace has no semantic meaning, with the exception of the Line Feed and 38 | Carriage Return characters which terminate a line comment. 39 | 40 | Comments 41 | -------- 42 | 43 | Comments are syntax elements that are ignored during parsing. 44 | 45 | :: 46 | 47 | Comment ::= BlockComment | LineComment 48 | BlockComment ::= '/*' .* '*/' 49 | LineComment ::= '//' .* EOL 50 | 51 | A block comment starts with ``/*`` and extends until the first occurrence of 52 | ``*/``. A line comment starts with ``//`` and extends until the end of the line. 53 | 54 | Identifiers 55 | ----------- 56 | 57 | Identifiers start with a letter or underscore followed by a sequence of 58 | letters, numbers and underscores. A language keyword cannot be used as an 59 | identifier. 60 | 61 | :: 62 | 63 | Identifier ::= [a-zA-Z_] [a-zA-Z0-9_]* 64 | 65 | 66 | Keywords 67 | -------- 68 | 69 | Any word occurring in the grammar (e.g., `class`) is a keyword. Keywords 70 | cannot be used as identifiers. 71 | 72 | TODO: list all language keywords here? 73 | 74 | .. _literals_ref: 75 | 76 | Literals 77 | -------- 78 | 79 | A literal is a textual representation of a value. SMOL supports integer, 80 | Boolean, string and float literals. 81 | 82 | :: 83 | 84 | Literal ::= IntLiteral | FloatLiteral | StringLiteral | BoolLiteral 85 | IntLiteral ::= '0' | '-'? [1-9] [0-9]* 86 | FloatLiteral ::= IntLiteral? '.' [0-9]* ([eE]IntLiteral)? 87 | StringLiteral ::= '"' ('\"' | .)* '"' 88 | 89 | String literals are delimited with quotation mark (``"``) characters; 90 | quotation marks in the middle of a string are escaped with a backslash (``\``) 91 | character. Strings can contain linebreaks. 92 | -------------------------------------------------------------------------------- /website/source/publications.rst: -------------------------------------------------------------------------------- 1 | Publications and Contributors 2 | ============================= 3 | 4 | Core Publications 5 | ----------------- 6 | 7 | - | Eduard Kamburjan, Vidar Norstein Klungre, Rudolf Schlatte, Einar Broch Johnsen, Martin Giese 8 | | *Programming and Debugging with Semantically Lifted States.* 9 | | ESWC 2021 10 | 11 | DOI: `10.1007/978-3-030-77385-4_8 `_ 12 | 13 | - | Eduard Kamburjan, Einar Broch Johnsen. 14 | | *Knowledge Structures Over Simulation Units.* 15 | | ANNSIM 2022 16 | 17 | DOI: `10.23919/ANNSIM55834.2022.9859490 `_ 18 | 19 | 20 | Extensions 21 | ---------- 22 | 23 | - | Eduard Kamburjan, Vidar Norstein Klungre, Martin Giese. 24 | | *Never Mind the Semantic Gap: Modular, Lazy and Safe Loading of RDF Data.* 25 | | ESWC 2022 26 | 27 | DOI: `10.1007/978-3-031-06981-9_12 `_ 28 | 29 | - | Eduard Kamburjan, Egor V. Kostylev. 30 | | *Type Checking Semantically Lifted Programs via Query Containment under Entailment Regimes.* 31 | | Description Logics 2021 32 | 33 | Electronic edition: http://ceur-ws.org/Vol-2954/paper-19.pdf 34 | 35 | 36 | Digital Twins 37 | ------------- 38 | 39 | - | Eduard Kamburjan, Crystal Chang Din, Rudolf Schlatte, Silvia Lizeth Tapia Tarifa, Einar Broch Johnsen. 40 | | *Twinning-by-Construction: Ensuring Correctness for Self-adaptive Digital Twins.* 41 | | ISoLA (1) 2022 42 | 43 | DOI: `10.1007/978-3-031-19849-6_12 `_ 44 | 45 | - | Eduard Kamburjan, Vidar Norstein Klungre, Rudolf Schlatte, Silvia Lizeth Tapia Tarifa, David Cameron, Einar Broch Johnsen. 46 | | *Digital Twin Reconfiguration Using Asset Models.* 47 | | ISoLA (4) 2022 48 | 49 | DOI: `10.1007/978-3-031-19762-8_6 `_ 50 | 51 | 52 | Published Case Studies 53 | ---------------------- 54 | 55 | - | Yuanwei Qu, Eduard Kamburjan, Anita Tarabi, Martin Giese. 56 | | *Semantically triggered qualitative simulation of a geological process.* 57 | | Applied Computing and Geosciences. Vol. 21. 2024 58 | 59 | DOI: `10.1016/j.acags.2023.100152 `_ 60 | 61 | - | Eduard Kamburjan, Riccardo Sieve, Chinmayi Prabhu Baramashetru, Einar Broch Johnsen, Marco Amato, Gianluca Barmina, Eduard Occhipinti 62 | | *GreenhouseDT: An Exemplar for Digital Twins.* 63 | | SEAMS 2024. To appear 64 | -------------------------------------------------------------------------------- /website/source/tutorial.rst: -------------------------------------------------------------------------------- 1 | SMOL Tutorials 2 | ============== 3 | 4 | A SMOL tutorial was presented on September 26-27, 2022 at the `ICTAC 2022 5 | summer school `_, 6 | Tbilisi, Georgia. 7 | 8 | :download:`Slides for day one ` 9 | 10 | :download:`Slides for day two ` 11 | 12 | The online version of the tutorial is under development. 13 | 14 | .. toctree:: 15 | :maxdepth: 2 16 | :caption: Contents: 17 | 18 | Digital Twins 19 | Knowledge Modelling 20 | Modelling Physical Systems 21 | Semantic Reflection 22 | --------------------------------------------------------------------------------