diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000000000000000000000000000000000..0b58118283eb694753962956f681536c96b161c2 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ +root = true + +[*.{gradle,java}] +indent_style = tab + +[*.yml] +indent_style = space +indent_size = 2 diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..4a7e620b9c7816fb6caefdaa9e1122dc3b3a6955 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,39 @@ +image: openjdk:8-jdk-slim + +stages: + - test + - deploy + +variables: + GRADLE_OPTIONS: --no-daemon --info --stacktrace --warning-mode=all + +cache: + paths: + - .gradle/wrapper + - .gradle/caches + +before_script: + - export GRADLE_USER_HOME=`pwd`/.gradle + +tests: + stage: test + script: ./gradlew ${GRADLE_OPTIONS} check + +tests:jdk-11: + extends: tests + image: openjdk:11-jdk-slim + +tests:jdk-17: + extends: tests + image: openjdk:17-jdk-slim + +publish: + stage: deploy + script: + - openssl aes-256-cbc -pass "env:ENCRYPTION_PASSWORD" -d -a -md md5 -in secring.gpg.enc -out secring.gpg + - openssl aes-256-cbc -pass "env:ENCRYPTION_PASSWORD" -d -a -md md5 -in pubring.gpg.enc -out pubring.gpg + - openssl aes-256-cbc -pass "env:ENCRYPTION_PASSWORD" -d -a -md md5 -in gradle.properties.enc -out gradle.properties + - ./gradlew ${GRADLE_OPTIONS} publish + only: + - master@general/stups/tlc4b + - develop@general/stups/tlc4b diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 5149dfc6f470e97b754b9d376b3a05d11d4adf74..0000000000000000000000000000000000000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: java -script: ./gradlew --no-daemon --console verbose --stacktrace build -before_install: -- openssl aes-256-cbc -pass pass:$ENCRYPTION_PASSWORD -in secring.gpg.enc -out secring.gpg - -d -- openssl aes-256-cbc -pass pass:$ENCRYPTION_PASSWORD -in pubring.gpg.enc -out pubring.gpg - -d -- openssl aes-256-cbc -pass pass:$ENCRYPTION_PASSWORD -in gradle.properties.enc -out - gradle.properties -d -after_success: "[ $TRAVIS_BRANCH = 'master' ] && ./gradlew --no-daemon uploadArchives" -env: - global: - - secure: EnIo0zaQsHATGH8S5L1W0EHtqgV2kx6bfSgxyhz7XU+xw5y2JLDn+Y3ZaX7EcMK25RkgM8nld5Se72QmpienkP7tQlb5KHdwC10KgwbHDq+IP9q+ZMD2V1MsMRdTilW/eTZ0SUohlV5g4t3KqIe8l3Hs1dzNL0YmCMtXwYHdfwk= diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..edcdcde56c97aca593c770a160f2c0420b2f0122 --- /dev/null +++ b/Makefile @@ -0,0 +1,8 @@ +.PHONY: build +build: + ./gradlew createJar + +.PHONY: install +install: + echo "installing to local probcli/lib folder:" + cp build/libs/tlc4b-1.0.*.jar ../../prob_prolog/lib/TLC4B.jar diff --git a/README.md b/README.md index db8592946b417b7d4948a727be8e0ee42508869e..ece10b6dd1a3daba5f17a83840f2267b4ef6aa5e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ TLC4B ===== -[](https://travis-ci.org/hhu-stups/tlc4b) +[](https://gitlab.cs.uni-duesseldorf.de/general/stups/tlc4b/pipelines) diff --git a/build.gradle b/build.gradle index 6fa3de76be5ad3d3fb8c546676dcf9e2ee84c622..561ade0971b4f9d78166a6416888c93251dad67c 100644 --- a/build.gradle +++ b/build.gradle @@ -1,61 +1,66 @@ plugins { - id 'java' - id 'eclipse' - id 'maven' - id 'jacoco' - id 'findbugs' - id "de.undercouch.download" version "3.4.3" + id 'java' + id 'eclipse' + id 'jacoco' + id "maven-publish" + id "signing" + id "de.undercouch.download" version "5.4.0" } -project.version = '1.0.4' +project.version = '1.0.5' project.group = 'de.hhu.stups' -project.sourceCompatibility = '1.7' -project.targetCompatibility = '1.7' +final isSnapshot = project.version.endsWith("-SNAPSHOT") repositories { - mavenCentral() - maven { - name "sonatype snapshots" - url "https://oss.sonatype.org/content/repositories/snapshots" - } + mavenCentral() + if (isSnapshot) { + maven { + name "sonatype snapshots" + url "https://oss.sonatype.org/content/repositories/snapshots" + } + } } configurations.all { - resolutionStrategy.cacheChangingModulesFor 0, 'seconds' + resolutionStrategy.cacheChangingModulesFor 0, 'seconds' } -def parser_version = '2.9.12' +def parser_version = '2.9.25' def tlatools_version = '1.0.2' dependencies { - //compile (group: 'com.microsoft', name: 'tla2tools', version: '1.4.6') - compile 'commons-cli:commons-cli:1.2' - compile (group: 'de.hhu.stups', name: 'tlatools', version: tlatools_version) + //implementation(group: 'com.microsoft', name: 'tla2tools', version: '1.4.6') + implementation(group: 'commons-cli', name: 'commons-cli', version: '1.5.0') + implementation(group: 'de.hhu.stups', name: 'tlatools', version: tlatools_version) - compile (group: 'de.hhu.stups', name: 'prologlib', version: parser_version) - compile (group: 'de.hhu.stups', name: 'parserbase', version: parser_version) - compile (group: 'de.hhu.stups', name: 'bparser', version: parser_version) - compile (group: 'de.hhu.stups', name: 'ltlparser', version: parser_version) + implementation(group: 'de.hhu.stups', name: 'bparser', version: parser_version) + implementation(group: 'de.hhu.stups', name: 'ltlparser', version: parser_version) - //compile(group: 'de.hhu.stups', name: 'de.prob.core.kernel', version: '2.0.0-milestone-13-SNAPSHOT') + testImplementation(group: 'junit', name: 'junit', version: '4.13.2') + testImplementation(group: 'de.hhu.stups', name: 'tla2bAST', version: '1.1.3') +} - testCompile (group: 'junit', name: 'junit', version: '4.12') - testCompile (group: 'de.hhu.stups', name: 'tla2bAST', version: '1.1.0') +java { + project.sourceCompatibility = JavaVersion.VERSION_1_7 + project.targetCompatibility = JavaVersion.VERSION_1_7 + + withSourcesJar() + withJavadocJar() } jacoco { - toolVersion = "0.7.1.201405082137" - reportsDir = file("$buildDir/JacocoReports") + toolVersion = "0.8.7" + reportsDirectory = file("$buildDir/JacocoReports") } jacocoTestReport { - reports { - xml.enabled false - csv.enabled false - html.destination file("${buildDir}/jacocoHtml") - } + reports { + xml.required = false + csv.required = false + html.destination file("${buildDir}/jacocoHtml") + } } @@ -66,25 +71,25 @@ test { } task downloadPublicExamples(type: Download) { - src 'https://www3.hhu.de/stups/downloads/prob/source/ProB_public_examples.tgz' - dest buildDir - onlyIfModified true + src 'https://stups.hhu-hosting.de/downloads/prob/source/ProB_public_examples.tgz' + dest buildDir + onlyIfModified true } task extractPublicExamples(dependsOn: downloadPublicExamples, type: Copy) { - from tarTree(resources.gzip("${buildDir}/ProB_public_examples.tgz")) - into projectDir + from tarTree(resources.gzip("${buildDir}/ProB_public_examples.tgz")) + into "${buildDir}/prob_examples" + include "public_examples/TLC/**" } clean { - delete "${projectDir}/public_examples" + delete "${projectDir}/public_examples" // now extracted into build, but previous versions placed it at top level + delete "${projectDir}/states" + delete "${projectDir}/temp" } -task regressionTests(dependsOn: extractPublicExamples, type: Test){ - doFirst{ println("Running integration tests") } - scanForTestClasses = true - //include('de/tlc4b/tlc/integration/probprivate/**') - include('de/tlc4b/**') +task regressionTests(dependsOn: extractPublicExamples, type: Test) { + include('de/tlc4b/tlc/integration/probprivate/**') } check.dependsOn(regressionTests) @@ -95,21 +100,8 @@ task jacocoIntegrationTestReport(type: JacocoReport) { executionData fileTree(project.rootDir.absolutePath).include("**/build/jacoco/*.exec") } -tasks.withType(FindBugs) { - // disable findbugs by default - // in order to run findbugs type 'gradle build findbugsMain findbugsTest' - task -> enabled = gradle.startParameter.taskNames.contains(task.name) - - reports { - xml.enabled = false - html.enabled = true - } - - ignoreFailures = true -} - task createJar(type: Jar, dependsOn: build){ - archiveName = 'TLC4B.jar' + archiveFileName = 'TLC4B.jar' from sourceSets.main.output from {configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } exclude('**/*.java') @@ -118,76 +110,57 @@ task createJar(type: Jar, dependsOn: build){ } } +publishing { + publications { + mavenJava(MavenPublication) { + from components.java + + pom { + name = "TLC integration into ProB" + description = "Use the TLC model checker within ProB." + url = "https://github.com/hhu-stups/tlc4b" + + licenses { + license { + name = "Eclipse Public License, Version 2.1" + url = "https://www.eclipse.org/legal/epl-v10.html" + } + } + + scm { + connection = "scm:git:git://github.com/hhu-stups/tlc4b.git" + developerConnection = "scm:git:git@github.com:hhu-stups/tlc4b.git" + url = "https://github.com/bendisposto/hhu-stups/tlc4b" + } + + developers { + developer { + id = "bendisposto" + name = "Jens Bendisposto" + email = "jens@bendisposto.de" + } + } + } + } + } -if (project.hasProperty('ossrhUsername') && project.hasProperty('ossrhPassword')) { - -apply plugin: 'signing' - -signing { - sign configurations.archives -} - -javadoc { - failOnError = false -} - -task javadocJar(type: Jar) { - classifier = 'javadoc' - from javadoc -} - -task sourcesJar(type: Jar) { - classifier = 'sources' - from sourceSets.main.allSource -} - -artifacts { - archives javadocJar, sourcesJar + repositories { + maven { + final releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2" + final snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots" + url isSnapshot ? snapshotsRepoUrl : releasesRepoUrl + if (project.hasProperty("ossrhUsername") && project.hasProperty("ossrhPassword")) { + credentials { + username project.ossrhUsername + password project.ossrhPassword + } + } + } + } } -uploadArchives { - repositories { - mavenDeployer { - beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) } - - repository(url: "https://oss.sonatype.org/service/local/staging/deploy/maven2/") { - authentication(userName: ossrhUsername, password: ossrhPassword) - } +ext."signing.secretKeyRingFile" = rootProject.file("secring.gpg").absolutePath - snapshotRepository(url: "https://oss.sonatype.org/content/repositories/snapshots/") { - authentication(userName: ossrhUsername, password: ossrhPassword) - } - - pom.project { - name 'TLC integration into ProB' - packaging 'jar' - // optionally artifactId can be defined here - description "Use the TLC model checker within ProB." - url 'https://github.com/hhu-stups/tlc4b' - - licenses { - license { - name 'Eclipse Public License, Version 2.1' - url 'https://www.eclipse.org/legal/epl-v10.html' - } - } - - scm { - connection 'scm:git:git://github.com/hhu-stups/tlc4b.git' - developerConnection 'scm:git:git@github.com:hhu-stups/tlc4b.git' - url 'https://github.com/bendisposto/hhu-stups/tlc4b' - } - - - developers { - developer { - id 'bendisposto' - name 'Jens Bendisposto' - email 'jens@bendisposto.de' - } - } - } - } - } -} +signing { + sign publishing.publications.mavenJava } diff --git a/gradle.properties.enc b/gradle.properties.enc index 5cdf0502f03c0571840f17442e1280e3a0e4c3e7..83e084509404a88a304c64f23a26e07bf592c44d 100644 --- a/gradle.properties.enc +++ b/gradle.properties.enc @@ -1,4 +1,5 @@ -Salted__ݐ� -'�\�"۬��u ��.U�xF;F�bO}>*&S�ؠf�ߝ��{RenU���n��s8y�a��1/�X;�� ��ԏ�:?��JO��~�dBG,;���-݄2XW��FFfp;����8r6�O����Z����qN]�����0�x��Bl�P��6Ч�Y��j����{ -�n(�m$�.��,K -����a����6؇�� 7���!�E� \ No newline at end of file +U2FsdGVkX18nOHLNyyzYk3lwSF0IGgXp8ubFJuMWOPaMbTBmgRPWS/jQT4LO17HP +W5yqIb+NzcYqzLBohg9s9r4XFyoS5ic3TIyPp87IXzgWNh3gKV+F+DfbggwMjiyJ +0gZI+90cmkWXBDW7c3JijLOX2f0NATwuiwHFPau3FCKC0cp7uOArtqkbfZau2how +oP8hzzAue50fahPuBfg8h3OtofJW9x9UCUxxD/NXzD8VZFQabICUjI8mcjEcvaea +MqQn9JuoekIRPDUsUwZ9Er07OkzKXHB5c968S3DUP3w= diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 29953ea141f55e3b8fc691d31b5ca8816d89fa87..943f0cbfa754578e88a3dae77fce6e3dea56edbf 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e0b3fb8d70b1bbf790f6f8ed1c928ddf09f54628..508322917bdcd5b42c43cf8ce0d1f9269226a405 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip +networkTimeout=10000 zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/gradlew b/gradlew index cccdd3d517fc5249beaefa600691cf150f2fa3e6..65dcd68d65c82f2a5338fded4af852f9caf93b93 100755 --- a/gradlew +++ b/gradlew @@ -1,78 +1,129 @@ -#!/usr/bin/env sh +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## # Attempt to set APP_HOME + # Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >/dev/null -APP_HOME="`pwd -P`" -cd "$SAVED" >/dev/null -APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum warn () { echo "$*" -} +} >&2 die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false nonstop=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; - NONSTOP* ) - nonstop=true - ;; +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -81,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -89,84 +140,105 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - JAVACMD=`cygpath --unix "$JAVACMD"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Escape application args -save () { - for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done - echo " " -} -APP_ARGS=$(save "$@") - -# Collect all arguments for the java command, following the shell quoting and substitution rules -eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" - -# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong -if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then - cd "$(dirname "$0")" +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" fi +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index f9553162f122c71b34635112e717c3e733b5b212..6689b85beecde676054c39c2408085f41e6be6dc 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,84 +1,92 @@ -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/pubring.gpg.enc b/pubring.gpg.enc index 06bc9ccbe75197099d89fd6ad6acdefcb7bb251a..fb1dfb132bd34d077723753821aefdc42be64bc2 100644 Binary files a/pubring.gpg.enc and b/pubring.gpg.enc differ diff --git a/secring.gpg.enc b/secring.gpg.enc index 388a462e3456cf708c557fa5136bbd43e59596ce..048652a825198ed70f778f2b82600b83be9d5d3e 100644 Binary files a/secring.gpg.enc and b/secring.gpg.enc differ diff --git a/src/main/java/de/tlc4b/TLC4B.java b/src/main/java/de/tlc4b/TLC4B.java index 970b42bf0774f7ee922fdc11d3b1b18bdf6d73ae..4efe0950a58f11c2258fa6e9eb2d28223117bc55 100644 --- a/src/main/java/de/tlc4b/TLC4B.java +++ b/src/main/java/de/tlc4b/TLC4B.java @@ -1,549 +1,549 @@ -package de.tlc4b; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStreamWriter; -import java.io.UnsupportedEncodingException; -import java.util.LinkedHashMap; -import java.util.Map.Entry; - -import de.be4.classicalb.core.parser.exceptions.BCompoundException; -import de.tlc4b.TLC4BGlobals; -import de.tlc4b.analysis.UsedStandardModules.STANDARD_MODULES; -import de.tlc4b.exceptions.TLC4BIOException; -import de.tlc4b.exceptions.TLC4BException; -import de.tlc4b.exceptions.TranslationException; -import de.tlc4b.tlc.TLCOutputInfo; -import de.tlc4b.tlc.TLCResults; -import de.tlc4b.util.StopWatch; -import static de.tlc4b.util.StopWatch.Watches.*; -import static de.tlc4b.MP.*; - -public class TLC4B { - - private String filename; - private File mainfile; - private String machineFileNameWithoutFileExtension; - // e.g. Test of file foo/bar/Test.mch - private String logFileString; - - private File buildDir; - - private String tlaModule; - private String config; - private Translator translator; - private TLCOutputInfo tlcOutputInfo; - private String ltlFormula; - private String constantsSetup; - - public static void main(String[] args) { - System.setProperty("apple.awt.UIElement", "true"); - // avoiding pop up window - - TLC4B tlc4b = new TLC4B(); - try { - tlc4b.process(args); - } catch (BCompoundException e) { - printlnErr("***** Parsing Error *****"); - printlnErr(e.getMessage()); - return; - } catch (TLC4BException e) { - printlnErr(e.getMessage()); - println("Model checking time: 0 sec"); - println("Result: " + e.getError()); - return; - } catch (IOException e) { - printlnErr(e.getMessage()); - println("Model checking time: 0 sec"); - println("Result: " + "I/O Error"); - } - - if (TLC4BGlobals.isRunTLC()) { - try { - - TLCRunner.runTLC(tlc4b.machineFileNameWithoutFileExtension, - tlc4b.buildDir); - TLCResults results = new TLCResults(tlc4b.tlcOutputInfo); - results.evalResults(); - tlc4b.printResults(results, TLC4BGlobals.isCreateTraceFile()); - Log log = new Log(tlc4b, results); - tlc4b.createLogFile(log); - System.exit(0); - - } catch (NoClassDefFoundError e) { - printlnErr("Can not find TLC. The tlatools.jar must be included in the classpath."); - } - - } - - } - - private void printResults(TLCResults results, boolean createTraceFile) { - printOperationsCount(results); - // options - println("Used Options"); - println("| Number of workers: " + TLC4BGlobals.getWorkers()); - println("| Invariants check: " + TLC4BGlobals.isInvariant()); - println("| Deadlock check: " + TLC4BGlobals.isDeadlockCheck()); - println("| Assertion check: " + TLC4BGlobals.isAssertion()); - println("| Find Goal check: " + TLC4BGlobals.isGOAL()); - println("| LTL formulas check: " + TLC4BGlobals.isCheckLTL()); - println("| Partial invariant evaluation: " - + TLC4BGlobals.isPartialInvariantEvaluation()); - println("| Lazy constants setup: " - + !TLC4BGlobals.isForceTLCToEvalConstants()); - println("| Agressive well-definedness check: " - + TLC4BGlobals.checkWelldefinedness()); - println("| Prob constant setup: " + TLC4BGlobals.isProBconstantsSetup()); - println("| Symmetry reduction: " + TLC4BGlobals.useSymmetry()); - println("| MIN Int: " + TLC4BGlobals.getMIN_INT()); - println("| MAX Int: " + TLC4BGlobals.getMAX_INT()); - println("| Standard deferret set size: " - + TLC4BGlobals.getDEFERRED_SET_SIZE()); - println("--------------------------------"); - println("Parsing time: " + StopWatch.getRunTime(PARSING_TIME) + " ms"); - println("Translation time: " + StopWatch.getRunTime(TRANSLATION_TIME) - + " ms"); - println("Model checking time: " + results.getModelCheckingTime() - + " sec"); - // MP.printMessage("Number of workers: " + - // TLCGlobals.getNumWorkers()); - if (results.getViolatedAssertions().size() > 0) { - println("Violated assertions: " + results.getViolatedAssertions()); - } - println("States analysed: " + results.getNumberOfDistinctStates()); - println("Transitions fired: " + results.getNumberOfTransitions()); - println("Result: " + results.getResultString()); - String violatedDefinition = results.getViolatedDefinition(); - if (violatedDefinition != null) { - println("Violated Definition: " + violatedDefinition); - } - - if (results.hasTrace() && createTraceFile) { - String trace = results.getTrace(); - String tracefileName = machineFileNameWithoutFileExtension - + ".tla.trace"; - File traceFile = createFile(mainfile.getParentFile(), - tracefileName, trace, false); - if (traceFile != null) { - println("Trace file '" + traceFile.getAbsolutePath() - + "' created."); - } - } - - } - - private void printOperationsCount(TLCResults results) { - LinkedHashMap<String, Long> operationCount = results - .getOperationCount(); - if (TLC4BGlobals.isPrintCoverage() && operationCount != null) { - println("---------- Coverage statistics ----------"); - - for (Entry<String, Long> entry : operationCount.entrySet()) { - String key = entry.getKey(); - String value = entry.getValue().toString(); - println(key + ": " + value); - } - println("---------- End of coverage statistics ----------"); - } - } - - public static void test(String[] args, boolean deleteFiles) - throws Exception { - System.setProperty("apple.awt.UIElement", "true"); // avoiding pop up - // windows - TLC4BGlobals.resetGlobals(); - TLC4BGlobals.setDeleteOnExit(deleteFiles); - TLC4BGlobals.setCreateTraceFile(false); - TLC4BGlobals.setTestingMode(true); - // B2TLAGlobals.setCleanup(true); - TLC4B tlc4b = new TLC4B(); - try { - tlc4b.process(args); - } catch (Exception e) { - e.printStackTrace(); - printlnErr(e.getMessage()); - throw e; - } - if (TLC4BGlobals.isRunTLC()) { - MP.TLCOutputStream.changeOutputStream(); - TLCRunner.runTLC(tlc4b.machineFileNameWithoutFileExtension, - tlc4b.buildDir); - MP.TLCOutputStream.resetOutputStream(); - TLCResults results = new TLCResults(tlc4b.tlcOutputInfo); - results.evalResults(); - tlc4b.printResults(results, false); - - System.exit(0); - } - } - - public static void testString(String machineString, boolean deleteFiles) - throws Exception { - System.setProperty("apple.awt.UIElement", "true"); // avoiding pop up - // windows - TLC4BGlobals.resetGlobals(); - TLC4BGlobals.setDeleteOnExit(deleteFiles); - TLC4BGlobals.setCreateTraceFile(false); - TLC4BGlobals.setTestingMode(true); - // B2TLAGlobals.setCleanup(true); - TLC4B tlc4b = new TLC4B(); - tlc4b.buildDir = new File("temp/"); - - tlc4b.machineFileNameWithoutFileExtension = "Test"; - - StopWatch.start(PARSING_TIME); - MP.print("Parsing... "); - tlc4b.translator = new Translator(machineString); - StopWatch.stop(PARSING_TIME); - println("(" + StopWatch.getRunTimeAsString(PARSING_TIME) + "ms)"); - - StopWatch.start(TRANSLATION_TIME); - MP.print("Translating... "); - tlc4b.translator.translate(); - tlc4b.tlaModule = tlc4b.translator.getModuleString(); - tlc4b.config = tlc4b.translator.getConfigString(); - tlc4b.tlcOutputInfo = tlc4b.translator.getTLCOutputInfo(); - StopWatch.stop(TRANSLATION_TIME); - println("(" + StopWatch.getRunTimeAsString(TRANSLATION_TIME) + "ms)"); - tlc4b.createFiles(); - - if (TLC4BGlobals.isRunTLC()) { - MP.TLCOutputStream.changeOutputStream(); - TLCRunner.runTLC(tlc4b.machineFileNameWithoutFileExtension, - tlc4b.buildDir); - MP.TLCOutputStream.resetOutputStream(); - TLCResults results = new TLCResults(tlc4b.tlcOutputInfo); - results.evalResults(); - tlc4b.printResults(results, false); - System.exit(0); - } - } - - private void handleParameter(String[] args) { - int index = 0; - while (index < args.length) { - if (args[index].toLowerCase().equals("-nodead")) { - TLC4BGlobals.setDeadlockCheck(false); - } else if (args[index].toLowerCase().equals("-notlc")) { - TLC4BGlobals.setRunTLC(false); - } else if (args[index].toLowerCase().equals("-notranslation")) { - TLC4BGlobals.setTranslate(false); - } else if (args[index].toLowerCase().equals("-nogoal")) { - TLC4BGlobals.setGOAL(false); - } else if (args[index].toLowerCase().equals("-noinv")) { - TLC4BGlobals.setInvariant(false); - } else if (args[index].toLowerCase().equals("-noass")) { - TLC4BGlobals.setAssertionCheck(false); - } else if (args[index].toLowerCase().equals("-wdcheck")) { - TLC4BGlobals.setWelldefinednessCheck(true); - } else if (args[index].toLowerCase().equals("-symmetry")) { - TLC4BGlobals.setSymmetryUse(true); - } else if (args[index].toLowerCase().equals("-tool")) { - TLC4BGlobals.setTool(false); - } else if (args[index].toLowerCase().equals("-tmp")) { - buildDir = new File(System.getProperty("java.io.tmpdir")); - } else if (args[index].toLowerCase().equals("-noltl")) { - TLC4BGlobals.setCheckltl(false); - } else if (args[index].toLowerCase().equals("-lazyconstants")) { - TLC4BGlobals.setForceTLCToEvalConstants(false); - } else if (args[index].toLowerCase().equals("-testscript")) { - TLC4BGlobals.setRunTestscript(true); - } else if (args[index].toLowerCase().equals("-notrace")) { - TLC4BGlobals.setCreateTraceFile(false); - } else if (args[index].toLowerCase().equals("-del")) { - TLC4BGlobals.setDeleteOnExit(true); - } else if (args[index].toLowerCase().equals("-parinveval")) { - TLC4BGlobals.setPartialInvariantEvaluation(true); - } else if (args[index].toLowerCase().equals("-log")) { - index = index + 1; - if (index == args.length) { - throw new TLC4BIOException( - "Error: File requiered after option '-log'."); - } - logFileString = args[index]; - - } else if (args[index].toLowerCase().equals("-maxint")) { - index = index + 1; - if (index == args.length) { - throw new TLC4BIOException( - "Error: Number requiered after option '-maxint'."); - } - int maxint = Integer.parseInt(args[index]); - TLC4BGlobals.setMAX_INT(maxint); - } else if (args[index].toLowerCase().equals("-default_setsize")) { - index = index + 1; - if (index == args.length) { - throw new TLC4BIOException( - "Error: Number requiered after option '-default_setsize'."); - } - int deferredSetSize = Integer.parseInt(args[index]); - TLC4BGlobals.setDEFERRED_SET_SIZE(deferredSetSize); - } - else if (args[index].toLowerCase().equals("-minint")) { - index = index + 1; - if (index == args.length) { - throw new TLC4BIOException( - "Error: Number requiered after option '-minint'."); - } - int minint = Integer.parseInt(args[index]); - TLC4BGlobals.setMIN_INT(minint); - ; - } else if (args[index].toLowerCase().equals("-workers")) { - index = index + 1; - if (index == args.length) { - throw new TLC4BIOException( - "Error: Number requiered after option '-workers'."); - } - int workers = Integer.parseInt(args[index]); - TLC4BGlobals.setWorkers(workers); - } else if (args[index].toLowerCase().equals("-constantssetup")) { - TLC4BGlobals.setProBconstantsSetup(true); - index = index + 1; - if (index == args.length) { - throw new TLC4BIOException( - "Error: String requiered after option '-constantssetup'."); - } - constantsSetup = args[index]; - } else if (args[index].toLowerCase().equals("-ltlformula")) { - index = index + 1; - if (index == args.length) { - throw new TLC4BIOException( - "Error: LTL formula requiered after option '-ltlformula'."); - } - ltlFormula = args[index]; - } else if (args[index].charAt(0) == '-') { - throw new TLC4BIOException("Error: unrecognized option: " - + args[index]); - } else { - if (filename != null) { - throw new TLC4BIOException( - "Error: more than one input files: " + filename - + " and " + args[index]); - } - filename = args[index]; - - } - index++; - } - if (filename == null) { - throw new TLC4BIOException("Main machine required!"); - } - } - - public void process(String[] args) throws IOException, BCompoundException { - - MP.print("Arguments: "); - for (int i = 0; i < args.length; i++) { - String string = args[i]; - MP.print(string); - MP.print(" "); - } - println(""); - - handleParameter(args); - - handleMainFileName(); - if (TLC4BGlobals.isTranslate()) { - StopWatch.start(PARSING_TIME); - MP.print("Parsing... "); - translator = new Translator(machineFileNameWithoutFileExtension, - mainfile, this.ltlFormula, this.constantsSetup); - StopWatch.stop(PARSING_TIME); - println("(" + StopWatch.getRunTimeAsString(PARSING_TIME) + "ms)"); - - StopWatch.start(TRANSLATION_TIME); - MP.print("Translating... "); - translator.translate(); - this.tlaModule = translator.getModuleString(); - this.config = translator.getConfigString(); - this.tlcOutputInfo = translator.getTLCOutputInfo(); - StopWatch.stop(TRANSLATION_TIME); - println("(" + StopWatch.getRunTimeAsString(TRANSLATION_TIME) - + "ms)"); - createFiles(); - } - - } - - private void handleMainFileName() { - // the following lines fix incorrect file names - filename = filename.replace("\\", File.separator); - filename = filename.replace("/", File.separator); - if (!filename.toLowerCase().endsWith(".mch") && - !filename.toLowerCase().endsWith(".sys")) { - filename = filename + ".mch"; - } - - mainfile = new File(filename); - if (!mainfile.exists()) { - throw new TLC4BIOException("The file " + mainfile.getPath() - + " does not exist."); - } - try { - mainfile = mainfile.getCanonicalFile(); - } catch (IOException e) { - throw new TLC4BIOException("The file '" + mainfile.getPath() - + "' can not be accessed."); - } - - machineFileNameWithoutFileExtension = mainfile.getName().substring(0, - mainfile.getName().length() - 4); // deleting .mch - - if (buildDir == null) { - buildDir = new File(mainfile.getParentFile(), - machineFileNameWithoutFileExtension); - } - } - - private void createLogFile(Log log) { - if (logFileString != null) { - File logFile = new File(logFileString); - FileWriter fw; - boolean fileExists = logFile.exists(); - try { - fw = new FileWriter(logFile, true); // the true will append the - // new data - if (!fileExists) { - fw.write(log.getCSVFieldNamesLine()); - } - fw.write(log.getCSVValueLine()); - fw.close(); - println("Log file: " + logFile.getAbsolutePath()); - } catch (IOException e) { - new TLC4BIOException(e.getLocalizedMessage()); - } - } - } - - private void createFiles() { - boolean dirCreated = buildDir.mkdir(); - if (dirCreated && TLC4BGlobals.isDeleteOnExit()) { - buildDir.deleteOnExit(); - } - - File moduleFile = createFile(buildDir, - machineFileNameWithoutFileExtension + ".tla", tlaModule, - TLC4BGlobals.isDeleteOnExit()); - if (moduleFile != null) { - println("TLA+ module '" + moduleFile.getAbsolutePath() - + "' created."); - } - - File configFile = createFile(buildDir, - machineFileNameWithoutFileExtension + ".cfg", config, - TLC4BGlobals.isDeleteOnExit()); - if (configFile != null) { - println("Configuration file '" + configFile.getAbsolutePath() - + "' created."); - } - - createStandardModules(); - } - - private void createStandardModules() { - for (STANDARD_MODULES module : translator - .getStandardModuleToBeCreated()) { - createStandardModule(buildDir, module.toString()); - } - } - - private void createStandardModule(File path, String name) { - // standard modules are copied from the standardModules folder to the - // current directory - - File file = new File(path, name + ".tla"); - InputStream is = null; - FileOutputStream fos = null; - try { - - try { - is = new FileInputStream("src/main/resources/standardModules/" - + name + ".tla"); - } catch (FileNotFoundException e) { - is = this - .getClass() - .getClassLoader() - .getResourceAsStream("standardModules/" + name + ".tla"); - } - - if (is == null) { - // should never happen - throw new TranslationException( - "Unable to determine the source of the standard module: " - + name); - } - - fos = new FileOutputStream(file); - - int read = 0; - byte[] bytes = new byte[1024]; - - while ((read = is.read(bytes)) != -1) { - fos.write(bytes, 0, read); - } - println("Standard module '" + file.getName() + "' created."); - } catch (IOException e) { - throw new TLC4BIOException(e.getMessage()); - } finally { - if (TLC4BGlobals.isDeleteOnExit() && file.exists()) { - file.deleteOnExit(); - } - try { - if (is != null) { - is.close(); - } - if (fos != null) { - fos.flush(); - fos.close(); - } - } catch (IOException ex) { - throw new TLC4BIOException(ex.getMessage()); - } - } - } - - public static File createFile(File dir, String fileName, String text, - boolean deleteOnExit) { - - File file = new File(dir, fileName); - boolean exists = false; - try { - exists = file.createNewFile(); - BufferedWriter out = new BufferedWriter(new OutputStreamWriter( - new FileOutputStream(file), "UTF-8")); - out.write(text); - out.close(); - return file; - } catch (UnsupportedEncodingException e1) { - throw new TLC4BIOException(e1.getMessage()); - } catch (FileNotFoundException e1) { - throw new TLC4BIOException(e1.getMessage()); - } catch (IOException e) { - throw new TLC4BIOException(e.getMessage()); - } finally { - if (deleteOnExit && exists) { - file.deleteOnExit(); - } - } - } - - public File getBuildDir() { - return buildDir; - } - - public String getMachineFileNameWithoutFileExtension() { - return machineFileNameWithoutFileExtension; - } - - public File getMainFile(){ - return this.mainfile; - } - -} +package de.tlc4b; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStreamWriter; +import java.io.UnsupportedEncodingException; +import java.util.LinkedHashMap; +import java.util.Map.Entry; + +import de.be4.classicalb.core.parser.exceptions.BCompoundException; +import de.tlc4b.TLC4BGlobals; +import de.tlc4b.analysis.UsedStandardModules.STANDARD_MODULES; +import de.tlc4b.exceptions.TLC4BIOException; +import de.tlc4b.exceptions.TLC4BException; +import de.tlc4b.exceptions.TranslationException; +import de.tlc4b.tlc.TLCOutputInfo; +import de.tlc4b.tlc.TLCResults; +import de.tlc4b.util.StopWatch; +import static de.tlc4b.util.StopWatch.Watches.*; +import static de.tlc4b.MP.*; + +public class TLC4B { + + private String filename; + private File mainfile; + private String machineFileNameWithoutFileExtension; + // e.g. Test of file foo/bar/Test.mch + private String logFileString; + + private File buildDir; + + private String tlaModule; + private String config; + private Translator translator; + private TLCOutputInfo tlcOutputInfo; + private String ltlFormula; + private String constantsSetup; + + public static void main(String[] args) { + System.setProperty("apple.awt.UIElement", "true"); + // avoiding pop up window + + TLC4B tlc4b = new TLC4B(); + try { + tlc4b.process(args); + } catch (BCompoundException e) { + printlnErr("***** Parsing Error *****"); + printlnErr(e.getMessage()); + return; + } catch (TLC4BException e) { + printlnErr(e.getMessage()); + println("Model checking time: 0 sec"); + println("Result: " + e.getError()); + return; + } catch (IOException e) { + printlnErr(e.getMessage()); + println("Model checking time: 0 sec"); + println("Result: " + "I/O Error"); + } + + if (TLC4BGlobals.isRunTLC()) { + try { + + TLCRunner.runTLC(tlc4b.machineFileNameWithoutFileExtension, + tlc4b.buildDir); + TLCResults results = new TLCResults(tlc4b.tlcOutputInfo); + results.evalResults(); + tlc4b.printResults(results, TLC4BGlobals.isCreateTraceFile()); + Log log = new Log(tlc4b, results); + tlc4b.createLogFile(log); + System.exit(0); + + } catch (NoClassDefFoundError e) { + printlnErr("Can not find TLC. The tlatools.jar must be included in the classpath."); + } + + } + + } + + private void printResults(TLCResults results, boolean createTraceFile) { + printOperationsCount(results); + // options + println("Used Options"); + println("| Number of workers: " + TLC4BGlobals.getWorkers()); + println("| Invariants check: " + TLC4BGlobals.isInvariant()); + println("| Deadlock check: " + TLC4BGlobals.isDeadlockCheck()); + println("| Assertion check: " + TLC4BGlobals.isAssertion()); + println("| Find Goal check: " + TLC4BGlobals.isGOAL()); + println("| LTL formulas check: " + TLC4BGlobals.isCheckLTL()); + println("| Partial invariant evaluation: " + + TLC4BGlobals.isPartialInvariantEvaluation()); + println("| Lazy constants setup: " + + !TLC4BGlobals.isForceTLCToEvalConstants()); + println("| Agressive well-definedness check: " + + TLC4BGlobals.checkWelldefinedness()); + println("| Prob constant setup: " + TLC4BGlobals.isProBconstantsSetup()); + println("| Symmetry reduction: " + TLC4BGlobals.useSymmetry()); + println("| MIN Int: " + TLC4BGlobals.getMIN_INT()); + println("| MAX Int: " + TLC4BGlobals.getMAX_INT()); + println("| Standard deferret set size: " + + TLC4BGlobals.getDEFERRED_SET_SIZE()); + println("--------------------------------"); + println("Parsing time: " + StopWatch.getRunTime(PARSING_TIME) + " ms"); + println("Translation time: " + StopWatch.getRunTime(TRANSLATION_TIME) + + " ms"); + println("Model checking time: " + results.getModelCheckingTime() + + " sec"); + // MP.printMessage("Number of workers: " + + // TLCGlobals.getNumWorkers()); + if (results.getViolatedAssertions().size() > 0) { + println("Violated assertions: " + results.getViolatedAssertions()); + } + println("States analysed: " + results.getNumberOfDistinctStates()); + println("Transitions fired: " + results.getNumberOfTransitions()); + println("Result: " + results.getResultString()); + String violatedDefinition = results.getViolatedDefinition(); + if (violatedDefinition != null) { + println("Violated Definition: " + violatedDefinition); + } + + if (results.hasTrace() && createTraceFile) { + String trace = results.getTrace(); + String tracefileName = machineFileNameWithoutFileExtension + + ".tla.trace"; + File traceFile = createFile(mainfile.getParentFile(), + tracefileName, trace, false); + if (traceFile != null) { + println("Trace file '" + traceFile.getAbsolutePath() + + "' created."); + } + } + + } + + private void printOperationsCount(TLCResults results) { + LinkedHashMap<String, Long> operationCount = results + .getOperationCount(); + if (TLC4BGlobals.isPrintCoverage() && operationCount != null) { + println("---------- Coverage statistics ----------"); + + for (Entry<String, Long> entry : operationCount.entrySet()) { + String key = entry.getKey(); + String value = entry.getValue().toString(); + println(key + ": " + value); + } + println("---------- End of coverage statistics ----------"); + } + } + + public static void test(String[] args, boolean deleteFiles) + throws Exception { + System.setProperty("apple.awt.UIElement", "true"); // avoiding pop up + // windows + TLC4BGlobals.resetGlobals(); + TLC4BGlobals.setDeleteOnExit(deleteFiles); + TLC4BGlobals.setCreateTraceFile(false); + TLC4BGlobals.setTestingMode(true); + // B2TLAGlobals.setCleanup(true); + TLC4B tlc4b = new TLC4B(); + try { + tlc4b.process(args); + } catch (Exception e) { + e.printStackTrace(); + printlnErr(e.getMessage()); + throw e; + } + if (TLC4BGlobals.isRunTLC()) { + MP.TLCOutputStream.changeOutputStream(); + TLCRunner.runTLC(tlc4b.machineFileNameWithoutFileExtension, + tlc4b.buildDir); + MP.TLCOutputStream.resetOutputStream(); + TLCResults results = new TLCResults(tlc4b.tlcOutputInfo); + results.evalResults(); + tlc4b.printResults(results, false); + + System.exit(0); + } + } + + public static void testString(String machineString, boolean deleteFiles) + throws Exception { + System.setProperty("apple.awt.UIElement", "true"); // avoiding pop up + // windows + TLC4BGlobals.resetGlobals(); + TLC4BGlobals.setDeleteOnExit(deleteFiles); + TLC4BGlobals.setCreateTraceFile(false); + TLC4BGlobals.setTestingMode(true); + // B2TLAGlobals.setCleanup(true); + TLC4B tlc4b = new TLC4B(); + tlc4b.buildDir = new File("temp/"); + + tlc4b.machineFileNameWithoutFileExtension = "Test"; + + StopWatch.start(PARSING_TIME); + MP.print("Parsing... "); + tlc4b.translator = new Translator(machineString); + StopWatch.stop(PARSING_TIME); + println("(" + StopWatch.getRunTimeAsString(PARSING_TIME) + "ms)"); + + StopWatch.start(TRANSLATION_TIME); + MP.print("Translating... "); + tlc4b.translator.translate(); + tlc4b.tlaModule = tlc4b.translator.getModuleString(); + tlc4b.config = tlc4b.translator.getConfigString(); + tlc4b.tlcOutputInfo = tlc4b.translator.getTLCOutputInfo(); + StopWatch.stop(TRANSLATION_TIME); + println("(" + StopWatch.getRunTimeAsString(TRANSLATION_TIME) + "ms)"); + tlc4b.createFiles(); + + if (TLC4BGlobals.isRunTLC()) { + MP.TLCOutputStream.changeOutputStream(); + TLCRunner.runTLC(tlc4b.machineFileNameWithoutFileExtension, + tlc4b.buildDir); + MP.TLCOutputStream.resetOutputStream(); + TLCResults results = new TLCResults(tlc4b.tlcOutputInfo); + results.evalResults(); + tlc4b.printResults(results, false); + System.exit(0); + } + } + + private void handleParameter(String[] args) { + int index = 0; + while (index < args.length) { + if (args[index].toLowerCase().equals("-nodead")) { + TLC4BGlobals.setDeadlockCheck(false); + } else if (args[index].toLowerCase().equals("-notlc")) { + TLC4BGlobals.setRunTLC(false); + } else if (args[index].toLowerCase().equals("-notranslation")) { + TLC4BGlobals.setTranslate(false); + } else if (args[index].toLowerCase().equals("-nogoal")) { + TLC4BGlobals.setGOAL(false); + } else if (args[index].toLowerCase().equals("-noinv")) { + TLC4BGlobals.setInvariant(false); + } else if (args[index].toLowerCase().equals("-noass")) { + TLC4BGlobals.setAssertionCheck(false); + } else if (args[index].toLowerCase().equals("-wdcheck")) { + TLC4BGlobals.setWelldefinednessCheck(true); + } else if (args[index].toLowerCase().equals("-symmetry")) { + TLC4BGlobals.setSymmetryUse(true); + } else if (args[index].toLowerCase().equals("-tool")) { + TLC4BGlobals.setTool(false); + } else if (args[index].toLowerCase().equals("-tmp")) { + buildDir = new File(System.getProperty("java.io.tmpdir")); + } else if (args[index].toLowerCase().equals("-noltl")) { + TLC4BGlobals.setCheckltl(false); + } else if (args[index].toLowerCase().equals("-lazyconstants")) { + TLC4BGlobals.setForceTLCToEvalConstants(false); + } else if (args[index].toLowerCase().equals("-testscript")) { + TLC4BGlobals.setRunTestscript(true); + } else if (args[index].toLowerCase().equals("-notrace")) { + TLC4BGlobals.setCreateTraceFile(false); + } else if (args[index].toLowerCase().equals("-del")) { + TLC4BGlobals.setDeleteOnExit(true); + } else if (args[index].toLowerCase().equals("-parinveval")) { + TLC4BGlobals.setPartialInvariantEvaluation(true); + } else if (args[index].toLowerCase().equals("-log")) { + index = index + 1; + if (index == args.length) { + throw new TLC4BIOException( + "Error: File requiered after option '-log'."); + } + logFileString = args[index]; + + } else if (args[index].toLowerCase().equals("-maxint")) { + index = index + 1; + if (index == args.length) { + throw new TLC4BIOException( + "Error: Number requiered after option '-maxint'."); + } + int maxint = Integer.parseInt(args[index]); + TLC4BGlobals.setMAX_INT(maxint); + } else if (args[index].toLowerCase().equals("-default_setsize")) { + index = index + 1; + if (index == args.length) { + throw new TLC4BIOException( + "Error: Number requiered after option '-default_setsize'."); + } + int deferredSetSize = Integer.parseInt(args[index]); + TLC4BGlobals.setDEFERRED_SET_SIZE(deferredSetSize); + } + else if (args[index].toLowerCase().equals("-minint")) { + index = index + 1; + if (index == args.length) { + throw new TLC4BIOException( + "Error: Number requiered after option '-minint'."); + } + int minint = Integer.parseInt(args[index]); + TLC4BGlobals.setMIN_INT(minint); + ; + } else if (args[index].toLowerCase().equals("-workers")) { + index = index + 1; + if (index == args.length) { + throw new TLC4BIOException( + "Error: Number requiered after option '-workers'."); + } + int workers = Integer.parseInt(args[index]); + TLC4BGlobals.setWorkers(workers); + } else if (args[index].toLowerCase().equals("-constantssetup")) { + TLC4BGlobals.setProBconstantsSetup(true); + index = index + 1; + if (index == args.length) { + throw new TLC4BIOException( + "Error: String requiered after option '-constantssetup'."); + } + constantsSetup = args[index]; + } else if (args[index].toLowerCase().equals("-ltlformula")) { + index = index + 1; + if (index == args.length) { + throw new TLC4BIOException( + "Error: LTL formula requiered after option '-ltlformula'."); + } + ltlFormula = args[index]; + } else if (args[index].charAt(0) == '-') { + throw new TLC4BIOException("Error: unrecognized option: " + + args[index]); + } else { + if (filename != null) { + throw new TLC4BIOException( + "Error: more than one input files: " + filename + + " and " + args[index]); + } + filename = args[index]; + + } + index++; + } + if (filename == null) { + throw new TLC4BIOException("Main machine required!"); + } + } + + public void process(String[] args) throws IOException, BCompoundException { + + MP.print("Arguments: "); + for (int i = 0; i < args.length; i++) { + String string = args[i]; + MP.print(string); + MP.print(" "); + } + println(""); + + handleParameter(args); + + handleMainFileName(); + if (TLC4BGlobals.isTranslate()) { + StopWatch.start(PARSING_TIME); + MP.print("Parsing... "); + translator = new Translator(machineFileNameWithoutFileExtension, + mainfile, this.ltlFormula, this.constantsSetup); + StopWatch.stop(PARSING_TIME); + println("(" + StopWatch.getRunTimeAsString(PARSING_TIME) + "ms)"); + + StopWatch.start(TRANSLATION_TIME); + MP.print("Translating... "); + translator.translate(); + this.tlaModule = translator.getModuleString(); + this.config = translator.getConfigString(); + this.tlcOutputInfo = translator.getTLCOutputInfo(); + StopWatch.stop(TRANSLATION_TIME); + println("(" + StopWatch.getRunTimeAsString(TRANSLATION_TIME) + + "ms)"); + createFiles(); + } + + } + + private void handleMainFileName() { + // the following lines fix incorrect file names + filename = filename.replace("\\", File.separator); + filename = filename.replace("/", File.separator); + if (!filename.toLowerCase().endsWith(".mch") && + !filename.toLowerCase().endsWith(".sys")) { + filename = filename + ".mch"; + } + + mainfile = new File(filename); + if (!mainfile.exists()) { + throw new TLC4BIOException("The file " + mainfile.getPath() + + " does not exist."); + } + try { + mainfile = mainfile.getCanonicalFile(); + } catch (IOException e) { + throw new TLC4BIOException("The file '" + mainfile.getPath() + + "' can not be accessed."); + } + + machineFileNameWithoutFileExtension = mainfile.getName().substring(0, + mainfile.getName().length() - 4); // deleting .mch + + if (buildDir == null) { + buildDir = new File(mainfile.getParentFile(), + machineFileNameWithoutFileExtension); + } + } + + private void createLogFile(Log log) { + if (logFileString != null) { + File logFile = new File(logFileString); + FileWriter fw; + boolean fileExists = logFile.exists(); + try { + fw = new FileWriter(logFile, true); // the true will append the + // new data + if (!fileExists) { + fw.write(log.getCSVFieldNamesLine()); + } + fw.write(log.getCSVValueLine()); + fw.close(); + println("Log file: " + logFile.getAbsolutePath()); + } catch (IOException e) { + new TLC4BIOException(e.getLocalizedMessage()); + } + } + } + + private void createFiles() { + boolean dirCreated = buildDir.mkdir(); + if (dirCreated && TLC4BGlobals.isDeleteOnExit()) { + buildDir.deleteOnExit(); + } + + File moduleFile = createFile(buildDir, + machineFileNameWithoutFileExtension + ".tla", tlaModule, + TLC4BGlobals.isDeleteOnExit()); + if (moduleFile != null) { + println("TLA+ module '" + moduleFile.getAbsolutePath() + + "' created."); + } + + File configFile = createFile(buildDir, + machineFileNameWithoutFileExtension + ".cfg", config, + TLC4BGlobals.isDeleteOnExit()); + if (configFile != null) { + println("Configuration file '" + configFile.getAbsolutePath() + + "' created."); + } + + createStandardModules(); + } + + private void createStandardModules() { + for (STANDARD_MODULES module : translator + .getStandardModuleToBeCreated()) { + createStandardModule(buildDir, module.toString()); + } + } + + private void createStandardModule(File path, String name) { + // standard modules are copied from the standardModules folder to the + // current directory + + File file = new File(path, name + ".tla"); + InputStream is = null; + FileOutputStream fos = null; + try { + + try { + is = new FileInputStream("src/main/resources/standardModules/" + + name + ".tla"); + } catch (FileNotFoundException e) { + is = this + .getClass() + .getClassLoader() + .getResourceAsStream("standardModules/" + name + ".tla"); + } + + if (is == null) { + // should never happen + throw new TranslationException( + "Unable to determine the source of the standard module: " + + name); + } + + fos = new FileOutputStream(file); + + int read = 0; + byte[] bytes = new byte[1024]; + + while ((read = is.read(bytes)) != -1) { + fos.write(bytes, 0, read); + } + println("Standard module '" + file.getName() + "' created."); + } catch (IOException e) { + throw new TLC4BIOException(e.getMessage()); + } finally { + if (TLC4BGlobals.isDeleteOnExit() && file.exists()) { + file.deleteOnExit(); + } + try { + if (is != null) { + is.close(); + } + if (fos != null) { + fos.flush(); + fos.close(); + } + } catch (IOException ex) { + throw new TLC4BIOException(ex.getMessage()); + } + } + } + + public static File createFile(File dir, String fileName, String text, + boolean deleteOnExit) { + + File file = new File(dir, fileName); + boolean exists = false; + try { + exists = file.createNewFile(); + BufferedWriter out = new BufferedWriter(new OutputStreamWriter( + new FileOutputStream(file), "UTF-8")); + out.write(text); + out.close(); + return file; + } catch (UnsupportedEncodingException e1) { + throw new TLC4BIOException(e1.getMessage()); + } catch (FileNotFoundException e1) { + throw new TLC4BIOException(e1.getMessage()); + } catch (IOException e) { + throw new TLC4BIOException(e.getMessage()); + } finally { + if (deleteOnExit && exists) { + file.deleteOnExit(); + } + } + } + + public File getBuildDir() { + return buildDir; + } + + public String getMachineFileNameWithoutFileExtension() { + return machineFileNameWithoutFileExtension; + } + + public File getMainFile(){ + return this.mainfile; + } + +} diff --git a/src/main/java/de/tlc4b/TLC4BGlobals.java b/src/main/java/de/tlc4b/TLC4BGlobals.java index bb216e912c69b0766f9148fc7e2ad59e2ba494bb..af3a7d49f53d46de3d1195b7bd7a507b08e9ba23 100644 --- a/src/main/java/de/tlc4b/TLC4BGlobals.java +++ b/src/main/java/de/tlc4b/TLC4BGlobals.java @@ -1,268 +1,268 @@ -package de.tlc4b; - -public class TLC4BGlobals { - private static int DEFERRED_SET_SIZE; - private static int MAX_INT; - private static int MIN_INT; - - private static boolean checkGOAL; - private static boolean checkDeadlock; - private static boolean checkInvariant; - private static boolean checkAssertion; - private static boolean checkLTL; - private static boolean checkWD; - private static boolean proBconstantsSetup; - private static boolean partialInvariantEvaluation; - private static boolean useSymmetry; - private static boolean printCoverage; - - private static boolean checkOnlyMainAssertions; - - private static boolean deleteFilesOnExit; - - private static boolean runTLC; - private static boolean translate; - private static boolean hideTLCConsoleOutput; - private static boolean createTraceFile; - - private static boolean testingMode; - - private static boolean cleanup; - - private static boolean forceTLCToEvalConstants; - - private static int workers; - - private static boolean runTestscript; - - static { - resetGlobals(); - } - - public static void resetGlobals() { - DEFERRED_SET_SIZE = 3; - MAX_INT = 3; - MIN_INT = -1; - - checkGOAL = true; - checkDeadlock = true; - checkInvariant = true; - checkAssertion = true; - checkLTL = true; - checkWD = true; - partialInvariantEvaluation = false; - useSymmetry = false; - printCoverage = false; - forceTLCToEvalConstants = false; - checkOnlyMainAssertions = false; - - proBconstantsSetup = false; - - cleanup = true; - - workers = 1; - - // for debugging purposes - runTLC = true; - translate = true; - hideTLCConsoleOutput = false; // is mapped to TOOLIO.tool - deleteFilesOnExit = false; // if enabled: deletes all created '.tla', - // '.cfg' files on exit of the JVM. This - // includes - // the created B2TLA standard modules (e.g. - // Relation, but not Naturals etc.). - runTestscript = false; - testingMode = false; - createTraceFile = true; - } - - public static boolean isCreateTraceFile() { - return createTraceFile; - } - - public static void setCreateTraceFile(boolean createTraceFile) { - TLC4BGlobals.createTraceFile = createTraceFile; - } - - public static boolean isRunTestscript() { - return runTestscript; - } - - public static void setRunTestscript(boolean runTestscript) { - TLC4BGlobals.runTestscript = runTestscript; - } - - public static int getDEFERRED_SET_SIZE() { - return DEFERRED_SET_SIZE; - } - - public static int getMAX_INT() { - return MAX_INT; - } - - public static int getMIN_INT() { - return MIN_INT; - } - - public static boolean isGOAL() { - return checkGOAL; - } - - public static boolean isDeadlockCheck() { - return checkDeadlock; - } - - public static boolean isRunTLC() { - return runTLC; - } - - public static boolean isTranslate() { - return translate; - } - - public static boolean isInvariant() { - return checkInvariant; - } - - public static boolean isAssertion() { - return checkAssertion; - } - - public static boolean isCheckLTL() { - return checkLTL; - } - - public static boolean isTool() { - return hideTLCConsoleOutput; - } - - public static boolean isDeleteOnExit() { - return deleteFilesOnExit; - } - - public static boolean isPartialInvariantEvaluation() { - return partialInvariantEvaluation; - } - - public static void setPartialInvariantEvaluation(boolean b) { - partialInvariantEvaluation = b; - } - - public static void setDEFERRED_SET_SIZE(int dEFERRED_SET_SIZE) { - DEFERRED_SET_SIZE = dEFERRED_SET_SIZE; - } - - public static void setMAX_INT(int mAX_INT) { - MAX_INT = mAX_INT; - } - - public static void setMIN_INT(int mIN_INT) { - MIN_INT = mIN_INT; - } - - public static void setGOAL(boolean gOAL) { - checkGOAL = gOAL; - } - - public static void setDeadlockCheck(boolean deadlockCheck) { - TLC4BGlobals.checkDeadlock = deadlockCheck; - } - - public static void setRunTLC(boolean runTLC) { - TLC4BGlobals.runTLC = runTLC; - } - - public static void setTranslate(boolean translate) { - TLC4BGlobals.translate = translate; - } - - public static void setInvariant(boolean invariant) { - TLC4BGlobals.checkInvariant = invariant; - } - - public static void setAssertionCheck(boolean b) { - TLC4BGlobals.checkAssertion = b; - } - - public static void setCheckltl(boolean checkltl) { - TLC4BGlobals.checkLTL = checkltl; - } - - public static void setTool(boolean tool) { - TLC4BGlobals.hideTLCConsoleOutput = tool; - } - - public static void setDeleteOnExit(boolean deleteOnExit) { - TLC4BGlobals.deleteFilesOnExit = deleteOnExit; - } - - public static void setWorkers(int w) { - TLC4BGlobals.workers = w; - } - - public static int getWorkers() { - return TLC4BGlobals.workers; - } - - public static boolean isCleanup() { - return cleanup; - } - - public static void setCleanup(boolean cleanup) { - TLC4BGlobals.cleanup = cleanup; - } - - public static boolean isProBconstantsSetup() { - return proBconstantsSetup; - } - - public static void setProBconstantsSetup(boolean proBconstantsSetup) { - TLC4BGlobals.proBconstantsSetup = proBconstantsSetup; - } - - public static void setTestingMode(boolean b) { - TLC4BGlobals.testingMode = b; - } - - public static boolean getTestingMode() { - return TLC4BGlobals.testingMode; - } - - public static void setWelldefinednessCheck(boolean b) { - TLC4BGlobals.checkWD = b; - } - - public static boolean checkWelldefinedness() { - return TLC4BGlobals.checkWD; - } - - public static boolean isForceTLCToEvalConstants() { - return forceTLCToEvalConstants; - } - - public static void setForceTLCToEvalConstants( - boolean forceTLCToEvalConstants) { - TLC4BGlobals.forceTLCToEvalConstants = forceTLCToEvalConstants; - } - - public static boolean useSymmetry() { - return useSymmetry; - } - - public static void setSymmetryUse(boolean b) { - useSymmetry = b; - } - - public static void setPrintCoverage(boolean b) { - printCoverage = b; - } - - public static boolean isPrintCoverage() { - return printCoverage; - } - - public static boolean isCheckOnlyMainAssertions(){ - return checkOnlyMainAssertions; - } - -} +package de.tlc4b; + +public class TLC4BGlobals { + private static int DEFERRED_SET_SIZE; + private static int MAX_INT; + private static int MIN_INT; + + private static boolean checkGOAL; + private static boolean checkDeadlock; + private static boolean checkInvariant; + private static boolean checkAssertion; + private static boolean checkLTL; + private static boolean checkWD; + private static boolean proBconstantsSetup; + private static boolean partialInvariantEvaluation; + private static boolean useSymmetry; + private static boolean printCoverage; + + private static boolean checkOnlyMainAssertions; + + private static boolean deleteFilesOnExit; + + private static boolean runTLC; + private static boolean translate; + private static boolean hideTLCConsoleOutput; + private static boolean createTraceFile; + + private static boolean testingMode; + + private static boolean cleanup; + + private static boolean forceTLCToEvalConstants; + + private static int workers; + + private static boolean runTestscript; + + static { + resetGlobals(); + } + + public static void resetGlobals() { + DEFERRED_SET_SIZE = 3; + MAX_INT = 3; + MIN_INT = -1; + + checkGOAL = true; + checkDeadlock = true; + checkInvariant = true; + checkAssertion = true; + checkLTL = true; + checkWD = true; + partialInvariantEvaluation = false; + useSymmetry = false; + printCoverage = false; + forceTLCToEvalConstants = false; + checkOnlyMainAssertions = false; + + proBconstantsSetup = false; + + cleanup = true; + + workers = 1; + + // for debugging purposes + runTLC = true; + translate = true; + hideTLCConsoleOutput = false; // is mapped to TOOLIO.tool + deleteFilesOnExit = false; // if enabled: deletes all created '.tla', + // '.cfg' files on exit of the JVM. This + // includes + // the created B2TLA standard modules (e.g. + // Relation, but not Naturals etc.). + runTestscript = false; + testingMode = false; + createTraceFile = true; + } + + public static boolean isCreateTraceFile() { + return createTraceFile; + } + + public static void setCreateTraceFile(boolean createTraceFile) { + TLC4BGlobals.createTraceFile = createTraceFile; + } + + public static boolean isRunTestscript() { + return runTestscript; + } + + public static void setRunTestscript(boolean runTestscript) { + TLC4BGlobals.runTestscript = runTestscript; + } + + public static int getDEFERRED_SET_SIZE() { + return DEFERRED_SET_SIZE; + } + + public static int getMAX_INT() { + return MAX_INT; + } + + public static int getMIN_INT() { + return MIN_INT; + } + + public static boolean isGOAL() { + return checkGOAL; + } + + public static boolean isDeadlockCheck() { + return checkDeadlock; + } + + public static boolean isRunTLC() { + return runTLC; + } + + public static boolean isTranslate() { + return translate; + } + + public static boolean isInvariant() { + return checkInvariant; + } + + public static boolean isAssertion() { + return checkAssertion; + } + + public static boolean isCheckLTL() { + return checkLTL; + } + + public static boolean isTool() { + return hideTLCConsoleOutput; + } + + public static boolean isDeleteOnExit() { + return deleteFilesOnExit; + } + + public static boolean isPartialInvariantEvaluation() { + return partialInvariantEvaluation; + } + + public static void setPartialInvariantEvaluation(boolean b) { + partialInvariantEvaluation = b; + } + + public static void setDEFERRED_SET_SIZE(int dEFERRED_SET_SIZE) { + DEFERRED_SET_SIZE = dEFERRED_SET_SIZE; + } + + public static void setMAX_INT(int mAX_INT) { + MAX_INT = mAX_INT; + } + + public static void setMIN_INT(int mIN_INT) { + MIN_INT = mIN_INT; + } + + public static void setGOAL(boolean gOAL) { + checkGOAL = gOAL; + } + + public static void setDeadlockCheck(boolean deadlockCheck) { + TLC4BGlobals.checkDeadlock = deadlockCheck; + } + + public static void setRunTLC(boolean runTLC) { + TLC4BGlobals.runTLC = runTLC; + } + + public static void setTranslate(boolean translate) { + TLC4BGlobals.translate = translate; + } + + public static void setInvariant(boolean invariant) { + TLC4BGlobals.checkInvariant = invariant; + } + + public static void setAssertionCheck(boolean b) { + TLC4BGlobals.checkAssertion = b; + } + + public static void setCheckltl(boolean checkltl) { + TLC4BGlobals.checkLTL = checkltl; + } + + public static void setTool(boolean tool) { + TLC4BGlobals.hideTLCConsoleOutput = tool; + } + + public static void setDeleteOnExit(boolean deleteOnExit) { + TLC4BGlobals.deleteFilesOnExit = deleteOnExit; + } + + public static void setWorkers(int w) { + TLC4BGlobals.workers = w; + } + + public static int getWorkers() { + return TLC4BGlobals.workers; + } + + public static boolean isCleanup() { + return cleanup; + } + + public static void setCleanup(boolean cleanup) { + TLC4BGlobals.cleanup = cleanup; + } + + public static boolean isProBconstantsSetup() { + return proBconstantsSetup; + } + + public static void setProBconstantsSetup(boolean proBconstantsSetup) { + TLC4BGlobals.proBconstantsSetup = proBconstantsSetup; + } + + public static void setTestingMode(boolean b) { + TLC4BGlobals.testingMode = b; + } + + public static boolean getTestingMode() { + return TLC4BGlobals.testingMode; + } + + public static void setWelldefinednessCheck(boolean b) { + TLC4BGlobals.checkWD = b; + } + + public static boolean checkWelldefinedness() { + return TLC4BGlobals.checkWD; + } + + public static boolean isForceTLCToEvalConstants() { + return forceTLCToEvalConstants; + } + + public static void setForceTLCToEvalConstants( + boolean forceTLCToEvalConstants) { + TLC4BGlobals.forceTLCToEvalConstants = forceTLCToEvalConstants; + } + + public static boolean useSymmetry() { + return useSymmetry; + } + + public static void setSymmetryUse(boolean b) { + useSymmetry = b; + } + + public static void setPrintCoverage(boolean b) { + printCoverage = b; + } + + public static boolean isPrintCoverage() { + return printCoverage; + } + + public static boolean isCheckOnlyMainAssertions(){ + return checkOnlyMainAssertions; + } + +} diff --git a/src/main/java/de/tlc4b/TLCRunner.java b/src/main/java/de/tlc4b/TLCRunner.java index d90fbef8607fc2af0b00f0a85de709df035437be..2b80c04ebdc3d8ab562d5267f289c8c0a7f9deed 100644 --- a/src/main/java/de/tlc4b/TLCRunner.java +++ b/src/main/java/de/tlc4b/TLCRunner.java @@ -1,186 +1,186 @@ -package de.tlc4b; - -import static de.tlc4b.util.StopWatch.Watches.MODEL_CHECKING_TIME; - -import java.io.BufferedReader; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import de.tlc4b.util.StopWatch; -import util.SimpleFilenameToStream; -import util.ToolIO; -import tlc2.TLC; - -public class TLCRunner { - - public static void main(String[] args) { - // this method will be executed in a separate JVM - System.setProperty("apple.awt.UIElement", "true"); - System.out.println("Starting TLC..."); - String path = args[0]; - ToolIO.setUserDir(path); - String[] parameters = new String[args.length - 1]; - for (int i = 0; i < parameters.length; i++) { - parameters[i] = args[i + 1]; - } - try { - TLC.main(parameters); - } catch (UnknownHostException e) { - e.printStackTrace(); - } catch (FileNotFoundException e) { - e.printStackTrace(); - } - } - - private static Process startJVM(final String optionsAsString, - final String mainClass, final String[] arguments) - throws IOException { - - String separator = System.getProperty("file.separator"); - - String jvm = System.getProperty("java.home") + separator + "bin" - + separator + "java"; - String classpath = System.getProperty("java.class.path"); - - List<String> command = new ArrayList<String>(); - command.add(jvm); - command.add("-cp"); - command.add(classpath); - command.add(mainClass); - command.addAll(Arrays.asList(arguments)); - - ProcessBuilder processBuilder = new ProcessBuilder(command); - Process process = processBuilder.start(); - return process; - } - - public static ArrayList<String> runTLCInANewJVM(String machineName, - String path) throws IOException { - ArrayList<String> list = new ArrayList<String>(); - list.add(path); - list.add(machineName); - if (!TLC4BGlobals.isDeadlockCheck()) { - list.add("-deadlock"); - } - - if (TLC4BGlobals.isCheckLTL()) { - list.add("-cleanup"); - } - // list.add("-coverage"); - // list.add("1"); - - String[] args = list.toArray(new String[list.size()]); - final Process p = startJVM("", TLCRunner.class.getCanonicalName(), args); - StreamGobbler stdOut = new StreamGobbler(p.getInputStream()); - stdOut.start(); - StreamGobbler errOut = new StreamGobbler(p.getErrorStream()); - errOut.start(); - try { - p.waitFor(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - return stdOut.getLog(); - } - - public static void runTLC(String machineName, File path) { - StopWatch.start(MODEL_CHECKING_TIME); - MP.println("--------------------------------"); - MP.TLCOutputStream.changeOutputStream(); - ToolIO.setMode(ToolIO.SYSTEM); - - ArrayList<String> list = new ArrayList<String>(); - if (!TLC4BGlobals.isDeadlockCheck()) { - list.add("-deadlock"); - } - if (TLC4BGlobals.getWorkers() > 1) { - list.add("-workers"); - list.add("" + TLC4BGlobals.getWorkers()); - } - - if (TLC4BGlobals.isPrintCoverage()) { - list.add("-nowarning"); - list.add("-coverage"); - list.add("" + 60); - } - - list.add("-maxSetSize"); - list.add("100000000"); - - - // list.add("-config"); - // list.add(machineName + ".cfg"); - list.add(machineName); - ToolIO.setUserDir(path.getPath()); - String[] args = list.toArray(new String[list.size()]); - TLC tlc = new TLC(); - // handle parameters - if (tlc.handleParameters(args)) { - tlc.setResolver(new SimpleFilenameToStream()); - // call the actual processing method - try { - tlc.process(); - } catch (Exception e) { - } - } - // System.setOut(systemOut); - // ArrayList<String> messages = btlcStream.getArrayList(); - closeThreads(); - // return messages; - MP.TLCOutputStream.resetOutputStream(); - MP.println("--------------------------------"); - StopWatch.stop(MODEL_CHECKING_TIME); - } - - private static void closeThreads() { - Set<Thread> threadSet = new HashSet<Thread>(Thread.getAllStackTraces() - .keySet()); - Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]); - for (int i = 0; i < threadArray.length; i++) { - Thread t = threadArray[i]; - // System.out.println(t.getId()+ " "+t.getThreadGroup()); - if (t.getName().equals("RMI Reaper")) { - t.interrupt(); - } - } - // System.exit(0); - } -} - -class StreamGobbler extends Thread { - private InputStream is; - private ArrayList<String> log; - - public ArrayList<String> getLog() { - return log; - } - - StreamGobbler(InputStream is) { - this.is = is; - this.log = new ArrayList<String>(); - } - - public void run() { - try { - InputStreamReader isr = new InputStreamReader(is, "UTF-8"); - BufferedReader br = new BufferedReader(isr); - String line = null; - while ((line = br.readLine()) != null) { - System.out.println("> " + line); - log.add(line); - } - - } catch (IOException e) { - e.printStackTrace(); - } - } -} +package de.tlc4b; + +import static de.tlc4b.util.StopWatch.Watches.MODEL_CHECKING_TIME; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import de.tlc4b.util.StopWatch; +import util.SimpleFilenameToStream; +import util.ToolIO; +import tlc2.TLC; + +public class TLCRunner { + + public static void main(String[] args) { + // this method will be executed in a separate JVM + System.setProperty("apple.awt.UIElement", "true"); + System.out.println("Starting TLC..."); + String path = args[0]; + ToolIO.setUserDir(path); + String[] parameters = new String[args.length - 1]; + for (int i = 0; i < parameters.length; i++) { + parameters[i] = args[i + 1]; + } + try { + TLC.main(parameters); + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (FileNotFoundException e) { + e.printStackTrace(); + } + } + + private static Process startJVM(final String optionsAsString, + final String mainClass, final String[] arguments) + throws IOException { + + String separator = System.getProperty("file.separator"); + + String jvm = System.getProperty("java.home") + separator + "bin" + + separator + "java"; + String classpath = System.getProperty("java.class.path"); + + List<String> command = new ArrayList<String>(); + command.add(jvm); + command.add("-cp"); + command.add(classpath); + command.add(mainClass); + command.addAll(Arrays.asList(arguments)); + + ProcessBuilder processBuilder = new ProcessBuilder(command); + Process process = processBuilder.start(); + return process; + } + + public static ArrayList<String> runTLCInANewJVM(String machineName, + String path) throws IOException { + ArrayList<String> list = new ArrayList<String>(); + list.add(path); + list.add(machineName); + if (!TLC4BGlobals.isDeadlockCheck()) { + list.add("-deadlock"); + } + + if (TLC4BGlobals.isCheckLTL()) { + list.add("-cleanup"); + } + // list.add("-coverage"); + // list.add("1"); + + String[] args = list.toArray(new String[list.size()]); + final Process p = startJVM("", TLCRunner.class.getCanonicalName(), args); + StreamGobbler stdOut = new StreamGobbler(p.getInputStream()); + stdOut.start(); + StreamGobbler errOut = new StreamGobbler(p.getErrorStream()); + errOut.start(); + try { + p.waitFor(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return stdOut.getLog(); + } + + public static void runTLC(String machineName, File path) { + StopWatch.start(MODEL_CHECKING_TIME); + MP.println("--------------------------------"); + MP.TLCOutputStream.changeOutputStream(); + ToolIO.setMode(ToolIO.SYSTEM); + + ArrayList<String> list = new ArrayList<String>(); + if (!TLC4BGlobals.isDeadlockCheck()) { + list.add("-deadlock"); + } + if (TLC4BGlobals.getWorkers() > 1) { + list.add("-workers"); + list.add("" + TLC4BGlobals.getWorkers()); + } + + if (TLC4BGlobals.isPrintCoverage()) { + list.add("-nowarning"); + list.add("-coverage"); + list.add("" + 60); + } + + list.add("-maxSetSize"); + list.add("100000000"); + + + // list.add("-config"); + // list.add(machineName + ".cfg"); + list.add(machineName); + ToolIO.setUserDir(path.getPath()); + String[] args = list.toArray(new String[list.size()]); + TLC tlc = new TLC(); + // handle parameters + if (tlc.handleParameters(args)) { + tlc.setResolver(new SimpleFilenameToStream()); + // call the actual processing method + try { + tlc.process(); + } catch (Exception e) { + } + } + // System.setOut(systemOut); + // ArrayList<String> messages = btlcStream.getArrayList(); + closeThreads(); + // return messages; + MP.TLCOutputStream.resetOutputStream(); + MP.println("--------------------------------"); + StopWatch.stop(MODEL_CHECKING_TIME); + } + + private static void closeThreads() { + Set<Thread> threadSet = new HashSet<Thread>(Thread.getAllStackTraces() + .keySet()); + Thread[] threadArray = threadSet.toArray(new Thread[threadSet.size()]); + for (int i = 0; i < threadArray.length; i++) { + Thread t = threadArray[i]; + // System.out.println(t.getId()+ " "+t.getThreadGroup()); + if (t.getName().equals("RMI Reaper")) { + t.interrupt(); + } + } + // System.exit(0); + } +} + +class StreamGobbler extends Thread { + private InputStream is; + private ArrayList<String> log; + + public ArrayList<String> getLog() { + return log; + } + + StreamGobbler(InputStream is) { + this.is = is; + this.log = new ArrayList<String>(); + } + + public void run() { + try { + InputStreamReader isr = new InputStreamReader(is, "UTF-8"); + BufferedReader br = new BufferedReader(isr); + String line = null; + while ((line = br.readLine()) != null) { + System.out.println("> " + line); + log.add(line); + } + + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/main/java/de/tlc4b/Translator.java b/src/main/java/de/tlc4b/Translator.java index da8bd947a67919c6f315c29376d46ba93abea9c4..c177a4b3c88c0cd91eb6aaa1739b9be6afb50e44 100644 --- a/src/main/java/de/tlc4b/Translator.java +++ b/src/main/java/de/tlc4b/Translator.java @@ -1,219 +1,204 @@ -package de.tlc4b; - -import java.io.File; -import java.io.IOException; -import java.util.HashSet; -import java.util.Map; - -import de.be4.classicalb.core.parser.BParser; -import de.be4.classicalb.core.parser.analysis.prolog.RecursiveMachineLoader; -import de.be4.classicalb.core.parser.exceptions.BCompoundException; -import de.be4.classicalb.core.parser.node.APredicateParseUnit; -import de.be4.classicalb.core.parser.node.PPredicate; -import de.be4.classicalb.core.parser.node.Start; -import de.tlc4b.analysis.ConstantsEliminator; -import de.tlc4b.analysis.ConstantsEvaluator; -import de.tlc4b.analysis.DefinitionsAnalyser; -import de.tlc4b.analysis.MachineContext; -import de.tlc4b.analysis.UnsupportedConstructsFinder; -import de.tlc4b.analysis.PrecedenceCollector; -import de.tlc4b.analysis.PrimedNodesMarker; -import de.tlc4b.analysis.Renamer; -import de.tlc4b.analysis.Typechecker; -import de.tlc4b.analysis.UsedStandardModules; -import de.tlc4b.analysis.UsedStandardModules.STANDARD_MODULES; -import de.tlc4b.analysis.transformation.DefinitionsEliminator; -import de.tlc4b.analysis.transformation.SeesEliminator; -import de.tlc4b.analysis.transformation.SetComprehensionOptimizer; -import de.tlc4b.analysis.typerestriction.TypeRestrictor; -import de.tlc4b.analysis.unchangedvariables.InvariantPreservationAnalysis; -import de.tlc4b.analysis.unchangedvariables.UnchangedVariablesFinder; -import de.tlc4b.exceptions.TLC4BIOException; -import de.tlc4b.prettyprint.TLAPrinter; -import de.tlc4b.tla.Generator; -import de.tlc4b.tlc.TLCOutputInfo; -import de.tlc4b.util.Ast2String; - -public class Translator { - - private String machineString; - private Start start; - private Map<String, Start> parsedMachines; - private String moduleString; - private String configString; - private String machineName; - private String ltlFormula; - private PPredicate constantsSetup; - private HashSet<STANDARD_MODULES> standardModulesToBeCreated; - private TLCOutputInfo tlcOutputInfo; - private String translatedLTLFormula; - - public Translator(String machineString) throws BCompoundException { - this.machineString = machineString; - BParser parser = new BParser("Testing"); - start = parser.parse(machineString, false); - final Ast2String ast2String2 = new Ast2String(); - start.apply(ast2String2); - // System.out.println(ast2String2.toString()); - } - - public Translator(String machineString, String ltlFormula) throws BCompoundException { - this.machineString = machineString; - this.ltlFormula = ltlFormula; - BParser parser = new BParser("Testing"); - start = parser.parse(machineString, false); - final Ast2String ast2String2 = new Ast2String(); - start.apply(ast2String2); - // System.out.println(ast2String2.toString()); - } - - public Translator(String machineName, File machineFile, String ltlFormula, String constantSetup) - throws BCompoundException, IOException { - this.machineName = machineName; - this.ltlFormula = ltlFormula; - - BParser parser = new BParser(machineName); - try { - start = parser.parseFile(machineFile, false); - } catch (NoClassDefFoundError e) { - throw new TLC4BIOException("Definitions file cannot be found."); - } - - // Definitions of definitions files are injected in the ast of the main - // machine - final RecursiveMachineLoader rml = new RecursiveMachineLoader(machineFile.getParent(), - parser.getContentProvider()); - rml.loadAllMachines(machineFile, start, parser.getDefinitions()); - - parsedMachines = rml.getParsedMachines(); - - if (constantSetup != null) { - BParser con = new BParser(); - Start start2 = null; - try { - start2 = con.parse("#FORMULA " + constantSetup, false); - } catch (BCompoundException e) { - System.err.println("An error occured while parsing the constants setup predicate."); - throw e; - } - - APredicateParseUnit parseUnit = (APredicateParseUnit) start2.getPParseUnit(); - this.constantsSetup = parseUnit.getPredicate(); - - final Ast2String ast2String2 = new Ast2String(); - start2.apply(ast2String2); - // System.out.println(ast2String2.toString()); - } - - final Ast2String ast2String2 = new Ast2String(); - start.apply(ast2String2); - // System.out.println(ast2String2.toString()); - } - - public void translate() { - UnsupportedConstructsFinder unsupportedConstructsFinder = new UnsupportedConstructsFinder(start); - unsupportedConstructsFinder.find(); - - // ast transformation - SeesEliminator.eliminateSeesClauses(start, parsedMachines); - - DefinitionsEliminator.eliminateDefinitions(start); - - // TODO move set comprehension optimizer behind the type checker - SetComprehensionOptimizer.optimizeSetComprehensions(start); - - MachineContext machineContext = new MachineContext(machineName, start); - if (ltlFormula != null) { - machineContext.addLTLFromula(this.ltlFormula); - } - if (this.constantsSetup != null) { - machineContext.setConstantSetupPredicate(constantsSetup); - } - machineContext.analyseMachine(); - - this.machineName = machineContext.getMachineName(); - if (machineContext.machineContainsOperations()) { - TLC4BGlobals.setPrintCoverage(true); - } - - Typechecker typechecker = new Typechecker(machineContext); - UnchangedVariablesFinder unchangedVariablesFinder = new UnchangedVariablesFinder(machineContext); - - ConstantsEliminator constantsEliminator = new ConstantsEliminator(machineContext); - constantsEliminator.start(); - - ConstantsEvaluator constantsEvaluator = new ConstantsEvaluator(machineContext); - - InvariantPreservationAnalysis invariantPreservationAnalysis = new InvariantPreservationAnalysis(machineContext, - constantsEvaluator.getInvariantList(), unchangedVariablesFinder); - - TypeRestrictor typeRestrictor = new TypeRestrictor(start, machineContext, typechecker, constantsEvaluator); - - PrecedenceCollector precedenceCollector = new PrecedenceCollector(start, typechecker, machineContext, - typeRestrictor); - - DefinitionsAnalyser deferredSetSizeCalculator = new DefinitionsAnalyser(machineContext); - - Generator generator = new Generator(machineContext, typeRestrictor, constantsEvaluator, - deferredSetSizeCalculator, typechecker); - generator.generate(); - - UsedStandardModules usedModules = new UsedStandardModules(start, typechecker, typeRestrictor, - generator.getTlaModule()); - - standardModulesToBeCreated = usedModules.getStandardModulesToBeCreated(); - - PrimedNodesMarker primedNodesMarker = new PrimedNodesMarker(generator.getTlaModule().getOperations(), - machineContext); - primedNodesMarker.start(); - - Renamer renamer = new Renamer(machineContext); - TLAPrinter printer = new TLAPrinter(machineContext, typechecker, unchangedVariablesFinder, precedenceCollector, - usedModules, typeRestrictor, generator.getTlaModule(), generator.getConfigFile(), primedNodesMarker, - renamer, invariantPreservationAnalysis); - printer.start(); - moduleString = printer.getStringbuilder().toString(); - configString = printer.getConfigString().toString(); - translatedLTLFormula = printer.geTranslatedLTLFormula(); - - tlcOutputInfo = new TLCOutputInfo(machineContext, renamer, typechecker, generator.getTlaModule(), - generator.getConfigFile()); - } - - public String getMachineString() { - return machineString; - } - - public String getModuleString() { - return moduleString; - } - - public String getConfigString() { - return configString; - } - - public Start getStart() { - return start; - } - - public String getMachineName() { - return machineName; - } - - public TLCOutputInfo getTLCOutputInfo() { - return tlcOutputInfo; - } - - public boolean containsUsedStandardModule(STANDARD_MODULES module) { - return standardModulesToBeCreated.contains(module); - } - - public HashSet<UsedStandardModules.STANDARD_MODULES> getStandardModuleToBeCreated() { - return standardModulesToBeCreated; - } - - public String getTranslatedLTLFormula() { - return translatedLTLFormula; - } - -} +package de.tlc4b; + +import java.io.File; +import java.io.IOException; +import java.util.HashSet; +import java.util.Map; + +import de.be4.classicalb.core.parser.BParser; +import de.be4.classicalb.core.parser.analysis.prolog.RecursiveMachineLoader; +import de.be4.classicalb.core.parser.exceptions.BCompoundException; +import de.be4.classicalb.core.parser.node.APredicateParseUnit; +import de.be4.classicalb.core.parser.node.PPredicate; +import de.be4.classicalb.core.parser.node.Start; +import de.tlc4b.analysis.ConstantsEliminator; +import de.tlc4b.analysis.ConstantsEvaluator; +import de.tlc4b.analysis.DefinitionsAnalyser; +import de.tlc4b.analysis.MachineContext; +import de.tlc4b.analysis.PrecedenceCollector; +import de.tlc4b.analysis.PrimedNodesMarker; +import de.tlc4b.analysis.Renamer; +import de.tlc4b.analysis.Typechecker; +import de.tlc4b.analysis.UnsupportedConstructsFinder; +import de.tlc4b.analysis.UsedStandardModules; +import de.tlc4b.analysis.UsedStandardModules.STANDARD_MODULES; +import de.tlc4b.analysis.transformation.DefinitionsEliminator; +import de.tlc4b.analysis.transformation.SeesEliminator; +import de.tlc4b.analysis.transformation.SetComprehensionOptimizer; +import de.tlc4b.analysis.typerestriction.TypeRestrictor; +import de.tlc4b.analysis.unchangedvariables.InvariantPreservationAnalysis; +import de.tlc4b.analysis.unchangedvariables.UnchangedVariablesFinder; +import de.tlc4b.exceptions.TLC4BIOException; +import de.tlc4b.prettyprint.TLAPrinter; +import de.tlc4b.tla.Generator; +import de.tlc4b.tlc.TLCOutputInfo; + +public class Translator { + + private String machineString; + private Start start; + private Map<String, Start> parsedMachines; + private String moduleString; + private String configString; + private String machineName; + private String ltlFormula; + private PPredicate constantsSetup; + private HashSet<STANDARD_MODULES> standardModulesToBeCreated; + private TLCOutputInfo tlcOutputInfo; + private String translatedLTLFormula; + + public Translator(String machineString) throws BCompoundException { + this.machineString = machineString; + BParser parser = new BParser("Testing"); + start = parser.parse(machineString, false); + } + + public Translator(String machineString, String ltlFormula) throws BCompoundException { + this.machineString = machineString; + this.ltlFormula = ltlFormula; + BParser parser = new BParser("Testing"); + start = parser.parse(machineString, false); + } + + public Translator(String machineName, File machineFile, String ltlFormula, String constantSetup) + throws BCompoundException, IOException { + this.machineName = machineName; + this.ltlFormula = ltlFormula; + + BParser parser = new BParser(machineName); + try { + start = parser.parseFile(machineFile, false); + } catch (NoClassDefFoundError e) { + throw new TLC4BIOException("Definitions file cannot be found."); + } + + // Definitions of definitions files are injected in the ast of the main + // machine + final RecursiveMachineLoader rml = new RecursiveMachineLoader(machineFile.getParent(), + parser.getContentProvider()); + rml.loadAllMachines(machineFile, start, parser.getDefinitions()); + + parsedMachines = rml.getParsedMachines(); + + if (constantSetup != null) { + BParser con = new BParser(); + Start start2 = null; + try { + start2 = con.parse("#FORMULA " + constantSetup, false); + } catch (BCompoundException e) { + System.err.println("An error occured while parsing the constants setup predicate."); + throw e; + } + + APredicateParseUnit parseUnit = (APredicateParseUnit) start2.getPParseUnit(); + this.constantsSetup = parseUnit.getPredicate(); + } + } + + public void translate() { + UnsupportedConstructsFinder unsupportedConstructsFinder = new UnsupportedConstructsFinder(start); + unsupportedConstructsFinder.find(); + + // ast transformation + SeesEliminator.eliminateSeesClauses(start, parsedMachines); + + DefinitionsEliminator.eliminateDefinitions(start); + + // TODO move set comprehension optimizer behind the type checker + SetComprehensionOptimizer.optimizeSetComprehensions(start); + + MachineContext machineContext = new MachineContext(machineName, start); + if (ltlFormula != null) { + machineContext.addLTLFromula(this.ltlFormula); + } + if (this.constantsSetup != null) { + machineContext.setConstantSetupPredicate(constantsSetup); + } + machineContext.analyseMachine(); + + this.machineName = machineContext.getMachineName(); + if (machineContext.machineContainsOperations()) { + TLC4BGlobals.setPrintCoverage(true); + } + + Typechecker typechecker = new Typechecker(machineContext); + UnchangedVariablesFinder unchangedVariablesFinder = new UnchangedVariablesFinder(machineContext); + + ConstantsEliminator constantsEliminator = new ConstantsEliminator(machineContext); + constantsEliminator.start(); + + ConstantsEvaluator constantsEvaluator = new ConstantsEvaluator(machineContext); + + InvariantPreservationAnalysis invariantPreservationAnalysis = new InvariantPreservationAnalysis(machineContext, + constantsEvaluator.getInvariantList(), unchangedVariablesFinder); + + TypeRestrictor typeRestrictor = new TypeRestrictor(start, machineContext, typechecker, constantsEvaluator); + + PrecedenceCollector precedenceCollector = new PrecedenceCollector(start, typechecker, machineContext, + typeRestrictor); + + DefinitionsAnalyser deferredSetSizeCalculator = new DefinitionsAnalyser(machineContext); + + Generator generator = new Generator(machineContext, typeRestrictor, constantsEvaluator, + deferredSetSizeCalculator, typechecker); + generator.generate(); + + UsedStandardModules usedModules = new UsedStandardModules(start, typechecker, typeRestrictor, + generator.getTlaModule()); + + standardModulesToBeCreated = usedModules.getStandardModulesToBeCreated(); + + PrimedNodesMarker primedNodesMarker = new PrimedNodesMarker(generator.getTlaModule().getOperations(), + machineContext); + primedNodesMarker.start(); + + Renamer renamer = new Renamer(machineContext); + TLAPrinter printer = new TLAPrinter(machineContext, typechecker, unchangedVariablesFinder, precedenceCollector, + usedModules, typeRestrictor, generator.getTlaModule(), generator.getConfigFile(), primedNodesMarker, + renamer, invariantPreservationAnalysis); + printer.start(); + moduleString = printer.getStringbuilder().toString(); + configString = printer.getConfigString().toString(); + translatedLTLFormula = printer.geTranslatedLTLFormula(); + + tlcOutputInfo = new TLCOutputInfo(machineContext, renamer, typechecker, generator.getTlaModule(), + generator.getConfigFile()); + } + + public String getMachineString() { + return machineString; + } + + public String getModuleString() { + return moduleString; + } + + public String getConfigString() { + return configString; + } + + public Start getStart() { + return start; + } + + public String getMachineName() { + return machineName; + } + + public TLCOutputInfo getTLCOutputInfo() { + return tlcOutputInfo; + } + + public boolean containsUsedStandardModule(STANDARD_MODULES module) { + return standardModulesToBeCreated.contains(module); + } + + public HashSet<UsedStandardModules.STANDARD_MODULES> getStandardModuleToBeCreated() { + return standardModulesToBeCreated; + } + + public String getTranslatedLTLFormula() { + return translatedLTLFormula; + } + +} diff --git a/src/main/java/de/tlc4b/analysis/ConstantsEvaluator.java b/src/main/java/de/tlc4b/analysis/ConstantsEvaluator.java index a373f1fed0781337f2b400b6e36fdb17155b4f9f..59da5145eab85be4221e88ba0b802a8c0b4607e1 100644 --- a/src/main/java/de/tlc4b/analysis/ConstantsEvaluator.java +++ b/src/main/java/de/tlc4b/analysis/ConstantsEvaluator.java @@ -1,357 +1,357 @@ -package de.tlc4b.analysis; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.LinkedHashMap; - -import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; -import de.be4.classicalb.core.parser.node.ACardExpression; -import de.be4.classicalb.core.parser.node.AConjunctPredicate; -import de.be4.classicalb.core.parser.node.AConstraintsMachineClause; -import de.be4.classicalb.core.parser.node.ADisjunctPredicate; -import de.be4.classicalb.core.parser.node.AEqualPredicate; -import de.be4.classicalb.core.parser.node.AIdentifierExpression; -import de.be4.classicalb.core.parser.node.AIntegerExpression; -import de.be4.classicalb.core.parser.node.AInvariantMachineClause; -import de.be4.classicalb.core.parser.node.APredicateParseUnit; -import de.be4.classicalb.core.parser.node.APropertiesMachineClause; -import de.be4.classicalb.core.parser.node.Node; -import de.be4.classicalb.core.parser.node.PExpression; -import de.be4.classicalb.core.parser.node.PPredicate; - -/** - * In this class the order of constants is determined. Constants can depend on - * other constants: as an example in the expression k = k2 + 1 the value of the - * constant k depends on k2. Constants are translated as definitions to TLA+ and - * these definitions must be in order. - * - */ -public class ConstantsEvaluator extends DepthFirstAdapter { - private LinkedHashMap<Node, HashSet<Node>> dependsOnIdentifierTable; - private MachineContext machineContext; - private ValuesOfIdentifierFinder valuesOfConstantsFinder; - private HashMap<Node, Integer> integerValueTable; - private final ArrayList<Node> propertiesList; - private final ArrayList<Node> invariantList; - - private LinkedHashMap<Node, Node> valueOfIdentifier; - - public Node getValueOfConstant(Node con) { - return valueOfIdentifier.get(con); - } - - public ArrayList<Node> getInvariantList() { - return this.invariantList; - } - - public ArrayList<Node> getPropertiesList() { - return this.propertiesList; - } - - public LinkedHashMap<Node, Node> getValueOfIdentifierMap() { - return valueOfIdentifier; - } - - public Integer getIntValue(Node node) { - return integerValueTable.get(node); - } - - public ArrayList<PExpression> getRangeOfIdentifier(Node con) { - return valuesOfConstantsFinder.rangeOfIdentifierTable.get(con); - } - - public ConstantsEvaluator(MachineContext machineContext) { - this.dependsOnIdentifierTable = new LinkedHashMap<Node, HashSet<Node>>(); - this.integerValueTable = new HashMap<Node, Integer>(); - this.machineContext = machineContext; - this.propertiesList = new ArrayList<Node>(); - this.invariantList = new ArrayList<Node>(); - - ConstantsInTreeFinder constantInTreeFinder = new ConstantsInTreeFinder(); - - if (machineContext.getConstantsSetup() != null) { - machineContext.getConstantsSetup().apply(constantInTreeFinder); - } - - APropertiesMachineClause properties = machineContext - .getPropertiesMachineClause(); - if (null != properties) { - properties.apply(constantInTreeFinder); - } - - AConstraintsMachineClause constraints = machineContext - .getConstraintMachineClause(); - if (null != constraints) { - constraints.apply(constantInTreeFinder); - } - - this.valuesOfConstantsFinder = new ValuesOfIdentifierFinder(); - - this.valueOfIdentifier = new LinkedHashMap<Node, Node>(); - - evalIdentifier(machineContext.getConstants().values()); - evalIdentifier(machineContext.getScalarParameter().values()); - } - - private void evalIdentifier(Collection<Node> ids) { - boolean newRun = true; - while (newRun) { - newRun = false; - Iterator<Node> itr = ids.iterator(); - while (itr.hasNext()) { - Node id = itr.next(); - if (valueOfIdentifier.containsKey(id)) - continue; - HashSet<Node> idValues = valuesOfConstantsFinder.valuesOfIdentifierTable - .get(id); - - for (Node val : idValues) { - HashSet<Node> idsInVal = dependsOnIdentifierTable.get(val); - idsInVal.remove(id); - if (idsInVal.size() == 0) { - valueOfIdentifier.put(id, val); - removeIdentifier(ids, id); - newRun = true; - break; - } - } - } - } - } - - private void removeIdentifier(Collection<Node> collection, - Node identifierToRemove) { - Iterator<Node> itr = collection.iterator(); - while (itr.hasNext()) { - Node id = itr.next(); - HashSet<Node> idValues = valuesOfConstantsFinder.valuesOfIdentifierTable - .get(id); - for (Node val : idValues) { - HashSet<Node> idsInVal = dependsOnIdentifierTable.get(val); - idsInVal.remove(identifierToRemove); - } - } - } - - class ConstantsInTreeFinder extends DepthFirstAdapter { - @Override - public void defaultIn(Node node) { - dependsOnIdentifierTable.put(node, new HashSet<Node>()); - } - - @Override - public void defaultOut(Node node) { - HashSet<Node> set = dependsOnIdentifierTable.get(node); - Node parent = node.parent(); - HashSet<Node> parentSet = dependsOnIdentifierTable.get(parent); - if (parentSet != null) { - parentSet.addAll(set); - } - - } - - @Override - public void caseAPropertiesMachineClause(APropertiesMachineClause node) { - defaultIn(node); - node.getPredicates().apply(this); - } - - @Override - public void caseAPredicateParseUnit(APredicateParseUnit node) { - defaultIn(node); - node.getPredicate().apply(this); - } - - @Override - public void caseAConstraintsMachineClause(AConstraintsMachineClause node) { - defaultIn(node); - node.getPredicates().apply(this); - } - - @Override - public void caseAIdentifierExpression(AIdentifierExpression node) { - defaultIn(node); - Node refNode = machineContext.getReferences().get(node); - if (machineContext.getConstants().containsValue(refNode)) { - HashSet<Node> set = dependsOnIdentifierTable.get(node); - set.add(refNode); - } - // it must be a bounded variable - defaultOut(node); - } - } - - class ValuesOfIdentifierFinder extends DepthFirstAdapter { - private Hashtable<Node, HashSet<Node>> valuesOfIdentifierTable; - private Hashtable<Node, ArrayList<PExpression>> rangeOfIdentifierTable; - private HashSet<Node> identifiers; - - public ValuesOfIdentifierFinder() { - this.valuesOfIdentifierTable = new Hashtable<Node, HashSet<Node>>(); - this.rangeOfIdentifierTable = new Hashtable<Node, ArrayList<PExpression>>(); - - this.identifiers = new HashSet<Node>(); - this.identifiers.addAll(machineContext.getConstants().values()); - this.identifiers.addAll(machineContext.getScalarParameter() - .values()); - - Iterator<Node> itr = identifiers.iterator(); - while (itr.hasNext()) { - Node id = itr.next(); - valuesOfIdentifierTable.put(id, new HashSet<Node>()); - rangeOfIdentifierTable.put(id, new ArrayList<PExpression>()); - } - - Node constraints = machineContext.getConstraintMachineClause(); - if (constraints != null) { - analysePredicate( - ((AConstraintsMachineClause) constraints) - .getPredicates(), - false); - } - - if (machineContext.getConstantsSetup() != null) { - if (machineContext.getConstantsSetup() instanceof ADisjunctPredicate) { - analyseConstantSetupPredicate(machineContext - .getConstantsSetup()); - for (Node con : this.identifiers) { - ArrayList<PExpression> list = rangeOfIdentifierTable - .get(con); - if (list.size() == 1) { - // there only one value for the constant con, hence - // con remains a constant - valuesOfIdentifierTable.get(con).add(list.get(0)); - } - } - } else { - analysePredicate(machineContext.getConstantsSetup(), true); - } - - } - - Node properties = machineContext.getPropertiesMachineClause(); - if (properties != null) { - PPredicate predicate = (PPredicate) ((APropertiesMachineClause) properties) - .getPredicates(); - analysePredicate(predicate, true); - - } - - Node invariantClause = machineContext.getInvariantMachineClause(); - if (invariantClause != null) { - analyseInvariantPredicate(((AInvariantMachineClause) invariantClause) - .getPredicates()); - } - } - - private void analyseConstantSetupPredicate(PPredicate constantsSetup) { - if (constantsSetup instanceof ADisjunctPredicate) { - ADisjunctPredicate dis = (ADisjunctPredicate) constantsSetup; - analyseConstantSetupPredicate(dis.getLeft()); - analyseConstantSetupPredicate(dis.getRight()); - } else if (constantsSetup instanceof AConjunctPredicate) { - AConjunctPredicate con = (AConjunctPredicate) constantsSetup; - analyseConstantSetupPredicate(con.getLeft()); - analyseConstantSetupPredicate(con.getRight()); - } else if (constantsSetup instanceof AEqualPredicate) { - AEqualPredicate equals = (AEqualPredicate) constantsSetup; - PExpression left = equals.getLeft(); - Node left_ref = machineContext.getReferences().get(left); - if (rangeOfIdentifierTable.containsKey(left_ref)) { - // TODO - } - ArrayList<PExpression> currentRange = rangeOfIdentifierTable - .get(left_ref); - boolean found = false; - for (PExpression pExpression : currentRange) { - if (pExpression.toString().equals( - equals.getRight().toString())) { - found = true; - } - } - if (found == false) { - currentRange.add((PExpression) equals.getRight()); - } - - } - - } - - private void analyseInvariantPredicate(Node node) { - if (node instanceof AConjunctPredicate) { - AConjunctPredicate conjunction = (AConjunctPredicate) node; - analyseInvariantPredicate(conjunction.getLeft()); - analyseInvariantPredicate(conjunction.getRight()); - return; - } - - invariantList.add(node); - } - - private void analysePredicate(Node node, boolean isProperties) { - if (node instanceof AEqualPredicate) { - analyseEqualsPredicate((AEqualPredicate) node); - } else if (node instanceof AConjunctPredicate) { - AConjunctPredicate conjunction = (AConjunctPredicate) node; - analysePredicate(conjunction.getLeft(), isProperties); - analysePredicate(conjunction.getRight(), isProperties); - return; - } - - if (isProperties) { - propertiesList.add((PPredicate) node); - } - } - - private void analyseEqualsPredicate(AEqualPredicate node) { - PExpression left = node.getLeft(); - Node left_ref = machineContext.getReferences().get(left); - PExpression right = node.getRight(); - Node right_ref = machineContext.getReferences().get(right); - - if (left instanceof ACardExpression) { - Node ref = machineContext.getReferences().get( - ((ACardExpression) left).getExpression()); - if (!machineContext.getConstants().containsValue(ref)) { - try { - AIntegerExpression intExpr = (AIntegerExpression) right; - int size = Integer.parseInt(intExpr.getLiteral() - .getText()); - integerValueTable.put(ref, size); - } catch (ClassCastException e) { - } - } - } - - if (right instanceof ACardExpression) { - Node ref = machineContext.getReferences().get( - ((ACardExpression) right).getExpression()); - if (!machineContext.getConstants().containsValue(ref)) { - try { - AIntegerExpression intExpr = (AIntegerExpression) left; - int size = Integer.parseInt(intExpr.getLiteral() - .getText()); - integerValueTable.put(ref, size); - } catch (ClassCastException e) { - } - } - } - - if (identifiers.contains(left_ref)) { - valuesOfIdentifierTable.get(left_ref).add(right); - } - - if (identifiers.contains(right_ref)) { - valuesOfIdentifierTable.get(right_ref).add(left); - } - return; - - } - - } - -} +package de.tlc4b.analysis; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.LinkedHashMap; + +import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; +import de.be4.classicalb.core.parser.node.ACardExpression; +import de.be4.classicalb.core.parser.node.AConjunctPredicate; +import de.be4.classicalb.core.parser.node.AConstraintsMachineClause; +import de.be4.classicalb.core.parser.node.ADisjunctPredicate; +import de.be4.classicalb.core.parser.node.AEqualPredicate; +import de.be4.classicalb.core.parser.node.AIdentifierExpression; +import de.be4.classicalb.core.parser.node.AIntegerExpression; +import de.be4.classicalb.core.parser.node.AInvariantMachineClause; +import de.be4.classicalb.core.parser.node.APredicateParseUnit; +import de.be4.classicalb.core.parser.node.APropertiesMachineClause; +import de.be4.classicalb.core.parser.node.Node; +import de.be4.classicalb.core.parser.node.PExpression; +import de.be4.classicalb.core.parser.node.PPredicate; + +/** + * In this class the order of constants is determined. Constants can depend on + * other constants: as an example in the expression k = k2 + 1 the value of the + * constant k depends on k2. Constants are translated as definitions to TLA+ and + * these definitions must be in order. + * + */ +public class ConstantsEvaluator extends DepthFirstAdapter { + private LinkedHashMap<Node, HashSet<Node>> dependsOnIdentifierTable; + private MachineContext machineContext; + private ValuesOfIdentifierFinder valuesOfConstantsFinder; + private HashMap<Node, Integer> integerValueTable; + private final ArrayList<Node> propertiesList; + private final ArrayList<Node> invariantList; + + private LinkedHashMap<Node, Node> valueOfIdentifier; + + public Node getValueOfConstant(Node con) { + return valueOfIdentifier.get(con); + } + + public ArrayList<Node> getInvariantList() { + return this.invariantList; + } + + public ArrayList<Node> getPropertiesList() { + return this.propertiesList; + } + + public LinkedHashMap<Node, Node> getValueOfIdentifierMap() { + return valueOfIdentifier; + } + + public Integer getIntValue(Node node) { + return integerValueTable.get(node); + } + + public ArrayList<PExpression> getRangeOfIdentifier(Node con) { + return valuesOfConstantsFinder.rangeOfIdentifierTable.get(con); + } + + public ConstantsEvaluator(MachineContext machineContext) { + this.dependsOnIdentifierTable = new LinkedHashMap<Node, HashSet<Node>>(); + this.integerValueTable = new HashMap<Node, Integer>(); + this.machineContext = machineContext; + this.propertiesList = new ArrayList<Node>(); + this.invariantList = new ArrayList<Node>(); + + ConstantsInTreeFinder constantInTreeFinder = new ConstantsInTreeFinder(); + + if (machineContext.getConstantsSetup() != null) { + machineContext.getConstantsSetup().apply(constantInTreeFinder); + } + + APropertiesMachineClause properties = machineContext + .getPropertiesMachineClause(); + if (null != properties) { + properties.apply(constantInTreeFinder); + } + + AConstraintsMachineClause constraints = machineContext + .getConstraintMachineClause(); + if (null != constraints) { + constraints.apply(constantInTreeFinder); + } + + this.valuesOfConstantsFinder = new ValuesOfIdentifierFinder(); + + this.valueOfIdentifier = new LinkedHashMap<Node, Node>(); + + evalIdentifier(machineContext.getConstants().values()); + evalIdentifier(machineContext.getScalarParameter().values()); + } + + private void evalIdentifier(Collection<Node> ids) { + boolean newRun = true; + while (newRun) { + newRun = false; + Iterator<Node> itr = ids.iterator(); + while (itr.hasNext()) { + Node id = itr.next(); + if (valueOfIdentifier.containsKey(id)) + continue; + HashSet<Node> idValues = valuesOfConstantsFinder.valuesOfIdentifierTable + .get(id); + + for (Node val : idValues) { + HashSet<Node> idsInVal = dependsOnIdentifierTable.get(val); + idsInVal.remove(id); + if (idsInVal.size() == 0) { + valueOfIdentifier.put(id, val); + removeIdentifier(ids, id); + newRun = true; + break; + } + } + } + } + } + + private void removeIdentifier(Collection<Node> collection, + Node identifierToRemove) { + Iterator<Node> itr = collection.iterator(); + while (itr.hasNext()) { + Node id = itr.next(); + HashSet<Node> idValues = valuesOfConstantsFinder.valuesOfIdentifierTable + .get(id); + for (Node val : idValues) { + HashSet<Node> idsInVal = dependsOnIdentifierTable.get(val); + idsInVal.remove(identifierToRemove); + } + } + } + + class ConstantsInTreeFinder extends DepthFirstAdapter { + @Override + public void defaultIn(Node node) { + dependsOnIdentifierTable.put(node, new HashSet<Node>()); + } + + @Override + public void defaultOut(Node node) { + HashSet<Node> set = dependsOnIdentifierTable.get(node); + Node parent = node.parent(); + HashSet<Node> parentSet = dependsOnIdentifierTable.get(parent); + if (parentSet != null) { + parentSet.addAll(set); + } + + } + + @Override + public void caseAPropertiesMachineClause(APropertiesMachineClause node) { + defaultIn(node); + node.getPredicates().apply(this); + } + + @Override + public void caseAPredicateParseUnit(APredicateParseUnit node) { + defaultIn(node); + node.getPredicate().apply(this); + } + + @Override + public void caseAConstraintsMachineClause(AConstraintsMachineClause node) { + defaultIn(node); + node.getPredicates().apply(this); + } + + @Override + public void caseAIdentifierExpression(AIdentifierExpression node) { + defaultIn(node); + Node refNode = machineContext.getReferences().get(node); + if (machineContext.getConstants().containsValue(refNode)) { + HashSet<Node> set = dependsOnIdentifierTable.get(node); + set.add(refNode); + } + // it must be a bounded variable + defaultOut(node); + } + } + + class ValuesOfIdentifierFinder extends DepthFirstAdapter { + private Hashtable<Node, HashSet<Node>> valuesOfIdentifierTable; + private Hashtable<Node, ArrayList<PExpression>> rangeOfIdentifierTable; + private HashSet<Node> identifiers; + + public ValuesOfIdentifierFinder() { + this.valuesOfIdentifierTable = new Hashtable<Node, HashSet<Node>>(); + this.rangeOfIdentifierTable = new Hashtable<Node, ArrayList<PExpression>>(); + + this.identifiers = new HashSet<Node>(); + this.identifiers.addAll(machineContext.getConstants().values()); + this.identifiers.addAll(machineContext.getScalarParameter() + .values()); + + Iterator<Node> itr = identifiers.iterator(); + while (itr.hasNext()) { + Node id = itr.next(); + valuesOfIdentifierTable.put(id, new HashSet<Node>()); + rangeOfIdentifierTable.put(id, new ArrayList<PExpression>()); + } + + Node constraints = machineContext.getConstraintMachineClause(); + if (constraints != null) { + analysePredicate( + ((AConstraintsMachineClause) constraints) + .getPredicates(), + false); + } + + if (machineContext.getConstantsSetup() != null) { + if (machineContext.getConstantsSetup() instanceof ADisjunctPredicate) { + analyseConstantSetupPredicate(machineContext + .getConstantsSetup()); + for (Node con : this.identifiers) { + ArrayList<PExpression> list = rangeOfIdentifierTable + .get(con); + if (list.size() == 1) { + // there only one value for the constant con, hence + // con remains a constant + valuesOfIdentifierTable.get(con).add(list.get(0)); + } + } + } else { + analysePredicate(machineContext.getConstantsSetup(), true); + } + + } + + Node properties = machineContext.getPropertiesMachineClause(); + if (properties != null) { + PPredicate predicate = (PPredicate) ((APropertiesMachineClause) properties) + .getPredicates(); + analysePredicate(predicate, true); + + } + + Node invariantClause = machineContext.getInvariantMachineClause(); + if (invariantClause != null) { + analyseInvariantPredicate(((AInvariantMachineClause) invariantClause) + .getPredicates()); + } + } + + private void analyseConstantSetupPredicate(PPredicate constantsSetup) { + if (constantsSetup instanceof ADisjunctPredicate) { + ADisjunctPredicate dis = (ADisjunctPredicate) constantsSetup; + analyseConstantSetupPredicate(dis.getLeft()); + analyseConstantSetupPredicate(dis.getRight()); + } else if (constantsSetup instanceof AConjunctPredicate) { + AConjunctPredicate con = (AConjunctPredicate) constantsSetup; + analyseConstantSetupPredicate(con.getLeft()); + analyseConstantSetupPredicate(con.getRight()); + } else if (constantsSetup instanceof AEqualPredicate) { + AEqualPredicate equals = (AEqualPredicate) constantsSetup; + PExpression left = equals.getLeft(); + Node left_ref = machineContext.getReferences().get(left); + if (rangeOfIdentifierTable.containsKey(left_ref)) { + // TODO + } + ArrayList<PExpression> currentRange = rangeOfIdentifierTable + .get(left_ref); + boolean found = false; + for (PExpression pExpression : currentRange) { + if (pExpression.toString().equals( + equals.getRight().toString())) { + found = true; + } + } + if (found == false) { + currentRange.add((PExpression) equals.getRight()); + } + + } + + } + + private void analyseInvariantPredicate(Node node) { + if (node instanceof AConjunctPredicate) { + AConjunctPredicate conjunction = (AConjunctPredicate) node; + analyseInvariantPredicate(conjunction.getLeft()); + analyseInvariantPredicate(conjunction.getRight()); + return; + } + + invariantList.add(node); + } + + private void analysePredicate(Node node, boolean isProperties) { + if (node instanceof AEqualPredicate) { + analyseEqualsPredicate((AEqualPredicate) node); + } else if (node instanceof AConjunctPredicate) { + AConjunctPredicate conjunction = (AConjunctPredicate) node; + analysePredicate(conjunction.getLeft(), isProperties); + analysePredicate(conjunction.getRight(), isProperties); + return; + } + + if (isProperties) { + propertiesList.add((PPredicate) node); + } + } + + private void analyseEqualsPredicate(AEqualPredicate node) { + PExpression left = node.getLeft(); + Node left_ref = machineContext.getReferences().get(left); + PExpression right = node.getRight(); + Node right_ref = machineContext.getReferences().get(right); + + if (left instanceof ACardExpression) { + Node ref = machineContext.getReferences().get( + ((ACardExpression) left).getExpression()); + if (!machineContext.getConstants().containsValue(ref)) { + try { + AIntegerExpression intExpr = (AIntegerExpression) right; + int size = Integer.parseInt(intExpr.getLiteral() + .getText()); + integerValueTable.put(ref, size); + } catch (ClassCastException e) { + } + } + } + + if (right instanceof ACardExpression) { + Node ref = machineContext.getReferences().get( + ((ACardExpression) right).getExpression()); + if (!machineContext.getConstants().containsValue(ref)) { + try { + AIntegerExpression intExpr = (AIntegerExpression) left; + int size = Integer.parseInt(intExpr.getLiteral() + .getText()); + integerValueTable.put(ref, size); + } catch (ClassCastException e) { + } + } + } + + if (identifiers.contains(left_ref)) { + valuesOfIdentifierTable.get(left_ref).add(right); + } + + if (identifiers.contains(right_ref)) { + valuesOfIdentifierTable.get(right_ref).add(left); + } + return; + + } + + } + +} diff --git a/src/main/java/de/tlc4b/analysis/DefinitionsAnalyser.java b/src/main/java/de/tlc4b/analysis/DefinitionsAnalyser.java index 4164bc3d36b2ae7d7144f6eb42daa6e3c244b6a6..594dbcac5a660568bca3db70fac8acb52672b9cc 100644 --- a/src/main/java/de/tlc4b/analysis/DefinitionsAnalyser.java +++ b/src/main/java/de/tlc4b/analysis/DefinitionsAnalyser.java @@ -1,154 +1,154 @@ -package de.tlc4b.analysis; - -import java.util.HashMap; -import java.util.HashSet; -import java.util.Set; - -import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; -import de.be4.classicalb.core.parser.node.ACardExpression; -import de.be4.classicalb.core.parser.node.AEqualPredicate; -import de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition; -import de.be4.classicalb.core.parser.node.AIdentifierExpression; -import de.be4.classicalb.core.parser.node.AIntegerExpression; -import de.be4.classicalb.core.parser.node.AIntervalExpression; -import de.be4.classicalb.core.parser.node.AUnaryMinusExpression; -import de.be4.classicalb.core.parser.node.Node; -import de.tlc4b.TLC4BGlobals; -import de.tlc4b.exceptions.TranslationException; - -/** - * @author hansen In this class we search for preferences set in the definitions - * clause, e.g. minint or maxint. - */ - -public class DefinitionsAnalyser extends DepthFirstAdapter { - private MachineContext machineContext; - private HashMap<Node, Integer> deferredSetSizeTable; - - public Integer getSize(Node node) { - return deferredSetSizeTable.get(node); - } - - public DefinitionsAnalyser(MachineContext machineContext) { - this.machineContext = machineContext; - deferredSetSizeTable = new HashMap<Node, Integer>(); - HashSet<Node> deferredSets = new HashSet<Node>(machineContext - .getDeferredSets().values()); - - findDefaultSizesInDefinitions(); - - if (deferredSets.size() == 0) - return; - - Set<String> strings = machineContext.getDeferredSets().keySet(); - for (String string : strings) { - String s = "scope_" + string; - Node node = machineContext.getDefinitions().get(s); - if (null != node) { - try { - AExpressionDefinitionDefinition d = (AExpressionDefinitionDefinition) node; - AIntervalExpression interval = (AIntervalExpression) d - .getRhs(); - AIntegerExpression left = (AIntegerExpression) interval - .getLeftBorder(); - AIntegerExpression right = (AIntegerExpression) interval - .getRightBorder(); - int l_int = Integer.parseInt(left.getLiteral().getText()); - int r_int = Integer.parseInt(right.getLiteral().getText()); - int size = r_int - l_int + 1; - deferredSetSizeTable.put(machineContext.getDeferredSets() - .get(string), size); - } catch (ClassCastException e) { - } - try { - AExpressionDefinitionDefinition d = (AExpressionDefinitionDefinition) node; - AIntegerExpression sizeExpr = (AIntegerExpression) d - .getRhs(); - int size = Integer - .parseInt(sizeExpr.getLiteral().getText()); - deferredSetSizeTable.put(machineContext.getDeferredSets() - .get(string), size); - } catch (ClassCastException e) { - } - - } - } - } - - private void findDefaultSizesInDefinitions() { - Node node = machineContext.getDefinitions().get( - "SET_PREF_DEFAULT_SETSIZE"); - if (null != node) { - try { - AExpressionDefinitionDefinition d = (AExpressionDefinitionDefinition) node; - AIntegerExpression sizeExpr = (AIntegerExpression) d.getRhs(); - int value = Integer.parseInt(sizeExpr.getLiteral().getText()); - TLC4BGlobals.setDEFERRED_SET_SIZE(value); - } catch (ClassCastException e) { - throw new TranslationException( - "Unable to determine the default set size from definition SET_PREF_DEFAULT_SETSIZE: " - + node.getEndPos()); - } - } - - node = machineContext.getDefinitions().get("SET_PREF_MAXINT"); - if (null != node) { - try { - AExpressionDefinitionDefinition d = (AExpressionDefinitionDefinition) node; - AIntegerExpression sizeExpr = (AIntegerExpression) d.getRhs(); - int value = Integer.parseInt(sizeExpr.getLiteral().getText()); - TLC4BGlobals.setMAX_INT(value); - } catch (ClassCastException e) { - throw new TranslationException( - "Unable to determine MAXINT from definition SET_PREF_MAXINT: " - + node.getEndPos()); - } - } - - node = machineContext.getDefinitions().get("SET_PREF_MININT"); - if (null != node) { - try { - AExpressionDefinitionDefinition d = (AExpressionDefinitionDefinition) node; - AIntegerExpression sizeExpr = null; - Integer value = null; - if (d.getRhs() instanceof AUnaryMinusExpression) { - AUnaryMinusExpression minus = (AUnaryMinusExpression) d - .getRhs(); - sizeExpr = (AIntegerExpression) minus.getExpression(); - value = -Integer.parseInt(sizeExpr.getLiteral().getText()); - } else { - sizeExpr = (AIntegerExpression) d.getRhs(); - value = Integer.parseInt(sizeExpr.getLiteral().getText()); - } - TLC4BGlobals.setMIN_INT(value); - } catch (ClassCastException e) { - throw new TranslationException( - "Unable to determine the MININT from definition SET_PREF_MININT: " + node.getEndPos()); - } - } - } - - @Override - public void caseAIdentifierExpression(AIdentifierExpression node) { - // TODO never reached - Node ref_node = machineContext.getReferences().get(node); - if (deferredSetSizeTable.containsKey(ref_node)) { - try { - ACardExpression cardNode = (ACardExpression) node.parent(); - AEqualPredicate equalsNode = (AEqualPredicate) cardNode - .parent(); - AIntegerExpression integer; - if (equalsNode.getLeft() == cardNode) { - integer = (AIntegerExpression) equalsNode.getRight(); - } else { - integer = (AIntegerExpression) equalsNode.getLeft(); - } - String intString = integer.getLiteral().getText(); - deferredSetSizeTable.put(ref_node, Integer.parseInt(intString)); - } catch (ClassCastException e) { - return; - } - - } - } -} +package de.tlc4b.analysis; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Set; + +import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; +import de.be4.classicalb.core.parser.node.ACardExpression; +import de.be4.classicalb.core.parser.node.AEqualPredicate; +import de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition; +import de.be4.classicalb.core.parser.node.AIdentifierExpression; +import de.be4.classicalb.core.parser.node.AIntegerExpression; +import de.be4.classicalb.core.parser.node.AIntervalExpression; +import de.be4.classicalb.core.parser.node.AUnaryMinusExpression; +import de.be4.classicalb.core.parser.node.Node; +import de.tlc4b.TLC4BGlobals; +import de.tlc4b.exceptions.TranslationException; + +/** + * @author hansen In this class we search for preferences set in the definitions + * clause, e.g. minint or maxint. + */ + +public class DefinitionsAnalyser extends DepthFirstAdapter { + private MachineContext machineContext; + private HashMap<Node, Integer> deferredSetSizeTable; + + public Integer getSize(Node node) { + return deferredSetSizeTable.get(node); + } + + public DefinitionsAnalyser(MachineContext machineContext) { + this.machineContext = machineContext; + deferredSetSizeTable = new HashMap<Node, Integer>(); + HashSet<Node> deferredSets = new HashSet<Node>(machineContext + .getDeferredSets().values()); + + findDefaultSizesInDefinitions(); + + if (deferredSets.size() == 0) + return; + + Set<String> strings = machineContext.getDeferredSets().keySet(); + for (String string : strings) { + String s = "scope_" + string; + Node node = machineContext.getDefinitions().get(s); + if (null != node) { + try { + AExpressionDefinitionDefinition d = (AExpressionDefinitionDefinition) node; + AIntervalExpression interval = (AIntervalExpression) d + .getRhs(); + AIntegerExpression left = (AIntegerExpression) interval + .getLeftBorder(); + AIntegerExpression right = (AIntegerExpression) interval + .getRightBorder(); + int l_int = Integer.parseInt(left.getLiteral().getText()); + int r_int = Integer.parseInt(right.getLiteral().getText()); + int size = r_int - l_int + 1; + deferredSetSizeTable.put(machineContext.getDeferredSets() + .get(string), size); + } catch (ClassCastException e) { + } + try { + AExpressionDefinitionDefinition d = (AExpressionDefinitionDefinition) node; + AIntegerExpression sizeExpr = (AIntegerExpression) d + .getRhs(); + int size = Integer + .parseInt(sizeExpr.getLiteral().getText()); + deferredSetSizeTable.put(machineContext.getDeferredSets() + .get(string), size); + } catch (ClassCastException e) { + } + + } + } + } + + private void findDefaultSizesInDefinitions() { + Node node = machineContext.getDefinitions().get( + "SET_PREF_DEFAULT_SETSIZE"); + if (null != node) { + try { + AExpressionDefinitionDefinition d = (AExpressionDefinitionDefinition) node; + AIntegerExpression sizeExpr = (AIntegerExpression) d.getRhs(); + int value = Integer.parseInt(sizeExpr.getLiteral().getText()); + TLC4BGlobals.setDEFERRED_SET_SIZE(value); + } catch (ClassCastException e) { + throw new TranslationException( + "Unable to determine the default set size from definition SET_PREF_DEFAULT_SETSIZE: " + + node.getEndPos()); + } + } + + node = machineContext.getDefinitions().get("SET_PREF_MAXINT"); + if (null != node) { + try { + AExpressionDefinitionDefinition d = (AExpressionDefinitionDefinition) node; + AIntegerExpression sizeExpr = (AIntegerExpression) d.getRhs(); + int value = Integer.parseInt(sizeExpr.getLiteral().getText()); + TLC4BGlobals.setMAX_INT(value); + } catch (ClassCastException e) { + throw new TranslationException( + "Unable to determine MAXINT from definition SET_PREF_MAXINT: " + + node.getEndPos()); + } + } + + node = machineContext.getDefinitions().get("SET_PREF_MININT"); + if (null != node) { + try { + AExpressionDefinitionDefinition d = (AExpressionDefinitionDefinition) node; + AIntegerExpression sizeExpr = null; + Integer value = null; + if (d.getRhs() instanceof AUnaryMinusExpression) { + AUnaryMinusExpression minus = (AUnaryMinusExpression) d + .getRhs(); + sizeExpr = (AIntegerExpression) minus.getExpression(); + value = -Integer.parseInt(sizeExpr.getLiteral().getText()); + } else { + sizeExpr = (AIntegerExpression) d.getRhs(); + value = Integer.parseInt(sizeExpr.getLiteral().getText()); + } + TLC4BGlobals.setMIN_INT(value); + } catch (ClassCastException e) { + throw new TranslationException( + "Unable to determine the MININT from definition SET_PREF_MININT: " + node.getEndPos()); + } + } + } + + @Override + public void caseAIdentifierExpression(AIdentifierExpression node) { + // TODO never reached + Node ref_node = machineContext.getReferences().get(node); + if (deferredSetSizeTable.containsKey(ref_node)) { + try { + ACardExpression cardNode = (ACardExpression) node.parent(); + AEqualPredicate equalsNode = (AEqualPredicate) cardNode + .parent(); + AIntegerExpression integer; + if (equalsNode.getLeft() == cardNode) { + integer = (AIntegerExpression) equalsNode.getRight(); + } else { + integer = (AIntegerExpression) equalsNode.getLeft(); + } + String intString = integer.getLiteral().getText(); + deferredSetSizeTable.put(ref_node, Integer.parseInt(intString)); + } catch (ClassCastException e) { + return; + } + + } + } +} diff --git a/src/main/java/de/tlc4b/analysis/MachineContext.java b/src/main/java/de/tlc4b/analysis/MachineContext.java index 14ccb839f370d24244113cb31df39615783d8b6e..184f6bd70abff3acc9d02a697ac20894ce4dda18 100644 --- a/src/main/java/de/tlc4b/analysis/MachineContext.java +++ b/src/main/java/de/tlc4b/analysis/MachineContext.java @@ -1,1049 +1,1049 @@ -package de.tlc4b.analysis; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map.Entry; - -import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; -import de.be4.classicalb.core.parser.node.AAbstractConstantsMachineClause; -import de.be4.classicalb.core.parser.node.AAbstractMachineParseUnit; -import de.be4.classicalb.core.parser.node.AAnySubstitution; -import de.be4.classicalb.core.parser.node.AAssertionsMachineClause; -import de.be4.classicalb.core.parser.node.AAssignSubstitution; -import de.be4.classicalb.core.parser.node.AComprehensionSetExpression; -import de.be4.classicalb.core.parser.node.AConcreteVariablesMachineClause; -import de.be4.classicalb.core.parser.node.AConstantsMachineClause; -import de.be4.classicalb.core.parser.node.AConstraintsMachineClause; -import de.be4.classicalb.core.parser.node.ADeferredSetSet; -import de.be4.classicalb.core.parser.node.ADefinitionExpression; -import de.be4.classicalb.core.parser.node.ADefinitionPredicate; -import de.be4.classicalb.core.parser.node.ADefinitionSubstitution; -import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause; -import de.be4.classicalb.core.parser.node.AEnumeratedSetSet; -import de.be4.classicalb.core.parser.node.AEventBComprehensionSetExpression; -import de.be4.classicalb.core.parser.node.AExistsPredicate; -import de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition; -import de.be4.classicalb.core.parser.node.AForallPredicate; -import de.be4.classicalb.core.parser.node.AFunctionExpression; -import de.be4.classicalb.core.parser.node.AGeneralProductExpression; -import de.be4.classicalb.core.parser.node.AGeneralSumExpression; -import de.be4.classicalb.core.parser.node.AIdentifierExpression; -import de.be4.classicalb.core.parser.node.AInitialisationMachineClause; -import de.be4.classicalb.core.parser.node.AInvariantMachineClause; -import de.be4.classicalb.core.parser.node.ALambdaExpression; -import de.be4.classicalb.core.parser.node.ALetSubstitution; -import de.be4.classicalb.core.parser.node.AMachineHeader; -import de.be4.classicalb.core.parser.node.AOpSubstitution; -import de.be4.classicalb.core.parser.node.AOperation; -import de.be4.classicalb.core.parser.node.AOperationsMachineClause; -import de.be4.classicalb.core.parser.node.APredicateDefinitionDefinition; -import de.be4.classicalb.core.parser.node.APredicateParseUnit; -import de.be4.classicalb.core.parser.node.APrimedIdentifierExpression; -import de.be4.classicalb.core.parser.node.APropertiesMachineClause; -import de.be4.classicalb.core.parser.node.AQuantifiedIntersectionExpression; -import de.be4.classicalb.core.parser.node.AQuantifiedUnionExpression; -import de.be4.classicalb.core.parser.node.ARecEntry; -import de.be4.classicalb.core.parser.node.ARecordFieldExpression; -import de.be4.classicalb.core.parser.node.ASeesMachineClause; -import de.be4.classicalb.core.parser.node.ASetsContextClause; -import de.be4.classicalb.core.parser.node.ASubstitutionDefinitionDefinition; -import de.be4.classicalb.core.parser.node.AVariablesMachineClause; -import de.be4.classicalb.core.parser.node.Node; -import de.be4.classicalb.core.parser.node.PDefinition; -import de.be4.classicalb.core.parser.node.PExpression; -import de.be4.classicalb.core.parser.node.PMachineClause; -import de.be4.classicalb.core.parser.node.PMachineHeader; -import de.be4.classicalb.core.parser.node.POperation; -import de.be4.classicalb.core.parser.node.PPredicate; -import de.be4.classicalb.core.parser.node.PSet; -import de.be4.classicalb.core.parser.node.Start; -import de.be4.classicalb.core.parser.node.TIdentifierLiteral; -import de.be4.classicalb.core.parser.util.Utils; -import de.tlc4b.MP; -import de.tlc4b.TLC4BGlobals; -import de.tlc4b.analysis.transformation.DefinitionsSorter; -import de.tlc4b.analysis.transformation.MachineClauseSorter; -import de.tlc4b.exceptions.ScopeException; -import de.tlc4b.ltl.LTLBPredicate; -import de.tlc4b.ltl.LTLFormulaVisitor; - -public class MachineContext extends DepthFirstAdapter { - - private String machineName; - private final Start start; - - private final ArrayList<LTLFormulaVisitor> ltlVisitors; - private PPredicate constantsSetupPredicate; - private boolean hasConstants = false; - - private final LinkedHashMap<String, Node> machineSetParameter; - private final LinkedHashMap<String, Node> machineScalarParameter; - private final LinkedHashMap<String, Node> deferredSets; - private final LinkedHashMap<String, Node> enumeratedSets; - private final LinkedHashMap<String, Node> enumValues; - private final LinkedHashMap<String, Node> variables; - private final LinkedHashMap<String, Node> constants; - private final LinkedHashMap<String, Node> definitions; - private final LinkedHashMap<String, Node> operations; - private final LinkedHashMap<String, AIdentifierExpression> seenMachines; - - private PMachineHeader header; - private AAbstractMachineParseUnit abstractMachineParseUnit; - private AConstraintsMachineClause constraintMachineClause; - private ASeesMachineClause seesMachineClause; - private ASetsContextClause setsMachineClause; - private ADefinitionsMachineClause definitionMachineClause; - private APropertiesMachineClause propertiesMachineClause; - private AInvariantMachineClause invariantMachineClause; - private AInitialisationMachineClause initialisationMachineClause; - private AOperationsMachineClause operationMachineClause; - private AAssertionsMachineClause assertiondMachineClause; - - private ArrayList<LinkedHashMap<String, Node>> contextTable; - - protected final Hashtable<Node, Node> referencesTable; - - public MachineContext(final String machineName, final Start start) { - this.start = start; - this.machineName = machineName; - this.referencesTable = new Hashtable<Node, Node>(); - this.ltlVisitors = new ArrayList<LTLFormulaVisitor>(); - - this.machineSetParameter = new LinkedHashMap<String, Node>(); - this.machineScalarParameter = new LinkedHashMap<String, Node>(); - - this.deferredSets = new LinkedHashMap<String, Node>(); - this.enumeratedSets = new LinkedHashMap<String, Node>(); - this.enumValues = new LinkedHashMap<String, Node>(); - this.constants = new LinkedHashMap<String, Node>(); - this.variables = new LinkedHashMap<String, Node>(); - this.definitions = new LinkedHashMap<String, Node>(); - this.operations = new LinkedHashMap<String, Node>(); - this.seenMachines = new LinkedHashMap<String, AIdentifierExpression>(); - } - - public void analyseMachine() { - this.start.apply(this); - checkConstantsSetup(); - checkLTLFormulas(); - } - - public void addLTLFromula(final String ltlFormula) { - LTLFormulaVisitor ltlVisitor = new LTLFormulaVisitor("ltl", this); - ltlVisitor.parseLTLString(ltlFormula); - this.ltlVisitors.add(ltlVisitor); - } - - public void setConstantSetupPredicate(final PPredicate constantsSetup) { - this.constantsSetupPredicate = constantsSetup; - } - - private void checkConstantsSetup() { - if (constantsSetupPredicate == null) { - return; - } - this.contextTable = new ArrayList<LinkedHashMap<String, Node>>(); - ArrayList<MachineContext> list = lookupReferencedMachines(); - for (int i = 0; i < list.size(); i++) { - MachineContext s = list.get(i); - contextTable.add(s.getDeferredSets()); - contextTable.add(s.getEnumeratedSets()); - contextTable.add(s.getEnumValues()); - contextTable.add(s.getConstants()); - contextTable.add(s.getDefinitions()); - } - constantsSetupPredicate.apply(this); - } - - private void checkLTLFormulas() { - if (ltlVisitors.size() == 1) { - ltlVisitors.get(0).start(); - return; - } - ArrayList<LTLFormulaVisitor> formulasNotSupportedByTLC = new ArrayList<LTLFormulaVisitor>(); - for (int i = 0; i < ltlVisitors.size(); i++) { - LTLFormulaVisitor visitor = ltlVisitors.get(i); - try { - visitor.start(); - } catch (ScopeException e) { - MP.println("Warning: LTL formula '" + visitor.getName() + "' cannot be checked by TLC."); - formulasNotSupportedByTLC.add(visitor); - } - } - ltlVisitors.removeAll(formulasNotSupportedByTLC); - } - - public void checkLTLBPredicate(LTLBPredicate ltlbPredicate) { - contextTable = new ArrayList<LinkedHashMap<String, Node>>(); - contextTable.add(getDeferredSets()); - contextTable.add(getEnumeratedSets()); - contextTable.add(getEnumValues()); - contextTable.add(getConstants()); - contextTable.add(getVariables()); - contextTable.add(getDefinitions()); - - LinkedHashMap<String, Node> identifierHashTable = ltlbPredicate.getIdentifierList(); - if (identifierHashTable.size() > 0) { - LinkedHashMap<String, Node> currentContext = new LinkedHashMap<String, Node>(); - currentContext.putAll(identifierHashTable); - contextTable.add(currentContext); - } - ltlbPredicate.getBFormula().apply(this); - } - - private void exist(LinkedList<TIdentifierLiteral> list) { - String name = Utils.getTIdentifierListAsString(list); - identifierAlreadyExists(name); - } - - private void identifierAlreadyExists(String name) { - if (constants.containsKey(name) || variables.containsKey(name) || operations.containsKey(name) - || deferredSets.containsKey(name) || enumeratedSets.containsKey(name) || enumValues.containsKey(name) - || machineSetParameter.containsKey(name) || machineScalarParameter.containsKey(name) - || seenMachines.containsKey(name) || definitions.containsKey(name)) { - throw new ScopeException("Duplicate identifier: '" + name + "'"); - } - } - - @Override - public void caseAAbstractMachineParseUnit(AAbstractMachineParseUnit node) { - this.abstractMachineParseUnit = node; - if (node.getVariant() != null) { - node.getVariant().apply(this); - } - if (node.getHeader() != null) { - node.getHeader().apply(this); - } - - List<PMachineClause> machineClauses = node.getMachineClauses(); - // Sort the machine clauses: declarations clauses first, then - // properties clauses - MachineClauseSorter.sortMachineClauses(start); - - for (PMachineClause e : machineClauses) { - e.apply(this); - } - } - - @Override - public void caseAMachineHeader(AMachineHeader node) { - this.header = node; - if (machineName == null) { - List<TIdentifierLiteral> nameList = new ArrayList<TIdentifierLiteral>(node.getName()); - this.machineName = Utils.getTIdentifierListAsString(nameList); - } - - List<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); - for (PExpression e : copy) { - AIdentifierExpression p = (AIdentifierExpression) e; - String name = Utils.getTIdentifierListAsString(p.getIdentifier()); - exist(p.getIdentifier()); - if (Character.isUpperCase(name.charAt(0))) { - this.machineSetParameter.put(name, p); - } else { - this.machineScalarParameter.put(name, p); - } - } - } - - @Override - public void caseAPredicateParseUnit(APredicateParseUnit node) { - node.getPredicate().apply(this); - } - - /** - * Definitions - */ - - @Override - public void caseADefinitionsMachineClause(ADefinitionsMachineClause node) { - definitionMachineClause = node; - DefinitionsSorter.sortDefinitions(node); - - List<PDefinition> copy = node.getDefinitions(); - - /* - * The definitions are not in a predefined order. In particular - * definitions can depend on each other. First all definitions are added - * to the definitions context table. Then all definitions are visited. - */ - Collection<PDefinition> definitionsToRemove = new HashSet<PDefinition>(); - - for (PDefinition e : copy) { - if (e instanceof AExpressionDefinitionDefinition) { - AExpressionDefinitionDefinition def = (AExpressionDefinitionDefinition) e; - String name = def.getName().getText(); - if (name.startsWith("ASSERT_LTL")) { - if (TLC4BGlobals.isCheckLTL()) { - LTLFormulaVisitor visitor = new LTLFormulaVisitor(name, this); - visitor.parseDefinition(def); - this.ltlVisitors.add(visitor); - } - definitionsToRemove.add(def); - } else if (name.startsWith("ANIMATION_")) { - definitionsToRemove.add(def); - } - evalDefinitionName(((AExpressionDefinitionDefinition) e).getName().getText().toString(), e); - } else if (e instanceof APredicateDefinitionDefinition) { - evalDefinitionName(((APredicateDefinitionDefinition) e).getName().getText().toString(), e); - } else if (e instanceof ASubstitutionDefinitionDefinition) { - evalDefinitionName(((ASubstitutionDefinitionDefinition) e).getName().getText().toString(), e); - } - } - /* - * At this point all LTL definitions (ASSERT_LTL) are removed. LTL - * formulas are stored in the Arraylist {@value #ltlVisitors}. - */ - copy.removeAll(definitionsToRemove); - this.contextTable = new ArrayList<LinkedHashMap<String, Node>>(); - ArrayList<MachineContext> list = lookupReferencedMachines(); - for (int i = 0; i < list.size(); i++) { - MachineContext s = list.get(i); - contextTable.add(s.getDeferredSets()); - contextTable.add(s.getEnumeratedSets()); - contextTable.add(s.getEnumValues()); - contextTable.add(s.getConstants()); - contextTable.add(s.getVariables()); - contextTable.add(s.getDefinitions()); - } - - for (PDefinition e : copy) { - e.apply(this); - } - } - - private void evalDefinitionName(String name, Node node) { - identifierAlreadyExists(name); - definitions.put(name, node); - } - - @Override - public void caseAExpressionDefinitionDefinition(AExpressionDefinitionDefinition node) { - visitBDefinition(node, node.getName().getText().toString(), node.getParameters(), node.getRhs()); - } - - @Override - public void caseAPredicateDefinitionDefinition(APredicateDefinitionDefinition node) { - visitBDefinition(node, node.getName().getText().toString(), node.getParameters(), node.getRhs()); - } - - /* d == x := 1 */ - @Override - public void caseASubstitutionDefinitionDefinition(ASubstitutionDefinitionDefinition node) { - visitBDefinition(node, node.getName().getText().toString(), node.getParameters(), node.getRhs()); - - } - - public void visitBDefinition(Node node, String name, List<PExpression> copy, Node rightSide) { - if (!this.definitions.containsValue(node)) { - return; - } - contextTable.add(new LinkedHashMap<String, Node>()); - for (PExpression e : copy) { - putLocalVariableIntoCurrentScope((AIdentifierExpression) e); - } - rightSide.apply(this); - contextTable.remove(contextTable.size() - 1); - } - - @Override - public void caseADefinitionExpression(ADefinitionExpression node) { - visitBDefinitionCall(node, node.getDefLiteral().getText().toString(), node.getParameters()); - } - - @Override - public void caseADefinitionPredicate(ADefinitionPredicate node) { - visitBDefinitionCall(node, node.getDefLiteral().getText().toString(), node.getParameters()); - } - - @Override - public void caseADefinitionSubstitution(ADefinitionSubstitution node) { - visitBDefinitionCall(node, node.getDefLiteral().getText().toString(), node.getParameters()); - } - - private void visitBDefinitionCall(Node node, String name, List<PExpression> copy) { - for (PExpression pExpression : copy) { - pExpression.apply(this); - } - for (int i = contextTable.size() - 1; i >= 0; i--) { - LinkedHashMap<String, Node> currentScope = contextTable.get(i); - if (currentScope.containsKey(name)) { - this.referencesTable.put(node, currentScope.get(name)); - return; - } - } - throw new ScopeException("Unkown definition: '" + name + "' at position: " + node.getStartPos()); - } - - @Override - public void caseASeesMachineClause(ASeesMachineClause node) { - this.seesMachineClause = node; - List<PExpression> copy = new ArrayList<PExpression>(node.getMachineNames()); - for (PExpression e : copy) { - AIdentifierExpression p = (AIdentifierExpression) e; - String name = Utils.getTIdentifierListAsString(p.getIdentifier()); - - try { - exist(p.getIdentifier()); - } catch (ScopeException e2) { - throw new ScopeException("Machine '" + name + "' is seen twice."); - } - seenMachines.put(name, p); - } - } - - @Override - public void caseASetsContextClause(ASetsContextClause node) { - this.setsMachineClause = node; - List<PSet> copy = new ArrayList<PSet>(node.getSet()); - for (PSet e : copy) { - e.apply(this); - } - } - - @Override - public void caseADeferredSetSet(ADeferredSetSet node) { - List<TIdentifierLiteral> copy = new ArrayList<TIdentifierLiteral>(node.getIdentifier()); - String name = Utils.getTIdentifierListAsString(copy); - exist(node.getIdentifier()); - deferredSets.put(name, node); - } - - @Override - public void caseAEnumeratedSetSet(AEnumeratedSetSet node) { - { - List<TIdentifierLiteral> copy = new ArrayList<TIdentifierLiteral>(node.getIdentifier()); - String name = Utils.getTIdentifierListAsString(copy); - exist(node.getIdentifier()); - enumeratedSets.put(name, node); - } - List<PExpression> copy = new ArrayList<PExpression>(node.getElements()); - for (PExpression e : copy) { - AIdentifierExpression v = (AIdentifierExpression) e; - String name = Utils.getTIdentifierListAsString(v.getIdentifier()); - exist(v.getIdentifier()); - enumValues.put(name, v); - } - } - - @Override - public void caseAConstantsMachineClause(AConstantsMachineClause node) { - hasConstants = true; - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - AIdentifierExpression c = (AIdentifierExpression) e; - String name = Utils.getTIdentifierListAsString(c.getIdentifier()); - exist(c.getIdentifier()); - constants.put(name, c); - } - } - - @Override - public void caseAAbstractConstantsMachineClause(AAbstractConstantsMachineClause node) { - hasConstants = true; - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - AIdentifierExpression c = (AIdentifierExpression) e; - String name = Utils.getTIdentifierListAsString(c.getIdentifier()); - exist(c.getIdentifier()); - constants.put(name, c); - } - } - - @Override - public void caseAVariablesMachineClause(AVariablesMachineClause node) { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - AIdentifierExpression v = (AIdentifierExpression) e; - String name = Utils.getTIdentifierListAsString(v.getIdentifier()); - exist(v.getIdentifier()); - variables.put(name, v); - } - } - - @Override - public void caseAConcreteVariablesMachineClause(AConcreteVariablesMachineClause node) { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - AIdentifierExpression v = (AIdentifierExpression) e; - String name = Utils.getTIdentifierListAsString(v.getIdentifier()); - exist(v.getIdentifier()); - variables.put(name, v); - } - } - - private void putLocalVariableIntoCurrentScope(AIdentifierExpression node) throws ScopeException { - String name = Utils.getTIdentifierListAsString(node.getIdentifier()); - LinkedHashMap<String, Node> currentScope = contextTable.get(contextTable.size() - 1); - if (currentScope.containsKey(name)) { - throw new ScopeException("Duplicate Identifier: " + name); - } else { - currentScope.put(name, node); - } - } - - @Override - public void caseAIdentifierExpression(AIdentifierExpression node) { - String name = Utils.getTIdentifierListAsString(node.getIdentifier()); - for (int i = contextTable.size() - 1; i >= 0; i--) { - LinkedHashMap<String, Node> currentScope = contextTable.get(i); - if (currentScope.containsKey(name)) { - this.referencesTable.put(node, currentScope.get(name)); - return; - } - } - throw new ScopeException("Unkown Identifier: '" + name + "' at position: " + node.getStartPos()); - } - - @Override - public void caseAPrimedIdentifierExpression(APrimedIdentifierExpression node) { - String name = Utils.getTIdentifierListAsString(node.getIdentifier()); - for (int i = contextTable.size() - 1; i >= 0; i--) { - LinkedHashMap<String, Node> currentScope = contextTable.get(i); - if (currentScope.containsKey(name)) { - this.referencesTable.put(node, currentScope.get(name)); - return; - } - } - throw new ScopeException("Unkown Identifier: '" + name + "' at position: " + node.getStartPos()); - } - - private ArrayList<MachineContext> lookupReferencedMachines() { - ArrayList<MachineContext> list = new ArrayList<MachineContext>(); - list.add(this); - return list; - } - - @Override - public void caseAConstraintsMachineClause(AConstraintsMachineClause node) { - this.constraintMachineClause = node; - - this.contextTable = new ArrayList<LinkedHashMap<String, Node>>(); - this.contextTable.add(this.machineScalarParameter); - this.contextTable.add(this.machineSetParameter); - if (node.getPredicates() != null) { - node.getPredicates().apply(this); - } - } - - @Override - public void caseAPropertiesMachineClause(APropertiesMachineClause node) { - this.propertiesMachineClause = node; - hasConstants = true; - /** - * check identifier scope in properties clauses - */ - - this.contextTable = new ArrayList<LinkedHashMap<String, Node>>(); - ArrayList<MachineContext> list = lookupReferencedMachines(); - for (int i = 0; i < list.size(); i++) { - MachineContext s = list.get(i); - contextTable.add(s.getDeferredSets()); - contextTable.add(s.getEnumeratedSets()); - contextTable.add(s.getEnumValues()); - contextTable.add(s.getConstants()); - contextTable.add(s.getDefinitions()); - } - if (node.getPredicates() != null) { - node.getPredicates().apply(this); - } - } - - @Override - public void caseAInvariantMachineClause(AInvariantMachineClause node) { - this.invariantMachineClause = node; - - this.contextTable = new ArrayList<LinkedHashMap<String, Node>>(); - - ArrayList<MachineContext> list = lookupReferencedMachines(); - for (int i = 0; i < list.size(); i++) { - MachineContext s = list.get(i); - this.contextTable.add(s.getSetParamter()); - this.contextTable.add(s.getScalarParameter()); - this.contextTable.add(s.getDeferredSets()); - this.contextTable.add(s.getEnumeratedSets()); - this.contextTable.add(s.getEnumValues()); - this.contextTable.add(s.getConstants()); - this.contextTable.add(s.getDefinitions()); - this.contextTable.add(s.getVariables()); - } - node.getPredicates().apply(this); - } - - @Override - public void caseAAssertionsMachineClause(AAssertionsMachineClause node) { - this.assertiondMachineClause = node; - - this.contextTable = new ArrayList<LinkedHashMap<String, Node>>(); - ArrayList<MachineContext> list = lookupReferencedMachines(); - for (int i = 0; i < list.size(); i++) { - MachineContext s = list.get(i); - this.contextTable.add(s.getSetParamter()); - this.contextTable.add(s.getScalarParameter()); - this.contextTable.add(s.getDeferredSets()); - this.contextTable.add(s.getEnumeratedSets()); - this.contextTable.add(s.getEnumValues()); - this.contextTable.add(s.getConstants()); - this.contextTable.add(s.getDefinitions()); - this.contextTable.add(s.getVariables()); - } - - List<PPredicate> copy = new ArrayList<PPredicate>(node.getPredicates()); - for (PPredicate e : copy) { - e.apply(this); - } - } - - @Override - public void caseAInitialisationMachineClause(AInitialisationMachineClause node) { - this.initialisationMachineClause = node; - - this.contextTable = new ArrayList<LinkedHashMap<String, Node>>(); - - ArrayList<MachineContext> list = lookupReferencedMachines(); - for (int i = 0; i < list.size(); i++) { - MachineContext s = list.get(i); - - this.contextTable.add(s.getSetParamter()); - this.contextTable.add(s.getScalarParameter()); - this.contextTable.add(s.getDeferredSets()); - this.contextTable.add(s.getEnumeratedSets()); - this.contextTable.add(s.getEnumValues()); - this.contextTable.add(s.getConstants()); - this.contextTable.add(s.getDefinitions()); - this.contextTable.add(s.getVariables()); - } - if (node.getSubstitutions() != null) { - node.getSubstitutions().apply(this); - } - } - - @Override - public void caseAOperationsMachineClause(AOperationsMachineClause node) { - this.operationMachineClause = node; - this.contextTable = new ArrayList<LinkedHashMap<String, Node>>(); - ArrayList<MachineContext> list = lookupReferencedMachines(); - for (int i = 0; i < list.size(); i++) { - MachineContext s = list.get(i); - this.contextTable.add(s.getSetParamter()); - this.contextTable.add(s.getScalarParameter()); - this.contextTable.add(s.getDeferredSets()); - this.contextTable.add(s.getEnumeratedSets()); - this.contextTable.add(s.getEnumValues()); - this.contextTable.add(s.getConstants()); - this.contextTable.add(s.getDefinitions()); - this.contextTable.add(s.getVariables()); - } - List<POperation> copy = new ArrayList<POperation>(node.getOperations()); - // first collect all operations - for (POperation e : copy) { - AOperation op = (AOperation) e; - String name = Utils.getTIdentifierListAsString(op.getOpName()); - // existString(name); - if (operations.keySet().contains(name)) { - throw new ScopeException(String.format("Duplicate operation: '%s'", name)); - } - operations.put(name, op); - } - // visit all operations - for (POperation e : copy) { - e.apply(this); - } - } - - @Override - public void caseAOperation(AOperation node) { - contextTable.add(new LinkedHashMap<String, Node>()); - { - List<PExpression> copy = new ArrayList<PExpression>(node.getReturnValues()); - for (PExpression e : copy) { - AIdentifierExpression id = (AIdentifierExpression) e; - exist(id.getIdentifier()); - putLocalVariableIntoCurrentScope((AIdentifierExpression) e); - } - } - - { - List<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); - for (PExpression e : copy) { - AIdentifierExpression id = (AIdentifierExpression) e; - exist(id.getIdentifier()); - putLocalVariableIntoCurrentScope((AIdentifierExpression) e); - } - } - if (node.getOperationBody() != null) { - node.getOperationBody().apply(this); - } - contextTable.remove(contextTable.size() - 1); - } - - @Override - public void caseAAssignSubstitution(AAssignSubstitution node) { - ArrayList<LinkedHashMap<String, Node>> temp = contextTable; - { - List<PExpression> copy = new ArrayList<PExpression>(node.getLhsExpression()); - ArrayList<LinkedHashMap<String, Node>> varTable = new ArrayList<LinkedHashMap<String, Node>>(); - varTable.add(variables); - for (PExpression e : copy) { - if (e instanceof AFunctionExpression) { - contextTable = varTable; - ((AFunctionExpression) e).getIdentifier().apply(this); - - // full context table - contextTable = temp; - for (Node n : ((AFunctionExpression) e).getParameters()) { - n.apply(this); - } - } else { - contextTable = temp; // TODO outputparameter + variables - e.apply(this); - } - } - } - { - contextTable = temp; - List<PExpression> copy = new ArrayList<PExpression>(node.getRhsExpressions()); - for (PExpression e : copy) { - e.apply(this); - } - } - } - - @Override - public void caseALetSubstitution(ALetSubstitution node) { - contextTable.add(new LinkedHashMap<String, Node>()); - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - putLocalVariableIntoCurrentScope((AIdentifierExpression) e); - } - node.getPredicate().apply(this); - node.getSubstitution().apply(this); - } - - @Override - public void caseAAnySubstitution(AAnySubstitution node) { - contextTable.add(new LinkedHashMap<String, Node>()); - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - putLocalVariableIntoCurrentScope((AIdentifierExpression) e); - } - node.getWhere().apply(this); - node.getThen().apply(this); - } - - @Override - public void caseAOpSubstitution(AOpSubstitution node) { - if (node.getName() != null) { - AIdentifierExpression op = (AIdentifierExpression) node.getName(); - String name = Utils.getTIdentifierListAsString(op.getIdentifier()); - Node o = operations.get(name); - if (o != null) { - this.referencesTable.put(op, o); - } else { - throw new ScopeException("Unknown operation '" + name + "'"); - } - } - { - List<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); - for (PExpression e : copy) { - e.apply(this); - } - } - } - - @Override - public void caseAForallPredicate(AForallPredicate node) { - contextTable.add(new LinkedHashMap<String, Node>()); - { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - putLocalVariableIntoCurrentScope((AIdentifierExpression) e); - } - } - if (node.getImplication() != null) { - node.getImplication().apply(this); - } - contextTable.remove(contextTable.size() - 1); - } - - @Override - public void caseAExistsPredicate(AExistsPredicate node) { - contextTable.add(new LinkedHashMap<String, Node>()); - { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - putLocalVariableIntoCurrentScope((AIdentifierExpression) e); - } - } - if (node.getPredicate() != null) { - node.getPredicate().apply(this); - } - contextTable.remove(contextTable.size() - 1); - } - - @Override - public void caseALambdaExpression(ALambdaExpression node) { - contextTable.add(new LinkedHashMap<String, Node>()); - { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - putLocalVariableIntoCurrentScope((AIdentifierExpression) e); - } - } - node.getPredicate().apply(this); - node.getExpression().apply(this); - contextTable.remove(contextTable.size() - 1); - } - - @Override - public void caseAComprehensionSetExpression(AComprehensionSetExpression node) { - contextTable.add(new LinkedHashMap<String, Node>()); - { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - putLocalVariableIntoCurrentScope((AIdentifierExpression) e); - } - } - node.getPredicates().apply(this); - contextTable.remove(contextTable.size() - 1); - } - - @Override - public void caseAEventBComprehensionSetExpression(AEventBComprehensionSetExpression node) { - contextTable.add(new LinkedHashMap<String, Node>()); - { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - putLocalVariableIntoCurrentScope((AIdentifierExpression) e); - } - } - node.getPredicates().apply(this); - - node.getExpression().apply(this); - contextTable.remove(contextTable.size() - 1); - } - - @Override - public void caseAQuantifiedUnionExpression(AQuantifiedUnionExpression node) { - contextTable.add(new LinkedHashMap<String, Node>()); - { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - putLocalVariableIntoCurrentScope((AIdentifierExpression) e); - } - } - if (node.getPredicates() != null) { - node.getPredicates().apply(this); - } - if (node.getExpression() != null) { - node.getExpression().apply(this); - } - contextTable.remove(contextTable.size() - 1); - } - - @Override - public void caseAQuantifiedIntersectionExpression(AQuantifiedIntersectionExpression node) { - contextTable.add(new LinkedHashMap<String, Node>()); - { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - putLocalVariableIntoCurrentScope((AIdentifierExpression) e); - } - } - if (node.getPredicates() != null) { - node.getPredicates().apply(this); - } - if (node.getExpression() != null) { - node.getExpression().apply(this); - } - contextTable.remove(contextTable.size() - 1); - } - - @Override - public void caseAGeneralProductExpression(AGeneralProductExpression node) { - contextTable.add(new LinkedHashMap<String, Node>()); - { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - putLocalVariableIntoCurrentScope((AIdentifierExpression) e); - } - } - if (node.getPredicates() != null) { - node.getPredicates().apply(this); - } - if (node.getExpression() != null) { - node.getExpression().apply(this); - } - contextTable.remove(contextTable.size() - 1); - } - - @Override - public void caseAGeneralSumExpression(AGeneralSumExpression node) { - contextTable.add(new LinkedHashMap<String, Node>()); - { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - putLocalVariableIntoCurrentScope((AIdentifierExpression) e); - } - } - if (node.getPredicates() != null) { - node.getPredicates().apply(this); - } - if (node.getExpression() != null) { - node.getExpression().apply(this); - } - contextTable.remove(contextTable.size() - 1); - } - - @Override - public void caseARecEntry(ARecEntry node) { - node.getValue().apply(this); - } - - @Override - public void caseARecordFieldExpression(ARecordFieldExpression node) { - node.getRecord().apply(this); - } - - public String getMachineName() { - return machineName; - } - - public PMachineHeader getHeader() { - return header; - } - - public Start getStartNode() { - return start; - } - - public LinkedHashMap<String, Node> getSetParamter() { - return new LinkedHashMap<>(machineSetParameter); - } - - public ArrayList<Node> getConstantArrayList() { - ArrayList<Node> list = new ArrayList<Node>(); - for (Entry<String, Node> entry : constants.entrySet()) { - list.add(entry.getValue()); - } - return list; - } - - public LinkedHashMap<String, Node> getScalarParameter() { - return new LinkedHashMap<>(machineScalarParameter); - } - - public LinkedHashMap<String, Node> getConstants() { - return constants; - } - - public LinkedHashMap<String, Node> getDefinitions() { - return new LinkedHashMap<>(definitions); - } - - public LinkedHashMap<String, Node> getVariables() { - return new LinkedHashMap<>(variables); - } - - public LinkedHashMap<String, Node> getOperations() { - return new LinkedHashMap<>(operations); - } - - public LinkedHashMap<String, Node> getDeferredSets() { - return new LinkedHashMap<>(deferredSets); - } - - public LinkedHashMap<String, Node> getEnumeratedSets() { - return new LinkedHashMap<>(enumeratedSets); - } - - public LinkedHashMap<String, Node> getEnumValues() { - return new LinkedHashMap<>(enumValues); - } - - public LinkedHashMap<String, AIdentifierExpression> getSeenMachines() { - return new LinkedHashMap<>(seenMachines); - } - - protected Hashtable<Node, Node> getReferences() { - return referencesTable; - } - - public Node getReferenceNode(Node node) { - return referencesTable.get(node); - } - - public void addReference(Node node, Node ref) { - referencesTable.put(node, ref); - } - - public ArrayList<LTLFormulaVisitor> getLTLFormulas() { - return ltlVisitors; - } - - public AAbstractMachineParseUnit getAbstractMachineParseUnit() { - return abstractMachineParseUnit; - } - - public AConstraintsMachineClause getConstraintMachineClause() { - return constraintMachineClause; - } - - public ASeesMachineClause getSeesMachineClause() { - return seesMachineClause; - } - - public ASetsContextClause getSetsMachineClause() { - return setsMachineClause; - } - - public APropertiesMachineClause getPropertiesMachineClause() { - return propertiesMachineClause; - } - - public AAssertionsMachineClause getAssertionMachineClause() { - return assertiondMachineClause; - } - - public void setPropertiesMachineClaus(APropertiesMachineClause propertiesMachineClause) { - this.propertiesMachineClause = propertiesMachineClause; - } - - public AInvariantMachineClause getInvariantMachineClause() { - return invariantMachineClause; - } - - public boolean machineContainsOperations() { - return operations.size() > 0; - } - - public AInitialisationMachineClause getInitialisationMachineClause() { - return initialisationMachineClause; - } - - public AOperationsMachineClause getOperationMachineClause() { - return operationMachineClause; - } - - public ADefinitionsMachineClause getDefinitionMachineClause() { - return definitionMachineClause; - } - - public void setDefinitionsMachineClause(ADefinitionsMachineClause definitionMachineClause) { - this.definitionMachineClause = definitionMachineClause; - } - - public PPredicate getConstantsSetup() { - return constantsSetupPredicate; - } - - public boolean hasConstants() { - return hasConstants; - } - -} +package de.tlc4b.analysis; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map.Entry; + +import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; +import de.be4.classicalb.core.parser.node.AAbstractConstantsMachineClause; +import de.be4.classicalb.core.parser.node.AAbstractMachineParseUnit; +import de.be4.classicalb.core.parser.node.AAnySubstitution; +import de.be4.classicalb.core.parser.node.AAssertionsMachineClause; +import de.be4.classicalb.core.parser.node.AAssignSubstitution; +import de.be4.classicalb.core.parser.node.AComprehensionSetExpression; +import de.be4.classicalb.core.parser.node.AConcreteVariablesMachineClause; +import de.be4.classicalb.core.parser.node.AConstantsMachineClause; +import de.be4.classicalb.core.parser.node.AConstraintsMachineClause; +import de.be4.classicalb.core.parser.node.ADeferredSetSet; +import de.be4.classicalb.core.parser.node.ADefinitionExpression; +import de.be4.classicalb.core.parser.node.ADefinitionPredicate; +import de.be4.classicalb.core.parser.node.ADefinitionSubstitution; +import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause; +import de.be4.classicalb.core.parser.node.AEnumeratedSetSet; +import de.be4.classicalb.core.parser.node.AEventBComprehensionSetExpression; +import de.be4.classicalb.core.parser.node.AExistsPredicate; +import de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition; +import de.be4.classicalb.core.parser.node.AForallPredicate; +import de.be4.classicalb.core.parser.node.AFunctionExpression; +import de.be4.classicalb.core.parser.node.AGeneralProductExpression; +import de.be4.classicalb.core.parser.node.AGeneralSumExpression; +import de.be4.classicalb.core.parser.node.AIdentifierExpression; +import de.be4.classicalb.core.parser.node.AInitialisationMachineClause; +import de.be4.classicalb.core.parser.node.AInvariantMachineClause; +import de.be4.classicalb.core.parser.node.ALambdaExpression; +import de.be4.classicalb.core.parser.node.ALetSubstitution; +import de.be4.classicalb.core.parser.node.AMachineHeader; +import de.be4.classicalb.core.parser.node.AOpSubstitution; +import de.be4.classicalb.core.parser.node.AOperation; +import de.be4.classicalb.core.parser.node.AOperationsMachineClause; +import de.be4.classicalb.core.parser.node.APredicateDefinitionDefinition; +import de.be4.classicalb.core.parser.node.APredicateParseUnit; +import de.be4.classicalb.core.parser.node.APrimedIdentifierExpression; +import de.be4.classicalb.core.parser.node.APropertiesMachineClause; +import de.be4.classicalb.core.parser.node.AQuantifiedIntersectionExpression; +import de.be4.classicalb.core.parser.node.AQuantifiedUnionExpression; +import de.be4.classicalb.core.parser.node.ARecEntry; +import de.be4.classicalb.core.parser.node.ARecordFieldExpression; +import de.be4.classicalb.core.parser.node.ASeesMachineClause; +import de.be4.classicalb.core.parser.node.ASetsContextClause; +import de.be4.classicalb.core.parser.node.ASubstitutionDefinitionDefinition; +import de.be4.classicalb.core.parser.node.AVariablesMachineClause; +import de.be4.classicalb.core.parser.node.Node; +import de.be4.classicalb.core.parser.node.PDefinition; +import de.be4.classicalb.core.parser.node.PExpression; +import de.be4.classicalb.core.parser.node.PMachineClause; +import de.be4.classicalb.core.parser.node.PMachineHeader; +import de.be4.classicalb.core.parser.node.POperation; +import de.be4.classicalb.core.parser.node.PPredicate; +import de.be4.classicalb.core.parser.node.PSet; +import de.be4.classicalb.core.parser.node.Start; +import de.be4.classicalb.core.parser.node.TIdentifierLiteral; +import de.be4.classicalb.core.parser.util.Utils; +import de.tlc4b.MP; +import de.tlc4b.TLC4BGlobals; +import de.tlc4b.analysis.transformation.DefinitionsSorter; +import de.tlc4b.analysis.transformation.MachineClauseSorter; +import de.tlc4b.exceptions.ScopeException; +import de.tlc4b.ltl.LTLBPredicate; +import de.tlc4b.ltl.LTLFormulaVisitor; + +public class MachineContext extends DepthFirstAdapter { + + private String machineName; + private final Start start; + + private final ArrayList<LTLFormulaVisitor> ltlVisitors; + private PPredicate constantsSetupPredicate; + private boolean hasConstants = false; + + private final LinkedHashMap<String, Node> machineSetParameter; + private final LinkedHashMap<String, Node> machineScalarParameter; + private final LinkedHashMap<String, Node> deferredSets; + private final LinkedHashMap<String, Node> enumeratedSets; + private final LinkedHashMap<String, Node> enumValues; + private final LinkedHashMap<String, Node> variables; + private final LinkedHashMap<String, Node> constants; + private final LinkedHashMap<String, Node> definitions; + private final LinkedHashMap<String, Node> operations; + private final LinkedHashMap<String, AIdentifierExpression> seenMachines; + + private PMachineHeader header; + private AAbstractMachineParseUnit abstractMachineParseUnit; + private AConstraintsMachineClause constraintMachineClause; + private ASeesMachineClause seesMachineClause; + private ASetsContextClause setsMachineClause; + private ADefinitionsMachineClause definitionMachineClause; + private APropertiesMachineClause propertiesMachineClause; + private AInvariantMachineClause invariantMachineClause; + private AInitialisationMachineClause initialisationMachineClause; + private AOperationsMachineClause operationMachineClause; + private AAssertionsMachineClause assertiondMachineClause; + + private ArrayList<LinkedHashMap<String, Node>> contextTable; + + protected final Hashtable<Node, Node> referencesTable; + + public MachineContext(final String machineName, final Start start) { + this.start = start; + this.machineName = machineName; + this.referencesTable = new Hashtable<Node, Node>(); + this.ltlVisitors = new ArrayList<LTLFormulaVisitor>(); + + this.machineSetParameter = new LinkedHashMap<String, Node>(); + this.machineScalarParameter = new LinkedHashMap<String, Node>(); + + this.deferredSets = new LinkedHashMap<String, Node>(); + this.enumeratedSets = new LinkedHashMap<String, Node>(); + this.enumValues = new LinkedHashMap<String, Node>(); + this.constants = new LinkedHashMap<String, Node>(); + this.variables = new LinkedHashMap<String, Node>(); + this.definitions = new LinkedHashMap<String, Node>(); + this.operations = new LinkedHashMap<String, Node>(); + this.seenMachines = new LinkedHashMap<String, AIdentifierExpression>(); + } + + public void analyseMachine() { + this.start.apply(this); + checkConstantsSetup(); + checkLTLFormulas(); + } + + public void addLTLFromula(final String ltlFormula) { + LTLFormulaVisitor ltlVisitor = new LTLFormulaVisitor("ltl", this); + ltlVisitor.parseLTLString(ltlFormula); + this.ltlVisitors.add(ltlVisitor); + } + + public void setConstantSetupPredicate(final PPredicate constantsSetup) { + this.constantsSetupPredicate = constantsSetup; + } + + private void checkConstantsSetup() { + if (constantsSetupPredicate == null) { + return; + } + this.contextTable = new ArrayList<LinkedHashMap<String, Node>>(); + ArrayList<MachineContext> list = lookupReferencedMachines(); + for (int i = 0; i < list.size(); i++) { + MachineContext s = list.get(i); + contextTable.add(s.getDeferredSets()); + contextTable.add(s.getEnumeratedSets()); + contextTable.add(s.getEnumValues()); + contextTable.add(s.getConstants()); + contextTable.add(s.getDefinitions()); + } + constantsSetupPredicate.apply(this); + } + + private void checkLTLFormulas() { + if (ltlVisitors.size() == 1) { + ltlVisitors.get(0).start(); + return; + } + ArrayList<LTLFormulaVisitor> formulasNotSupportedByTLC = new ArrayList<LTLFormulaVisitor>(); + for (int i = 0; i < ltlVisitors.size(); i++) { + LTLFormulaVisitor visitor = ltlVisitors.get(i); + try { + visitor.start(); + } catch (ScopeException e) { + MP.println("Warning: LTL formula '" + visitor.getName() + "' cannot be checked by TLC."); + formulasNotSupportedByTLC.add(visitor); + } + } + ltlVisitors.removeAll(formulasNotSupportedByTLC); + } + + public void checkLTLBPredicate(LTLBPredicate ltlbPredicate) { + contextTable = new ArrayList<LinkedHashMap<String, Node>>(); + contextTable.add(getDeferredSets()); + contextTable.add(getEnumeratedSets()); + contextTable.add(getEnumValues()); + contextTable.add(getConstants()); + contextTable.add(getVariables()); + contextTable.add(getDefinitions()); + + LinkedHashMap<String, Node> identifierHashTable = ltlbPredicate.getIdentifierList(); + if (identifierHashTable.size() > 0) { + LinkedHashMap<String, Node> currentContext = new LinkedHashMap<String, Node>(); + currentContext.putAll(identifierHashTable); + contextTable.add(currentContext); + } + ltlbPredicate.getBFormula().apply(this); + } + + private void exist(LinkedList<TIdentifierLiteral> list) { + String name = Utils.getTIdentifierListAsString(list); + identifierAlreadyExists(name); + } + + private void identifierAlreadyExists(String name) { + if (constants.containsKey(name) || variables.containsKey(name) || operations.containsKey(name) + || deferredSets.containsKey(name) || enumeratedSets.containsKey(name) || enumValues.containsKey(name) + || machineSetParameter.containsKey(name) || machineScalarParameter.containsKey(name) + || seenMachines.containsKey(name) || definitions.containsKey(name)) { + throw new ScopeException("Duplicate identifier: '" + name + "'"); + } + } + + @Override + public void caseAAbstractMachineParseUnit(AAbstractMachineParseUnit node) { + this.abstractMachineParseUnit = node; + if (node.getVariant() != null) { + node.getVariant().apply(this); + } + if (node.getHeader() != null) { + node.getHeader().apply(this); + } + + List<PMachineClause> machineClauses = node.getMachineClauses(); + // Sort the machine clauses: declarations clauses first, then + // properties clauses + MachineClauseSorter.sortMachineClauses(start); + + for (PMachineClause e : machineClauses) { + e.apply(this); + } + } + + @Override + public void caseAMachineHeader(AMachineHeader node) { + this.header = node; + if (machineName == null) { + List<TIdentifierLiteral> nameList = new ArrayList<TIdentifierLiteral>(node.getName()); + this.machineName = Utils.getTIdentifierListAsString(nameList); + } + + List<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); + for (PExpression e : copy) { + AIdentifierExpression p = (AIdentifierExpression) e; + String name = Utils.getTIdentifierListAsString(p.getIdentifier()); + exist(p.getIdentifier()); + if (Character.isUpperCase(name.charAt(0))) { + this.machineSetParameter.put(name, p); + } else { + this.machineScalarParameter.put(name, p); + } + } + } + + @Override + public void caseAPredicateParseUnit(APredicateParseUnit node) { + node.getPredicate().apply(this); + } + + /** + * Definitions + */ + + @Override + public void caseADefinitionsMachineClause(ADefinitionsMachineClause node) { + definitionMachineClause = node; + DefinitionsSorter.sortDefinitions(node); + + List<PDefinition> copy = node.getDefinitions(); + + /* + * The definitions are not in a predefined order. In particular + * definitions can depend on each other. First all definitions are added + * to the definitions context table. Then all definitions are visited. + */ + Collection<PDefinition> definitionsToRemove = new HashSet<PDefinition>(); + + for (PDefinition e : copy) { + if (e instanceof AExpressionDefinitionDefinition) { + AExpressionDefinitionDefinition def = (AExpressionDefinitionDefinition) e; + String name = def.getName().getText(); + if (name.startsWith("ASSERT_LTL")) { + if (TLC4BGlobals.isCheckLTL()) { + LTLFormulaVisitor visitor = new LTLFormulaVisitor(name, this); + visitor.parseDefinition(def); + this.ltlVisitors.add(visitor); + } + definitionsToRemove.add(def); + } else if (name.startsWith("ANIMATION_")) { + definitionsToRemove.add(def); + } + evalDefinitionName(((AExpressionDefinitionDefinition) e).getName().getText().toString(), e); + } else if (e instanceof APredicateDefinitionDefinition) { + evalDefinitionName(((APredicateDefinitionDefinition) e).getName().getText().toString(), e); + } else if (e instanceof ASubstitutionDefinitionDefinition) { + evalDefinitionName(((ASubstitutionDefinitionDefinition) e).getName().getText().toString(), e); + } + } + /* + * At this point all LTL definitions (ASSERT_LTL) are removed. LTL + * formulas are stored in the Arraylist {@value #ltlVisitors}. + */ + copy.removeAll(definitionsToRemove); + this.contextTable = new ArrayList<LinkedHashMap<String, Node>>(); + ArrayList<MachineContext> list = lookupReferencedMachines(); + for (int i = 0; i < list.size(); i++) { + MachineContext s = list.get(i); + contextTable.add(s.getDeferredSets()); + contextTable.add(s.getEnumeratedSets()); + contextTable.add(s.getEnumValues()); + contextTable.add(s.getConstants()); + contextTable.add(s.getVariables()); + contextTable.add(s.getDefinitions()); + } + + for (PDefinition e : copy) { + e.apply(this); + } + } + + private void evalDefinitionName(String name, Node node) { + identifierAlreadyExists(name); + definitions.put(name, node); + } + + @Override + public void caseAExpressionDefinitionDefinition(AExpressionDefinitionDefinition node) { + visitBDefinition(node, node.getName().getText().toString(), node.getParameters(), node.getRhs()); + } + + @Override + public void caseAPredicateDefinitionDefinition(APredicateDefinitionDefinition node) { + visitBDefinition(node, node.getName().getText().toString(), node.getParameters(), node.getRhs()); + } + + /* d == x := 1 */ + @Override + public void caseASubstitutionDefinitionDefinition(ASubstitutionDefinitionDefinition node) { + visitBDefinition(node, node.getName().getText().toString(), node.getParameters(), node.getRhs()); + + } + + public void visitBDefinition(Node node, String name, List<PExpression> copy, Node rightSide) { + if (!this.definitions.containsValue(node)) { + return; + } + contextTable.add(new LinkedHashMap<String, Node>()); + for (PExpression e : copy) { + putLocalVariableIntoCurrentScope((AIdentifierExpression) e); + } + rightSide.apply(this); + contextTable.remove(contextTable.size() - 1); + } + + @Override + public void caseADefinitionExpression(ADefinitionExpression node) { + visitBDefinitionCall(node, node.getDefLiteral().getText().toString(), node.getParameters()); + } + + @Override + public void caseADefinitionPredicate(ADefinitionPredicate node) { + visitBDefinitionCall(node, node.getDefLiteral().getText().toString(), node.getParameters()); + } + + @Override + public void caseADefinitionSubstitution(ADefinitionSubstitution node) { + visitBDefinitionCall(node, node.getDefLiteral().getText().toString(), node.getParameters()); + } + + private void visitBDefinitionCall(Node node, String name, List<PExpression> copy) { + for (PExpression pExpression : copy) { + pExpression.apply(this); + } + for (int i = contextTable.size() - 1; i >= 0; i--) { + LinkedHashMap<String, Node> currentScope = contextTable.get(i); + if (currentScope.containsKey(name)) { + this.referencesTable.put(node, currentScope.get(name)); + return; + } + } + throw new ScopeException("Unkown definition: '" + name + "' at position: " + node.getStartPos()); + } + + @Override + public void caseASeesMachineClause(ASeesMachineClause node) { + this.seesMachineClause = node; + List<PExpression> copy = new ArrayList<PExpression>(node.getMachineNames()); + for (PExpression e : copy) { + AIdentifierExpression p = (AIdentifierExpression) e; + String name = Utils.getTIdentifierListAsString(p.getIdentifier()); + + try { + exist(p.getIdentifier()); + } catch (ScopeException e2) { + throw new ScopeException("Machine '" + name + "' is seen twice."); + } + seenMachines.put(name, p); + } + } + + @Override + public void caseASetsContextClause(ASetsContextClause node) { + this.setsMachineClause = node; + List<PSet> copy = new ArrayList<PSet>(node.getSet()); + for (PSet e : copy) { + e.apply(this); + } + } + + @Override + public void caseADeferredSetSet(ADeferredSetSet node) { + List<TIdentifierLiteral> copy = new ArrayList<TIdentifierLiteral>(node.getIdentifier()); + String name = Utils.getTIdentifierListAsString(copy); + exist(node.getIdentifier()); + deferredSets.put(name, node); + } + + @Override + public void caseAEnumeratedSetSet(AEnumeratedSetSet node) { + { + List<TIdentifierLiteral> copy = new ArrayList<TIdentifierLiteral>(node.getIdentifier()); + String name = Utils.getTIdentifierListAsString(copy); + exist(node.getIdentifier()); + enumeratedSets.put(name, node); + } + List<PExpression> copy = new ArrayList<PExpression>(node.getElements()); + for (PExpression e : copy) { + AIdentifierExpression v = (AIdentifierExpression) e; + String name = Utils.getTIdentifierListAsString(v.getIdentifier()); + exist(v.getIdentifier()); + enumValues.put(name, v); + } + } + + @Override + public void caseAConstantsMachineClause(AConstantsMachineClause node) { + hasConstants = true; + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + AIdentifierExpression c = (AIdentifierExpression) e; + String name = Utils.getTIdentifierListAsString(c.getIdentifier()); + exist(c.getIdentifier()); + constants.put(name, c); + } + } + + @Override + public void caseAAbstractConstantsMachineClause(AAbstractConstantsMachineClause node) { + hasConstants = true; + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + AIdentifierExpression c = (AIdentifierExpression) e; + String name = Utils.getTIdentifierListAsString(c.getIdentifier()); + exist(c.getIdentifier()); + constants.put(name, c); + } + } + + @Override + public void caseAVariablesMachineClause(AVariablesMachineClause node) { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + AIdentifierExpression v = (AIdentifierExpression) e; + String name = Utils.getTIdentifierListAsString(v.getIdentifier()); + exist(v.getIdentifier()); + variables.put(name, v); + } + } + + @Override + public void caseAConcreteVariablesMachineClause(AConcreteVariablesMachineClause node) { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + AIdentifierExpression v = (AIdentifierExpression) e; + String name = Utils.getTIdentifierListAsString(v.getIdentifier()); + exist(v.getIdentifier()); + variables.put(name, v); + } + } + + private void putLocalVariableIntoCurrentScope(AIdentifierExpression node) throws ScopeException { + String name = Utils.getTIdentifierListAsString(node.getIdentifier()); + LinkedHashMap<String, Node> currentScope = contextTable.get(contextTable.size() - 1); + if (currentScope.containsKey(name)) { + throw new ScopeException("Duplicate Identifier: " + name); + } else { + currentScope.put(name, node); + } + } + + @Override + public void caseAIdentifierExpression(AIdentifierExpression node) { + String name = Utils.getTIdentifierListAsString(node.getIdentifier()); + for (int i = contextTable.size() - 1; i >= 0; i--) { + LinkedHashMap<String, Node> currentScope = contextTable.get(i); + if (currentScope.containsKey(name)) { + this.referencesTable.put(node, currentScope.get(name)); + return; + } + } + throw new ScopeException("Unkown Identifier: '" + name + "' at position: " + node.getStartPos()); + } + + @Override + public void caseAPrimedIdentifierExpression(APrimedIdentifierExpression node) { + String name = Utils.getTIdentifierListAsString(node.getIdentifier()); + for (int i = contextTable.size() - 1; i >= 0; i--) { + LinkedHashMap<String, Node> currentScope = contextTable.get(i); + if (currentScope.containsKey(name)) { + this.referencesTable.put(node, currentScope.get(name)); + return; + } + } + throw new ScopeException("Unkown Identifier: '" + name + "' at position: " + node.getStartPos()); + } + + private ArrayList<MachineContext> lookupReferencedMachines() { + ArrayList<MachineContext> list = new ArrayList<MachineContext>(); + list.add(this); + return list; + } + + @Override + public void caseAConstraintsMachineClause(AConstraintsMachineClause node) { + this.constraintMachineClause = node; + + this.contextTable = new ArrayList<LinkedHashMap<String, Node>>(); + this.contextTable.add(this.machineScalarParameter); + this.contextTable.add(this.machineSetParameter); + if (node.getPredicates() != null) { + node.getPredicates().apply(this); + } + } + + @Override + public void caseAPropertiesMachineClause(APropertiesMachineClause node) { + this.propertiesMachineClause = node; + hasConstants = true; + /** + * check identifier scope in properties clauses + */ + + this.contextTable = new ArrayList<LinkedHashMap<String, Node>>(); + ArrayList<MachineContext> list = lookupReferencedMachines(); + for (int i = 0; i < list.size(); i++) { + MachineContext s = list.get(i); + contextTable.add(s.getDeferredSets()); + contextTable.add(s.getEnumeratedSets()); + contextTable.add(s.getEnumValues()); + contextTable.add(s.getConstants()); + contextTable.add(s.getDefinitions()); + } + if (node.getPredicates() != null) { + node.getPredicates().apply(this); + } + } + + @Override + public void caseAInvariantMachineClause(AInvariantMachineClause node) { + this.invariantMachineClause = node; + + this.contextTable = new ArrayList<LinkedHashMap<String, Node>>(); + + ArrayList<MachineContext> list = lookupReferencedMachines(); + for (int i = 0; i < list.size(); i++) { + MachineContext s = list.get(i); + this.contextTable.add(s.getSetParamter()); + this.contextTable.add(s.getScalarParameter()); + this.contextTable.add(s.getDeferredSets()); + this.contextTable.add(s.getEnumeratedSets()); + this.contextTable.add(s.getEnumValues()); + this.contextTable.add(s.getConstants()); + this.contextTable.add(s.getDefinitions()); + this.contextTable.add(s.getVariables()); + } + node.getPredicates().apply(this); + } + + @Override + public void caseAAssertionsMachineClause(AAssertionsMachineClause node) { + this.assertiondMachineClause = node; + + this.contextTable = new ArrayList<LinkedHashMap<String, Node>>(); + ArrayList<MachineContext> list = lookupReferencedMachines(); + for (int i = 0; i < list.size(); i++) { + MachineContext s = list.get(i); + this.contextTable.add(s.getSetParamter()); + this.contextTable.add(s.getScalarParameter()); + this.contextTable.add(s.getDeferredSets()); + this.contextTable.add(s.getEnumeratedSets()); + this.contextTable.add(s.getEnumValues()); + this.contextTable.add(s.getConstants()); + this.contextTable.add(s.getDefinitions()); + this.contextTable.add(s.getVariables()); + } + + List<PPredicate> copy = new ArrayList<PPredicate>(node.getPredicates()); + for (PPredicate e : copy) { + e.apply(this); + } + } + + @Override + public void caseAInitialisationMachineClause(AInitialisationMachineClause node) { + this.initialisationMachineClause = node; + + this.contextTable = new ArrayList<LinkedHashMap<String, Node>>(); + + ArrayList<MachineContext> list = lookupReferencedMachines(); + for (int i = 0; i < list.size(); i++) { + MachineContext s = list.get(i); + + this.contextTable.add(s.getSetParamter()); + this.contextTable.add(s.getScalarParameter()); + this.contextTable.add(s.getDeferredSets()); + this.contextTable.add(s.getEnumeratedSets()); + this.contextTable.add(s.getEnumValues()); + this.contextTable.add(s.getConstants()); + this.contextTable.add(s.getDefinitions()); + this.contextTable.add(s.getVariables()); + } + if (node.getSubstitutions() != null) { + node.getSubstitutions().apply(this); + } + } + + @Override + public void caseAOperationsMachineClause(AOperationsMachineClause node) { + this.operationMachineClause = node; + this.contextTable = new ArrayList<LinkedHashMap<String, Node>>(); + ArrayList<MachineContext> list = lookupReferencedMachines(); + for (int i = 0; i < list.size(); i++) { + MachineContext s = list.get(i); + this.contextTable.add(s.getSetParamter()); + this.contextTable.add(s.getScalarParameter()); + this.contextTable.add(s.getDeferredSets()); + this.contextTable.add(s.getEnumeratedSets()); + this.contextTable.add(s.getEnumValues()); + this.contextTable.add(s.getConstants()); + this.contextTable.add(s.getDefinitions()); + this.contextTable.add(s.getVariables()); + } + List<POperation> copy = new ArrayList<POperation>(node.getOperations()); + // first collect all operations + for (POperation e : copy) { + AOperation op = (AOperation) e; + String name = Utils.getTIdentifierListAsString(op.getOpName()); + // existString(name); + if (operations.keySet().contains(name)) { + throw new ScopeException(String.format("Duplicate operation: '%s'", name)); + } + operations.put(name, op); + } + // visit all operations + for (POperation e : copy) { + e.apply(this); + } + } + + @Override + public void caseAOperation(AOperation node) { + contextTable.add(new LinkedHashMap<String, Node>()); + { + List<PExpression> copy = new ArrayList<PExpression>(node.getReturnValues()); + for (PExpression e : copy) { + AIdentifierExpression id = (AIdentifierExpression) e; + exist(id.getIdentifier()); + putLocalVariableIntoCurrentScope((AIdentifierExpression) e); + } + } + + { + List<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); + for (PExpression e : copy) { + AIdentifierExpression id = (AIdentifierExpression) e; + exist(id.getIdentifier()); + putLocalVariableIntoCurrentScope((AIdentifierExpression) e); + } + } + if (node.getOperationBody() != null) { + node.getOperationBody().apply(this); + } + contextTable.remove(contextTable.size() - 1); + } + + @Override + public void caseAAssignSubstitution(AAssignSubstitution node) { + ArrayList<LinkedHashMap<String, Node>> temp = contextTable; + { + List<PExpression> copy = new ArrayList<PExpression>(node.getLhsExpression()); + ArrayList<LinkedHashMap<String, Node>> varTable = new ArrayList<LinkedHashMap<String, Node>>(); + varTable.add(variables); + for (PExpression e : copy) { + if (e instanceof AFunctionExpression) { + contextTable = varTable; + ((AFunctionExpression) e).getIdentifier().apply(this); + + // full context table + contextTable = temp; + for (Node n : ((AFunctionExpression) e).getParameters()) { + n.apply(this); + } + } else { + contextTable = temp; // TODO outputparameter + variables + e.apply(this); + } + } + } + { + contextTable = temp; + List<PExpression> copy = new ArrayList<PExpression>(node.getRhsExpressions()); + for (PExpression e : copy) { + e.apply(this); + } + } + } + + @Override + public void caseALetSubstitution(ALetSubstitution node) { + contextTable.add(new LinkedHashMap<String, Node>()); + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + putLocalVariableIntoCurrentScope((AIdentifierExpression) e); + } + node.getPredicate().apply(this); + node.getSubstitution().apply(this); + } + + @Override + public void caseAAnySubstitution(AAnySubstitution node) { + contextTable.add(new LinkedHashMap<String, Node>()); + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + putLocalVariableIntoCurrentScope((AIdentifierExpression) e); + } + node.getWhere().apply(this); + node.getThen().apply(this); + } + + @Override + public void caseAOpSubstitution(AOpSubstitution node) { + if (node.getName() != null) { + AIdentifierExpression op = (AIdentifierExpression) node.getName(); + String name = Utils.getTIdentifierListAsString(op.getIdentifier()); + Node o = operations.get(name); + if (o != null) { + this.referencesTable.put(op, o); + } else { + throw new ScopeException("Unknown operation '" + name + "'"); + } + } + { + List<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); + for (PExpression e : copy) { + e.apply(this); + } + } + } + + @Override + public void caseAForallPredicate(AForallPredicate node) { + contextTable.add(new LinkedHashMap<String, Node>()); + { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + putLocalVariableIntoCurrentScope((AIdentifierExpression) e); + } + } + if (node.getImplication() != null) { + node.getImplication().apply(this); + } + contextTable.remove(contextTable.size() - 1); + } + + @Override + public void caseAExistsPredicate(AExistsPredicate node) { + contextTable.add(new LinkedHashMap<String, Node>()); + { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + putLocalVariableIntoCurrentScope((AIdentifierExpression) e); + } + } + if (node.getPredicate() != null) { + node.getPredicate().apply(this); + } + contextTable.remove(contextTable.size() - 1); + } + + @Override + public void caseALambdaExpression(ALambdaExpression node) { + contextTable.add(new LinkedHashMap<String, Node>()); + { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + putLocalVariableIntoCurrentScope((AIdentifierExpression) e); + } + } + node.getPredicate().apply(this); + node.getExpression().apply(this); + contextTable.remove(contextTable.size() - 1); + } + + @Override + public void caseAComprehensionSetExpression(AComprehensionSetExpression node) { + contextTable.add(new LinkedHashMap<String, Node>()); + { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + putLocalVariableIntoCurrentScope((AIdentifierExpression) e); + } + } + node.getPredicates().apply(this); + contextTable.remove(contextTable.size() - 1); + } + + @Override + public void caseAEventBComprehensionSetExpression(AEventBComprehensionSetExpression node) { + contextTable.add(new LinkedHashMap<String, Node>()); + { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + putLocalVariableIntoCurrentScope((AIdentifierExpression) e); + } + } + node.getPredicates().apply(this); + + node.getExpression().apply(this); + contextTable.remove(contextTable.size() - 1); + } + + @Override + public void caseAQuantifiedUnionExpression(AQuantifiedUnionExpression node) { + contextTable.add(new LinkedHashMap<String, Node>()); + { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + putLocalVariableIntoCurrentScope((AIdentifierExpression) e); + } + } + if (node.getPredicates() != null) { + node.getPredicates().apply(this); + } + if (node.getExpression() != null) { + node.getExpression().apply(this); + } + contextTable.remove(contextTable.size() - 1); + } + + @Override + public void caseAQuantifiedIntersectionExpression(AQuantifiedIntersectionExpression node) { + contextTable.add(new LinkedHashMap<String, Node>()); + { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + putLocalVariableIntoCurrentScope((AIdentifierExpression) e); + } + } + if (node.getPredicates() != null) { + node.getPredicates().apply(this); + } + if (node.getExpression() != null) { + node.getExpression().apply(this); + } + contextTable.remove(contextTable.size() - 1); + } + + @Override + public void caseAGeneralProductExpression(AGeneralProductExpression node) { + contextTable.add(new LinkedHashMap<String, Node>()); + { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + putLocalVariableIntoCurrentScope((AIdentifierExpression) e); + } + } + if (node.getPredicates() != null) { + node.getPredicates().apply(this); + } + if (node.getExpression() != null) { + node.getExpression().apply(this); + } + contextTable.remove(contextTable.size() - 1); + } + + @Override + public void caseAGeneralSumExpression(AGeneralSumExpression node) { + contextTable.add(new LinkedHashMap<String, Node>()); + { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + putLocalVariableIntoCurrentScope((AIdentifierExpression) e); + } + } + if (node.getPredicates() != null) { + node.getPredicates().apply(this); + } + if (node.getExpression() != null) { + node.getExpression().apply(this); + } + contextTable.remove(contextTable.size() - 1); + } + + @Override + public void caseARecEntry(ARecEntry node) { + node.getValue().apply(this); + } + + @Override + public void caseARecordFieldExpression(ARecordFieldExpression node) { + node.getRecord().apply(this); + } + + public String getMachineName() { + return machineName; + } + + public PMachineHeader getHeader() { + return header; + } + + public Start getStartNode() { + return start; + } + + public LinkedHashMap<String, Node> getSetParamter() { + return new LinkedHashMap<>(machineSetParameter); + } + + public ArrayList<Node> getConstantArrayList() { + ArrayList<Node> list = new ArrayList<Node>(); + for (Entry<String, Node> entry : constants.entrySet()) { + list.add(entry.getValue()); + } + return list; + } + + public LinkedHashMap<String, Node> getScalarParameter() { + return new LinkedHashMap<>(machineScalarParameter); + } + + public LinkedHashMap<String, Node> getConstants() { + return constants; + } + + public LinkedHashMap<String, Node> getDefinitions() { + return new LinkedHashMap<>(definitions); + } + + public LinkedHashMap<String, Node> getVariables() { + return new LinkedHashMap<>(variables); + } + + public LinkedHashMap<String, Node> getOperations() { + return new LinkedHashMap<>(operations); + } + + public LinkedHashMap<String, Node> getDeferredSets() { + return new LinkedHashMap<>(deferredSets); + } + + public LinkedHashMap<String, Node> getEnumeratedSets() { + return new LinkedHashMap<>(enumeratedSets); + } + + public LinkedHashMap<String, Node> getEnumValues() { + return new LinkedHashMap<>(enumValues); + } + + public LinkedHashMap<String, AIdentifierExpression> getSeenMachines() { + return new LinkedHashMap<>(seenMachines); + } + + protected Hashtable<Node, Node> getReferences() { + return referencesTable; + } + + public Node getReferenceNode(Node node) { + return referencesTable.get(node); + } + + public void addReference(Node node, Node ref) { + referencesTable.put(node, ref); + } + + public ArrayList<LTLFormulaVisitor> getLTLFormulas() { + return ltlVisitors; + } + + public AAbstractMachineParseUnit getAbstractMachineParseUnit() { + return abstractMachineParseUnit; + } + + public AConstraintsMachineClause getConstraintMachineClause() { + return constraintMachineClause; + } + + public ASeesMachineClause getSeesMachineClause() { + return seesMachineClause; + } + + public ASetsContextClause getSetsMachineClause() { + return setsMachineClause; + } + + public APropertiesMachineClause getPropertiesMachineClause() { + return propertiesMachineClause; + } + + public AAssertionsMachineClause getAssertionMachineClause() { + return assertiondMachineClause; + } + + public void setPropertiesMachineClaus(APropertiesMachineClause propertiesMachineClause) { + this.propertiesMachineClause = propertiesMachineClause; + } + + public AInvariantMachineClause getInvariantMachineClause() { + return invariantMachineClause; + } + + public boolean machineContainsOperations() { + return operations.size() > 0; + } + + public AInitialisationMachineClause getInitialisationMachineClause() { + return initialisationMachineClause; + } + + public AOperationsMachineClause getOperationMachineClause() { + return operationMachineClause; + } + + public ADefinitionsMachineClause getDefinitionMachineClause() { + return definitionMachineClause; + } + + public void setDefinitionsMachineClause(ADefinitionsMachineClause definitionMachineClause) { + this.definitionMachineClause = definitionMachineClause; + } + + public PPredicate getConstantsSetup() { + return constantsSetupPredicate; + } + + public boolean hasConstants() { + return hasConstants; + } + +} diff --git a/src/main/java/de/tlc4b/analysis/PrecedenceCollector.java b/src/main/java/de/tlc4b/analysis/PrecedenceCollector.java index 63389ad5b0893f8898eeeeb642d9a40fae068304..1e9c694be48687f6ff9cd01a882a5688a758d541 100644 --- a/src/main/java/de/tlc4b/analysis/PrecedenceCollector.java +++ b/src/main/java/de/tlc4b/analysis/PrecedenceCollector.java @@ -1,240 +1,240 @@ -package de.tlc4b.analysis; - -import java.util.HashSet; -import java.util.Hashtable; - -import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; -import de.be4.classicalb.core.parser.node.AConvertBoolExpression; -import de.be4.classicalb.core.parser.node.ADomainExpression; -import de.be4.classicalb.core.parser.node.ALabelPredicate; -import de.be4.classicalb.core.parser.node.AMinusOrSetSubtractExpression; -import de.be4.classicalb.core.parser.node.AMultOrCartExpression; -import de.be4.classicalb.core.parser.node.Node; -import de.be4.classicalb.core.parser.node.Start; -import de.tlc4b.analysis.typerestriction.TypeRestrictor; -import de.tlc4b.btypes.BType; -import de.tlc4b.btypes.FunctionType; -import de.tlc4b.btypes.IntegerType; - -public class PrecedenceCollector extends DepthFirstAdapter { - - private final static Hashtable<String, Precedence> PRECEDENCES = new Hashtable<String, Precedence>(); - - private static void put(String s, int from, int to, boolean leftAssociative) { - PRECEDENCES.put(s, new Precedence(s, from, to, leftAssociative)); - } - - static { - - put("AImplicationPredicate", 1, 1, false); - put("AExistsPredicate", 1, 1, false); - put("AForallPredicate", 1, 1, false); - put("AEquivalencePredicate", 2, 2, false); - put("ADisjunctPredicate", 3, 3, true); // or - - /** and **/ - put("AConjunctPredicate", 3, 3, true); - put("APreconditionSubstitution", 3, 3, true); - put("AAssertionSubstitution", 3, 3, true); - put("ASelectWhenSubstitution", 3, 3, true); - put("AParallelSubstitution", 3, 3, true); - - put("ASelectSubstitution", 3, 3, true); // and or or - - put("AEqualPredicate", 5, 5, false); - put("ALessPredicate", 5, 5, false); - put("AGreaterPredicate", 5, 5, false); - put("ALessEqualPredicate", 5, 5, false); - put("AGreaterEqualPredicate", 5, 5, false); - put("ANotEqualPredicate", 5, 5, false); - put("APowerOfExpression", 14, 14, false); - put("ASubsetPredicate", 5, 5, false); - // put("ANatural1SetExpression", 8, 8, false); // NAT \ {0} - - put("APowSubsetExpression", 8, 8, false); - put("AUnionExpression", 8, 8, true); - put("AIntersectionExpression", 8, 8, true); - put("AUnionExpression", 8, 8, true); - put("ASetSubtractionExpression", 8, 8, false); - put("AIntervalExpression", 9, 9, true); - - put("ACartesianProductExpression", 8, 13, false); - - put("AAddExpression", 10, 10, true); - - put("AModuloExpression", 10, 11, true); - put("AUnaryMinusExpression", 12, 12, false); - put("AConcatExpression", 13, 13, true); - put("ADivExpression", 13, 13, false); - - put("AFunctionExpression", 20, 20, false); - - } - - private Precedence getPrecedence(Node node) { - String name = node.getClass().getSimpleName(); - return PRECEDENCES.get(name); - } - - private final Hashtable<Node, Precedence> precedenceTable; - private final HashSet<Node> brackets; - private final Typechecker typechecker; - - public HashSet<Node> getBrackets() { - return brackets; - } - - public PrecedenceCollector(Start start, Typechecker typeChecker, - MachineContext machineContext, TypeRestrictor typeRestrictor) { - precedenceTable = new Hashtable<Node, Precedence>(); - brackets = new HashSet<Node>(); - this.typechecker = typeChecker; - start.apply(this); - - if (machineContext.getConstantsSetup() != null) { - machineContext.getConstantsSetup().apply(this); - } - - for (Node node : typeRestrictor.getAllRestrictedNodes()) { - node.apply(this); - } - - } - - @Override - public void caseStart(final Start node) { - inStart(node); - node.getPParseUnit().apply(this); - node.getEOF().apply(this); - outStart(node); - } - - @Override - public void defaultIn(final Node node) { - Node parent = node.parent(); - Precedence p = getPrecedence(node); - if (p != null) { - precedenceTable.put(node, p); - if (parent instanceof ALabelPredicate) { - parent = parent.parent(); - } - - if (parent != null) { - Precedence parentPrecedence = precedenceTable - .get(node.parent()); - if (Precedence.makeBrackets(p, parentPrecedence)) { - brackets.add(node); - } - } - } - // System.out.println(node.getClass().getSimpleName() + " " + p ); - } - - public void inAConvertBoolExpression(AConvertBoolExpression node) { - Precedence parent = PRECEDENCES.get(node.parent().getClass() - .getSimpleName()); - if (parent != null) { - precedenceTable.put(node, parent); - } - } - - @Override - public void inAMultOrCartExpression(AMultOrCartExpression node) { - BType type = typechecker.getType(node); - - Precedence p; - if (type instanceof IntegerType) { - // integer - p = new Precedence("AMultOrCartExpression", 13, 13, true); - } else { - // \times - p = new Precedence("AMultOrCartExpression", 8, 13, false); - } - precedenceTable.put(node, p); - - Precedence parent = precedenceTable.get(node.parent()); - if (Precedence.makeBrackets(p, parent)) { - brackets.add(node); - } - } - - @Override - public void inADomainExpression(ADomainExpression node) { - BType type = typechecker.getType(node.getExpression()); - - Precedence p; - if (type instanceof FunctionType) { - // Function - p = new Precedence("ADomainExpression", 9, 9, false); - - precedenceTable.put(node, p); - - Precedence parent = precedenceTable.get(node.parent()); - if (Precedence.makeBrackets(p, parent)) { - brackets.add(node); - } - } - - } - - @Override - public void inAMinusOrSetSubtractExpression( - AMinusOrSetSubtractExpression node) { - BType type = typechecker.getType(node); - Precedence p; - if (type instanceof IntegerType) { - // minus - p = new Precedence("AMinusOrSetSubtractExpression", 11, 11, true); - } else { - // set difference - p = new Precedence("AMinusOrSetSubtractExpression", 8, 8, false); - } - precedenceTable.put(node, p); - - Precedence parent = precedenceTable.get(node.parent()); - if (Precedence.makeBrackets(p, parent)) { - brackets.add(node); - } - } - -} - -class Precedence { - int from; - int to; - String name; - boolean leftAssociative; - - public Precedence(String s, int from, int to, boolean leftAssociative) { - this.from = from; - this.to = to; - this.name = s; - this.leftAssociative = leftAssociative; - } - - public static boolean makeBrackets(Precedence node, Precedence parent) { - if (parent == null) - return false; - - if (node.name.equals(parent.name)) { - if (node.leftAssociative) { - return false; - } - - } - if (node.from >= parent.from && node.from <= parent.to - || node.to >= parent.from && node.to <= parent.to) { - return true; - } - if (parent.from > node.from) - return true; - - return false; - } - - @Override - public String toString() { - return from + "-" + to; - } - -} +package de.tlc4b.analysis; + +import java.util.HashSet; +import java.util.Hashtable; + +import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; +import de.be4.classicalb.core.parser.node.AConvertBoolExpression; +import de.be4.classicalb.core.parser.node.ADomainExpression; +import de.be4.classicalb.core.parser.node.ALabelPredicate; +import de.be4.classicalb.core.parser.node.AMinusOrSetSubtractExpression; +import de.be4.classicalb.core.parser.node.AMultOrCartExpression; +import de.be4.classicalb.core.parser.node.Node; +import de.be4.classicalb.core.parser.node.Start; +import de.tlc4b.analysis.typerestriction.TypeRestrictor; +import de.tlc4b.btypes.BType; +import de.tlc4b.btypes.FunctionType; +import de.tlc4b.btypes.IntegerType; + +public class PrecedenceCollector extends DepthFirstAdapter { + + private final static Hashtable<String, Precedence> PRECEDENCES = new Hashtable<String, Precedence>(); + + private static void put(String s, int from, int to, boolean leftAssociative) { + PRECEDENCES.put(s, new Precedence(s, from, to, leftAssociative)); + } + + static { + + put("AImplicationPredicate", 1, 1, false); + put("AExistsPredicate", 1, 1, false); + put("AForallPredicate", 1, 1, false); + put("AEquivalencePredicate", 2, 2, false); + put("ADisjunctPredicate", 3, 3, true); // or + + /** and **/ + put("AConjunctPredicate", 3, 3, true); + put("APreconditionSubstitution", 3, 3, true); + put("AAssertionSubstitution", 3, 3, true); + put("ASelectWhenSubstitution", 3, 3, true); + put("AParallelSubstitution", 3, 3, true); + + put("ASelectSubstitution", 3, 3, true); // and or or + + put("AEqualPredicate", 5, 5, false); + put("ALessPredicate", 5, 5, false); + put("AGreaterPredicate", 5, 5, false); + put("ALessEqualPredicate", 5, 5, false); + put("AGreaterEqualPredicate", 5, 5, false); + put("ANotEqualPredicate", 5, 5, false); + put("APowerOfExpression", 14, 14, false); + put("ASubsetPredicate", 5, 5, false); + // put("ANatural1SetExpression", 8, 8, false); // NAT \ {0} + + put("APowSubsetExpression", 8, 8, false); + put("AUnionExpression", 8, 8, true); + put("AIntersectionExpression", 8, 8, true); + put("AUnionExpression", 8, 8, true); + put("ASetSubtractionExpression", 8, 8, false); + put("AIntervalExpression", 9, 9, true); + + put("ACartesianProductExpression", 8, 13, false); + + put("AAddExpression", 10, 10, true); + + put("AModuloExpression", 10, 11, true); + put("AUnaryMinusExpression", 12, 12, false); + put("AConcatExpression", 13, 13, true); + put("ADivExpression", 13, 13, false); + + put("AFunctionExpression", 20, 20, false); + + } + + private Precedence getPrecedence(Node node) { + String name = node.getClass().getSimpleName(); + return PRECEDENCES.get(name); + } + + private final Hashtable<Node, Precedence> precedenceTable; + private final HashSet<Node> brackets; + private final Typechecker typechecker; + + public HashSet<Node> getBrackets() { + return brackets; + } + + public PrecedenceCollector(Start start, Typechecker typeChecker, + MachineContext machineContext, TypeRestrictor typeRestrictor) { + precedenceTable = new Hashtable<Node, Precedence>(); + brackets = new HashSet<Node>(); + this.typechecker = typeChecker; + start.apply(this); + + if (machineContext.getConstantsSetup() != null) { + machineContext.getConstantsSetup().apply(this); + } + + for (Node node : typeRestrictor.getAllRestrictedNodes()) { + node.apply(this); + } + + } + + @Override + public void caseStart(final Start node) { + inStart(node); + node.getPParseUnit().apply(this); + node.getEOF().apply(this); + outStart(node); + } + + @Override + public void defaultIn(final Node node) { + Node parent = node.parent(); + Precedence p = getPrecedence(node); + if (p != null) { + precedenceTable.put(node, p); + if (parent instanceof ALabelPredicate) { + parent = parent.parent(); + } + + if (parent != null) { + Precedence parentPrecedence = precedenceTable + .get(node.parent()); + if (Precedence.makeBrackets(p, parentPrecedence)) { + brackets.add(node); + } + } + } + // System.out.println(node.getClass().getSimpleName() + " " + p ); + } + + public void inAConvertBoolExpression(AConvertBoolExpression node) { + Precedence parent = PRECEDENCES.get(node.parent().getClass() + .getSimpleName()); + if (parent != null) { + precedenceTable.put(node, parent); + } + } + + @Override + public void inAMultOrCartExpression(AMultOrCartExpression node) { + BType type = typechecker.getType(node); + + Precedence p; + if (type instanceof IntegerType) { + // integer + p = new Precedence("AMultOrCartExpression", 13, 13, true); + } else { + // \times + p = new Precedence("AMultOrCartExpression", 8, 13, false); + } + precedenceTable.put(node, p); + + Precedence parent = precedenceTable.get(node.parent()); + if (Precedence.makeBrackets(p, parent)) { + brackets.add(node); + } + } + + @Override + public void inADomainExpression(ADomainExpression node) { + BType type = typechecker.getType(node.getExpression()); + + Precedence p; + if (type instanceof FunctionType) { + // Function + p = new Precedence("ADomainExpression", 9, 9, false); + + precedenceTable.put(node, p); + + Precedence parent = precedenceTable.get(node.parent()); + if (Precedence.makeBrackets(p, parent)) { + brackets.add(node); + } + } + + } + + @Override + public void inAMinusOrSetSubtractExpression( + AMinusOrSetSubtractExpression node) { + BType type = typechecker.getType(node); + Precedence p; + if (type instanceof IntegerType) { + // minus + p = new Precedence("AMinusOrSetSubtractExpression", 11, 11, true); + } else { + // set difference + p = new Precedence("AMinusOrSetSubtractExpression", 8, 8, false); + } + precedenceTable.put(node, p); + + Precedence parent = precedenceTable.get(node.parent()); + if (Precedence.makeBrackets(p, parent)) { + brackets.add(node); + } + } + +} + +class Precedence { + int from; + int to; + String name; + boolean leftAssociative; + + public Precedence(String s, int from, int to, boolean leftAssociative) { + this.from = from; + this.to = to; + this.name = s; + this.leftAssociative = leftAssociative; + } + + public static boolean makeBrackets(Precedence node, Precedence parent) { + if (parent == null) + return false; + + if (node.name.equals(parent.name)) { + if (node.leftAssociative) { + return false; + } + + } + if (node.from >= parent.from && node.from <= parent.to + || node.to >= parent.from && node.to <= parent.to) { + return true; + } + if (parent.from > node.from) + return true; + + return false; + } + + @Override + public String toString() { + return from + "-" + to; + } + +} diff --git a/src/main/java/de/tlc4b/analysis/PrimedNodesMarker.java b/src/main/java/de/tlc4b/analysis/PrimedNodesMarker.java index c09d4a2e31046baf26fa15d0d60d18f838b807bd..0447ecbf93de818e2daf49bb3820c17577a2ec14 100644 --- a/src/main/java/de/tlc4b/analysis/PrimedNodesMarker.java +++ b/src/main/java/de/tlc4b/analysis/PrimedNodesMarker.java @@ -1,107 +1,107 @@ -package de.tlc4b.analysis; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; - -import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; -import de.be4.classicalb.core.parser.node.AAssignSubstitution; -import de.be4.classicalb.core.parser.node.ABecomesElementOfSubstitution; -import de.be4.classicalb.core.parser.node.ABecomesSuchSubstitution; -import de.be4.classicalb.core.parser.node.AIdentifierExpression; -import de.be4.classicalb.core.parser.node.APrimedIdentifierExpression; -import de.be4.classicalb.core.parser.node.Node; -import de.be4.classicalb.core.parser.node.PExpression; -import de.be4.classicalb.core.parser.node.POperation; -import de.be4.classicalb.core.parser.util.Utils; -import de.tlc4b.exceptions.ScopeException; - -public class PrimedNodesMarker extends DepthFirstAdapter { - private ArrayList<POperation> operations; - private MachineContext machineContext; - private HashSet<Node> primedNodes; - - private HashSet<Node> nodesToPrime; - - public PrimedNodesMarker(ArrayList<POperation> operations, - MachineContext machineContext) { - this.primedNodes = new HashSet<Node>(); - this.operations = operations; - this.machineContext = machineContext; - } - - public void start() { - for (Node def : machineContext.getDefinitions().values()) { - def.apply(this); - } - for (POperation pOperation : operations) { - pOperation.apply(this); - } - } - - @Override - public void caseAAssignSubstitution(AAssignSubstitution node) { - List<PExpression> copy = new ArrayList<PExpression>( - node.getLhsExpression()); - for (PExpression e : copy) { - Node ref = machineContext.getReferences().get(e); - if (machineContext.getVariables().values().contains(ref)) { - primedNodes.add(e); - } - - } - } - - @Override - public void caseABecomesElementOfSubstitution( - ABecomesElementOfSubstitution node) { - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - Node ref = machineContext.getReferences().get(e); - if (machineContext.getVariables().values().contains(ref)) { - primedNodes.add(e); - } - } - } - - @Override - public void caseABecomesSuchSubstitution(ABecomesSuchSubstitution node) { - nodesToPrime = new HashSet<Node>(); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - Node ref = machineContext.getReferences().get(e); - nodesToPrime.add(ref); - primedNodes.add(e); - } - node.getPredicate().apply(this); - nodesToPrime = null; - } - - @Override - public void caseAIdentifierExpression(AIdentifierExpression node) { - if (nodesToPrime != null) { - Node ref = machineContext.getReferences().get(node); - if (nodesToPrime.contains(ref)) { - primedNodes.add(node); - } - } - } - - @Override - public void caseAPrimedIdentifierExpression(APrimedIdentifierExpression node) { - if(nodesToPrime != null){ - Node ref = machineContext.getReferences().get(node); - if (nodesToPrime.contains(ref)) { - return; - } - } - String name = Utils.getTIdentifierListAsString(node.getIdentifier()); - throw new ScopeException("Unkown identifier: '"+name+"$0'"); - } - - public boolean isPrimed(Node node) { - return primedNodes.contains(node); - } -} +package de.tlc4b.analysis; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; +import de.be4.classicalb.core.parser.node.AAssignSubstitution; +import de.be4.classicalb.core.parser.node.ABecomesElementOfSubstitution; +import de.be4.classicalb.core.parser.node.ABecomesSuchSubstitution; +import de.be4.classicalb.core.parser.node.AIdentifierExpression; +import de.be4.classicalb.core.parser.node.APrimedIdentifierExpression; +import de.be4.classicalb.core.parser.node.Node; +import de.be4.classicalb.core.parser.node.PExpression; +import de.be4.classicalb.core.parser.node.POperation; +import de.be4.classicalb.core.parser.util.Utils; +import de.tlc4b.exceptions.ScopeException; + +public class PrimedNodesMarker extends DepthFirstAdapter { + private ArrayList<POperation> operations; + private MachineContext machineContext; + private HashSet<Node> primedNodes; + + private HashSet<Node> nodesToPrime; + + public PrimedNodesMarker(ArrayList<POperation> operations, + MachineContext machineContext) { + this.primedNodes = new HashSet<Node>(); + this.operations = operations; + this.machineContext = machineContext; + } + + public void start() { + for (Node def : machineContext.getDefinitions().values()) { + def.apply(this); + } + for (POperation pOperation : operations) { + pOperation.apply(this); + } + } + + @Override + public void caseAAssignSubstitution(AAssignSubstitution node) { + List<PExpression> copy = new ArrayList<PExpression>( + node.getLhsExpression()); + for (PExpression e : copy) { + Node ref = machineContext.getReferences().get(e); + if (machineContext.getVariables().values().contains(ref)) { + primedNodes.add(e); + } + + } + } + + @Override + public void caseABecomesElementOfSubstitution( + ABecomesElementOfSubstitution node) { + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + Node ref = machineContext.getReferences().get(e); + if (machineContext.getVariables().values().contains(ref)) { + primedNodes.add(e); + } + } + } + + @Override + public void caseABecomesSuchSubstitution(ABecomesSuchSubstitution node) { + nodesToPrime = new HashSet<Node>(); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + Node ref = machineContext.getReferences().get(e); + nodesToPrime.add(ref); + primedNodes.add(e); + } + node.getPredicate().apply(this); + nodesToPrime = null; + } + + @Override + public void caseAIdentifierExpression(AIdentifierExpression node) { + if (nodesToPrime != null) { + Node ref = machineContext.getReferences().get(node); + if (nodesToPrime.contains(ref)) { + primedNodes.add(node); + } + } + } + + @Override + public void caseAPrimedIdentifierExpression(APrimedIdentifierExpression node) { + if(nodesToPrime != null){ + Node ref = machineContext.getReferences().get(node); + if (nodesToPrime.contains(ref)) { + return; + } + } + String name = Utils.getTIdentifierListAsString(node.getIdentifier()); + throw new ScopeException("Unkown identifier: '"+name+"$0'"); + } + + public boolean isPrimed(Node node) { + return primedNodes.contains(node); + } +} diff --git a/src/main/java/de/tlc4b/analysis/Renamer.java b/src/main/java/de/tlc4b/analysis/Renamer.java index 63676ea98bfb86e74f1d208854cd81a9c67e45f1..d72766838cfb4846ec85491675c3a5ecf4b47157 100644 --- a/src/main/java/de/tlc4b/analysis/Renamer.java +++ b/src/main/java/de/tlc4b/analysis/Renamer.java @@ -1,387 +1,387 @@ -package de.tlc4b.analysis; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Set; -import java.util.Map.Entry; - -import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; -import de.be4.classicalb.core.parser.node.AAnySubstitution; -import de.be4.classicalb.core.parser.node.AComprehensionSetExpression; -import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause; -import de.be4.classicalb.core.parser.node.AExistsPredicate; -import de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition; -import de.be4.classicalb.core.parser.node.AForallPredicate; -import de.be4.classicalb.core.parser.node.AGeneralProductExpression; -import de.be4.classicalb.core.parser.node.AGeneralSumExpression; -import de.be4.classicalb.core.parser.node.AIdentifierExpression; -import de.be4.classicalb.core.parser.node.ALambdaExpression; -import de.be4.classicalb.core.parser.node.ALetSubstitution; -import de.be4.classicalb.core.parser.node.AOperation; -import de.be4.classicalb.core.parser.node.APredicateDefinitionDefinition; -import de.be4.classicalb.core.parser.node.AQuantifiedIntersectionExpression; -import de.be4.classicalb.core.parser.node.AQuantifiedUnionExpression; -import de.be4.classicalb.core.parser.node.ASubstitutionDefinitionDefinition; -import de.be4.classicalb.core.parser.node.AVarSubstitution; -import de.be4.classicalb.core.parser.node.Node; -import de.be4.classicalb.core.parser.node.PDefinition; -import de.be4.classicalb.core.parser.node.PExpression; -import de.be4.classicalb.core.parser.util.Utils; - -public class Renamer extends DepthFirstAdapter { - private final MachineContext machineContext; - private final Hashtable<Node, String> namesTable; - private final HashSet<String> globalNames; - private final static Set<String> KEYWORDS = new HashSet<String>(); - static { - KEYWORDS.add("ASSUME"); - KEYWORDS.add("ASSUMPTION"); - KEYWORDS.add("AXIOM"); - KEYWORDS.add("CASE"); - KEYWORDS.add("CHOOSE"); - KEYWORDS.add("CONSTANT"); - KEYWORDS.add("CONSTANTS"); - KEYWORDS.add("DOMAIN"); - KEYWORDS.add("ELSE"); - KEYWORDS.add("ENABLED"); - KEYWORDS.add("EXCEPT"); - KEYWORDS.add("EXTENDS"); - KEYWORDS.add("IF"); - KEYWORDS.add("IN"); - KEYWORDS.add("INSTANCE"); - KEYWORDS.add("LET"); - KEYWORDS.add("LOCAL"); - KEYWORDS.add("MODULE"); - KEYWORDS.add("OTHER"); - KEYWORDS.add("SF_"); - KEYWORDS.add("SUBSET"); - KEYWORDS.add("THEN"); - KEYWORDS.add("THEOREM"); - KEYWORDS.add("UNCHANGED"); - KEYWORDS.add("UNION"); - KEYWORDS.add("VARIABLE"); - KEYWORDS.add("VARIABLES"); - KEYWORDS.add("WF_"); - KEYWORDS.add("WITH"); - KEYWORDS.add("STATE"); - KEYWORDS.add("DEF"); - - KEYWORDS.add("Init"); - KEYWORDS.add("Next"); - KEYWORDS.add("INVARIANT"); - - KEYWORDS.add("Nat"); - KEYWORDS.add("Int"); - KEYWORDS.add("Seq"); - } - private final static Set<String> RelationsKeywords = new HashSet<String>(); - static { - RelationsKeywords.add("domain"); - RelationsKeywords.add("range"); - RelationsKeywords.add("id"); - RelationsKeywords.add("set_of_relations"); - RelationsKeywords.add("domain_restriction"); - RelationsKeywords.add("domain_substraction"); - RelationsKeywords.add("rel_inverse"); - RelationsKeywords.add("relational_image"); - RelationsKeywords.add("relational_overriding"); - RelationsKeywords.add("direct"); - RelationsKeywords.add("Seq"); - - } - - public Renamer(MachineContext machineContext) { - this.machineContext = machineContext; - this.namesTable = new Hashtable<Node, String>(); - this.globalNames = new HashSet<String>(); - start(); - - } - - public void start() { - evalGlobalNames(machineContext.getDeferredSets()); - evalGlobalNames(machineContext.getEnumeratedSets()); - evalEnumValues(); - evalGlobalNames(machineContext.getConstants()); - evalGlobalNames(machineContext.getVariables()); - evalGlobalNames(machineContext.getOperations()); - - evalDefinitions(); - - machineContext.getStartNode().apply(this); - } - - private void evalEnumValues() { - - for (Entry<String, Node> entry : machineContext.getEnumValues() - .entrySet()) { - String name = entry.getKey(); - Node node = entry.getValue(); - - if (name.indexOf('_') == 1) { - name = name.replaceFirst("_", "1_"); - } - String newName = incName(name); - - namesTable.put(node, newName); - globalNames.add(newName); - } - } - - public void evalGlobalNames(LinkedHashMap<String, Node> map) { - for (Entry<String, Node> entry : map.entrySet()) { - String name = entry.getKey(); - String newName = incName(name); - namesTable.put(map.get(name), newName); - globalNames.add(newName); - } - } - - private void evalDefinitions() { - ADefinitionsMachineClause node = machineContext - .getDefinitionMachineClause(); - if (null == node) { - return; - } - - List<PDefinition> copy = new ArrayList<PDefinition>( - node.getDefinitions()); - for (PDefinition e : copy) { - String name = null; - if (e instanceof AExpressionDefinitionDefinition) { - name = ((AExpressionDefinitionDefinition) e).getName() - .getText(); - } else if (e instanceof APredicateDefinitionDefinition) { - name = ((APredicateDefinitionDefinition) e).getName().getText(); - } else if (e instanceof ASubstitutionDefinitionDefinition) { - name = ((ASubstitutionDefinitionDefinition) e).getName() - .getText(); - } - String newName = incName(name); - namesTable.put(e, newName); - globalNames.add(newName); - } - - for (PDefinition e : copy) { - e.apply(this); - } - } - - public String getNameOfRef(Node node) { - Node refNode = machineContext.getReferences().get(node); - if (refNode == null) { - refNode = node; - } - return namesTable.get(refNode); - } - - public String getName(Node node) { - return namesTable.get(node); - } - - private String incName(String name) { - String res = name; - for (int i = 1; exist(res); i++) { - res = name + "_" + i; - } - return res; - } - - private ArrayList<HashSet<String>> localContexts = new ArrayList<HashSet<String>>(); - - private boolean exist(String name) { - if (KEYWORDS.contains(name)) - return true; - if (globalNames.contains(name)) - return true; - // TODO check only if the standard module is extended - - if (StandardMadules.isKeywordInModuleFunctions(name)) - return true; - if (StandardMadules.isKeywordInModuleSequences(name)) - return true; - if (StandardMadules.isKeywordInModuleSequencesExtended(name)) - return true; - - for (int i = 0; i < localContexts.size(); i++) { - if (localContexts.get(i).contains(name)) - return true; - } - - return false; - } - - private String renameIdentifier(Node node) { - AIdentifierExpression id = (AIdentifierExpression) node; - String name = Utils.getTIdentifierListAsString(id.getIdentifier()); - String newName = incName(name); - namesTable.put(id, newName); - return newName; - } - - private void evalDefinition(List<PExpression> params) { - for (PExpression e : params) { - renameIdentifier(e); - } - } - - @Override - public void inAExpressionDefinitionDefinition( - AExpressionDefinitionDefinition node) { - evalDefinition(node.getParameters()); - } - - @Override - public void inAPredicateDefinitionDefinition( - APredicateDefinitionDefinition node) { - evalDefinition(node.getParameters()); - } - - @Override - public void inASubstitutionDefinitionDefinition( - ASubstitutionDefinitionDefinition node) { - evalDefinition(node.getParameters()); - } - - // local variables - - @Override - public void caseAForallPredicate(AForallPredicate node) { - evalBoundedVariables(node, node.getIdentifiers()); - node.getImplication().apply(this); - removeLastContext(); - } - - @Override - public void caseAExistsPredicate(AExistsPredicate node) { - evalBoundedVariables(node, node.getIdentifiers()); - node.getPredicate().apply(this); - removeLastContext(); - } - - @Override - public void caseALambdaExpression(ALambdaExpression node) { - evalBoundedVariables(node, node.getIdentifiers()); - node.getPredicate().apply(this); - node.getExpression().apply(this); - removeLastContext(); - } - - @Override - public void caseAComprehensionSetExpression(AComprehensionSetExpression node) { - evalBoundedVariables(node, node.getIdentifiers()); - node.getPredicates().apply(this); - removeLastContext(); - } - - @Override - public void caseAQuantifiedUnionExpression(AQuantifiedUnionExpression node) { - evalBoundedVariables(node, node.getIdentifiers()); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - e.apply(this); - } - node.getPredicates().apply(this); - node.getExpression().apply(this); - removeLastContext(); - } - - @Override - public void caseAQuantifiedIntersectionExpression( - AQuantifiedIntersectionExpression node) { - evalBoundedVariables(node, node.getIdentifiers()); - node.getPredicates().apply(this); - node.getExpression().apply(this); - removeLastContext(); - } - - @Override - public void caseAGeneralSumExpression(AGeneralSumExpression node) { - evalBoundedVariables(node, node.getIdentifiers()); - node.getPredicates().apply(this); - node.getExpression().apply(this); - removeLastContext(); - } - - @Override - public void caseAGeneralProductExpression(AGeneralProductExpression node) { - evalBoundedVariables(node, node.getIdentifiers()); - node.getPredicates().apply(this); - node.getExpression().apply(this); - removeLastContext(); - } - - @Override - public void caseAOperation(AOperation node) { - List<PExpression> list = new ArrayList<PExpression>(); - list.addAll(node.getParameters()); - list.addAll(node.getReturnValues()); - evalBoundedVariables(node, list); - node.getOperationBody().apply(this); - removeLastContext(); - } - - private void evalBoundedVariables(Node node, List<PExpression> params) { - HashSet<String> context = new HashSet<String>(); - for (PExpression e : params) { - String newName = renameIdentifier(e); - context.add(newName); - } - localContexts.add(context); - } - - @Override - public void caseAAnySubstitution(AAnySubstitution node) { - List<PExpression> list = new ArrayList<PExpression>(); - list.addAll(node.getIdentifiers()); - evalBoundedVariables(node, list); - - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - e.apply(this); - } - node.getWhere().apply(this); - node.getThen().apply(this); - removeLastContext(); - } - - @Override - public void caseALetSubstitution(ALetSubstitution node) { - List<PExpression> list = new ArrayList<PExpression>(); - list.addAll(node.getIdentifiers()); - evalBoundedVariables(node, list); - - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - e.apply(this); - } - node.getPredicate().apply(this); - node.getSubstitution().apply(this); - removeLastContext(); - } - - @Override - public void caseAVarSubstitution(AVarSubstitution node) { - List<PExpression> list = new ArrayList<PExpression>(); - list.addAll(node.getIdentifiers()); - evalBoundedVariables(node, list); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - e.apply(this); - } - node.getSubstitution().apply(this); - removeLastContext(); - } - - public void removeLastContext() { - localContexts.remove(localContexts.size() - 1); - } - -} +package de.tlc4b.analysis; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Set; +import java.util.Map.Entry; + +import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; +import de.be4.classicalb.core.parser.node.AAnySubstitution; +import de.be4.classicalb.core.parser.node.AComprehensionSetExpression; +import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause; +import de.be4.classicalb.core.parser.node.AExistsPredicate; +import de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition; +import de.be4.classicalb.core.parser.node.AForallPredicate; +import de.be4.classicalb.core.parser.node.AGeneralProductExpression; +import de.be4.classicalb.core.parser.node.AGeneralSumExpression; +import de.be4.classicalb.core.parser.node.AIdentifierExpression; +import de.be4.classicalb.core.parser.node.ALambdaExpression; +import de.be4.classicalb.core.parser.node.ALetSubstitution; +import de.be4.classicalb.core.parser.node.AOperation; +import de.be4.classicalb.core.parser.node.APredicateDefinitionDefinition; +import de.be4.classicalb.core.parser.node.AQuantifiedIntersectionExpression; +import de.be4.classicalb.core.parser.node.AQuantifiedUnionExpression; +import de.be4.classicalb.core.parser.node.ASubstitutionDefinitionDefinition; +import de.be4.classicalb.core.parser.node.AVarSubstitution; +import de.be4.classicalb.core.parser.node.Node; +import de.be4.classicalb.core.parser.node.PDefinition; +import de.be4.classicalb.core.parser.node.PExpression; +import de.be4.classicalb.core.parser.util.Utils; + +public class Renamer extends DepthFirstAdapter { + private final MachineContext machineContext; + private final Hashtable<Node, String> namesTable; + private final HashSet<String> globalNames; + private final static Set<String> KEYWORDS = new HashSet<String>(); + static { + KEYWORDS.add("ASSUME"); + KEYWORDS.add("ASSUMPTION"); + KEYWORDS.add("AXIOM"); + KEYWORDS.add("CASE"); + KEYWORDS.add("CHOOSE"); + KEYWORDS.add("CONSTANT"); + KEYWORDS.add("CONSTANTS"); + KEYWORDS.add("DOMAIN"); + KEYWORDS.add("ELSE"); + KEYWORDS.add("ENABLED"); + KEYWORDS.add("EXCEPT"); + KEYWORDS.add("EXTENDS"); + KEYWORDS.add("IF"); + KEYWORDS.add("IN"); + KEYWORDS.add("INSTANCE"); + KEYWORDS.add("LET"); + KEYWORDS.add("LOCAL"); + KEYWORDS.add("MODULE"); + KEYWORDS.add("OTHER"); + KEYWORDS.add("SF_"); + KEYWORDS.add("SUBSET"); + KEYWORDS.add("THEN"); + KEYWORDS.add("THEOREM"); + KEYWORDS.add("UNCHANGED"); + KEYWORDS.add("UNION"); + KEYWORDS.add("VARIABLE"); + KEYWORDS.add("VARIABLES"); + KEYWORDS.add("WF_"); + KEYWORDS.add("WITH"); + KEYWORDS.add("STATE"); + KEYWORDS.add("DEF"); + + KEYWORDS.add("Init"); + KEYWORDS.add("Next"); + KEYWORDS.add("INVARIANT"); + + KEYWORDS.add("Nat"); + KEYWORDS.add("Int"); + KEYWORDS.add("Seq"); + } + private final static Set<String> RelationsKeywords = new HashSet<String>(); + static { + RelationsKeywords.add("domain"); + RelationsKeywords.add("range"); + RelationsKeywords.add("id"); + RelationsKeywords.add("set_of_relations"); + RelationsKeywords.add("domain_restriction"); + RelationsKeywords.add("domain_substraction"); + RelationsKeywords.add("rel_inverse"); + RelationsKeywords.add("relational_image"); + RelationsKeywords.add("relational_overriding"); + RelationsKeywords.add("direct"); + RelationsKeywords.add("Seq"); + + } + + public Renamer(MachineContext machineContext) { + this.machineContext = machineContext; + this.namesTable = new Hashtable<Node, String>(); + this.globalNames = new HashSet<String>(); + start(); + + } + + public void start() { + evalGlobalNames(machineContext.getDeferredSets()); + evalGlobalNames(machineContext.getEnumeratedSets()); + evalEnumValues(); + evalGlobalNames(machineContext.getConstants()); + evalGlobalNames(machineContext.getVariables()); + evalGlobalNames(machineContext.getOperations()); + + evalDefinitions(); + + machineContext.getStartNode().apply(this); + } + + private void evalEnumValues() { + + for (Entry<String, Node> entry : machineContext.getEnumValues() + .entrySet()) { + String name = entry.getKey(); + Node node = entry.getValue(); + + if (name.indexOf('_') == 1) { + name = name.replaceFirst("_", "1_"); + } + String newName = incName(name); + + namesTable.put(node, newName); + globalNames.add(newName); + } + } + + public void evalGlobalNames(LinkedHashMap<String, Node> map) { + for (Entry<String, Node> entry : map.entrySet()) { + String name = entry.getKey(); + String newName = incName(name); + namesTable.put(map.get(name), newName); + globalNames.add(newName); + } + } + + private void evalDefinitions() { + ADefinitionsMachineClause node = machineContext + .getDefinitionMachineClause(); + if (null == node) { + return; + } + + List<PDefinition> copy = new ArrayList<PDefinition>( + node.getDefinitions()); + for (PDefinition e : copy) { + String name = null; + if (e instanceof AExpressionDefinitionDefinition) { + name = ((AExpressionDefinitionDefinition) e).getName() + .getText(); + } else if (e instanceof APredicateDefinitionDefinition) { + name = ((APredicateDefinitionDefinition) e).getName().getText(); + } else if (e instanceof ASubstitutionDefinitionDefinition) { + name = ((ASubstitutionDefinitionDefinition) e).getName() + .getText(); + } + String newName = incName(name); + namesTable.put(e, newName); + globalNames.add(newName); + } + + for (PDefinition e : copy) { + e.apply(this); + } + } + + public String getNameOfRef(Node node) { + Node refNode = machineContext.getReferences().get(node); + if (refNode == null) { + refNode = node; + } + return namesTable.get(refNode); + } + + public String getName(Node node) { + return namesTable.get(node); + } + + private String incName(String name) { + String res = name; + for (int i = 1; exist(res); i++) { + res = name + "_" + i; + } + return res; + } + + private ArrayList<HashSet<String>> localContexts = new ArrayList<HashSet<String>>(); + + private boolean exist(String name) { + if (KEYWORDS.contains(name)) + return true; + if (globalNames.contains(name)) + return true; + // TODO check only if the standard module is extended + + if (StandardMadules.isKeywordInModuleFunctions(name)) + return true; + if (StandardMadules.isKeywordInModuleSequences(name)) + return true; + if (StandardMadules.isKeywordInModuleSequencesExtended(name)) + return true; + + for (int i = 0; i < localContexts.size(); i++) { + if (localContexts.get(i).contains(name)) + return true; + } + + return false; + } + + private String renameIdentifier(Node node) { + AIdentifierExpression id = (AIdentifierExpression) node; + String name = Utils.getTIdentifierListAsString(id.getIdentifier()); + String newName = incName(name); + namesTable.put(id, newName); + return newName; + } + + private void evalDefinition(List<PExpression> params) { + for (PExpression e : params) { + renameIdentifier(e); + } + } + + @Override + public void inAExpressionDefinitionDefinition( + AExpressionDefinitionDefinition node) { + evalDefinition(node.getParameters()); + } + + @Override + public void inAPredicateDefinitionDefinition( + APredicateDefinitionDefinition node) { + evalDefinition(node.getParameters()); + } + + @Override + public void inASubstitutionDefinitionDefinition( + ASubstitutionDefinitionDefinition node) { + evalDefinition(node.getParameters()); + } + + // local variables + + @Override + public void caseAForallPredicate(AForallPredicate node) { + evalBoundedVariables(node, node.getIdentifiers()); + node.getImplication().apply(this); + removeLastContext(); + } + + @Override + public void caseAExistsPredicate(AExistsPredicate node) { + evalBoundedVariables(node, node.getIdentifiers()); + node.getPredicate().apply(this); + removeLastContext(); + } + + @Override + public void caseALambdaExpression(ALambdaExpression node) { + evalBoundedVariables(node, node.getIdentifiers()); + node.getPredicate().apply(this); + node.getExpression().apply(this); + removeLastContext(); + } + + @Override + public void caseAComprehensionSetExpression(AComprehensionSetExpression node) { + evalBoundedVariables(node, node.getIdentifiers()); + node.getPredicates().apply(this); + removeLastContext(); + } + + @Override + public void caseAQuantifiedUnionExpression(AQuantifiedUnionExpression node) { + evalBoundedVariables(node, node.getIdentifiers()); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + e.apply(this); + } + node.getPredicates().apply(this); + node.getExpression().apply(this); + removeLastContext(); + } + + @Override + public void caseAQuantifiedIntersectionExpression( + AQuantifiedIntersectionExpression node) { + evalBoundedVariables(node, node.getIdentifiers()); + node.getPredicates().apply(this); + node.getExpression().apply(this); + removeLastContext(); + } + + @Override + public void caseAGeneralSumExpression(AGeneralSumExpression node) { + evalBoundedVariables(node, node.getIdentifiers()); + node.getPredicates().apply(this); + node.getExpression().apply(this); + removeLastContext(); + } + + @Override + public void caseAGeneralProductExpression(AGeneralProductExpression node) { + evalBoundedVariables(node, node.getIdentifiers()); + node.getPredicates().apply(this); + node.getExpression().apply(this); + removeLastContext(); + } + + @Override + public void caseAOperation(AOperation node) { + List<PExpression> list = new ArrayList<PExpression>(); + list.addAll(node.getParameters()); + list.addAll(node.getReturnValues()); + evalBoundedVariables(node, list); + node.getOperationBody().apply(this); + removeLastContext(); + } + + private void evalBoundedVariables(Node node, List<PExpression> params) { + HashSet<String> context = new HashSet<String>(); + for (PExpression e : params) { + String newName = renameIdentifier(e); + context.add(newName); + } + localContexts.add(context); + } + + @Override + public void caseAAnySubstitution(AAnySubstitution node) { + List<PExpression> list = new ArrayList<PExpression>(); + list.addAll(node.getIdentifiers()); + evalBoundedVariables(node, list); + + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + e.apply(this); + } + node.getWhere().apply(this); + node.getThen().apply(this); + removeLastContext(); + } + + @Override + public void caseALetSubstitution(ALetSubstitution node) { + List<PExpression> list = new ArrayList<PExpression>(); + list.addAll(node.getIdentifiers()); + evalBoundedVariables(node, list); + + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + e.apply(this); + } + node.getPredicate().apply(this); + node.getSubstitution().apply(this); + removeLastContext(); + } + + @Override + public void caseAVarSubstitution(AVarSubstitution node) { + List<PExpression> list = new ArrayList<PExpression>(); + list.addAll(node.getIdentifiers()); + evalBoundedVariables(node, list); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + e.apply(this); + } + node.getSubstitution().apply(this); + removeLastContext(); + } + + public void removeLastContext() { + localContexts.remove(localContexts.size() - 1); + } + +} diff --git a/src/main/java/de/tlc4b/analysis/StandardMadules.java b/src/main/java/de/tlc4b/analysis/StandardMadules.java index 15f51f4c6d8e1b4309e537e68387ef55ddc95ba1..e85c5475483801131cbb56242a42572cd9d00baf 100644 --- a/src/main/java/de/tlc4b/analysis/StandardMadules.java +++ b/src/main/java/de/tlc4b/analysis/StandardMadules.java @@ -1,281 +1,281 @@ -package de.tlc4b.analysis; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Set; - - -public final class StandardMadules { - - private StandardMadules() { - } - - // Functions - public static final String FUNC_RANGE = "Range"; - public static final String FUNC_IMAGE = "Image"; - public static final String FUNC_ID = "Id"; - public static final String FUNC_INVERSE = "Inverse"; - public static final String FUNC_DOMAIN_RESTRICTION = "DomRes"; - public static final String FUNC_DOMAIN_SUBSTRACTION = "DomSub"; - public static final String FUNC_RANGE_RESTRICTION = "RanRes"; - public static final String FUNC_RANGE_SUBSTRACTION = "RanSub"; - public static final String FUNC_OVERRIDE = "Override"; - public static final String FUNC_ASSIGN = "FuncAssign"; - - private static final ArrayList<String> functions = new ArrayList<String>(); - static { - functions.add(FUNC_RANGE); - functions.add(FUNC_ID); - functions.add(FUNC_INVERSE); - functions.add(FUNC_DOMAIN_RESTRICTION); - functions.add(FUNC_DOMAIN_SUBSTRACTION); - functions.add(FUNC_RANGE_RESTRICTION); - functions.add(FUNC_RANGE_SUBSTRACTION); - functions.add(FUNC_OVERRIDE); - functions.add(FUNC_ASSIGN); - } - - public static final boolean isKeywordInModuleFunctions(String name) { - return functions.contains(name); - } - - public static final String TOTAL_INJECTIVE_FUNCTION = "TotalInjFunc"; - public static final String TOTAL_SURJECTIVE_FUNCTION = "TotalSurFunc"; - public static final String TOTAL_BIJECTIVE_FUNCTION = "TotalBijFunc"; - - /** Sets of Partial functions **/ - public static final String PARTIAL_FUNCTION = "ParFunc"; - public static final String PARTIAL_FUNCTION_ELEMENT_OF = "ParFuncEleOf"; - public static final String ELEMENT_OF_PARTIAL_FUNCTION = "isEleOfParFunc"; - - // injective - public static final String PARTIAL_INJECTIVE_FUNCTION = "ParInjFunc"; - public static final String PARTIAL_INJECTIVE_FUNCTION_ELEMENT_OF = "ParInjFuncEleOf"; - // surjective - public static final String PARTIAL_SURJECTIVE_FUNCTION = "ParSurFunc"; - public static final String PARTIAL_SURJECTIVE_FUNCTION_ELEMENT_OF = "ParSurFuncEleOf"; - // bijective - public static final String PARITAL_BIJECTIVE_FUNCTION = "ParBijFunc"; - public static final String PARITAL_BIJECTIVE_FUNCTION_ELEMENT_OF = "ParBijFuncEleOf"; - - // Relations - public static final String RELATIONS = "Relations"; - public static final String REL_DOMAIN = "RelDomain"; - public static final String REL_RANGE = "RelRange"; - public static final String REL_ID = "RelId"; - public static final String REL_DOMAIN_RESTRICTION = "RelDomRes"; - public static final String REL_DOMAIN_SUBSTRACTION = "RelDomSub"; - public static final String REL_RANGE_RESTRICTION = "RelRanRes"; - public static final String REL_RANGE_SUBSTRACTION = "RelRanSub"; - public static final String REL_INVERSE = "RelInverse"; - public static final String REL_IMAGE = "RelImage"; - public static final String REL_OVERRIDING = "RelOverride"; - public static final String REL_OVERRIDING_FUNC = "RelOverrideFunc"; - public static final String REL_DIRECT_PRODUCT = "RelDirectProduct"; - public static final String REL_PARALLEL_PRODUCT = "RelParallelProduct"; - public static final String REL_COMPOSITION = "RelComposition"; - public static final String REL_PROJECTION_FUNCTION_FIRST = "RelPrj1"; - public static final String REL_PROJECTION_FUNCTION_SECOND = "RelPrj2"; - public static final String REL_ITERATE = "RelIterate"; - public static final String REL_CLOSURE1 = "RelClosure1"; - public static final String REL_CLOSURE = "RelClosure"; - public static final String REL_FNC = "RelFnc"; - public static final String REL_REL = "RelRel"; - - // FunctionsAsRelations - public static final String REL_CALL = "RelCall"; - public static final String REL_CALL_WITHOUT_WD_CHECK = "RelCallWithoutWDCheck"; - - public static final String REL_TOTAL_FUNCTION = "RelTotalFunc"; - public static final String REL_TOTAL_FUNCTION_ELEMENT_OF = "RelTotalFuncEleOf"; - - public static final String REL_TOTAL_INJECTIVE_FUNCTION = "RelTotalInjFunc"; - public static final String REL_TOTAL_INJECTIVE_FUNCTION_ELEMENT_OF = "RelTotalInjFuncEleOf"; - - public static final String REL_TOTAL_SURJECTIVE_FUNCTION = "RelTotalSurFunc"; - public static final String REL_TOTAL_SURJECTIVE_FUNCTION_ELEMENT_OF = "RelTotalSurFuncEleOf"; - - public static final String REL_TOTAL_BIJECTIVE_FUNCTION = "RelTotalBijFunc"; - public static final String REL_TOTAL_BIJECTIVE_FUNCTION_ELEMENT_OF = "RelTotalBijFuncEleOf"; - - public static final String REL_PARTIAL_FUNCTION = "RelParFunc"; - public static final String REL_PARTIAL_FUNCTION_ELEMENT_OF = "RelParFuncEleOf"; - - public static final String REL_PARTIAL_INJECTIVE_FUNCTION = "RelParInjFunc"; - public static final String REL_PARTIAL_INJECTIVE_FUNCTION_ELEMENT_OF = "RelParInjFuncEleOf"; - - public static final String REL_PARTIAL_SURJECTIVE_FUNCTION = "RelParSurFunc"; - public static final String REL_PARTIAL_SURJECTIVE_FUNCTION_ELEMENT_OF = "RelParSurFuncEleOf"; - - public static final String REL_PARTIAL_BIJECTIVE_FUNCTION = "RelParBijFunc"; - public static final String REL_PARTIAL_BIJECTIVE_FUNCTION_ELEMENT_OF = "RelParBijFuncEleOf"; - - private final static Set<String> SequencesKeywords = new HashSet<String>(); - static { - SequencesKeywords.add("Seq"); - SequencesKeywords.add("Len"); - SequencesKeywords.add("Append"); - SequencesKeywords.add("Head"); - SequencesKeywords.add("Tail"); - SequencesKeywords.add("Subseq"); - SequencesKeywords.add("SelectSeq"); - } - - public final static boolean isKeywordInModuleSequences(String name) { - return SequencesKeywords.contains(name); - } - - // SequencesExtended - public static final String SEQUENCE_LAST_ELEMENT = "Last"; - public static final String SEQUENCE_PREPEND_ELEMENT = "Prepend"; - public static final String SEQUENCE_FRONT = "Front"; - public static final String SEQUENCE_1 = "Seq1"; - public static final String INJECTIVE_SEQUENCE = "ISeq"; - public static final String INJECTIVE_SEQUENCE_ELEMENT_OF = "ISeqEleOf"; - public static final String INJECTIVE_SEQUENCE_1 = "ISeq1"; - public static final String INJECTIVE_SEQUENCE_1_ELEMENT_OF = "ISeq1EleOf"; - public static final String SEQUENCE_PERMUTATION = "Perm"; - public static final String SEQUENCE_REVERSE = "Reverse"; - public static final String SEQUENCE_GENERAL_CONCATINATION = "Conc"; - public static final String SEQUENCE_TAKE_FIRST_ELEMENTS = "TakeFirstElements"; - public static final String SEQUENCE_DROP_FIRST_ELEMENTS = "DropFirstElements"; - - private final static Set<String> SequencesExtendedKeywords = new HashSet<String>(); - static { - SequencesExtendedKeywords.add(SEQUENCE_LAST_ELEMENT); - SequencesExtendedKeywords.add(SEQUENCE_PREPEND_ELEMENT); - SequencesExtendedKeywords.add(SEQUENCE_FRONT); - SequencesExtendedKeywords.add(SEQUENCE_1); - SequencesExtendedKeywords.add(INJECTIVE_SEQUENCE); - SequencesExtendedKeywords.add(INJECTIVE_SEQUENCE_ELEMENT_OF); - SequencesExtendedKeywords.add(INJECTIVE_SEQUENCE_1); - SequencesExtendedKeywords.add(INJECTIVE_SEQUENCE_1_ELEMENT_OF); - SequencesExtendedKeywords.add(SEQUENCE_PERMUTATION); - SequencesExtendedKeywords.add(SEQUENCE_REVERSE); - SequencesExtendedKeywords.add(SEQUENCE_GENERAL_CONCATINATION); - SequencesExtendedKeywords.add(SEQUENCE_TAKE_FIRST_ELEMENTS); - SequencesExtendedKeywords.add(SEQUENCE_DROP_FIRST_ELEMENTS); - } - - public final static boolean isKeywordInModuleSequencesExtended(String name) { - return SequencesExtendedKeywords.contains(name); - } - - // SequencesAsRelations - public static final String REL_SEQUENCE_SIZE = "RelSeqSize"; - public static final String IS_REL_SEQUENCE = "isRelSeq"; - public static final String REL_SEQUENCE_SET = "RelSeqSet"; - public static final String REL_SET_OF_SEQUENCES = "RelSeq"; - public static final String REL_SET_OF_NON_EMPTY_SEQUENCES = "RelSeq1"; - public static final String IS_REL_SEQUENCE_1 = "isRelSeq1"; - public static final String REL_SEQUENCE_1_SET = "RelSeqSet1"; - public static final String REL_INJECTIVE_SEQUENCE = "RelISeq"; - public static final String REL_INJECTIVE_SEQUENCE_ELEMENT_OF = "RelISeqEleOf"; - public static final String REL_INJECTIVE_SEQUENCE_1 = "RelISeq1"; - public static final String REL_INJECTIVE_SEQUENCE_1_ELEMENT_OF = "RelISeq1EleOf"; - public static final String REL_SEQUENCE_Concat = "RelSeqConcat"; - public static final String REL_SEQUENCE_PREPAND = "RelSeqPrepand"; - public static final String REL_SEQUENCE_APPEND = "RelSeqAppend"; - public static final String REL_SEQUENCE_REVERSE = "RelSeqReverse"; - public static final String REL_SEQUENCE_FIRST_ELEMENT = "RelSeqFirst"; - public static final String REL_SEQUENCE_LAST_ELEMENT = "RelSeqLast"; - public static final String REL_SEQUENCE_FRONT = "RelSeqFront"; - public static final String REL_SEQUENCE_TAIL = "RelSeqTail"; - public static final String REL_SEQUENCE_PERM = "RelSeqPerm"; - public static final String REL_SEQUENCE_GENERAL_CONCATINATION = "RelSeqConc"; - public static final String REL_SEQUENCE_TAKE_FIRST_ELEMENTS = "RelSeqTakeFirstElements"; - public static final String REL_SEQUENCE_DROP_FIRST_ELEMENTS = "RelSeqDropFirstElements"; - - /* - * BBuiltIns - */ - - public static final String MIN = "Min"; - public static final String MAX = "Max"; - public static final String NOT_SUBSET = "NotSubset"; - public static final String NOT_STRICT_SUBSET = "NotStrictSubset"; - public static final String POW_1 = "Pow1"; - public static final String FINITE_SUBSETS = "Fin"; - public static final String FINITE_1_SUBSETS = "Fin1"; - public static final String B_POWER_Of = "BPowerOf"; - public static final String B_MODULO = "BModulo"; - public static final String B_DIVISION = "BDivision"; - - public static final String GENERAL_SUMMATION = "Sigma"; - public static final String GENERAL_PRODUCT = "Pi"; - - private static final ArrayList<String> Relations = new ArrayList<String>(); - static { - Relations.add(RELATIONS); - Relations.add(REL_DOMAIN); - Relations.add(REL_RANGE); - Relations.add(REL_ID); - Relations.add(REL_DOMAIN_RESTRICTION); - Relations.add(REL_DOMAIN_SUBSTRACTION); - Relations.add(REL_RANGE_RESTRICTION); - Relations.add(REL_RANGE_SUBSTRACTION); - Relations.add(REL_INVERSE); - Relations.add(REL_IMAGE); - Relations.add(REL_OVERRIDING); - Relations.add(REL_DIRECT_PRODUCT); - Relations.add(REL_COMPOSITION); - Relations.add(REL_PROJECTION_FUNCTION_FIRST); - Relations.add(REL_PROJECTION_FUNCTION_SECOND); - Relations.add(REL_CLOSURE1); - Relations.add(REL_CLOSURE); - Relations.add(REL_TOTAL_FUNCTION); - Relations.add(REL_TOTAL_INJECTIVE_FUNCTION); - Relations.add(REL_PARTIAL_FUNCTION); - - } - - public static final boolean containsNameFromModuleRelations(String name) { - return Relations.contains(name); - } - - /* - * External Functions - * - * All external functions must be defined in the standard module - * ExternalFunctions.tla (src/main/resources/standardModules/). The B - * machine must contain a definition declaring the external function. The - * typing definition (e.g. EXTERNAL_FUNCTION_STRING_SPLIT == - * ((STRING*STRING) --> (INTEGER<->STRING));) is not mandatory. - * - * The B definitions will be ignored in the {@link TLAPrinter}. - */ - - public static final String EXTERNAL_printf = "printf"; - public static final String INT_TO_STRING = "INT_TO_STRING"; - public static final String STRING_SPLIT = "STRING_SPLIT"; - public static final String SORT_SET = "SORT_SET"; - public static final String STRING_APPEND = "STRING_APPEND"; - public static final String STRING_TO_INT = "STRING_TO_INT"; - public static final String DECIMAL_TO_INT = "DECIMAL_TO_INT"; - - private static final ArrayList<String> ExternalFunctions = new ArrayList<String>(); - static { - ExternalFunctions.add(EXTERNAL_printf); - ExternalFunctions.add(INT_TO_STRING); - ExternalFunctions.add(STRING_SPLIT); - ExternalFunctions.add(STRING_APPEND); - ExternalFunctions.add(STRING_TO_INT); - - ExternalFunctions.add(SORT_SET); - ExternalFunctions.add(DECIMAL_TO_INT); - } - - public static boolean isAbstractConstant(String name) { - if (name.equals(SORT_SET) || name.equals(DECIMAL_TO_INT)) { - return true; - } else { - return false; - } - - } - - public static boolean isKeywordInModuleExternalFunctions(String name) { - return ExternalFunctions.contains(name); - } - -} +package de.tlc4b.analysis; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; + + +public final class StandardMadules { + + private StandardMadules() { + } + + // Functions + public static final String FUNC_RANGE = "Range"; + public static final String FUNC_IMAGE = "Image"; + public static final String FUNC_ID = "Id"; + public static final String FUNC_INVERSE = "Inverse"; + public static final String FUNC_DOMAIN_RESTRICTION = "DomRes"; + public static final String FUNC_DOMAIN_SUBSTRACTION = "DomSub"; + public static final String FUNC_RANGE_RESTRICTION = "RanRes"; + public static final String FUNC_RANGE_SUBSTRACTION = "RanSub"; + public static final String FUNC_OVERRIDE = "Override"; + public static final String FUNC_ASSIGN = "FuncAssign"; + + private static final ArrayList<String> functions = new ArrayList<String>(); + static { + functions.add(FUNC_RANGE); + functions.add(FUNC_ID); + functions.add(FUNC_INVERSE); + functions.add(FUNC_DOMAIN_RESTRICTION); + functions.add(FUNC_DOMAIN_SUBSTRACTION); + functions.add(FUNC_RANGE_RESTRICTION); + functions.add(FUNC_RANGE_SUBSTRACTION); + functions.add(FUNC_OVERRIDE); + functions.add(FUNC_ASSIGN); + } + + public static final boolean isKeywordInModuleFunctions(String name) { + return functions.contains(name); + } + + public static final String TOTAL_INJECTIVE_FUNCTION = "TotalInjFunc"; + public static final String TOTAL_SURJECTIVE_FUNCTION = "TotalSurFunc"; + public static final String TOTAL_BIJECTIVE_FUNCTION = "TotalBijFunc"; + + /** Sets of Partial functions **/ + public static final String PARTIAL_FUNCTION = "ParFunc"; + public static final String PARTIAL_FUNCTION_ELEMENT_OF = "ParFuncEleOf"; + public static final String ELEMENT_OF_PARTIAL_FUNCTION = "isEleOfParFunc"; + + // injective + public static final String PARTIAL_INJECTIVE_FUNCTION = "ParInjFunc"; + public static final String PARTIAL_INJECTIVE_FUNCTION_ELEMENT_OF = "ParInjFuncEleOf"; + // surjective + public static final String PARTIAL_SURJECTIVE_FUNCTION = "ParSurFunc"; + public static final String PARTIAL_SURJECTIVE_FUNCTION_ELEMENT_OF = "ParSurFuncEleOf"; + // bijective + public static final String PARITAL_BIJECTIVE_FUNCTION = "ParBijFunc"; + public static final String PARITAL_BIJECTIVE_FUNCTION_ELEMENT_OF = "ParBijFuncEleOf"; + + // Relations + public static final String RELATIONS = "Relations"; + public static final String REL_DOMAIN = "RelDomain"; + public static final String REL_RANGE = "RelRange"; + public static final String REL_ID = "RelId"; + public static final String REL_DOMAIN_RESTRICTION = "RelDomRes"; + public static final String REL_DOMAIN_SUBSTRACTION = "RelDomSub"; + public static final String REL_RANGE_RESTRICTION = "RelRanRes"; + public static final String REL_RANGE_SUBSTRACTION = "RelRanSub"; + public static final String REL_INVERSE = "RelInverse"; + public static final String REL_IMAGE = "RelImage"; + public static final String REL_OVERRIDING = "RelOverride"; + public static final String REL_OVERRIDING_FUNC = "RelOverrideFunc"; + public static final String REL_DIRECT_PRODUCT = "RelDirectProduct"; + public static final String REL_PARALLEL_PRODUCT = "RelParallelProduct"; + public static final String REL_COMPOSITION = "RelComposition"; + public static final String REL_PROJECTION_FUNCTION_FIRST = "RelPrj1"; + public static final String REL_PROJECTION_FUNCTION_SECOND = "RelPrj2"; + public static final String REL_ITERATE = "RelIterate"; + public static final String REL_CLOSURE1 = "RelClosure1"; + public static final String REL_CLOSURE = "RelClosure"; + public static final String REL_FNC = "RelFnc"; + public static final String REL_REL = "RelRel"; + + // FunctionsAsRelations + public static final String REL_CALL = "RelCall"; + public static final String REL_CALL_WITHOUT_WD_CHECK = "RelCallWithoutWDCheck"; + + public static final String REL_TOTAL_FUNCTION = "RelTotalFunc"; + public static final String REL_TOTAL_FUNCTION_ELEMENT_OF = "RelTotalFuncEleOf"; + + public static final String REL_TOTAL_INJECTIVE_FUNCTION = "RelTotalInjFunc"; + public static final String REL_TOTAL_INJECTIVE_FUNCTION_ELEMENT_OF = "RelTotalInjFuncEleOf"; + + public static final String REL_TOTAL_SURJECTIVE_FUNCTION = "RelTotalSurFunc"; + public static final String REL_TOTAL_SURJECTIVE_FUNCTION_ELEMENT_OF = "RelTotalSurFuncEleOf"; + + public static final String REL_TOTAL_BIJECTIVE_FUNCTION = "RelTotalBijFunc"; + public static final String REL_TOTAL_BIJECTIVE_FUNCTION_ELEMENT_OF = "RelTotalBijFuncEleOf"; + + public static final String REL_PARTIAL_FUNCTION = "RelParFunc"; + public static final String REL_PARTIAL_FUNCTION_ELEMENT_OF = "RelParFuncEleOf"; + + public static final String REL_PARTIAL_INJECTIVE_FUNCTION = "RelParInjFunc"; + public static final String REL_PARTIAL_INJECTIVE_FUNCTION_ELEMENT_OF = "RelParInjFuncEleOf"; + + public static final String REL_PARTIAL_SURJECTIVE_FUNCTION = "RelParSurFunc"; + public static final String REL_PARTIAL_SURJECTIVE_FUNCTION_ELEMENT_OF = "RelParSurFuncEleOf"; + + public static final String REL_PARTIAL_BIJECTIVE_FUNCTION = "RelParBijFunc"; + public static final String REL_PARTIAL_BIJECTIVE_FUNCTION_ELEMENT_OF = "RelParBijFuncEleOf"; + + private final static Set<String> SequencesKeywords = new HashSet<String>(); + static { + SequencesKeywords.add("Seq"); + SequencesKeywords.add("Len"); + SequencesKeywords.add("Append"); + SequencesKeywords.add("Head"); + SequencesKeywords.add("Tail"); + SequencesKeywords.add("Subseq"); + SequencesKeywords.add("SelectSeq"); + } + + public final static boolean isKeywordInModuleSequences(String name) { + return SequencesKeywords.contains(name); + } + + // SequencesExtended + public static final String SEQUENCE_LAST_ELEMENT = "Last"; + public static final String SEQUENCE_PREPEND_ELEMENT = "Prepend"; + public static final String SEQUENCE_FRONT = "Front"; + public static final String SEQUENCE_1 = "Seq1"; + public static final String INJECTIVE_SEQUENCE = "ISeq"; + public static final String INJECTIVE_SEQUENCE_ELEMENT_OF = "ISeqEleOf"; + public static final String INJECTIVE_SEQUENCE_1 = "ISeq1"; + public static final String INJECTIVE_SEQUENCE_1_ELEMENT_OF = "ISeq1EleOf"; + public static final String SEQUENCE_PERMUTATION = "Perm"; + public static final String SEQUENCE_REVERSE = "Reverse"; + public static final String SEQUENCE_GENERAL_CONCATINATION = "Conc"; + public static final String SEQUENCE_TAKE_FIRST_ELEMENTS = "TakeFirstElements"; + public static final String SEQUENCE_DROP_FIRST_ELEMENTS = "DropFirstElements"; + + private final static Set<String> SequencesExtendedKeywords = new HashSet<String>(); + static { + SequencesExtendedKeywords.add(SEQUENCE_LAST_ELEMENT); + SequencesExtendedKeywords.add(SEQUENCE_PREPEND_ELEMENT); + SequencesExtendedKeywords.add(SEQUENCE_FRONT); + SequencesExtendedKeywords.add(SEQUENCE_1); + SequencesExtendedKeywords.add(INJECTIVE_SEQUENCE); + SequencesExtendedKeywords.add(INJECTIVE_SEQUENCE_ELEMENT_OF); + SequencesExtendedKeywords.add(INJECTIVE_SEQUENCE_1); + SequencesExtendedKeywords.add(INJECTIVE_SEQUENCE_1_ELEMENT_OF); + SequencesExtendedKeywords.add(SEQUENCE_PERMUTATION); + SequencesExtendedKeywords.add(SEQUENCE_REVERSE); + SequencesExtendedKeywords.add(SEQUENCE_GENERAL_CONCATINATION); + SequencesExtendedKeywords.add(SEQUENCE_TAKE_FIRST_ELEMENTS); + SequencesExtendedKeywords.add(SEQUENCE_DROP_FIRST_ELEMENTS); + } + + public final static boolean isKeywordInModuleSequencesExtended(String name) { + return SequencesExtendedKeywords.contains(name); + } + + // SequencesAsRelations + public static final String REL_SEQUENCE_SIZE = "RelSeqSize"; + public static final String IS_REL_SEQUENCE = "isRelSeq"; + public static final String REL_SEQUENCE_SET = "RelSeqSet"; + public static final String REL_SET_OF_SEQUENCES = "RelSeq"; + public static final String REL_SET_OF_NON_EMPTY_SEQUENCES = "RelSeq1"; + public static final String IS_REL_SEQUENCE_1 = "isRelSeq1"; + public static final String REL_SEQUENCE_1_SET = "RelSeqSet1"; + public static final String REL_INJECTIVE_SEQUENCE = "RelISeq"; + public static final String REL_INJECTIVE_SEQUENCE_ELEMENT_OF = "RelISeqEleOf"; + public static final String REL_INJECTIVE_SEQUENCE_1 = "RelISeq1"; + public static final String REL_INJECTIVE_SEQUENCE_1_ELEMENT_OF = "RelISeq1EleOf"; + public static final String REL_SEQUENCE_Concat = "RelSeqConcat"; + public static final String REL_SEQUENCE_PREPAND = "RelSeqPrepand"; + public static final String REL_SEQUENCE_APPEND = "RelSeqAppend"; + public static final String REL_SEQUENCE_REVERSE = "RelSeqReverse"; + public static final String REL_SEQUENCE_FIRST_ELEMENT = "RelSeqFirst"; + public static final String REL_SEQUENCE_LAST_ELEMENT = "RelSeqLast"; + public static final String REL_SEQUENCE_FRONT = "RelSeqFront"; + public static final String REL_SEQUENCE_TAIL = "RelSeqTail"; + public static final String REL_SEQUENCE_PERM = "RelSeqPerm"; + public static final String REL_SEQUENCE_GENERAL_CONCATINATION = "RelSeqConc"; + public static final String REL_SEQUENCE_TAKE_FIRST_ELEMENTS = "RelSeqTakeFirstElements"; + public static final String REL_SEQUENCE_DROP_FIRST_ELEMENTS = "RelSeqDropFirstElements"; + + /* + * BBuiltIns + */ + + public static final String MIN = "Min"; + public static final String MAX = "Max"; + public static final String NOT_SUBSET = "NotSubset"; + public static final String NOT_STRICT_SUBSET = "NotStrictSubset"; + public static final String POW_1 = "Pow1"; + public static final String FINITE_SUBSETS = "Fin"; + public static final String FINITE_1_SUBSETS = "Fin1"; + public static final String B_POWER_Of = "BPowerOf"; + public static final String B_MODULO = "BModulo"; + public static final String B_DIVISION = "BDivision"; + + public static final String GENERAL_SUMMATION = "Sigma"; + public static final String GENERAL_PRODUCT = "Pi"; + + private static final ArrayList<String> Relations = new ArrayList<String>(); + static { + Relations.add(RELATIONS); + Relations.add(REL_DOMAIN); + Relations.add(REL_RANGE); + Relations.add(REL_ID); + Relations.add(REL_DOMAIN_RESTRICTION); + Relations.add(REL_DOMAIN_SUBSTRACTION); + Relations.add(REL_RANGE_RESTRICTION); + Relations.add(REL_RANGE_SUBSTRACTION); + Relations.add(REL_INVERSE); + Relations.add(REL_IMAGE); + Relations.add(REL_OVERRIDING); + Relations.add(REL_DIRECT_PRODUCT); + Relations.add(REL_COMPOSITION); + Relations.add(REL_PROJECTION_FUNCTION_FIRST); + Relations.add(REL_PROJECTION_FUNCTION_SECOND); + Relations.add(REL_CLOSURE1); + Relations.add(REL_CLOSURE); + Relations.add(REL_TOTAL_FUNCTION); + Relations.add(REL_TOTAL_INJECTIVE_FUNCTION); + Relations.add(REL_PARTIAL_FUNCTION); + + } + + public static final boolean containsNameFromModuleRelations(String name) { + return Relations.contains(name); + } + + /* + * External Functions + * + * All external functions must be defined in the standard module + * ExternalFunctions.tla (src/main/resources/standardModules/). The B + * machine must contain a definition declaring the external function. The + * typing definition (e.g. EXTERNAL_FUNCTION_STRING_SPLIT == + * ((STRING*STRING) --> (INTEGER<->STRING));) is not mandatory. + * + * The B definitions will be ignored in the {@link TLAPrinter}. + */ + + public static final String EXTERNAL_printf = "printf"; + public static final String INT_TO_STRING = "INT_TO_STRING"; + public static final String STRING_SPLIT = "STRING_SPLIT"; + public static final String SORT_SET = "SORT_SET"; + public static final String STRING_APPEND = "STRING_APPEND"; + public static final String STRING_TO_INT = "STRING_TO_INT"; + public static final String DECIMAL_TO_INT = "DECIMAL_TO_INT"; + + private static final ArrayList<String> ExternalFunctions = new ArrayList<String>(); + static { + ExternalFunctions.add(EXTERNAL_printf); + ExternalFunctions.add(INT_TO_STRING); + ExternalFunctions.add(STRING_SPLIT); + ExternalFunctions.add(STRING_APPEND); + ExternalFunctions.add(STRING_TO_INT); + + ExternalFunctions.add(SORT_SET); + ExternalFunctions.add(DECIMAL_TO_INT); + } + + public static boolean isAbstractConstant(String name) { + if (name.equals(SORT_SET) || name.equals(DECIMAL_TO_INT)) { + return true; + } else { + return false; + } + + } + + public static boolean isKeywordInModuleExternalFunctions(String name) { + return ExternalFunctions.contains(name); + } + +} diff --git a/src/main/java/de/tlc4b/analysis/Typechecker.java b/src/main/java/de/tlc4b/analysis/Typechecker.java index 9c487ec517380257988a91fe54f865809f350eb7..afb181e38ad6a9c0b574e15bd12fac1a25816f0e 100644 --- a/src/main/java/de/tlc4b/analysis/Typechecker.java +++ b/src/main/java/de/tlc4b/analysis/Typechecker.java @@ -1,2348 +1,2348 @@ -package de.tlc4b.analysis; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.LinkedList; -import java.util.List; -import java.util.Map.Entry; - -import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; -import de.be4.classicalb.core.parser.node.*; -import de.be4.classicalb.core.parser.util.Utils; -import de.tlc4b.btypes.AbstractHasFollowers; -import de.tlc4b.btypes.BType; -import de.tlc4b.btypes.BoolType; -import de.tlc4b.btypes.FunctionType; -import de.tlc4b.btypes.ITypechecker; -import de.tlc4b.btypes.IntegerOrSetOfPairType; -import de.tlc4b.btypes.IntegerOrSetType; -import de.tlc4b.btypes.IntegerType; -import de.tlc4b.btypes.EnumeratedSetElement; -import de.tlc4b.btypes.PairType; -import de.tlc4b.btypes.SetType; -import de.tlc4b.btypes.StringType; -import de.tlc4b.btypes.StructType; -import de.tlc4b.btypes.UntypedType; -import de.tlc4b.exceptions.TypeErrorException; -import de.tlc4b.exceptions.UnificationException; -import de.tlc4b.ltl.LTLBPredicate; -import de.tlc4b.ltl.LTLFormulaVisitor; - -/** - * TODO we need a second run over the AST to check if all local variables have a - * type. This run should be performed after the normal model checking task. - */ -public class Typechecker extends DepthFirstAdapter implements ITypechecker { - - private final Hashtable<Node, BType> types; - private final Hashtable<Node, Node> referenceTable; - private final MachineContext machineContext; - - public Typechecker(MachineContext context) { - this.types = new Hashtable<Node, BType>(); - this.referenceTable = context.getReferences(); - this.machineContext = context; - - context.getStartNode().apply(this); - checkConstantsSetup(); - checkLTLFormulas(); - } - - private void checkLTLFormulas() { - ArrayList<LTLFormulaVisitor> visitors = machineContext.getLTLFormulas(); - for (int i = 0; i < visitors.size(); i++) { - LTLFormulaVisitor visitor = visitors.get(i); - Collection<AIdentifierExpression> parameter = visitor.getParameter(); - for (AIdentifierExpression param : parameter) { - setType(param, new UntypedType()); - } - for (int j = 0; j < visitor.getBPredicates().size(); j++) { - LTLBPredicate ltlBPredicate = visitor.getBPredicates().get(j); - ltlBPredicate.getBFormula().apply(this); - } - } - - } - - private void checkConstantsSetup() { - PPredicate p = machineContext.getConstantsSetup(); - if (p != null) { - setType(p, BoolType.getInstance()); - p.apply(this); - for (Entry<String, Node> entry : machineContext.getConstants().entrySet()) { - String c = entry.getKey(); - Node n = entry.getValue(); - if (getType(n).isUntyped()) { - throw new TypeErrorException("Can not infer type of constant '" + c + "': " + getType(n)); - } - } - } - } - - @Override - public void caseAPredicateParseUnit(APredicateParseUnit node) { - setType(node.getPredicate(), BoolType.getInstance()); - node.getPredicate().apply(this); - } - - public void setType(Node node, BType t) { - this.types.put(node, t); - if (t instanceof AbstractHasFollowers) { - ((AbstractHasFollowers) t).addFollower(node); - } - } - - public void updateType(Node node, AbstractHasFollowers oldType, BType newType) { - oldType.deleteFollower(node); - this.types.put(node, newType); - if (newType instanceof AbstractHasFollowers) { - ((AbstractHasFollowers) newType).addFollower(node); - } - } - - public BType getType(Node node) { - BType res = types.get(node); - if (res == null) { - new TypeErrorException("Node '" + node + "' has no type.\n" + node.getStartPos()); - } - return res; - } - - @Override - public void caseAAbstractMachineParseUnit(AAbstractMachineParseUnit node) { - if (node.getVariant() != null) { - node.getVariant().apply(this); - } - if (node.getHeader() != null) { - node.getHeader().apply(this); - } - { - List<PMachineClause> copy = new ArrayList<PMachineClause>(node.getMachineClauses()); - for (PMachineClause e : copy) { - e.apply(this); - } - } - } - - /** - * Declarations - */ - - @Override - public void caseAMachineHeader(AMachineHeader node) { - List<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); - for (PExpression e : copy) { - AIdentifierExpression p = (AIdentifierExpression) e; - String name = Utils.getTIdentifierListAsString(p.getIdentifier()); - - if (Character.isUpperCase(name.charAt(0))) { - - EnumeratedSetElement m = new EnumeratedSetElement(name); - setType(p, new SetType(m)); - } else { - UntypedType u = new UntypedType(); - setType(p, u); - } - } - } - - @Override - public void caseASetsMachineClause(ASetsMachineClause node) { - List<PSet> copy = new ArrayList<PSet>(node.getSetDefinitions()); - for (PSet e : copy) { - e.apply(this); - } - } - - @Override - public void caseAEnumeratedSetSet(AEnumeratedSetSet node) { - List<TIdentifierLiteral> copy = new ArrayList<TIdentifierLiteral>(node.getIdentifier()); - - String setName = Utils.getTIdentifierListAsString(copy); - SetType set = new SetType(new EnumeratedSetElement(setName)); - setType(node, set); - List<PExpression> copy2 = new ArrayList<PExpression>(node.getElements()); - for (PExpression e : copy2) { - setType(e, set.getSubtype()); - } - } - - @Override - public void caseADeferredSetSet(ADeferredSetSet node) { - List<TIdentifierLiteral> copy = new ArrayList<TIdentifierLiteral>(node.getIdentifier()); - String name = Utils.getTIdentifierListAsString(copy); - setType(node, new SetType(new EnumeratedSetElement(name))); - } - - @Override - public void caseAConstantsMachineClause(AConstantsMachineClause node) { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - AIdentifierExpression id = (AIdentifierExpression) e; - UntypedType u = new UntypedType(); - setType(id, u); - } - } - - @Override - public void caseAAbstractConstantsMachineClause(AAbstractConstantsMachineClause node) { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - AIdentifierExpression id = (AIdentifierExpression) e; - UntypedType u = new UntypedType(); - setType(id, u); - } - } - - @Override - public void caseAVariablesMachineClause(AVariablesMachineClause node) { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - AIdentifierExpression v = (AIdentifierExpression) e; - UntypedType u = new UntypedType(); - setType(v, u); - } - } - - @Override - public void caseAConcreteVariablesMachineClause(AConcreteVariablesMachineClause node) { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - AIdentifierExpression v = (AIdentifierExpression) e; - UntypedType u = new UntypedType(); - setType(v, u); - } - } - - /** - * Definitions - */ - - @Override - public void caseADefinitionsMachineClause(ADefinitionsMachineClause node) { - List<PDefinition> copy = new ArrayList<PDefinition>(node.getDefinitions()); - for (PDefinition e : copy) { - setType(e, new UntypedType()); - } - - for (PDefinition e : copy) { - e.apply(this); - } - } - - @Override - // d(a) == 1 - public void caseAExpressionDefinitionDefinition(AExpressionDefinitionDefinition node) { - List<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); - for (PExpression e : copy) { - UntypedType u = new UntypedType(); - setType(e, u); - } - setType(node.getRhs(), getType(node)); - node.getRhs().apply(this); - } - - @Override - // d(a) == 1 = 1 - public void caseAPredicateDefinitionDefinition(APredicateDefinitionDefinition node) { - setType(node, BoolType.getInstance()); - List<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); - for (PExpression e : copy) { - setType(e, new UntypedType()); - } - setType(node.getRhs(), BoolType.getInstance()); - node.getRhs().apply(this); - } - - @Override - public void caseADefinitionExpression(ADefinitionExpression node) { - BType expected = getType(node); - // String name = node.getDefLiteral().getText().toString(); - Node originalDef = referenceTable.get(node); - BType found = getType(originalDef); - - try { - found.unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Expected '" + expected + "', found '" + found + "' at definition call\n"); - } - LinkedList<PExpression> params = ((AExpressionDefinitionDefinition) originalDef).getParameters(); - List<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); - for (int i = 0; i < params.size(); i++) { - BType type = getType(params.get(i)); - setType(copy.get(i), type); - copy.get(i).apply(this); - } - } - - @Override - public void caseADefinitionPredicate(ADefinitionPredicate node) { - BType expected = getType(node); - Node originalDef = referenceTable.get(node); - BType found = BoolType.getInstance(); - - try { - found.unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Expected '" + expected + "', found '" + found + "' at definition call\n"); - } - LinkedList<PExpression> params = ((APredicateDefinitionDefinition) originalDef).getParameters(); - List<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); - for (int i = 0; i < params.size(); i++) { - setType(copy.get(i), getType(params.get(i))); - copy.get(i).apply(this); - } - } - - /** - * Properties - */ - - @Override - public void caseAConstraintsMachineClause(AConstraintsMachineClause node) { - if (node.getPredicates() != null) { - setType(node.getPredicates(), BoolType.getInstance()); - node.getPredicates().apply(this); - } - for (Entry<String, Node> entry : machineContext.getScalarParameter().entrySet()) { - String name = entry.getKey(); - Node n = entry.getValue(); - if (getType(n).isUntyped()) { - throw new TypeErrorException("Can not infer type of parameter '" + name + "'"); - } - } - } - - @Override - public void caseAPropertiesMachineClause(final APropertiesMachineClause node) { - if (node.getPredicates() != null) { - setType(node.getPredicates(), BoolType.getInstance()); - node.getPredicates().apply(this); - } - for (Entry<String, Node> entry : machineContext.getConstants().entrySet()) { - String c = entry.getKey(); - Node n = entry.getValue(); - if (getType(n).isUntyped()) { - throw new TypeErrorException("Can not infer type of constant '" + c + "': " + getType(n)); - } - } - } - - @Override - public void caseAInvariantMachineClause(AInvariantMachineClause node) { - setType(node.getPredicates(), BoolType.getInstance()); - node.getPredicates().apply(this); - for (Entry<String, Node> entry : machineContext.getVariables().entrySet()) { - String c = entry.getKey(); - Node n = entry.getValue(); - if (getType(n).isUntyped()) { - throw new TypeErrorException("Can not infer type of variable '" + c + "'"); - } - } - } - - @Override - public void caseAAssertionsMachineClause(AAssertionsMachineClause node) { - List<PPredicate> copy = new ArrayList<PPredicate>(node.getPredicates()); - for (PPredicate e : copy) { - setType(e, BoolType.getInstance()); - e.apply(this); - } - } - - @Override - public void caseAInitialisationMachineClause(AInitialisationMachineClause node) { - if (node.getSubstitutions() != null) { - node.getSubstitutions().apply(this); - } - } - - @Override - public void caseAOperation(AOperation node) { - { - List<PExpression> copy = new ArrayList<PExpression>(node.getReturnValues()); - for (PExpression e : copy) { - AIdentifierExpression id = (AIdentifierExpression) e; - UntypedType u = new UntypedType(); - setType(id, u); - } - - } - { - List<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); - for (PExpression e : copy) { - AIdentifierExpression id = (AIdentifierExpression) e; - UntypedType u = new UntypedType(); - setType(id, u); - } - } - if (node.getOperationBody() != null) { - node.getOperationBody().apply(this); - } - } - - /** - * Expressions - */ - - @Override - public void caseAIdentifierExpression(AIdentifierExpression node) { - - BType expected = getType(node); - - if (expected == null) { - System.out.println("Not implemented in Typechecker:" + node.parent().getClass()); - throw new RuntimeException(node + " Pos: " + node.getStartPos()); - } - Node identifierDeclarationNode = referenceTable.get(node); - BType found = getType(identifierDeclarationNode); - - String name = Utils.getTIdentifierListAsString(node.getIdentifier()); - try { - expected.unify(found, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found '" + found + "' at identifier " + name - + "\n" + node.getStartPos()); - } - } - - @Override - public void caseAEqualPredicate(AEqualPredicate node) { - try { - BoolType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Expected '" + getType(node) + "', found BOOL at '=' \n" + node.getStartPos()); - } - - UntypedType x = new UntypedType(); - setType(node.getLeft(), x); - setType(node.getRight(), x); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseAIfThenElseExpression(AIfThenElseExpression node) { - setType(node.getCondition(), BoolType.getInstance()); - node.getCondition().apply(this); - - UntypedType x = new UntypedType(); - setType(node.getThen(), x); - setType(node.getElse(), x); - node.getThen().apply(this); - node.getElse().apply(this); - BType found = getType(node.getThen()); - unify(getType(node), found, node); - } - - @Override - public void caseANotEqualPredicate(ANotEqualPredicate node) { - try { - BoolType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Expected '" + getType(node) + "', found BOOL at '=' \n" + node.getClass()); - } - - UntypedType x = new UntypedType(); - setType(node.getLeft(), x); - setType(node.getRight(), x); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseAForallPredicate(AForallPredicate node) { - try { - BoolType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Expected '" + getType(node) + "', found BOOL at 'For All' \n"); - } - - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - AIdentifierExpression v = (AIdentifierExpression) e; - setType(v, new UntypedType()); - } - - setType(node.getImplication(), BoolType.getInstance()); - node.getImplication().apply(this); - } - - @Override - public void caseAExistsPredicate(AExistsPredicate node) { - try { - BoolType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Expected '" + getType(node) + "', found BOOL at 'Exists' \n"); - } - - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - AIdentifierExpression v = (AIdentifierExpression) e; - setType(v, new UntypedType()); - } - - setType(node.getPredicate(), BoolType.getInstance()); - node.getPredicate().apply(this); - } - - /** - * Substitutions - * - */ - - @Override - public void caseAPreconditionSubstitution(APreconditionSubstitution node) { - setType(node.getPredicate(), BoolType.getInstance()); - node.getPredicate().apply(this); - node.getSubstitution().apply(this); - } - - @Override - public void caseAAssertionSubstitution(AAssertionSubstitution node) { - setType(node.getPredicate(), BoolType.getInstance()); - node.getPredicate().apply(this); - node.getSubstitution().apply(this); - } - - @Override - public void caseASelectSubstitution(ASelectSubstitution node) { - setType(node.getCondition(), BoolType.getInstance()); - node.getCondition().apply(this); - node.getThen().apply(this); - List<PSubstitution> copy = new ArrayList<PSubstitution>(node.getWhenSubstitutions()); - for (PSubstitution e : copy) { - e.apply(this); - } - if (node.getElse() != null) { - node.getElse().apply(this); - } - } - - @Override - public void caseASelectWhenSubstitution(ASelectWhenSubstitution node) { - setType(node.getCondition(), BoolType.getInstance()); - node.getCondition().apply(this); - node.getSubstitution().apply(this); - } - - @Override - public void caseAIfSubstitution(AIfSubstitution node) { - setType(node.getCondition(), BoolType.getInstance()); - node.getCondition().apply(this); - node.getThen().apply(this); - List<PSubstitution> copy = new ArrayList<PSubstitution>(node.getElsifSubstitutions()); - for (PSubstitution e : copy) { - e.apply(this); - } - if (node.getElse() != null) { - node.getElse().apply(this); - } - } - - @Override - public void caseAIfElsifSubstitution(AIfElsifSubstitution node) { - setType(node.getCondition(), BoolType.getInstance()); - node.getCondition().apply(this); - node.getThenSubstitution().apply(this); - } - - @Override - public void caseAAssignSubstitution(AAssignSubstitution node) { - List<PExpression> copy = new ArrayList<PExpression>(node.getLhsExpression()); - List<PExpression> copy2 = new ArrayList<PExpression>(node.getRhsExpressions()); - - for (int i = 0; i < copy.size(); i++) { - PExpression left = copy.get(i); - PExpression right = copy2.get(i); - - UntypedType x = new UntypedType(); - setType(left, x); - setType(right, x); - - left.apply(this); - right.apply(this); - } - - } - - @Override - public void caseABecomesSuchSubstitution(ABecomesSuchSubstitution node) { - setType(node.getPredicate(), BoolType.getInstance()); - node.getPredicate().apply(this); - } - - @Override - public void caseABecomesElementOfSubstitution(ABecomesElementOfSubstitution node) { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - SetType set = new SetType(new UntypedType()); - - setType(node.getSet(), set); - for (PExpression e : copy) { - setType(e, set.getSubtype()); - } - for (PExpression e : copy) { - e.apply(this); - } - node.getSet().apply(this); - } - - @Override - public void caseAAnySubstitution(AAnySubstitution node) { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - AIdentifierExpression v = (AIdentifierExpression) e; - setType(v, new UntypedType()); - } - setType(node.getWhere(), BoolType.getInstance()); - node.getWhere().apply(this); - node.getThen().apply(this); - } - - @Override - public void caseALetSubstitution(ALetSubstitution node) { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - AIdentifierExpression v = (AIdentifierExpression) e; - setType(v, new UntypedType()); - } - setType(node.getPredicate(), BoolType.getInstance()); - node.getPredicate().apply(this); - node.getSubstitution().apply(this); - } - - /**************************************************************************** - * Arithmetic operators * - ****************************************************************************/ - - @Override - public void caseAIntegerExpression(AIntegerExpression node) { - try { - IntegerType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException( - "Excepted '" + getType(node) + "' , found 'INTEGER' in '" + node.getLiteral().getText() + "'"); - } - } - - @Override - public void caseAIntegerSetExpression(AIntegerSetExpression node) { - try { - SetType found = new SetType(IntegerType.getInstance()); - found.unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'POW(INTEGER)' in 'INTEGER'"); - } - } - - @Override - public void caseANaturalSetExpression(ANaturalSetExpression node) { - try { - SetType found = new SetType(IntegerType.getInstance()); - found.unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'POW(INTEGER)' in 'NATURAL'"); - } - } - - @Override - public void caseANatural1SetExpression(ANatural1SetExpression node) { - try { - SetType found = new SetType(IntegerType.getInstance()); - found.unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'POW(INTEGER)' in 'NATURAL1'"); - } - } - - @Override - public void caseAIntSetExpression(AIntSetExpression node) { - try { - SetType found = new SetType(IntegerType.getInstance()); - found.unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'POW(INTEGER)' in 'INT'"); - } - } - - @Override - public void caseANatSetExpression(ANatSetExpression node) { - try { - SetType found = new SetType(IntegerType.getInstance()); - found.unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'POW(INTEGER)' in 'NAT'"); - } - } - - @Override - public void caseANat1SetExpression(ANat1SetExpression node) { - try { - SetType found = new SetType(IntegerType.getInstance()); - found.unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'POW(INTEGER)' in 'NAT1'"); - } - } - - @Override - public void caseAUnaryMinusExpression(AUnaryMinusExpression node) { - try { - IntegerType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'INTEGER' in '-'"); - } - } - - @Override - public void caseAIntervalExpression(AIntervalExpression node) { - try { - SetType found = new SetType(IntegerType.getInstance()); - found.unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException( - "Excepted '" + getType(node) + "' , found 'POW(INTEGER)' at interval operator"); - } - - setType(node.getLeftBorder(), IntegerType.getInstance()); - setType(node.getRightBorder(), IntegerType.getInstance()); - node.getLeftBorder().apply(this); - node.getRightBorder().apply(this); - } - - @Override - public void caseAMaxIntExpression(AMaxIntExpression node) { - unify(getType(node), IntegerType.getInstance(), node); - } - - @Override - public void caseAMinIntExpression(AMinIntExpression node) { - unify(getType(node), IntegerType.getInstance(), node); - } - - @Override - public void caseAGreaterPredicate(AGreaterPredicate node) { - try { - BoolType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in ' > '"); - } - setType(node.getLeft(), IntegerType.getInstance()); - setType(node.getRight(), IntegerType.getInstance()); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseALessPredicate(ALessPredicate node) { - try { - BoolType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in ' < '"); - } - setType(node.getLeft(), IntegerType.getInstance()); - setType(node.getRight(), IntegerType.getInstance()); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseAGreaterEqualPredicate(AGreaterEqualPredicate node) { - try { - BoolType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in ' >= '"); - } - setType(node.getLeft(), IntegerType.getInstance()); - setType(node.getRight(), IntegerType.getInstance()); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseALessEqualPredicate(ALessEqualPredicate node) { - try { - BoolType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in ' <= '"); - } - setType(node.getLeft(), IntegerType.getInstance()); - setType(node.getRight(), IntegerType.getInstance()); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseAMinExpression(AMinExpression node) { - try { - IntegerType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'INTEGER' in ' min '"); - } - setType(node.getExpression(), new SetType(IntegerType.getInstance())); - node.getExpression().apply(this); - } - - @Override - public void caseAMaxExpression(AMaxExpression node) { - try { - IntegerType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'INTEGER' in ' min '"); - } - setType(node.getExpression(), new SetType(IntegerType.getInstance())); - node.getExpression().apply(this); - } - - @Override - public void caseAAddExpression(AAddExpression node) { - try { - IntegerType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'INTEGER' in ' + '"); - } - setType(node.getLeft(), IntegerType.getInstance()); - setType(node.getRight(), IntegerType.getInstance()); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseAMinusOrSetSubtractExpression(AMinusOrSetSubtractExpression node) { - BType expected = getType(node); - - BType found = new IntegerOrSetType(); - unify(expected, found, node); - - setType(node.getLeft(), getType(node)); - setType(node.getRight(), getType(node)); - - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseAMultOrCartExpression(AMultOrCartExpression node) { - BType expected = getType(node); - IntegerOrSetOfPairType found = new IntegerOrSetOfPairType(node.getStartPos(), node.getEndPos()); - // setType(node.getLeft(), found.getFirst()); - // setType(node.getRight(), found.getSecond()); - BType result = null; - try { - result = expected.unify(found, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "' at " - + node.getClass().getSimpleName() + "\n " + node.getStartPos()); - } - // - // BType res2 = getType(node); - // if(res2 != result){ - // AbstractHasFollowers a = (AbstractHasFollowers) res2; - // throw new RuntimeException(); - // } - // - - if (result instanceof IntegerOrSetOfPairType) { - setType(node.getLeft(), ((IntegerOrSetOfPairType) result).getFirst()); - setType(node.getRight(), ((IntegerOrSetOfPairType) result).getSecond()); - } else if (result instanceof IntegerType) { - setType(node.getLeft(), result); - setType(node.getRight(), result); - } else if (result instanceof SetType) { - PairType pair = (PairType) ((SetType) result).getSubtype(); - setType(node.getLeft(), new SetType(pair.getFirst())); - setType(node.getRight(), new SetType(pair.getSecond())); - } else { - System.out.println(result); - throw new RuntimeException(); - } - - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseADivExpression(ADivExpression node) { - try { - IntegerType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'INTEGER' in ' / '"); - } - setType(node.getLeft(), IntegerType.getInstance()); - setType(node.getRight(), IntegerType.getInstance()); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseAPowerOfExpression(APowerOfExpression node) { - try { - IntegerType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'INTEGER' in ' ** '"); - } - setType(node.getLeft(), IntegerType.getInstance()); - setType(node.getRight(), IntegerType.getInstance()); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseAModuloExpression(AModuloExpression node) { - try { - IntegerType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'INTEGER' in ' mod '"); - } - setType(node.getLeft(), IntegerType.getInstance()); - setType(node.getRight(), IntegerType.getInstance()); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseASuccessorExpression(ASuccessorExpression node) { - FunctionType found = new FunctionType(IntegerType.getInstance(), IntegerType.getInstance()); - unify(getType(node), found, node); - } - - @Override - public void caseAPredecessorExpression(APredecessorExpression node) { - FunctionType found = new FunctionType(IntegerType.getInstance(), IntegerType.getInstance()); - unify(getType(node), found, node); - } - - @Override - public void caseAGeneralSumExpression(AGeneralSumExpression node) { - BType expected = getType(node); - try { - IntegerType.getInstance().unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found '" + "INTEGER" + "'"); - } - - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - AIdentifierExpression v = (AIdentifierExpression) e; - setType(v, new UntypedType()); - } - - setType(node.getPredicates(), BoolType.getInstance()); - node.getPredicates().apply(this); - - setType(node.getExpression(), IntegerType.getInstance()); - node.getExpression().apply(this); - } - - @Override - public void caseAGeneralProductExpression(AGeneralProductExpression node) { - BType expected = getType(node); - try { - IntegerType.getInstance().unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found '" + "INTEGER" + "'"); - } - - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - AIdentifierExpression v = (AIdentifierExpression) e; - setType(v, new UntypedType()); - } - - setType(node.getPredicates(), BoolType.getInstance()); - node.getPredicates().apply(this); - - setType(node.getExpression(), IntegerType.getInstance()); - node.getExpression().apply(this); - } - - /** - * Booleans - */ - - @Override - public void caseABooleanTrueExpression(ABooleanTrueExpression node) { - try { - BoolType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in 'TRUE'"); - } - } - - @Override - public void caseABooleanFalseExpression(ABooleanFalseExpression node) { - try { - BoolType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in 'FALSE'"); - } - } - - @Override - public void caseABoolSetExpression(ABoolSetExpression node) { - try { - SetType found = new SetType(BoolType.getInstance()); - found.unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'POW(BOOL)' in 'BOOL'"); - } - } - - @Override - public void caseAConvertBoolExpression(AConvertBoolExpression node) { - try { - BoolType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in 'bool(...)'"); - } - setType(node.getPredicate(), BoolType.getInstance()); - node.getPredicate().apply(this); - } - - /** - * Logical Operator - */ - - @Override - public void caseAConjunctPredicate(AConjunctPredicate node) { - try { - BoolType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException( - "Excepted '" + getType(node) + "' , found 'BOOL' in ' & '." + node.getStartPos()); - } - setType(node.getLeft(), BoolType.getInstance()); - setType(node.getRight(), BoolType.getInstance()); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseADisjunctPredicate(ADisjunctPredicate node) { - try { - BoolType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in ' or '"); - } - setType(node.getLeft(), BoolType.getInstance()); - setType(node.getRight(), BoolType.getInstance()); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseAImplicationPredicate(AImplicationPredicate node) { - try { - BoolType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in ' => '"); - } - setType(node.getLeft(), BoolType.getInstance()); - setType(node.getRight(), BoolType.getInstance()); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseAEquivalencePredicate(AEquivalencePredicate node) { - try { - BoolType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - System.out.println(node.parent().getClass()); - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in ' <=> '"); - } - setType(node.getLeft(), BoolType.getInstance()); - setType(node.getRight(), BoolType.getInstance()); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseANegationPredicate(ANegationPredicate node) { - try { - BoolType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in ' not '"); - } - setType(node.getPredicate(), BoolType.getInstance()); - node.getPredicate().apply(this); - } - - /** - * Sets - */ - - @Override - public void caseAEmptySetExpression(AEmptySetExpression node) { - BType expected = getType(node); - if (expected instanceof FunctionType) { - return; - } else { - unify(expected, new SetType(new UntypedType()), node); - } - } - - @Override - public void caseASetExtensionExpression(ASetExtensionExpression node) { - if (functionTest(node)) - return; - UntypedType u = new UntypedType(); - for (PExpression e : node.getExpressions()) { - setType(e, u); - } - BType expected = getType(node); - List<PExpression> copy = new ArrayList<PExpression>(node.getExpressions()); - for (PExpression e : copy) { - e.apply(this); - } - BType found = new SetType(getType(copy.get(0))); - unify(expected, found, node); - } - - private boolean functionTest(ASetExtensionExpression node) { - ArrayList<Node> list1 = new ArrayList<Node>(); - ArrayList<Node> list2 = new ArrayList<Node>(); - try { - for (PExpression e : node.getExpressions()) { - ACoupleExpression couple = (ACoupleExpression) e; - Node left = couple.getList().get(0); - Node right = couple.getList().get(1); - list1.add(left); - list2.add(right); - if (couple.getList().size() > 2) - return false; - } - if (compareElementsOfList(list1)) { - UntypedType leftType = new UntypedType(); - UntypedType rightType = new UntypedType(); - for (int i = 0; i < list1.size(); i++) { - setType(list1.get(i), leftType); - setType(list2.get(i), rightType); - } - for (int i = 0; i < list1.size(); i++) { - list1.get(i).apply(this); - list2.get(i).apply(this); - } - BType res1 = getType(list1.get(0)); - BType res2 = getType(list2.get(0)); - FunctionType func = new FunctionType(res1, res2); - BType expected = getType(node); - unify(expected, func, node); - return true; - } - - } catch (ClassCastException e) { - return false; - } - return false; - } - - private boolean compareElementsOfList(ArrayList<Node> list) { - if (list.size() == 1) { - return true; - } - try { - if (list.get(0) instanceof AIntegerExpression) { - HashSet<Integer> set = new HashSet<Integer>(); - for (int i = 0; i < list.size(); i++) { - AIntegerExpression aInt = (AIntegerExpression) list.get(i); - int integer = Integer.parseInt(aInt.getLiteral().getText()); - set.add(integer); - } - if (list.size() == set.size()) { - return true; - } - } else if (list.get(0) instanceof AIdentifierExpression) { - HashSet<Node> set = new HashSet<Node>(); - for (int i = 0; i < list.size(); i++) { - AIdentifierExpression id = (AIdentifierExpression) list.get(i); - Node enumValue = machineContext.getReferences().get(id); - if (!machineContext.getEnumValues().containsValue(enumValue)) { - return false; - } - set.add(enumValue); - } - if (list.size() == set.size()) { - return true; - } - - } - } catch (ClassCastException e) { - } - return false; - } - - @Override - public void caseAComprehensionSetExpression(AComprehensionSetExpression node) { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - ArrayList<BType> typesList = new ArrayList<BType>(); - for (PExpression e : copy) { - AIdentifierExpression v = (AIdentifierExpression) e; - UntypedType u = new UntypedType(); - typesList.add(u); - setType(v, u); - } - BType listType = makePair(typesList); - SetType found = new SetType(listType); - - try { - found.unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found " + found + "'"); - } - - setType(node.getPredicates(), BoolType.getInstance()); - node.getPredicates().apply(this); - - } - - @Override - public void caseAEventBComprehensionSetExpression(AEventBComprehensionSetExpression node) { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - AIdentifierExpression v = (AIdentifierExpression) e; - setType(v, new UntypedType()); - } - - setType(node.getPredicates(), BoolType.getInstance()); - node.getPredicates().apply(this); - - setType(node.getExpression(), new UntypedType()); - node.getExpression().apply(this); - - BType found = new SetType(getType(node.getExpression())); - - BType expected = getType(node); - unify(expected, found, node); - } - - public static BType makePair(ArrayList<BType> list) { - if (list.size() == 1) - return list.get(0); - PairType p = new PairType(list.get(0), null); - for (int i = 1; i < list.size(); i++) { - p.setSecond(list.get(i)); - if (i < list.size() - 1) { - p = new PairType(p, null); - } - } - return p; - } - - // POW, POW1, FIN, FIN1 - private void subset(Node node, Node expr) { - SetType found = new SetType(new SetType(new UntypedType())); - BType expected = getType(node); - try { - found = found.unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found 'POW(POW(_A))' in 'POW'"); - } - - setType(expr, found.getSubtype()); - expr.apply(this); - } - - @Override - public void caseAPowSubsetExpression(APowSubsetExpression node) { - subset(node, node.getExpression()); - } - - @Override - public void caseAPow1SubsetExpression(APow1SubsetExpression node) { - subset(node, node.getExpression()); - } - - @Override - public void caseAFinSubsetExpression(AFinSubsetExpression node) { - subset(node, node.getExpression()); - } - - @Override - public void caseAFin1SubsetExpression(AFin1SubsetExpression node) { - subset(node, node.getExpression()); - } - - // union, intersection, substraction, - private void setSetSet(Node node, Node left, Node right) { - SetType found = new SetType(new UntypedType()); - BType expected = getType(node); - try { - found = found.unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); - } - setType(left, found); - setType(right, found); - left.apply(this); - right.apply(this); - } - - @Override - public void caseAUnionExpression(AUnionExpression node) { - setSetSet(node, node.getLeft(), node.getRight()); - } - - @Override - public void caseAIntersectionExpression(AIntersectionExpression node) { - setSetSet(node, node.getLeft(), node.getRight()); - } - - @Override - public void caseASetSubtractionExpression(ASetSubtractionExpression node) { - setSetSet(node, node.getLeft(), node.getRight()); - } - - @Override - public void caseACardExpression(ACardExpression node) { - BType found = IntegerType.getInstance(); - BType expected = getType(node); - - try { - found.unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); - } - - setType(node.getExpression(), new UntypedType()); - node.getExpression().apply(this); - BType type = getType(node.getExpression()); - if (!(type instanceof FunctionType)) { - new SetType(new UntypedType()).unify(type, this); - } - } - - @Override - public void caseAMemberPredicate(AMemberPredicate node) { - SetType set = new SetType(new UntypedType()); - - setType(node.getLeft(), set.getSubtype()); - setType(node.getRight(), set); - - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseANotMemberPredicate(ANotMemberPredicate node) { - SetType set = new SetType(new UntypedType()); - - setType(node.getLeft(), set.getSubtype()); - setType(node.getRight(), set); - - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseASubsetPredicate(ASubsetPredicate node) { - BType expected = getType(node); - try { - BoolType.getInstance().unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found 'BOOL'"); - } - SetType set = new SetType(new UntypedType()); - - setType(node.getLeft(), set); - setType(node.getRight(), set); - - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseASubsetStrictPredicate(ASubsetStrictPredicate node) { - BType expected = getType(node); - try { - BoolType.getInstance().unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found 'BOOL'"); - } - - SetType set = new SetType(new UntypedType()); - - setType(node.getLeft(), set); - setType(node.getRight(), set); - - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseANotSubsetPredicate(ANotSubsetPredicate node) { - BType expected = getType(node); - try { - BoolType.getInstance().unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found 'BOOL'"); - } - - SetType set = new SetType(new UntypedType()); - - setType(node.getLeft(), set); - setType(node.getRight(), set); - - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseANotSubsetStrictPredicate(ANotSubsetStrictPredicate node) { - BType expected = getType(node); - try { - BoolType.getInstance().unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found 'BOOL'"); - } - - SetType set = new SetType(new UntypedType()); - - setType(node.getLeft(), set); - setType(node.getRight(), set); - - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseAGeneralUnionExpression(AGeneralUnionExpression node) { - SetType set = new SetType(new SetType(new UntypedType())); - setType(node.getExpression(), set); - node.getExpression().apply(this); - - BType found = ((SetType) getType(node.getExpression())).getSubtype(); - BType expected = getType(node); - try { - found.unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found '" + found + "'"); - } - } - - @Override - public void caseAGeneralIntersectionExpression(AGeneralIntersectionExpression node) { - SetType set = new SetType(new SetType(new UntypedType())); - setType(node.getExpression(), set); - node.getExpression().apply(this); - - BType found = ((SetType) getType(node.getExpression())).getSubtype(); - BType expected = getType(node); - try { - found.unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found '" + found + "'"); - } - } - - @Override - public void caseAQuantifiedUnionExpression(AQuantifiedUnionExpression node) { - BType expected = getType(node); - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - AIdentifierExpression v = (AIdentifierExpression) e; - UntypedType u = new UntypedType(); - setType(v, u); - } - - setType(node.getPredicates(), BoolType.getInstance()); - node.getPredicates().apply(this); - setType(node.getExpression(), new SetType(new UntypedType())); - node.getExpression().apply(this); - - BType found = getType(node.getExpression()); - try { - found.unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); - } - } - - @Override - public void caseAQuantifiedIntersectionExpression(AQuantifiedIntersectionExpression node) { - BType expected = getType(node); - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - AIdentifierExpression v = (AIdentifierExpression) e; - UntypedType u = new UntypedType(); - setType(v, u); - } - - setType(node.getPredicates(), BoolType.getInstance()); - node.getPredicates().apply(this); - setType(node.getExpression(), new SetType(new UntypedType())); - node.getExpression().apply(this); - - BType found = getType(node.getExpression()); - try { - found.unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); - } - } - - /** - * Functions - */ - - @Override - public void caseALambdaExpression(ALambdaExpression node) { - List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); - for (PExpression e : copy) { - AIdentifierExpression v = (AIdentifierExpression) e; - setType(v, new UntypedType()); - } - - setType(node.getPredicate(), BoolType.getInstance()); - node.getPredicate().apply(this); - - setType(node.getExpression(), new UntypedType()); - node.getExpression().apply(this); - - ArrayList<BType> typesList = new ArrayList<BType>(); - for (PExpression e : copy) { - typesList.add(getType(e)); - } - BType domain = makePair(typesList); - BType range = getType(node.getExpression()); - - BType found = new FunctionType(domain, range); - // BType found = new SetType(new PairType(domain, range)); - - BType expected = getType(node); - try { - found.unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); - } - } - - @Override - public void caseAFunctionExpression(AFunctionExpression node) { - FunctionType func = new FunctionType(new UntypedType(), new UntypedType()); - setType(node.getIdentifier(), func); - node.getIdentifier().apply(this); - - BType id = getType(node.getIdentifier()); - BType domainFound; - BType rangeFound; - if (id instanceof FunctionType) { - domainFound = ((FunctionType) id).getDomain(); - rangeFound = ((FunctionType) id).getRange(); - } else { - PairType p = (PairType) ((SetType) id).getSubtype(); - domainFound = p.getFirst(); - rangeFound = p.getSecond(); - } - BType expected = getType(node); - try { - rangeFound.unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found " + rangeFound + "'"); - } - - ArrayList<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); - for (PExpression e : copy) { - setType(e, new UntypedType()); - e.apply(this); - } - - ArrayList<BType> foundList = new ArrayList<BType>(); - for (PExpression e : copy) { - foundList.add(getType(e)); - } - - BType p = makePair(foundList); - try { - domainFound.unify(p, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + domainFound + "' , found '" + makePair(foundList) + "'"); - } - } - - @Override - public void caseADomainExpression(ADomainExpression node) { - FunctionType f = new FunctionType(new UntypedType(), new UntypedType()); - setType(node.getExpression(), f); - node.getExpression().apply(this); - - BType b = getType(node.getExpression()); - BType domainFound; - if (b instanceof FunctionType) { - domainFound = new SetType(((FunctionType) b).getDomain()); - } else { - PairType p = (PairType) ((SetType) b).getSubtype(); - domainFound = new SetType(p.getFirst()); - } - BType expected = getType(node); - try { - domainFound.unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found '" + domainFound + "'"); - } - } - - @Override - public void caseARangeExpression(ARangeExpression node) { - FunctionType f = new FunctionType(new UntypedType(), new UntypedType()); - setType(node.getExpression(), f); - node.getExpression().apply(this); - - BType b = getType(node.getExpression()); - BType rangeFound; - if (b instanceof FunctionType) { - rangeFound = new SetType(((FunctionType) b).getRange()); - } else { - PairType p = (PairType) ((SetType) b).getSubtype(); - rangeFound = new SetType(p.getSecond()); - } - BType expected = getType(node); - try { - rangeFound.unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found '" + rangeFound + "'"); - } - } - - @Override - public void caseATotalFunctionExpression(ATotalFunctionExpression node) { - evalFunction(node, node.getLeft(), node.getRight()); - } - - @Override - public void caseAPartialFunctionExpression(APartialFunctionExpression node) { - BType dom = new UntypedType(); - BType ran = new UntypedType(); - setType(node.getLeft(), new SetType(dom)); - setType(node.getRight(), new SetType(ran)); - BType expected = getType(node); - BType found = evalFunctionTypeVsRelationType(node, dom, ran); - unify(expected, found, node); - node.getLeft().apply(this); - node.getRight().apply(this); - // evalFunction(node, node.getLeft(), node.getRight()); - } - - private BType evalFunctionTypeVsRelationType(Node node, BType dom, BType ran) { - String clazz = node.parent().getClass().getName(); - if (clazz.contains("Total") || clazz.contains("Partial")) - return new SetType(new SetType(new PairType(dom, ran))); - else - return new SetType(new FunctionType(dom, ran)); - } - - @Override - public void caseATotalInjectionExpression(ATotalInjectionExpression node) { - evalFunction(node, node.getLeft(), node.getRight()); - } - - @Override - public void caseAPartialInjectionExpression(APartialInjectionExpression node) { - BType dom = new UntypedType(); - BType ran = new UntypedType(); - setType(node.getLeft(), new SetType(dom)); - setType(node.getRight(), new SetType(ran)); - BType expected = getType(node); - BType found = evalFunctionTypeVsRelationType(node, dom, ran); - unify(expected, found, node); - node.getLeft().apply(this); - node.getRight().apply(this); - // evalFunction(node, node.getLeft(), node.getRight()); - } - - @Override - public void caseATotalSurjectionExpression(ATotalSurjectionExpression node) { - evalFunction(node, node.getLeft(), node.getRight()); - } - - @Override - public void caseAPartialSurjectionExpression(APartialSurjectionExpression node) { - // evalFunction(node, node.getLeft(), node.getRight()); - BType dom = new UntypedType(); - BType ran = new UntypedType(); - setType(node.getLeft(), new SetType(dom)); - setType(node.getRight(), new SetType(ran)); - BType expected = getType(node); - BType found = evalFunctionTypeVsRelationType(node, dom, ran); - unify(expected, found, node); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseATotalBijectionExpression(ATotalBijectionExpression node) { - evalFunction(node, node.getLeft(), node.getRight()); - } - - @Override - public void caseAPartialBijectionExpression(APartialBijectionExpression node) { - // evalFunction(node, node.getLeft(), node.getRight()); - BType dom = new UntypedType(); - BType ran = new UntypedType(); - setType(node.getLeft(), new SetType(dom)); - setType(node.getRight(), new SetType(ran)); - BType expected = getType(node); - BType found = evalFunctionTypeVsRelationType(node, dom, ran); - unify(expected, found, node); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - public void evalFunction(Node node, Node left, Node right) { - setType(left, new SetType(new UntypedType())); - left.apply(this); - setType(right, new SetType(new UntypedType())); - right.apply(this); - - BType leftType = ((SetType) getType(left)).getSubtype(); - BType rightType = ((SetType) getType(right)).getSubtype(); - - BType found = new SetType(new FunctionType(leftType, rightType)); - BType expected = getType(node); - try { - expected.unify(found, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); - } - } - - /** - * Relations - */ - - @Override - public void caseACoupleExpression(ACoupleExpression node) { - BType expected = getType(node); - - List<PExpression> copy = new ArrayList<PExpression>(node.getList()); - - ArrayList<BType> list = new ArrayList<BType>(); - - for (PExpression e : copy) { - setType(e, new UntypedType()); - e.apply(this); - } - - for (PExpression e : copy) { - list.add(getType(e)); - } - - BType found = makePair(list); - try { - found.unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); - } - } - - @Override - public void caseARelationsExpression(ARelationsExpression node) { - setType(node.getLeft(), new SetType(new UntypedType())); - node.getLeft().apply(this); - setType(node.getRight(), new SetType(new UntypedType())); - node.getRight().apply(this); - - BType left = ((SetType) getType(node.getLeft())).getSubtype(); - BType right = ((SetType) getType(node.getRight())).getSubtype(); - - BType found = new SetType(new SetType(new PairType(left, right))); - BType expected = getType(node); - try { - expected.unify(found, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); - } - } - - @Override - public void caseAIdentityExpression(AIdentityExpression node) { - SetType s = new SetType(new UntypedType()); - setType(node.getExpression(), s); - node.getExpression().apply(this); - - s = (SetType) getType(node.getExpression()); - - // BType found = new SetType(new PairType(s.getSubtype(), - // s.getSubtype())); - BType found = new FunctionType(s.getSubtype(), s.getSubtype()); - BType expected = getType(node); - - unify(expected, found, node); - } - - @Override - public void caseADomainRestrictionExpression(ADomainRestrictionExpression node) { - UntypedType u = new UntypedType(); - SetType setType = new SetType(u); - FunctionType f = new FunctionType(u, new UntypedType()); - setType(node.getLeft(), setType); - setType(node.getRight(), f); - node.getLeft().apply(this); - node.getRight().apply(this); - - BType found = getType(node.getRight()); - BType expected = getType(node); - unify(expected, found, node); - } - - @Override - public void caseADomainSubtractionExpression(ADomainSubtractionExpression node) { - UntypedType u = new UntypedType(); - SetType setType = new SetType(u); - FunctionType f = new FunctionType(u, new UntypedType()); - setType(node.getLeft(), setType); - setType(node.getRight(), f); - node.getLeft().apply(this); - node.getRight().apply(this); - - BType found = getType(node.getRight()); - BType expected = getType(node); - unify(expected, found, node); - } - - @Override - public void caseARangeRestrictionExpression(ARangeRestrictionExpression node) { - UntypedType u = new UntypedType(); - SetType setType = new SetType(u); - FunctionType f = new FunctionType(new UntypedType(), u); - setType(node.getLeft(), f); - setType(node.getRight(), setType); - node.getLeft().apply(this); - node.getRight().apply(this); - - BType found = getType(node.getLeft()); - BType expected = getType(node); - unify(expected, found, node); - } - - @Override - public void caseARangeSubtractionExpression(ARangeSubtractionExpression node) { - UntypedType u = new UntypedType(); - SetType setType = new SetType(u); - FunctionType f = new FunctionType(new UntypedType(), u); - setType(node.getLeft(), f); - setType(node.getRight(), setType); - node.getLeft().apply(this); - node.getRight().apply(this); - - BType found = getType(node.getLeft()); - BType expected = getType(node); - unify(expected, found, node); - } - - @Override - public void caseAImageExpression(AImageExpression node) { - BType expected = getType(node); - BType dom = new UntypedType(); - BType ran = new UntypedType(); - BType found = new SetType(ran); - BType left = new FunctionType(dom, ran); - BType right = new SetType(dom); - setType(node.getLeft(), left); - setType(node.getRight(), right); - unify(expected, found, node); - - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseAReverseExpression(AReverseExpression node) { - BType left = new UntypedType(); - BType right = new UntypedType(); - - BType found = new SetType(new PairType(left, right)); - - BType expr = new FunctionType(right, left); - setType(node.getExpression(), expr); - BType expected = getType(node); - - unify(expected, found, node); - node.getExpression().apply(this); - } - - @Override - public void caseAOverwriteExpression(AOverwriteExpression node) { - BType expected = getType(node); - BType found = new FunctionType(new UntypedType(), new UntypedType()); - setType(node.getLeft(), found); - setType(node.getRight(), found); - unify(expected, found, node); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseADirectProductExpression(ADirectProductExpression node) { - UntypedType u = new UntypedType(); - UntypedType u1 = new UntypedType(); - UntypedType u2 = new UntypedType(); - BType left = new SetType(new PairType(u, u1)); - BType right = new SetType(new PairType(u, u2)); - setType(node.getLeft(), left); - setType(node.getRight(), right); - - BType expected = getType(node); - BType found = new SetType(new PairType(u, new PairType(u1, u2))); - try { - expected.unify(found, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); - } - - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseAParallelProductExpression(AParallelProductExpression node) { - UntypedType t = new UntypedType(); - UntypedType u = new UntypedType(); - BType left = new SetType(new PairType(t, u)); - UntypedType v = new UntypedType(); - UntypedType w = new UntypedType(); - BType right = new SetType(new PairType(v, w)); - setType(node.getLeft(), left); - setType(node.getRight(), right); - BType found = new SetType(new PairType(new PairType(t, v), new PairType(u, w))); - BType expected = getType(node); - - unify(expected, found, node); - - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseACompositionExpression(ACompositionExpression node) { - UntypedType t = new UntypedType(); - UntypedType u = new UntypedType(); - UntypedType v = new UntypedType(); - BType left = new SetType(new PairType(t, u)); - BType right = new SetType(new PairType(u, v)); - setType(node.getLeft(), left); - setType(node.getRight(), right); - BType found = new SetType(new PairType(t, v)); - BType expected = getType(node); - - unify(expected, found, node); - - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseAFirstProjectionExpression(AFirstProjectionExpression node) { - UntypedType t = new UntypedType(); - UntypedType u = new UntypedType(); - BType left = new SetType(t); - BType right = new SetType(u); - BType found = new SetType(new PairType(new PairType(t, u), t)); - setType(node.getExp1(), left); - setType(node.getExp2(), right); - BType expected = getType(node); - - unify(expected, found, node); - - node.getExp1().apply(this); - node.getExp2().apply(this); - } - - @Override - public void caseASecondProjectionExpression(ASecondProjectionExpression node) { - UntypedType t = new UntypedType(); - UntypedType u = new UntypedType(); - BType left = new SetType(t); - BType right = new SetType(u); - BType found = new SetType(new PairType(new PairType(t, u), u)); - setType(node.getExp1(), left); - setType(node.getExp2(), right); - BType expected = getType(node); - - unify(expected, found, node); - - node.getExp1().apply(this); - node.getExp2().apply(this); - } - - @Override - public void caseAIterationExpression(AIterationExpression node) { - UntypedType t = new UntypedType(); - BType found = new SetType(new PairType(t, t)); - setType(node.getRight(), IntegerType.getInstance()); - setType(node.getLeft(), found); - BType expected = getType(node); - - unify(expected, found, node); - - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseAClosureExpression(AClosureExpression node) { - UntypedType t = new UntypedType(); - BType found = new SetType(new PairType(t, t)); - setType(node.getExpression(), found); - BType expected = getType(node); - unify(expected, found, node); - node.getExpression().apply(this); - } - - @Override - public void caseAReflexiveClosureExpression(AReflexiveClosureExpression node) { - UntypedType t = new UntypedType(); - BType found = new SetType(new PairType(t, t)); - setType(node.getExpression(), found); - BType expected = getType(node); - unify(expected, found, node); - node.getExpression().apply(this); - } - - @Override - public void caseATransFunctionExpression(ATransFunctionExpression node) { - UntypedType t = new UntypedType(); - UntypedType u = new UntypedType(); - setType(node.getExpression(), new SetType(new PairType(t, u))); - BType found = new SetType(new PairType(t, new SetType(u))); - BType expected = getType(node); - unify(expected, found, node); - node.getExpression().apply(this); - } - - @Override - public void caseATransRelationExpression(ATransRelationExpression node) { - UntypedType t = new UntypedType(); - UntypedType u = new UntypedType(); - setType(node.getExpression(), new SetType(new PairType(t, new SetType(u)))); - BType found = new SetType(new PairType(t, u)); - BType expected = getType(node); - unify(expected, found, node); - node.getExpression().apply(this); - } - - public void unify(BType expected, BType found, Node node) { - try { - expected.unify(found, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "' at " - + node.getClass().getSimpleName() + "\n " + node.getStartPos() + ":" + node.getEndPos()); - } - } - - @Override - public void caseAEmptySequenceExpression(AEmptySequenceExpression node) { - BType expected = getType(node); - BType found = new FunctionType(IntegerType.getInstance(), new UntypedType()); - try { - expected.unify(found, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); - } - } - - /** - * Sequences - */ - - @Override - public void caseASeqExpression(ASeqExpression node) { - UntypedType t = new UntypedType(); - setType(node.getExpression(), new SetType(t)); - BType found = new SetType(new FunctionType(IntegerType.getInstance(), t)); - BType expected = getType(node); - unify(expected, found, node); - node.getExpression().apply(this); - } - - @Override - public void caseASizeExpression(ASizeExpression node) { - setType(node.getExpression(), new FunctionType(IntegerType.getInstance(), new UntypedType())); - BType found = IntegerType.getInstance(); - BType expected = getType(node); - unify(expected, found, node); - node.getExpression().apply(this); - } - - @Override - public void caseAConcatExpression(AConcatExpression node) { - BType found = new FunctionType(IntegerType.getInstance(), new UntypedType()); - setType(node.getLeft(), found); - setType(node.getRight(), found); - BType expected = getType(node); - unify(expected, found, node); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseAInsertTailExpression(AInsertTailExpression node) { - UntypedType t = new UntypedType(); - BType found = new FunctionType(IntegerType.getInstance(), t); - setType(node.getLeft(), found); - setType(node.getRight(), t); - BType expected = getType(node); - unify(expected, found, node); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseAFirstExpression(AFirstExpression node) { - BType found = new UntypedType(); - setType(node.getExpression(), new FunctionType(IntegerType.getInstance(), found)); - BType expected = getType(node); - unify(expected, found, node); - node.getExpression().apply(this); - } - - @Override - public void caseATailExpression(ATailExpression node) { - BType found = new FunctionType(IntegerType.getInstance(), new UntypedType()); - setType(node.getExpression(), found); - BType expected = getType(node); - unify(expected, found, node); - node.getExpression().apply(this); - } - - /** - * Sequences Extended - */ - - private void evalSetOfSequences(Node node, Node expr) { - UntypedType t = new UntypedType(); - setType(expr, new SetType(t)); - BType found = new SetType(new FunctionType(IntegerType.getInstance(), t)); - BType expected = getType(node); - unify(expected, found, node); - expr.apply(this); - } - - @Override - public void caseAIseqExpression(AIseqExpression node) { - evalSetOfSequences(node, node.getExpression()); - } - - @Override - public void caseAIseq1Expression(AIseq1Expression node) { - evalSetOfSequences(node, node.getExpression()); - } - - @Override - public void caseASeq1Expression(ASeq1Expression node) { - evalSetOfSequences(node, node.getExpression()); - } - - @Override - public void caseAInsertFrontExpression(AInsertFrontExpression node) { - UntypedType t = new UntypedType(); - BType found = new FunctionType(IntegerType.getInstance(), t); - setType(node.getLeft(), t); - setType(node.getRight(), found); - BType expected = getType(node); - unify(expected, found, node); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseALastExpression(ALastExpression node) { - BType found = new UntypedType(); - setType(node.getExpression(), new FunctionType(IntegerType.getInstance(), found)); - BType expected = getType(node); - unify(expected, found, node); - node.getExpression().apply(this); - } - - @Override - public void caseAPermExpression(APermExpression node) { - evalSetOfSequences(node, node.getExpression()); - } - - @Override - public void caseARevExpression(ARevExpression node) { - BType found = new FunctionType(IntegerType.getInstance(), new UntypedType()); - setType(node.getExpression(), found); - BType expected = getType(node); - unify(expected, found, node); - node.getExpression().apply(this); - } - - @Override - public void caseAFrontExpression(AFrontExpression node) { - BType found = new FunctionType(IntegerType.getInstance(), new UntypedType()); - setType(node.getExpression(), found); - BType expected = getType(node); - unify(expected, found, node); - node.getExpression().apply(this); - } - - @Override - public void caseAGeneralConcatExpression(AGeneralConcatExpression node) { - - BType found = new FunctionType(IntegerType.getInstance(), new UntypedType()); - setType(node.getExpression(), new FunctionType(IntegerType.getInstance(), found)); - - // BType found = new SetType(new PairType(IntegerType.getInstance(), - // new UntypedType())); - // setType(node.getExpression(), - // new SetType(new PairType(IntegerType.getInstance(), found))); - - BType expected = getType(node); - unify(expected, found, node); - node.getExpression().apply(this); - } - - @Override - public void caseARestrictFrontExpression(ARestrictFrontExpression node) { - UntypedType t = new UntypedType(); - BType found = new FunctionType(IntegerType.getInstance(), t); - setType(node.getLeft(), found); - setType(node.getRight(), IntegerType.getInstance()); - BType expected = getType(node); - unify(expected, found, node); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseARestrictTailExpression(ARestrictTailExpression node) { - UntypedType t = new UntypedType(); - BType found = new FunctionType(IntegerType.getInstance(), t); - setType(node.getLeft(), found); - setType(node.getRight(), IntegerType.getInstance()); - BType expected = getType(node); - unify(expected, found, node); - node.getLeft().apply(this); - node.getRight().apply(this); - } - - @Override - public void caseASequenceExtensionExpression(ASequenceExtensionExpression node) { - BType expected = getType(node); - BType found = new FunctionType(IntegerType.getInstance(), new UntypedType()); - try { - found = found.unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); - } - BType subtype; - if (found instanceof FunctionType) { - subtype = ((FunctionType) found).getRange(); - } else { - PairType p = (PairType) ((SetType) found).getSubtype(); - subtype = p.getSecond(); - } - for (PExpression e : node.getExpression()) { - setType(e, subtype); - } - List<PExpression> copy = new ArrayList<PExpression>(node.getExpression()); - for (PExpression e : copy) { - e.apply(this); - } - } - - /** - * Records - */ - - @Override - public void caseARecExpression(ARecExpression node) { - StructType found = new StructType(); - found.setComplete(); - - List<PRecEntry> copy = new ArrayList<PRecEntry>(node.getEntries()); - for (PRecEntry e2 : copy) { - ARecEntry e = (ARecEntry) e2; - setType(e.getValue(), new UntypedType()); - e.getValue().apply(this); - - AIdentifierExpression i = (AIdentifierExpression) e.getIdentifier(); - String name = Utils.getTIdentifierListAsString(i.getIdentifier()); - found.add(name, getType(e.getValue())); - } - BType expected = getType(node); - try { - unify(expected, found, node); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); - } - } - - @Override - public void caseARecordFieldExpression(ARecordFieldExpression node) { - StructType s = new StructType(); - AIdentifierExpression i = (AIdentifierExpression) node.getIdentifier(); - String fieldName = Utils.getTIdentifierListAsString(i.getIdentifier()); - s.add(fieldName, new UntypedType()); - setType(node.getRecord(), s); - - node.getRecord().apply(this); - - BType found = ((StructType) getType(node.getRecord())).getType(fieldName); - BType expected = getType(node); - try { - unify(expected, found, node); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); - } - - } - - @Override - public void caseAStructExpression(AStructExpression node) { - StructType s = new StructType(); - s.setComplete(); - - List<PRecEntry> copy = new ArrayList<PRecEntry>(node.getEntries()); - for (PRecEntry e2 : copy) { - ARecEntry e = (ARecEntry) e2; - setType(e.getValue(), new SetType(new UntypedType())); - e.getValue().apply(this); - - AIdentifierExpression i = (AIdentifierExpression) e.getIdentifier(); - String name = Utils.getTIdentifierListAsString(i.getIdentifier()); - BType t = ((SetType) getType(e.getValue())).getSubtype(); - s.add(name, t); - } - BType found = new SetType(s); - - BType expected = getType(node); - try { - found.unify(expected, this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); - } - } - - /** - * Strings - */ - - @Override - public void caseAStringExpression(AStringExpression node) { - try { - StringType.getInstance().unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found " + StringType.getInstance() + "'"); - } - } - - @Override - public void caseAStringSetExpression(AStringSetExpression node) { - SetType found = new SetType(StringType.getInstance()); - try { - found.unify(getType(node), this); - } catch (UnificationException e) { - throw new TypeErrorException("Excepted '" + getType(node) + "' , found " + found + "'"); - } - } - - public void inALabelPredicate(ALabelPredicate node) { - BType type = getType(node); - setType(node.getPredicate(), type); - } - -} +package de.tlc4b.analysis; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.LinkedList; +import java.util.List; +import java.util.Map.Entry; + +import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; +import de.be4.classicalb.core.parser.node.*; +import de.be4.classicalb.core.parser.util.Utils; +import de.tlc4b.btypes.AbstractHasFollowers; +import de.tlc4b.btypes.BType; +import de.tlc4b.btypes.BoolType; +import de.tlc4b.btypes.FunctionType; +import de.tlc4b.btypes.ITypechecker; +import de.tlc4b.btypes.IntegerOrSetOfPairType; +import de.tlc4b.btypes.IntegerOrSetType; +import de.tlc4b.btypes.IntegerType; +import de.tlc4b.btypes.EnumeratedSetElement; +import de.tlc4b.btypes.PairType; +import de.tlc4b.btypes.SetType; +import de.tlc4b.btypes.StringType; +import de.tlc4b.btypes.StructType; +import de.tlc4b.btypes.UntypedType; +import de.tlc4b.exceptions.TypeErrorException; +import de.tlc4b.exceptions.UnificationException; +import de.tlc4b.ltl.LTLBPredicate; +import de.tlc4b.ltl.LTLFormulaVisitor; + +/** + * TODO we need a second run over the AST to check if all local variables have a + * type. This run should be performed after the normal model checking task. + */ +public class Typechecker extends DepthFirstAdapter implements ITypechecker { + + private final Hashtable<Node, BType> types; + private final Hashtable<Node, Node> referenceTable; + private final MachineContext machineContext; + + public Typechecker(MachineContext context) { + this.types = new Hashtable<Node, BType>(); + this.referenceTable = context.getReferences(); + this.machineContext = context; + + context.getStartNode().apply(this); + checkConstantsSetup(); + checkLTLFormulas(); + } + + private void checkLTLFormulas() { + ArrayList<LTLFormulaVisitor> visitors = machineContext.getLTLFormulas(); + for (int i = 0; i < visitors.size(); i++) { + LTLFormulaVisitor visitor = visitors.get(i); + Collection<AIdentifierExpression> parameter = visitor.getParameter(); + for (AIdentifierExpression param : parameter) { + setType(param, new UntypedType()); + } + for (int j = 0; j < visitor.getBPredicates().size(); j++) { + LTLBPredicate ltlBPredicate = visitor.getBPredicates().get(j); + ltlBPredicate.getBFormula().apply(this); + } + } + + } + + private void checkConstantsSetup() { + PPredicate p = machineContext.getConstantsSetup(); + if (p != null) { + setType(p, BoolType.getInstance()); + p.apply(this); + for (Entry<String, Node> entry : machineContext.getConstants().entrySet()) { + String c = entry.getKey(); + Node n = entry.getValue(); + if (getType(n).isUntyped()) { + throw new TypeErrorException("Can not infer type of constant '" + c + "': " + getType(n)); + } + } + } + } + + @Override + public void caseAPredicateParseUnit(APredicateParseUnit node) { + setType(node.getPredicate(), BoolType.getInstance()); + node.getPredicate().apply(this); + } + + public void setType(Node node, BType t) { + this.types.put(node, t); + if (t instanceof AbstractHasFollowers) { + ((AbstractHasFollowers) t).addFollower(node); + } + } + + public void updateType(Node node, AbstractHasFollowers oldType, BType newType) { + oldType.deleteFollower(node); + this.types.put(node, newType); + if (newType instanceof AbstractHasFollowers) { + ((AbstractHasFollowers) newType).addFollower(node); + } + } + + public BType getType(Node node) { + BType res = types.get(node); + if (res == null) { + new TypeErrorException("Node '" + node + "' has no type.\n" + node.getStartPos()); + } + return res; + } + + @Override + public void caseAAbstractMachineParseUnit(AAbstractMachineParseUnit node) { + if (node.getVariant() != null) { + node.getVariant().apply(this); + } + if (node.getHeader() != null) { + node.getHeader().apply(this); + } + { + List<PMachineClause> copy = new ArrayList<PMachineClause>(node.getMachineClauses()); + for (PMachineClause e : copy) { + e.apply(this); + } + } + } + + /** + * Declarations + */ + + @Override + public void caseAMachineHeader(AMachineHeader node) { + List<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); + for (PExpression e : copy) { + AIdentifierExpression p = (AIdentifierExpression) e; + String name = Utils.getTIdentifierListAsString(p.getIdentifier()); + + if (Character.isUpperCase(name.charAt(0))) { + + EnumeratedSetElement m = new EnumeratedSetElement(name); + setType(p, new SetType(m)); + } else { + UntypedType u = new UntypedType(); + setType(p, u); + } + } + } + + @Override + public void caseASetsMachineClause(ASetsMachineClause node) { + List<PSet> copy = new ArrayList<PSet>(node.getSetDefinitions()); + for (PSet e : copy) { + e.apply(this); + } + } + + @Override + public void caseAEnumeratedSetSet(AEnumeratedSetSet node) { + List<TIdentifierLiteral> copy = new ArrayList<TIdentifierLiteral>(node.getIdentifier()); + + String setName = Utils.getTIdentifierListAsString(copy); + SetType set = new SetType(new EnumeratedSetElement(setName)); + setType(node, set); + List<PExpression> copy2 = new ArrayList<PExpression>(node.getElements()); + for (PExpression e : copy2) { + setType(e, set.getSubtype()); + } + } + + @Override + public void caseADeferredSetSet(ADeferredSetSet node) { + List<TIdentifierLiteral> copy = new ArrayList<TIdentifierLiteral>(node.getIdentifier()); + String name = Utils.getTIdentifierListAsString(copy); + setType(node, new SetType(new EnumeratedSetElement(name))); + } + + @Override + public void caseAConstantsMachineClause(AConstantsMachineClause node) { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + AIdentifierExpression id = (AIdentifierExpression) e; + UntypedType u = new UntypedType(); + setType(id, u); + } + } + + @Override + public void caseAAbstractConstantsMachineClause(AAbstractConstantsMachineClause node) { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + AIdentifierExpression id = (AIdentifierExpression) e; + UntypedType u = new UntypedType(); + setType(id, u); + } + } + + @Override + public void caseAVariablesMachineClause(AVariablesMachineClause node) { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + AIdentifierExpression v = (AIdentifierExpression) e; + UntypedType u = new UntypedType(); + setType(v, u); + } + } + + @Override + public void caseAConcreteVariablesMachineClause(AConcreteVariablesMachineClause node) { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + AIdentifierExpression v = (AIdentifierExpression) e; + UntypedType u = new UntypedType(); + setType(v, u); + } + } + + /** + * Definitions + */ + + @Override + public void caseADefinitionsMachineClause(ADefinitionsMachineClause node) { + List<PDefinition> copy = new ArrayList<PDefinition>(node.getDefinitions()); + for (PDefinition e : copy) { + setType(e, new UntypedType()); + } + + for (PDefinition e : copy) { + e.apply(this); + } + } + + @Override + // d(a) == 1 + public void caseAExpressionDefinitionDefinition(AExpressionDefinitionDefinition node) { + List<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); + for (PExpression e : copy) { + UntypedType u = new UntypedType(); + setType(e, u); + } + setType(node.getRhs(), getType(node)); + node.getRhs().apply(this); + } + + @Override + // d(a) == 1 = 1 + public void caseAPredicateDefinitionDefinition(APredicateDefinitionDefinition node) { + setType(node, BoolType.getInstance()); + List<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); + for (PExpression e : copy) { + setType(e, new UntypedType()); + } + setType(node.getRhs(), BoolType.getInstance()); + node.getRhs().apply(this); + } + + @Override + public void caseADefinitionExpression(ADefinitionExpression node) { + BType expected = getType(node); + // String name = node.getDefLiteral().getText().toString(); + Node originalDef = referenceTable.get(node); + BType found = getType(originalDef); + + try { + found.unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Expected '" + expected + "', found '" + found + "' at definition call\n"); + } + LinkedList<PExpression> params = ((AExpressionDefinitionDefinition) originalDef).getParameters(); + List<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); + for (int i = 0; i < params.size(); i++) { + BType type = getType(params.get(i)); + setType(copy.get(i), type); + copy.get(i).apply(this); + } + } + + @Override + public void caseADefinitionPredicate(ADefinitionPredicate node) { + BType expected = getType(node); + Node originalDef = referenceTable.get(node); + BType found = BoolType.getInstance(); + + try { + found.unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Expected '" + expected + "', found '" + found + "' at definition call\n"); + } + LinkedList<PExpression> params = ((APredicateDefinitionDefinition) originalDef).getParameters(); + List<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); + for (int i = 0; i < params.size(); i++) { + setType(copy.get(i), getType(params.get(i))); + copy.get(i).apply(this); + } + } + + /** + * Properties + */ + + @Override + public void caseAConstraintsMachineClause(AConstraintsMachineClause node) { + if (node.getPredicates() != null) { + setType(node.getPredicates(), BoolType.getInstance()); + node.getPredicates().apply(this); + } + for (Entry<String, Node> entry : machineContext.getScalarParameter().entrySet()) { + String name = entry.getKey(); + Node n = entry.getValue(); + if (getType(n).isUntyped()) { + throw new TypeErrorException("Can not infer type of parameter '" + name + "'"); + } + } + } + + @Override + public void caseAPropertiesMachineClause(final APropertiesMachineClause node) { + if (node.getPredicates() != null) { + setType(node.getPredicates(), BoolType.getInstance()); + node.getPredicates().apply(this); + } + for (Entry<String, Node> entry : machineContext.getConstants().entrySet()) { + String c = entry.getKey(); + Node n = entry.getValue(); + if (getType(n).isUntyped()) { + throw new TypeErrorException("Can not infer type of constant '" + c + "': " + getType(n)); + } + } + } + + @Override + public void caseAInvariantMachineClause(AInvariantMachineClause node) { + setType(node.getPredicates(), BoolType.getInstance()); + node.getPredicates().apply(this); + for (Entry<String, Node> entry : machineContext.getVariables().entrySet()) { + String c = entry.getKey(); + Node n = entry.getValue(); + if (getType(n).isUntyped()) { + throw new TypeErrorException("Can not infer type of variable '" + c + "'"); + } + } + } + + @Override + public void caseAAssertionsMachineClause(AAssertionsMachineClause node) { + List<PPredicate> copy = new ArrayList<PPredicate>(node.getPredicates()); + for (PPredicate e : copy) { + setType(e, BoolType.getInstance()); + e.apply(this); + } + } + + @Override + public void caseAInitialisationMachineClause(AInitialisationMachineClause node) { + if (node.getSubstitutions() != null) { + node.getSubstitutions().apply(this); + } + } + + @Override + public void caseAOperation(AOperation node) { + { + List<PExpression> copy = new ArrayList<PExpression>(node.getReturnValues()); + for (PExpression e : copy) { + AIdentifierExpression id = (AIdentifierExpression) e; + UntypedType u = new UntypedType(); + setType(id, u); + } + + } + { + List<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); + for (PExpression e : copy) { + AIdentifierExpression id = (AIdentifierExpression) e; + UntypedType u = new UntypedType(); + setType(id, u); + } + } + if (node.getOperationBody() != null) { + node.getOperationBody().apply(this); + } + } + + /** + * Expressions + */ + + @Override + public void caseAIdentifierExpression(AIdentifierExpression node) { + + BType expected = getType(node); + + if (expected == null) { + System.out.println("Not implemented in Typechecker:" + node.parent().getClass()); + throw new RuntimeException(node + " Pos: " + node.getStartPos()); + } + Node identifierDeclarationNode = referenceTable.get(node); + BType found = getType(identifierDeclarationNode); + + String name = Utils.getTIdentifierListAsString(node.getIdentifier()); + try { + expected.unify(found, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found '" + found + "' at identifier " + name + + "\n" + node.getStartPos()); + } + } + + @Override + public void caseAEqualPredicate(AEqualPredicate node) { + try { + BoolType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Expected '" + getType(node) + "', found BOOL at '=' \n" + node.getStartPos()); + } + + UntypedType x = new UntypedType(); + setType(node.getLeft(), x); + setType(node.getRight(), x); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseAIfThenElseExpression(AIfThenElseExpression node) { + setType(node.getCondition(), BoolType.getInstance()); + node.getCondition().apply(this); + + UntypedType x = new UntypedType(); + setType(node.getThen(), x); + setType(node.getElse(), x); + node.getThen().apply(this); + node.getElse().apply(this); + BType found = getType(node.getThen()); + unify(getType(node), found, node); + } + + @Override + public void caseANotEqualPredicate(ANotEqualPredicate node) { + try { + BoolType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Expected '" + getType(node) + "', found BOOL at '=' \n" + node.getClass()); + } + + UntypedType x = new UntypedType(); + setType(node.getLeft(), x); + setType(node.getRight(), x); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseAForallPredicate(AForallPredicate node) { + try { + BoolType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Expected '" + getType(node) + "', found BOOL at 'For All' \n"); + } + + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + AIdentifierExpression v = (AIdentifierExpression) e; + setType(v, new UntypedType()); + } + + setType(node.getImplication(), BoolType.getInstance()); + node.getImplication().apply(this); + } + + @Override + public void caseAExistsPredicate(AExistsPredicate node) { + try { + BoolType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Expected '" + getType(node) + "', found BOOL at 'Exists' \n"); + } + + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + AIdentifierExpression v = (AIdentifierExpression) e; + setType(v, new UntypedType()); + } + + setType(node.getPredicate(), BoolType.getInstance()); + node.getPredicate().apply(this); + } + + /** + * Substitutions + * + */ + + @Override + public void caseAPreconditionSubstitution(APreconditionSubstitution node) { + setType(node.getPredicate(), BoolType.getInstance()); + node.getPredicate().apply(this); + node.getSubstitution().apply(this); + } + + @Override + public void caseAAssertionSubstitution(AAssertionSubstitution node) { + setType(node.getPredicate(), BoolType.getInstance()); + node.getPredicate().apply(this); + node.getSubstitution().apply(this); + } + + @Override + public void caseASelectSubstitution(ASelectSubstitution node) { + setType(node.getCondition(), BoolType.getInstance()); + node.getCondition().apply(this); + node.getThen().apply(this); + List<PSubstitution> copy = new ArrayList<PSubstitution>(node.getWhenSubstitutions()); + for (PSubstitution e : copy) { + e.apply(this); + } + if (node.getElse() != null) { + node.getElse().apply(this); + } + } + + @Override + public void caseASelectWhenSubstitution(ASelectWhenSubstitution node) { + setType(node.getCondition(), BoolType.getInstance()); + node.getCondition().apply(this); + node.getSubstitution().apply(this); + } + + @Override + public void caseAIfSubstitution(AIfSubstitution node) { + setType(node.getCondition(), BoolType.getInstance()); + node.getCondition().apply(this); + node.getThen().apply(this); + List<PSubstitution> copy = new ArrayList<PSubstitution>(node.getElsifSubstitutions()); + for (PSubstitution e : copy) { + e.apply(this); + } + if (node.getElse() != null) { + node.getElse().apply(this); + } + } + + @Override + public void caseAIfElsifSubstitution(AIfElsifSubstitution node) { + setType(node.getCondition(), BoolType.getInstance()); + node.getCondition().apply(this); + node.getThenSubstitution().apply(this); + } + + @Override + public void caseAAssignSubstitution(AAssignSubstitution node) { + List<PExpression> copy = new ArrayList<PExpression>(node.getLhsExpression()); + List<PExpression> copy2 = new ArrayList<PExpression>(node.getRhsExpressions()); + + for (int i = 0; i < copy.size(); i++) { + PExpression left = copy.get(i); + PExpression right = copy2.get(i); + + UntypedType x = new UntypedType(); + setType(left, x); + setType(right, x); + + left.apply(this); + right.apply(this); + } + + } + + @Override + public void caseABecomesSuchSubstitution(ABecomesSuchSubstitution node) { + setType(node.getPredicate(), BoolType.getInstance()); + node.getPredicate().apply(this); + } + + @Override + public void caseABecomesElementOfSubstitution(ABecomesElementOfSubstitution node) { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + SetType set = new SetType(new UntypedType()); + + setType(node.getSet(), set); + for (PExpression e : copy) { + setType(e, set.getSubtype()); + } + for (PExpression e : copy) { + e.apply(this); + } + node.getSet().apply(this); + } + + @Override + public void caseAAnySubstitution(AAnySubstitution node) { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + AIdentifierExpression v = (AIdentifierExpression) e; + setType(v, new UntypedType()); + } + setType(node.getWhere(), BoolType.getInstance()); + node.getWhere().apply(this); + node.getThen().apply(this); + } + + @Override + public void caseALetSubstitution(ALetSubstitution node) { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + AIdentifierExpression v = (AIdentifierExpression) e; + setType(v, new UntypedType()); + } + setType(node.getPredicate(), BoolType.getInstance()); + node.getPredicate().apply(this); + node.getSubstitution().apply(this); + } + + /**************************************************************************** + * Arithmetic operators * + ****************************************************************************/ + + @Override + public void caseAIntegerExpression(AIntegerExpression node) { + try { + IntegerType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException( + "Excepted '" + getType(node) + "' , found 'INTEGER' in '" + node.getLiteral().getText() + "'"); + } + } + + @Override + public void caseAIntegerSetExpression(AIntegerSetExpression node) { + try { + SetType found = new SetType(IntegerType.getInstance()); + found.unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'POW(INTEGER)' in 'INTEGER'"); + } + } + + @Override + public void caseANaturalSetExpression(ANaturalSetExpression node) { + try { + SetType found = new SetType(IntegerType.getInstance()); + found.unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'POW(INTEGER)' in 'NATURAL'"); + } + } + + @Override + public void caseANatural1SetExpression(ANatural1SetExpression node) { + try { + SetType found = new SetType(IntegerType.getInstance()); + found.unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'POW(INTEGER)' in 'NATURAL1'"); + } + } + + @Override + public void caseAIntSetExpression(AIntSetExpression node) { + try { + SetType found = new SetType(IntegerType.getInstance()); + found.unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'POW(INTEGER)' in 'INT'"); + } + } + + @Override + public void caseANatSetExpression(ANatSetExpression node) { + try { + SetType found = new SetType(IntegerType.getInstance()); + found.unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'POW(INTEGER)' in 'NAT'"); + } + } + + @Override + public void caseANat1SetExpression(ANat1SetExpression node) { + try { + SetType found = new SetType(IntegerType.getInstance()); + found.unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'POW(INTEGER)' in 'NAT1'"); + } + } + + @Override + public void caseAUnaryMinusExpression(AUnaryMinusExpression node) { + try { + IntegerType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'INTEGER' in '-'"); + } + } + + @Override + public void caseAIntervalExpression(AIntervalExpression node) { + try { + SetType found = new SetType(IntegerType.getInstance()); + found.unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException( + "Excepted '" + getType(node) + "' , found 'POW(INTEGER)' at interval operator"); + } + + setType(node.getLeftBorder(), IntegerType.getInstance()); + setType(node.getRightBorder(), IntegerType.getInstance()); + node.getLeftBorder().apply(this); + node.getRightBorder().apply(this); + } + + @Override + public void caseAMaxIntExpression(AMaxIntExpression node) { + unify(getType(node), IntegerType.getInstance(), node); + } + + @Override + public void caseAMinIntExpression(AMinIntExpression node) { + unify(getType(node), IntegerType.getInstance(), node); + } + + @Override + public void caseAGreaterPredicate(AGreaterPredicate node) { + try { + BoolType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in ' > '"); + } + setType(node.getLeft(), IntegerType.getInstance()); + setType(node.getRight(), IntegerType.getInstance()); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseALessPredicate(ALessPredicate node) { + try { + BoolType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in ' < '"); + } + setType(node.getLeft(), IntegerType.getInstance()); + setType(node.getRight(), IntegerType.getInstance()); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseAGreaterEqualPredicate(AGreaterEqualPredicate node) { + try { + BoolType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in ' >= '"); + } + setType(node.getLeft(), IntegerType.getInstance()); + setType(node.getRight(), IntegerType.getInstance()); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseALessEqualPredicate(ALessEqualPredicate node) { + try { + BoolType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in ' <= '"); + } + setType(node.getLeft(), IntegerType.getInstance()); + setType(node.getRight(), IntegerType.getInstance()); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseAMinExpression(AMinExpression node) { + try { + IntegerType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'INTEGER' in ' min '"); + } + setType(node.getExpression(), new SetType(IntegerType.getInstance())); + node.getExpression().apply(this); + } + + @Override + public void caseAMaxExpression(AMaxExpression node) { + try { + IntegerType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'INTEGER' in ' min '"); + } + setType(node.getExpression(), new SetType(IntegerType.getInstance())); + node.getExpression().apply(this); + } + + @Override + public void caseAAddExpression(AAddExpression node) { + try { + IntegerType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'INTEGER' in ' + '"); + } + setType(node.getLeft(), IntegerType.getInstance()); + setType(node.getRight(), IntegerType.getInstance()); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseAMinusOrSetSubtractExpression(AMinusOrSetSubtractExpression node) { + BType expected = getType(node); + + BType found = new IntegerOrSetType(); + unify(expected, found, node); + + setType(node.getLeft(), getType(node)); + setType(node.getRight(), getType(node)); + + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseAMultOrCartExpression(AMultOrCartExpression node) { + BType expected = getType(node); + IntegerOrSetOfPairType found = new IntegerOrSetOfPairType(node.getStartPos(), node.getEndPos()); + // setType(node.getLeft(), found.getFirst()); + // setType(node.getRight(), found.getSecond()); + BType result = null; + try { + result = expected.unify(found, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "' at " + + node.getClass().getSimpleName() + "\n " + node.getStartPos()); + } + // + // BType res2 = getType(node); + // if(res2 != result){ + // AbstractHasFollowers a = (AbstractHasFollowers) res2; + // throw new RuntimeException(); + // } + // + + if (result instanceof IntegerOrSetOfPairType) { + setType(node.getLeft(), ((IntegerOrSetOfPairType) result).getFirst()); + setType(node.getRight(), ((IntegerOrSetOfPairType) result).getSecond()); + } else if (result instanceof IntegerType) { + setType(node.getLeft(), result); + setType(node.getRight(), result); + } else if (result instanceof SetType) { + PairType pair = (PairType) ((SetType) result).getSubtype(); + setType(node.getLeft(), new SetType(pair.getFirst())); + setType(node.getRight(), new SetType(pair.getSecond())); + } else { + System.out.println(result); + throw new RuntimeException(); + } + + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseADivExpression(ADivExpression node) { + try { + IntegerType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'INTEGER' in ' / '"); + } + setType(node.getLeft(), IntegerType.getInstance()); + setType(node.getRight(), IntegerType.getInstance()); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseAPowerOfExpression(APowerOfExpression node) { + try { + IntegerType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'INTEGER' in ' ** '"); + } + setType(node.getLeft(), IntegerType.getInstance()); + setType(node.getRight(), IntegerType.getInstance()); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseAModuloExpression(AModuloExpression node) { + try { + IntegerType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'INTEGER' in ' mod '"); + } + setType(node.getLeft(), IntegerType.getInstance()); + setType(node.getRight(), IntegerType.getInstance()); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseASuccessorExpression(ASuccessorExpression node) { + FunctionType found = new FunctionType(IntegerType.getInstance(), IntegerType.getInstance()); + unify(getType(node), found, node); + } + + @Override + public void caseAPredecessorExpression(APredecessorExpression node) { + FunctionType found = new FunctionType(IntegerType.getInstance(), IntegerType.getInstance()); + unify(getType(node), found, node); + } + + @Override + public void caseAGeneralSumExpression(AGeneralSumExpression node) { + BType expected = getType(node); + try { + IntegerType.getInstance().unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found '" + "INTEGER" + "'"); + } + + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + AIdentifierExpression v = (AIdentifierExpression) e; + setType(v, new UntypedType()); + } + + setType(node.getPredicates(), BoolType.getInstance()); + node.getPredicates().apply(this); + + setType(node.getExpression(), IntegerType.getInstance()); + node.getExpression().apply(this); + } + + @Override + public void caseAGeneralProductExpression(AGeneralProductExpression node) { + BType expected = getType(node); + try { + IntegerType.getInstance().unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found '" + "INTEGER" + "'"); + } + + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + AIdentifierExpression v = (AIdentifierExpression) e; + setType(v, new UntypedType()); + } + + setType(node.getPredicates(), BoolType.getInstance()); + node.getPredicates().apply(this); + + setType(node.getExpression(), IntegerType.getInstance()); + node.getExpression().apply(this); + } + + /** + * Booleans + */ + + @Override + public void caseABooleanTrueExpression(ABooleanTrueExpression node) { + try { + BoolType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in 'TRUE'"); + } + } + + @Override + public void caseABooleanFalseExpression(ABooleanFalseExpression node) { + try { + BoolType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in 'FALSE'"); + } + } + + @Override + public void caseABoolSetExpression(ABoolSetExpression node) { + try { + SetType found = new SetType(BoolType.getInstance()); + found.unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'POW(BOOL)' in 'BOOL'"); + } + } + + @Override + public void caseAConvertBoolExpression(AConvertBoolExpression node) { + try { + BoolType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in 'bool(...)'"); + } + setType(node.getPredicate(), BoolType.getInstance()); + node.getPredicate().apply(this); + } + + /** + * Logical Operator + */ + + @Override + public void caseAConjunctPredicate(AConjunctPredicate node) { + try { + BoolType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException( + "Excepted '" + getType(node) + "' , found 'BOOL' in ' & '." + node.getStartPos()); + } + setType(node.getLeft(), BoolType.getInstance()); + setType(node.getRight(), BoolType.getInstance()); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseADisjunctPredicate(ADisjunctPredicate node) { + try { + BoolType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in ' or '"); + } + setType(node.getLeft(), BoolType.getInstance()); + setType(node.getRight(), BoolType.getInstance()); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseAImplicationPredicate(AImplicationPredicate node) { + try { + BoolType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in ' => '"); + } + setType(node.getLeft(), BoolType.getInstance()); + setType(node.getRight(), BoolType.getInstance()); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseAEquivalencePredicate(AEquivalencePredicate node) { + try { + BoolType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + System.out.println(node.parent().getClass()); + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in ' <=> '"); + } + setType(node.getLeft(), BoolType.getInstance()); + setType(node.getRight(), BoolType.getInstance()); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseANegationPredicate(ANegationPredicate node) { + try { + BoolType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found 'BOOL' in ' not '"); + } + setType(node.getPredicate(), BoolType.getInstance()); + node.getPredicate().apply(this); + } + + /** + * Sets + */ + + @Override + public void caseAEmptySetExpression(AEmptySetExpression node) { + BType expected = getType(node); + if (expected instanceof FunctionType) { + return; + } else { + unify(expected, new SetType(new UntypedType()), node); + } + } + + @Override + public void caseASetExtensionExpression(ASetExtensionExpression node) { + if (functionTest(node)) + return; + UntypedType u = new UntypedType(); + for (PExpression e : node.getExpressions()) { + setType(e, u); + } + BType expected = getType(node); + List<PExpression> copy = new ArrayList<PExpression>(node.getExpressions()); + for (PExpression e : copy) { + e.apply(this); + } + BType found = new SetType(getType(copy.get(0))); + unify(expected, found, node); + } + + private boolean functionTest(ASetExtensionExpression node) { + ArrayList<Node> list1 = new ArrayList<Node>(); + ArrayList<Node> list2 = new ArrayList<Node>(); + try { + for (PExpression e : node.getExpressions()) { + ACoupleExpression couple = (ACoupleExpression) e; + Node left = couple.getList().get(0); + Node right = couple.getList().get(1); + list1.add(left); + list2.add(right); + if (couple.getList().size() > 2) + return false; + } + if (compareElementsOfList(list1)) { + UntypedType leftType = new UntypedType(); + UntypedType rightType = new UntypedType(); + for (int i = 0; i < list1.size(); i++) { + setType(list1.get(i), leftType); + setType(list2.get(i), rightType); + } + for (int i = 0; i < list1.size(); i++) { + list1.get(i).apply(this); + list2.get(i).apply(this); + } + BType res1 = getType(list1.get(0)); + BType res2 = getType(list2.get(0)); + FunctionType func = new FunctionType(res1, res2); + BType expected = getType(node); + unify(expected, func, node); + return true; + } + + } catch (ClassCastException e) { + return false; + } + return false; + } + + private boolean compareElementsOfList(ArrayList<Node> list) { + if (list.size() == 1) { + return true; + } + try { + if (list.get(0) instanceof AIntegerExpression) { + HashSet<Integer> set = new HashSet<Integer>(); + for (int i = 0; i < list.size(); i++) { + AIntegerExpression aInt = (AIntegerExpression) list.get(i); + int integer = Integer.parseInt(aInt.getLiteral().getText()); + set.add(integer); + } + if (list.size() == set.size()) { + return true; + } + } else if (list.get(0) instanceof AIdentifierExpression) { + HashSet<Node> set = new HashSet<Node>(); + for (int i = 0; i < list.size(); i++) { + AIdentifierExpression id = (AIdentifierExpression) list.get(i); + Node enumValue = machineContext.getReferences().get(id); + if (!machineContext.getEnumValues().containsValue(enumValue)) { + return false; + } + set.add(enumValue); + } + if (list.size() == set.size()) { + return true; + } + + } + } catch (ClassCastException e) { + } + return false; + } + + @Override + public void caseAComprehensionSetExpression(AComprehensionSetExpression node) { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + ArrayList<BType> typesList = new ArrayList<BType>(); + for (PExpression e : copy) { + AIdentifierExpression v = (AIdentifierExpression) e; + UntypedType u = new UntypedType(); + typesList.add(u); + setType(v, u); + } + BType listType = makePair(typesList); + SetType found = new SetType(listType); + + try { + found.unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found " + found + "'"); + } + + setType(node.getPredicates(), BoolType.getInstance()); + node.getPredicates().apply(this); + + } + + @Override + public void caseAEventBComprehensionSetExpression(AEventBComprehensionSetExpression node) { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + AIdentifierExpression v = (AIdentifierExpression) e; + setType(v, new UntypedType()); + } + + setType(node.getPredicates(), BoolType.getInstance()); + node.getPredicates().apply(this); + + setType(node.getExpression(), new UntypedType()); + node.getExpression().apply(this); + + BType found = new SetType(getType(node.getExpression())); + + BType expected = getType(node); + unify(expected, found, node); + } + + public static BType makePair(ArrayList<BType> list) { + if (list.size() == 1) + return list.get(0); + PairType p = new PairType(list.get(0), null); + for (int i = 1; i < list.size(); i++) { + p.setSecond(list.get(i)); + if (i < list.size() - 1) { + p = new PairType(p, null); + } + } + return p; + } + + // POW, POW1, FIN, FIN1 + private void subset(Node node, Node expr) { + SetType found = new SetType(new SetType(new UntypedType())); + BType expected = getType(node); + try { + found = found.unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found 'POW(POW(_A))' in 'POW'"); + } + + setType(expr, found.getSubtype()); + expr.apply(this); + } + + @Override + public void caseAPowSubsetExpression(APowSubsetExpression node) { + subset(node, node.getExpression()); + } + + @Override + public void caseAPow1SubsetExpression(APow1SubsetExpression node) { + subset(node, node.getExpression()); + } + + @Override + public void caseAFinSubsetExpression(AFinSubsetExpression node) { + subset(node, node.getExpression()); + } + + @Override + public void caseAFin1SubsetExpression(AFin1SubsetExpression node) { + subset(node, node.getExpression()); + } + + // union, intersection, substraction, + private void setSetSet(Node node, Node left, Node right) { + SetType found = new SetType(new UntypedType()); + BType expected = getType(node); + try { + found = found.unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); + } + setType(left, found); + setType(right, found); + left.apply(this); + right.apply(this); + } + + @Override + public void caseAUnionExpression(AUnionExpression node) { + setSetSet(node, node.getLeft(), node.getRight()); + } + + @Override + public void caseAIntersectionExpression(AIntersectionExpression node) { + setSetSet(node, node.getLeft(), node.getRight()); + } + + @Override + public void caseASetSubtractionExpression(ASetSubtractionExpression node) { + setSetSet(node, node.getLeft(), node.getRight()); + } + + @Override + public void caseACardExpression(ACardExpression node) { + BType found = IntegerType.getInstance(); + BType expected = getType(node); + + try { + found.unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); + } + + setType(node.getExpression(), new UntypedType()); + node.getExpression().apply(this); + BType type = getType(node.getExpression()); + if (!(type instanceof FunctionType)) { + new SetType(new UntypedType()).unify(type, this); + } + } + + @Override + public void caseAMemberPredicate(AMemberPredicate node) { + SetType set = new SetType(new UntypedType()); + + setType(node.getLeft(), set.getSubtype()); + setType(node.getRight(), set); + + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseANotMemberPredicate(ANotMemberPredicate node) { + SetType set = new SetType(new UntypedType()); + + setType(node.getLeft(), set.getSubtype()); + setType(node.getRight(), set); + + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseASubsetPredicate(ASubsetPredicate node) { + BType expected = getType(node); + try { + BoolType.getInstance().unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found 'BOOL'"); + } + SetType set = new SetType(new UntypedType()); + + setType(node.getLeft(), set); + setType(node.getRight(), set); + + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseASubsetStrictPredicate(ASubsetStrictPredicate node) { + BType expected = getType(node); + try { + BoolType.getInstance().unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found 'BOOL'"); + } + + SetType set = new SetType(new UntypedType()); + + setType(node.getLeft(), set); + setType(node.getRight(), set); + + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseANotSubsetPredicate(ANotSubsetPredicate node) { + BType expected = getType(node); + try { + BoolType.getInstance().unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found 'BOOL'"); + } + + SetType set = new SetType(new UntypedType()); + + setType(node.getLeft(), set); + setType(node.getRight(), set); + + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseANotSubsetStrictPredicate(ANotSubsetStrictPredicate node) { + BType expected = getType(node); + try { + BoolType.getInstance().unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found 'BOOL'"); + } + + SetType set = new SetType(new UntypedType()); + + setType(node.getLeft(), set); + setType(node.getRight(), set); + + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseAGeneralUnionExpression(AGeneralUnionExpression node) { + SetType set = new SetType(new SetType(new UntypedType())); + setType(node.getExpression(), set); + node.getExpression().apply(this); + + BType found = ((SetType) getType(node.getExpression())).getSubtype(); + BType expected = getType(node); + try { + found.unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found '" + found + "'"); + } + } + + @Override + public void caseAGeneralIntersectionExpression(AGeneralIntersectionExpression node) { + SetType set = new SetType(new SetType(new UntypedType())); + setType(node.getExpression(), set); + node.getExpression().apply(this); + + BType found = ((SetType) getType(node.getExpression())).getSubtype(); + BType expected = getType(node); + try { + found.unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found '" + found + "'"); + } + } + + @Override + public void caseAQuantifiedUnionExpression(AQuantifiedUnionExpression node) { + BType expected = getType(node); + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + AIdentifierExpression v = (AIdentifierExpression) e; + UntypedType u = new UntypedType(); + setType(v, u); + } + + setType(node.getPredicates(), BoolType.getInstance()); + node.getPredicates().apply(this); + setType(node.getExpression(), new SetType(new UntypedType())); + node.getExpression().apply(this); + + BType found = getType(node.getExpression()); + try { + found.unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); + } + } + + @Override + public void caseAQuantifiedIntersectionExpression(AQuantifiedIntersectionExpression node) { + BType expected = getType(node); + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + AIdentifierExpression v = (AIdentifierExpression) e; + UntypedType u = new UntypedType(); + setType(v, u); + } + + setType(node.getPredicates(), BoolType.getInstance()); + node.getPredicates().apply(this); + setType(node.getExpression(), new SetType(new UntypedType())); + node.getExpression().apply(this); + + BType found = getType(node.getExpression()); + try { + found.unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); + } + } + + /** + * Functions + */ + + @Override + public void caseALambdaExpression(ALambdaExpression node) { + List<PExpression> copy = new ArrayList<PExpression>(node.getIdentifiers()); + for (PExpression e : copy) { + AIdentifierExpression v = (AIdentifierExpression) e; + setType(v, new UntypedType()); + } + + setType(node.getPredicate(), BoolType.getInstance()); + node.getPredicate().apply(this); + + setType(node.getExpression(), new UntypedType()); + node.getExpression().apply(this); + + ArrayList<BType> typesList = new ArrayList<BType>(); + for (PExpression e : copy) { + typesList.add(getType(e)); + } + BType domain = makePair(typesList); + BType range = getType(node.getExpression()); + + BType found = new FunctionType(domain, range); + // BType found = new SetType(new PairType(domain, range)); + + BType expected = getType(node); + try { + found.unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); + } + } + + @Override + public void caseAFunctionExpression(AFunctionExpression node) { + FunctionType func = new FunctionType(new UntypedType(), new UntypedType()); + setType(node.getIdentifier(), func); + node.getIdentifier().apply(this); + + BType id = getType(node.getIdentifier()); + BType domainFound; + BType rangeFound; + if (id instanceof FunctionType) { + domainFound = ((FunctionType) id).getDomain(); + rangeFound = ((FunctionType) id).getRange(); + } else { + PairType p = (PairType) ((SetType) id).getSubtype(); + domainFound = p.getFirst(); + rangeFound = p.getSecond(); + } + BType expected = getType(node); + try { + rangeFound.unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found " + rangeFound + "'"); + } + + ArrayList<PExpression> copy = new ArrayList<PExpression>(node.getParameters()); + for (PExpression e : copy) { + setType(e, new UntypedType()); + e.apply(this); + } + + ArrayList<BType> foundList = new ArrayList<BType>(); + for (PExpression e : copy) { + foundList.add(getType(e)); + } + + BType p = makePair(foundList); + try { + domainFound.unify(p, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + domainFound + "' , found '" + makePair(foundList) + "'"); + } + } + + @Override + public void caseADomainExpression(ADomainExpression node) { + FunctionType f = new FunctionType(new UntypedType(), new UntypedType()); + setType(node.getExpression(), f); + node.getExpression().apply(this); + + BType b = getType(node.getExpression()); + BType domainFound; + if (b instanceof FunctionType) { + domainFound = new SetType(((FunctionType) b).getDomain()); + } else { + PairType p = (PairType) ((SetType) b).getSubtype(); + domainFound = new SetType(p.getFirst()); + } + BType expected = getType(node); + try { + domainFound.unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found '" + domainFound + "'"); + } + } + + @Override + public void caseARangeExpression(ARangeExpression node) { + FunctionType f = new FunctionType(new UntypedType(), new UntypedType()); + setType(node.getExpression(), f); + node.getExpression().apply(this); + + BType b = getType(node.getExpression()); + BType rangeFound; + if (b instanceof FunctionType) { + rangeFound = new SetType(((FunctionType) b).getRange()); + } else { + PairType p = (PairType) ((SetType) b).getSubtype(); + rangeFound = new SetType(p.getSecond()); + } + BType expected = getType(node); + try { + rangeFound.unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found '" + rangeFound + "'"); + } + } + + @Override + public void caseATotalFunctionExpression(ATotalFunctionExpression node) { + evalFunction(node, node.getLeft(), node.getRight()); + } + + @Override + public void caseAPartialFunctionExpression(APartialFunctionExpression node) { + BType dom = new UntypedType(); + BType ran = new UntypedType(); + setType(node.getLeft(), new SetType(dom)); + setType(node.getRight(), new SetType(ran)); + BType expected = getType(node); + BType found = evalFunctionTypeVsRelationType(node, dom, ran); + unify(expected, found, node); + node.getLeft().apply(this); + node.getRight().apply(this); + // evalFunction(node, node.getLeft(), node.getRight()); + } + + private BType evalFunctionTypeVsRelationType(Node node, BType dom, BType ran) { + String clazz = node.parent().getClass().getName(); + if (clazz.contains("Total") || clazz.contains("Partial")) + return new SetType(new SetType(new PairType(dom, ran))); + else + return new SetType(new FunctionType(dom, ran)); + } + + @Override + public void caseATotalInjectionExpression(ATotalInjectionExpression node) { + evalFunction(node, node.getLeft(), node.getRight()); + } + + @Override + public void caseAPartialInjectionExpression(APartialInjectionExpression node) { + BType dom = new UntypedType(); + BType ran = new UntypedType(); + setType(node.getLeft(), new SetType(dom)); + setType(node.getRight(), new SetType(ran)); + BType expected = getType(node); + BType found = evalFunctionTypeVsRelationType(node, dom, ran); + unify(expected, found, node); + node.getLeft().apply(this); + node.getRight().apply(this); + // evalFunction(node, node.getLeft(), node.getRight()); + } + + @Override + public void caseATotalSurjectionExpression(ATotalSurjectionExpression node) { + evalFunction(node, node.getLeft(), node.getRight()); + } + + @Override + public void caseAPartialSurjectionExpression(APartialSurjectionExpression node) { + // evalFunction(node, node.getLeft(), node.getRight()); + BType dom = new UntypedType(); + BType ran = new UntypedType(); + setType(node.getLeft(), new SetType(dom)); + setType(node.getRight(), new SetType(ran)); + BType expected = getType(node); + BType found = evalFunctionTypeVsRelationType(node, dom, ran); + unify(expected, found, node); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseATotalBijectionExpression(ATotalBijectionExpression node) { + evalFunction(node, node.getLeft(), node.getRight()); + } + + @Override + public void caseAPartialBijectionExpression(APartialBijectionExpression node) { + // evalFunction(node, node.getLeft(), node.getRight()); + BType dom = new UntypedType(); + BType ran = new UntypedType(); + setType(node.getLeft(), new SetType(dom)); + setType(node.getRight(), new SetType(ran)); + BType expected = getType(node); + BType found = evalFunctionTypeVsRelationType(node, dom, ran); + unify(expected, found, node); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + public void evalFunction(Node node, Node left, Node right) { + setType(left, new SetType(new UntypedType())); + left.apply(this); + setType(right, new SetType(new UntypedType())); + right.apply(this); + + BType leftType = ((SetType) getType(left)).getSubtype(); + BType rightType = ((SetType) getType(right)).getSubtype(); + + BType found = new SetType(new FunctionType(leftType, rightType)); + BType expected = getType(node); + try { + expected.unify(found, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); + } + } + + /** + * Relations + */ + + @Override + public void caseACoupleExpression(ACoupleExpression node) { + BType expected = getType(node); + + List<PExpression> copy = new ArrayList<PExpression>(node.getList()); + + ArrayList<BType> list = new ArrayList<BType>(); + + for (PExpression e : copy) { + setType(e, new UntypedType()); + e.apply(this); + } + + for (PExpression e : copy) { + list.add(getType(e)); + } + + BType found = makePair(list); + try { + found.unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); + } + } + + @Override + public void caseARelationsExpression(ARelationsExpression node) { + setType(node.getLeft(), new SetType(new UntypedType())); + node.getLeft().apply(this); + setType(node.getRight(), new SetType(new UntypedType())); + node.getRight().apply(this); + + BType left = ((SetType) getType(node.getLeft())).getSubtype(); + BType right = ((SetType) getType(node.getRight())).getSubtype(); + + BType found = new SetType(new SetType(new PairType(left, right))); + BType expected = getType(node); + try { + expected.unify(found, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); + } + } + + @Override + public void caseAIdentityExpression(AIdentityExpression node) { + SetType s = new SetType(new UntypedType()); + setType(node.getExpression(), s); + node.getExpression().apply(this); + + s = (SetType) getType(node.getExpression()); + + // BType found = new SetType(new PairType(s.getSubtype(), + // s.getSubtype())); + BType found = new FunctionType(s.getSubtype(), s.getSubtype()); + BType expected = getType(node); + + unify(expected, found, node); + } + + @Override + public void caseADomainRestrictionExpression(ADomainRestrictionExpression node) { + UntypedType u = new UntypedType(); + SetType setType = new SetType(u); + FunctionType f = new FunctionType(u, new UntypedType()); + setType(node.getLeft(), setType); + setType(node.getRight(), f); + node.getLeft().apply(this); + node.getRight().apply(this); + + BType found = getType(node.getRight()); + BType expected = getType(node); + unify(expected, found, node); + } + + @Override + public void caseADomainSubtractionExpression(ADomainSubtractionExpression node) { + UntypedType u = new UntypedType(); + SetType setType = new SetType(u); + FunctionType f = new FunctionType(u, new UntypedType()); + setType(node.getLeft(), setType); + setType(node.getRight(), f); + node.getLeft().apply(this); + node.getRight().apply(this); + + BType found = getType(node.getRight()); + BType expected = getType(node); + unify(expected, found, node); + } + + @Override + public void caseARangeRestrictionExpression(ARangeRestrictionExpression node) { + UntypedType u = new UntypedType(); + SetType setType = new SetType(u); + FunctionType f = new FunctionType(new UntypedType(), u); + setType(node.getLeft(), f); + setType(node.getRight(), setType); + node.getLeft().apply(this); + node.getRight().apply(this); + + BType found = getType(node.getLeft()); + BType expected = getType(node); + unify(expected, found, node); + } + + @Override + public void caseARangeSubtractionExpression(ARangeSubtractionExpression node) { + UntypedType u = new UntypedType(); + SetType setType = new SetType(u); + FunctionType f = new FunctionType(new UntypedType(), u); + setType(node.getLeft(), f); + setType(node.getRight(), setType); + node.getLeft().apply(this); + node.getRight().apply(this); + + BType found = getType(node.getLeft()); + BType expected = getType(node); + unify(expected, found, node); + } + + @Override + public void caseAImageExpression(AImageExpression node) { + BType expected = getType(node); + BType dom = new UntypedType(); + BType ran = new UntypedType(); + BType found = new SetType(ran); + BType left = new FunctionType(dom, ran); + BType right = new SetType(dom); + setType(node.getLeft(), left); + setType(node.getRight(), right); + unify(expected, found, node); + + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseAReverseExpression(AReverseExpression node) { + BType left = new UntypedType(); + BType right = new UntypedType(); + + BType found = new SetType(new PairType(left, right)); + + BType expr = new FunctionType(right, left); + setType(node.getExpression(), expr); + BType expected = getType(node); + + unify(expected, found, node); + node.getExpression().apply(this); + } + + @Override + public void caseAOverwriteExpression(AOverwriteExpression node) { + BType expected = getType(node); + BType found = new FunctionType(new UntypedType(), new UntypedType()); + setType(node.getLeft(), found); + setType(node.getRight(), found); + unify(expected, found, node); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseADirectProductExpression(ADirectProductExpression node) { + UntypedType u = new UntypedType(); + UntypedType u1 = new UntypedType(); + UntypedType u2 = new UntypedType(); + BType left = new SetType(new PairType(u, u1)); + BType right = new SetType(new PairType(u, u2)); + setType(node.getLeft(), left); + setType(node.getRight(), right); + + BType expected = getType(node); + BType found = new SetType(new PairType(u, new PairType(u1, u2))); + try { + expected.unify(found, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); + } + + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseAParallelProductExpression(AParallelProductExpression node) { + UntypedType t = new UntypedType(); + UntypedType u = new UntypedType(); + BType left = new SetType(new PairType(t, u)); + UntypedType v = new UntypedType(); + UntypedType w = new UntypedType(); + BType right = new SetType(new PairType(v, w)); + setType(node.getLeft(), left); + setType(node.getRight(), right); + BType found = new SetType(new PairType(new PairType(t, v), new PairType(u, w))); + BType expected = getType(node); + + unify(expected, found, node); + + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseACompositionExpression(ACompositionExpression node) { + UntypedType t = new UntypedType(); + UntypedType u = new UntypedType(); + UntypedType v = new UntypedType(); + BType left = new SetType(new PairType(t, u)); + BType right = new SetType(new PairType(u, v)); + setType(node.getLeft(), left); + setType(node.getRight(), right); + BType found = new SetType(new PairType(t, v)); + BType expected = getType(node); + + unify(expected, found, node); + + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseAFirstProjectionExpression(AFirstProjectionExpression node) { + UntypedType t = new UntypedType(); + UntypedType u = new UntypedType(); + BType left = new SetType(t); + BType right = new SetType(u); + BType found = new SetType(new PairType(new PairType(t, u), t)); + setType(node.getExp1(), left); + setType(node.getExp2(), right); + BType expected = getType(node); + + unify(expected, found, node); + + node.getExp1().apply(this); + node.getExp2().apply(this); + } + + @Override + public void caseASecondProjectionExpression(ASecondProjectionExpression node) { + UntypedType t = new UntypedType(); + UntypedType u = new UntypedType(); + BType left = new SetType(t); + BType right = new SetType(u); + BType found = new SetType(new PairType(new PairType(t, u), u)); + setType(node.getExp1(), left); + setType(node.getExp2(), right); + BType expected = getType(node); + + unify(expected, found, node); + + node.getExp1().apply(this); + node.getExp2().apply(this); + } + + @Override + public void caseAIterationExpression(AIterationExpression node) { + UntypedType t = new UntypedType(); + BType found = new SetType(new PairType(t, t)); + setType(node.getRight(), IntegerType.getInstance()); + setType(node.getLeft(), found); + BType expected = getType(node); + + unify(expected, found, node); + + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseAClosureExpression(AClosureExpression node) { + UntypedType t = new UntypedType(); + BType found = new SetType(new PairType(t, t)); + setType(node.getExpression(), found); + BType expected = getType(node); + unify(expected, found, node); + node.getExpression().apply(this); + } + + @Override + public void caseAReflexiveClosureExpression(AReflexiveClosureExpression node) { + UntypedType t = new UntypedType(); + BType found = new SetType(new PairType(t, t)); + setType(node.getExpression(), found); + BType expected = getType(node); + unify(expected, found, node); + node.getExpression().apply(this); + } + + @Override + public void caseATransFunctionExpression(ATransFunctionExpression node) { + UntypedType t = new UntypedType(); + UntypedType u = new UntypedType(); + setType(node.getExpression(), new SetType(new PairType(t, u))); + BType found = new SetType(new PairType(t, new SetType(u))); + BType expected = getType(node); + unify(expected, found, node); + node.getExpression().apply(this); + } + + @Override + public void caseATransRelationExpression(ATransRelationExpression node) { + UntypedType t = new UntypedType(); + UntypedType u = new UntypedType(); + setType(node.getExpression(), new SetType(new PairType(t, new SetType(u)))); + BType found = new SetType(new PairType(t, u)); + BType expected = getType(node); + unify(expected, found, node); + node.getExpression().apply(this); + } + + public void unify(BType expected, BType found, Node node) { + try { + expected.unify(found, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "' at " + + node.getClass().getSimpleName() + "\n " + node.getStartPos() + ":" + node.getEndPos()); + } + } + + @Override + public void caseAEmptySequenceExpression(AEmptySequenceExpression node) { + BType expected = getType(node); + BType found = new FunctionType(IntegerType.getInstance(), new UntypedType()); + try { + expected.unify(found, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); + } + } + + /** + * Sequences + */ + + @Override + public void caseASeqExpression(ASeqExpression node) { + UntypedType t = new UntypedType(); + setType(node.getExpression(), new SetType(t)); + BType found = new SetType(new FunctionType(IntegerType.getInstance(), t)); + BType expected = getType(node); + unify(expected, found, node); + node.getExpression().apply(this); + } + + @Override + public void caseASizeExpression(ASizeExpression node) { + setType(node.getExpression(), new FunctionType(IntegerType.getInstance(), new UntypedType())); + BType found = IntegerType.getInstance(); + BType expected = getType(node); + unify(expected, found, node); + node.getExpression().apply(this); + } + + @Override + public void caseAConcatExpression(AConcatExpression node) { + BType found = new FunctionType(IntegerType.getInstance(), new UntypedType()); + setType(node.getLeft(), found); + setType(node.getRight(), found); + BType expected = getType(node); + unify(expected, found, node); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseAInsertTailExpression(AInsertTailExpression node) { + UntypedType t = new UntypedType(); + BType found = new FunctionType(IntegerType.getInstance(), t); + setType(node.getLeft(), found); + setType(node.getRight(), t); + BType expected = getType(node); + unify(expected, found, node); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseAFirstExpression(AFirstExpression node) { + BType found = new UntypedType(); + setType(node.getExpression(), new FunctionType(IntegerType.getInstance(), found)); + BType expected = getType(node); + unify(expected, found, node); + node.getExpression().apply(this); + } + + @Override + public void caseATailExpression(ATailExpression node) { + BType found = new FunctionType(IntegerType.getInstance(), new UntypedType()); + setType(node.getExpression(), found); + BType expected = getType(node); + unify(expected, found, node); + node.getExpression().apply(this); + } + + /** + * Sequences Extended + */ + + private void evalSetOfSequences(Node node, Node expr) { + UntypedType t = new UntypedType(); + setType(expr, new SetType(t)); + BType found = new SetType(new FunctionType(IntegerType.getInstance(), t)); + BType expected = getType(node); + unify(expected, found, node); + expr.apply(this); + } + + @Override + public void caseAIseqExpression(AIseqExpression node) { + evalSetOfSequences(node, node.getExpression()); + } + + @Override + public void caseAIseq1Expression(AIseq1Expression node) { + evalSetOfSequences(node, node.getExpression()); + } + + @Override + public void caseASeq1Expression(ASeq1Expression node) { + evalSetOfSequences(node, node.getExpression()); + } + + @Override + public void caseAInsertFrontExpression(AInsertFrontExpression node) { + UntypedType t = new UntypedType(); + BType found = new FunctionType(IntegerType.getInstance(), t); + setType(node.getLeft(), t); + setType(node.getRight(), found); + BType expected = getType(node); + unify(expected, found, node); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseALastExpression(ALastExpression node) { + BType found = new UntypedType(); + setType(node.getExpression(), new FunctionType(IntegerType.getInstance(), found)); + BType expected = getType(node); + unify(expected, found, node); + node.getExpression().apply(this); + } + + @Override + public void caseAPermExpression(APermExpression node) { + evalSetOfSequences(node, node.getExpression()); + } + + @Override + public void caseARevExpression(ARevExpression node) { + BType found = new FunctionType(IntegerType.getInstance(), new UntypedType()); + setType(node.getExpression(), found); + BType expected = getType(node); + unify(expected, found, node); + node.getExpression().apply(this); + } + + @Override + public void caseAFrontExpression(AFrontExpression node) { + BType found = new FunctionType(IntegerType.getInstance(), new UntypedType()); + setType(node.getExpression(), found); + BType expected = getType(node); + unify(expected, found, node); + node.getExpression().apply(this); + } + + @Override + public void caseAGeneralConcatExpression(AGeneralConcatExpression node) { + + BType found = new FunctionType(IntegerType.getInstance(), new UntypedType()); + setType(node.getExpression(), new FunctionType(IntegerType.getInstance(), found)); + + // BType found = new SetType(new PairType(IntegerType.getInstance(), + // new UntypedType())); + // setType(node.getExpression(), + // new SetType(new PairType(IntegerType.getInstance(), found))); + + BType expected = getType(node); + unify(expected, found, node); + node.getExpression().apply(this); + } + + @Override + public void caseARestrictFrontExpression(ARestrictFrontExpression node) { + UntypedType t = new UntypedType(); + BType found = new FunctionType(IntegerType.getInstance(), t); + setType(node.getLeft(), found); + setType(node.getRight(), IntegerType.getInstance()); + BType expected = getType(node); + unify(expected, found, node); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseARestrictTailExpression(ARestrictTailExpression node) { + UntypedType t = new UntypedType(); + BType found = new FunctionType(IntegerType.getInstance(), t); + setType(node.getLeft(), found); + setType(node.getRight(), IntegerType.getInstance()); + BType expected = getType(node); + unify(expected, found, node); + node.getLeft().apply(this); + node.getRight().apply(this); + } + + @Override + public void caseASequenceExtensionExpression(ASequenceExtensionExpression node) { + BType expected = getType(node); + BType found = new FunctionType(IntegerType.getInstance(), new UntypedType()); + try { + found = found.unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); + } + BType subtype; + if (found instanceof FunctionType) { + subtype = ((FunctionType) found).getRange(); + } else { + PairType p = (PairType) ((SetType) found).getSubtype(); + subtype = p.getSecond(); + } + for (PExpression e : node.getExpression()) { + setType(e, subtype); + } + List<PExpression> copy = new ArrayList<PExpression>(node.getExpression()); + for (PExpression e : copy) { + e.apply(this); + } + } + + /** + * Records + */ + + @Override + public void caseARecExpression(ARecExpression node) { + StructType found = new StructType(); + found.setComplete(); + + List<PRecEntry> copy = new ArrayList<PRecEntry>(node.getEntries()); + for (PRecEntry e2 : copy) { + ARecEntry e = (ARecEntry) e2; + setType(e.getValue(), new UntypedType()); + e.getValue().apply(this); + + AIdentifierExpression i = (AIdentifierExpression) e.getIdentifier(); + String name = Utils.getTIdentifierListAsString(i.getIdentifier()); + found.add(name, getType(e.getValue())); + } + BType expected = getType(node); + try { + unify(expected, found, node); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); + } + } + + @Override + public void caseARecordFieldExpression(ARecordFieldExpression node) { + StructType s = new StructType(); + AIdentifierExpression i = (AIdentifierExpression) node.getIdentifier(); + String fieldName = Utils.getTIdentifierListAsString(i.getIdentifier()); + s.add(fieldName, new UntypedType()); + setType(node.getRecord(), s); + + node.getRecord().apply(this); + + BType found = ((StructType) getType(node.getRecord())).getType(fieldName); + BType expected = getType(node); + try { + unify(expected, found, node); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); + } + + } + + @Override + public void caseAStructExpression(AStructExpression node) { + StructType s = new StructType(); + s.setComplete(); + + List<PRecEntry> copy = new ArrayList<PRecEntry>(node.getEntries()); + for (PRecEntry e2 : copy) { + ARecEntry e = (ARecEntry) e2; + setType(e.getValue(), new SetType(new UntypedType())); + e.getValue().apply(this); + + AIdentifierExpression i = (AIdentifierExpression) e.getIdentifier(); + String name = Utils.getTIdentifierListAsString(i.getIdentifier()); + BType t = ((SetType) getType(e.getValue())).getSubtype(); + s.add(name, t); + } + BType found = new SetType(s); + + BType expected = getType(node); + try { + found.unify(expected, this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + expected + "' , found " + found + "'"); + } + } + + /** + * Strings + */ + + @Override + public void caseAStringExpression(AStringExpression node) { + try { + StringType.getInstance().unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found " + StringType.getInstance() + "'"); + } + } + + @Override + public void caseAStringSetExpression(AStringSetExpression node) { + SetType found = new SetType(StringType.getInstance()); + try { + found.unify(getType(node), this); + } catch (UnificationException e) { + throw new TypeErrorException("Excepted '" + getType(node) + "' , found " + found + "'"); + } + } + + public void inALabelPredicate(ALabelPredicate node) { + BType type = getType(node); + setType(node.getPredicate(), type); + } + +} diff --git a/src/main/java/de/tlc4b/analysis/UsedStandardModules.java b/src/main/java/de/tlc4b/analysis/UsedStandardModules.java index 3eaa3126d9035a15ed1657bc5ec56ad6fbb8c951..a5ff66c597b4501b9a9eefb9f6e26d08c878b769 100644 --- a/src/main/java/de/tlc4b/analysis/UsedStandardModules.java +++ b/src/main/java/de/tlc4b/analysis/UsedStandardModules.java @@ -1,704 +1,704 @@ -package de.tlc4b.analysis; - -import java.util.ArrayList; -import java.util.Comparator; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.Collections; - -import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; -import de.be4.classicalb.core.parser.node.AAddExpression; -import de.be4.classicalb.core.parser.node.AAssignSubstitution; -import de.be4.classicalb.core.parser.node.ACardExpression; -import de.be4.classicalb.core.parser.node.AClosureExpression; -import de.be4.classicalb.core.parser.node.ACompositionExpression; -import de.be4.classicalb.core.parser.node.AConcatExpression; -import de.be4.classicalb.core.parser.node.ADefinitionPredicate; -import de.be4.classicalb.core.parser.node.ADirectProductExpression; -import de.be4.classicalb.core.parser.node.ADivExpression; -import de.be4.classicalb.core.parser.node.ADomainExpression; -import de.be4.classicalb.core.parser.node.ADomainRestrictionExpression; -import de.be4.classicalb.core.parser.node.ADomainSubtractionExpression; -import de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition; -import de.be4.classicalb.core.parser.node.AFin1SubsetExpression; -import de.be4.classicalb.core.parser.node.AFinSubsetExpression; -import de.be4.classicalb.core.parser.node.AFirstExpression; -import de.be4.classicalb.core.parser.node.AFirstProjectionExpression; -import de.be4.classicalb.core.parser.node.AFrontExpression; -import de.be4.classicalb.core.parser.node.AFunctionExpression; -import de.be4.classicalb.core.parser.node.AGeneralConcatExpression; -import de.be4.classicalb.core.parser.node.AGeneralIntersectionExpression; -import de.be4.classicalb.core.parser.node.AGeneralProductExpression; -import de.be4.classicalb.core.parser.node.AGeneralSumExpression; -import de.be4.classicalb.core.parser.node.AGreaterEqualPredicate; -import de.be4.classicalb.core.parser.node.AGreaterPredicate; -import de.be4.classicalb.core.parser.node.AIdentityExpression; -import de.be4.classicalb.core.parser.node.AImageExpression; -import de.be4.classicalb.core.parser.node.AInsertFrontExpression; -import de.be4.classicalb.core.parser.node.AIntSetExpression; -import de.be4.classicalb.core.parser.node.AIntegerSetExpression; -import de.be4.classicalb.core.parser.node.AIntervalExpression; -import de.be4.classicalb.core.parser.node.AIseq1Expression; -import de.be4.classicalb.core.parser.node.AIseqExpression; -import de.be4.classicalb.core.parser.node.AIterationExpression; -import de.be4.classicalb.core.parser.node.ALastExpression; -import de.be4.classicalb.core.parser.node.ALessEqualPredicate; -import de.be4.classicalb.core.parser.node.ALessPredicate; -import de.be4.classicalb.core.parser.node.AMaxExpression; -import de.be4.classicalb.core.parser.node.AMinExpression; -import de.be4.classicalb.core.parser.node.AMinIntExpression; -import de.be4.classicalb.core.parser.node.AMinusOrSetSubtractExpression; -import de.be4.classicalb.core.parser.node.AModuloExpression; -import de.be4.classicalb.core.parser.node.AMultOrCartExpression; -import de.be4.classicalb.core.parser.node.ANat1SetExpression; -import de.be4.classicalb.core.parser.node.ANatSetExpression; -import de.be4.classicalb.core.parser.node.ANatural1SetExpression; -import de.be4.classicalb.core.parser.node.ANaturalSetExpression; -import de.be4.classicalb.core.parser.node.ANotSubsetPredicate; -import de.be4.classicalb.core.parser.node.ANotSubsetStrictPredicate; -import de.be4.classicalb.core.parser.node.AOverwriteExpression; -import de.be4.classicalb.core.parser.node.AParallelProductExpression; -import de.be4.classicalb.core.parser.node.APartialBijectionExpression; -import de.be4.classicalb.core.parser.node.APartialFunctionExpression; -import de.be4.classicalb.core.parser.node.APartialInjectionExpression; -import de.be4.classicalb.core.parser.node.APartialSurjectionExpression; -import de.be4.classicalb.core.parser.node.APermExpression; -import de.be4.classicalb.core.parser.node.APow1SubsetExpression; -import de.be4.classicalb.core.parser.node.APowerOfExpression; -import de.be4.classicalb.core.parser.node.APredecessorExpression; -import de.be4.classicalb.core.parser.node.AQuantifiedIntersectionExpression; -import de.be4.classicalb.core.parser.node.AQuantifiedUnionExpression; -import de.be4.classicalb.core.parser.node.ARangeExpression; -import de.be4.classicalb.core.parser.node.ARangeRestrictionExpression; -import de.be4.classicalb.core.parser.node.ARangeSubtractionExpression; -import de.be4.classicalb.core.parser.node.AReflexiveClosureExpression; -import de.be4.classicalb.core.parser.node.ARelationsExpression; -import de.be4.classicalb.core.parser.node.ARestrictFrontExpression; -import de.be4.classicalb.core.parser.node.ARestrictTailExpression; -import de.be4.classicalb.core.parser.node.ARevExpression; -import de.be4.classicalb.core.parser.node.AReverseExpression; -import de.be4.classicalb.core.parser.node.ASecondProjectionExpression; -import de.be4.classicalb.core.parser.node.ASeq1Expression; -import de.be4.classicalb.core.parser.node.ASeqExpression; -import de.be4.classicalb.core.parser.node.ASetExtensionExpression; -import de.be4.classicalb.core.parser.node.ASizeExpression; -import de.be4.classicalb.core.parser.node.ASuccessorExpression; -import de.be4.classicalb.core.parser.node.ATailExpression; -import de.be4.classicalb.core.parser.node.ATotalBijectionExpression; -import de.be4.classicalb.core.parser.node.ATotalFunctionExpression; -import de.be4.classicalb.core.parser.node.ATotalInjectionExpression; -import de.be4.classicalb.core.parser.node.ATotalSurjectionExpression; -import de.be4.classicalb.core.parser.node.ATransFunctionExpression; -import de.be4.classicalb.core.parser.node.ATransRelationExpression; -import de.be4.classicalb.core.parser.node.AUnaryMinusExpression; -import de.be4.classicalb.core.parser.node.Node; -import de.be4.classicalb.core.parser.node.PDefinition; -import de.be4.classicalb.core.parser.node.PExpression; -import de.be4.classicalb.core.parser.node.Start; -import de.tlc4b.TLC4BGlobals; -import de.tlc4b.analysis.typerestriction.TypeRestrictor; -import de.tlc4b.btypes.BType; -import de.tlc4b.btypes.FunctionType; -import de.tlc4b.btypes.IntegerType; -import de.tlc4b.btypes.SetType; -import de.tlc4b.tla.TLAModule; - -public class UsedStandardModules extends DepthFirstAdapter { - - public static enum STANDARD_MODULES { - Naturals, Integers, FiniteSets, Sequences, TLC, BBuiltIns, Relations, FunctionsAsRelations, Functions, SequencesExtended, SequencesAsRelations, ExternalFunctions, Foo - } - - private final static ArrayList<STANDARD_MODULES> modules = new ArrayList<UsedStandardModules.STANDARD_MODULES>(); - static { - modules.add(STANDARD_MODULES.Naturals); - modules.add(STANDARD_MODULES.Integers); - modules.add(STANDARD_MODULES.FiniteSets); - modules.add(STANDARD_MODULES.Sequences); - modules.add(STANDARD_MODULES.TLC); - modules.add(STANDARD_MODULES.BBuiltIns); - modules.add(STANDARD_MODULES.Relations); - modules.add(STANDARD_MODULES.Functions); - modules.add(STANDARD_MODULES.FunctionsAsRelations); - modules.add(STANDARD_MODULES.SequencesExtended); - modules.add(STANDARD_MODULES.SequencesAsRelations); - modules.add(STANDARD_MODULES.ExternalFunctions); - } - - private final Set<STANDARD_MODULES> extendedStandardModules; - private final Typechecker typechecker; - - public UsedStandardModules(Start start, Typechecker typechecker, - TypeRestrictor typeRestrictor, TLAModule tlaModule) { - this.extendedStandardModules = new HashSet<STANDARD_MODULES>(); - this.typechecker = typechecker; - - if (TLC4BGlobals.useSymmetry()) { - extendedStandardModules.add(STANDARD_MODULES.TLC); - } - - List<PDefinition> definitions = tlaModule.getAllDefinitions(); - if (definitions != null) { - for (PDefinition pDefinition : definitions) { - pDefinition.apply(this); - } - } - for (Node node : typeRestrictor.getAllRestrictedNodes()) { - node.apply(this); - } - - start.apply(this); - } - - public ArrayList<STANDARD_MODULES> getExtendedModules() { - ArrayList<STANDARD_MODULES> list = new ArrayList<STANDARD_MODULES>( - extendedStandardModules); - if (list.contains(STANDARD_MODULES.Integers)) { - list.remove(STANDARD_MODULES.Naturals); - } - Collections.sort(list, new Comparator<STANDARD_MODULES>() { - public int compare(STANDARD_MODULES s1, STANDARD_MODULES s2) { - Integer i1 = Integer.valueOf(modules.indexOf(s1)); - Integer i2 = Integer.valueOf(modules.indexOf(s2)); - return i1.compareTo(i2); - } - }); - return list; - } - - public HashSet<STANDARD_MODULES> getStandardModulesToBeCreated() { - // dependencies of standard modules - HashSet<STANDARD_MODULES> res = new HashSet<STANDARD_MODULES>(); - for (STANDARD_MODULES module : extendedStandardModules) { - switch (module) { - case ExternalFunctions: - res.add(STANDARD_MODULES.ExternalFunctions); - break; - case FunctionsAsRelations: - res.add(STANDARD_MODULES.FunctionsAsRelations); - res.add(STANDARD_MODULES.Functions); - break; - case SequencesAsRelations: - res.add(STANDARD_MODULES.SequencesAsRelations); - res.add(STANDARD_MODULES.Relations); - res.add(STANDARD_MODULES.FunctionsAsRelations); - res.add(STANDARD_MODULES.Functions); - break; - case BBuiltIns: - res.add(STANDARD_MODULES.BBuiltIns); - break; - case Functions: - res.add(STANDARD_MODULES.Functions); - break; - case Relations: - res.add(STANDARD_MODULES.Relations); - break; - case Sequences: - break; - case SequencesExtended: - res.add(STANDARD_MODULES.SequencesExtended); - break; - default: - break; - } - - } - return res; - } - - @Override - public void inAExpressionDefinitionDefinition( - AExpressionDefinitionDefinition node) { - if (TLC4BGlobals.isForceTLCToEvalConstants()) { - extendedStandardModules.add(STANDARD_MODULES.TLC); - } - String name = node.getName().getText().trim(); - if (StandardMadules.isKeywordInModuleExternalFunctions(name)) { - extendedStandardModules.add(STANDARD_MODULES.ExternalFunctions); - } - } - - @Override - public void inADefinitionPredicate(ADefinitionPredicate node) { - String name = node.getDefLiteral().getText().trim(); - if (StandardMadules.isKeywordInModuleExternalFunctions(name)) { - extendedStandardModules.add(STANDARD_MODULES.ExternalFunctions); - } - } - - /** - * Naturals - */ - - @Override - public void caseANaturalSetExpression(ANaturalSetExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Naturals); - } - - @Override - public void caseANatural1SetExpression(ANatural1SetExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Naturals); - } - - @Override - public void caseANatSetExpression(ANatSetExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Naturals); - } - - @Override - public void caseANat1SetExpression(ANat1SetExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Naturals); - } - - public void inALessEqualPredicate(ALessEqualPredicate node) { - extendedStandardModules.add(STANDARD_MODULES.Naturals); - } - - public void inALessPredicate(ALessPredicate node) { - extendedStandardModules.add(STANDARD_MODULES.Naturals); - } - - public void inAGreaterEqualPredicate(AGreaterEqualPredicate node) { - extendedStandardModules.add(STANDARD_MODULES.Naturals); - } - - public void inAGreaterPredicate(AGreaterPredicate node) { - extendedStandardModules.add(STANDARD_MODULES.Naturals); - } - - public void inAAddExpression(AAddExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Naturals); - } - - public void inAIntervalExpression(AIntervalExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Naturals); - } - - - public void inAMinusOrSetSubtractExpression( - AMinusOrSetSubtractExpression node) { - BType t = typechecker.getType(node); - if (t instanceof IntegerType) { - extendedStandardModules.add(STANDARD_MODULES.Naturals); - } - } - - public void inAMultOrCartExpression(AMultOrCartExpression node) { - BType t = typechecker.getType(node); - if (t instanceof IntegerType) { - extendedStandardModules.add(STANDARD_MODULES.Naturals); - } else { - // usedStandardModules.add(STANDARD_MODULES.RelationsNew); - } - } - - /** - * Integers - */ - - public void inAIntSetExpression(AIntSetExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Integers); - } - - public void inAIntegerSetExpression(AIntegerSetExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Integers); - } - - public void inAUnaryMinusExpression(AUnaryMinusExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Integers); - } - - public void inAMinIntExpression(AMinIntExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Integers); - } - - /** - * FiniteSets - */ - public void inACardExpression(ACardExpression node) { - extendedStandardModules.add(STANDARD_MODULES.FiniteSets); - } - - /** - * BBuiltIns - */ - - public void inAPowerOfExpression(APowerOfExpression node) { - extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); - } - - public void inAMinExpression(AMinExpression node) { - extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); - } - - public void inAMaxExpression(AMaxExpression node) { - extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); - } - - public void inAModuloExpression(AModuloExpression node) { - extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); - } - - public void inADivExpression(ADivExpression node) { - extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); - } - - public void inAGeneralSumExpression(AGeneralSumExpression node) { - extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); - } - - public void inAGeneralProductExpression(AGeneralProductExpression node) { - extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); - } - - public void inASuccessorExpression(ASuccessorExpression node) { - extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); - } - - public void inAPredecessorExpression(APredecessorExpression node) { - extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); - } - - public void inAPow1SubsetExpression(APow1SubsetExpression node) { - extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); - } - - public void inAFinSubsetExpression(AFinSubsetExpression node) { - extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); - } - - public void inAFin1SubsetExpression(AFin1SubsetExpression node) { - extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); - } - - public void inANotSubsetPredicate(ANotSubsetPredicate node) { - extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); - } - - public void inANotSubsetStrictPredicate(ANotSubsetStrictPredicate node) { - extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); - } - - public void inAGeneralIntersectionExpression( - AGeneralIntersectionExpression node) { - extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); - } - - public void inAQuantifiedIntersectionExpression( - AQuantifiedIntersectionExpression node) { - extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); - } - - public void inAQuantifiedUnionExpression(AQuantifiedUnionExpression node) { - // usedStandardModules.add(STANDARD_MODULES.BBuiltIns); - } - - /** - * Functions - */ - private void setOfFunctions(Node node) { - SetType set = (SetType) typechecker.getType(node); - if (set.getSubtype() instanceof FunctionType) { - extendedStandardModules.add(STANDARD_MODULES.Functions); - } else { - extendedStandardModules.add(STANDARD_MODULES.FunctionsAsRelations); - } - } - - public void inAPartialFunctionExpression(APartialFunctionExpression node) { - setOfFunctions(node); - } - - public void inATotalInjectionExpression(ATotalInjectionExpression node) { - setOfFunctions(node); - } - - public void inAPartialInjectionExpression(APartialInjectionExpression node) { - setOfFunctions(node); - } - - public void inATotalSurjectionExpression(ATotalSurjectionExpression node) { - setOfFunctions(node); - } - - public void inAPartialSurjectionExpression(APartialSurjectionExpression node) { - setOfFunctions(node); - } - - public void inATotalBijectionExpression(ATotalBijectionExpression node) { - setOfFunctions(node); - } - - public void inAPartialBijectionExpression(APartialBijectionExpression node) { - setOfFunctions(node); - } - - /** - * Functions as Relations - */ - - // Function call - public void inAFunctionExpression(AFunctionExpression node) { - // System.out.println(node.parent().getClass()); - if (node.parent() instanceof AAssignSubstitution) { - AAssignSubstitution parent = (AAssignSubstitution) node.parent(); - if (parent.getLhsExpression().contains(node)) { - // function assignment (function call on the left side), e.g. - // f(x) := 1 - return; - } - } - BType type = typechecker.getType(node.getIdentifier()); - if (type instanceof SetType) { - extendedStandardModules.add(STANDARD_MODULES.FunctionsAsRelations); - } - - } - - public void inATotalFunctionExpression(ATotalFunctionExpression node) { - SetType type = (SetType) typechecker.getType(node); - if (type.getSubtype() instanceof SetType) { - extendedStandardModules.add(STANDARD_MODULES.FunctionsAsRelations); - } - } - - /** - * Relations - */ - - private void evalFunctionOrRelation(Node node) { - BType t = typechecker.getType(node); - if (t instanceof FunctionType) { - extendedStandardModules.add(STANDARD_MODULES.Functions); - } else { - extendedStandardModules.add(STANDARD_MODULES.Relations); - } - } - - public void inARelationsExpression(ARelationsExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Relations); - } - - public void inADomainExpression(ADomainExpression node) { - BType t = typechecker.getType(node.getExpression()); - if (!(t instanceof FunctionType)) { - extendedStandardModules.add(STANDARD_MODULES.Relations); - } - } - - public void inASetExtensionExpression(ASetExtensionExpression node) { - BType t = typechecker.getType(node); - if (t instanceof FunctionType) { - extendedStandardModules.add(STANDARD_MODULES.TLC); - } - } - - public void inARangeExpression(ARangeExpression node) { - evalFunctionOrRelation(node.getExpression()); - } - - public void inAImageExpression(AImageExpression node) { - evalFunctionOrRelation(node.getLeft()); - } - - public void inAIdentityExpression(AIdentityExpression node) { - evalFunctionOrRelation(node); - } - - public void inADomainRestrictionExpression(ADomainRestrictionExpression node) { - evalFunctionOrRelation(node); - } - - public void inADomainSubtractionExpression(ADomainSubtractionExpression node) { - evalFunctionOrRelation(node); - } - - public void inARangeRestrictionExpression(ARangeRestrictionExpression node) { - evalFunctionOrRelation(node); - } - - public void inARangeSubtractionExpression(ARangeSubtractionExpression node) { - evalFunctionOrRelation(node); - } - - public void inAReverseExpression(AReverseExpression node) { - evalFunctionOrRelation(node.getExpression()); - } - - public void inAOverwriteExpression(AOverwriteExpression node) { - evalFunctionOrRelation(node); - } - - public void inAAssignSubstitution(AAssignSubstitution node) { - List<PExpression> copy = new ArrayList<PExpression>( - node.getLhsExpression()); - for (PExpression e : copy) { - if (e instanceof AFunctionExpression) { - BType type = typechecker.getType(((AFunctionExpression) e) - .getIdentifier()); - if (type instanceof SetType) { - extendedStandardModules.add(STANDARD_MODULES.Relations); - } else { - extendedStandardModules.add(STANDARD_MODULES.Functions); - } - } - } - } - - public void inADirectProductExpression(ADirectProductExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Relations); - } - - public void inAParallelProductExpression(AParallelProductExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Relations); - } - - public void inACompositionExpression(ACompositionExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Relations); - } - - public void inAFirstProjectionExpression(AFirstProjectionExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Relations); - } - - public void inASecondProjectionExpression(ASecondProjectionExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Relations); - } - - public void inAIterationExpression(AIterationExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Relations); - } - - public void inAClosureExpression(AClosureExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Relations); - } - - public void inAReflexiveClosureExpression(AReflexiveClosureExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Relations); - } - - public void inATransFunctionExpression(ATransFunctionExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Relations); - } - - public void inATransRelationExpression(ATransRelationExpression node) { - extendedStandardModules.add(STANDARD_MODULES.Relations); - } - - /** - * Sequences - */ - - public void inASeqExpression(ASeqExpression node) { - SetType type = (SetType) typechecker.getType(node); - if (type.getSubtype() instanceof FunctionType) { - extendedStandardModules.add(STANDARD_MODULES.Sequences); - } else { - extendedStandardModules.add(STANDARD_MODULES.SequencesAsRelations); - } - } - - public void inASizeExpression(ASizeExpression node) { - evalSequenceOrRelation(node.getExpression()); - } - - public void inAConcatExpression(AConcatExpression node) { - evalSequenceOrRelation(node); - } - - private void evalSequenceOrRelation(Node node) { - BType type = typechecker.getType(node); - if (type instanceof FunctionType) { - extendedStandardModules.add(STANDARD_MODULES.Sequences); - } else { - extendedStandardModules.add(STANDARD_MODULES.SequencesAsRelations); - } - } - - public void inAFirstExpression(AFirstExpression node) { - evalSequenceOrRelation(node.getExpression()); - } - - public void inATailExpression(ATailExpression node) { - evalSequenceOrRelation(node.getExpression()); - } - - /** - * SequencesExtended - */ - - private void evalSequenceExtendedOrRelation(Node node) { - BType type = typechecker.getType(node); - if (type instanceof FunctionType) { - extendedStandardModules.add(STANDARD_MODULES.SequencesExtended); - } else { - extendedStandardModules.add(STANDARD_MODULES.SequencesAsRelations); - } - } - - public void inAIseqExpression(AIseqExpression node) { - SetType set = (SetType) typechecker.getType(node); - if (set.getSubtype() instanceof FunctionType) { - extendedStandardModules.add(STANDARD_MODULES.SequencesExtended); - } else { - extendedStandardModules.add(STANDARD_MODULES.SequencesAsRelations); - } - } - - public void inASeq1Expression(ASeq1Expression node) { - SetType set = (SetType) typechecker.getType(node); - if (set.getSubtype() instanceof FunctionType) { - extendedStandardModules.add(STANDARD_MODULES.SequencesExtended); - } else { - extendedStandardModules.add(STANDARD_MODULES.SequencesAsRelations); - } - } - - public void inAIseq1Expression(AIseq1Expression node) { - SetType set = (SetType) typechecker.getType(node); - if (set.getSubtype() instanceof FunctionType) { - extendedStandardModules.add(STANDARD_MODULES.SequencesExtended); - } else { - extendedStandardModules.add(STANDARD_MODULES.SequencesAsRelations); - } - } - - public void inAInsertFrontExpression(AInsertFrontExpression node) { - evalSequenceExtendedOrRelation(node); - } - - public void inALastExpression(ALastExpression node) { - evalSequenceExtendedOrRelation(node.getExpression()); - } - - public void inAFrontExpression(AFrontExpression node) { - evalSequenceExtendedOrRelation(node); - } - - public void inAPermExpression(APermExpression node) { - SetType set = (SetType) typechecker.getType(node); - if (set.getSubtype() instanceof SetType) { - extendedStandardModules.add(STANDARD_MODULES.SequencesAsRelations); - } else { - extendedStandardModules.add(STANDARD_MODULES.SequencesExtended); - } - } - - public void inARevExpression(ARevExpression node) { - evalSequenceExtendedOrRelation(node); - } - - public void inAGeneralConcatExpression(AGeneralConcatExpression node) { - evalSequenceExtendedOrRelation(node); - } - - public void inARestrictFrontExpression(ARestrictFrontExpression node) { - evalSequenceExtendedOrRelation(node); - } - - public void inARestrictTailExpression(ARestrictTailExpression node) { - evalSequenceExtendedOrRelation(node); - } - -} +package de.tlc4b.analysis; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.Collections; + +import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; +import de.be4.classicalb.core.parser.node.AAddExpression; +import de.be4.classicalb.core.parser.node.AAssignSubstitution; +import de.be4.classicalb.core.parser.node.ACardExpression; +import de.be4.classicalb.core.parser.node.AClosureExpression; +import de.be4.classicalb.core.parser.node.ACompositionExpression; +import de.be4.classicalb.core.parser.node.AConcatExpression; +import de.be4.classicalb.core.parser.node.ADefinitionPredicate; +import de.be4.classicalb.core.parser.node.ADirectProductExpression; +import de.be4.classicalb.core.parser.node.ADivExpression; +import de.be4.classicalb.core.parser.node.ADomainExpression; +import de.be4.classicalb.core.parser.node.ADomainRestrictionExpression; +import de.be4.classicalb.core.parser.node.ADomainSubtractionExpression; +import de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition; +import de.be4.classicalb.core.parser.node.AFin1SubsetExpression; +import de.be4.classicalb.core.parser.node.AFinSubsetExpression; +import de.be4.classicalb.core.parser.node.AFirstExpression; +import de.be4.classicalb.core.parser.node.AFirstProjectionExpression; +import de.be4.classicalb.core.parser.node.AFrontExpression; +import de.be4.classicalb.core.parser.node.AFunctionExpression; +import de.be4.classicalb.core.parser.node.AGeneralConcatExpression; +import de.be4.classicalb.core.parser.node.AGeneralIntersectionExpression; +import de.be4.classicalb.core.parser.node.AGeneralProductExpression; +import de.be4.classicalb.core.parser.node.AGeneralSumExpression; +import de.be4.classicalb.core.parser.node.AGreaterEqualPredicate; +import de.be4.classicalb.core.parser.node.AGreaterPredicate; +import de.be4.classicalb.core.parser.node.AIdentityExpression; +import de.be4.classicalb.core.parser.node.AImageExpression; +import de.be4.classicalb.core.parser.node.AInsertFrontExpression; +import de.be4.classicalb.core.parser.node.AIntSetExpression; +import de.be4.classicalb.core.parser.node.AIntegerSetExpression; +import de.be4.classicalb.core.parser.node.AIntervalExpression; +import de.be4.classicalb.core.parser.node.AIseq1Expression; +import de.be4.classicalb.core.parser.node.AIseqExpression; +import de.be4.classicalb.core.parser.node.AIterationExpression; +import de.be4.classicalb.core.parser.node.ALastExpression; +import de.be4.classicalb.core.parser.node.ALessEqualPredicate; +import de.be4.classicalb.core.parser.node.ALessPredicate; +import de.be4.classicalb.core.parser.node.AMaxExpression; +import de.be4.classicalb.core.parser.node.AMinExpression; +import de.be4.classicalb.core.parser.node.AMinIntExpression; +import de.be4.classicalb.core.parser.node.AMinusOrSetSubtractExpression; +import de.be4.classicalb.core.parser.node.AModuloExpression; +import de.be4.classicalb.core.parser.node.AMultOrCartExpression; +import de.be4.classicalb.core.parser.node.ANat1SetExpression; +import de.be4.classicalb.core.parser.node.ANatSetExpression; +import de.be4.classicalb.core.parser.node.ANatural1SetExpression; +import de.be4.classicalb.core.parser.node.ANaturalSetExpression; +import de.be4.classicalb.core.parser.node.ANotSubsetPredicate; +import de.be4.classicalb.core.parser.node.ANotSubsetStrictPredicate; +import de.be4.classicalb.core.parser.node.AOverwriteExpression; +import de.be4.classicalb.core.parser.node.AParallelProductExpression; +import de.be4.classicalb.core.parser.node.APartialBijectionExpression; +import de.be4.classicalb.core.parser.node.APartialFunctionExpression; +import de.be4.classicalb.core.parser.node.APartialInjectionExpression; +import de.be4.classicalb.core.parser.node.APartialSurjectionExpression; +import de.be4.classicalb.core.parser.node.APermExpression; +import de.be4.classicalb.core.parser.node.APow1SubsetExpression; +import de.be4.classicalb.core.parser.node.APowerOfExpression; +import de.be4.classicalb.core.parser.node.APredecessorExpression; +import de.be4.classicalb.core.parser.node.AQuantifiedIntersectionExpression; +import de.be4.classicalb.core.parser.node.AQuantifiedUnionExpression; +import de.be4.classicalb.core.parser.node.ARangeExpression; +import de.be4.classicalb.core.parser.node.ARangeRestrictionExpression; +import de.be4.classicalb.core.parser.node.ARangeSubtractionExpression; +import de.be4.classicalb.core.parser.node.AReflexiveClosureExpression; +import de.be4.classicalb.core.parser.node.ARelationsExpression; +import de.be4.classicalb.core.parser.node.ARestrictFrontExpression; +import de.be4.classicalb.core.parser.node.ARestrictTailExpression; +import de.be4.classicalb.core.parser.node.ARevExpression; +import de.be4.classicalb.core.parser.node.AReverseExpression; +import de.be4.classicalb.core.parser.node.ASecondProjectionExpression; +import de.be4.classicalb.core.parser.node.ASeq1Expression; +import de.be4.classicalb.core.parser.node.ASeqExpression; +import de.be4.classicalb.core.parser.node.ASetExtensionExpression; +import de.be4.classicalb.core.parser.node.ASizeExpression; +import de.be4.classicalb.core.parser.node.ASuccessorExpression; +import de.be4.classicalb.core.parser.node.ATailExpression; +import de.be4.classicalb.core.parser.node.ATotalBijectionExpression; +import de.be4.classicalb.core.parser.node.ATotalFunctionExpression; +import de.be4.classicalb.core.parser.node.ATotalInjectionExpression; +import de.be4.classicalb.core.parser.node.ATotalSurjectionExpression; +import de.be4.classicalb.core.parser.node.ATransFunctionExpression; +import de.be4.classicalb.core.parser.node.ATransRelationExpression; +import de.be4.classicalb.core.parser.node.AUnaryMinusExpression; +import de.be4.classicalb.core.parser.node.Node; +import de.be4.classicalb.core.parser.node.PDefinition; +import de.be4.classicalb.core.parser.node.PExpression; +import de.be4.classicalb.core.parser.node.Start; +import de.tlc4b.TLC4BGlobals; +import de.tlc4b.analysis.typerestriction.TypeRestrictor; +import de.tlc4b.btypes.BType; +import de.tlc4b.btypes.FunctionType; +import de.tlc4b.btypes.IntegerType; +import de.tlc4b.btypes.SetType; +import de.tlc4b.tla.TLAModule; + +public class UsedStandardModules extends DepthFirstAdapter { + + public static enum STANDARD_MODULES { + Naturals, Integers, FiniteSets, Sequences, TLC, BBuiltIns, Relations, FunctionsAsRelations, Functions, SequencesExtended, SequencesAsRelations, ExternalFunctions, Foo + } + + private final static ArrayList<STANDARD_MODULES> modules = new ArrayList<UsedStandardModules.STANDARD_MODULES>(); + static { + modules.add(STANDARD_MODULES.Naturals); + modules.add(STANDARD_MODULES.Integers); + modules.add(STANDARD_MODULES.FiniteSets); + modules.add(STANDARD_MODULES.Sequences); + modules.add(STANDARD_MODULES.TLC); + modules.add(STANDARD_MODULES.BBuiltIns); + modules.add(STANDARD_MODULES.Relations); + modules.add(STANDARD_MODULES.Functions); + modules.add(STANDARD_MODULES.FunctionsAsRelations); + modules.add(STANDARD_MODULES.SequencesExtended); + modules.add(STANDARD_MODULES.SequencesAsRelations); + modules.add(STANDARD_MODULES.ExternalFunctions); + } + + private final Set<STANDARD_MODULES> extendedStandardModules; + private final Typechecker typechecker; + + public UsedStandardModules(Start start, Typechecker typechecker, + TypeRestrictor typeRestrictor, TLAModule tlaModule) { + this.extendedStandardModules = new HashSet<STANDARD_MODULES>(); + this.typechecker = typechecker; + + if (TLC4BGlobals.useSymmetry()) { + extendedStandardModules.add(STANDARD_MODULES.TLC); + } + + List<PDefinition> definitions = tlaModule.getAllDefinitions(); + if (definitions != null) { + for (PDefinition pDefinition : definitions) { + pDefinition.apply(this); + } + } + for (Node node : typeRestrictor.getAllRestrictedNodes()) { + node.apply(this); + } + + start.apply(this); + } + + public ArrayList<STANDARD_MODULES> getExtendedModules() { + ArrayList<STANDARD_MODULES> list = new ArrayList<STANDARD_MODULES>( + extendedStandardModules); + if (list.contains(STANDARD_MODULES.Integers)) { + list.remove(STANDARD_MODULES.Naturals); + } + Collections.sort(list, new Comparator<STANDARD_MODULES>() { + public int compare(STANDARD_MODULES s1, STANDARD_MODULES s2) { + Integer i1 = Integer.valueOf(modules.indexOf(s1)); + Integer i2 = Integer.valueOf(modules.indexOf(s2)); + return i1.compareTo(i2); + } + }); + return list; + } + + public HashSet<STANDARD_MODULES> getStandardModulesToBeCreated() { + // dependencies of standard modules + HashSet<STANDARD_MODULES> res = new HashSet<STANDARD_MODULES>(); + for (STANDARD_MODULES module : extendedStandardModules) { + switch (module) { + case ExternalFunctions: + res.add(STANDARD_MODULES.ExternalFunctions); + break; + case FunctionsAsRelations: + res.add(STANDARD_MODULES.FunctionsAsRelations); + res.add(STANDARD_MODULES.Functions); + break; + case SequencesAsRelations: + res.add(STANDARD_MODULES.SequencesAsRelations); + res.add(STANDARD_MODULES.Relations); + res.add(STANDARD_MODULES.FunctionsAsRelations); + res.add(STANDARD_MODULES.Functions); + break; + case BBuiltIns: + res.add(STANDARD_MODULES.BBuiltIns); + break; + case Functions: + res.add(STANDARD_MODULES.Functions); + break; + case Relations: + res.add(STANDARD_MODULES.Relations); + break; + case Sequences: + break; + case SequencesExtended: + res.add(STANDARD_MODULES.SequencesExtended); + break; + default: + break; + } + + } + return res; + } + + @Override + public void inAExpressionDefinitionDefinition( + AExpressionDefinitionDefinition node) { + if (TLC4BGlobals.isForceTLCToEvalConstants()) { + extendedStandardModules.add(STANDARD_MODULES.TLC); + } + String name = node.getName().getText().trim(); + if (StandardMadules.isKeywordInModuleExternalFunctions(name)) { + extendedStandardModules.add(STANDARD_MODULES.ExternalFunctions); + } + } + + @Override + public void inADefinitionPredicate(ADefinitionPredicate node) { + String name = node.getDefLiteral().getText().trim(); + if (StandardMadules.isKeywordInModuleExternalFunctions(name)) { + extendedStandardModules.add(STANDARD_MODULES.ExternalFunctions); + } + } + + /** + * Naturals + */ + + @Override + public void caseANaturalSetExpression(ANaturalSetExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Naturals); + } + + @Override + public void caseANatural1SetExpression(ANatural1SetExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Naturals); + } + + @Override + public void caseANatSetExpression(ANatSetExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Naturals); + } + + @Override + public void caseANat1SetExpression(ANat1SetExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Naturals); + } + + public void inALessEqualPredicate(ALessEqualPredicate node) { + extendedStandardModules.add(STANDARD_MODULES.Naturals); + } + + public void inALessPredicate(ALessPredicate node) { + extendedStandardModules.add(STANDARD_MODULES.Naturals); + } + + public void inAGreaterEqualPredicate(AGreaterEqualPredicate node) { + extendedStandardModules.add(STANDARD_MODULES.Naturals); + } + + public void inAGreaterPredicate(AGreaterPredicate node) { + extendedStandardModules.add(STANDARD_MODULES.Naturals); + } + + public void inAAddExpression(AAddExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Naturals); + } + + public void inAIntervalExpression(AIntervalExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Naturals); + } + + + public void inAMinusOrSetSubtractExpression( + AMinusOrSetSubtractExpression node) { + BType t = typechecker.getType(node); + if (t instanceof IntegerType) { + extendedStandardModules.add(STANDARD_MODULES.Naturals); + } + } + + public void inAMultOrCartExpression(AMultOrCartExpression node) { + BType t = typechecker.getType(node); + if (t instanceof IntegerType) { + extendedStandardModules.add(STANDARD_MODULES.Naturals); + } else { + // usedStandardModules.add(STANDARD_MODULES.RelationsNew); + } + } + + /** + * Integers + */ + + public void inAIntSetExpression(AIntSetExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Integers); + } + + public void inAIntegerSetExpression(AIntegerSetExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Integers); + } + + public void inAUnaryMinusExpression(AUnaryMinusExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Integers); + } + + public void inAMinIntExpression(AMinIntExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Integers); + } + + /** + * FiniteSets + */ + public void inACardExpression(ACardExpression node) { + extendedStandardModules.add(STANDARD_MODULES.FiniteSets); + } + + /** + * BBuiltIns + */ + + public void inAPowerOfExpression(APowerOfExpression node) { + extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); + } + + public void inAMinExpression(AMinExpression node) { + extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); + } + + public void inAMaxExpression(AMaxExpression node) { + extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); + } + + public void inAModuloExpression(AModuloExpression node) { + extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); + } + + public void inADivExpression(ADivExpression node) { + extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); + } + + public void inAGeneralSumExpression(AGeneralSumExpression node) { + extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); + } + + public void inAGeneralProductExpression(AGeneralProductExpression node) { + extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); + } + + public void inASuccessorExpression(ASuccessorExpression node) { + extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); + } + + public void inAPredecessorExpression(APredecessorExpression node) { + extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); + } + + public void inAPow1SubsetExpression(APow1SubsetExpression node) { + extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); + } + + public void inAFinSubsetExpression(AFinSubsetExpression node) { + extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); + } + + public void inAFin1SubsetExpression(AFin1SubsetExpression node) { + extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); + } + + public void inANotSubsetPredicate(ANotSubsetPredicate node) { + extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); + } + + public void inANotSubsetStrictPredicate(ANotSubsetStrictPredicate node) { + extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); + } + + public void inAGeneralIntersectionExpression( + AGeneralIntersectionExpression node) { + extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); + } + + public void inAQuantifiedIntersectionExpression( + AQuantifiedIntersectionExpression node) { + extendedStandardModules.add(STANDARD_MODULES.BBuiltIns); + } + + public void inAQuantifiedUnionExpression(AQuantifiedUnionExpression node) { + // usedStandardModules.add(STANDARD_MODULES.BBuiltIns); + } + + /** + * Functions + */ + private void setOfFunctions(Node node) { + SetType set = (SetType) typechecker.getType(node); + if (set.getSubtype() instanceof FunctionType) { + extendedStandardModules.add(STANDARD_MODULES.Functions); + } else { + extendedStandardModules.add(STANDARD_MODULES.FunctionsAsRelations); + } + } + + public void inAPartialFunctionExpression(APartialFunctionExpression node) { + setOfFunctions(node); + } + + public void inATotalInjectionExpression(ATotalInjectionExpression node) { + setOfFunctions(node); + } + + public void inAPartialInjectionExpression(APartialInjectionExpression node) { + setOfFunctions(node); + } + + public void inATotalSurjectionExpression(ATotalSurjectionExpression node) { + setOfFunctions(node); + } + + public void inAPartialSurjectionExpression(APartialSurjectionExpression node) { + setOfFunctions(node); + } + + public void inATotalBijectionExpression(ATotalBijectionExpression node) { + setOfFunctions(node); + } + + public void inAPartialBijectionExpression(APartialBijectionExpression node) { + setOfFunctions(node); + } + + /** + * Functions as Relations + */ + + // Function call + public void inAFunctionExpression(AFunctionExpression node) { + // System.out.println(node.parent().getClass()); + if (node.parent() instanceof AAssignSubstitution) { + AAssignSubstitution parent = (AAssignSubstitution) node.parent(); + if (parent.getLhsExpression().contains(node)) { + // function assignment (function call on the left side), e.g. + // f(x) := 1 + return; + } + } + BType type = typechecker.getType(node.getIdentifier()); + if (type instanceof SetType) { + extendedStandardModules.add(STANDARD_MODULES.FunctionsAsRelations); + } + + } + + public void inATotalFunctionExpression(ATotalFunctionExpression node) { + SetType type = (SetType) typechecker.getType(node); + if (type.getSubtype() instanceof SetType) { + extendedStandardModules.add(STANDARD_MODULES.FunctionsAsRelations); + } + } + + /** + * Relations + */ + + private void evalFunctionOrRelation(Node node) { + BType t = typechecker.getType(node); + if (t instanceof FunctionType) { + extendedStandardModules.add(STANDARD_MODULES.Functions); + } else { + extendedStandardModules.add(STANDARD_MODULES.Relations); + } + } + + public void inARelationsExpression(ARelationsExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Relations); + } + + public void inADomainExpression(ADomainExpression node) { + BType t = typechecker.getType(node.getExpression()); + if (!(t instanceof FunctionType)) { + extendedStandardModules.add(STANDARD_MODULES.Relations); + } + } + + public void inASetExtensionExpression(ASetExtensionExpression node) { + BType t = typechecker.getType(node); + if (t instanceof FunctionType) { + extendedStandardModules.add(STANDARD_MODULES.TLC); + } + } + + public void inARangeExpression(ARangeExpression node) { + evalFunctionOrRelation(node.getExpression()); + } + + public void inAImageExpression(AImageExpression node) { + evalFunctionOrRelation(node.getLeft()); + } + + public void inAIdentityExpression(AIdentityExpression node) { + evalFunctionOrRelation(node); + } + + public void inADomainRestrictionExpression(ADomainRestrictionExpression node) { + evalFunctionOrRelation(node); + } + + public void inADomainSubtractionExpression(ADomainSubtractionExpression node) { + evalFunctionOrRelation(node); + } + + public void inARangeRestrictionExpression(ARangeRestrictionExpression node) { + evalFunctionOrRelation(node); + } + + public void inARangeSubtractionExpression(ARangeSubtractionExpression node) { + evalFunctionOrRelation(node); + } + + public void inAReverseExpression(AReverseExpression node) { + evalFunctionOrRelation(node.getExpression()); + } + + public void inAOverwriteExpression(AOverwriteExpression node) { + evalFunctionOrRelation(node); + } + + public void inAAssignSubstitution(AAssignSubstitution node) { + List<PExpression> copy = new ArrayList<PExpression>( + node.getLhsExpression()); + for (PExpression e : copy) { + if (e instanceof AFunctionExpression) { + BType type = typechecker.getType(((AFunctionExpression) e) + .getIdentifier()); + if (type instanceof SetType) { + extendedStandardModules.add(STANDARD_MODULES.Relations); + } else { + extendedStandardModules.add(STANDARD_MODULES.Functions); + } + } + } + } + + public void inADirectProductExpression(ADirectProductExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Relations); + } + + public void inAParallelProductExpression(AParallelProductExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Relations); + } + + public void inACompositionExpression(ACompositionExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Relations); + } + + public void inAFirstProjectionExpression(AFirstProjectionExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Relations); + } + + public void inASecondProjectionExpression(ASecondProjectionExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Relations); + } + + public void inAIterationExpression(AIterationExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Relations); + } + + public void inAClosureExpression(AClosureExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Relations); + } + + public void inAReflexiveClosureExpression(AReflexiveClosureExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Relations); + } + + public void inATransFunctionExpression(ATransFunctionExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Relations); + } + + public void inATransRelationExpression(ATransRelationExpression node) { + extendedStandardModules.add(STANDARD_MODULES.Relations); + } + + /** + * Sequences + */ + + public void inASeqExpression(ASeqExpression node) { + SetType type = (SetType) typechecker.getType(node); + if (type.getSubtype() instanceof FunctionType) { + extendedStandardModules.add(STANDARD_MODULES.Sequences); + } else { + extendedStandardModules.add(STANDARD_MODULES.SequencesAsRelations); + } + } + + public void inASizeExpression(ASizeExpression node) { + evalSequenceOrRelation(node.getExpression()); + } + + public void inAConcatExpression(AConcatExpression node) { + evalSequenceOrRelation(node); + } + + private void evalSequenceOrRelation(Node node) { + BType type = typechecker.getType(node); + if (type instanceof FunctionType) { + extendedStandardModules.add(STANDARD_MODULES.Sequences); + } else { + extendedStandardModules.add(STANDARD_MODULES.SequencesAsRelations); + } + } + + public void inAFirstExpression(AFirstExpression node) { + evalSequenceOrRelation(node.getExpression()); + } + + public void inATailExpression(ATailExpression node) { + evalSequenceOrRelation(node.getExpression()); + } + + /** + * SequencesExtended + */ + + private void evalSequenceExtendedOrRelation(Node node) { + BType type = typechecker.getType(node); + if (type instanceof FunctionType) { + extendedStandardModules.add(STANDARD_MODULES.SequencesExtended); + } else { + extendedStandardModules.add(STANDARD_MODULES.SequencesAsRelations); + } + } + + public void inAIseqExpression(AIseqExpression node) { + SetType set = (SetType) typechecker.getType(node); + if (set.getSubtype() instanceof FunctionType) { + extendedStandardModules.add(STANDARD_MODULES.SequencesExtended); + } else { + extendedStandardModules.add(STANDARD_MODULES.SequencesAsRelations); + } + } + + public void inASeq1Expression(ASeq1Expression node) { + SetType set = (SetType) typechecker.getType(node); + if (set.getSubtype() instanceof FunctionType) { + extendedStandardModules.add(STANDARD_MODULES.SequencesExtended); + } else { + extendedStandardModules.add(STANDARD_MODULES.SequencesAsRelations); + } + } + + public void inAIseq1Expression(AIseq1Expression node) { + SetType set = (SetType) typechecker.getType(node); + if (set.getSubtype() instanceof FunctionType) { + extendedStandardModules.add(STANDARD_MODULES.SequencesExtended); + } else { + extendedStandardModules.add(STANDARD_MODULES.SequencesAsRelations); + } + } + + public void inAInsertFrontExpression(AInsertFrontExpression node) { + evalSequenceExtendedOrRelation(node); + } + + public void inALastExpression(ALastExpression node) { + evalSequenceExtendedOrRelation(node.getExpression()); + } + + public void inAFrontExpression(AFrontExpression node) { + evalSequenceExtendedOrRelation(node); + } + + public void inAPermExpression(APermExpression node) { + SetType set = (SetType) typechecker.getType(node); + if (set.getSubtype() instanceof SetType) { + extendedStandardModules.add(STANDARD_MODULES.SequencesAsRelations); + } else { + extendedStandardModules.add(STANDARD_MODULES.SequencesExtended); + } + } + + public void inARevExpression(ARevExpression node) { + evalSequenceExtendedOrRelation(node); + } + + public void inAGeneralConcatExpression(AGeneralConcatExpression node) { + evalSequenceExtendedOrRelation(node); + } + + public void inARestrictFrontExpression(ARestrictFrontExpression node) { + evalSequenceExtendedOrRelation(node); + } + + public void inARestrictTailExpression(ARestrictTailExpression node) { + evalSequenceExtendedOrRelation(node); + } + +} diff --git a/src/main/java/de/tlc4b/analysis/transformation/DefinitionCollector.java b/src/main/java/de/tlc4b/analysis/transformation/DefinitionCollector.java index d772860df8b19a9c17fb5e5bd8ab8e9465b41361..57e8c3cacede24aaed24a810faa9ec12056207ca 100644 --- a/src/main/java/de/tlc4b/analysis/transformation/DefinitionCollector.java +++ b/src/main/java/de/tlc4b/analysis/transformation/DefinitionCollector.java @@ -1,96 +1,96 @@ -package de.tlc4b.analysis.transformation; - -import java.util.Hashtable; - -import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; -import de.be4.classicalb.core.parser.node.AConstraintsMachineClause; -import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause; -import de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition; -import de.be4.classicalb.core.parser.node.AInitialisationMachineClause; -import de.be4.classicalb.core.parser.node.AInvariantMachineClause; -import de.be4.classicalb.core.parser.node.ALocalOperationsMachineClause; -import de.be4.classicalb.core.parser.node.AOperationsMachineClause; -import de.be4.classicalb.core.parser.node.APredicateDefinitionDefinition; -import de.be4.classicalb.core.parser.node.APropertiesMachineClause; -import de.be4.classicalb.core.parser.node.ASubstitutionDefinitionDefinition; -import de.be4.classicalb.core.parser.node.PDefinition; -import de.be4.classicalb.core.parser.node.Start; - -/** - * This class only collects all Definitions of a Machine. Definitions of other - * files which are included are not contained. - */ - -public class DefinitionCollector extends DepthFirstAdapter { - - private Hashtable<String, PDefinition> definitionsTable; - private ADefinitionsMachineClause definitionsMachineClause; - - public Hashtable<String, PDefinition> getDefinitions() { - return new Hashtable<String, PDefinition>(definitionsTable); - } - - public ADefinitionsMachineClause getDefinitionsMachineClause() { - return this.definitionsMachineClause; - } - - public DefinitionCollector(Start tree) { - definitionsTable = new Hashtable<String, PDefinition>(); - tree.apply(this); - } - - @Override - public void inADefinitionsMachineClause(ADefinitionsMachineClause node) { - this.definitionsMachineClause = node; - } - - @Override - public void caseAPredicateDefinitionDefinition( - APredicateDefinitionDefinition node) { - definitionsTable.put(node.getName().getText().toString(), node); - } - - @Override - public void caseASubstitutionDefinitionDefinition( - ASubstitutionDefinitionDefinition node) { - definitionsTable.put(node.getName().getText().toString(), node); - } - - @Override - public void caseAExpressionDefinitionDefinition( - AExpressionDefinitionDefinition node) { - definitionsTable.put(node.getName().getText().toString(), node); - } - - /*************************************************************************** - * exclude large sections of a machine without machine references by doing - * nothing - */ - - @Override - public void caseAConstraintsMachineClause(AConstraintsMachineClause node) { - } - - @Override - public void caseAInvariantMachineClause(AInvariantMachineClause node) { - } - - @Override - public void caseAOperationsMachineClause(AOperationsMachineClause node) { - } - - @Override - public void caseAPropertiesMachineClause(APropertiesMachineClause node) { - } - - @Override - public void caseAInitialisationMachineClause( - AInitialisationMachineClause node) { - } - - @Override - public void caseALocalOperationsMachineClause( - ALocalOperationsMachineClause node) { - } - -} +package de.tlc4b.analysis.transformation; + +import java.util.Hashtable; + +import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; +import de.be4.classicalb.core.parser.node.AConstraintsMachineClause; +import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause; +import de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition; +import de.be4.classicalb.core.parser.node.AInitialisationMachineClause; +import de.be4.classicalb.core.parser.node.AInvariantMachineClause; +import de.be4.classicalb.core.parser.node.ALocalOperationsMachineClause; +import de.be4.classicalb.core.parser.node.AOperationsMachineClause; +import de.be4.classicalb.core.parser.node.APredicateDefinitionDefinition; +import de.be4.classicalb.core.parser.node.APropertiesMachineClause; +import de.be4.classicalb.core.parser.node.ASubstitutionDefinitionDefinition; +import de.be4.classicalb.core.parser.node.PDefinition; +import de.be4.classicalb.core.parser.node.Start; + +/** + * This class only collects all Definitions of a Machine. Definitions of other + * files which are included are not contained. + */ + +public class DefinitionCollector extends DepthFirstAdapter { + + private Hashtable<String, PDefinition> definitionsTable; + private ADefinitionsMachineClause definitionsMachineClause; + + public Hashtable<String, PDefinition> getDefinitions() { + return new Hashtable<String, PDefinition>(definitionsTable); + } + + public ADefinitionsMachineClause getDefinitionsMachineClause() { + return this.definitionsMachineClause; + } + + public DefinitionCollector(Start tree) { + definitionsTable = new Hashtable<String, PDefinition>(); + tree.apply(this); + } + + @Override + public void inADefinitionsMachineClause(ADefinitionsMachineClause node) { + this.definitionsMachineClause = node; + } + + @Override + public void caseAPredicateDefinitionDefinition( + APredicateDefinitionDefinition node) { + definitionsTable.put(node.getName().getText().toString(), node); + } + + @Override + public void caseASubstitutionDefinitionDefinition( + ASubstitutionDefinitionDefinition node) { + definitionsTable.put(node.getName().getText().toString(), node); + } + + @Override + public void caseAExpressionDefinitionDefinition( + AExpressionDefinitionDefinition node) { + definitionsTable.put(node.getName().getText().toString(), node); + } + + /*************************************************************************** + * exclude large sections of a machine without machine references by doing + * nothing + */ + + @Override + public void caseAConstraintsMachineClause(AConstraintsMachineClause node) { + } + + @Override + public void caseAInvariantMachineClause(AInvariantMachineClause node) { + } + + @Override + public void caseAOperationsMachineClause(AOperationsMachineClause node) { + } + + @Override + public void caseAPropertiesMachineClause(APropertiesMachineClause node) { + } + + @Override + public void caseAInitialisationMachineClause( + AInitialisationMachineClause node) { + } + + @Override + public void caseALocalOperationsMachineClause( + ALocalOperationsMachineClause node) { + } + +} diff --git a/src/main/java/de/tlc4b/analysis/transformation/DefinitionsEliminator.java b/src/main/java/de/tlc4b/analysis/transformation/DefinitionsEliminator.java index 3456f2e9dd0a80896419b07d5f3ac65db0a2b1c4..3831adefc9894707cb2605d5c0d5a5e8aa45a5ce 100644 --- a/src/main/java/de/tlc4b/analysis/transformation/DefinitionsEliminator.java +++ b/src/main/java/de/tlc4b/analysis/transformation/DefinitionsEliminator.java @@ -1,232 +1,238 @@ -package de.tlc4b.analysis.transformation; - -import java.util.ArrayList; -import java.util.Hashtable; -import java.util.List; - -import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; -import de.be4.classicalb.core.parser.node.AAbstractMachineParseUnit; -import de.be4.classicalb.core.parser.node.ADefinitionExpression; -import de.be4.classicalb.core.parser.node.ADefinitionPredicate; -import de.be4.classicalb.core.parser.node.ADefinitionSubstitution; -import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause; -import de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition; -import de.be4.classicalb.core.parser.node.AIdentifierExpression; -import de.be4.classicalb.core.parser.node.APredicateDefinitionDefinition; -import de.be4.classicalb.core.parser.node.ASubstitutionDefinitionDefinition; -import de.be4.classicalb.core.parser.node.Node; -import de.be4.classicalb.core.parser.node.PDefinition; -import de.be4.classicalb.core.parser.node.PExpression; -import de.be4.classicalb.core.parser.node.PMachineClause; -import de.be4.classicalb.core.parser.node.Start; -import de.be4.classicalb.core.parser.util.Utils; -import de.tlc4b.analysis.StandardMadules; - -/** - * This class eliminates all definition calls in the MACHINE. A definition call - * will be replaced by the right-hand side of the definition and all parameter - * on the RHS are replaced by the arguments of the call. - * - * Note: All parameters of a definition are replaced before a call of a - * sub-definition is resolved. This behavior is similar to what ProB does when - * eliminating all definitions. - * - */ -public class DefinitionsEliminator extends DepthFirstAdapter { - - private Hashtable<String, PDefinition> definitionsTable; - private ArrayList<Hashtable<String, PExpression>> contextStack; - - public static void eliminateDefinitions(Start start){ - new DefinitionsEliminator(start); - } - - private DefinitionsEliminator(Start node) { - DefinitionCollector collector = new DefinitionCollector(node); - definitionsTable = collector.getDefinitions(); - contextStack = new ArrayList<Hashtable<String, PExpression>>(); - node.apply(this); - } - - @Override - public void caseAAbstractMachineParseUnit(AAbstractMachineParseUnit node) { - List<PMachineClause> copy = node.getMachineClauses(); - ADefinitionsMachineClause defClause = null; - for (PMachineClause e : copy) { - e.apply(this); - if (e instanceof ADefinitionsMachineClause) { - defClause = (ADefinitionsMachineClause) e; - } - } - if (defClause != null && defClause.getDefinitions().size() == 0) { - defClause.replaceBy(null); - } - } - - @Override - public void caseADefinitionsMachineClause(ADefinitionsMachineClause node) { - /** - * Definitions from other definitions files were injected into the - * DefinitionsCLause. However, their parent was not correctly set to the - * DefinitionsClause. Hence e.replaceBy(null) would not eliminate them. - * Therefore, we have to create a new list and have to the use the - * setDefinitions method form {link ADefinitionsMachineClause}. - **/ - - List<PDefinition> newDefinitionsList = new ArrayList<PDefinition>(); - List<PDefinition> oldDefinitionsList = new ArrayList<PDefinition>( - node.getDefinitions()); - for (PDefinition e : oldDefinitionsList) { - // replace all definitions calls inside the definitions bodies - if (e instanceof AExpressionDefinitionDefinition) { - String name = ((AExpressionDefinitionDefinition) e).getName() - .getText().toString(); - if (name.startsWith("ASSERT_LTL") || name.startsWith("scope_") - || name.startsWith("SET_PREF_") - || name.startsWith("ANIMATION_FUNCTION")) - continue; - } - e.apply(this); - } - - // add certain definitions to the new definitions list in order to - // obtain them for the translation - for (PDefinition e : oldDefinitionsList) { - - if (e instanceof AExpressionDefinitionDefinition) { - - String name = ((AExpressionDefinitionDefinition) e).getName() - .getText().toString(); - if (name.startsWith("ASSERT_LTL") - || name.startsWith("scope_") - || name.startsWith("SET_PREF_") - || StandardMadules - .isKeywordInModuleExternalFunctions(name)) { - - newDefinitionsList.add(e); - } - } else if (e instanceof APredicateDefinitionDefinition) { - String name = ((APredicateDefinitionDefinition) e).getName() - .getText().toString(); - if (name.equals("GOAL") - || StandardMadules - .isKeywordInModuleExternalFunctions(name)) { - newDefinitionsList.add(e); - } - } - } - for (PDefinition def : newDefinitionsList) { - // we have delete all parents of the definitions in order to set - // them in the next step (seems to be a bug in SabbleCC) - def.replaceBy(null); - } - node.setDefinitions(newDefinitionsList); - } - - @Override - public void caseADefinitionSubstitution(ADefinitionSubstitution node) { - String name = node.getDefLiteral().getText(); - PDefinition def = definitionsTable.get(name); - - ASubstitutionDefinitionDefinition clone = (ASubstitutionDefinitionDefinition) def - .clone(); - Hashtable<String, PExpression> context = new Hashtable<String, PExpression>(); - ArrayList<PExpression> arguments = new ArrayList<PExpression>( - node.getParameters()); - for (int i = 0; i < clone.getParameters().size(); i++) { - AIdentifierExpression p = (AIdentifierExpression) clone - .getParameters().get(i); - String paramName = Utils.getTIdentifierListAsString(p.getIdentifier()); - - Node arg = arguments.get(i); - arg.apply(this); - context.put(paramName, node.getParameters().get(i)); - } - contextStack.add(context); - clone.getRhs().apply(this); - node.replaceBy(clone.getRhs()); - contextStack.remove(context); - } - - @Override - public void caseADefinitionExpression(ADefinitionExpression node) { - String name = node.getDefLiteral().getText(); - ArrayList<PExpression> arguments = new ArrayList<PExpression>( - node.getParameters()); - if (StandardMadules.isKeywordInModuleExternalFunctions(name)) { - for (PExpression arg : arguments) { - arg.apply(this); - } - return; - } - - PDefinition def = definitionsTable.get(name); - AExpressionDefinitionDefinition clone = (AExpressionDefinitionDefinition) def - .clone(); - Hashtable<String, PExpression> context = new Hashtable<String, PExpression>(); - - for (int i = 0; i < clone.getParameters().size(); i++) { - AIdentifierExpression p = (AIdentifierExpression) clone - .getParameters().get(i); - String paramName = Utils.getTIdentifierListAsString(p.getIdentifier()); - Node arg = arguments.get(i); - arg.apply(this); - context.put(paramName, node.getParameters().get(i)); - } - contextStack.add(context); - clone.getRhs().apply(this); - node.replaceBy(clone.getRhs()); - contextStack.remove(context); - } - - @Override - public void caseADefinitionPredicate(ADefinitionPredicate node) { - String name = node.getDefLiteral().getText(); - PDefinition def = definitionsTable.get(name); - - ArrayList<PExpression> arguments = new ArrayList<PExpression>( - node.getParameters()); - if (StandardMadules.isKeywordInModuleExternalFunctions(name)) { - for (PExpression arg : arguments) { - arg.apply(this); - } - return; - } - - APredicateDefinitionDefinition clone = (APredicateDefinitionDefinition) def - .clone(); - Hashtable<String, PExpression> context = new Hashtable<String, PExpression>(); - - for (int i = 0; i < clone.getParameters().size(); i++) { - AIdentifierExpression p = (AIdentifierExpression) clone - .getParameters().get(i); - String paramName = Utils.getTIdentifierListAsString(p.getIdentifier()); - - Node arg = arguments.get(i); - arg.apply(this); - context.put(paramName, node.getParameters().get(i)); - // context.put(paramName, arguments.get(i)); - } - contextStack.add(context); - clone.getRhs().apply(this); - node.replaceBy(clone.getRhs()); - - contextStack.remove(context); - } - - @Override - public void caseAIdentifierExpression(AIdentifierExpression node) { - if (contextStack.size() == 0) - return; - String name = Utils.getTIdentifierListAsString(node.getIdentifier()); - - for (int i = contextStack.size() - 1; i >= 0; i--) { - Hashtable<String, PExpression> context = contextStack.get(i); - PExpression e = context.get(name); - if (e != null) { - node.replaceBy((PExpression) e.clone()); - } - } - } - -} +package de.tlc4b.analysis.transformation; + +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.List; + +import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; +import de.be4.classicalb.core.parser.node.AAbstractMachineParseUnit; +import de.be4.classicalb.core.parser.node.ADefinitionExpression; +import de.be4.classicalb.core.parser.node.ADefinitionPredicate; +import de.be4.classicalb.core.parser.node.ADefinitionSubstitution; +import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause; +import de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition; +import de.be4.classicalb.core.parser.node.AIdentifierExpression; +import de.be4.classicalb.core.parser.node.APredicateDefinitionDefinition; +import de.be4.classicalb.core.parser.node.ASubstitutionDefinitionDefinition; +import de.be4.classicalb.core.parser.node.Node; +import de.be4.classicalb.core.parser.node.PDefinition; +import de.be4.classicalb.core.parser.node.PExpression; +import de.be4.classicalb.core.parser.node.PMachineClause; +import de.be4.classicalb.core.parser.node.Start; +import de.be4.classicalb.core.parser.util.Utils; +import de.tlc4b.analysis.StandardMadules; + +/** + * This class eliminates all definition calls in the MACHINE. A definition call + * will be replaced by the right-hand side of the definition and all parameter + * on the RHS are replaced by the arguments of the call. + * + * Note: All parameters of a definition are replaced before a call of a + * sub-definition is resolved. This behavior is similar to what ProB does when + * eliminating all definitions. + * + */ +public class DefinitionsEliminator extends DepthFirstAdapter { + + private Hashtable<String, PDefinition> definitionsTable; + private ArrayList<Hashtable<String, PExpression>> contextStack; + + public static void eliminateDefinitions(Start start){ + new DefinitionsEliminator(start); + } + + private DefinitionsEliminator(Start node) { + DefinitionCollector collector = new DefinitionCollector(node); + definitionsTable = collector.getDefinitions(); + contextStack = new ArrayList<Hashtable<String, PExpression>>(); + node.apply(this); + } + + @Override + public void caseAAbstractMachineParseUnit(AAbstractMachineParseUnit node) { + List<PMachineClause> copy = node.getMachineClauses(); + ADefinitionsMachineClause defClause = null; + for (PMachineClause e : copy) { + e.apply(this); + if (e instanceof ADefinitionsMachineClause) { + defClause = (ADefinitionsMachineClause) e; + } + } + if (defClause != null && defClause.getDefinitions().size() == 0) { + defClause.replaceBy(null); + } + } + + @Override + public void caseADefinitionsMachineClause(ADefinitionsMachineClause node) { + /** + * Definitions from other definitions files were injected into the + * DefinitionsCLause. However, their parent was not correctly set to the + * DefinitionsClause. Hence e.replaceBy(null) would not eliminate them. + * Therefore, we have to create a new list and have to the use the + * setDefinitions method form {link ADefinitionsMachineClause}. + **/ + + List<PDefinition> newDefinitionsList = new ArrayList<PDefinition>(); + List<PDefinition> oldDefinitionsList = new ArrayList<PDefinition>( + node.getDefinitions()); + for (PDefinition e : oldDefinitionsList) { + // replace all definitions calls inside the definitions bodies + if (e instanceof AExpressionDefinitionDefinition) { + String name = ((AExpressionDefinitionDefinition) e).getName() + .getText().toString(); + if (name.startsWith("ASSERT_LTL") + || name.startsWith("scope_") + || name.startsWith("SET_PREF_") + || name.equals("VISB_JSON_FILE") + || name.startsWith("ANIMATION_FUNCTION") + || name.startsWith("ANIMATION_IMG")) + continue; + } + e.apply(this); + } + + // add certain definitions to the new definitions list in order to + // obtain them for the translation + for (PDefinition e : oldDefinitionsList) { + + if (e instanceof AExpressionDefinitionDefinition) { + + String name = ((AExpressionDefinitionDefinition) e).getName() + .getText().toString(); + if (name.startsWith("ASSERT_LTL") + || name.startsWith("scope_") + || name.startsWith("SET_PREF_") + || name.equals("VISB_JSON_FILE") + || name.startsWith("ANIMATION_FUNCTION") + || name.startsWith("ANIMATION_IMG") + || StandardMadules + .isKeywordInModuleExternalFunctions(name)) { + + newDefinitionsList.add(e); + } + } else if (e instanceof APredicateDefinitionDefinition) { + String name = ((APredicateDefinitionDefinition) e).getName() + .getText().toString(); + if (name.equals("GOAL") + || StandardMadules + .isKeywordInModuleExternalFunctions(name)) { + newDefinitionsList.add(e); + } + } + } + for (PDefinition def : newDefinitionsList) { + // we have delete all parents of the definitions in order to set + // them in the next step (seems to be a bug in SabbleCC) + def.replaceBy(null); + } + node.setDefinitions(newDefinitionsList); + } + + @Override + public void caseADefinitionSubstitution(ADefinitionSubstitution node) { + String name = node.getDefLiteral().getText(); + PDefinition def = definitionsTable.get(name); + + ASubstitutionDefinitionDefinition clone = (ASubstitutionDefinitionDefinition) def + .clone(); + Hashtable<String, PExpression> context = new Hashtable<String, PExpression>(); + ArrayList<PExpression> arguments = new ArrayList<PExpression>( + node.getParameters()); + for (int i = 0; i < clone.getParameters().size(); i++) { + AIdentifierExpression p = (AIdentifierExpression) clone + .getParameters().get(i); + String paramName = Utils.getTIdentifierListAsString(p.getIdentifier()); + + Node arg = arguments.get(i); + arg.apply(this); + context.put(paramName, node.getParameters().get(i)); + } + contextStack.add(context); + clone.getRhs().apply(this); + node.replaceBy(clone.getRhs()); + contextStack.remove(context); + } + + @Override + public void caseADefinitionExpression(ADefinitionExpression node) { + String name = node.getDefLiteral().getText(); + ArrayList<PExpression> arguments = new ArrayList<PExpression>( + node.getParameters()); + if (StandardMadules.isKeywordInModuleExternalFunctions(name)) { + for (PExpression arg : arguments) { + arg.apply(this); + } + return; + } + + PDefinition def = definitionsTable.get(name); + AExpressionDefinitionDefinition clone = (AExpressionDefinitionDefinition) def + .clone(); + Hashtable<String, PExpression> context = new Hashtable<String, PExpression>(); + + for (int i = 0; i < clone.getParameters().size(); i++) { + AIdentifierExpression p = (AIdentifierExpression) clone + .getParameters().get(i); + String paramName = Utils.getTIdentifierListAsString(p.getIdentifier()); + Node arg = arguments.get(i); + arg.apply(this); + context.put(paramName, node.getParameters().get(i)); + } + contextStack.add(context); + clone.getRhs().apply(this); + node.replaceBy(clone.getRhs()); + contextStack.remove(context); + } + + @Override + public void caseADefinitionPredicate(ADefinitionPredicate node) { + String name = node.getDefLiteral().getText(); + PDefinition def = definitionsTable.get(name); + + ArrayList<PExpression> arguments = new ArrayList<PExpression>( + node.getParameters()); + if (StandardMadules.isKeywordInModuleExternalFunctions(name)) { + for (PExpression arg : arguments) { + arg.apply(this); + } + return; + } + + APredicateDefinitionDefinition clone = (APredicateDefinitionDefinition) def + .clone(); + Hashtable<String, PExpression> context = new Hashtable<String, PExpression>(); + + for (int i = 0; i < clone.getParameters().size(); i++) { + AIdentifierExpression p = (AIdentifierExpression) clone + .getParameters().get(i); + String paramName = Utils.getTIdentifierListAsString(p.getIdentifier()); + + Node arg = arguments.get(i); + arg.apply(this); + context.put(paramName, node.getParameters().get(i)); + // context.put(paramName, arguments.get(i)); + } + contextStack.add(context); + clone.getRhs().apply(this); + node.replaceBy(clone.getRhs()); + + contextStack.remove(context); + } + + @Override + public void caseAIdentifierExpression(AIdentifierExpression node) { + if (contextStack.size() == 0) + return; + String name = Utils.getTIdentifierListAsString(node.getIdentifier()); + + for (int i = contextStack.size() - 1; i >= 0; i--) { + Hashtable<String, PExpression> context = contextStack.get(i); + PExpression e = context.get(name); + if (e != null) { + node.replaceBy((PExpression) e.clone()); + } + } + } + +} diff --git a/src/main/java/de/tlc4b/analysis/typerestriction/TypeRestrictor.java b/src/main/java/de/tlc4b/analysis/typerestriction/TypeRestrictor.java index 80a65e7fbf35f130b9457c41e6ac02ddfeb3bf09..b6b2648804fef658b29c7e1a3510ab8413383879 100644 --- a/src/main/java/de/tlc4b/analysis/typerestriction/TypeRestrictor.java +++ b/src/main/java/de/tlc4b/analysis/typerestriction/TypeRestrictor.java @@ -1,622 +1,622 @@ -package de.tlc4b.analysis.typerestriction; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.List; -import java.util.Set; - -import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; -import de.be4.classicalb.core.parser.node.AAnySubstitution; -import de.be4.classicalb.core.parser.node.AAssertionsMachineClause; -import de.be4.classicalb.core.parser.node.ABecomesSuchSubstitution; -import de.be4.classicalb.core.parser.node.AComprehensionSetExpression; -import de.be4.classicalb.core.parser.node.AConjunctPredicate; -import de.be4.classicalb.core.parser.node.AConstraintsMachineClause; -import de.be4.classicalb.core.parser.node.ADisjunctPredicate; -import de.be4.classicalb.core.parser.node.AEqualPredicate; -import de.be4.classicalb.core.parser.node.AExistsPredicate; -import de.be4.classicalb.core.parser.node.AForallPredicate; -import de.be4.classicalb.core.parser.node.AGeneralProductExpression; -import de.be4.classicalb.core.parser.node.AGeneralSumExpression; -import de.be4.classicalb.core.parser.node.AIdentifierExpression; -import de.be4.classicalb.core.parser.node.AImplicationPredicate; -import de.be4.classicalb.core.parser.node.AInitialisationMachineClause; -import de.be4.classicalb.core.parser.node.AIntersectionExpression; -import de.be4.classicalb.core.parser.node.ALambdaExpression; -import de.be4.classicalb.core.parser.node.ALetSubstitution; -import de.be4.classicalb.core.parser.node.AMemberPredicate; -import de.be4.classicalb.core.parser.node.ANotMemberPredicate; -import de.be4.classicalb.core.parser.node.AOperation; -import de.be4.classicalb.core.parser.node.APowSubsetExpression; -import de.be4.classicalb.core.parser.node.APreconditionSubstitution; -import de.be4.classicalb.core.parser.node.APredicateParseUnit; -import de.be4.classicalb.core.parser.node.APropertiesMachineClause; -import de.be4.classicalb.core.parser.node.AQuantifiedIntersectionExpression; -import de.be4.classicalb.core.parser.node.AQuantifiedUnionExpression; -import de.be4.classicalb.core.parser.node.ASelectSubstitution; -import de.be4.classicalb.core.parser.node.ASetExtensionExpression; -import de.be4.classicalb.core.parser.node.ASetSubtractionExpression; -import de.be4.classicalb.core.parser.node.ASubsetPredicate; -import de.be4.classicalb.core.parser.node.Node; -import de.be4.classicalb.core.parser.node.PExpression; -import de.be4.classicalb.core.parser.node.PPredicate; -import de.be4.classicalb.core.parser.node.Start; -import de.be4.classicalb.core.parser.util.Utils; -import de.be4.ltl.core.parser.node.AExistsLtl; -import de.be4.ltl.core.parser.node.AForallLtl; -import de.tlc4b.TLC4BGlobals; -import de.tlc4b.analysis.ConstantsEvaluator; -import de.tlc4b.analysis.MachineContext; -import de.tlc4b.analysis.Typechecker; -import de.tlc4b.btypes.BType; -import de.tlc4b.exceptions.NotSupportedException; -import de.tlc4b.ltl.LTLFormulaVisitor; -import de.tlc4b.util.UtilMethods; - -public class TypeRestrictor extends DepthFirstAdapter { - - private final MachineContext machineContext; - private final IdentifierDependencies identifierDependencies; - private final Typechecker typechecker; - private final ConstantsEvaluator constantsEvaluator; - - private final Hashtable<Node, Node> restrictedTypeNodeTable; - private final HashSet<Node> removedNodes; - - private final Hashtable<Node, ArrayList<Node>> restrictedNodeTable; - private final Hashtable<Node, ArrayList<Node>> subtractedNodeTable; - - public Node getRestrictedNode(Node node) { - return restrictedTypeNodeTable.get(node); - } - - public Collection<Node> getAllRestrictedNodes() { - return restrictedTypeNodeTable.values(); - } - - public TypeRestrictor(Start start, MachineContext machineContext, - Typechecker typechecker, ConstantsEvaluator constantsEvaluator) { - this.machineContext = machineContext; - this.typechecker = typechecker; - this.constantsEvaluator = constantsEvaluator; - - this.restrictedTypeNodeTable = new Hashtable<Node, Node>(); - this.removedNodes = new HashSet<Node>(); - - this.restrictedNodeTable = new Hashtable<Node, ArrayList<Node>>(); - this.subtractedNodeTable = new Hashtable<Node, ArrayList<Node>>(); - - this.identifierDependencies = new IdentifierDependencies(machineContext); - - start.apply(this); - - checkLTLFormulas(); - } - - private void checkLTLFormulas() { - for (LTLFormulaVisitor visitor : machineContext.getLTLFormulas()) { - - for (de.be4.ltl.core.parser.node.Node ltlNode : visitor - .getUnparsedHashTable().keySet()) { - Node bNode = visitor.getBAst(ltlNode); - - if (ltlNode instanceof AExistsLtl) { - Node id = visitor.getLTLIdentifier(((AExistsLtl) ltlNode) - .getExistsIdentifier().getText()); - HashSet<Node> list = new HashSet<Node>(); - list.add(id); - analysePredicate(bNode, list, new HashSet<Node>()); - - PExpression e = (PExpression) id; - HashSet<PExpression> set = new HashSet<PExpression>(); - set.add(e); - createRestrictedTypeofLocalVariables(set, true); - } else if (ltlNode instanceof AForallLtl) { - Node id = visitor.getLTLIdentifier(((AForallLtl) ltlNode) - .getForallIdentifier().getText()); - HashSet<Node> list = new HashSet<Node>(); - list.add(id); - analysePredicate(bNode, list, new HashSet<Node>()); - - PExpression e = (PExpression) id; - HashSet<PExpression> set = new HashSet<PExpression>(); - set.add(e); - createRestrictedTypeofLocalVariables(set, true); - } - bNode.apply(this); - } - - } - } - - public boolean isARemovedNode(Node node) { - return this.removedNodes.contains(node); - } - - private void putRestrictedType(Node identifier, Node expression) { - ArrayList<Node> list = restrictedNodeTable.get(identifier); - - if (list == null) { - list = new ArrayList<Node>(); - list.add(expression); - restrictedNodeTable.put(identifier, list); - } else { - if (!list.contains(expression)) { - list.add(expression); - } - } - } - - private void putSubstractedType(Node identifier, Node expression) { - ArrayList<Node> list = subtractedNodeTable.get(identifier); - if (list == null) { - list = new ArrayList<Node>(); - list.add(expression); - subtractedNodeTable.put(identifier, list); - } else { - list.add(expression); - } - } - - @Override - public void inAConstraintsMachineClause(AConstraintsMachineClause node) { - HashSet<Node> list = new HashSet<Node>(); - // list.addAll(machineContext.getSetParamter().values()); - list.addAll(machineContext.getScalarParameter().values()); - analysePredicate(node.getPredicates(), list, new HashSet<Node>()); - HashSet<PExpression> set = new HashSet<PExpression>(); - for (Node param : list) { - set.add((PExpression) param); - } - createRestrictedTypeofLocalVariables(new HashSet<PExpression>(set), - false); - } - - @Override - public void inAPropertiesMachineClause(APropertiesMachineClause node) { - HashSet<PExpression> set = new HashSet<PExpression>(); - for (Node con : machineContext.getConstants().values()) { - set.add((PExpression) con); - Node valueOfConstant = constantsEvaluator.getValueOfConstant(con); - if(valueOfConstant!= null){ - removedNodes.add(valueOfConstant.parent()); - } - - } - HashSet<Node> list = new HashSet<Node>(); - list.addAll(machineContext.getConstants().values()); - analysePredicate(node.getPredicates(), list, new HashSet<Node>()); - - - createRestrictedTypeofLocalVariables(new HashSet<PExpression>(set), - false); - } - - public void analyseDisjunktionPredicate(PPredicate node, HashSet<Node> list) { - if (node instanceof ADisjunctPredicate) { - ADisjunctPredicate dis = (ADisjunctPredicate) node; - analyseDisjunktionPredicate(dis.getLeft(), list); - analyseDisjunktionPredicate(dis.getRight(), list); - } else { - analysePredicate(node, list, new HashSet<Node>()); - } - } - - private void analysePredicate(Node n, HashSet<Node> list, - HashSet<Node> ignoreList) { - - if (removedNodes.contains(n)) - return; - - if (n instanceof AEqualPredicate) { - PExpression left = ((AEqualPredicate) n).getLeft(); - Node r_left = machineContext.getReferenceNode(left); - PExpression right = ((AEqualPredicate) n).getRight(); - Node r_right = machineContext.getReferenceNode(right); - - if (list.contains(r_left) - && isAConstantExpression(right, list, ignoreList)) { - right.apply(this); - ArrayList<PExpression> element = new ArrayList<PExpression>(); - element.add(right); - if (machineContext.getVariables().values().contains(r_left)) { - r_left = variablesHashTable.get(r_left); - } - putRestrictedType(r_left, new ASetExtensionExpression(element)); - removedNodes.add(n); - } - if (list.contains(r_right) - && isAConstantExpression(left, list, ignoreList)) { - left.apply(this); - ArrayList<PExpression> element = new ArrayList<PExpression>(); - element.add(left); - if (machineContext.getVariables().values().contains(r_right)) { - r_right = variablesHashTable.get(r_right); - } - putRestrictedType(r_right, new ASetExtensionExpression(element)); - removedNodes.add(n); - } - // detecting couples, e.g. (a,b) = (1,3) - // if (left instanceof ACoupleExpression) { - // ACoupleExpression couple = (ACoupleExpression) left; - // PExpression first = couple.getList().get(0); - // Node r_first = machineContext.getReferenceNode(first); - // PExpression second = couple.getList().get(0); - // Node r_second = machineContext.getReferenceNode(second); - // - // if (list.contains(r_first) && list.contains(r_second) - // && isAConstantExpression(right, list, ignoreList)) { - // ArrayList<PExpression> element = new ArrayList<PExpression>(); - // element.add(right); - // putRestrictedTypeOfTuple(r_right, - // new ASetExtensionExpression(element)); - // removedNodes.add(n); - // } - // } - - return; - } - - if (n instanceof AMemberPredicate) { - PExpression left = ((AMemberPredicate) n).getLeft(); - Node r_left = machineContext.getReferenceNode(left); - PExpression right = ((AMemberPredicate) n).getRight(); - if (list.contains(r_left) - && isAConstantExpression(right, list, ignoreList)) { - if (machineContext.getVariables().values().contains(r_left)) { - r_left = variablesHashTable.get(r_left); - } - putRestrictedType(r_left, right); - removedNodes.add(n); - } - return; - } - - if (n instanceof ANotMemberPredicate) { - PExpression left = ((ANotMemberPredicate) n).getLeft(); - Node r_left = machineContext.getReferenceNode(left); - PExpression right = ((ANotMemberPredicate) n).getRight(); - if (list.contains(r_left) - && isAConstantExpression(right, list, ignoreList)) { - if (machineContext.getVariables().values().contains(r_left)) { - r_left = variablesHashTable.get(r_left); - } - putSubstractedType(r_left, right); - removedNodes.add(n); - } - return; - } - - if (n instanceof ASubsetPredicate) { - PExpression left = ((ASubsetPredicate) n).getLeft(); - Node r_left = machineContext.getReferenceNode(left); - PExpression right = ((ASubsetPredicate) n).getRight(); - - if (list.contains(r_left) - && isAConstantExpression(right, list, ignoreList)) { - right.apply(this); - if (machineContext.getVariables().values().contains(r_left)) { - r_left = variablesHashTable.get(r_left); - } - putRestrictedType(r_left, new APowSubsetExpression(right)); - removedNodes.add(n); - } - return; - } - - if (n instanceof AConjunctPredicate) { - Node left = ((AConjunctPredicate) n).getLeft(); - Node right = ((AConjunctPredicate) n).getRight(); - analysePredicate(left, list, ignoreList); - analysePredicate(right, list, ignoreList); - if (removedNodes.contains(left) && removedNodes.contains(right)) { - removedNodes.add(n); - } - return; - } - - if (n instanceof AExistsPredicate) { - HashSet<Node> set = new HashSet<Node>(); - for (PExpression e : ((AExistsPredicate) n).getIdentifiers()) { - set.add(e); - } - set.addAll(ignoreList); - analysePredicate(((AExistsPredicate) n).getPredicate(), list, set); - } - - if (n instanceof Start) { - analysePredicate(((Start) n).getPParseUnit(), list, ignoreList); - } - - if (n instanceof APredicateParseUnit) { - analysePredicate(((APredicateParseUnit) n).getPredicate(), list, - ignoreList); - return; - } - } - - public boolean isAConstantExpression(Node node, HashSet<Node> list, - HashSet<Node> ignoreList) { - HashSet<Node> newList = new HashSet<Node>(); - newList.addAll(list); - newList.addAll(ignoreList); - if (identifierDependencies.containsIdentifier(node, newList)) { - return false; - } - return true; - } - - @Override - public void inAForallPredicate(AForallPredicate node) { - HashSet<Node> list = new HashSet<Node>(); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - list.add(e); - } - AImplicationPredicate implication = (AImplicationPredicate) node - .getImplication(); - analysePredicate(implication.getLeft(), list, new HashSet<Node>()); - createRestrictedTypeofLocalVariables( - new HashSet<PExpression>(node.getIdentifiers()), false); - } - - @Override - public void inAExistsPredicate(AExistsPredicate node) { - HashSet<Node> list = new HashSet<Node>(); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - list.add(e); - } - analysePredicate(node.getPredicate(), list, new HashSet<Node>()); - createRestrictedTypeofLocalVariables( - new HashSet<PExpression>(node.getIdentifiers()), false); - } - - @Override - public void inAQuantifiedUnionExpression(AQuantifiedUnionExpression node) { - HashSet<Node> list = new HashSet<Node>(); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - list.add(e); - } - analysePredicate(node.getPredicates(), list, new HashSet<Node>()); - createRestrictedTypeofLocalVariables( - new HashSet<PExpression>(node.getIdentifiers()), false); - } - - @Override - public void inAQuantifiedIntersectionExpression( - AQuantifiedIntersectionExpression node) { - HashSet<Node> list = new HashSet<Node>(); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - list.add(e); - } - analysePredicate(node.getPredicates(), list, new HashSet<Node>()); - createRestrictedTypeofLocalVariables( - new HashSet<PExpression>(node.getIdentifiers()), false); - } - - @Override - public void inAComprehensionSetExpression(AComprehensionSetExpression node) { - HashSet<Node> list = new HashSet<Node>(); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - list.add(e); - } - analysePredicate(node.getPredicates(), list, new HashSet<Node>()); - createRestrictedTypeofLocalVariables( - new HashSet<PExpression>(node.getIdentifiers()), false); - } - - @Override - public void inALambdaExpression(ALambdaExpression node) { - HashSet<Node> list = new HashSet<Node>(); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - list.add(e); - } - analysePredicate(node.getPredicate(), list, new HashSet<Node>()); - createRestrictedTypeofLocalVariables( - new HashSet<PExpression>(node.getIdentifiers()), false); - } - - public void inAGeneralSumExpression(AGeneralSumExpression node) { - HashSet<Node> list = new HashSet<Node>(); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - list.add(e); - } - analysePredicate(node.getPredicates(), list, new HashSet<Node>()); - createRestrictedTypeofLocalVariables( - new HashSet<PExpression>(node.getIdentifiers()), false); - } - - public void inAGeneralProductExpression(AGeneralProductExpression node) { - HashSet<Node> list = new HashSet<Node>(); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - list.add(e); - } - analysePredicate(node.getPredicates(), list, new HashSet<Node>()); - createRestrictedTypeofLocalVariables( - new HashSet<PExpression>(node.getIdentifiers()), false); - } - - private Hashtable<Node, HashSet<PExpression>> expectedIdentifieListTable = new Hashtable<Node, HashSet<PExpression>>(); - - @Override - public void caseAInitialisationMachineClause( - AInitialisationMachineClause node) { - expectedIdentifieListTable.put(node.getSubstitutions(), - new HashSet<PExpression>()); - node.getSubstitutions().apply(this); - } - - @Override - public void caseAOperation(AOperation node) { - HashSet<PExpression> list = new HashSet<PExpression>(); - { - List<PExpression> copy = new ArrayList<PExpression>( - node.getParameters()); - for (PExpression e : copy) { - list.add(e); - } - } - expectedIdentifieListTable.put(node.getOperationBody(), list); - if (node.getOperationBody() != null) { - node.getOperationBody().apply(this); - } - createRestrictedTypeofLocalVariables(list, false); - } - - @Override - public void inAPreconditionSubstitution(APreconditionSubstitution node) { - HashSet<Node> set = new HashSet<Node>(getExpectedIdentifier(node)); - analysePredicate(node.getPredicate(), set, new HashSet<Node>()); - } - - private HashSet<PExpression> getExpectedIdentifier(Node node) { - HashSet<PExpression> list = expectedIdentifieListTable.get(node); - if (list == null) - list = new HashSet<PExpression>(); - return list; - } - - @Override - public void inASelectSubstitution(ASelectSubstitution node) { - HashSet<Node> list = new HashSet<Node>(getExpectedIdentifier(node)); - analysePredicate(node.getCondition(), list, new HashSet<Node>()); - } - - @Override - public void inAAnySubstitution(AAnySubstitution node) { - HashSet<Node> list = new HashSet<Node>(); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - list.add(e); - } - list.addAll(getExpectedIdentifier(node)); - analysePredicate(node.getWhere(), list, new HashSet<Node>()); - createRestrictedTypeofLocalVariables( - new HashSet<PExpression>(node.getIdentifiers()), false); - } - - @Override - public void inALetSubstitution(ALetSubstitution node) { - HashSet<Node> list = new HashSet<Node>(); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - list.add(e); - } - list.addAll(getExpectedIdentifier(node)); - analysePredicate(node.getPredicate(), list, new HashSet<Node>()); - createRestrictedTypeofLocalVariables( - new HashSet<PExpression>(node.getIdentifiers()), false); - } - - private Hashtable<Node, Node> variablesHashTable; - - public void inABecomesSuchSubstitution(ABecomesSuchSubstitution node) { - if (!(node.getPredicate() instanceof AExistsPredicate)) { - variablesHashTable = new Hashtable<Node, Node>(); - - HashSet<Node> list = new HashSet<Node>(); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - Node ref = machineContext.getReferenceNode(e); - - list.add(ref); - variablesHashTable.put(ref, e); - } - analysePredicate(node.getPredicate(), list, new HashSet<Node>()); - createRestrictedTypeofLocalVariables( - new HashSet<PExpression>(copy), false); - } - } - - private void createRestrictedTypeofLocalVariables(Set<PExpression> copy, - boolean constant) { - // TODO if constant is true, only constant expressions should be used to - // restrict the type. - // This is required by the TLC model checker when checking an LTL - // formula. - - for (PExpression e : copy) { - if (constantsEvaluator.getValueOfIdentifierMap().containsKey(e)) { - continue; - } - - PExpression tree = null; - ArrayList<Node> restrictedList = restrictedNodeTable.get(e); - if (restrictedList == null) { - BType conType = typechecker.getType(e); - if (conType == null) { - conType = typechecker.getType(machineContext - .getReferenceNode(e)); - } - if (conType.containsInfiniteType() - && !(e.parent() instanceof ALambdaExpression) - && !(e.parent() instanceof AComprehensionSetExpression)) { - AIdentifierExpression id = (AIdentifierExpression) e; - String localVariableName = Utils.getTIdentifierListAsString(id - .getIdentifier()); - throw new NotSupportedException( - "Unable to restrict the type '" - + conType - + "' of identifier '" - + localVariableName - + "' to a finite set. TLC is not able to handle infinite sets.\n" - + UtilMethods.getPositionAsString(e)); - } - - tree = conType.createASTNode(typechecker); - } else { - tree = (PExpression) restrictedList.get(0); - for (int i = 1; i < restrictedList.size(); i++) { - PExpression n = (PExpression) restrictedList.get(i); - tree = new AIntersectionExpression(tree, n); - } - - } - ArrayList<Node> substractedList = subtractedNodeTable.get(e); - if (substractedList != null) { - for (int i = 0; i < substractedList.size(); i++) { - PExpression n = (PExpression) substractedList.get(i); - tree = new ASetSubtractionExpression(tree, n); - - } - } - this.restrictedTypeNodeTable.put(e, tree); - } - } - - @Override - public void caseAAssertionsMachineClause(AAssertionsMachineClause node) { - if (TLC4BGlobals.isAssertion()) { - List<PPredicate> copy = new ArrayList<PPredicate>( - node.getPredicates()); - for (PPredicate e : copy) { - e.apply(this); - } - } - } - - public void addRemoveNode(Node node) { - this.removedNodes.add(node); - } - -} +package de.tlc4b.analysis.typerestriction; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.List; +import java.util.Set; + +import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; +import de.be4.classicalb.core.parser.node.AAnySubstitution; +import de.be4.classicalb.core.parser.node.AAssertionsMachineClause; +import de.be4.classicalb.core.parser.node.ABecomesSuchSubstitution; +import de.be4.classicalb.core.parser.node.AComprehensionSetExpression; +import de.be4.classicalb.core.parser.node.AConjunctPredicate; +import de.be4.classicalb.core.parser.node.AConstraintsMachineClause; +import de.be4.classicalb.core.parser.node.ADisjunctPredicate; +import de.be4.classicalb.core.parser.node.AEqualPredicate; +import de.be4.classicalb.core.parser.node.AExistsPredicate; +import de.be4.classicalb.core.parser.node.AForallPredicate; +import de.be4.classicalb.core.parser.node.AGeneralProductExpression; +import de.be4.classicalb.core.parser.node.AGeneralSumExpression; +import de.be4.classicalb.core.parser.node.AIdentifierExpression; +import de.be4.classicalb.core.parser.node.AImplicationPredicate; +import de.be4.classicalb.core.parser.node.AInitialisationMachineClause; +import de.be4.classicalb.core.parser.node.AIntersectionExpression; +import de.be4.classicalb.core.parser.node.ALambdaExpression; +import de.be4.classicalb.core.parser.node.ALetSubstitution; +import de.be4.classicalb.core.parser.node.AMemberPredicate; +import de.be4.classicalb.core.parser.node.ANotMemberPredicate; +import de.be4.classicalb.core.parser.node.AOperation; +import de.be4.classicalb.core.parser.node.APowSubsetExpression; +import de.be4.classicalb.core.parser.node.APreconditionSubstitution; +import de.be4.classicalb.core.parser.node.APredicateParseUnit; +import de.be4.classicalb.core.parser.node.APropertiesMachineClause; +import de.be4.classicalb.core.parser.node.AQuantifiedIntersectionExpression; +import de.be4.classicalb.core.parser.node.AQuantifiedUnionExpression; +import de.be4.classicalb.core.parser.node.ASelectSubstitution; +import de.be4.classicalb.core.parser.node.ASetExtensionExpression; +import de.be4.classicalb.core.parser.node.ASetSubtractionExpression; +import de.be4.classicalb.core.parser.node.ASubsetPredicate; +import de.be4.classicalb.core.parser.node.Node; +import de.be4.classicalb.core.parser.node.PExpression; +import de.be4.classicalb.core.parser.node.PPredicate; +import de.be4.classicalb.core.parser.node.Start; +import de.be4.classicalb.core.parser.util.Utils; +import de.be4.ltl.core.parser.node.AExistsLtl; +import de.be4.ltl.core.parser.node.AForallLtl; +import de.tlc4b.TLC4BGlobals; +import de.tlc4b.analysis.ConstantsEvaluator; +import de.tlc4b.analysis.MachineContext; +import de.tlc4b.analysis.Typechecker; +import de.tlc4b.btypes.BType; +import de.tlc4b.exceptions.NotSupportedException; +import de.tlc4b.ltl.LTLFormulaVisitor; +import de.tlc4b.util.UtilMethods; + +public class TypeRestrictor extends DepthFirstAdapter { + + private final MachineContext machineContext; + private final IdentifierDependencies identifierDependencies; + private final Typechecker typechecker; + private final ConstantsEvaluator constantsEvaluator; + + private final Hashtable<Node, Node> restrictedTypeNodeTable; + private final HashSet<Node> removedNodes; + + private final Hashtable<Node, ArrayList<Node>> restrictedNodeTable; + private final Hashtable<Node, ArrayList<Node>> subtractedNodeTable; + + public Node getRestrictedNode(Node node) { + return restrictedTypeNodeTable.get(node); + } + + public Collection<Node> getAllRestrictedNodes() { + return restrictedTypeNodeTable.values(); + } + + public TypeRestrictor(Start start, MachineContext machineContext, + Typechecker typechecker, ConstantsEvaluator constantsEvaluator) { + this.machineContext = machineContext; + this.typechecker = typechecker; + this.constantsEvaluator = constantsEvaluator; + + this.restrictedTypeNodeTable = new Hashtable<Node, Node>(); + this.removedNodes = new HashSet<Node>(); + + this.restrictedNodeTable = new Hashtable<Node, ArrayList<Node>>(); + this.subtractedNodeTable = new Hashtable<Node, ArrayList<Node>>(); + + this.identifierDependencies = new IdentifierDependencies(machineContext); + + start.apply(this); + + checkLTLFormulas(); + } + + private void checkLTLFormulas() { + for (LTLFormulaVisitor visitor : machineContext.getLTLFormulas()) { + + for (de.be4.ltl.core.parser.node.Node ltlNode : visitor + .getUnparsedHashTable().keySet()) { + Node bNode = visitor.getBAst(ltlNode); + + if (ltlNode instanceof AExistsLtl) { + Node id = visitor.getLTLIdentifier(((AExistsLtl) ltlNode) + .getExistsIdentifier().getText()); + HashSet<Node> list = new HashSet<Node>(); + list.add(id); + analysePredicate(bNode, list, new HashSet<Node>()); + + PExpression e = (PExpression) id; + HashSet<PExpression> set = new HashSet<PExpression>(); + set.add(e); + createRestrictedTypeofLocalVariables(set, true); + } else if (ltlNode instanceof AForallLtl) { + Node id = visitor.getLTLIdentifier(((AForallLtl) ltlNode) + .getForallIdentifier().getText()); + HashSet<Node> list = new HashSet<Node>(); + list.add(id); + analysePredicate(bNode, list, new HashSet<Node>()); + + PExpression e = (PExpression) id; + HashSet<PExpression> set = new HashSet<PExpression>(); + set.add(e); + createRestrictedTypeofLocalVariables(set, true); + } + bNode.apply(this); + } + + } + } + + public boolean isARemovedNode(Node node) { + return this.removedNodes.contains(node); + } + + private void putRestrictedType(Node identifier, Node expression) { + ArrayList<Node> list = restrictedNodeTable.get(identifier); + + if (list == null) { + list = new ArrayList<Node>(); + list.add(expression); + restrictedNodeTable.put(identifier, list); + } else { + if (!list.contains(expression)) { + list.add(expression); + } + } + } + + private void putSubstractedType(Node identifier, Node expression) { + ArrayList<Node> list = subtractedNodeTable.get(identifier); + if (list == null) { + list = new ArrayList<Node>(); + list.add(expression); + subtractedNodeTable.put(identifier, list); + } else { + list.add(expression); + } + } + + @Override + public void inAConstraintsMachineClause(AConstraintsMachineClause node) { + HashSet<Node> list = new HashSet<Node>(); + // list.addAll(machineContext.getSetParamter().values()); + list.addAll(machineContext.getScalarParameter().values()); + analysePredicate(node.getPredicates(), list, new HashSet<Node>()); + HashSet<PExpression> set = new HashSet<PExpression>(); + for (Node param : list) { + set.add((PExpression) param); + } + createRestrictedTypeofLocalVariables(new HashSet<PExpression>(set), + false); + } + + @Override + public void inAPropertiesMachineClause(APropertiesMachineClause node) { + HashSet<PExpression> set = new HashSet<PExpression>(); + for (Node con : machineContext.getConstants().values()) { + set.add((PExpression) con); + Node valueOfConstant = constantsEvaluator.getValueOfConstant(con); + if(valueOfConstant!= null){ + removedNodes.add(valueOfConstant.parent()); + } + + } + HashSet<Node> list = new HashSet<Node>(); + list.addAll(machineContext.getConstants().values()); + analysePredicate(node.getPredicates(), list, new HashSet<Node>()); + + + createRestrictedTypeofLocalVariables(new HashSet<PExpression>(set), + false); + } + + public void analyseDisjunktionPredicate(PPredicate node, HashSet<Node> list) { + if (node instanceof ADisjunctPredicate) { + ADisjunctPredicate dis = (ADisjunctPredicate) node; + analyseDisjunktionPredicate(dis.getLeft(), list); + analyseDisjunktionPredicate(dis.getRight(), list); + } else { + analysePredicate(node, list, new HashSet<Node>()); + } + } + + private void analysePredicate(Node n, HashSet<Node> list, + HashSet<Node> ignoreList) { + + if (removedNodes.contains(n)) + return; + + if (n instanceof AEqualPredicate) { + PExpression left = ((AEqualPredicate) n).getLeft(); + Node r_left = machineContext.getReferenceNode(left); + PExpression right = ((AEqualPredicate) n).getRight(); + Node r_right = machineContext.getReferenceNode(right); + + if (list.contains(r_left) + && isAConstantExpression(right, list, ignoreList)) { + right.apply(this); + ArrayList<PExpression> element = new ArrayList<PExpression>(); + element.add(right); + if (machineContext.getVariables().values().contains(r_left)) { + r_left = variablesHashTable.get(r_left); + } + putRestrictedType(r_left, new ASetExtensionExpression(element)); + removedNodes.add(n); + } + if (list.contains(r_right) + && isAConstantExpression(left, list, ignoreList)) { + left.apply(this); + ArrayList<PExpression> element = new ArrayList<PExpression>(); + element.add(left); + if (machineContext.getVariables().values().contains(r_right)) { + r_right = variablesHashTable.get(r_right); + } + putRestrictedType(r_right, new ASetExtensionExpression(element)); + removedNodes.add(n); + } + // detecting couples, e.g. (a,b) = (1,3) + // if (left instanceof ACoupleExpression) { + // ACoupleExpression couple = (ACoupleExpression) left; + // PExpression first = couple.getList().get(0); + // Node r_first = machineContext.getReferenceNode(first); + // PExpression second = couple.getList().get(0); + // Node r_second = machineContext.getReferenceNode(second); + // + // if (list.contains(r_first) && list.contains(r_second) + // && isAConstantExpression(right, list, ignoreList)) { + // ArrayList<PExpression> element = new ArrayList<PExpression>(); + // element.add(right); + // putRestrictedTypeOfTuple(r_right, + // new ASetExtensionExpression(element)); + // removedNodes.add(n); + // } + // } + + return; + } + + if (n instanceof AMemberPredicate) { + PExpression left = ((AMemberPredicate) n).getLeft(); + Node r_left = machineContext.getReferenceNode(left); + PExpression right = ((AMemberPredicate) n).getRight(); + if (list.contains(r_left) + && isAConstantExpression(right, list, ignoreList)) { + if (machineContext.getVariables().values().contains(r_left)) { + r_left = variablesHashTable.get(r_left); + } + putRestrictedType(r_left, right); + removedNodes.add(n); + } + return; + } + + if (n instanceof ANotMemberPredicate) { + PExpression left = ((ANotMemberPredicate) n).getLeft(); + Node r_left = machineContext.getReferenceNode(left); + PExpression right = ((ANotMemberPredicate) n).getRight(); + if (list.contains(r_left) + && isAConstantExpression(right, list, ignoreList)) { + if (machineContext.getVariables().values().contains(r_left)) { + r_left = variablesHashTable.get(r_left); + } + putSubstractedType(r_left, right); + removedNodes.add(n); + } + return; + } + + if (n instanceof ASubsetPredicate) { + PExpression left = ((ASubsetPredicate) n).getLeft(); + Node r_left = machineContext.getReferenceNode(left); + PExpression right = ((ASubsetPredicate) n).getRight(); + + if (list.contains(r_left) + && isAConstantExpression(right, list, ignoreList)) { + right.apply(this); + if (machineContext.getVariables().values().contains(r_left)) { + r_left = variablesHashTable.get(r_left); + } + putRestrictedType(r_left, new APowSubsetExpression(right)); + removedNodes.add(n); + } + return; + } + + if (n instanceof AConjunctPredicate) { + Node left = ((AConjunctPredicate) n).getLeft(); + Node right = ((AConjunctPredicate) n).getRight(); + analysePredicate(left, list, ignoreList); + analysePredicate(right, list, ignoreList); + if (removedNodes.contains(left) && removedNodes.contains(right)) { + removedNodes.add(n); + } + return; + } + + if (n instanceof AExistsPredicate) { + HashSet<Node> set = new HashSet<Node>(); + for (PExpression e : ((AExistsPredicate) n).getIdentifiers()) { + set.add(e); + } + set.addAll(ignoreList); + analysePredicate(((AExistsPredicate) n).getPredicate(), list, set); + } + + if (n instanceof Start) { + analysePredicate(((Start) n).getPParseUnit(), list, ignoreList); + } + + if (n instanceof APredicateParseUnit) { + analysePredicate(((APredicateParseUnit) n).getPredicate(), list, + ignoreList); + return; + } + } + + public boolean isAConstantExpression(Node node, HashSet<Node> list, + HashSet<Node> ignoreList) { + HashSet<Node> newList = new HashSet<Node>(); + newList.addAll(list); + newList.addAll(ignoreList); + if (identifierDependencies.containsIdentifier(node, newList)) { + return false; + } + return true; + } + + @Override + public void inAForallPredicate(AForallPredicate node) { + HashSet<Node> list = new HashSet<Node>(); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + list.add(e); + } + AImplicationPredicate implication = (AImplicationPredicate) node + .getImplication(); + analysePredicate(implication.getLeft(), list, new HashSet<Node>()); + createRestrictedTypeofLocalVariables( + new HashSet<PExpression>(node.getIdentifiers()), false); + } + + @Override + public void inAExistsPredicate(AExistsPredicate node) { + HashSet<Node> list = new HashSet<Node>(); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + list.add(e); + } + analysePredicate(node.getPredicate(), list, new HashSet<Node>()); + createRestrictedTypeofLocalVariables( + new HashSet<PExpression>(node.getIdentifiers()), false); + } + + @Override + public void inAQuantifiedUnionExpression(AQuantifiedUnionExpression node) { + HashSet<Node> list = new HashSet<Node>(); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + list.add(e); + } + analysePredicate(node.getPredicates(), list, new HashSet<Node>()); + createRestrictedTypeofLocalVariables( + new HashSet<PExpression>(node.getIdentifiers()), false); + } + + @Override + public void inAQuantifiedIntersectionExpression( + AQuantifiedIntersectionExpression node) { + HashSet<Node> list = new HashSet<Node>(); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + list.add(e); + } + analysePredicate(node.getPredicates(), list, new HashSet<Node>()); + createRestrictedTypeofLocalVariables( + new HashSet<PExpression>(node.getIdentifiers()), false); + } + + @Override + public void inAComprehensionSetExpression(AComprehensionSetExpression node) { + HashSet<Node> list = new HashSet<Node>(); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + list.add(e); + } + analysePredicate(node.getPredicates(), list, new HashSet<Node>()); + createRestrictedTypeofLocalVariables( + new HashSet<PExpression>(node.getIdentifiers()), false); + } + + @Override + public void inALambdaExpression(ALambdaExpression node) { + HashSet<Node> list = new HashSet<Node>(); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + list.add(e); + } + analysePredicate(node.getPredicate(), list, new HashSet<Node>()); + createRestrictedTypeofLocalVariables( + new HashSet<PExpression>(node.getIdentifiers()), false); + } + + public void inAGeneralSumExpression(AGeneralSumExpression node) { + HashSet<Node> list = new HashSet<Node>(); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + list.add(e); + } + analysePredicate(node.getPredicates(), list, new HashSet<Node>()); + createRestrictedTypeofLocalVariables( + new HashSet<PExpression>(node.getIdentifiers()), false); + } + + public void inAGeneralProductExpression(AGeneralProductExpression node) { + HashSet<Node> list = new HashSet<Node>(); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + list.add(e); + } + analysePredicate(node.getPredicates(), list, new HashSet<Node>()); + createRestrictedTypeofLocalVariables( + new HashSet<PExpression>(node.getIdentifiers()), false); + } + + private Hashtable<Node, HashSet<PExpression>> expectedIdentifieListTable = new Hashtable<Node, HashSet<PExpression>>(); + + @Override + public void caseAInitialisationMachineClause( + AInitialisationMachineClause node) { + expectedIdentifieListTable.put(node.getSubstitutions(), + new HashSet<PExpression>()); + node.getSubstitutions().apply(this); + } + + @Override + public void caseAOperation(AOperation node) { + HashSet<PExpression> list = new HashSet<PExpression>(); + { + List<PExpression> copy = new ArrayList<PExpression>( + node.getParameters()); + for (PExpression e : copy) { + list.add(e); + } + } + expectedIdentifieListTable.put(node.getOperationBody(), list); + if (node.getOperationBody() != null) { + node.getOperationBody().apply(this); + } + createRestrictedTypeofLocalVariables(list, false); + } + + @Override + public void inAPreconditionSubstitution(APreconditionSubstitution node) { + HashSet<Node> set = new HashSet<Node>(getExpectedIdentifier(node)); + analysePredicate(node.getPredicate(), set, new HashSet<Node>()); + } + + private HashSet<PExpression> getExpectedIdentifier(Node node) { + HashSet<PExpression> list = expectedIdentifieListTable.get(node); + if (list == null) + list = new HashSet<PExpression>(); + return list; + } + + @Override + public void inASelectSubstitution(ASelectSubstitution node) { + HashSet<Node> list = new HashSet<Node>(getExpectedIdentifier(node)); + analysePredicate(node.getCondition(), list, new HashSet<Node>()); + } + + @Override + public void inAAnySubstitution(AAnySubstitution node) { + HashSet<Node> list = new HashSet<Node>(); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + list.add(e); + } + list.addAll(getExpectedIdentifier(node)); + analysePredicate(node.getWhere(), list, new HashSet<Node>()); + createRestrictedTypeofLocalVariables( + new HashSet<PExpression>(node.getIdentifiers()), false); + } + + @Override + public void inALetSubstitution(ALetSubstitution node) { + HashSet<Node> list = new HashSet<Node>(); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + list.add(e); + } + list.addAll(getExpectedIdentifier(node)); + analysePredicate(node.getPredicate(), list, new HashSet<Node>()); + createRestrictedTypeofLocalVariables( + new HashSet<PExpression>(node.getIdentifiers()), false); + } + + private Hashtable<Node, Node> variablesHashTable; + + public void inABecomesSuchSubstitution(ABecomesSuchSubstitution node) { + if (!(node.getPredicate() instanceof AExistsPredicate)) { + variablesHashTable = new Hashtable<Node, Node>(); + + HashSet<Node> list = new HashSet<Node>(); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + Node ref = machineContext.getReferenceNode(e); + + list.add(ref); + variablesHashTable.put(ref, e); + } + analysePredicate(node.getPredicate(), list, new HashSet<Node>()); + createRestrictedTypeofLocalVariables( + new HashSet<PExpression>(copy), false); + } + } + + private void createRestrictedTypeofLocalVariables(Set<PExpression> copy, + boolean constant) { + // TODO if constant is true, only constant expressions should be used to + // restrict the type. + // This is required by the TLC model checker when checking an LTL + // formula. + + for (PExpression e : copy) { + if (constantsEvaluator.getValueOfIdentifierMap().containsKey(e)) { + continue; + } + + PExpression tree = null; + ArrayList<Node> restrictedList = restrictedNodeTable.get(e); + if (restrictedList == null) { + BType conType = typechecker.getType(e); + if (conType == null) { + conType = typechecker.getType(machineContext + .getReferenceNode(e)); + } + if (conType.containsInfiniteType() + && !(e.parent() instanceof ALambdaExpression) + && !(e.parent() instanceof AComprehensionSetExpression)) { + AIdentifierExpression id = (AIdentifierExpression) e; + String localVariableName = Utils.getTIdentifierListAsString(id + .getIdentifier()); + throw new NotSupportedException( + "Unable to restrict the type '" + + conType + + "' of identifier '" + + localVariableName + + "' to a finite set. TLC is not able to handle infinite sets.\n" + + UtilMethods.getPositionAsString(e)); + } + + tree = conType.createASTNode(typechecker); + } else { + tree = (PExpression) restrictedList.get(0); + for (int i = 1; i < restrictedList.size(); i++) { + PExpression n = (PExpression) restrictedList.get(i); + tree = new AIntersectionExpression(tree, n); + } + + } + ArrayList<Node> substractedList = subtractedNodeTable.get(e); + if (substractedList != null) { + for (int i = 0; i < substractedList.size(); i++) { + PExpression n = (PExpression) substractedList.get(i); + tree = new ASetSubtractionExpression(tree, n); + + } + } + this.restrictedTypeNodeTable.put(e, tree); + } + } + + @Override + public void caseAAssertionsMachineClause(AAssertionsMachineClause node) { + if (TLC4BGlobals.isAssertion()) { + List<PPredicate> copy = new ArrayList<PPredicate>( + node.getPredicates()); + for (PPredicate e : copy) { + e.apply(this); + } + } + } + + public void addRemoveNode(Node node) { + this.removedNodes.add(node); + } + +} diff --git a/src/main/java/de/tlc4b/analysis/unchangedvariables/AssignedVariablesFinder.java b/src/main/java/de/tlc4b/analysis/unchangedvariables/AssignedVariablesFinder.java index eb7a3a40950a4b7eeca71af60a0d64b75af8cdd1..0b82cc59b410404a46f2cd73b0904b46d86bdc58 100644 --- a/src/main/java/de/tlc4b/analysis/unchangedvariables/AssignedVariablesFinder.java +++ b/src/main/java/de/tlc4b/analysis/unchangedvariables/AssignedVariablesFinder.java @@ -1,293 +1,293 @@ -package de.tlc4b.analysis.unchangedvariables; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.List; - -import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; -import de.be4.classicalb.core.parser.node.AAssignSubstitution; -import de.be4.classicalb.core.parser.node.ABecomesElementOfSubstitution; -import de.be4.classicalb.core.parser.node.ABecomesSuchSubstitution; -import de.be4.classicalb.core.parser.node.ABlockSubstitution; -import de.be4.classicalb.core.parser.node.AChoiceOrSubstitution; -import de.be4.classicalb.core.parser.node.AChoiceSubstitution; -import de.be4.classicalb.core.parser.node.ADefinitionSubstitution; -import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause; -import de.be4.classicalb.core.parser.node.AFunctionExpression; -import de.be4.classicalb.core.parser.node.AIdentifierExpression; -import de.be4.classicalb.core.parser.node.AIfElsifSubstitution; -import de.be4.classicalb.core.parser.node.AIfSubstitution; -import de.be4.classicalb.core.parser.node.AInitialisationMachineClause; -import de.be4.classicalb.core.parser.node.AOperation; -import de.be4.classicalb.core.parser.node.AParallelSubstitution; -import de.be4.classicalb.core.parser.node.ASelectSubstitution; -import de.be4.classicalb.core.parser.node.ASelectWhenSubstitution; -import de.be4.classicalb.core.parser.node.ASkipSubstitution; -import de.be4.classicalb.core.parser.node.Node; -import de.be4.classicalb.core.parser.node.PDefinition; -import de.be4.classicalb.core.parser.node.PExpression; -import de.be4.classicalb.core.parser.node.PSubstitution; -import de.tlc4b.analysis.MachineContext; -import de.tlc4b.exceptions.SubstitutionException; - -/** - * - * This class is a tree walker which searches for all assigned variables in a - * branch of a operation body. The algorithm works in a bottom up style. The - * {@link assignedVariablesTable} will finally contain all assigned variables - * for a node. For example a {@link AParallelSubstitution} node will get a list - * of all assigned variables of its children. Operation output parameter are - * handled as variables. - * - */ - -public class AssignedVariablesFinder extends DepthFirstAdapter { - protected final Hashtable<Node, HashSet<Node>> assignedVariablesTable; - private final MachineContext machineContext; - - public AssignedVariablesFinder(MachineContext machineContext) { - this.assignedVariablesTable = new Hashtable<Node, HashSet<Node>>(); - this.machineContext = machineContext; - machineContext.getStartNode().apply(this); - - } - - protected Hashtable<Node, HashSet<Node>> getAssignedVariablesTable() { - return assignedVariablesTable; - } - - private HashSet<Node> getVariableList(Node node) { - return assignedVariablesTable.get(node); - } - - @Override - public void defaultOut(final Node node) { - /* - * This case is important if the parent node is not visited by the - * visitor. The assigned variables are transfered up in the tree. e.g. - * if the parent node is a block substitution, the assigned variables - * are transfered to parent of the block substitution - */ - HashSet<Node> assignedVariables = assignedVariablesTable.get(node); - if (null != assignedVariables) { - assignedVariablesTable.put(node.parent(), assignedVariables); - } - } - - @Override - public void caseABlockSubstitution(ABlockSubstitution node) { - inABlockSubstitution(node); - if (node.getSubstitution() != null) { - node.getSubstitution().apply(this); - } - outABlockSubstitution(node); - } - - @Override - public void caseAOperation(AOperation node) { - node.getOperationBody().apply(this); - assignedVariablesTable.put(node, - getVariableList(node.getOperationBody())); - } - - @Override - public void caseAInitialisationMachineClause( - AInitialisationMachineClause node) { - // first visit the sub node - node.getSubstitutions().apply(this); - assignedVariablesTable.put(node, - getVariableList(node.getSubstitutions())); - - /* - * In the INITIALISATION clause all variables must be assigned. - */ - HashSet<Node> allVariables = new HashSet<Node>(machineContext - .getVariables().values()); - HashSet<Node> foundVariables = new HashSet<Node>( - getVariableList(node.getSubstitutions())); - - if (allVariables.retainAll(foundVariables)) { - HashSet<Node> missingVariables = new HashSet<Node>(machineContext - .getVariables().values()); - missingVariables.removeAll(allVariables); - throw new SubstitutionException( - "Initialisation Error: Missing assignment for variable(s): " - + missingVariables); - } - - } - - @Override - public void caseABecomesSuchSubstitution(ABecomesSuchSubstitution node) { - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - HashSet<Node> list = new HashSet<Node>(); - for (PExpression e : copy) { - Node identifier = machineContext.getReferenceNode(e); - list.add(identifier); - } - assignedVariablesTable.put(node, list); - defaultOut(node); - } - - public void caseAAssignSubstitution(AAssignSubstitution node) { - List<PExpression> copy = new ArrayList<PExpression>( - node.getLhsExpression()); - HashSet<Node> list = new HashSet<Node>(); - for (PExpression e : copy) { - if (e instanceof AIdentifierExpression) { - Node identifier = machineContext.getReferenceNode(e); - list.add(identifier); - } else { - AFunctionExpression func = (AFunctionExpression) e; - Node identifier = machineContext.getReferenceNode( - func.getIdentifier()); - list.add(identifier); - } - } - assignedVariablesTable.put(node, list); - defaultOut(node); - } - - @Override - public void caseABecomesElementOfSubstitution( - ABecomesElementOfSubstitution node) { - - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - HashSet<Node> list = new HashSet<Node>(); - for (PExpression e : copy) { - Node identifier = machineContext.getReferenceNode(e); - list.add(identifier); - } - assignedVariablesTable.put(node, list); - defaultOut(node); - } - - @Override - public void caseAChoiceSubstitution(AChoiceSubstitution node) { - List<PSubstitution> copy = new ArrayList<PSubstitution>( - node.getSubstitutions()); - HashSet<Node> list = new HashSet<Node>(); - for (PSubstitution e : copy) { - e.apply(this); - list.addAll(getVariableList(e)); - } - assignedVariablesTable.put(node, list); - defaultOut(node); - } - - @Override - public void caseAChoiceOrSubstitution(AChoiceOrSubstitution node) { - node.getSubstitution().apply(this); - assignedVariablesTable.put(node, - getVariableList(node.getSubstitution())); - defaultOut(node); - } - - @Override - public void caseAIfSubstitution(AIfSubstitution node) { - HashSet<Node> list = new HashSet<Node>(); - node.getThen().apply(this); - list.addAll(getVariableList(node.getThen())); - - List<PSubstitution> copy = new ArrayList<PSubstitution>( - node.getElsifSubstitutions()); - for (PSubstitution e : copy) { - e.apply(this); - list.addAll(getVariableList(e)); - } - if (node.getElse() != null) { - node.getElse().apply(this); - list.addAll(getVariableList(node.getElse())); - } - - assignedVariablesTable.put(node, list); - defaultOut(node); - } - - @Override - public void caseAIfElsifSubstitution(AIfElsifSubstitution node) { - HashSet<Node> list = new HashSet<Node>(); - node.getThenSubstitution().apply(this); - list.addAll(getVariableList(node.getThenSubstitution())); - - assignedVariablesTable.put(node, list); - defaultOut(node); - } - - @Override - public void caseAParallelSubstitution(AParallelSubstitution node) { - List<PSubstitution> copy = new ArrayList<PSubstitution>( - node.getSubstitutions()); - for (PSubstitution e : copy) { - e.apply(this); - } - HashSet<Node> list = new HashSet<Node>(); - for (PSubstitution e : copy) { - HashSet<Node> listOfe = getVariableList(e); - HashSet<Node> temp = new HashSet<Node>(list); - temp.retainAll(listOfe); - if (temp.size() > 0) { - throw new SubstitutionException("The variable(s) " + temp - + " are assigned twice"); - } - list.addAll(listOfe); - } - assignedVariablesTable.put(node, list); - defaultOut(node); - } - - @Override - public void caseASelectSubstitution(ASelectSubstitution node) { - HashSet<Node> list = new HashSet<Node>(); - node.getThen().apply(this); - list.addAll(getVariableList(node.getThen())); - List<PSubstitution> copy = new ArrayList<PSubstitution>( - node.getWhenSubstitutions()); - for (PSubstitution e : copy) { - e.apply(this); - list.addAll(getVariableList(e)); - } - if (node.getElse() != null) { - node.getElse().apply(this); - list.addAll(getVariableList(node.getElse())); - } - assignedVariablesTable.put(node, list); - defaultOut(node); - } - - @Override - public void caseASelectWhenSubstitution(ASelectWhenSubstitution node) { - node.getSubstitution().apply(this); - assignedVariablesTable.put(node, - getVariableList(node.getSubstitution())); - assignedVariablesTable.put(node.parent(), - getVariableList(node.getSubstitution())); - } - - @Override - public void caseADefinitionsMachineClause(ADefinitionsMachineClause node) { - List<PDefinition> copy = new ArrayList<PDefinition>( - node.getDefinitions()); - for (PDefinition e : copy) { - e.apply(this); - } - } - - @Override - public void caseADefinitionSubstitution(ADefinitionSubstitution node) { - Node refNode = machineContext.getReferenceNode(node); - HashSet<Node> assignedVariables = assignedVariablesTable.get(refNode); - assignedVariablesTable.put(node, assignedVariables); - assignedVariablesTable.put(node.parent(), assignedVariables); - } - - @Override - public void caseASkipSubstitution(ASkipSubstitution node) { - HashSet<Node> list = new HashSet<Node>(); - assignedVariablesTable.put(node, list); - defaultOut(node); - } +package de.tlc4b.analysis.unchangedvariables; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.List; + +import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; +import de.be4.classicalb.core.parser.node.AAssignSubstitution; +import de.be4.classicalb.core.parser.node.ABecomesElementOfSubstitution; +import de.be4.classicalb.core.parser.node.ABecomesSuchSubstitution; +import de.be4.classicalb.core.parser.node.ABlockSubstitution; +import de.be4.classicalb.core.parser.node.AChoiceOrSubstitution; +import de.be4.classicalb.core.parser.node.AChoiceSubstitution; +import de.be4.classicalb.core.parser.node.ADefinitionSubstitution; +import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause; +import de.be4.classicalb.core.parser.node.AFunctionExpression; +import de.be4.classicalb.core.parser.node.AIdentifierExpression; +import de.be4.classicalb.core.parser.node.AIfElsifSubstitution; +import de.be4.classicalb.core.parser.node.AIfSubstitution; +import de.be4.classicalb.core.parser.node.AInitialisationMachineClause; +import de.be4.classicalb.core.parser.node.AOperation; +import de.be4.classicalb.core.parser.node.AParallelSubstitution; +import de.be4.classicalb.core.parser.node.ASelectSubstitution; +import de.be4.classicalb.core.parser.node.ASelectWhenSubstitution; +import de.be4.classicalb.core.parser.node.ASkipSubstitution; +import de.be4.classicalb.core.parser.node.Node; +import de.be4.classicalb.core.parser.node.PDefinition; +import de.be4.classicalb.core.parser.node.PExpression; +import de.be4.classicalb.core.parser.node.PSubstitution; +import de.tlc4b.analysis.MachineContext; +import de.tlc4b.exceptions.SubstitutionException; + +/** + * + * This class is a tree walker which searches for all assigned variables in a + * branch of a operation body. The algorithm works in a bottom up style. The + * {@link assignedVariablesTable} will finally contain all assigned variables + * for a node. For example a {@link AParallelSubstitution} node will get a list + * of all assigned variables of its children. Operation output parameter are + * handled as variables. + * + */ + +public class AssignedVariablesFinder extends DepthFirstAdapter { + protected final Hashtable<Node, HashSet<Node>> assignedVariablesTable; + private final MachineContext machineContext; + + public AssignedVariablesFinder(MachineContext machineContext) { + this.assignedVariablesTable = new Hashtable<Node, HashSet<Node>>(); + this.machineContext = machineContext; + machineContext.getStartNode().apply(this); + + } + + protected Hashtable<Node, HashSet<Node>> getAssignedVariablesTable() { + return assignedVariablesTable; + } + + private HashSet<Node> getVariableList(Node node) { + return assignedVariablesTable.get(node); + } + + @Override + public void defaultOut(final Node node) { + /* + * This case is important if the parent node is not visited by the + * visitor. The assigned variables are transfered up in the tree. e.g. + * if the parent node is a block substitution, the assigned variables + * are transfered to parent of the block substitution + */ + HashSet<Node> assignedVariables = assignedVariablesTable.get(node); + if (null != assignedVariables) { + assignedVariablesTable.put(node.parent(), assignedVariables); + } + } + + @Override + public void caseABlockSubstitution(ABlockSubstitution node) { + inABlockSubstitution(node); + if (node.getSubstitution() != null) { + node.getSubstitution().apply(this); + } + outABlockSubstitution(node); + } + + @Override + public void caseAOperation(AOperation node) { + node.getOperationBody().apply(this); + assignedVariablesTable.put(node, + getVariableList(node.getOperationBody())); + } + + @Override + public void caseAInitialisationMachineClause( + AInitialisationMachineClause node) { + // first visit the sub node + node.getSubstitutions().apply(this); + assignedVariablesTable.put(node, + getVariableList(node.getSubstitutions())); + + /* + * In the INITIALISATION clause all variables must be assigned. + */ + HashSet<Node> allVariables = new HashSet<Node>(machineContext + .getVariables().values()); + HashSet<Node> foundVariables = new HashSet<Node>( + getVariableList(node.getSubstitutions())); + + if (allVariables.retainAll(foundVariables)) { + HashSet<Node> missingVariables = new HashSet<Node>(machineContext + .getVariables().values()); + missingVariables.removeAll(allVariables); + throw new SubstitutionException( + "Initialisation Error: Missing assignment for variable(s): " + + missingVariables); + } + + } + + @Override + public void caseABecomesSuchSubstitution(ABecomesSuchSubstitution node) { + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + HashSet<Node> list = new HashSet<Node>(); + for (PExpression e : copy) { + Node identifier = machineContext.getReferenceNode(e); + list.add(identifier); + } + assignedVariablesTable.put(node, list); + defaultOut(node); + } + + public void caseAAssignSubstitution(AAssignSubstitution node) { + List<PExpression> copy = new ArrayList<PExpression>( + node.getLhsExpression()); + HashSet<Node> list = new HashSet<Node>(); + for (PExpression e : copy) { + if (e instanceof AIdentifierExpression) { + Node identifier = machineContext.getReferenceNode(e); + list.add(identifier); + } else { + AFunctionExpression func = (AFunctionExpression) e; + Node identifier = machineContext.getReferenceNode( + func.getIdentifier()); + list.add(identifier); + } + } + assignedVariablesTable.put(node, list); + defaultOut(node); + } + + @Override + public void caseABecomesElementOfSubstitution( + ABecomesElementOfSubstitution node) { + + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + HashSet<Node> list = new HashSet<Node>(); + for (PExpression e : copy) { + Node identifier = machineContext.getReferenceNode(e); + list.add(identifier); + } + assignedVariablesTable.put(node, list); + defaultOut(node); + } + + @Override + public void caseAChoiceSubstitution(AChoiceSubstitution node) { + List<PSubstitution> copy = new ArrayList<PSubstitution>( + node.getSubstitutions()); + HashSet<Node> list = new HashSet<Node>(); + for (PSubstitution e : copy) { + e.apply(this); + list.addAll(getVariableList(e)); + } + assignedVariablesTable.put(node, list); + defaultOut(node); + } + + @Override + public void caseAChoiceOrSubstitution(AChoiceOrSubstitution node) { + node.getSubstitution().apply(this); + assignedVariablesTable.put(node, + getVariableList(node.getSubstitution())); + defaultOut(node); + } + + @Override + public void caseAIfSubstitution(AIfSubstitution node) { + HashSet<Node> list = new HashSet<Node>(); + node.getThen().apply(this); + list.addAll(getVariableList(node.getThen())); + + List<PSubstitution> copy = new ArrayList<PSubstitution>( + node.getElsifSubstitutions()); + for (PSubstitution e : copy) { + e.apply(this); + list.addAll(getVariableList(e)); + } + if (node.getElse() != null) { + node.getElse().apply(this); + list.addAll(getVariableList(node.getElse())); + } + + assignedVariablesTable.put(node, list); + defaultOut(node); + } + + @Override + public void caseAIfElsifSubstitution(AIfElsifSubstitution node) { + HashSet<Node> list = new HashSet<Node>(); + node.getThenSubstitution().apply(this); + list.addAll(getVariableList(node.getThenSubstitution())); + + assignedVariablesTable.put(node, list); + defaultOut(node); + } + + @Override + public void caseAParallelSubstitution(AParallelSubstitution node) { + List<PSubstitution> copy = new ArrayList<PSubstitution>( + node.getSubstitutions()); + for (PSubstitution e : copy) { + e.apply(this); + } + HashSet<Node> list = new HashSet<Node>(); + for (PSubstitution e : copy) { + HashSet<Node> listOfe = getVariableList(e); + HashSet<Node> temp = new HashSet<Node>(list); + temp.retainAll(listOfe); + if (temp.size() > 0) { + throw new SubstitutionException("The variable(s) " + temp + + " are assigned twice"); + } + list.addAll(listOfe); + } + assignedVariablesTable.put(node, list); + defaultOut(node); + } + + @Override + public void caseASelectSubstitution(ASelectSubstitution node) { + HashSet<Node> list = new HashSet<Node>(); + node.getThen().apply(this); + list.addAll(getVariableList(node.getThen())); + List<PSubstitution> copy = new ArrayList<PSubstitution>( + node.getWhenSubstitutions()); + for (PSubstitution e : copy) { + e.apply(this); + list.addAll(getVariableList(e)); + } + if (node.getElse() != null) { + node.getElse().apply(this); + list.addAll(getVariableList(node.getElse())); + } + assignedVariablesTable.put(node, list); + defaultOut(node); + } + + @Override + public void caseASelectWhenSubstitution(ASelectWhenSubstitution node) { + node.getSubstitution().apply(this); + assignedVariablesTable.put(node, + getVariableList(node.getSubstitution())); + assignedVariablesTable.put(node.parent(), + getVariableList(node.getSubstitution())); + } + + @Override + public void caseADefinitionsMachineClause(ADefinitionsMachineClause node) { + List<PDefinition> copy = new ArrayList<PDefinition>( + node.getDefinitions()); + for (PDefinition e : copy) { + e.apply(this); + } + } + + @Override + public void caseADefinitionSubstitution(ADefinitionSubstitution node) { + Node refNode = machineContext.getReferenceNode(node); + HashSet<Node> assignedVariables = assignedVariablesTable.get(refNode); + assignedVariablesTable.put(node, assignedVariables); + assignedVariablesTable.put(node.parent(), assignedVariables); + } + + @Override + public void caseASkipSubstitution(ASkipSubstitution node) { + HashSet<Node> list = new HashSet<Node>(); + assignedVariablesTable.put(node, list); + defaultOut(node); + } } \ No newline at end of file diff --git a/src/main/java/de/tlc4b/analysis/unchangedvariables/UnchangedVariablesFinder.java b/src/main/java/de/tlc4b/analysis/unchangedvariables/UnchangedVariablesFinder.java index fe08cb904fe3567060755ad992bd19d0455f3860..d1d453ba1918e0babacc2631740cffc6e8e75c79 100644 --- a/src/main/java/de/tlc4b/analysis/unchangedvariables/UnchangedVariablesFinder.java +++ b/src/main/java/de/tlc4b/analysis/unchangedvariables/UnchangedVariablesFinder.java @@ -1,346 +1,346 @@ -package de.tlc4b.analysis.unchangedvariables; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Hashtable; -import java.util.List; - -import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; -import de.be4.classicalb.core.parser.node.AAnySubstitution; -import de.be4.classicalb.core.parser.node.AAssertionSubstitution; -import de.be4.classicalb.core.parser.node.AAssignSubstitution; -import de.be4.classicalb.core.parser.node.ABecomesElementOfSubstitution; -import de.be4.classicalb.core.parser.node.ABecomesSuchSubstitution; -import de.be4.classicalb.core.parser.node.ABlockSubstitution; -import de.be4.classicalb.core.parser.node.AChoiceOrSubstitution; -import de.be4.classicalb.core.parser.node.AChoiceSubstitution; -import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause; -import de.be4.classicalb.core.parser.node.AIfElsifSubstitution; -import de.be4.classicalb.core.parser.node.AIfSubstitution; -import de.be4.classicalb.core.parser.node.AInitialisationMachineClause; -import de.be4.classicalb.core.parser.node.ALetSubstitution; -import de.be4.classicalb.core.parser.node.AOperation; -import de.be4.classicalb.core.parser.node.AParallelSubstitution; -import de.be4.classicalb.core.parser.node.APreconditionSubstitution; -import de.be4.classicalb.core.parser.node.ASelectSubstitution; -import de.be4.classicalb.core.parser.node.ASelectWhenSubstitution; -import de.be4.classicalb.core.parser.node.ASkipSubstitution; -import de.be4.classicalb.core.parser.node.Node; -import de.be4.classicalb.core.parser.node.PExpression; -import de.be4.classicalb.core.parser.node.PSubstitution; -import de.tlc4b.analysis.MachineContext; -import de.tlc4b.exceptions.SubstitutionException; - -/** - * This class is a tree walker which calculates all missing variables - * assignments for each node inside a operation body. Missing variables - * assignments correspond to unchanged variables in TLA+. B definitions or the - * initialisation are not visited by this class. - */ - -public class UnchangedVariablesFinder extends DepthFirstAdapter { - private final MachineContext machineContext; - private final Hashtable<Node, HashSet<Node>> assignedIdentifiersTable; - - // this table contains a set of all variables which must be assigned in the - // node or in the sub nodes of the node - private final Hashtable<Node, HashSet<Node>> expectedVariablesTable; - private final Hashtable<Node, HashSet<Node>> expectedOutputParametersTable; - - private final Hashtable<Node, HashSet<Node>> unchangedVariablesTable; - - private final Hashtable<Node, HashSet<Node>> unchangedVariablesNull; - - public HashSet<Node> getUnchangedVariables(Node node) { - return unchangedVariablesTable.get(node); - } - - public HashSet<Node> getAssignedVariables(Node node){ - return assignedIdentifiersTable.get(node); - } - - public boolean hasUnchangedVariables(Node node){ - HashSet<Node> set = unchangedVariablesTable.get(node); - if(set== null){ - return false; - }else{ - if(set.size() == 0){ - return false; - }else - return true; - } - } - - public HashSet<Node> getUnchangedVariablesNull(Node node) { - return unchangedVariablesNull.get(node); - } - - public UnchangedVariablesFinder(MachineContext c) { - this.machineContext = c; - - AssignedVariablesFinder aVF = new AssignedVariablesFinder(c); - this.assignedIdentifiersTable = aVF.getAssignedVariablesTable(); - - this.expectedVariablesTable = new Hashtable<Node, HashSet<Node>>(); - this.expectedOutputParametersTable = new Hashtable<Node, HashSet<Node>>(); - - this.unchangedVariablesTable = new Hashtable<Node, HashSet<Node>>(); - this.unchangedVariablesNull = new Hashtable<Node, HashSet<Node>>(); - - c.getStartNode().apply(this); - } - - @Override - public void caseAInitialisationMachineClause( - AInitialisationMachineClause node) { - } - - @Override - public void caseADefinitionsMachineClause(ADefinitionsMachineClause node) { - } - - @Override - public void caseAOperation(AOperation node) { - HashSet<Node> expectedOutputParameter = new HashSet<Node>(); - List<PExpression> returnValues = new ArrayList<PExpression>( - node.getReturnValues()); - for (PExpression e : returnValues) { - expectedOutputParameter.add(e); - } - - Node body = node.getOperationBody(); - expectedOutputParametersTable.put(body, expectedOutputParameter); - expectedVariablesTable.put(body, new HashSet<Node>(machineContext - .getVariables().values())); - - body.apply(this); - - // missingVariablesTable.put(node, missingVariablesTable.get(body)); - } - - private void check(Node node) { - HashSet<Node> found = assignedIdentifiersTable.get(node); - HashSet<Node> missingVariables = new HashSet<Node>( - expectedVariablesTable.get(node)); - missingVariables.removeAll(found); - unchangedVariablesTable.put(node, missingVariables); - - HashSet<Node> missingOutputParameter = new HashSet<Node>( - expectedOutputParametersTable.get(node)); - missingOutputParameter.removeAll(found); - if (missingOutputParameter.size() > 0) { - throw new SubstitutionException( - "To the following output parameters no values are assigned: " - + missingOutputParameter); - } - } - - @Override - public void caseAAssignSubstitution(AAssignSubstitution node) { - check(node); - } - - @Override - public void caseABecomesSuchSubstitution(ABecomesSuchSubstitution node) { - check(node); - } - - @Override - public void caseABecomesElementOfSubstitution( - ABecomesElementOfSubstitution node) { - check(node); - } - - @Override - public void caseAParallelSubstitution(AParallelSubstitution node) { - check(node); - - List<PSubstitution> copy = new ArrayList<PSubstitution>( - node.getSubstitutions()); - for (PSubstitution e : copy) { - - expectedOutputParametersTable.put(e, new HashSet<Node>()); - expectedVariablesTable.put(e, new HashSet<Node>()); - e.apply(this); - } - } - - @Override - public void caseAAnySubstitution(AAnySubstitution node) { - check(node); - - expectedOutputParametersTable.put(node.getThen(), new HashSet<Node>()); - expectedVariablesTable.put(node.getThen(), new HashSet<Node>()); - node.getThen().apply(this); - } - - @Override - public void caseALetSubstitution(ALetSubstitution node) { - check(node); - - expectedOutputParametersTable.put(node.getSubstitution(), - new HashSet<Node>()); - expectedVariablesTable.put(node.getSubstitution(), new HashSet<Node>()); - node.getSubstitution().apply(this); - } - - @Override - public void caseAChoiceSubstitution(AChoiceSubstitution node) { - check(node); - - // Separating variables and output parameters - HashSet<Node> foundIdentifiers = assignedIdentifiersTable.get(node); - HashSet<Node> variables = new HashSet<Node>(foundIdentifiers); - variables.removeAll(expectedOutputParametersTable.get(node)); - - // System.out.println(parameters); - - List<PSubstitution> copy = new ArrayList<PSubstitution>( - node.getSubstitutions()); - for (PSubstitution e : copy) { - // each child of CHOICE must assign all variables and all output - // parameter - expectedOutputParametersTable.put(e, - expectedOutputParametersTable.get(node)); - expectedVariablesTable.put(e, variables); - e.apply(this); - } - } - - @Override - public void caseAChoiceOrSubstitution(AChoiceOrSubstitution node) { - Node sub = node.getSubstitution(); - expectedOutputParametersTable.put(sub, - expectedOutputParametersTable.get(node)); - expectedVariablesTable.put(sub, expectedVariablesTable.get(node)); - - sub.apply(this); - - unchangedVariablesTable.put(node, unchangedVariablesTable.get(sub)); - - } - - @Override - public void caseAIfSubstitution(AIfSubstitution node) { - check(node); - // Separating variables and output parameters - HashSet<Node> foundIdentifiers = assignedIdentifiersTable.get(node); - HashSet<Node> foundVariables = new HashSet<Node>(foundIdentifiers); - foundVariables.removeAll(expectedOutputParametersTable.get(node)); - - expectedOutputParametersTable.put(node.getThen(), - expectedOutputParametersTable.get(node)); - expectedVariablesTable.put(node.getThen(), foundVariables); - node.getThen().apply(this); - - List<PSubstitution> copy = new ArrayList<PSubstitution>( - node.getElsifSubstitutions()); - for (PSubstitution e : copy) { - expectedOutputParametersTable.put(e, - expectedOutputParametersTable.get(node)); - expectedVariablesTable.put(e, foundVariables); - e.apply(this); - } - - if (node.getElse() != null) { - expectedOutputParametersTable.put(node.getElse(), - expectedOutputParametersTable.get(node)); - expectedVariablesTable.put(node.getElse(), foundVariables); - node.getElse().apply(this); - } else { - unchangedVariablesNull.put(node, - assignedIdentifiersTable.get(node.getThen())); - } - - } - - @Override - public void caseAIfElsifSubstitution(AIfElsifSubstitution node) { - expectedOutputParametersTable.put(node.getThenSubstitution(), - expectedOutputParametersTable.get(node)); - expectedVariablesTable.put(node.getThenSubstitution(), - expectedVariablesTable.get(node)); - node.getThenSubstitution().apply(this); - } - - @Override - public void caseAPreconditionSubstitution(APreconditionSubstitution node) { - // check(node); - // - // // Separating variables and output parameters - // HashSet<Node> foundIdentifiers = assignedIdentifiersTable.get(node); - // System.out.println(foundIdentifiers); - // HashSet<Node> foundVariables = new HashSet<Node>(foundIdentifiers); - // foundVariables.removeAll(expectedOutputParametersTable.get(node)); - - expectedOutputParametersTable.put(node.getSubstitution(), - expectedOutputParametersTable.get(node)); - expectedVariablesTable.put(node.getSubstitution(), - expectedVariablesTable.get(node)); - node.getSubstitution().apply(this); - } - - @Override - public void caseAAssertionSubstitution(AAssertionSubstitution node) { - expectedOutputParametersTable.put(node.getSubstitution(), - expectedOutputParametersTable.get(node)); - expectedVariablesTable.put(node.getSubstitution(), - expectedVariablesTable.get(node)); - node.getSubstitution().apply(this); - } - - @Override - public void caseABlockSubstitution(ABlockSubstitution node) { - expectedOutputParametersTable.put(node.getSubstitution(), - expectedOutputParametersTable.get(node)); - expectedVariablesTable.put(node.getSubstitution(), - expectedVariablesTable.get(node)); - node.getSubstitution().apply(this); - } - - @Override - public void caseASelectSubstitution(ASelectSubstitution node) { - check(node); - // Separating variables and output parameters - HashSet<Node> foundIdentifiers = assignedIdentifiersTable.get(node); - HashSet<Node> variables = new HashSet<Node>(foundIdentifiers); - variables.removeAll(expectedOutputParametersTable.get(node)); - - expectedOutputParametersTable.put(node.getThen(), - expectedOutputParametersTable.get(node)); - expectedVariablesTable.put(node.getThen(), variables); - node.getThen().apply(this); - { - List<PSubstitution> copy = new ArrayList<PSubstitution>( - node.getWhenSubstitutions()); - for (PSubstitution e : copy) { - expectedOutputParametersTable.put(e, - expectedOutputParametersTable.get(node)); - expectedVariablesTable.put(e, variables); - e.apply(this); - } - } - - if (node.getElse() != null) { - expectedOutputParametersTable.put(node.getElse(), - expectedOutputParametersTable.get(node)); - expectedVariablesTable.put(node.getElse(), variables); - node.getElse().apply(this); - } - } - - @Override - public void caseASelectWhenSubstitution(ASelectWhenSubstitution node) { - check(node); - expectedOutputParametersTable.put(node.getSubstitution(), - expectedOutputParametersTable.get(node)); - expectedVariablesTable.put(node.getSubstitution(), - expectedVariablesTable.get(node)); - node.getSubstitution().apply(this); - } - - @Override - public void caseASkipSubstitution(ASkipSubstitution node) { - check(node); - } -} +package de.tlc4b.analysis.unchangedvariables; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.List; + +import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; +import de.be4.classicalb.core.parser.node.AAnySubstitution; +import de.be4.classicalb.core.parser.node.AAssertionSubstitution; +import de.be4.classicalb.core.parser.node.AAssignSubstitution; +import de.be4.classicalb.core.parser.node.ABecomesElementOfSubstitution; +import de.be4.classicalb.core.parser.node.ABecomesSuchSubstitution; +import de.be4.classicalb.core.parser.node.ABlockSubstitution; +import de.be4.classicalb.core.parser.node.AChoiceOrSubstitution; +import de.be4.classicalb.core.parser.node.AChoiceSubstitution; +import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause; +import de.be4.classicalb.core.parser.node.AIfElsifSubstitution; +import de.be4.classicalb.core.parser.node.AIfSubstitution; +import de.be4.classicalb.core.parser.node.AInitialisationMachineClause; +import de.be4.classicalb.core.parser.node.ALetSubstitution; +import de.be4.classicalb.core.parser.node.AOperation; +import de.be4.classicalb.core.parser.node.AParallelSubstitution; +import de.be4.classicalb.core.parser.node.APreconditionSubstitution; +import de.be4.classicalb.core.parser.node.ASelectSubstitution; +import de.be4.classicalb.core.parser.node.ASelectWhenSubstitution; +import de.be4.classicalb.core.parser.node.ASkipSubstitution; +import de.be4.classicalb.core.parser.node.Node; +import de.be4.classicalb.core.parser.node.PExpression; +import de.be4.classicalb.core.parser.node.PSubstitution; +import de.tlc4b.analysis.MachineContext; +import de.tlc4b.exceptions.SubstitutionException; + +/** + * This class is a tree walker which calculates all missing variables + * assignments for each node inside a operation body. Missing variables + * assignments correspond to unchanged variables in TLA+. B definitions or the + * initialisation are not visited by this class. + */ + +public class UnchangedVariablesFinder extends DepthFirstAdapter { + private final MachineContext machineContext; + private final Hashtable<Node, HashSet<Node>> assignedIdentifiersTable; + + // this table contains a set of all variables which must be assigned in the + // node or in the sub nodes of the node + private final Hashtable<Node, HashSet<Node>> expectedVariablesTable; + private final Hashtable<Node, HashSet<Node>> expectedOutputParametersTable; + + private final Hashtable<Node, HashSet<Node>> unchangedVariablesTable; + + private final Hashtable<Node, HashSet<Node>> unchangedVariablesNull; + + public HashSet<Node> getUnchangedVariables(Node node) { + return unchangedVariablesTable.get(node); + } + + public HashSet<Node> getAssignedVariables(Node node){ + return assignedIdentifiersTable.get(node); + } + + public boolean hasUnchangedVariables(Node node){ + HashSet<Node> set = unchangedVariablesTable.get(node); + if(set== null){ + return false; + }else{ + if(set.size() == 0){ + return false; + }else + return true; + } + } + + public HashSet<Node> getUnchangedVariablesNull(Node node) { + return unchangedVariablesNull.get(node); + } + + public UnchangedVariablesFinder(MachineContext c) { + this.machineContext = c; + + AssignedVariablesFinder aVF = new AssignedVariablesFinder(c); + this.assignedIdentifiersTable = aVF.getAssignedVariablesTable(); + + this.expectedVariablesTable = new Hashtable<Node, HashSet<Node>>(); + this.expectedOutputParametersTable = new Hashtable<Node, HashSet<Node>>(); + + this.unchangedVariablesTable = new Hashtable<Node, HashSet<Node>>(); + this.unchangedVariablesNull = new Hashtable<Node, HashSet<Node>>(); + + c.getStartNode().apply(this); + } + + @Override + public void caseAInitialisationMachineClause( + AInitialisationMachineClause node) { + } + + @Override + public void caseADefinitionsMachineClause(ADefinitionsMachineClause node) { + } + + @Override + public void caseAOperation(AOperation node) { + HashSet<Node> expectedOutputParameter = new HashSet<Node>(); + List<PExpression> returnValues = new ArrayList<PExpression>( + node.getReturnValues()); + for (PExpression e : returnValues) { + expectedOutputParameter.add(e); + } + + Node body = node.getOperationBody(); + expectedOutputParametersTable.put(body, expectedOutputParameter); + expectedVariablesTable.put(body, new HashSet<Node>(machineContext + .getVariables().values())); + + body.apply(this); + + // missingVariablesTable.put(node, missingVariablesTable.get(body)); + } + + private void check(Node node) { + HashSet<Node> found = assignedIdentifiersTable.get(node); + HashSet<Node> missingVariables = new HashSet<Node>( + expectedVariablesTable.get(node)); + missingVariables.removeAll(found); + unchangedVariablesTable.put(node, missingVariables); + + HashSet<Node> missingOutputParameter = new HashSet<Node>( + expectedOutputParametersTable.get(node)); + missingOutputParameter.removeAll(found); + if (missingOutputParameter.size() > 0) { + throw new SubstitutionException( + "To the following output parameters no values are assigned: " + + missingOutputParameter); + } + } + + @Override + public void caseAAssignSubstitution(AAssignSubstitution node) { + check(node); + } + + @Override + public void caseABecomesSuchSubstitution(ABecomesSuchSubstitution node) { + check(node); + } + + @Override + public void caseABecomesElementOfSubstitution( + ABecomesElementOfSubstitution node) { + check(node); + } + + @Override + public void caseAParallelSubstitution(AParallelSubstitution node) { + check(node); + + List<PSubstitution> copy = new ArrayList<PSubstitution>( + node.getSubstitutions()); + for (PSubstitution e : copy) { + + expectedOutputParametersTable.put(e, new HashSet<Node>()); + expectedVariablesTable.put(e, new HashSet<Node>()); + e.apply(this); + } + } + + @Override + public void caseAAnySubstitution(AAnySubstitution node) { + check(node); + + expectedOutputParametersTable.put(node.getThen(), new HashSet<Node>()); + expectedVariablesTable.put(node.getThen(), new HashSet<Node>()); + node.getThen().apply(this); + } + + @Override + public void caseALetSubstitution(ALetSubstitution node) { + check(node); + + expectedOutputParametersTable.put(node.getSubstitution(), + new HashSet<Node>()); + expectedVariablesTable.put(node.getSubstitution(), new HashSet<Node>()); + node.getSubstitution().apply(this); + } + + @Override + public void caseAChoiceSubstitution(AChoiceSubstitution node) { + check(node); + + // Separating variables and output parameters + HashSet<Node> foundIdentifiers = assignedIdentifiersTable.get(node); + HashSet<Node> variables = new HashSet<Node>(foundIdentifiers); + variables.removeAll(expectedOutputParametersTable.get(node)); + + // System.out.println(parameters); + + List<PSubstitution> copy = new ArrayList<PSubstitution>( + node.getSubstitutions()); + for (PSubstitution e : copy) { + // each child of CHOICE must assign all variables and all output + // parameter + expectedOutputParametersTable.put(e, + expectedOutputParametersTable.get(node)); + expectedVariablesTable.put(e, variables); + e.apply(this); + } + } + + @Override + public void caseAChoiceOrSubstitution(AChoiceOrSubstitution node) { + Node sub = node.getSubstitution(); + expectedOutputParametersTable.put(sub, + expectedOutputParametersTable.get(node)); + expectedVariablesTable.put(sub, expectedVariablesTable.get(node)); + + sub.apply(this); + + unchangedVariablesTable.put(node, unchangedVariablesTable.get(sub)); + + } + + @Override + public void caseAIfSubstitution(AIfSubstitution node) { + check(node); + // Separating variables and output parameters + HashSet<Node> foundIdentifiers = assignedIdentifiersTable.get(node); + HashSet<Node> foundVariables = new HashSet<Node>(foundIdentifiers); + foundVariables.removeAll(expectedOutputParametersTable.get(node)); + + expectedOutputParametersTable.put(node.getThen(), + expectedOutputParametersTable.get(node)); + expectedVariablesTable.put(node.getThen(), foundVariables); + node.getThen().apply(this); + + List<PSubstitution> copy = new ArrayList<PSubstitution>( + node.getElsifSubstitutions()); + for (PSubstitution e : copy) { + expectedOutputParametersTable.put(e, + expectedOutputParametersTable.get(node)); + expectedVariablesTable.put(e, foundVariables); + e.apply(this); + } + + if (node.getElse() != null) { + expectedOutputParametersTable.put(node.getElse(), + expectedOutputParametersTable.get(node)); + expectedVariablesTable.put(node.getElse(), foundVariables); + node.getElse().apply(this); + } else { + unchangedVariablesNull.put(node, + assignedIdentifiersTable.get(node.getThen())); + } + + } + + @Override + public void caseAIfElsifSubstitution(AIfElsifSubstitution node) { + expectedOutputParametersTable.put(node.getThenSubstitution(), + expectedOutputParametersTable.get(node)); + expectedVariablesTable.put(node.getThenSubstitution(), + expectedVariablesTable.get(node)); + node.getThenSubstitution().apply(this); + } + + @Override + public void caseAPreconditionSubstitution(APreconditionSubstitution node) { + // check(node); + // + // // Separating variables and output parameters + // HashSet<Node> foundIdentifiers = assignedIdentifiersTable.get(node); + // System.out.println(foundIdentifiers); + // HashSet<Node> foundVariables = new HashSet<Node>(foundIdentifiers); + // foundVariables.removeAll(expectedOutputParametersTable.get(node)); + + expectedOutputParametersTable.put(node.getSubstitution(), + expectedOutputParametersTable.get(node)); + expectedVariablesTable.put(node.getSubstitution(), + expectedVariablesTable.get(node)); + node.getSubstitution().apply(this); + } + + @Override + public void caseAAssertionSubstitution(AAssertionSubstitution node) { + expectedOutputParametersTable.put(node.getSubstitution(), + expectedOutputParametersTable.get(node)); + expectedVariablesTable.put(node.getSubstitution(), + expectedVariablesTable.get(node)); + node.getSubstitution().apply(this); + } + + @Override + public void caseABlockSubstitution(ABlockSubstitution node) { + expectedOutputParametersTable.put(node.getSubstitution(), + expectedOutputParametersTable.get(node)); + expectedVariablesTable.put(node.getSubstitution(), + expectedVariablesTable.get(node)); + node.getSubstitution().apply(this); + } + + @Override + public void caseASelectSubstitution(ASelectSubstitution node) { + check(node); + // Separating variables and output parameters + HashSet<Node> foundIdentifiers = assignedIdentifiersTable.get(node); + HashSet<Node> variables = new HashSet<Node>(foundIdentifiers); + variables.removeAll(expectedOutputParametersTable.get(node)); + + expectedOutputParametersTable.put(node.getThen(), + expectedOutputParametersTable.get(node)); + expectedVariablesTable.put(node.getThen(), variables); + node.getThen().apply(this); + { + List<PSubstitution> copy = new ArrayList<PSubstitution>( + node.getWhenSubstitutions()); + for (PSubstitution e : copy) { + expectedOutputParametersTable.put(e, + expectedOutputParametersTable.get(node)); + expectedVariablesTable.put(e, variables); + e.apply(this); + } + } + + if (node.getElse() != null) { + expectedOutputParametersTable.put(node.getElse(), + expectedOutputParametersTable.get(node)); + expectedVariablesTable.put(node.getElse(), variables); + node.getElse().apply(this); + } + } + + @Override + public void caseASelectWhenSubstitution(ASelectWhenSubstitution node) { + check(node); + expectedOutputParametersTable.put(node.getSubstitution(), + expectedOutputParametersTable.get(node)); + expectedVariablesTable.put(node.getSubstitution(), + expectedVariablesTable.get(node)); + node.getSubstitution().apply(this); + } + + @Override + public void caseASkipSubstitution(ASkipSubstitution node) { + check(node); + } +} diff --git a/src/main/java/de/tlc4b/btypes/AbstractHasFollowers.java b/src/main/java/de/tlc4b/btypes/AbstractHasFollowers.java index 868598c0021f6e5698a63fe41249d37a10c11227..f13dc8c8869251ddf92c85a6bb91469317f9e5fd 100644 --- a/src/main/java/de/tlc4b/btypes/AbstractHasFollowers.java +++ b/src/main/java/de/tlc4b/btypes/AbstractHasFollowers.java @@ -1,67 +1,67 @@ -package de.tlc4b.btypes; - -import java.util.ArrayList; - -import de.be4.classicalb.core.parser.node.Node; - -public abstract class AbstractHasFollowers implements BType { - - public abstract boolean contains(BType other); - - private ArrayList<Object> followers = new ArrayList<Object>(); - - public ArrayList<Object> getFollowers() { - return this.followers; - } - - public void addFollower(Object obj) { - if (!followers.contains(obj)) - followers.add(obj); - } - - public String printFollower() { - StringBuffer res = new StringBuffer(); - res.append("["); - for (Object o : followers) { - if (!(o instanceof Node)) { - res.append(o.hashCode()); - res.append(o.getClass()); - res.append(" "); - } - } - res.append("]"); - return res.toString(); - } - - public void deleteFollower(Object obj) { - followers.remove(obj); - } - - public void setFollowersTo(BType newType, ITypechecker typechecker) { - if (this == newType) { - return; - } - ArrayList<Object> list = new ArrayList<Object>(followers); - for (Object obj : list) { - if (obj instanceof Node) { - typechecker.setType((Node) obj, newType); - } else if (obj instanceof SetType) { - ((SetType) obj).setSubtype(newType); - } else if (obj instanceof IntegerOrSetOfPairType) { - // System.out.println("this " +this + " old " + obj + " new " + - // newType); - ((IntegerOrSetOfPairType) obj).update(this, newType, typechecker); - } else if (obj instanceof PairType) { - ((PairType) obj).update(this, newType); - } else if (obj instanceof FunctionType) { - ((FunctionType) obj).update(this, newType); - } else if (obj instanceof StructType) { - ((StructType) obj).update(this, newType); - } else { - throw new RuntimeException("Missing follower type: " + obj.getClass()); - } - } - this.followers.clear(); - - } -} +package de.tlc4b.btypes; + +import java.util.ArrayList; + +import de.be4.classicalb.core.parser.node.Node; + +public abstract class AbstractHasFollowers implements BType { + + public abstract boolean contains(BType other); + + private ArrayList<Object> followers = new ArrayList<Object>(); + + public ArrayList<Object> getFollowers() { + return this.followers; + } + + public void addFollower(Object obj) { + if (!followers.contains(obj)) + followers.add(obj); + } + + public String printFollower() { + StringBuffer res = new StringBuffer(); + res.append("["); + for (Object o : followers) { + if (!(o instanceof Node)) { + res.append(o.hashCode()); + res.append(o.getClass()); + res.append(" "); + } + } + res.append("]"); + return res.toString(); + } + + public void deleteFollower(Object obj) { + followers.remove(obj); + } + + public void setFollowersTo(BType newType, ITypechecker typechecker) { + if (this == newType) { + return; + } + ArrayList<Object> list = new ArrayList<Object>(followers); + for (Object obj : list) { + if (obj instanceof Node) { + typechecker.setType((Node) obj, newType); + } else if (obj instanceof SetType) { + ((SetType) obj).setSubtype(newType); + } else if (obj instanceof IntegerOrSetOfPairType) { + // System.out.println("this " +this + " old " + obj + " new " + + // newType); + ((IntegerOrSetOfPairType) obj).update(this, newType, typechecker); + } else if (obj instanceof PairType) { + ((PairType) obj).update(this, newType); + } else if (obj instanceof FunctionType) { + ((FunctionType) obj).update(this, newType); + } else if (obj instanceof StructType) { + ((StructType) obj).update(this, newType); + } else { + throw new RuntimeException("Missing follower type: " + obj.getClass()); + } + } + this.followers.clear(); + + } +} diff --git a/src/main/java/de/tlc4b/btypes/BType.java b/src/main/java/de/tlc4b/btypes/BType.java index b90b379def0affef19c9d9292e50f26ff792a954..552e540fc4af31c017221530228b90240c834c14 100644 --- a/src/main/java/de/tlc4b/btypes/BType.java +++ b/src/main/java/de/tlc4b/btypes/BType.java @@ -1,12 +1,12 @@ -package de.tlc4b.btypes; - -import de.be4.classicalb.core.parser.node.PExpression; -import de.tlc4b.analysis.Typechecker; - -public interface BType { - public BType unify(BType other, ITypechecker typechecker); - public boolean isUntyped(); - public boolean compare(BType other); - public boolean containsInfiniteType(); - public PExpression createASTNode(Typechecker typechecker); -} +package de.tlc4b.btypes; + +import de.be4.classicalb.core.parser.node.PExpression; +import de.tlc4b.analysis.Typechecker; + +public interface BType { + public BType unify(BType other, ITypechecker typechecker); + public boolean isUntyped(); + public boolean compare(BType other); + public boolean containsInfiniteType(); + public PExpression createASTNode(Typechecker typechecker); +} diff --git a/src/main/java/de/tlc4b/btypes/BoolType.java b/src/main/java/de/tlc4b/btypes/BoolType.java index e2937dd21edcc337e4291864282c59b2f141afdd..5d06ed9adfab70f8c039f8d2436218986c9cdc7b 100644 --- a/src/main/java/de/tlc4b/btypes/BoolType.java +++ b/src/main/java/de/tlc4b/btypes/BoolType.java @@ -1,56 +1,56 @@ -package de.tlc4b.btypes; - -import de.be4.classicalb.core.parser.node.ABoolSetExpression; -import de.be4.classicalb.core.parser.node.PExpression; -import de.tlc4b.analysis.Typechecker; -import de.tlc4b.exceptions.UnificationException; - -public class BoolType implements BType { - - private static BoolType instance = new BoolType(); - - public static BoolType getInstance() { - return instance; - } - - public BType unify(BType other, ITypechecker typechecker) { - if(!this.compare(other)) - throw new UnificationException(); - - if (other instanceof BoolType) { - return this; - } - if (other instanceof UntypedType) { - ((UntypedType) other).setFollowersTo(this, typechecker); - return this; - } - throw new UnificationException(); - } - - @Override - public String toString() { - return "BOOL"; - } - - public boolean isUntyped() { - return false; - } - - public boolean compare(BType other) { - if (other instanceof UntypedType || other instanceof BoolType) - return true; - else - return false; - } - - public boolean containsInfiniteType() { - return false; - } - - public PExpression createASTNode(Typechecker typechecker) { - ABoolSetExpression node = new ABoolSetExpression(); - typechecker.setType(node, new SetType(this)); - return node; - } - -} +package de.tlc4b.btypes; + +import de.be4.classicalb.core.parser.node.ABoolSetExpression; +import de.be4.classicalb.core.parser.node.PExpression; +import de.tlc4b.analysis.Typechecker; +import de.tlc4b.exceptions.UnificationException; + +public class BoolType implements BType { + + private static BoolType instance = new BoolType(); + + public static BoolType getInstance() { + return instance; + } + + public BType unify(BType other, ITypechecker typechecker) { + if(!this.compare(other)) + throw new UnificationException(); + + if (other instanceof BoolType) { + return this; + } + if (other instanceof UntypedType) { + ((UntypedType) other).setFollowersTo(this, typechecker); + return this; + } + throw new UnificationException(); + } + + @Override + public String toString() { + return "BOOL"; + } + + public boolean isUntyped() { + return false; + } + + public boolean compare(BType other) { + if (other instanceof UntypedType || other instanceof BoolType) + return true; + else + return false; + } + + public boolean containsInfiniteType() { + return false; + } + + public PExpression createASTNode(Typechecker typechecker) { + ABoolSetExpression node = new ABoolSetExpression(); + typechecker.setType(node, new SetType(this)); + return node; + } + +} diff --git a/src/main/java/de/tlc4b/btypes/EnumeratedSetElement.java b/src/main/java/de/tlc4b/btypes/EnumeratedSetElement.java index 41728d814aca42662b85218cc336c75ed9051ab6..dd3d0dd55208d516f197c4c9b4d3ec45553b1889 100644 --- a/src/main/java/de/tlc4b/btypes/EnumeratedSetElement.java +++ b/src/main/java/de/tlc4b/btypes/EnumeratedSetElement.java @@ -1,72 +1,72 @@ -package de.tlc4b.btypes; - -import java.util.ArrayList; - -import de.be4.classicalb.core.parser.node.AIdentifierExpression; -import de.be4.classicalb.core.parser.node.PExpression; -import de.be4.classicalb.core.parser.node.TIdentifierLiteral; -import de.tlc4b.analysis.Typechecker; -import de.tlc4b.exceptions.UnificationException; - -public class EnumeratedSetElement implements BType { - private String name; - - public EnumeratedSetElement(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public BType unify(BType other, ITypechecker typechecker) { - if (!this.compare(other)) { - throw new UnificationException(); - } - if (other instanceof EnumeratedSetElement) { - if (((EnumeratedSetElement) other).getName().equals(this.name)) { - return this; - } else { - throw new UnificationException(); - } - - } else if (other instanceof UntypedType) { - ((UntypedType) other).setFollowersTo(this, typechecker); - return this; - } - throw new RuntimeException(); - } - - public boolean isUntyped() { - return false; - } - - @Override - public String toString() { - return name; - } - - public boolean compare(BType other) { - if (other instanceof UntypedType) - return true; - if (other instanceof EnumeratedSetElement) { - if (((EnumeratedSetElement) other).getName().equals(this.name)) { - return true; - } - } - return false; - } - - public boolean containsInfiniteType() { - return false; - } - - public PExpression createASTNode(Typechecker typechecker) { - TIdentifierLiteral literal = new TIdentifierLiteral(name); - ArrayList<TIdentifierLiteral> idList = new ArrayList<TIdentifierLiteral>(); - idList.add(literal); - AIdentifierExpression id = new AIdentifierExpression(idList); - typechecker.setType(id, new SetType(this)); - return id; - } -} +package de.tlc4b.btypes; + +import java.util.ArrayList; + +import de.be4.classicalb.core.parser.node.AIdentifierExpression; +import de.be4.classicalb.core.parser.node.PExpression; +import de.be4.classicalb.core.parser.node.TIdentifierLiteral; +import de.tlc4b.analysis.Typechecker; +import de.tlc4b.exceptions.UnificationException; + +public class EnumeratedSetElement implements BType { + private String name; + + public EnumeratedSetElement(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public BType unify(BType other, ITypechecker typechecker) { + if (!this.compare(other)) { + throw new UnificationException(); + } + if (other instanceof EnumeratedSetElement) { + if (((EnumeratedSetElement) other).getName().equals(this.name)) { + return this; + } else { + throw new UnificationException(); + } + + } else if (other instanceof UntypedType) { + ((UntypedType) other).setFollowersTo(this, typechecker); + return this; + } + throw new RuntimeException(); + } + + public boolean isUntyped() { + return false; + } + + @Override + public String toString() { + return name; + } + + public boolean compare(BType other) { + if (other instanceof UntypedType) + return true; + if (other instanceof EnumeratedSetElement) { + if (((EnumeratedSetElement) other).getName().equals(this.name)) { + return true; + } + } + return false; + } + + public boolean containsInfiniteType() { + return false; + } + + public PExpression createASTNode(Typechecker typechecker) { + TIdentifierLiteral literal = new TIdentifierLiteral(name); + ArrayList<TIdentifierLiteral> idList = new ArrayList<TIdentifierLiteral>(); + idList.add(literal); + AIdentifierExpression id = new AIdentifierExpression(idList); + typechecker.setType(id, new SetType(this)); + return id; + } +} diff --git a/src/main/java/de/tlc4b/btypes/FunctionType.java b/src/main/java/de/tlc4b/btypes/FunctionType.java index 5687f1b866010fe55c81381951f806eab4bb014e..c38fe6f57989e0b592bbd27fbd2867b8afcf5b57 100644 --- a/src/main/java/de/tlc4b/btypes/FunctionType.java +++ b/src/main/java/de/tlc4b/btypes/FunctionType.java @@ -1,139 +1,139 @@ -package de.tlc4b.btypes; - -import de.be4.classicalb.core.parser.node.APartialFunctionExpression; -import de.be4.classicalb.core.parser.node.PExpression; -import de.tlc4b.analysis.Typechecker; -import de.tlc4b.exceptions.UnificationException; - -public class FunctionType extends AbstractHasFollowers { - private BType domain; - private BType range; - - public FunctionType(BType domain, BType range) { - setDomain(domain); - setRange(range); - } - - public BType getDomain() { - return domain; - } - - public void setDomain(BType domain) { - this.domain = domain; - if (domain instanceof AbstractHasFollowers) { - ((AbstractHasFollowers) domain).addFollower(this); - } - } - - public BType getRange() { - return range; - } - - public void setRange(BType range) { - this.range = range; - if (range instanceof AbstractHasFollowers) { - ((AbstractHasFollowers) range).addFollower(this); - } - } - - public BType unify(BType other, ITypechecker typechecker) { - if (!this.compare(other)) { - throw new UnificationException(); - } - if (other instanceof UntypedType) { - ((UntypedType) other).setFollowersTo(this, typechecker); - return this; - } else if (other instanceof FunctionType) { - ((FunctionType) other).setFollowersTo(this, typechecker); - setDomain(domain.unify(((FunctionType) other).domain, typechecker)); - setRange(range.unify(((FunctionType) other).range, typechecker)); - return this; - } else if (other instanceof SetType - || other instanceof IntegerOrSetType - || other instanceof IntegerOrSetOfPairType) { - if (domain instanceof AbstractHasFollowers) { - ((AbstractHasFollowers) domain).deleteFollower(this); - } - if (range instanceof AbstractHasFollowers) { - ((AbstractHasFollowers) range).deleteFollower(this); - } - SetType s = new SetType(new PairType(domain, range)); - this.setFollowersTo(s, typechecker); - return s.unify(other, typechecker); - } - throw new RuntimeException(); - } - - public boolean isUntyped() { - return domain.isUntyped() || range.isUntyped(); - } - - @Override - public String toString() { - String res = "FUNC(" + domain + "," + range + ")"; - return res; - } - - public void update(BType oldType, BType newType) { - if (domain == oldType) - setDomain(newType); - if (range == oldType) - setRange(newType); - } - - @Override - public boolean compare(BType other) { - if (other instanceof UntypedType) - return true; - else if (other instanceof FunctionType) { - return domain.compare(((FunctionType) other).domain) - && range.compare(((FunctionType) other).range); - } else if (other instanceof IntegerOrSetOfPairType - || other instanceof IntegerOrSetType) { - return true; - } else if (other instanceof SetType) { - BType t = ((SetType) other).getSubtype(); - if (t instanceof PairType) { - return ((PairType) t).getFirst().compare(domain) - && ((PairType) t).getSecond().compare(range); - } else if (t instanceof UntypedType) { - return true; - } else - return false; - } - return false; - } - - @Override - public boolean contains(BType other) { - if (this.domain.equals(other) || this.range.equals(other)) { - return true; - } - if (domain instanceof AbstractHasFollowers) { - if (((AbstractHasFollowers) domain).contains(other)) - return true; - } - if (range instanceof AbstractHasFollowers) { - if (((AbstractHasFollowers) range).contains(other)) - return true; - } - return false; - } - - @Override - public boolean containsInfiniteType() { - return this.domain.containsInfiniteType() - || this.range.containsInfiniteType(); - } - - @Override - public PExpression createASTNode(Typechecker typechecker) { - APartialFunctionExpression node = new APartialFunctionExpression( - domain.createASTNode(typechecker), - range.createASTNode(typechecker)); - typechecker.setType(node, new SetType(this)); - - return node; - } - -} +package de.tlc4b.btypes; + +import de.be4.classicalb.core.parser.node.APartialFunctionExpression; +import de.be4.classicalb.core.parser.node.PExpression; +import de.tlc4b.analysis.Typechecker; +import de.tlc4b.exceptions.UnificationException; + +public class FunctionType extends AbstractHasFollowers { + private BType domain; + private BType range; + + public FunctionType(BType domain, BType range) { + setDomain(domain); + setRange(range); + } + + public BType getDomain() { + return domain; + } + + public void setDomain(BType domain) { + this.domain = domain; + if (domain instanceof AbstractHasFollowers) { + ((AbstractHasFollowers) domain).addFollower(this); + } + } + + public BType getRange() { + return range; + } + + public void setRange(BType range) { + this.range = range; + if (range instanceof AbstractHasFollowers) { + ((AbstractHasFollowers) range).addFollower(this); + } + } + + public BType unify(BType other, ITypechecker typechecker) { + if (!this.compare(other)) { + throw new UnificationException(); + } + if (other instanceof UntypedType) { + ((UntypedType) other).setFollowersTo(this, typechecker); + return this; + } else if (other instanceof FunctionType) { + ((FunctionType) other).setFollowersTo(this, typechecker); + setDomain(domain.unify(((FunctionType) other).domain, typechecker)); + setRange(range.unify(((FunctionType) other).range, typechecker)); + return this; + } else if (other instanceof SetType + || other instanceof IntegerOrSetType + || other instanceof IntegerOrSetOfPairType) { + if (domain instanceof AbstractHasFollowers) { + ((AbstractHasFollowers) domain).deleteFollower(this); + } + if (range instanceof AbstractHasFollowers) { + ((AbstractHasFollowers) range).deleteFollower(this); + } + SetType s = new SetType(new PairType(domain, range)); + this.setFollowersTo(s, typechecker); + return s.unify(other, typechecker); + } + throw new RuntimeException(); + } + + public boolean isUntyped() { + return domain.isUntyped() || range.isUntyped(); + } + + @Override + public String toString() { + String res = "FUNC(" + domain + "," + range + ")"; + return res; + } + + public void update(BType oldType, BType newType) { + if (domain == oldType) + setDomain(newType); + if (range == oldType) + setRange(newType); + } + + @Override + public boolean compare(BType other) { + if (other instanceof UntypedType) + return true; + else if (other instanceof FunctionType) { + return domain.compare(((FunctionType) other).domain) + && range.compare(((FunctionType) other).range); + } else if (other instanceof IntegerOrSetOfPairType + || other instanceof IntegerOrSetType) { + return true; + } else if (other instanceof SetType) { + BType t = ((SetType) other).getSubtype(); + if (t instanceof PairType) { + return ((PairType) t).getFirst().compare(domain) + && ((PairType) t).getSecond().compare(range); + } else if (t instanceof UntypedType) { + return true; + } else + return false; + } + return false; + } + + @Override + public boolean contains(BType other) { + if (this.domain.equals(other) || this.range.equals(other)) { + return true; + } + if (domain instanceof AbstractHasFollowers) { + if (((AbstractHasFollowers) domain).contains(other)) + return true; + } + if (range instanceof AbstractHasFollowers) { + if (((AbstractHasFollowers) range).contains(other)) + return true; + } + return false; + } + + @Override + public boolean containsInfiniteType() { + return this.domain.containsInfiniteType() + || this.range.containsInfiniteType(); + } + + @Override + public PExpression createASTNode(Typechecker typechecker) { + APartialFunctionExpression node = new APartialFunctionExpression( + domain.createASTNode(typechecker), + range.createASTNode(typechecker)); + typechecker.setType(node, new SetType(this)); + + return node; + } + +} diff --git a/src/main/java/de/tlc4b/btypes/ITypechecker.java b/src/main/java/de/tlc4b/btypes/ITypechecker.java index f620866b1ee900e0b5989a1c6f4d3c13749784d1..9e996d9a0756620a6fe257350ad5d4c6c99fb443 100644 --- a/src/main/java/de/tlc4b/btypes/ITypechecker.java +++ b/src/main/java/de/tlc4b/btypes/ITypechecker.java @@ -1,9 +1,9 @@ -package de.tlc4b.btypes; - -import de.be4.classicalb.core.parser.node.Node; - - -public interface ITypechecker { - public void setType(Node node, BType type); - public void updateType(Node node, AbstractHasFollowers oldType, BType newType); -} +package de.tlc4b.btypes; + +import de.be4.classicalb.core.parser.node.Node; + + +public interface ITypechecker { + public void setType(Node node, BType type); + public void updateType(Node node, AbstractHasFollowers oldType, BType newType); +} diff --git a/src/main/java/de/tlc4b/btypes/IntegerOrSetOfPairType.java b/src/main/java/de/tlc4b/btypes/IntegerOrSetOfPairType.java index d0d929bd7a2cac9a3785c4152a11b5171c7d8bb2..a9215a24e57a00e5c935f824c7cf660a6b11511b 100644 --- a/src/main/java/de/tlc4b/btypes/IntegerOrSetOfPairType.java +++ b/src/main/java/de/tlc4b/btypes/IntegerOrSetOfPairType.java @@ -1,230 +1,230 @@ -package de.tlc4b.btypes; - -import de.be4.classicalb.core.parser.node.PExpression; -import de.hhu.stups.sablecc.patch.SourcePosition; -import de.tlc4b.analysis.Typechecker; -import de.tlc4b.exceptions.TypeErrorException; -import de.tlc4b.exceptions.UnificationException; - -public class IntegerOrSetOfPairType extends AbstractHasFollowers { - - private AbstractHasFollowers first; - private AbstractHasFollowers second; - - public AbstractHasFollowers getFirst() { - return first; - } - - public AbstractHasFollowers getSecond() { - return second; - } - - public IntegerOrSetOfPairType(SourcePosition sourcePosition, - SourcePosition sourcePosition2) { - - IntegerOrSetType i1 = new IntegerOrSetType(); - this.first = i1; - first.addFollower(this); - - IntegerOrSetType i2 = new IntegerOrSetType(); - this.second = i2; - second.addFollower(this); - } - - public void update(BType oldType, BType newType, ITypechecker typechecker) { - if(second.getFollowers().contains(first)){ - System.out.println("integerOrsetOfPair"); - throw new RuntimeException(); - } - if (newType instanceof IntegerType) { - // if newType is an Integer then both arguments and the result are - // Integers - - if (this.first == oldType) { - // do nothing - } else { - first.deleteFollower(this); // we do not want to update this - // node twice - first.unify(newType, typechecker); - } - if (this.second == oldType) { - // do nothing - } else { - second.deleteFollower(this); - second.unify(newType, typechecker); - } - this.setFollowersTo(IntegerType.getInstance(), typechecker); - - return; - } else if (newType instanceof SetType) { - SetType newFirst; - SetType newSecond; - - - if (first == second && first != oldType){ - first.deleteFollower(this); - newFirst = new SetType(new UntypedType()); - newSecond = newFirst; - newFirst.addFollower(this); - }else { - if (this.first == oldType) { - first.deleteFollower(this); - newFirst = (SetType) newType; - } else { - first.deleteFollower(this); - newFirst = new SetType(new UntypedType()); - first.setFollowersTo(newFirst, typechecker); - } - - if (this.second == oldType) { - first.deleteFollower(this); - newSecond = (SetType) newType; - } else { - second.deleteFollower(this); - newSecond = new SetType(new UntypedType()); - this.second.setFollowersTo(newSecond, typechecker); - } - } - - if (oldType == this) { - this.setFollowersTo(newType, typechecker); - - PairType pair = new PairType(newFirst, newSecond); - ((SetType) newType).getSubtype().unify(pair, typechecker); - } else { - SetType setOfPairSetType = new SetType(new PairType( - newFirst.getSubtype(), newSecond.getSubtype())); - setOfPairSetType.unify(this, typechecker); - } - return; - } else if (newType instanceof IntegerOrSetOfPairType) { - if (this.first == oldType) { - first.deleteFollower(this); - first = (AbstractHasFollowers) newType; - first.addFollower(this); - } - if (this.second == oldType) { - second.deleteFollower(this); - second = (AbstractHasFollowers) newType; - second.addFollower(this); - } - } else if (newType instanceof IntegerOrSetType) { - if (this.first == oldType) { - first.deleteFollower(this); - first = (AbstractHasFollowers) newType; - first.addFollower(this); - } - if (this.second == oldType) { - second.deleteFollower(this); - second = (AbstractHasFollowers) newType; - second.addFollower(this); - } - } else { - throw new TypeErrorException( - "Expected 'INTEGER' or 'POW(_A)', found " + newType); - } - - } - - public BType unify(BType other, ITypechecker typechecker) { - if (!this.compare(other) || this.contains(other)){ - throw new UnificationException(); - } - - - if (other instanceof UntypedType) { - ((UntypedType) other).setFollowersTo(this, typechecker); - return this; - } - - if (other instanceof IntegerType) { - this.setFollowersTo(IntegerType.getInstance(), typechecker); - this.getFirst().deleteFollower(this); - this.getSecond().deleteFollower(this); - first.unify(IntegerType.getInstance(), typechecker); - second.unify(IntegerType.getInstance(), typechecker); - return IntegerType.getInstance(); - } - - if (other instanceof IntegerOrSetType) { - ((IntegerOrSetType) other).setFollowersTo(this, typechecker); - return this; - } - - if(other instanceof SetType){ - first.deleteFollower(this); - second.deleteFollower(this); - - SetType newFirst = new SetType(new UntypedType()).unify(first, typechecker); - SetType newSecond = new SetType(new UntypedType()).unify(second, typechecker); - - SetType found = new SetType(new PairType(newFirst.getSubtype(), - newSecond.getSubtype())); - - this.setFollowersTo(found, typechecker); - - return found.unify(other, typechecker); - } - if(other instanceof FunctionType){ - return other.unify(this, typechecker); - } - if(other instanceof IntegerOrSetOfPairType){ - IntegerOrSetOfPairType o = (IntegerOrSetOfPairType) other; - o.first.deleteFollower(o); - o.second.deleteFollower(o); - first = (AbstractHasFollowers) this.first.unify(((IntegerOrSetOfPairType) other).first, typechecker); - second = (AbstractHasFollowers) this.second.unify(((IntegerOrSetOfPairType) other).second, typechecker); - ((IntegerOrSetOfPairType) other).setFollowersTo(this, typechecker); - return this; - } - throw new RuntimeException(); - } - - @Override - public String toString() { - return "IntegerOrSetOfPairType" + this.hashCode() + "(" - + this.getFirst() + "," + this.getSecond() + ")"; - } - - public boolean isUntyped() { - // TODO proof - return true; - } - - public boolean compare(BType other) { - if (other instanceof UntypedType || other instanceof IntegerType - || other instanceof IntegerOrSetType - || other instanceof IntegerOrSetOfPairType - || other instanceof FunctionType) - return true; - else if (other instanceof SetType) { - BType subType = ((SetType) other).getSubtype(); - if (subType instanceof UntypedType || subType instanceof PairType) - return true; - else - return false; - } else - return false; - } - - @Override - public boolean contains(BType other) { - if (this.first.equals(other) || this.second.equals(other)) { - return true; - } - - if(first.contains(other) || second.contains(other)){ - return true; - }else - return false; - } - - public boolean containsInfiniteType() { - return false; - } - - public PExpression createASTNode(Typechecker typechecker) { - return null; - } - -} +package de.tlc4b.btypes; + +import de.be4.classicalb.core.parser.node.PExpression; +import de.hhu.stups.sablecc.patch.SourcePosition; +import de.tlc4b.analysis.Typechecker; +import de.tlc4b.exceptions.TypeErrorException; +import de.tlc4b.exceptions.UnificationException; + +public class IntegerOrSetOfPairType extends AbstractHasFollowers { + + private AbstractHasFollowers first; + private AbstractHasFollowers second; + + public AbstractHasFollowers getFirst() { + return first; + } + + public AbstractHasFollowers getSecond() { + return second; + } + + public IntegerOrSetOfPairType(SourcePosition sourcePosition, + SourcePosition sourcePosition2) { + + IntegerOrSetType i1 = new IntegerOrSetType(); + this.first = i1; + first.addFollower(this); + + IntegerOrSetType i2 = new IntegerOrSetType(); + this.second = i2; + second.addFollower(this); + } + + public void update(BType oldType, BType newType, ITypechecker typechecker) { + if(second.getFollowers().contains(first)){ + System.out.println("integerOrsetOfPair"); + throw new RuntimeException(); + } + if (newType instanceof IntegerType) { + // if newType is an Integer then both arguments and the result are + // Integers + + if (this.first == oldType) { + // do nothing + } else { + first.deleteFollower(this); // we do not want to update this + // node twice + first.unify(newType, typechecker); + } + if (this.second == oldType) { + // do nothing + } else { + second.deleteFollower(this); + second.unify(newType, typechecker); + } + this.setFollowersTo(IntegerType.getInstance(), typechecker); + + return; + } else if (newType instanceof SetType) { + SetType newFirst; + SetType newSecond; + + + if (first == second && first != oldType){ + first.deleteFollower(this); + newFirst = new SetType(new UntypedType()); + newSecond = newFirst; + newFirst.addFollower(this); + }else { + if (this.first == oldType) { + first.deleteFollower(this); + newFirst = (SetType) newType; + } else { + first.deleteFollower(this); + newFirst = new SetType(new UntypedType()); + first.setFollowersTo(newFirst, typechecker); + } + + if (this.second == oldType) { + first.deleteFollower(this); + newSecond = (SetType) newType; + } else { + second.deleteFollower(this); + newSecond = new SetType(new UntypedType()); + this.second.setFollowersTo(newSecond, typechecker); + } + } + + if (oldType == this) { + this.setFollowersTo(newType, typechecker); + + PairType pair = new PairType(newFirst, newSecond); + ((SetType) newType).getSubtype().unify(pair, typechecker); + } else { + SetType setOfPairSetType = new SetType(new PairType( + newFirst.getSubtype(), newSecond.getSubtype())); + setOfPairSetType.unify(this, typechecker); + } + return; + } else if (newType instanceof IntegerOrSetOfPairType) { + if (this.first == oldType) { + first.deleteFollower(this); + first = (AbstractHasFollowers) newType; + first.addFollower(this); + } + if (this.second == oldType) { + second.deleteFollower(this); + second = (AbstractHasFollowers) newType; + second.addFollower(this); + } + } else if (newType instanceof IntegerOrSetType) { + if (this.first == oldType) { + first.deleteFollower(this); + first = (AbstractHasFollowers) newType; + first.addFollower(this); + } + if (this.second == oldType) { + second.deleteFollower(this); + second = (AbstractHasFollowers) newType; + second.addFollower(this); + } + } else { + throw new TypeErrorException( + "Expected 'INTEGER' or 'POW(_A)', found " + newType); + } + + } + + public BType unify(BType other, ITypechecker typechecker) { + if (!this.compare(other) || this.contains(other)){ + throw new UnificationException(); + } + + + if (other instanceof UntypedType) { + ((UntypedType) other).setFollowersTo(this, typechecker); + return this; + } + + if (other instanceof IntegerType) { + this.setFollowersTo(IntegerType.getInstance(), typechecker); + this.getFirst().deleteFollower(this); + this.getSecond().deleteFollower(this); + first.unify(IntegerType.getInstance(), typechecker); + second.unify(IntegerType.getInstance(), typechecker); + return IntegerType.getInstance(); + } + + if (other instanceof IntegerOrSetType) { + ((IntegerOrSetType) other).setFollowersTo(this, typechecker); + return this; + } + + if(other instanceof SetType){ + first.deleteFollower(this); + second.deleteFollower(this); + + SetType newFirst = new SetType(new UntypedType()).unify(first, typechecker); + SetType newSecond = new SetType(new UntypedType()).unify(second, typechecker); + + SetType found = new SetType(new PairType(newFirst.getSubtype(), + newSecond.getSubtype())); + + this.setFollowersTo(found, typechecker); + + return found.unify(other, typechecker); + } + if(other instanceof FunctionType){ + return other.unify(this, typechecker); + } + if(other instanceof IntegerOrSetOfPairType){ + IntegerOrSetOfPairType o = (IntegerOrSetOfPairType) other; + o.first.deleteFollower(o); + o.second.deleteFollower(o); + first = (AbstractHasFollowers) this.first.unify(((IntegerOrSetOfPairType) other).first, typechecker); + second = (AbstractHasFollowers) this.second.unify(((IntegerOrSetOfPairType) other).second, typechecker); + ((IntegerOrSetOfPairType) other).setFollowersTo(this, typechecker); + return this; + } + throw new RuntimeException(); + } + + @Override + public String toString() { + return "IntegerOrSetOfPairType" + this.hashCode() + "(" + + this.getFirst() + "," + this.getSecond() + ")"; + } + + public boolean isUntyped() { + // TODO proof + return true; + } + + public boolean compare(BType other) { + if (other instanceof UntypedType || other instanceof IntegerType + || other instanceof IntegerOrSetType + || other instanceof IntegerOrSetOfPairType + || other instanceof FunctionType) + return true; + else if (other instanceof SetType) { + BType subType = ((SetType) other).getSubtype(); + if (subType instanceof UntypedType || subType instanceof PairType) + return true; + else + return false; + } else + return false; + } + + @Override + public boolean contains(BType other) { + if (this.first.equals(other) || this.second.equals(other)) { + return true; + } + + if(first.contains(other) || second.contains(other)){ + return true; + }else + return false; + } + + public boolean containsInfiniteType() { + return false; + } + + public PExpression createASTNode(Typechecker typechecker) { + return null; + } + +} diff --git a/src/main/java/de/tlc4b/btypes/IntegerOrSetType.java b/src/main/java/de/tlc4b/btypes/IntegerOrSetType.java index 7d52dfae8b2d30cf1212699b26677083d4de14bf..ecf671de4157ff089d79cd401132f7b3c5b43437 100644 --- a/src/main/java/de/tlc4b/btypes/IntegerOrSetType.java +++ b/src/main/java/de/tlc4b/btypes/IntegerOrSetType.java @@ -1,64 +1,64 @@ -package de.tlc4b.btypes; - -import de.be4.classicalb.core.parser.node.PExpression; -import de.tlc4b.analysis.Typechecker; -import de.tlc4b.exceptions.UnificationException; - -public class IntegerOrSetType extends AbstractHasFollowers { - - public BType unify(BType other, ITypechecker typechecker) { - if (!this.compare(other)) - throw new UnificationException(); - - if (other instanceof IntegerType) { - this.setFollowersTo(IntegerType.getInstance(), typechecker); - return IntegerType.getInstance(); - } - if (other instanceof UntypedType) { - ((UntypedType) other).setFollowersTo(this, typechecker); - return this; - } - if (other instanceof SetType) { - this.setFollowersTo(other, typechecker); - return other; - } - if (other instanceof IntegerOrSetType) { - ((IntegerOrSetType) other).setFollowersTo(this, typechecker); - return this; - } - if (other instanceof IntegerOrSetOfPairType) { - this.setFollowersTo(other, typechecker); - return other; - } - throw new RuntimeException(); - } - - public boolean isUntyped() { - return true; - } - - public boolean compare(BType other) { - if (other instanceof UntypedType || other instanceof IntegerType - || other instanceof SetType - || other instanceof IntegerOrSetType - || other instanceof IntegerOrSetOfPairType) - return true; - else if (other instanceof FunctionType) { - return other.compare(this); - } else - return false; - } - - @Override - public boolean contains(BType other) { - return false; - } - - public boolean containsInfiniteType() { - return false; - } - - public PExpression createASTNode(Typechecker typechecker) { - return null; - } -} +package de.tlc4b.btypes; + +import de.be4.classicalb.core.parser.node.PExpression; +import de.tlc4b.analysis.Typechecker; +import de.tlc4b.exceptions.UnificationException; + +public class IntegerOrSetType extends AbstractHasFollowers { + + public BType unify(BType other, ITypechecker typechecker) { + if (!this.compare(other)) + throw new UnificationException(); + + if (other instanceof IntegerType) { + this.setFollowersTo(IntegerType.getInstance(), typechecker); + return IntegerType.getInstance(); + } + if (other instanceof UntypedType) { + ((UntypedType) other).setFollowersTo(this, typechecker); + return this; + } + if (other instanceof SetType) { + this.setFollowersTo(other, typechecker); + return other; + } + if (other instanceof IntegerOrSetType) { + ((IntegerOrSetType) other).setFollowersTo(this, typechecker); + return this; + } + if (other instanceof IntegerOrSetOfPairType) { + this.setFollowersTo(other, typechecker); + return other; + } + throw new RuntimeException(); + } + + public boolean isUntyped() { + return true; + } + + public boolean compare(BType other) { + if (other instanceof UntypedType || other instanceof IntegerType + || other instanceof SetType + || other instanceof IntegerOrSetType + || other instanceof IntegerOrSetOfPairType) + return true; + else if (other instanceof FunctionType) { + return other.compare(this); + } else + return false; + } + + @Override + public boolean contains(BType other) { + return false; + } + + public boolean containsInfiniteType() { + return false; + } + + public PExpression createASTNode(Typechecker typechecker) { + return null; + } +} diff --git a/src/main/java/de/tlc4b/btypes/IntegerType.java b/src/main/java/de/tlc4b/btypes/IntegerType.java index 9516c9f1321645bfe49208775bbd04fa24ec2fa1..3143b42d6747e5914f33d0f4cfd98f29b5d393cf 100644 --- a/src/main/java/de/tlc4b/btypes/IntegerType.java +++ b/src/main/java/de/tlc4b/btypes/IntegerType.java @@ -1,65 +1,65 @@ -package de.tlc4b.btypes; - -import de.be4.classicalb.core.parser.node.AIntegerSetExpression; -import de.be4.classicalb.core.parser.node.PExpression; -import de.tlc4b.analysis.Typechecker; -import de.tlc4b.exceptions.UnificationException; - -public class IntegerType implements BType { - - private static IntegerType instance = new IntegerType(); - - public static IntegerType getInstance() { - return instance; - } - - public BType unify(BType other, ITypechecker typechecker) { - if (!this.compare(other)) { - throw new UnificationException(); - } - if (other instanceof IntegerType) { - return getInstance(); - } - if (other instanceof UntypedType) { - ((UntypedType) other).setFollowersTo(this, typechecker); - return getInstance(); - } - if (other instanceof IntegerOrSetOfPairType) { - return other.unify(this, typechecker); - } - if (other instanceof IntegerOrSetType) { - return other.unify(this, typechecker); - } - // System.out.println(other.getClass()); - throw new UnificationException(); - } - - @Override - public String toString() { - return "INTEGER"; - } - - - public boolean isUntyped() { - return false; - } - - public boolean compare(BType other) { - if (other instanceof UntypedType || other instanceof IntegerType) - return true; - if (other instanceof IntegerOrSetType - || other instanceof IntegerOrSetOfPairType) - return true; - return false; - } - - public boolean containsInfiniteType() { - return true; - } - - public PExpression createASTNode(Typechecker typechecker) { - AIntegerSetExpression node = new AIntegerSetExpression(); - typechecker.setType(node, new SetType(this)); - return node; - } -} +package de.tlc4b.btypes; + +import de.be4.classicalb.core.parser.node.AIntegerSetExpression; +import de.be4.classicalb.core.parser.node.PExpression; +import de.tlc4b.analysis.Typechecker; +import de.tlc4b.exceptions.UnificationException; + +public class IntegerType implements BType { + + private static IntegerType instance = new IntegerType(); + + public static IntegerType getInstance() { + return instance; + } + + public BType unify(BType other, ITypechecker typechecker) { + if (!this.compare(other)) { + throw new UnificationException(); + } + if (other instanceof IntegerType) { + return getInstance(); + } + if (other instanceof UntypedType) { + ((UntypedType) other).setFollowersTo(this, typechecker); + return getInstance(); + } + if (other instanceof IntegerOrSetOfPairType) { + return other.unify(this, typechecker); + } + if (other instanceof IntegerOrSetType) { + return other.unify(this, typechecker); + } + // System.out.println(other.getClass()); + throw new UnificationException(); + } + + @Override + public String toString() { + return "INTEGER"; + } + + + public boolean isUntyped() { + return false; + } + + public boolean compare(BType other) { + if (other instanceof UntypedType || other instanceof IntegerType) + return true; + if (other instanceof IntegerOrSetType + || other instanceof IntegerOrSetOfPairType) + return true; + return false; + } + + public boolean containsInfiniteType() { + return true; + } + + public PExpression createASTNode(Typechecker typechecker) { + AIntegerSetExpression node = new AIntegerSetExpression(); + typechecker.setType(node, new SetType(this)); + return node; + } +} diff --git a/src/main/java/de/tlc4b/btypes/PairType.java b/src/main/java/de/tlc4b/btypes/PairType.java index fe7e270a4b0dce4cd300a93ea6c7b9b6d5f51773..e5c2ff7aa8b3b85bb08ad0eb2c3960cabd6fa154 100644 --- a/src/main/java/de/tlc4b/btypes/PairType.java +++ b/src/main/java/de/tlc4b/btypes/PairType.java @@ -1,135 +1,135 @@ -package de.tlc4b.btypes; - -import de.be4.classicalb.core.parser.node.ACartesianProductExpression; -import de.be4.classicalb.core.parser.node.PExpression; -import de.tlc4b.analysis.Typechecker; -import de.tlc4b.exceptions.UnificationException; - -public class PairType extends AbstractHasFollowers { - - private BType first; - private BType second; - - public BType getFirst() { - return this.first; - } - - public BType getSecond() { - return this.second; - } - - public void setFirst(BType newType) { - this.first = newType; - if (newType instanceof AbstractHasFollowers) { - ((AbstractHasFollowers) newType).addFollower(this); - } - } - - public void setSecond(BType newType) { - this.second = newType; - if (newType instanceof AbstractHasFollowers) { - ((AbstractHasFollowers) newType).addFollower(this); - } - } - - public void update(BType oldType, BType newType) { - - if (this.first == oldType) - setFirst(newType); - if (this.second == oldType) - setSecond(newType); - } - - public PairType(BType first, BType second) { - setFirst(first); - setSecond(second); - } - - public BType unify(BType other, ITypechecker typechecker) { - if (!this.compare(other) || this.contains(other)) - throw new UnificationException(); - - if (other instanceof PairType) { - ((PairType) other).setFollowersTo(this, typechecker); - setFirst(first.unify(((PairType) other).first, typechecker)); - setSecond(second.unify(((PairType) other).second, typechecker)); - return this; - } else if (other instanceof UntypedType) { - ((UntypedType) other).setFollowersTo(this, typechecker); - return this; - } - throw new UnificationException(); - } - - @Override - public String toString() { - String res = ""; - if(this.equals(first)|| this.equals(second)){ - res += "(Recursive Type)"; - return res; - }else{ - if (first instanceof PairType) { - res += "(" + first + ")"; - } else - res += first; - res += "*"; - if (second instanceof PairType) { - res += "(" + second + ")"; - } else - res += second; - return res; - } - - - - } - - public boolean isUntyped() { - if (first.isUntyped() || second.isUntyped()) - return true; - else - return false; - } - - public boolean compare(BType other) { - if (other instanceof UntypedType) - return true; - if (other instanceof PairType) { - return this.first.compare(((PairType) other).first) - && this.second.compare(((PairType) other).second); - } - return false; - } - - @Override - public boolean contains(BType other) { - if (this.equals(this.first) || this.equals(this.second)) { - return true; - } - if (this.first.equals(other) || this.second.equals(other)) { - return true; - } - if (first instanceof AbstractHasFollowers) { - if (((AbstractHasFollowers) first).contains(other)) - return true; - } - if (second instanceof AbstractHasFollowers) { - if (((AbstractHasFollowers) second).contains(other)) - return true; - } - return false; - } - - public boolean containsInfiniteType() { - return this.first.containsInfiniteType() - || this.second.containsInfiniteType(); - } - - public PExpression createASTNode(Typechecker typechecker) { - ACartesianProductExpression node = new ACartesianProductExpression( - first.createASTNode(typechecker), - second.createASTNode(typechecker)); - typechecker.setType(node, new SetType(this)); - return node; - } -} +package de.tlc4b.btypes; + +import de.be4.classicalb.core.parser.node.ACartesianProductExpression; +import de.be4.classicalb.core.parser.node.PExpression; +import de.tlc4b.analysis.Typechecker; +import de.tlc4b.exceptions.UnificationException; + +public class PairType extends AbstractHasFollowers { + + private BType first; + private BType second; + + public BType getFirst() { + return this.first; + } + + public BType getSecond() { + return this.second; + } + + public void setFirst(BType newType) { + this.first = newType; + if (newType instanceof AbstractHasFollowers) { + ((AbstractHasFollowers) newType).addFollower(this); + } + } + + public void setSecond(BType newType) { + this.second = newType; + if (newType instanceof AbstractHasFollowers) { + ((AbstractHasFollowers) newType).addFollower(this); + } + } + + public void update(BType oldType, BType newType) { + + if (this.first == oldType) + setFirst(newType); + if (this.second == oldType) + setSecond(newType); + } + + public PairType(BType first, BType second) { + setFirst(first); + setSecond(second); + } + + public BType unify(BType other, ITypechecker typechecker) { + if (!this.compare(other) || this.contains(other)) + throw new UnificationException(); + + if (other instanceof PairType) { + ((PairType) other).setFollowersTo(this, typechecker); + setFirst(first.unify(((PairType) other).first, typechecker)); + setSecond(second.unify(((PairType) other).second, typechecker)); + return this; + } else if (other instanceof UntypedType) { + ((UntypedType) other).setFollowersTo(this, typechecker); + return this; + } + throw new UnificationException(); + } + + @Override + public String toString() { + String res = ""; + if(this.equals(first)|| this.equals(second)){ + res += "(Recursive Type)"; + return res; + }else{ + if (first instanceof PairType) { + res += "(" + first + ")"; + } else + res += first; + res += "*"; + if (second instanceof PairType) { + res += "(" + second + ")"; + } else + res += second; + return res; + } + + + + } + + public boolean isUntyped() { + if (first.isUntyped() || second.isUntyped()) + return true; + else + return false; + } + + public boolean compare(BType other) { + if (other instanceof UntypedType) + return true; + if (other instanceof PairType) { + return this.first.compare(((PairType) other).first) + && this.second.compare(((PairType) other).second); + } + return false; + } + + @Override + public boolean contains(BType other) { + if (this.equals(this.first) || this.equals(this.second)) { + return true; + } + if (this.first.equals(other) || this.second.equals(other)) { + return true; + } + if (first instanceof AbstractHasFollowers) { + if (((AbstractHasFollowers) first).contains(other)) + return true; + } + if (second instanceof AbstractHasFollowers) { + if (((AbstractHasFollowers) second).contains(other)) + return true; + } + return false; + } + + public boolean containsInfiniteType() { + return this.first.containsInfiniteType() + || this.second.containsInfiniteType(); + } + + public PExpression createASTNode(Typechecker typechecker) { + ACartesianProductExpression node = new ACartesianProductExpression( + first.createASTNode(typechecker), + second.createASTNode(typechecker)); + typechecker.setType(node, new SetType(this)); + return node; + } +} diff --git a/src/main/java/de/tlc4b/btypes/SetType.java b/src/main/java/de/tlc4b/btypes/SetType.java index 8edfe6889efbcb5bc2301932cfce8aacbee9cd31..9d76ccc261bd20786c00c46286114b9f4be1d723 100644 --- a/src/main/java/de/tlc4b/btypes/SetType.java +++ b/src/main/java/de/tlc4b/btypes/SetType.java @@ -1,109 +1,109 @@ -package de.tlc4b.btypes; - -import de.be4.classicalb.core.parser.node.APowSubsetExpression; -import de.be4.classicalb.core.parser.node.PExpression; -import de.tlc4b.analysis.Typechecker; -import de.tlc4b.exceptions.UnificationException; - -public class SetType extends AbstractHasFollowers { - - private BType subtype; - - public SetType(BType subtype) { - setSubtype(subtype); - } - - public BType getSubtype() { - return subtype; - } - - public void setSubtype(BType type) { - this.subtype = type; - if (type instanceof AbstractHasFollowers) { - ((AbstractHasFollowers) type).addFollower(this); - } - } - - public SetType unify(BType other, ITypechecker typechecker) { - if (!this.compare(other) || this.contains(other)) - throw new UnificationException(); - - if (other instanceof UntypedType) { - ((UntypedType) other).setFollowersTo(this, typechecker); - return this; - } - if (other instanceof SetType) { - ((SetType) other).setFollowersTo(this, typechecker); - this.subtype = this.subtype.unify(((SetType) other).subtype, typechecker); - return this; - } - - if (other instanceof IntegerOrSetType) { - return (SetType) other.unify(this, typechecker); - } - - if (other instanceof IntegerOrSetOfPairType) { - return (SetType) other.unify(this, typechecker); - } - - if (other instanceof FunctionType) { - return (SetType) other.unify(this, typechecker); - } - - throw new UnificationException(); - } - - @Override - public String toString() { - if (this.equals(subtype)) { - return "POW(recursive call)"; - } else { - return "POW(" + subtype + ")"; - } - - } - - public boolean isUntyped() { - return subtype.isUntyped(); - } - - public boolean compare(BType other) { - if (other instanceof SetType) { - return this.subtype.compare(((SetType) other).subtype); - } - - if (other instanceof UntypedType) - return true; - if (other instanceof IntegerOrSetType || other instanceof IntegerOrSetOfPairType) { - return true; - } else if (other instanceof FunctionType) { - return other.compare(this); - } - return false; - } - - @Override - public boolean contains(BType other) { - if (this.equals(subtype)) { - return true; - } - if (this.subtype.equals(other)) { - return true; - } - if (this.subtype instanceof AbstractHasFollowers) { - return ((AbstractHasFollowers) subtype).contains(other); - } - return false; - } - - public boolean containsInfiniteType() { - return this.subtype.containsInfiniteType(); - } - - public PExpression createASTNode(Typechecker typechecker) { - APowSubsetExpression node = new APowSubsetExpression(subtype.createASTNode(typechecker)); - typechecker.setType(node, this); - return node; - } - -} +package de.tlc4b.btypes; + +import de.be4.classicalb.core.parser.node.APowSubsetExpression; +import de.be4.classicalb.core.parser.node.PExpression; +import de.tlc4b.analysis.Typechecker; +import de.tlc4b.exceptions.UnificationException; + +public class SetType extends AbstractHasFollowers { + + private BType subtype; + + public SetType(BType subtype) { + setSubtype(subtype); + } + + public BType getSubtype() { + return subtype; + } + + public void setSubtype(BType type) { + this.subtype = type; + if (type instanceof AbstractHasFollowers) { + ((AbstractHasFollowers) type).addFollower(this); + } + } + + public SetType unify(BType other, ITypechecker typechecker) { + if (!this.compare(other) || this.contains(other)) + throw new UnificationException(); + + if (other instanceof UntypedType) { + ((UntypedType) other).setFollowersTo(this, typechecker); + return this; + } + if (other instanceof SetType) { + ((SetType) other).setFollowersTo(this, typechecker); + this.subtype = this.subtype.unify(((SetType) other).subtype, typechecker); + return this; + } + + if (other instanceof IntegerOrSetType) { + return (SetType) other.unify(this, typechecker); + } + + if (other instanceof IntegerOrSetOfPairType) { + return (SetType) other.unify(this, typechecker); + } + + if (other instanceof FunctionType) { + return (SetType) other.unify(this, typechecker); + } + + throw new UnificationException(); + } + + @Override + public String toString() { + if (this.equals(subtype)) { + return "POW(recursive call)"; + } else { + return "POW(" + subtype + ")"; + } + + } + + public boolean isUntyped() { + return subtype.isUntyped(); + } + + public boolean compare(BType other) { + if (other instanceof SetType) { + return this.subtype.compare(((SetType) other).subtype); + } + + if (other instanceof UntypedType) + return true; + if (other instanceof IntegerOrSetType || other instanceof IntegerOrSetOfPairType) { + return true; + } else if (other instanceof FunctionType) { + return other.compare(this); + } + return false; + } + + @Override + public boolean contains(BType other) { + if (this.equals(subtype)) { + return true; + } + if (this.subtype.equals(other)) { + return true; + } + if (this.subtype instanceof AbstractHasFollowers) { + return ((AbstractHasFollowers) subtype).contains(other); + } + return false; + } + + public boolean containsInfiniteType() { + return this.subtype.containsInfiniteType(); + } + + public PExpression createASTNode(Typechecker typechecker) { + APowSubsetExpression node = new APowSubsetExpression(subtype.createASTNode(typechecker)); + typechecker.setType(node, this); + return node; + } + +} diff --git a/src/main/java/de/tlc4b/btypes/StringType.java b/src/main/java/de/tlc4b/btypes/StringType.java index b4599467f9e19f5a588c74934667dab5a8a4462a..f37ac4ec5eaa1a5a482eecf7afd22a9db00bffc5 100644 --- a/src/main/java/de/tlc4b/btypes/StringType.java +++ b/src/main/java/de/tlc4b/btypes/StringType.java @@ -1,61 +1,61 @@ -package de.tlc4b.btypes; - -import de.be4.classicalb.core.parser.node.AStringSetExpression; -import de.be4.classicalb.core.parser.node.PExpression; -import de.tlc4b.analysis.Typechecker; -import de.tlc4b.exceptions.UnificationException; - -public class StringType implements BType { - - private static StringType instance = new StringType(); - - public static StringType getInstance() { - return instance; - } - - @Override - public String toString() { - return "STRING"; - } - - public BType unify(BType other, ITypechecker typechecker) { - if (!this.compare(other)) { - throw new UnificationException(); - } - - if (other instanceof UntypedType) { - ((UntypedType) other).setFollowersTo(this, typechecker); - return this; - } - if (other instanceof StringType) { - return this; - } - - throw new UnificationException(); - } - - public boolean isUntyped() { - return false; - } - - public boolean compare(BType other) { - if (other instanceof UntypedType) { - return true; - } - if (other instanceof StringType) { - return true; - } - return false; - } - - public boolean containsInfiniteType() { - return true; - } - - public PExpression createASTNode(Typechecker typechecker) { - AStringSetExpression node = new AStringSetExpression(); - typechecker.setType(node, new SetType(this)); - return node; - } - -} +package de.tlc4b.btypes; + +import de.be4.classicalb.core.parser.node.AStringSetExpression; +import de.be4.classicalb.core.parser.node.PExpression; +import de.tlc4b.analysis.Typechecker; +import de.tlc4b.exceptions.UnificationException; + +public class StringType implements BType { + + private static StringType instance = new StringType(); + + public static StringType getInstance() { + return instance; + } + + @Override + public String toString() { + return "STRING"; + } + + public BType unify(BType other, ITypechecker typechecker) { + if (!this.compare(other)) { + throw new UnificationException(); + } + + if (other instanceof UntypedType) { + ((UntypedType) other).setFollowersTo(this, typechecker); + return this; + } + if (other instanceof StringType) { + return this; + } + + throw new UnificationException(); + } + + public boolean isUntyped() { + return false; + } + + public boolean compare(BType other) { + if (other instanceof UntypedType) { + return true; + } + if (other instanceof StringType) { + return true; + } + return false; + } + + public boolean containsInfiniteType() { + return true; + } + + public PExpression createASTNode(Typechecker typechecker) { + AStringSetExpression node = new AStringSetExpression(); + typechecker.setType(node, new SetType(this)); + return node; + } + +} diff --git a/src/main/java/de/tlc4b/btypes/StructType.java b/src/main/java/de/tlc4b/btypes/StructType.java index e2e4345bea039c43fe0714881c57d39f092f9574..4893a3e99abd567d805f1f7ccc5ce3ac394d83e4 100644 --- a/src/main/java/de/tlc4b/btypes/StructType.java +++ b/src/main/java/de/tlc4b/btypes/StructType.java @@ -1,220 +1,220 @@ -package de.tlc4b.btypes; - -import java.util.ArrayList; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.Map.Entry; -import java.util.Set; - -import de.be4.classicalb.core.parser.node.AIdentifierExpression; -import de.be4.classicalb.core.parser.node.ARecEntry; -import de.be4.classicalb.core.parser.node.AStructExpression; -import de.be4.classicalb.core.parser.node.PExpression; -import de.be4.classicalb.core.parser.node.PRecEntry; -import de.be4.classicalb.core.parser.node.TIdentifierLiteral; -import de.tlc4b.analysis.Typechecker; -import de.tlc4b.exceptions.UnificationException; - -public class StructType extends AbstractHasFollowers { - - private LinkedHashMap<String, BType> types; - private boolean complete; - - public StructType() { - types = new LinkedHashMap<String, BType>(); - } - - public BType getType(String fieldName) { - return types.get(fieldName); - } - - public void setComplete() { - complete = true; - } - - public void add(String name, BType type) { - if (type instanceof AbstractHasFollowers) { - ((AbstractHasFollowers) type).addFollower(this); - } - types.put(name, type); - } - - @Override - public String toString() { - StringBuffer res = new StringBuffer(); - res.append("struct("); - - Iterator<Entry<String, BType>> iterator = types.entrySet().iterator(); - if (!iterator.hasNext()) - res.append("..."); - while (iterator.hasNext()) { - Entry<String, BType> next = iterator.next(); - String fieldName = (String) next.getKey(); - res.append(fieldName).append(":").append(next.getValue()); - if (iterator.hasNext()) - res.append(","); - } - res.append(")"); - return res.toString(); - } - - public void update(BType oldType, BType newType) { - Iterator<Entry<String, BType>> iterator = this.types.entrySet() - .iterator(); - while (iterator.hasNext()) { - Entry<String, BType> next = iterator.next(); - String name = next.getKey(); - BType type = next.getValue(); - if (type == oldType) { - this.types.put(name, newType); - if (newType instanceof AbstractHasFollowers) { - ((AbstractHasFollowers) newType).addFollower(this); - } - } - - } - } - - public BType unify(BType other, ITypechecker typechecker) { - if (!this.compare(other) || this.contains(other)) { - throw new UnificationException(); - } - if (other instanceof UntypedType) { - ((UntypedType) other).setFollowersTo(this, typechecker); - return this; - } - if (other instanceof StructType) { - StructType s = (StructType) other; - - Iterator<Entry<String, BType>> iterator = s.types.entrySet() - .iterator(); - while (iterator.hasNext()) { - Entry<String, BType> next = iterator.next(); - String fieldName = next.getKey(); - BType sType = next.getValue(); - if (this.types.containsKey(fieldName)) { - BType res = this.types.get(fieldName).unify(sType, - typechecker); - this.types.put(fieldName, res); - if(res instanceof AbstractHasFollowers){ - ((AbstractHasFollowers) res).addFollower(this); - } - } else { - this.types.put(fieldName, sType); - if (sType instanceof AbstractHasFollowers) { - AbstractHasFollowers f = (AbstractHasFollowers) sType; - f.deleteFollower(other); - f.addFollower(this); - } - } - } - ((StructType) other).setFollowersTo(this, typechecker); - complete = this.complete || s.complete; - return this; - - } - throw new UnificationException(); - } - - public boolean isUntyped() { - Iterator<BType> iterator = types.values().iterator(); - while (iterator.hasNext()) { - if (iterator.next().isUntyped()) { - return true; - } - } - return false; - } - - public boolean compare(BType other) { - if (other instanceof UntypedType) { - return true; - } - if (other instanceof StructType) { - StructType s = (StructType) other; - Iterator<String> itr = types.keySet().iterator(); - Set<String> intersection = new HashSet<String>(); - while (itr.hasNext()) { - String temp = itr.next(); - if (s.types.keySet().contains(temp)) { - intersection.add(temp); - } - } - if (this.complete) { - Set<String> temp = new HashSet<String>(s.types.keySet()); - temp.removeAll(intersection); - if (!temp.equals(new HashSet<String>())) { - return false; - } - } - - if (s.complete) { - Set<String> temp = new HashSet<String>(this.types.keySet()); - temp.removeAll(intersection); - if (!temp.equals(new HashSet<String>())) { - return false; - } - } - Iterator<Entry<String, BType>> iterator = types.entrySet() - .iterator(); - while (iterator.hasNext()) { - Entry<String, BType> next = iterator.next(); - String name = next.getKey(); - BType value = next.getValue(); - if (!this.types.get(name).compare(value)) { - return false; - } - } - return true; - } - return false; - } - - @Override - public boolean contains(BType other) { - Iterator<BType> itr = types.values().iterator(); - while (itr.hasNext()) { - BType t = itr.next(); - if (t.equals(other)) { - return true; - } - if (t instanceof AbstractHasFollowers) { - if (((AbstractHasFollowers) t).contains(other)) { - return true; - } - } - } - return false; - } - - public boolean containsInfiniteType() { - Iterator<BType> iterator = this.types.values().iterator(); - while (iterator.hasNext()) { - if (iterator.next().containsInfiniteType()) - return true; - } - return false; - } - - public PExpression createASTNode(Typechecker typechecker) { - ArrayList<PRecEntry> list = new ArrayList<PRecEntry>(); - - Set<Entry<String, BType>> entrySet = this.types.entrySet(); - for (Entry<String, BType> entry : entrySet) { - String name = entry.getKey(); - BType type = entry.getValue(); - TIdentifierLiteral literal = new TIdentifierLiteral(name); - ArrayList<TIdentifierLiteral> idList = new ArrayList<TIdentifierLiteral>(); - idList.add(literal); - AIdentifierExpression id = new AIdentifierExpression(idList); - ARecEntry recEntry = new ARecEntry(id, - type.createASTNode(typechecker)); - list.add(recEntry); - } - AStructExpression node = new AStructExpression(list); - typechecker.setType(node, new SetType(this)); - return node; - } - -} +package de.tlc4b.btypes; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map.Entry; +import java.util.Set; + +import de.be4.classicalb.core.parser.node.AIdentifierExpression; +import de.be4.classicalb.core.parser.node.ARecEntry; +import de.be4.classicalb.core.parser.node.AStructExpression; +import de.be4.classicalb.core.parser.node.PExpression; +import de.be4.classicalb.core.parser.node.PRecEntry; +import de.be4.classicalb.core.parser.node.TIdentifierLiteral; +import de.tlc4b.analysis.Typechecker; +import de.tlc4b.exceptions.UnificationException; + +public class StructType extends AbstractHasFollowers { + + private LinkedHashMap<String, BType> types; + private boolean complete; + + public StructType() { + types = new LinkedHashMap<String, BType>(); + } + + public BType getType(String fieldName) { + return types.get(fieldName); + } + + public void setComplete() { + complete = true; + } + + public void add(String name, BType type) { + if (type instanceof AbstractHasFollowers) { + ((AbstractHasFollowers) type).addFollower(this); + } + types.put(name, type); + } + + @Override + public String toString() { + StringBuffer res = new StringBuffer(); + res.append("struct("); + + Iterator<Entry<String, BType>> iterator = types.entrySet().iterator(); + if (!iterator.hasNext()) + res.append("..."); + while (iterator.hasNext()) { + Entry<String, BType> next = iterator.next(); + String fieldName = (String) next.getKey(); + res.append(fieldName).append(":").append(next.getValue()); + if (iterator.hasNext()) + res.append(","); + } + res.append(")"); + return res.toString(); + } + + public void update(BType oldType, BType newType) { + Iterator<Entry<String, BType>> iterator = this.types.entrySet() + .iterator(); + while (iterator.hasNext()) { + Entry<String, BType> next = iterator.next(); + String name = next.getKey(); + BType type = next.getValue(); + if (type == oldType) { + this.types.put(name, newType); + if (newType instanceof AbstractHasFollowers) { + ((AbstractHasFollowers) newType).addFollower(this); + } + } + + } + } + + public BType unify(BType other, ITypechecker typechecker) { + if (!this.compare(other) || this.contains(other)) { + throw new UnificationException(); + } + if (other instanceof UntypedType) { + ((UntypedType) other).setFollowersTo(this, typechecker); + return this; + } + if (other instanceof StructType) { + StructType s = (StructType) other; + + Iterator<Entry<String, BType>> iterator = s.types.entrySet() + .iterator(); + while (iterator.hasNext()) { + Entry<String, BType> next = iterator.next(); + String fieldName = next.getKey(); + BType sType = next.getValue(); + if (this.types.containsKey(fieldName)) { + BType res = this.types.get(fieldName).unify(sType, + typechecker); + this.types.put(fieldName, res); + if(res instanceof AbstractHasFollowers){ + ((AbstractHasFollowers) res).addFollower(this); + } + } else { + this.types.put(fieldName, sType); + if (sType instanceof AbstractHasFollowers) { + AbstractHasFollowers f = (AbstractHasFollowers) sType; + f.deleteFollower(other); + f.addFollower(this); + } + } + } + ((StructType) other).setFollowersTo(this, typechecker); + complete = this.complete || s.complete; + return this; + + } + throw new UnificationException(); + } + + public boolean isUntyped() { + Iterator<BType> iterator = types.values().iterator(); + while (iterator.hasNext()) { + if (iterator.next().isUntyped()) { + return true; + } + } + return false; + } + + public boolean compare(BType other) { + if (other instanceof UntypedType) { + return true; + } + if (other instanceof StructType) { + StructType s = (StructType) other; + Iterator<String> itr = types.keySet().iterator(); + Set<String> intersection = new HashSet<String>(); + while (itr.hasNext()) { + String temp = itr.next(); + if (s.types.keySet().contains(temp)) { + intersection.add(temp); + } + } + if (this.complete) { + Set<String> temp = new HashSet<String>(s.types.keySet()); + temp.removeAll(intersection); + if (!temp.equals(new HashSet<String>())) { + return false; + } + } + + if (s.complete) { + Set<String> temp = new HashSet<String>(this.types.keySet()); + temp.removeAll(intersection); + if (!temp.equals(new HashSet<String>())) { + return false; + } + } + Iterator<Entry<String, BType>> iterator = types.entrySet() + .iterator(); + while (iterator.hasNext()) { + Entry<String, BType> next = iterator.next(); + String name = next.getKey(); + BType value = next.getValue(); + if (!this.types.get(name).compare(value)) { + return false; + } + } + return true; + } + return false; + } + + @Override + public boolean contains(BType other) { + Iterator<BType> itr = types.values().iterator(); + while (itr.hasNext()) { + BType t = itr.next(); + if (t.equals(other)) { + return true; + } + if (t instanceof AbstractHasFollowers) { + if (((AbstractHasFollowers) t).contains(other)) { + return true; + } + } + } + return false; + } + + public boolean containsInfiniteType() { + Iterator<BType> iterator = this.types.values().iterator(); + while (iterator.hasNext()) { + if (iterator.next().containsInfiniteType()) + return true; + } + return false; + } + + public PExpression createASTNode(Typechecker typechecker) { + ArrayList<PRecEntry> list = new ArrayList<PRecEntry>(); + + Set<Entry<String, BType>> entrySet = this.types.entrySet(); + for (Entry<String, BType> entry : entrySet) { + String name = entry.getKey(); + BType type = entry.getValue(); + TIdentifierLiteral literal = new TIdentifierLiteral(name); + ArrayList<TIdentifierLiteral> idList = new ArrayList<TIdentifierLiteral>(); + idList.add(literal); + AIdentifierExpression id = new AIdentifierExpression(idList); + ARecEntry recEntry = new ARecEntry(id, + type.createASTNode(typechecker)); + list.add(recEntry); + } + AStructExpression node = new AStructExpression(list); + typechecker.setType(node, new SetType(this)); + return node; + } + +} diff --git a/src/main/java/de/tlc4b/btypes/UntypedType.java b/src/main/java/de/tlc4b/btypes/UntypedType.java index 2d1eee0ce0f77b006f666a19e3d49a38c9ae64b3..8803c34d3c2e86d4de24c567bd6e830f233cd0b5 100644 --- a/src/main/java/de/tlc4b/btypes/UntypedType.java +++ b/src/main/java/de/tlc4b/btypes/UntypedType.java @@ -1,34 +1,34 @@ -package de.tlc4b.btypes; - -import de.be4.classicalb.core.parser.node.PExpression; -import de.tlc4b.analysis.Typechecker; - -public class UntypedType extends AbstractHasFollowers { - - public BType unify(BType other, ITypechecker typechecker) { - this.setFollowersTo(other, typechecker); - return other; - } - - public boolean isUntyped() { - return true; - } - - public boolean compare(BType other) { - return true; - } - - @Override - public boolean contains(BType other) { - return false; - } - - public boolean containsInfiniteType() { - return false; - } - - public PExpression createASTNode(Typechecker typechecker) { - return null; - } - -} +package de.tlc4b.btypes; + +import de.be4.classicalb.core.parser.node.PExpression; +import de.tlc4b.analysis.Typechecker; + +public class UntypedType extends AbstractHasFollowers { + + public BType unify(BType other, ITypechecker typechecker) { + this.setFollowersTo(other, typechecker); + return other; + } + + public boolean isUntyped() { + return true; + } + + public boolean compare(BType other) { + return true; + } + + @Override + public boolean contains(BType other) { + return false; + } + + public boolean containsInfiniteType() { + return false; + } + + public PExpression createASTNode(Typechecker typechecker) { + return null; + } + +} diff --git a/src/main/java/de/tlc4b/exceptions/ScopeException.java b/src/main/java/de/tlc4b/exceptions/ScopeException.java index 2a38f1c2016a2ce5f46f719f406cdc8b81071bc7..c6acf285131f93271bbe6787304faddb40b670d1 100644 --- a/src/main/java/de/tlc4b/exceptions/ScopeException.java +++ b/src/main/java/de/tlc4b/exceptions/ScopeException.java @@ -1,15 +1,15 @@ -package de.tlc4b.exceptions; - -@SuppressWarnings("serial") -public class ScopeException extends TLC4BException{ - - public ScopeException(String e){ - super(e); - } - - @Override - public String getError() { - return "ScopeException"; - } - -} +package de.tlc4b.exceptions; + +@SuppressWarnings("serial") +public class ScopeException extends TLC4BException{ + + public ScopeException(String e){ + super(e); + } + + @Override + public String getError() { + return "ScopeException"; + } + +} diff --git a/src/main/java/de/tlc4b/exceptions/SubstitutionException.java b/src/main/java/de/tlc4b/exceptions/SubstitutionException.java index 0dc1d3af77064354d3f989deb18e654ed7a309c7..fd8b81fb00372e7a2250fdd4a8c9678247bc9860 100644 --- a/src/main/java/de/tlc4b/exceptions/SubstitutionException.java +++ b/src/main/java/de/tlc4b/exceptions/SubstitutionException.java @@ -1,15 +1,15 @@ -package de.tlc4b.exceptions; - -@SuppressWarnings("serial") -public class SubstitutionException extends TLC4BException{ - - public SubstitutionException(String e) { - super(e); - } - - @Override - public String getError() { - return "SubstitutionError"; - } - -} +package de.tlc4b.exceptions; + +@SuppressWarnings("serial") +public class SubstitutionException extends TLC4BException{ + + public SubstitutionException(String e) { + super(e); + } + + @Override + public String getError() { + return "SubstitutionError"; + } + +} diff --git a/src/main/java/de/tlc4b/exceptions/TLC4BException.java b/src/main/java/de/tlc4b/exceptions/TLC4BException.java index 5c4090a5698ebf1c4b1f38a5b87e30318d99eb9c..f9e14ea9b66948ccb78399fce3e494d5fd42b7df 100644 --- a/src/main/java/de/tlc4b/exceptions/TLC4BException.java +++ b/src/main/java/de/tlc4b/exceptions/TLC4BException.java @@ -1,12 +1,12 @@ -package de.tlc4b.exceptions; - -@SuppressWarnings("serial") -public abstract class TLC4BException extends RuntimeException { - - public TLC4BException(String e) { - super(e); - } - - public abstract String getError(); - -} +package de.tlc4b.exceptions; + +@SuppressWarnings("serial") +public abstract class TLC4BException extends RuntimeException { + + public TLC4BException(String e) { + super(e); + } + + public abstract String getError(); + +} diff --git a/src/main/java/de/tlc4b/exceptions/TypeErrorException.java b/src/main/java/de/tlc4b/exceptions/TypeErrorException.java index 77a201ccad0ae6e7dfd920c5005fbb09d48d005e..c0f72dd0eb9e5f64bb7536d7c7ad202e998cd92e 100644 --- a/src/main/java/de/tlc4b/exceptions/TypeErrorException.java +++ b/src/main/java/de/tlc4b/exceptions/TypeErrorException.java @@ -1,14 +1,14 @@ -package de.tlc4b.exceptions; - -@SuppressWarnings("serial") -public class TypeErrorException extends TLC4BException { - - public TypeErrorException(String e) { - super(e); - } - - @Override - public String getError() { - return "TypeError"; - } -} +package de.tlc4b.exceptions; + +@SuppressWarnings("serial") +public class TypeErrorException extends TLC4BException { + + public TypeErrorException(String e) { + super(e); + } + + @Override + public String getError() { + return "TypeError"; + } +} diff --git a/src/main/java/de/tlc4b/exceptions/UnificationException.java b/src/main/java/de/tlc4b/exceptions/UnificationException.java index 676d270928b5cbd3e8ff4b633cf5f3d0c5dbacbb..4e0d579af2d6189f5cc0bdb0c1ac1139aa0fe3ee 100644 --- a/src/main/java/de/tlc4b/exceptions/UnificationException.java +++ b/src/main/java/de/tlc4b/exceptions/UnificationException.java @@ -1,10 +1,10 @@ -package de.tlc4b.exceptions; - -@SuppressWarnings("serial") -public class UnificationException extends RuntimeException{ - - public UnificationException() { - super(""); - } - -} +package de.tlc4b.exceptions; + +@SuppressWarnings("serial") +public class UnificationException extends RuntimeException{ + + public UnificationException() { + super(""); + } + +} diff --git a/src/main/java/de/tlc4b/ltl/LTLFormulaPrinter.java b/src/main/java/de/tlc4b/ltl/LTLFormulaPrinter.java index cdf903e66e708c231425bd23a99a46bdc93b5054..012e21779354845c12c7b2d4052433afd2af138f 100644 --- a/src/main/java/de/tlc4b/ltl/LTLFormulaPrinter.java +++ b/src/main/java/de/tlc4b/ltl/LTLFormulaPrinter.java @@ -127,8 +127,13 @@ public class LTLFormulaPrinter extends DepthFirstAdapter { @Override public void caseAEnabledLtl(AEnabledLtl node) { + LinkedHashMap<String, Node> operations = ltlFormulaVisitor + .getMachineContext().getOperations(); tlaPrinter.moduleStringAppend("ENABLED("); - tlaPrinter.moduleStringAppend(node.getOperation().getText()); + //tlaPrinter.moduleStringAppend(node.getOperation().getText()); + String action1Name = node.getOperation().getText(); + Node op1 = operations.get(action1Name); + tlaPrinter.printOperationCall(op1); tlaPrinter.moduleStringAppend(")"); } diff --git a/src/main/java/de/tlc4b/prettyprint/TLAPrinter.java b/src/main/java/de/tlc4b/prettyprint/TLAPrinter.java index 9504f362b72e2e4dd502e204e15721b1dafeb9e3..da66c6a45a33fe015c5b2472a173a8a549cfb71e 100644 --- a/src/main/java/de/tlc4b/prettyprint/TLAPrinter.java +++ b/src/main/java/de/tlc4b/prettyprint/TLAPrinter.java @@ -1,3056 +1,3056 @@ -package de.tlc4b.prettyprint; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; - -import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; -import de.be4.classicalb.core.parser.node.*; -import de.be4.classicalb.core.parser.util.Utils; -import de.tlc4b.TLC4BGlobals; -import de.tlc4b.analysis.MachineContext; -import de.tlc4b.analysis.PrecedenceCollector; -import de.tlc4b.analysis.PrimedNodesMarker; -import de.tlc4b.analysis.Renamer; -import de.tlc4b.analysis.StandardMadules; -import de.tlc4b.analysis.Typechecker; -import de.tlc4b.analysis.UsedStandardModules; -import de.tlc4b.analysis.typerestriction.TypeRestrictor; -import de.tlc4b.analysis.unchangedvariables.InvariantPreservationAnalysis; -import de.tlc4b.analysis.unchangedvariables.UnchangedVariablesFinder; -import de.tlc4b.btypes.BType; -import de.tlc4b.btypes.FunctionType; -import de.tlc4b.btypes.IntegerType; -import de.tlc4b.btypes.PairType; -import de.tlc4b.btypes.SetType; -import de.tlc4b.btypes.StructType; -import de.tlc4b.btypes.UntypedType; -import de.tlc4b.ltl.LTLFormulaVisitor; -import de.tlc4b.tla.ConfigFile; -import de.tlc4b.tla.TLADefinition; -import de.tlc4b.tla.TLAModule; -import de.tlc4b.tla.config.ConfigFileAssignment; -import static de.tlc4b.analysis.StandardMadules.*; - -public class TLAPrinter extends DepthFirstAdapter { - - private StringBuilder tlaModuleString; - private StringBuilder configFileString; - - public StringBuilder getConfigString() { - return configFileString; - } - - public StringBuilder getStringbuilder() { - return tlaModuleString; - } - - private MachineContext machineContext; - private Typechecker typechecker; - private UnchangedVariablesFinder missingVariableFinder; - private PrecedenceCollector precedenceCollector; - private UsedStandardModules usedStandardModules; - private TypeRestrictor typeRestrictor; - private TLAModule tlaModule; - private ConfigFile configFile; - private PrimedNodesMarker primedNodesMarker; - private Renamer renamer; - private boolean recordLTLFormula = false; - private StringBuilder translatedLTLFormula = new StringBuilder(); - private final InvariantPreservationAnalysis invariantPreservationAnalysis; - - public TLAPrinter(MachineContext machineContext, Typechecker typechecker, - UnchangedVariablesFinder unchangedVariablesFinder, - PrecedenceCollector precedenceCollector, - UsedStandardModules usedStandardModules, - TypeRestrictor typeRestrictor, TLAModule tlaModule, - ConfigFile configFile, PrimedNodesMarker primedNodesMarker, - Renamer renamer, - InvariantPreservationAnalysis invariantPreservationAnalysis) { - this.typechecker = typechecker; - this.machineContext = machineContext; - this.missingVariableFinder = unchangedVariablesFinder; - this.precedenceCollector = precedenceCollector; - this.usedStandardModules = usedStandardModules; - this.typeRestrictor = typeRestrictor; - this.tlaModule = tlaModule; - this.configFile = configFile; - this.primedNodesMarker = primedNodesMarker; - this.renamer = renamer; - this.invariantPreservationAnalysis = invariantPreservationAnalysis; - - this.tlaModuleString = new StringBuilder(); - this.configFileString = new StringBuilder(); - } - - public void start() { - printHeader(); - printExtendedModules(); - printConstants(); - printVariables(); - printDefinitions(); - printAssume(); - printInvariant(); - printAssertions(); - printInit(); - printOperations(); - printSpecFormula(); - printLTLFormulas(); - - printSymmetry(); - - moduleStringAppend("===="); - - printConfig(); - } - - private void printSymmetry() { - - if (TLC4BGlobals.useSymmetry() - && machineContext.getDeferredSets().size() > 0) { - - moduleStringAppend("Symmetry == "); - Collection<Node> values = machineContext.getDeferredSets().values(); - ArrayList<Node> array = new ArrayList<Node>(values); - for (int i = 0; i < array.size(); i++) { - Node node = array.get(i); - moduleStringAppend("Permutations("); - node.apply(this); - moduleStringAppend(")"); - if (i < array.size() - 1) { - moduleStringAppend(" \\cup "); - } - } - moduleStringAppend("\n"); - // Symmetry == Permutations(Clients) \cup Permutations(Resources) - } - } - - private void printSpecFormula() { - - if (this.configFile.isSpec()) { - moduleStringAppend("vars == "); - printVarsAsTuple(); - moduleStringAppend("\n"); - - moduleStringAppend("VWF == "); - printWeakFairness("Next"); - moduleStringAppend("\n"); - moduleStringAppend("Spec == Init /\\ [][Next]_vars /\\ VWF\n"); - } - - } - - public void printStrongFairness(String s) { - - moduleStringAppend(String - .format("([]<><<%s>>_vars \\/ <>[]~ENABLED(%s) \\/ []<> ENABLED(%s /\\ ", - s, s, s)); - printVarsStuttering(); - moduleStringAppend("))"); - - } - - public void printWeakFairness(String s) { - moduleStringAppend(String - .format("([]<><<%s>>_vars \\/ []<>~ENABLED(%s) \\/ []<> ENABLED(%s /\\ ", - s, s, s)); - printVarsStuttering(); - moduleStringAppend("))"); - - } - - public void printWeakFairnessWithParameter(String s) { - Node operation = machineContext.getOperations().get(s.trim()); - - moduleStringAppend("([]<><<"); - printOperationCall(operation); - moduleStringAppend(">>_vars \\/ []<>~ENABLED("); - printOperationCall(operation); - moduleStringAppend(") \\/ []<> ENABLED("); - printOperationCall(operation); - moduleStringAppend(" /\\ "); - printVarsStuttering(); - moduleStringAppend("))"); - - } - - private void printVarsStuttering() { - ArrayList<Node> vars = this.tlaModule.getVariables(); - for (int i = 0; i < vars.size(); i++) { - vars.get(i).apply(this); - moduleStringAppend("' = "); - vars.get(i).apply(this); - if (i < vars.size() - 1) - moduleStringAppend(" /\\ "); - } - } - - private void printVarsAsTuple() { - ArrayList<Node> vars = this.tlaModule.getVariables(); - if (vars.size() == 0) - return; - moduleStringAppend("<<"); - for (int i = 0; i < vars.size(); i++) { - vars.get(i).apply(this); - if (i < vars.size() - 1) - moduleStringAppend(","); - } - moduleStringAppend(">>"); - } - - private void printLTLFormulas() { - ArrayList<LTLFormulaVisitor> visitors = machineContext.getLTLFormulas(); - if (TLC4BGlobals.isCheckLTL()) { - for (int i = 0; i < visitors.size(); i++) { - LTLFormulaVisitor visitor = visitors.get(i); - moduleStringAppend(visitor.getName() + " == "); - if (TLC4BGlobals.getTestingMode() == true) { - recordLTLFormula = true; - visitor.printLTLFormula(this, typeRestrictor); - recordLTLFormula = false; - } else { - visitor.printLTLFormula(this, typeRestrictor); - } - moduleStringAppend("\n"); - } - } - } - - private void printConfig() { - if (this.configFile.isSpec()) { - this.configFileString.append("SPECIFICATION Spec\n"); - } else { - if (this.configFile.isInit()) { - this.configFileString.append("INIT Init\n"); - } - if (this.configFile.isInit()) { - this.configFileString.append("NEXT Next\n"); - } - } - if (TLC4BGlobals.isInvariant()) { - for (int i = 0; i < configFile.getInvariantNumber(); i++) { - this.configFileString.append("INVARIANT Invariant" + (i + 1) - + "\n"); - } - } - - if (configFile.isGoal()) { - this.configFileString.append("INVARIANT NotGoal\n"); - } - - if (TLC4BGlobals.isAssertion() && tlaModule.hasInitPredicate()) { - for (int i = 0; i < configFile.getAssertionSize(); i++) { - this.configFileString.append("INVARIANT Assertion") - .append(i + 1).append("\n"); - } - } - - if (TLC4BGlobals.isCheckLTL()) { - for (int i = 0; i < machineContext.getLTLFormulas().size(); i++) { - LTLFormulaVisitor ltlVisitor = machineContext.getLTLFormulas() - .get(i); - this.configFileString.append("PROPERTIES " - + ltlVisitor.getName() + "\n"); - } - } - // CONSTANTS - ArrayList<ConfigFileAssignment> assignments = configFile - .getAssignments(); - if (assignments.size() != 0) { - configFileString.append("CONSTANTS\n"); - for (int i = 0; i < assignments.size(); i++) { - configFileString.append(assignments.get(i).getString(renamer)); - } - } - if (TLC4BGlobals.useSymmetry() - && machineContext.getDeferredSets().size() > 0) { - configFileString.append("SYMMETRY Symmetry\n"); - } - - if (TLC4BGlobals.isPartialInvariantEvaluation()) { - configFileString.append("CONSTANTS\n"); - configFileString.append("Init_action = Init_action\n"); - - ArrayList<POperation> operations = tlaModule.getOperations(); - for (int i = 0; i < operations.size(); i++) { - AOperation node = (AOperation) operations.get(i); - String name = renamer.getNameOfRef(node); - String actionName = name + "actions"; - configFileString.append(actionName).append(" = ") - .append(actionName); - configFileString.append("\n"); - } - configFileString.append("\n"); - configFileString.append("VIEW myView"); - } - - } - - public void moduleStringAppend(String str) { - tlaModuleString.append(str); - if (recordLTLFormula) { - translatedLTLFormula.append(str); - } - } - - private void printHeader() { - moduleStringAppend("---- MODULE "); - moduleStringAppend(this.tlaModule.getModuleName()); - moduleStringAppend(" ----\n"); - } - - private void printExtendedModules() { - if (usedStandardModules.getExtendedModules().size() > 0) { - moduleStringAppend("EXTENDS "); - for (int i = 0; i < usedStandardModules.getExtendedModules().size(); i++) { - if (i > 0) { - moduleStringAppend(", "); - } - moduleStringAppend(usedStandardModules.getExtendedModules() - .get(i).toString()); - } - moduleStringAppend("\n"); - } - } - - private void printDefinitions() { - ArrayList<TLADefinition> definitions = tlaModule.getTLADefinitions(); - for (int i = 0; i < definitions.size(); i++) { - TLADefinition def = definitions.get(i); - if (def.getDefName() instanceof AEnumeratedSetSet) { - def.getDefName().apply(this); - continue; - } - def.getDefName().apply(this); - - moduleStringAppend(" == "); - Node e = def.getDefinition(); - if (e == null) { - moduleStringAppend(def.getInt().toString()); - } else { - e.apply(this); - } - moduleStringAppend("\n"); - } - - ArrayList<PDefinition> bDefinitions = tlaModule.getAllDefinitions(); - if (null == bDefinitions) { - return; - } - for (PDefinition node : bDefinitions) { - node.apply(this); - } - if (configFile.isGoal()) { - moduleStringAppend("NotGoal == ~GOAL\n"); - } - } - - private void printConstants() { - if (TLC4BGlobals.isPartialInvariantEvaluation()) { - ArrayList<POperation> operations = tlaModule.getOperations(); - moduleStringAppend("CONSTANTS Init_action, "); - for (int i = 0; i < operations.size(); i++) { - AOperation node = (AOperation) operations.get(i); - String name = renamer.getNameOfRef(node); - moduleStringAppend(name + "_action"); - - if (i < operations.size() - 1) - moduleStringAppend(", "); - } - moduleStringAppend("\n"); - } - /******************/ - ArrayList<Node> list = this.tlaModule.getConstants(); - if (list.size() == 0) - return; - moduleStringAppend("CONSTANTS "); - for (int i = 0; i < list.size(); i++) { - Node con = list.get(i); - con.apply(this); - - if (i < list.size() - 1) - moduleStringAppend(", "); - } - moduleStringAppend("\n"); - } - - private void printAssume() { - ArrayList<Node> list = this.tlaModule.getAssume(); - if (list.size() == 0) - return; - - for (int i = 0; i < list.size(); i++) { - Node node = list.get(i); - if(!typeRestrictor.isARemovedNode(node)){ - moduleStringAppend("ASSUME "); - list.get(i).apply(this); - moduleStringAppend("\n"); - } - } - - } - - private void printVariables() { - ArrayList<Node> vars = this.tlaModule.getVariables(); - if (vars.size() == 0) - return; - moduleStringAppend("VARIABLES "); - for (int i = 0; i < vars.size(); i++) { - vars.get(i).apply(this); - if (i < vars.size() - 1) { - moduleStringAppend(", "); - } - - } - if (TLC4BGlobals.isPartialInvariantEvaluation()) { - moduleStringAppend(", last_action"); - } - moduleStringAppend("\n"); - - if (TLC4BGlobals.isPartialInvariantEvaluation()) { - moduleStringAppend("myView == <<"); - for (int i = 0; i < vars.size(); i++) { - vars.get(i).apply(this); - if (i < vars.size() - 1) - moduleStringAppend(", "); - } - moduleStringAppend(">>\n"); - } - } - - private void printInvariant() { - ArrayList<Node> invariants = this.tlaModule.getInvariantList(); - for (int i = 0; i < invariants.size(); i++) { - Node inv = invariants.get(i); - moduleStringAppend("Invariant" + (i + 1) + " == "); - if (TLC4BGlobals.isPartialInvariantEvaluation()) { - ArrayList<Node> operations = invariantPreservationAnalysis - .getPreservingOperations(inv); - if (operations.size() > 0) { - moduleStringAppend("last_action \\in {"); - for (int j = 0; j < operations.size(); j++) { - Node op = operations.get(j); - String name = renamer.getNameOfRef(op); - moduleStringAppend(name); - moduleStringAppend("_action"); - if (j < operations.size() - 1) { - moduleStringAppend(", "); - } - } - moduleStringAppend("} \\/ "); - } - } - inv.apply(this); - moduleStringAppend("\n"); - } - } - - private void printAssertions() { - if (TLC4BGlobals.isAssertion()) { - ArrayList<Node> assertions = tlaModule.getAssertions(); - if (assertions.size() == 0) - return; - for (int i = 0; i < assertions.size(); i++) { - Node assertion = assertions.get(i); - String name = null; - if (assertion instanceof ALabelPredicate) { - ALabelPredicate label = (ALabelPredicate) assertion; - name = label.getName().getText(); - } - - if (name == null) { - name = "Assertion" + (i + 1); - } - - if (tlaModule.hasInitPredicate()) { - moduleStringAppend(name); - moduleStringAppend(" == "); - } else { - moduleStringAppend("ASSUME "); - moduleStringAppend(name); - moduleStringAppend(" == "); - } - // assertionMode = true; - // assertionName = name; - // parameterCounter = 0; - assertion.apply(this); - // assertionMode = false; - moduleStringAppend("\n"); - } - } - } - - private static boolean assertionMode = false; - private static String assertionName = null; - private static Integer parameterCounter = 0; - - private void printInit() { - ArrayList<Node> inits = this.tlaModule.getInitPredicates(); - if (inits.size() == 0) - return; - moduleStringAppend("Init == "); - if (inits.size() > 1) - moduleStringAppend("\n\t/\\ "); - for (int i = 0; i < inits.size(); i++) { - Node init = inits.get(i); - if (init instanceof ADisjunctPredicate) { - moduleStringAppend("("); - } - init.apply(this); - if (init instanceof ADisjunctPredicate) { - moduleStringAppend(")"); - } - if (TLC4BGlobals.isPartialInvariantEvaluation()) { - moduleStringAppend(" /\\ last_action = Init_action"); - } - if (i < inits.size() - 1) - moduleStringAppend("\n\t/\\ "); - } - moduleStringAppend("\n\n"); - } - - private void printOperations() { - ArrayList<POperation> ops = this.tlaModule.getOperations(); - if (ops.size() == 0) { - ArrayList<Node> vars = tlaModule.getVariables(); - if (vars.size() > 0) { - moduleStringAppend("Next == 1 = 2 /\\ UNCHANGED <<"); - for (int i = 0; i < vars.size(); i++) { - vars.get(i).apply(this); - if (i < vars.size() - 1) { - moduleStringAppend(", "); - } - } - moduleStringAppend(">>\n"); - } - return; - } - for (int i = 0; i < ops.size(); i++) { - ops.get(i).apply(this); - } - moduleStringAppend("Next == \\/ "); - Iterator<Node> itr = this.machineContext.getOperations().values() - .iterator(); - while (itr.hasNext()) { - Node operation = itr.next(); - printOperationCall(operation); - - if (itr.hasNext()) { - moduleStringAppend("\n\t\\/ "); - } - } - moduleStringAppend("\n"); - } - - public void printOperationCall(Node operation) { - AOperation op = (AOperation) operation; - List<PExpression> newList = new ArrayList<PExpression>(); - newList.addAll(op.getParameters()); - // newList.addAll(op.getReturnValues()); - if (newList.size() > 0) { - moduleStringAppend("\\E "); - for (int i = 0; i < newList.size(); i++) { - PExpression e = newList.get(i); - e.apply(this); - moduleStringAppend(" \\in "); - typeRestrictor.getRestrictedNode(e).apply(this); - ; - if (i < newList.size() - 1) { - moduleStringAppend(", "); - } - } - moduleStringAppend(" : "); - } - - String opName = renamer.getNameOfRef(op); - moduleStringAppend(opName); - if (newList.size() > 0) { - moduleStringAppend("("); - for (int i = 0; i < newList.size(); i++) { - newList.get(i).apply(this); - if (i < newList.size() - 1) { - moduleStringAppend(", "); - } - - } - moduleStringAppend(")"); - } - } - - @Override - public void defaultIn(final Node node) { - if (precedenceCollector.getBrackets().contains(node)) { - moduleStringAppend("("); - } - } - - @Override - public void defaultOut(final Node node) { - if (precedenceCollector.getBrackets().contains(node)) { - moduleStringAppend(")"); - } - } - - /* - * Treewalker - */ - - @Override - public void caseAMachineHeader(AMachineHeader node) { - inAMachineHeader(node); - moduleStringAppend(node.toString()); - { - List<TIdentifierLiteral> copy = new ArrayList<TIdentifierLiteral>( - node.getName()); - for (TIdentifierLiteral e : copy) { - e.apply(this); - } - } - { - List<PExpression> copy = new ArrayList<PExpression>( - node.getParameters()); - for (PExpression e : copy) { - e.apply(this); - } - } - outAMachineHeader(node); - } - - @Override - public void caseAEnumeratedSetSet(AEnumeratedSetSet node) { - List<PExpression> copy = new ArrayList<PExpression>(node.getElements()); - moduleStringAppend(renamer.getNameOfRef(node) + " == {"); - for (int i = 0; i < copy.size(); i++) { - copy.get(i).apply(this); - if (i < copy.size() - 1) { - moduleStringAppend(", "); - } - } - moduleStringAppend("}\n"); - } - - @Override - public void caseADeferredSetSet(ADeferredSetSet node) { - String name = renamer.getName(node); - moduleStringAppend(name); - } - - /** - * Substitutions - * - */ - - @Override - public void caseABecomesElementOfSubstitution( - ABecomesElementOfSubstitution node) { - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (int i = 0; i < copy.size(); i++) { - if (i != 0) { - moduleStringAppend(" /\\ "); - } - copy.get(i).apply(this); - moduleStringAppend(" \\in "); - node.getSet().apply(this); - } - printUnchangedVariables(node, true); - } - - @Override - public void caseAAssignSubstitution(AAssignSubstitution node) { - List<PExpression> copy = new ArrayList<PExpression>( - node.getLhsExpression()); - List<PExpression> copy2 = new ArrayList<PExpression>( - node.getRhsExpressions()); - - for (int i = 0; i < copy.size(); i++) { - PExpression left = copy.get(i); - PExpression right = copy2.get(i); - - if (left instanceof AFunctionExpression) { - printFunctionAssignment(left, right); - - } else { - printNormalAssignment(left, right); - } - - if (i < copy.size() - 1) { - moduleStringAppend(" /\\ "); - } - } - - printUnchangedVariables(node, true); - } - - @Override - public void caseABecomesSuchSubstitution(ABecomesSuchSubstitution node) { - inABecomesSuchSubstitution(node); - if (node.getPredicate() instanceof AExistsPredicate) { - node.getPredicate().apply(this); - } else { - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - - for (int i = 0; i < copy.size(); i++) { - PExpression e = copy.get(i); - e.apply(this); - moduleStringAppend(" \\in "); - typeRestrictor.getRestrictedNode(e).apply(this); - if (i < copy.size() - 1) { - moduleStringAppend(" /\\ "); - } - } - - if (!typeRestrictor.isARemovedNode(node.getPredicate())) { - moduleStringAppend(" /\\ "); - node.getPredicate().apply(this); - } - } - - printUnchangedVariables(node, true); - outABecomesSuchSubstitution(node); - } - - private void printNormalAssignment(PExpression left, PExpression right) { - AIdentifierExpression id = (AIdentifierExpression) left; - String name = Utils.getTIdentifierListAsString(id.getIdentifier()); - if (!machineContext.getVariables().containsKey(name)) { - moduleStringAppend("TRUE"); - } else { - left.apply(this); - moduleStringAppend(" = "); - right.apply(this); - } - } - - private void printFunctionAssignment(PExpression left, PExpression right) { - PExpression var = ((AFunctionExpression) left).getIdentifier(); - LinkedList<PExpression> params = ((AFunctionExpression) left) - .getParameters(); - BType type = typechecker.getType(var); - if (type instanceof FunctionType) { - var.apply(this); - moduleStringAppend("' = "); - moduleStringAppend(FUNC_ASSIGN); - moduleStringAppend("("); - var.apply(this); - moduleStringAppend(", "); - if (params.size() > 1) { - moduleStringAppend("<<"); - } - for (Iterator<PExpression> iterator = params.iterator(); iterator - .hasNext();) { - PExpression pExpression = (PExpression) iterator.next(); - pExpression.apply(this); - if (iterator.hasNext()) { - moduleStringAppend(", "); - } - } - if (params.size() > 1) { - moduleStringAppend(">>"); - } - moduleStringAppend(", "); - right.apply(this); - moduleStringAppend(")"); - } else { - var.apply(this); - moduleStringAppend("' = "); - moduleStringAppend(REL_OVERRIDING + "("); - var.apply(this); - moduleStringAppend(", {<<"); - - if (params.size() > 1) { - moduleStringAppend("<<"); - for (Iterator<PExpression> iterator = params.iterator(); iterator - .hasNext();) { - PExpression pExpression = (PExpression) iterator.next(); - pExpression.apply(this); - if (iterator.hasNext()) { - moduleStringAppend(", "); - } - } - moduleStringAppend(">>"); - } else { - params.get(0).apply(this); - } - moduleStringAppend(", "); - right.apply(this); - moduleStringAppend(">>})"); - } - } - - public void printUnchangedVariables(Node node, boolean printAnd) { - HashSet<Node> unchangedVariablesSet = missingVariableFinder - .getUnchangedVariables(node); - if (null != unchangedVariablesSet) { - ArrayList<Node> unchangedVariables = new ArrayList<Node>( - unchangedVariablesSet); - if (unchangedVariables.size() > 0) { - if (printAnd) { - moduleStringAppend(" /\\"); - } - moduleStringAppend(" UNCHANGED <<"); - for (int i = 0; i < unchangedVariables.size(); i++) { - unchangedVariables.get(i).apply(this); - if (i < unchangedVariables.size() - 1) { - moduleStringAppend(", "); - } - } - moduleStringAppend(">>"); - } else { - if (!printAnd) { - // there is already a /\ - moduleStringAppend("TRUE"); - } - } - } - } - - @Override - public void caseAChoiceSubstitution(AChoiceSubstitution node) { - List<PSubstitution> copy = new ArrayList<PSubstitution>( - node.getSubstitutions()); - moduleStringAppend("("); - for (int i = 0; i < copy.size(); i++) { - moduleStringAppend("("); - copy.get(i).apply(this); - moduleStringAppend(")"); - if (i < copy.size() - 1) { - moduleStringAppend(" \\/ "); - } - - } - moduleStringAppend(")"); - printUnchangedVariables(node, true); - } - - @Override - public void caseASkipSubstitution(ASkipSubstitution node) { - printUnchangedVariables(node, false); - } - - @Override - public void caseAIfSubstitution(AIfSubstitution node) { - if (node.getElsifSubstitutions().size() > 0) { - printElseIFSubsitution(node); - return; - } - moduleStringAppend("(IF "); - node.getCondition().apply(this); - moduleStringAppend(" THEN "); - node.getThen().apply(this); - List<PSubstitution> copy = new ArrayList<PSubstitution>( - node.getElsifSubstitutions()); - for (PSubstitution e : copy) { - e.apply(this); - } - moduleStringAppend(" ELSE "); - if (node.getElse() != null) { - node.getElse().apply(this); - } else { - printUnchangedVariablesNull(node, false); - } - - moduleStringAppend(")"); - printUnchangedVariables(node, true); - } - - private void printElseIFSubsitution(AIfSubstitution node) { - moduleStringAppend("(CASE "); - node.getCondition().apply(this); - moduleStringAppend(" -> "); - node.getThen().apply(this); - List<PSubstitution> copy = new ArrayList<PSubstitution>( - node.getElsifSubstitutions()); - for (PSubstitution e : copy) { - moduleStringAppend(" [] "); - e.apply(this); - } - moduleStringAppend(" [] OTHER -> "); - if (node.getElse() != null) { - node.getElse().apply(this); - } else { - printUnchangedVariablesNull(node, false); - } - moduleStringAppend(")"); - printUnchangedVariables(node, true); - - } - - @Override - public void caseAIfElsifSubstitution(AIfElsifSubstitution node) { - node.getCondition().apply(this); - moduleStringAppend(" -> "); - node.getThenSubstitution().apply(this); - printUnchangedVariables(node, true); - - } - - public void printUnchangedVariablesNull(Node node, boolean printAnd) { - HashSet<Node> unchangedVariablesSet = missingVariableFinder - .getUnchangedVariablesNull(node); - if (null != unchangedVariablesSet) { - ArrayList<Node> unchangedVariables = new ArrayList<Node>( - unchangedVariablesSet); - if (unchangedVariables.size() > 0) { - if (printAnd) { - moduleStringAppend(" /\\"); - } - moduleStringAppend(" UNCHANGED <<"); - for (int i = 0; i < unchangedVariables.size(); i++) { - unchangedVariables.get(i).apply(this); - if (i < unchangedVariables.size() - 1) { - moduleStringAppend(", "); - } - } - moduleStringAppend(">>"); - } - } - } - - @Override - public void caseAParallelSubstitution(AParallelSubstitution node) { - inAParallelSubstitution(node); - for (Iterator<PSubstitution> itr = node.getSubstitutions().iterator(); itr - .hasNext();) { - PSubstitution e = itr.next(); - - e.apply(this); - - if (itr.hasNext()) { - moduleStringAppend(" /\\ "); - } - } - - printUnchangedVariables(node, true); - outAParallelSubstitution(node); - } - - @Override - public void caseAPreconditionSubstitution(APreconditionSubstitution node) { - inAPreconditionSubstitution(node); - if (!typeRestrictor.isARemovedNode(node.getPredicate())) { - node.getPredicate().apply(this); - moduleStringAppend("\n\t/\\ "); - } - node.getSubstitution().apply(this); - - outAPreconditionSubstitution(node); - } - - @Override - public void caseAAssertionSubstitution(AAssertionSubstitution node) { - inAAssertionSubstitution(node); - node.getPredicate().apply(this); - moduleStringAppend("\n\t/\\ "); - node.getSubstitution().apply(this); - outAAssertionSubstitution(node); - } - - @Override - public void caseASelectSubstitution(ASelectSubstitution node) { - inASelectSubstitution(node); - // TODO remove brackets - moduleStringAppend("("); - List<PSubstitution> copy = new ArrayList<PSubstitution>( - node.getWhenSubstitutions()); - - if (missingVariableFinder.hasUnchangedVariables(node) - && (copy.size() > 0 || node.getElse() != null)) { - moduleStringAppend("("); - } - if (!typeRestrictor.isARemovedNode(node.getCondition())) { - if (copy.size() > 0 || node.getElse() != null) { - moduleStringAppend("("); - } - node.getCondition().apply(this); - moduleStringAppend(" /\\ "); - } - node.getThen().apply(this); - if (!typeRestrictor.isARemovedNode(node.getCondition())) { - if (copy.size() > 0 || node.getElse() != null) { - moduleStringAppend(")"); - } - } - - for (PSubstitution e : copy) { - moduleStringAppend(" \\/ "); - e.apply(this); - } - if (node.getElse() != null) { - moduleStringAppend(" \\/ ("); - moduleStringAppend("~("); - for (PSubstitution e : copy) { - ASelectWhenSubstitution w = (ASelectWhenSubstitution) e; - moduleStringAppend(" \\/ "); - w.getCondition().apply(this); - } - moduleStringAppend(")"); - moduleStringAppend(" /\\ "); - node.getElse().apply(this); - moduleStringAppend(")"); - } - - if (missingVariableFinder.hasUnchangedVariables(node) - && (copy.size() > 0 || node.getElse() != null)) { - moduleStringAppend(")"); - } - moduleStringAppend(")"); - printUnchangedVariables(node, true); - - outASelectSubstitution(node); - } - - @Override - public void caseASelectWhenSubstitution(ASelectWhenSubstitution node) { - inASelectWhenSubstitution(node); - node.getCondition().apply(this); - moduleStringAppend(" /\\ "); - node.getSubstitution().apply(this); - outASelectWhenSubstitution(node); - } - - @Override - public void caseAAnySubstitution(AAnySubstitution node) { - inAAnySubstitution(node); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - if (copy.size() > 0) { - moduleStringAppend("\\E "); - for (int i = 0; i < copy.size(); i++) { - PExpression e = copy.get(i); - e.apply(this); - moduleStringAppend(" \\in "); - typeRestrictor.getRestrictedNode(e).apply(this); - // printTypeOfIdentifier(e, false); - if (i < copy.size() - 1) { - moduleStringAppend(", "); - } - } - moduleStringAppend(" : "); - } - - if (!typeRestrictor.isARemovedNode(node.getWhere())) { - node.getWhere().apply(this); - moduleStringAppend(" /\\ "); - } - - node.getThen().apply(this); - printUnchangedVariables(node, true); - outAAnySubstitution(node); - } - - @Override - public void caseALetSubstitution(ALetSubstitution node) { - inALetSubstitution(node); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - if (copy.size() > 0) { - moduleStringAppend("\\E "); - for (int i = 0; i < copy.size(); i++) { - PExpression e = copy.get(i); - e.apply(this); - moduleStringAppend(" \\in "); - typeRestrictor.getRestrictedNode(e).apply(this); - if (i < copy.size() - 1) { - moduleStringAppend(", "); - } - } - moduleStringAppend(" : "); - } - - if (typeRestrictor.isARemovedNode(node.getPredicate())) { - moduleStringAppend("TRUE"); - } else { - node.getPredicate().apply(this); - } - - moduleStringAppend(" /\\ "); - node.getSubstitution().apply(this); - printUnchangedVariables(node, true); - - outALetSubstitution(node); - } - - @Override - public void caseAOperation(AOperation node) { - String name = renamer.getNameOfRef(node); - moduleStringAppend(name); - - // TODO handle output parameter of a operation - // List<PExpression> output = new ArrayList<PExpression>( - // node.getReturnValues()); - List<PExpression> params = new ArrayList<PExpression>( - node.getParameters()); - List<PExpression> newList = new ArrayList<PExpression>(); - newList.addAll(params); - // newList.addAll(output); - - if (newList.size() > 0) { - moduleStringAppend("("); - for (int i = 0; i < newList.size(); i++) { - if (i != 0) { - moduleStringAppend(", "); - } - newList.get(i).apply(this); - } - moduleStringAppend(")"); - } - moduleStringAppend(" == "); - if (node.getOperationBody() != null) { - node.getOperationBody().apply(this); - } - - printUnchangedConstants(); - - if (TLC4BGlobals.isPartialInvariantEvaluation()) { - moduleStringAppend(" /\\ last_action' = "); - moduleStringAppend(name); - moduleStringAppend("_action"); - } - - moduleStringAppend("\n\n"); - } - - private void printUnchangedConstants() { - ArrayList<Node> vars = new ArrayList<Node>(tlaModule.getVariables()); - vars.removeAll(machineContext.getVariables().values()); - if (vars.size() > 0) { - moduleStringAppend(" /\\ UNCHANGED <<"); - for (int i = 0; i < vars.size(); i++) { - if (i != 0) - moduleStringAppend(", "); - vars.get(i).apply(this); - } - - moduleStringAppend(">>"); - } - } - - /** Expression **/ - - @Override - public void caseAIdentifierExpression(AIdentifierExpression node) { - inAIdentifierExpression(node); - String name = renamer.getNameOfRef(node); - if (name == null) { - name = Utils.getTIdentifierListAsString(node.getIdentifier()); - } - if (StandardMadules.isAbstractConstant(name)) { - // in order to pass the member check - moduleStringAppend("{}"); - return; - } - moduleStringAppend(name); - if (primedNodesMarker.isPrimed(node)) { - moduleStringAppend("'"); - } - outAIdentifierExpression(node); - } - - @Override - public void caseAPrimedIdentifierExpression(APrimedIdentifierExpression node) { - String name = renamer.getNameOfRef(node); - if (name == null) { - name = Utils.getTIdentifierListAsString(node.getIdentifier()); - } - moduleStringAppend(name); - } - - @Override - public void caseAStringExpression(AStringExpression node) { - inAStringExpression(node); - moduleStringAppend("\""); - moduleStringAppend(node.getContent().getText().toString()); - moduleStringAppend("\""); - outAStringExpression(node); - } - - @Override - public void caseAStringSetExpression(AStringSetExpression node) { - moduleStringAppend("STRING"); - } - - /** - * Logical Predicates - */ - - @Override - public void caseAEqualPredicate(AEqualPredicate node) { - inAEqualPredicate(node); - node.getLeft().apply(this); - moduleStringAppend(" = "); - node.getRight().apply(this); - outAEqualPredicate(node); - } - - @Override - public void caseANotEqualPredicate(ANotEqualPredicate node) { - inANotEqualPredicate(node); - node.getLeft().apply(this); - moduleStringAppend(" # "); - node.getRight().apply(this); - outANotEqualPredicate(node); - } - - @Override - public void caseAIfThenElseExpression(AIfThenElseExpression node) { - moduleStringAppend("(IF "); - node.getCondition().apply(this); - moduleStringAppend(" THEN "); - node.getThen().apply(this); - moduleStringAppend(" ELSE "); - node.getElse().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseAConjunctPredicate(AConjunctPredicate node) { - boolean left = typeRestrictor.isARemovedNode(node.getLeft()); - boolean right = typeRestrictor.isARemovedNode(node.getRight()); - - if (left && right) { - moduleStringAppend("TRUE"); - } else if (left) { - node.getRight().apply(this); - } else if (right) { - node.getLeft().apply(this); - } else { - inAConjunctPredicate(node); - node.getLeft().apply(this); - moduleStringAppend(" /\\ "); - node.getRight().apply(this); - outAConjunctPredicate(node); - } - } - - @Override - public void caseADisjunctPredicate(ADisjunctPredicate node) { - inADisjunctPredicate(node); - node.getLeft().apply(this); - moduleStringAppend(" \\/ "); - node.getRight().apply(this); - outADisjunctPredicate(node); - } - - @Override - public void caseAImplicationPredicate(AImplicationPredicate node) { - inAImplicationPredicate(node); - if (!typeRestrictor.isARemovedNode(node.getLeft())) { - node.getLeft().apply(this); - moduleStringAppend(" => "); - } - node.getRight().apply(this); - outAImplicationPredicate(node); - } - - @Override - public void caseAEquivalencePredicate(AEquivalencePredicate node) { - inAEquivalencePredicate(node); - node.getLeft().apply(this); - moduleStringAppend(" <=> "); - node.getRight().apply(this); - outAEquivalencePredicate(node); - } - - @Override - public void caseABoolSetExpression(ABoolSetExpression node) { - moduleStringAppend("BOOLEAN"); - } - - @Override - public void caseABooleanTrueExpression(ABooleanTrueExpression node) { - inABooleanTrueExpression(node); - moduleStringAppend("TRUE"); - outABooleanTrueExpression(node); - } - - @Override - public void caseABooleanFalseExpression(ABooleanFalseExpression node) { - inABooleanFalseExpression(node); - moduleStringAppend("FALSE"); - outABooleanFalseExpression(node); - } - - @Override - public void caseAForallPredicate(AForallPredicate node) { - /* - * B: !x,y(T => P) TLA: \A x \in type(x), y \in type(y): T => P - */ - inAForallPredicate(node); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - - int start = parameterCounter; - int end = parameterCounter + copy.size(); - parameterCounter = end + 1; - if (assertionMode) { - - moduleStringAppend("("); - moduleStringAppend("TLCSet("); - moduleStringAppend("" + start); - moduleStringAppend(", TRUE) /\\ "); - for (int i = start; i < end; i++) { - moduleStringAppend("TLCSet("); - moduleStringAppend("" + (i + 1)); - moduleStringAppend(", \"NULL\")"); - moduleStringAppend(" /\\ "); - } - } - - moduleStringAppend("\\A "); - for (int i = 0; i < copy.size(); i++) { - PExpression e = copy.get(i); - e.apply(this); - moduleStringAppend(" \\in "); - typeRestrictor.getRestrictedNode(e).apply(this); - if (i < copy.size() - 1) { - moduleStringAppend(", "); - } - } - moduleStringAppend(" : "); - if (assertionMode) { - for (int i = 0; i < copy.size(); i++) { - PExpression e = copy.get(i); - moduleStringAppend("TLCSet("); - moduleStringAppend("" + (i + 1)); - moduleStringAppend(", "); - e.apply(this); - moduleStringAppend(")"); - moduleStringAppend(" /\\ "); - } - - assertionMode = false; - - moduleStringAppend(" IF "); - node.getImplication().apply(this); - moduleStringAppend(" THEN TRUE "); - moduleStringAppend(" ELSE SaveValue(<< \""); - moduleStringAppend(assertionName); - moduleStringAppend("\", "); - for (int i = start; i < end; i++) { - moduleStringAppend("TLCGet("); - moduleStringAppend("" + (i + 1)); - moduleStringAppend(")"); - if (i < copy.size() - 1) { - moduleStringAppend(", "); - } - - } - moduleStringAppend(" >>) "); - moduleStringAppend("/\\ TLCSet("); - moduleStringAppend("" + start); - moduleStringAppend(", FALSE)"); - moduleStringAppend(")"); - moduleStringAppend(" /\\ TLCGet("); - moduleStringAppend("" + start); - moduleStringAppend(")"); - } else { - node.getImplication().apply(this); - } - - outAForallPredicate(node); - } - - @Override - public void caseAExistsPredicate(AExistsPredicate node) { - /* - * B: #x,y(T => P) TLA: \E x \in type(x), y \in type(y): T => P - */ - inAExistsPredicate(node); - moduleStringAppend("\\E "); - - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (int i = 0; i < copy.size(); i++) { - PExpression e = copy.get(i); - e.apply(this); - moduleStringAppend(" \\in "); - typeRestrictor.getRestrictedNode(e).apply(this); - if (i < copy.size() - 1) { - moduleStringAppend(", "); - } - } - moduleStringAppend(" : "); - if (typeRestrictor.isARemovedNode(node.getPredicate())) { - moduleStringAppend("TRUE"); - } else { - node.getPredicate().apply(this); - } - outAExistsPredicate(node); - } - - @Override - public void caseANegationPredicate(ANegationPredicate node) { - inANegationPredicate(node); - moduleStringAppend("\\neg("); - node.getPredicate().apply(this); - moduleStringAppend(")"); - outANegationPredicate(node); - } - - @Override - public void caseAIntegerExpression(AIntegerExpression node) { - inAIntegerExpression(node); - if (node.getLiteral() != null) { - moduleStringAppend(node.getLiteral().getText()); - // node.getLiteral().apply(this); - } - outAIntegerExpression(node); - } - - @Override - public void caseAPredicateDefinitionDefinition( - APredicateDefinitionDefinition node) { - String name = renamer.getNameOfRef(node); - if (null == name) { - name = node.getName().getText().trim(); - } - printBDefinition(name, node.getParameters(), node.getRhs()); - } - - @Override - public void caseAExpressionDefinitionDefinition( - AExpressionDefinitionDefinition node) { - String oldName = node.getName().getText().trim(); - if (StandardMadules.isKeywordInModuleExternalFunctions(oldName)) { - return; - } - String name = renamer.getName(node); - if (null == name) { - name = node.getName().getText().trim(); - } - moduleStringAppend(name); - List<PExpression> args = node.getParameters(); - if (args.size() > 0) { - moduleStringAppend("("); - for (int i = 0; i < args.size(); i++) { - if (i != 0) - moduleStringAppend(", "); - args.get(i).apply(this); - } - moduleStringAppend(")"); - } - - moduleStringAppend(" == "); - if (TLC4BGlobals.isForceTLCToEvalConstants()) { - moduleStringAppend("TLCEval("); - } - node.getRhs().apply(this); - if (TLC4BGlobals.isForceTLCToEvalConstants()) { - moduleStringAppend(")"); - } - moduleStringAppend("\n"); - // printBDefinition(name, node.getParameters(), node.getRhs()); - } - - @Override - public void caseASubstitutionDefinitionDefinition( - ASubstitutionDefinitionDefinition node) { - String name = renamer.getNameOfRef(node); - if (null == name) { - name = node.getName().getText().trim(); - } - printBDefinition(name, node.getParameters(), node.getRhs()); - } - - private void printBDefinition(String name, List<PExpression> args, - Node rightSide) { - if (StandardMadules.isKeywordInModuleExternalFunctions(name)) { - return; - } - moduleStringAppend(name); - if (args.size() > 0) { - moduleStringAppend("("); - for (int i = 0; i < args.size(); i++) { - if (i != 0) - moduleStringAppend(", "); - args.get(i).apply(this); - } - moduleStringAppend(")"); - } - - moduleStringAppend(" == "); - rightSide.apply(this); - moduleStringAppend("\n"); - } - - @Override - public void caseADefinitionExpression(ADefinitionExpression node) { - String name = renamer.getNameOfRef(node); - if (null == name) { - name = node.getDefLiteral().getText().trim(); - } - printBDefinitionCall(name, node.getParameters()); - } - - @Override - public void caseADefinitionPredicate(ADefinitionPredicate node) { - String name = renamer.getNameOfRef(node); - if (null == name) { - name = node.getDefLiteral().getText().trim(); - } - printBDefinitionCall(name, node.getParameters()); - } - - @Override - public void caseADefinitionSubstitution(ADefinitionSubstitution node) { - String name = renamer.getNameOfRef(node); - if (null == name) { - name = node.getDefLiteral().getText().trim(); - } - printBDefinitionCall(name, node.getParameters()); - } - - public void printBDefinitionCall(String name, List<PExpression> args) { - moduleStringAppend(name); - if (args.size() > 0) { - moduleStringAppend("("); - for (int i = 0; i < args.size(); i++) { - if (i != 0) - moduleStringAppend(", "); - args.get(i).apply(this); - - } - moduleStringAppend(")"); - } - } - - /** - * Numbers - */ - - @Override - public void caseAIntegerSetExpression(AIntegerSetExpression node) { - inAIntegerSetExpression(node); - moduleStringAppend("Int"); - outAIntegerSetExpression(node); - } - - @Override - public void caseANaturalSetExpression(ANaturalSetExpression node) { - inANaturalSetExpression(node); - moduleStringAppend("Nat"); - outANaturalSetExpression(node); - } - - @Override - public void caseANatural1SetExpression(ANatural1SetExpression node) { - inANatural1SetExpression(node); - moduleStringAppend("(Nat \\ {0})"); - outANatural1SetExpression(node); - } - - @Override - public void caseAIntSetExpression(AIntSetExpression node) { - inAIntSetExpression(node); - moduleStringAppend("(" + TLC4BGlobals.getMIN_INT() + ".." - + TLC4BGlobals.getMAX_INT() + ")"); - outAIntSetExpression(node); - } - - @Override - public void caseANatSetExpression(ANatSetExpression node) { - inANatSetExpression(node); - moduleStringAppend("(0.." + TLC4BGlobals.getMAX_INT() + ")"); - outANatSetExpression(node); - } - - @Override - public void caseANat1SetExpression(ANat1SetExpression node) { - inANat1SetExpression(node); - moduleStringAppend("(1.." + TLC4BGlobals.getMAX_INT() + ")"); - outANat1SetExpression(node); - } - - @Override - public void caseAIntervalExpression(AIntervalExpression node) { - inAIntervalExpression(node); - moduleStringAppend("("); - node.getLeftBorder().apply(this); - moduleStringAppend(" .. "); - node.getRightBorder().apply(this); - moduleStringAppend(")"); - outAIntervalExpression(node); - } - - @Override - public void caseAGreaterPredicate(AGreaterPredicate node) { - inAGreaterPredicate(node); - node.getLeft().apply(this); - moduleStringAppend(" > "); - node.getRight().apply(this); - outAGreaterPredicate(node); - } - - @Override - public void caseALessPredicate(ALessPredicate node) { - inALessPredicate(node); - node.getLeft().apply(this); - moduleStringAppend(" < "); - node.getRight().apply(this); - outALessPredicate(node); - } - - @Override - public void caseAGreaterEqualPredicate(AGreaterEqualPredicate node) { - inAGreaterEqualPredicate(node); - node.getLeft().apply(this); - moduleStringAppend(" >= "); - node.getRight().apply(this); - outAGreaterEqualPredicate(node); - } - - @Override - public void caseALessEqualPredicate(ALessEqualPredicate node) { - inALessEqualPredicate(node); - node.getLeft().apply(this); - moduleStringAppend(" =< "); - node.getRight().apply(this); - outALessEqualPredicate(node); - } - - @Override - public void caseAMinExpression(AMinExpression node) { - moduleStringAppend(MIN); - moduleStringAppend("("); - node.getExpression().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseAMaxExpression(AMaxExpression node) { - moduleStringAppend(MAX); - moduleStringAppend("("); - node.getExpression().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseAUnaryMinusExpression(AUnaryMinusExpression node) { - inAUnaryMinusExpression(node); - moduleStringAppend("-"); - node.getExpression().apply(this); - outAUnaryMinusExpression(node); - } - - @Override - public void caseAAddExpression(AAddExpression node) { - inAAddExpression(node); - node.getLeft().apply(this); - moduleStringAppend(" + "); - node.getRight().apply(this); - outAAddExpression(node); - } - - @Override - public void caseADivExpression(ADivExpression node) { - inADivExpression(node); - moduleStringAppend(B_DIVISION); - moduleStringAppend("("); - node.getLeft().apply(this); - moduleStringAppend(", "); - node.getRight().apply(this); - moduleStringAppend(")"); - outADivExpression(node); - } - - @Override - public void caseAPowerOfExpression(APowerOfExpression node) { - moduleStringAppend(B_POWER_Of); - moduleStringAppend("("); - node.getLeft().apply(this); - moduleStringAppend(", "); - node.getRight().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseAModuloExpression(AModuloExpression node) { - - inAModuloExpression(node); - moduleStringAppend(B_MODULO); - moduleStringAppend("("); - node.getLeft().apply(this); - moduleStringAppend(", "); - node.getRight().apply(this); - moduleStringAppend(")"); - outAModuloExpression(node); - } - - @Override - public void caseAGeneralProductExpression(AGeneralProductExpression node) { - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - moduleStringAppend("Pi("); - moduleStringAppend("{"); - moduleStringAppend("<<"); - moduleStringAppend("<<"); - printIdentifierList(copy); - moduleStringAppend(">>"); - moduleStringAppend(", "); - node.getExpression().apply(this); - moduleStringAppend(">>"); - moduleStringAppend(" : "); - - printIdentifierList(copy); - moduleStringAppend(" \\in "); - if (typeRestrictor.isARemovedNode(node.getPredicates())) { - printTypesOfIdentifierList(copy); - } else { - moduleStringAppend("{"); - printIdentifierList(copy); - moduleStringAppend(" \\in "); - printTypesOfIdentifierList(copy); - moduleStringAppend(" : "); - node.getPredicates().apply(this); - moduleStringAppend("}"); - } - moduleStringAppend("}"); - moduleStringAppend(")"); - } - - @Override - public void caseAGeneralSumExpression(AGeneralSumExpression node) { - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - moduleStringAppend("Sigma("); - moduleStringAppend("{"); - moduleStringAppend("<<"); - moduleStringAppend("<<"); - printIdentifierList(copy); - moduleStringAppend(">>"); - moduleStringAppend(", "); - node.getExpression().apply(this); - moduleStringAppend(">>"); - moduleStringAppend(" : "); - - printIdentifierList(copy); - moduleStringAppend(" \\in "); - if (typeRestrictor.isARemovedNode(node.getPredicates())) { - printTypesOfIdentifierList(copy); - } else { - moduleStringAppend("{"); - printIdentifierList(copy); - moduleStringAppend(" \\in "); - printTypesOfIdentifierList(copy); - moduleStringAppend(" : "); - node.getPredicates().apply(this); - moduleStringAppend("}"); - } - moduleStringAppend("}"); - moduleStringAppend(")"); - } - - @Override - public void caseASuccessorExpression(ASuccessorExpression node) { - inASuccessorExpression(node); - moduleStringAppend("succ"); - outASuccessorExpression(node); - } - - @Override - public void caseAPredecessorExpression(APredecessorExpression node) { - inAPredecessorExpression(node); - moduleStringAppend("pred"); - outAPredecessorExpression(node); - } - - @Override - public void caseAMaxIntExpression(AMaxIntExpression node) { - moduleStringAppend(String.valueOf(TLC4BGlobals.getMAX_INT())); - } - - @Override - public void caseAMinIntExpression(AMinIntExpression node) { - moduleStringAppend(String.valueOf(TLC4BGlobals.getMIN_INT())); - } - - /** - * Function - */ - - private void printIdentifierList(List<PExpression> copy) { - if (copy.size() == 1) { - copy.get(0).apply(this); - return; - } - moduleStringAppend("<<"); - for (int i = 0; i < copy.size(); i++) { - if (i != 0) { - moduleStringAppend(", "); - } - copy.get(i).apply(this); - } - moduleStringAppend(">>"); - } - - private void printTypesOfIdentifierList(List<PExpression> copy) { - if (copy.size() > 1) { - moduleStringAppend("("); - } - for (int i = 0; i < copy.size(); i++) { - moduleStringAppend("("); - typeRestrictor.getRestrictedNode(copy.get(i)).apply(this); - moduleStringAppend(")"); - if (i < copy.size() - 1) - moduleStringAppend(" \\times "); - } - if (copy.size() > 1) { - moduleStringAppend(")"); - } - } - - /***************************************************************************** - * Functions - *****************************************************************************/ - - @Override - public void caseALambdaExpression(ALambdaExpression node) { - /** - * B: %a,b.(P|e) TLA+ function: [<<a,b>> \in {<<a,b>> \in - * type(a)*type(b) : P}|e] relation: TLA+: {<< <<a,b>>, e>>: <<a,b>> \in - * {<<a,b>> \in type(a)*type(b): P}} - */ - inALambdaExpression(node); - if (this.typechecker.getType(node) instanceof SetType) { - moduleStringAppend("{<<"); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - printIdentifierList(copy); - moduleStringAppend(", "); - node.getExpression().apply(this); - moduleStringAppend(">> : "); - - printIdentifierList(copy); - - moduleStringAppend(" \\in "); - - if (typeRestrictor.isARemovedNode(node.getPredicate())) { - printTypesOfIdentifierList(copy); - } else { - moduleStringAppend("{"); - printIdentifierList(copy); - moduleStringAppend(" \\in "); - printTypesOfIdentifierList(copy); - moduleStringAppend(" : "); - node.getPredicate().apply(this); - moduleStringAppend("}"); - } - moduleStringAppend("}"); - - } else { - moduleStringAppend("["); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - printIdentifierList(copy); - - moduleStringAppend(" \\in "); - if (typeRestrictor.isARemovedNode(node.getPredicate())) { - printTypesOfIdentifierList(copy); - - } else { - moduleStringAppend("{"); - printIdentifierList(copy); - - moduleStringAppend(" \\in "); - printTypesOfIdentifierList(copy); - moduleStringAppend(" : "); - node.getPredicate().apply(this); - moduleStringAppend("}"); - } - moduleStringAppend(" |-> "); - node.getExpression().apply(this); - moduleStringAppend("]"); - } - outALambdaExpression(node); - } - - @Override - // Function call - public void caseAFunctionExpression(AFunctionExpression node) { - inAFunctionExpression(node); - - if (node.getIdentifier() instanceof AIdentifierExpression) { - AIdentifierExpression id = (AIdentifierExpression) node - .getIdentifier(); - String name = Utils.getTIdentifierListAsString(id.getIdentifier()); - if (StandardMadules.isAbstractConstant(name)) { - - moduleStringAppend(name); - // node.getIdentifier().apply(this); - moduleStringAppend("("); - List<PExpression> copy = new ArrayList<PExpression>( - node.getParameters()); - copy.get(0).apply(this); - moduleStringAppend(")"); - return; - - } - - } - - BType type = this.typechecker.getType(node.getIdentifier()); - if (type instanceof FunctionType) { - node.getIdentifier().apply(this); - moduleStringAppend("["); - List<PExpression> copy = new ArrayList<PExpression>( - node.getParameters()); - for (int i = 0; i < copy.size(); i++) { - if (i != 0) { - moduleStringAppend(", "); - } - copy.get(i).apply(this); - } - moduleStringAppend("]"); - } else { - - if (TLC4BGlobals.checkWelldefinedness()) { - moduleStringAppend(REL_CALL); - } else { - moduleStringAppend(REL_CALL_WITHOUT_WD_CHECK); - } - moduleStringAppend("("); - node.getIdentifier().apply(this); - moduleStringAppend(", "); - List<PExpression> copy = new ArrayList<PExpression>( - node.getParameters()); - if (copy.size() > 1) - moduleStringAppend("<<"); - for (int i = 0; i < copy.size(); i++) { - if (i != 0) { - moduleStringAppend(", "); - } - copy.get(i).apply(this); - } - if (copy.size() > 1) - moduleStringAppend(">>"); - moduleStringAppend(")"); - } - - outAFunctionExpression(node); - } - - @Override - public void caseARangeExpression(ARangeExpression node) { - if (typechecker.getType(node.getExpression()) instanceof FunctionType) { - moduleStringAppend(FUNC_RANGE); - } else { - moduleStringAppend(REL_RANGE); - } - moduleStringAppend("("); - node.getExpression().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseAImageExpression(AImageExpression node) { - if (typechecker.getType(node.getLeft()) instanceof FunctionType) { - moduleStringAppend(FUNC_IMAGE); - } else { - moduleStringAppend(REL_IMAGE); - } - moduleStringAppend("("); - node.getLeft().apply(this); - moduleStringAppend(", "); - node.getRight().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseATotalFunctionExpression(ATotalFunctionExpression node) { - BType type = this.typechecker.getType(node); - BType subtype = ((SetType) type).getSubtype(); - if (subtype instanceof FunctionType) { - moduleStringAppend("["); - node.getLeft().apply(this); - moduleStringAppend(" -> "); - node.getRight().apply(this); - moduleStringAppend("]"); - } else { - if (node.parent() instanceof AMemberPredicate - && !typeRestrictor.isARemovedNode(node.parent()) - && !this.tlaModule.getInitPredicates().contains( - node.parent())) { - moduleStringAppend(REL_TOTAL_FUNCTION_ELEMENT_OF); - } else { - moduleStringAppend(REL_TOTAL_FUNCTION); - } - moduleStringAppend("("); - node.getLeft().apply(this); - moduleStringAppend(", "); - node.getRight().apply(this); - moduleStringAppend(")"); - } - } - - private boolean recursiveIsElementOfTest(Node node) { - Node parent = node.parent(); - if (parent instanceof AMemberPredicate - && !typeRestrictor.isARemovedNode(parent) - && !this.tlaModule.getInitPredicates().contains(parent)) { - return true; - } else { - String clazz = parent.getClass().getName(); - // todo include all expressions which have an "element of" - // translation - if (clazz.contains("Total") || clazz.contains("Partial")) { - return recursiveIsElementOfTest(node.parent()); - } else - return false; - } - } - - private void setOfFuntions(Node node, String funcName, String relName, - String relEleOfName, Node left, Node right) { - BType type = this.typechecker.getType(node); - BType subtype = ((SetType) type).getSubtype(); - if (subtype instanceof FunctionType) { - moduleStringAppend(funcName); - } else { - if (recursiveIsElementOfTest(node)) { - moduleStringAppend(relEleOfName); - } else { - moduleStringAppend(relName); - } - } - moduleStringAppend("("); - left.apply(this); - moduleStringAppend(", "); - right.apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseATotalInjectionExpression(ATotalInjectionExpression node) { - setOfFuntions(node, TOTAL_INJECTIVE_FUNCTION, - REL_TOTAL_INJECTIVE_FUNCTION, - REL_TOTAL_INJECTIVE_FUNCTION_ELEMENT_OF, node.getLeft(), - node.getRight()); - } - - @Override - public void caseATotalSurjectionExpression(ATotalSurjectionExpression node) { - setOfFuntions(node, TOTAL_SURJECTIVE_FUNCTION, - REL_TOTAL_SURJECTIVE_FUNCTION, - REL_TOTAL_SURJECTIVE_FUNCTION_ELEMENT_OF, node.getLeft(), - node.getRight()); - } - - @Override - public void caseATotalBijectionExpression(ATotalBijectionExpression node) { - setOfFuntions(node, TOTAL_BIJECTIVE_FUNCTION, - REL_TOTAL_BIJECTIVE_FUNCTION, - REL_TOTAL_BIJECTIVE_FUNCTION_ELEMENT_OF, node.getLeft(), - node.getRight()); - } - - private void setOfPartialFuntions(Node node, String funcName, - String funcEleOfName, String relName, String relEleOfName, - Node left, Node right) { - BType type = this.typechecker.getType(node); - BType subtype = ((SetType) type).getSubtype(); - if (subtype instanceof FunctionType) { - Node parent = node.parent(); - if (parent instanceof AMemberPredicate - && !typeRestrictor.isARemovedNode(parent)) { - moduleStringAppend(funcEleOfName); - moduleStringAppend("("); - ((AMemberPredicate) parent).getLeft().apply(this); - moduleStringAppend(", "); - left.apply(this); - moduleStringAppend(", "); - right.apply(this); - moduleStringAppend(")"); - return; - } else { - moduleStringAppend(funcName); - } - } else { - if (recursiveIsElementOfTest(node)) { - moduleStringAppend(relEleOfName); - } else { - moduleStringAppend(relName); - } - } - moduleStringAppend("("); - left.apply(this); - moduleStringAppend(", "); - right.apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseAPartialFunctionExpression(APartialFunctionExpression node) { - setOfPartialFuntions(node, PARTIAL_FUNCTION, - PARTIAL_FUNCTION_ELEMENT_OF, REL_PARTIAL_FUNCTION, - REL_PARTIAL_FUNCTION_ELEMENT_OF, node.getLeft(), - node.getRight()); - } - - @Override - public void caseAPartialInjectionExpression(APartialInjectionExpression node) { - setOfPartialFuntions(node, PARTIAL_INJECTIVE_FUNCTION, - PARTIAL_INJECTIVE_FUNCTION_ELEMENT_OF, - REL_PARTIAL_INJECTIVE_FUNCTION, - REL_PARTIAL_INJECTIVE_FUNCTION_ELEMENT_OF, node.getLeft(), - node.getRight()); - } - - @Override - public void caseAPartialSurjectionExpression( - APartialSurjectionExpression node) { - setOfPartialFuntions(node, PARTIAL_SURJECTIVE_FUNCTION, - PARTIAL_SURJECTIVE_FUNCTION_ELEMENT_OF, - REL_PARTIAL_SURJECTIVE_FUNCTION, - REL_PARTIAL_SURJECTIVE_FUNCTION_ELEMENT_OF, node.getLeft(), - node.getRight()); - } - - @Override - public void caseAPartialBijectionExpression(APartialBijectionExpression node) { - setOfPartialFuntions(node, PARITAL_BIJECTIVE_FUNCTION, - PARITAL_BIJECTIVE_FUNCTION_ELEMENT_OF, - REL_PARTIAL_BIJECTIVE_FUNCTION, - REL_PARTIAL_BIJECTIVE_FUNCTION_ELEMENT_OF, node.getLeft(), - node.getRight()); - } - - /** - * Sets - */ - - @Override - public void caseASetExtensionExpression(ASetExtensionExpression node) { - if (typechecker.getType(node) instanceof FunctionType) { - // 1 :> 2 @@ 2 :> 2 - moduleStringAppend("("); - for (int i = 0; i < node.getExpressions().size(); i++) { - ACoupleExpression couple = (ACoupleExpression) node - .getExpressions().get(i); - Node left = couple.getList().get(0); - Node right = couple.getList().get(1); - left.apply(this); - moduleStringAppend(":>"); - right.apply(this); - - if (i < node.getExpressions().size() - 1) { - moduleStringAppend(" @@ "); - } - } - moduleStringAppend(")"); - return; - } - moduleStringAppend("{"); - { - List<PExpression> copy = new ArrayList<PExpression>( - node.getExpressions()); - for (int i = 0; i < copy.size(); i++) { - if (i != 0) { - moduleStringAppend(", "); - } - copy.get(i).apply(this); - } - } - moduleStringAppend("}"); - } - - @Override - public void caseAEmptySetExpression(AEmptySetExpression node) { - if (typechecker.getType(node) instanceof FunctionType) { - moduleStringAppend("<< >>"); - } else { - moduleStringAppend("{}"); - } - } - - @Override - public void caseAMemberPredicate(AMemberPredicate node) { - inAMemberPredicate(node); - node.getLeft().apply(this); - moduleStringAppend(" \\in "); - node.getRight().apply(this); - outAMemberPredicate(node); - } - - @Override - public void caseANotMemberPredicate(ANotMemberPredicate node) { - inANotMemberPredicate(node); - node.getLeft().apply(this); - moduleStringAppend(" \\notin "); - node.getRight().apply(this); - outANotMemberPredicate(node); - } - - @Override - public void caseAComprehensionSetExpression(AComprehensionSetExpression node) { - inAComprehensionSetExpression(node); - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - if (copy.size() < 3) { - moduleStringAppend("{"); - printIdentifierList(copy); - moduleStringAppend(" \\in "); - printTypesOfIdentifierList(copy); - moduleStringAppend(": "); - if (typeRestrictor.isARemovedNode(node.getPredicates())) { - moduleStringAppend("TRUE"); - } else { - node.getPredicates().apply(this); - } - moduleStringAppend("}"); - - } else { - moduleStringAppend("{"); - printAuxiliaryVariables(copy.size()); - moduleStringAppend(": t_ \\in "); - moduleStringAppend("{"); - printIdentifierList(copy); - moduleStringAppend(" \\in "); - for (int i = 0; i < copy.size(); i++) { - moduleStringAppend("("); - typeRestrictor.getRestrictedNode(copy.get(i)).apply(this); - moduleStringAppend(")"); - if (i < copy.size() - 1) - moduleStringAppend(" \\times "); - } - moduleStringAppend(": "); - if (typeRestrictor.isARemovedNode(node.getPredicates())) { - moduleStringAppend("TRUE"); - } else { - node.getPredicates().apply(this); - } - moduleStringAppend("}"); - moduleStringAppend("}"); - } - - outAComprehensionSetExpression(node); - } - - @Override - public void caseAEventBComprehensionSetExpression( - AEventBComprehensionSetExpression node) { - inAEventBComprehensionSetExpression(node); - - moduleStringAppend("{"); - node.getExpression().apply(this); - moduleStringAppend(": "); - node.getPredicates().apply(this); - moduleStringAppend("}"); - - outAEventBComprehensionSetExpression(node); - } - - private void printAuxiliaryVariables(int size) { - for (int i = 0; i < size - 1; i++) { - moduleStringAppend("<<"); - } - for (int i = 0; i < size; i++) { - if (i != 0) { - moduleStringAppend(", "); - } - moduleStringAppend("t_[" + (i + 1) + "]"); - if (i != 0) { - moduleStringAppend(">>"); - } - } - } - - @Override - public void caseAUnionExpression(AUnionExpression node) { - inAUnionExpression(node); - node.getLeft().apply(this); - moduleStringAppend(" \\cup "); - node.getRight().apply(this); - outAUnionExpression(node); - } - - @Override - public void caseAIntersectionExpression(AIntersectionExpression node) { - inAIntersectionExpression(node); - node.getLeft().apply(this); - moduleStringAppend(" \\cap "); - node.getRight().apply(this); - outAIntersectionExpression(node); - } - - @Override - public void caseASetSubtractionExpression(ASetSubtractionExpression node) { - inASetSubtractionExpression(node); - node.getLeft().apply(this); - moduleStringAppend(" \\ "); - node.getRight().apply(this); - outASetSubtractionExpression(node); - } - - @Override - public void caseAPowSubsetExpression(APowSubsetExpression node) { - inAPowSubsetExpression(node); - moduleStringAppend("SUBSET("); - node.getExpression().apply(this); - moduleStringAppend(")"); - outAPowSubsetExpression(node); - } - - @Override - public void caseAPow1SubsetExpression(APow1SubsetExpression node) { - moduleStringAppend(POW_1); - moduleStringAppend("("); - node.getExpression().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseAFinSubsetExpression(AFinSubsetExpression node) { - moduleStringAppend(FINITE_SUBSETS); - moduleStringAppend("("); - node.getExpression().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseAFin1SubsetExpression(AFin1SubsetExpression node) { - moduleStringAppend(FINITE_1_SUBSETS); - moduleStringAppend("("); - node.getExpression().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseACardExpression(ACardExpression node) { - BType type = typechecker.getType(node.getExpression()); - if (type instanceof FunctionType) { - moduleStringAppend("Cardinality(DOMAIN("); - node.getExpression().apply(this); - moduleStringAppend("))"); - } else { - moduleStringAppend("Cardinality("); - node.getExpression().apply(this); - moduleStringAppend(")"); - } - } - - @Override - public void caseASubsetPredicate(ASubsetPredicate node) { - inASubsetPredicate(node); - node.getLeft().apply(this); - // moduleStringAppend(" \\in SUBSET("); - moduleStringAppend(" \\subseteq "); - node.getRight().apply(this); - // moduleStringAppend(")"); - outASubsetPredicate(node); - } - - @Override - public void caseASubsetStrictPredicate(ASubsetStrictPredicate node) { - inASubsetStrictPredicate(node); - node.getLeft().apply(this); - moduleStringAppend(" \\in (SUBSET("); - node.getRight().apply(this); - moduleStringAppend(") \\ {"); - node.getRight().apply(this); - moduleStringAppend("})"); - outASubsetStrictPredicate(node); - } - - @Override - public void caseANotSubsetPredicate(ANotSubsetPredicate node) { - moduleStringAppend(NOT_SUBSET); - moduleStringAppend("("); - node.getLeft().apply(this); - moduleStringAppend(", "); - node.getRight().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseANotSubsetStrictPredicate(ANotSubsetStrictPredicate node) { - moduleStringAppend(NOT_STRICT_SUBSET); - moduleStringAppend("("); - node.getLeft().apply(this); - moduleStringAppend(", "); - node.getRight().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseAGeneralUnionExpression(AGeneralUnionExpression node) { - inAGeneralUnionExpression(node); - moduleStringAppend("UNION("); - node.getExpression().apply(this); - moduleStringAppend(")"); - outAGeneralUnionExpression(node); - } - - @Override - public void caseAGeneralIntersectionExpression( - AGeneralIntersectionExpression node) { - inAGeneralIntersectionExpression(node); - moduleStringAppend("Inter("); - node.getExpression().apply(this); - moduleStringAppend(")"); - outAGeneralIntersectionExpression(node); - } - - @Override - public void caseAQuantifiedUnionExpression(AQuantifiedUnionExpression node) { - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - - moduleStringAppend("UNION({"); - node.getExpression().apply(this); - moduleStringAppend(": "); - printIdentifierList(copy); - if (typeRestrictor.isARemovedNode(node.getPredicates())) { - moduleStringAppend(" \\in "); - printTypesOfIdentifierList(copy); - moduleStringAppend("})"); - return; - } else { - moduleStringAppend(" \\in {"); - printIdentifierList(copy); - moduleStringAppend(" \\in "); - printTypesOfIdentifierList(copy); - moduleStringAppend(": "); - node.getPredicates().apply(this); - moduleStringAppend("}"); - moduleStringAppend("})"); - } - - } - - @Override - public void caseAQuantifiedIntersectionExpression( - AQuantifiedIntersectionExpression node) { - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - - moduleStringAppend("Inter({"); - node.getExpression().apply(this); - moduleStringAppend(": "); - printIdentifierList(copy); - if (typeRestrictor.isARemovedNode(node.getPredicates())) { - moduleStringAppend(" \\in "); - printTypesOfIdentifierList(copy); - moduleStringAppend("})"); - return; - } else { - moduleStringAppend(" \\in {"); - printIdentifierList(copy); - moduleStringAppend(" \\in "); - printTypesOfIdentifierList(copy); - moduleStringAppend(": "); - node.getPredicates().apply(this); - moduleStringAppend("}"); - moduleStringAppend("})"); - } - } - - /** - * Relations - */ - - @Override - public void caseACoupleExpression(ACoupleExpression node) { - inACoupleExpression(node); - List<PExpression> copy = new ArrayList<PExpression>(node.getList()); - for (int i = 0; i < copy.size() - 1; i++) { - moduleStringAppend("<<"); - } - for (int i = 0; i < copy.size(); i++) { - if (i != 0) { - moduleStringAppend(", "); - } - copy.get(i).apply(this); - if (i != 0) { - moduleStringAppend(">>"); - } - } - outACoupleExpression(node); - } - - @Override - public void caseARelationsExpression(ARelationsExpression node) { - moduleStringAppend(RELATIONS + "("); - node.getLeft().apply(this); - moduleStringAppend(", "); - node.getRight().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseADomainExpression(ADomainExpression node) { - inADomainExpression(node); - if (typechecker.getType(node.getExpression()) instanceof FunctionType) { - moduleStringAppend("DOMAIN "); - node.getExpression().apply(this); - } else { - moduleStringAppend(REL_DOMAIN + "("); - node.getExpression().apply(this); - moduleStringAppend(")"); - } - outADomainExpression(node); - } - - @Override - public void caseAIdentityExpression(AIdentityExpression node) { - inAIdentityExpression(node); - if (typechecker.getType(node) instanceof FunctionType) { - moduleStringAppend(FUNC_ID); - } else { - moduleStringAppend(REL_ID); - } - moduleStringAppend("("); - node.getExpression().apply(this); - moduleStringAppend(")"); - outAIdentityExpression(node); - } - - @Override - public void caseADomainRestrictionExpression( - ADomainRestrictionExpression node) { - if (typechecker.getType(node) instanceof FunctionType) { - moduleStringAppend(FUNC_DOMAIN_RESTRICTION); - } else { - moduleStringAppend(REL_DOMAIN_RESTRICTION); - } - moduleStringAppend("("); - node.getLeft().apply(this); - moduleStringAppend(", "); - node.getRight().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseADomainSubtractionExpression( - ADomainSubtractionExpression node) { - if (typechecker.getType(node) instanceof FunctionType) { - moduleStringAppend(FUNC_DOMAIN_SUBSTRACTION); - } else { - moduleStringAppend(REL_DOMAIN_SUBSTRACTION); - } - moduleStringAppend("("); - node.getLeft().apply(this); - moduleStringAppend(", "); - node.getRight().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseARangeRestrictionExpression(ARangeRestrictionExpression node) { - if (typechecker.getType(node) instanceof FunctionType) { - moduleStringAppend(FUNC_RANGE_RESTRICTION); - } else { - moduleStringAppend(REL_RANGE_RESTRICTION); - } - moduleStringAppend("("); - node.getLeft().apply(this); - moduleStringAppend(", "); - node.getRight().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseARangeSubtractionExpression(ARangeSubtractionExpression node) { - if (typechecker.getType(node) instanceof FunctionType) { - moduleStringAppend(FUNC_RANGE_SUBSTRACTION); - } else { - moduleStringAppend(REL_RANGE_SUBSTRACTION); - } - moduleStringAppend("("); - node.getLeft().apply(this); - moduleStringAppend(", "); - node.getRight().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseAReverseExpression(AReverseExpression node) { - if (typechecker.getType(node.getExpression()) instanceof FunctionType) { - moduleStringAppend(FUNC_INVERSE); - } else { - moduleStringAppend(REL_INVERSE); - } - moduleStringAppend("("); - node.getExpression().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseAOverwriteExpression(AOverwriteExpression node) { - if (typechecker.getType(node) instanceof FunctionType) { - moduleStringAppend(FUNC_OVERRIDE); - } else { - moduleStringAppend(REL_OVERRIDING); - } - moduleStringAppend("("); - node.getLeft().apply(this); - moduleStringAppend(", "); - node.getRight().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseADirectProductExpression(ADirectProductExpression node) { - moduleStringAppend(REL_DIRECT_PRODUCT); - moduleStringAppend("("); - node.getLeft().apply(this); - moduleStringAppend(", "); - node.getRight().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseAParallelProductExpression(AParallelProductExpression node) { - moduleStringAppend(REL_PARALLEL_PRODUCT); - moduleStringAppend("("); - node.getLeft().apply(this); - moduleStringAppend(", "); - node.getRight().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseACompositionExpression(ACompositionExpression node) { - moduleStringAppend(REL_COMPOSITION); - moduleStringAppend("("); - node.getLeft().apply(this); - moduleStringAppend(", "); - node.getRight().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseAFirstProjectionExpression(AFirstProjectionExpression node) { - moduleStringAppend(REL_PROJECTION_FUNCTION_FIRST); - moduleStringAppend("("); - node.getExp1().apply(this); - moduleStringAppend(", "); - node.getExp2().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseASecondProjectionExpression(ASecondProjectionExpression node) { - moduleStringAppend(REL_PROJECTION_FUNCTION_SECOND); - moduleStringAppend("("); - node.getExp1().apply(this); - moduleStringAppend(", "); - node.getExp2().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseAIterationExpression(AIterationExpression node) { - moduleStringAppend(REL_ITERATE); - moduleStringAppend("("); - node.getLeft().apply(this); - moduleStringAppend(", "); - node.getRight().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseAClosureExpression(AClosureExpression node) { - moduleStringAppend(REL_CLOSURE1); - moduleStringAppend("("); - node.getExpression().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseAReflexiveClosureExpression(AReflexiveClosureExpression node) { - moduleStringAppend(REL_CLOSURE); - moduleStringAppend("("); - node.getExpression().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseATransFunctionExpression(ATransFunctionExpression node) { - moduleStringAppend(REL_FNC); - moduleStringAppend("("); - node.getExpression().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseATransRelationExpression(ATransRelationExpression node) { - moduleStringAppend(REL_REL); - moduleStringAppend("("); - node.getExpression().apply(this); - moduleStringAppend(")"); - } - - /** - * Sequences - */ - - @Override - public void caseASequenceExtensionExpression( - ASequenceExtensionExpression node) { - List<PExpression> copy = new ArrayList<PExpression>( - node.getExpression()); - BType type = typechecker.getType(node); - if (type instanceof FunctionType) { - moduleStringAppend("<<"); - - for (int i = 0; i < copy.size(); i++) { - copy.get(i).apply(this); - if (i < copy.size() - 1) - moduleStringAppend(", "); - } - moduleStringAppend(">>"); - } else { - moduleStringAppend("{"); - for (int i = 0; i < copy.size(); i++) { - moduleStringAppend("<<"); - moduleStringAppend(String.valueOf(i + 1)); - moduleStringAppend(", "); - copy.get(i).apply(this); - moduleStringAppend(">>"); - if (i < copy.size() - 1) - moduleStringAppend(", "); - } - moduleStringAppend("}"); - } - } - - private void evalFunctionOrRelation(Node node, String function, - String relation) { - BType type = typechecker.getType(node); - if (type instanceof FunctionType) { - moduleStringAppend(function); - } else { - moduleStringAppend(relation); - } - } - - @Override - public void caseAEmptySequenceExpression(AEmptySequenceExpression node) { - evalFunctionOrRelation(node, "<<>>", "{}"); - } - - @Override - public void caseASeqExpression(ASeqExpression node) { - SetType set = (SetType) typechecker.getType(node); - if (set.getSubtype() instanceof SetType) { - moduleStringAppend(REL_SET_OF_SEQUENCES); - } else { - moduleStringAppend("Seq"); - } - moduleStringAppend("("); - node.getExpression().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseASizeExpression(ASizeExpression node) { - printSequenceOrRelation(node.getExpression(), "Len", REL_SEQUENCE_SIZE, - node.getExpression(), null); - } - - @Override - public void caseAConcatExpression(AConcatExpression node) { - BType type = typechecker.getType(node); - if (type instanceof SetType) { - moduleStringAppend(REL_SEQUENCE_Concat); - moduleStringAppend("("); - node.getLeft().apply(this); - moduleStringAppend(", "); - node.getRight().apply(this); - moduleStringAppend(")"); - } else { - inAConcatExpression(node); - node.getLeft().apply(this); - moduleStringAppend(" \\o "); - node.getRight().apply(this); - outAConcatExpression(node); - } - } - - @Override - public void caseAInsertTailExpression(AInsertTailExpression node) { - printSequenceOrRelation(node, "Append", REL_SEQUENCE_APPEND, - node.getLeft(), node.getRight()); - } - - private void printSequenceOrRelation(Node node, String sequence, - String relation, Node left, Node right) { - BType type = typechecker.getType(node); - if (type instanceof SetType) { - moduleStringAppend(relation); - } else { - moduleStringAppend(sequence); - } - moduleStringAppend("("); - left.apply(this); - - if (right != null) { - moduleStringAppend(","); - right.apply(this); - } - moduleStringAppend(")"); - } - - @Override - public void caseAFirstExpression(AFirstExpression node) { - printSequenceOrRelation(node.getExpression(), "Head", - REL_SEQUENCE_FIRST_ELEMENT, node.getExpression(), null); - } - - @Override - public void caseATailExpression(ATailExpression node) { - printSequenceOrRelation(node.getExpression(), "Tail", - REL_SEQUENCE_TAIL, node.getExpression(), null); - } - - /** - * SequencesExtended - */ - - @Override - public void caseAIseqExpression(AIseqExpression node) { - SetType set = (SetType) typechecker.getType(node); - if (set.getSubtype() instanceof SetType) { - - if (recursiveIsElementOfTest(node.parent()) - && !typeRestrictor.isARemovedNode(node.parent())) { - moduleStringAppend(REL_INJECTIVE_SEQUENCE_ELEMENT_OF); - } else { - moduleStringAppend(REL_INJECTIVE_SEQUENCE); - } - } else { - if (node.parent() instanceof AMemberPredicate - && !typeRestrictor.isARemovedNode(node.parent())) { - moduleStringAppend(INJECTIVE_SEQUENCE_ELEMENT_OF); - } else { - moduleStringAppend(INJECTIVE_SEQUENCE); - } - } - moduleStringAppend("("); - node.getExpression().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseAIseq1Expression(AIseq1Expression node) { - SetType set = (SetType) typechecker.getType(node); - if (set.getSubtype() instanceof SetType) { - if (recursiveIsElementOfTest(node)) { - moduleStringAppend(REL_INJECTIVE_SEQUENCE_1_ELEMENT_OF); - } else { - moduleStringAppend(REL_INJECTIVE_SEQUENCE_1); - } - } else { - if (recursiveIsElementOfTest(node)) { - moduleStringAppend(INJECTIVE_SEQUENCE_1_ELEMENT_OF); - } else { - moduleStringAppend(INJECTIVE_SEQUENCE_1); - } - } - moduleStringAppend("("); - node.getExpression().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseASeq1Expression(ASeq1Expression node) { - SetType set = (SetType) typechecker.getType(node); - if (set.getSubtype() instanceof SetType) { - moduleStringAppend(REL_SET_OF_NON_EMPTY_SEQUENCES); - } else { - moduleStringAppend(SEQUENCE_1); - } - moduleStringAppend("("); - node.getExpression().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseALastExpression(ALastExpression node) { - printSequenceOrRelation(node.getExpression(), SEQUENCE_LAST_ELEMENT, - REL_SEQUENCE_LAST_ELEMENT, node.getExpression(), null); - } - - @Override - public void caseAInsertFrontExpression(AInsertFrontExpression node) { - printSequenceOrRelation(node.getRight(), SEQUENCE_PREPEND_ELEMENT, - REL_SEQUENCE_PREPAND, node.getLeft(), node.getRight()); - } - - @Override - public void caseAPermExpression(APermExpression node) { - SetType set = (SetType) typechecker.getType(node); - if (set.getSubtype() instanceof SetType) { - moduleStringAppend(REL_SEQUENCE_PERM); - } else { - moduleStringAppend(SEQUENCE_PERMUTATION); - } - moduleStringAppend("("); - node.getExpression().apply(this); - moduleStringAppend(")"); - } - - @Override - public void caseARevExpression(ARevExpression node) { - printSequenceOrRelation(node, SEQUENCE_REVERSE, REL_SEQUENCE_REVERSE, - node.getExpression(), null); - } - - @Override - public void caseAFrontExpression(AFrontExpression node) { - printSequenceOrRelation(node.getExpression(), SEQUENCE_FRONT, - REL_SEQUENCE_FRONT, node.getExpression(), null); - } - - @Override - public void caseAGeneralConcatExpression(AGeneralConcatExpression node) { - BType result = typechecker.getType(node.getExpression()); - - if (result instanceof FunctionType - && ((FunctionType) result).getRange() instanceof FunctionType) { - - } else { - BType expected2 = new SetType(new PairType( - IntegerType.getInstance(), new SetType(new PairType( - IntegerType.getInstance(), new UntypedType())))); - typechecker.unify(expected2, result, node); - } - - printSequenceOrRelation(node, SEQUENCE_GENERAL_CONCATINATION, - REL_SEQUENCE_GENERAL_CONCATINATION, node.getExpression(), null); - } - - @Override - public void caseARestrictFrontExpression(ARestrictFrontExpression node) { - printSequenceOrRelation(node, SEQUENCE_TAKE_FIRST_ELEMENTS, - REL_SEQUENCE_TAKE_FIRST_ELEMENTS, node.getLeft(), - node.getRight()); - } - - @Override - public void caseARestrictTailExpression(ARestrictTailExpression node) { - printSequenceOrRelation(node, SEQUENCE_DROP_FIRST_ELEMENTS, - REL_SEQUENCE_DROP_FIRST_ELEMENTS, node.getLeft(), - node.getRight()); - } - - /** - * Special Operator - */ - @Override - public void caseAMinusOrSetSubtractExpression( - AMinusOrSetSubtractExpression node) { - inAMinusOrSetSubtractExpression(node); - node.getLeft().apply(this); - - BType leftType = this.typechecker.getType(node.getLeft()); - if (leftType instanceof IntegerType) { - moduleStringAppend(" - "); - } else { - moduleStringAppend(" \\ "); - } - - node.getRight().apply(this); - outAMinusOrSetSubtractExpression(node); - } - - @Override - public void caseAMultOrCartExpression(AMultOrCartExpression node) { - inAMultOrCartExpression(node); - node.getLeft().apply(this); - - BType leftType = this.typechecker.getType(node.getLeft()); - if (leftType instanceof IntegerType) { - moduleStringAppend(" * "); - } else { - moduleStringAppend(" \\times "); - } - - node.getRight().apply(this); - outAMultOrCartExpression(node); - } - - @Override - public void caseACartesianProductExpression(ACartesianProductExpression node) { - inACartesianProductExpression(node); // TODO cartesianproduct vs - // AMultOrCartExpression - node.getLeft().apply(this); - moduleStringAppend(" \\times "); - node.getRight().apply(this); - outACartesianProductExpression(node); - } - - @Override - public void caseAConvertBoolExpression(AConvertBoolExpression node) { - inAConvertBoolExpression(node); - moduleStringAppend("("); - if (node.getPredicate() != null) { - node.getPredicate().apply(this); - } - moduleStringAppend(")"); - outAConvertBoolExpression(node); - } - - // Records - - @Override - public void caseARecExpression(ARecExpression node) { - moduleStringAppend("["); - List<PRecEntry> copy = new ArrayList<PRecEntry>(node.getEntries()); - for (int i = 0; i < copy.size(); i++) { - copy.get(i).apply(this); - if (i < copy.size() - 1) { - moduleStringAppend(", "); - } - } - moduleStringAppend("]"); - } - - @Override - public void caseARecEntry(ARecEntry node) { - node.getIdentifier().apply(this); - if (typechecker.getType(node.parent()) instanceof StructType) { - moduleStringAppend(" |-> "); - } else { - moduleStringAppend(" : "); - } - - node.getValue().apply(this); - } - - @Override - public void caseARecordFieldExpression(ARecordFieldExpression node) { - inARecordFieldExpression(node); - node.getRecord().apply(this); - moduleStringAppend("."); - node.getIdentifier().apply(this); - outARecordFieldExpression(node); - } - - @Override - public void caseAStructExpression(AStructExpression node) { - moduleStringAppend("["); - List<PRecEntry> copy = new ArrayList<PRecEntry>(node.getEntries()); - for (int i = 0; i < copy.size(); i++) { - copy.get(i).apply(this); - if (i < copy.size() - 1) { - moduleStringAppend(", "); - } - } - moduleStringAppend("]"); - } - - public String geTranslatedLTLFormula() { - return this.translatedLTLFormula.toString(); - } - - public TLAModule getTLAModule() { - return this.tlaModule; - } -} +package de.tlc4b.prettyprint; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; + +import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; +import de.be4.classicalb.core.parser.node.*; +import de.be4.classicalb.core.parser.util.Utils; +import de.tlc4b.TLC4BGlobals; +import de.tlc4b.analysis.MachineContext; +import de.tlc4b.analysis.PrecedenceCollector; +import de.tlc4b.analysis.PrimedNodesMarker; +import de.tlc4b.analysis.Renamer; +import de.tlc4b.analysis.StandardMadules; +import de.tlc4b.analysis.Typechecker; +import de.tlc4b.analysis.UsedStandardModules; +import de.tlc4b.analysis.typerestriction.TypeRestrictor; +import de.tlc4b.analysis.unchangedvariables.InvariantPreservationAnalysis; +import de.tlc4b.analysis.unchangedvariables.UnchangedVariablesFinder; +import de.tlc4b.btypes.BType; +import de.tlc4b.btypes.FunctionType; +import de.tlc4b.btypes.IntegerType; +import de.tlc4b.btypes.PairType; +import de.tlc4b.btypes.SetType; +import de.tlc4b.btypes.StructType; +import de.tlc4b.btypes.UntypedType; +import de.tlc4b.ltl.LTLFormulaVisitor; +import de.tlc4b.tla.ConfigFile; +import de.tlc4b.tla.TLADefinition; +import de.tlc4b.tla.TLAModule; +import de.tlc4b.tla.config.ConfigFileAssignment; +import static de.tlc4b.analysis.StandardMadules.*; + +public class TLAPrinter extends DepthFirstAdapter { + + private StringBuilder tlaModuleString; + private StringBuilder configFileString; + + public StringBuilder getConfigString() { + return configFileString; + } + + public StringBuilder getStringbuilder() { + return tlaModuleString; + } + + private MachineContext machineContext; + private Typechecker typechecker; + private UnchangedVariablesFinder missingVariableFinder; + private PrecedenceCollector precedenceCollector; + private UsedStandardModules usedStandardModules; + private TypeRestrictor typeRestrictor; + private TLAModule tlaModule; + private ConfigFile configFile; + private PrimedNodesMarker primedNodesMarker; + private Renamer renamer; + private boolean recordLTLFormula = false; + private StringBuilder translatedLTLFormula = new StringBuilder(); + private final InvariantPreservationAnalysis invariantPreservationAnalysis; + + public TLAPrinter(MachineContext machineContext, Typechecker typechecker, + UnchangedVariablesFinder unchangedVariablesFinder, + PrecedenceCollector precedenceCollector, + UsedStandardModules usedStandardModules, + TypeRestrictor typeRestrictor, TLAModule tlaModule, + ConfigFile configFile, PrimedNodesMarker primedNodesMarker, + Renamer renamer, + InvariantPreservationAnalysis invariantPreservationAnalysis) { + this.typechecker = typechecker; + this.machineContext = machineContext; + this.missingVariableFinder = unchangedVariablesFinder; + this.precedenceCollector = precedenceCollector; + this.usedStandardModules = usedStandardModules; + this.typeRestrictor = typeRestrictor; + this.tlaModule = tlaModule; + this.configFile = configFile; + this.primedNodesMarker = primedNodesMarker; + this.renamer = renamer; + this.invariantPreservationAnalysis = invariantPreservationAnalysis; + + this.tlaModuleString = new StringBuilder(); + this.configFileString = new StringBuilder(); + } + + public void start() { + printHeader(); + printExtendedModules(); + printConstants(); + printVariables(); + printDefinitions(); + printAssume(); + printInvariant(); + printAssertions(); + printInit(); + printOperations(); + printSpecFormula(); + printLTLFormulas(); + + printSymmetry(); + + moduleStringAppend("===="); + + printConfig(); + } + + private void printSymmetry() { + + if (TLC4BGlobals.useSymmetry() + && machineContext.getDeferredSets().size() > 0) { + + moduleStringAppend("Symmetry == "); + Collection<Node> values = machineContext.getDeferredSets().values(); + ArrayList<Node> array = new ArrayList<Node>(values); + for (int i = 0; i < array.size(); i++) { + Node node = array.get(i); + moduleStringAppend("Permutations("); + node.apply(this); + moduleStringAppend(")"); + if (i < array.size() - 1) { + moduleStringAppend(" \\cup "); + } + } + moduleStringAppend("\n"); + // Symmetry == Permutations(Clients) \cup Permutations(Resources) + } + } + + private void printSpecFormula() { + + if (this.configFile.isSpec()) { + moduleStringAppend("vars == "); + printVarsAsTuple(); + moduleStringAppend("\n"); + + moduleStringAppend("VWF == "); + printWeakFairness("Next"); + moduleStringAppend("\n"); + moduleStringAppend("Spec == Init /\\ [][Next]_vars /\\ VWF\n"); + } + + } + + public void printStrongFairness(String s) { + + moduleStringAppend(String + .format("([]<><<%s>>_vars \\/ <>[]~ENABLED(%s) \\/ []<> ENABLED(%s /\\ ", + s, s, s)); + printVarsStuttering(); + moduleStringAppend("))"); + + } + + public void printWeakFairness(String s) { + moduleStringAppend(String + .format("([]<><<%s>>_vars \\/ []<>~ENABLED(%s) \\/ []<> ENABLED(%s /\\ ", + s, s, s)); + printVarsStuttering(); + moduleStringAppend("))"); + + } + + public void printWeakFairnessWithParameter(String s) { + Node operation = machineContext.getOperations().get(s.trim()); + + moduleStringAppend("([]<><<"); + printOperationCall(operation); + moduleStringAppend(">>_vars \\/ []<>~ENABLED("); + printOperationCall(operation); + moduleStringAppend(") \\/ []<> ENABLED("); + printOperationCall(operation); + moduleStringAppend(" /\\ "); + printVarsStuttering(); + moduleStringAppend("))"); + + } + + private void printVarsStuttering() { + ArrayList<Node> vars = this.tlaModule.getVariables(); + for (int i = 0; i < vars.size(); i++) { + vars.get(i).apply(this); + moduleStringAppend("' = "); + vars.get(i).apply(this); + if (i < vars.size() - 1) + moduleStringAppend(" /\\ "); + } + } + + private void printVarsAsTuple() { + ArrayList<Node> vars = this.tlaModule.getVariables(); + if (vars.size() == 0) + return; + moduleStringAppend("<<"); + for (int i = 0; i < vars.size(); i++) { + vars.get(i).apply(this); + if (i < vars.size() - 1) + moduleStringAppend(","); + } + moduleStringAppend(">>"); + } + + private void printLTLFormulas() { + ArrayList<LTLFormulaVisitor> visitors = machineContext.getLTLFormulas(); + if (TLC4BGlobals.isCheckLTL()) { + for (int i = 0; i < visitors.size(); i++) { + LTLFormulaVisitor visitor = visitors.get(i); + moduleStringAppend(visitor.getName() + " == "); + if (TLC4BGlobals.getTestingMode() == true) { + recordLTLFormula = true; + visitor.printLTLFormula(this, typeRestrictor); + recordLTLFormula = false; + } else { + visitor.printLTLFormula(this, typeRestrictor); + } + moduleStringAppend("\n"); + } + } + } + + private void printConfig() { + if (this.configFile.isSpec()) { + this.configFileString.append("SPECIFICATION Spec\n"); + } else { + if (this.configFile.isInit()) { + this.configFileString.append("INIT Init\n"); + } + if (this.configFile.isInit()) { + this.configFileString.append("NEXT Next\n"); + } + } + if (TLC4BGlobals.isInvariant()) { + for (int i = 0; i < configFile.getInvariantNumber(); i++) { + this.configFileString.append("INVARIANT Invariant" + (i + 1) + + "\n"); + } + } + + if (configFile.isGoal()) { + this.configFileString.append("INVARIANT NotGoal\n"); + } + + if (TLC4BGlobals.isAssertion() && tlaModule.hasInitPredicate()) { + for (int i = 0; i < configFile.getAssertionSize(); i++) { + this.configFileString.append("INVARIANT Assertion") + .append(i + 1).append("\n"); + } + } + + if (TLC4BGlobals.isCheckLTL()) { + for (int i = 0; i < machineContext.getLTLFormulas().size(); i++) { + LTLFormulaVisitor ltlVisitor = machineContext.getLTLFormulas() + .get(i); + this.configFileString.append("PROPERTIES " + + ltlVisitor.getName() + "\n"); + } + } + // CONSTANTS + ArrayList<ConfigFileAssignment> assignments = configFile + .getAssignments(); + if (assignments.size() != 0) { + configFileString.append("CONSTANTS\n"); + for (int i = 0; i < assignments.size(); i++) { + configFileString.append(assignments.get(i).getString(renamer)); + } + } + if (TLC4BGlobals.useSymmetry() + && machineContext.getDeferredSets().size() > 0) { + configFileString.append("SYMMETRY Symmetry\n"); + } + + if (TLC4BGlobals.isPartialInvariantEvaluation()) { + configFileString.append("CONSTANTS\n"); + configFileString.append("Init_action = Init_action\n"); + + ArrayList<POperation> operations = tlaModule.getOperations(); + for (int i = 0; i < operations.size(); i++) { + AOperation node = (AOperation) operations.get(i); + String name = renamer.getNameOfRef(node); + String actionName = name + "actions"; + configFileString.append(actionName).append(" = ") + .append(actionName); + configFileString.append("\n"); + } + configFileString.append("\n"); + configFileString.append("VIEW myView"); + } + + } + + public void moduleStringAppend(String str) { + tlaModuleString.append(str); + if (recordLTLFormula) { + translatedLTLFormula.append(str); + } + } + + private void printHeader() { + moduleStringAppend("---- MODULE "); + moduleStringAppend(this.tlaModule.getModuleName()); + moduleStringAppend(" ----\n"); + } + + private void printExtendedModules() { + if (usedStandardModules.getExtendedModules().size() > 0) { + moduleStringAppend("EXTENDS "); + for (int i = 0; i < usedStandardModules.getExtendedModules().size(); i++) { + if (i > 0) { + moduleStringAppend(", "); + } + moduleStringAppend(usedStandardModules.getExtendedModules() + .get(i).toString()); + } + moduleStringAppend("\n"); + } + } + + private void printDefinitions() { + ArrayList<TLADefinition> definitions = tlaModule.getTLADefinitions(); + for (int i = 0; i < definitions.size(); i++) { + TLADefinition def = definitions.get(i); + if (def.getDefName() instanceof AEnumeratedSetSet) { + def.getDefName().apply(this); + continue; + } + def.getDefName().apply(this); + + moduleStringAppend(" == "); + Node e = def.getDefinition(); + if (e == null) { + moduleStringAppend(def.getInt().toString()); + } else { + e.apply(this); + } + moduleStringAppend("\n"); + } + + ArrayList<PDefinition> bDefinitions = tlaModule.getAllDefinitions(); + if (null == bDefinitions) { + return; + } + for (PDefinition node : bDefinitions) { + node.apply(this); + } + if (configFile.isGoal()) { + moduleStringAppend("NotGoal == ~GOAL\n"); + } + } + + private void printConstants() { + if (TLC4BGlobals.isPartialInvariantEvaluation()) { + ArrayList<POperation> operations = tlaModule.getOperations(); + moduleStringAppend("CONSTANTS Init_action, "); + for (int i = 0; i < operations.size(); i++) { + AOperation node = (AOperation) operations.get(i); + String name = renamer.getNameOfRef(node); + moduleStringAppend(name + "_action"); + + if (i < operations.size() - 1) + moduleStringAppend(", "); + } + moduleStringAppend("\n"); + } + /******************/ + ArrayList<Node> list = this.tlaModule.getConstants(); + if (list.size() == 0) + return; + moduleStringAppend("CONSTANTS "); + for (int i = 0; i < list.size(); i++) { + Node con = list.get(i); + con.apply(this); + + if (i < list.size() - 1) + moduleStringAppend(", "); + } + moduleStringAppend("\n"); + } + + private void printAssume() { + ArrayList<Node> list = this.tlaModule.getAssume(); + if (list.size() == 0) + return; + + for (int i = 0; i < list.size(); i++) { + Node node = list.get(i); + if(!typeRestrictor.isARemovedNode(node)){ + moduleStringAppend("ASSUME "); + list.get(i).apply(this); + moduleStringAppend("\n"); + } + } + + } + + private void printVariables() { + ArrayList<Node> vars = this.tlaModule.getVariables(); + if (vars.size() == 0) + return; + moduleStringAppend("VARIABLES "); + for (int i = 0; i < vars.size(); i++) { + vars.get(i).apply(this); + if (i < vars.size() - 1) { + moduleStringAppend(", "); + } + + } + if (TLC4BGlobals.isPartialInvariantEvaluation()) { + moduleStringAppend(", last_action"); + } + moduleStringAppend("\n"); + + if (TLC4BGlobals.isPartialInvariantEvaluation()) { + moduleStringAppend("myView == <<"); + for (int i = 0; i < vars.size(); i++) { + vars.get(i).apply(this); + if (i < vars.size() - 1) + moduleStringAppend(", "); + } + moduleStringAppend(">>\n"); + } + } + + private void printInvariant() { + ArrayList<Node> invariants = this.tlaModule.getInvariantList(); + for (int i = 0; i < invariants.size(); i++) { + Node inv = invariants.get(i); + moduleStringAppend("Invariant" + (i + 1) + " == "); + if (TLC4BGlobals.isPartialInvariantEvaluation()) { + ArrayList<Node> operations = invariantPreservationAnalysis + .getPreservingOperations(inv); + if (operations.size() > 0) { + moduleStringAppend("last_action \\in {"); + for (int j = 0; j < operations.size(); j++) { + Node op = operations.get(j); + String name = renamer.getNameOfRef(op); + moduleStringAppend(name); + moduleStringAppend("_action"); + if (j < operations.size() - 1) { + moduleStringAppend(", "); + } + } + moduleStringAppend("} \\/ "); + } + } + inv.apply(this); + moduleStringAppend("\n"); + } + } + + private void printAssertions() { + if (TLC4BGlobals.isAssertion()) { + ArrayList<Node> assertions = tlaModule.getAssertions(); + if (assertions.size() == 0) + return; + for (int i = 0; i < assertions.size(); i++) { + Node assertion = assertions.get(i); + String name = null; + if (assertion instanceof ALabelPredicate) { + ALabelPredicate label = (ALabelPredicate) assertion; + name = label.getName().getText(); + } + + if (name == null) { + name = "Assertion" + (i + 1); + } + + if (tlaModule.hasInitPredicate()) { + moduleStringAppend(name); + moduleStringAppend(" == "); + } else { + moduleStringAppend("ASSUME "); + moduleStringAppend(name); + moduleStringAppend(" == "); + } + // assertionMode = true; + // assertionName = name; + // parameterCounter = 0; + assertion.apply(this); + // assertionMode = false; + moduleStringAppend("\n"); + } + } + } + + private static boolean assertionMode = false; + private static String assertionName = null; + private static Integer parameterCounter = 0; + + private void printInit() { + ArrayList<Node> inits = this.tlaModule.getInitPredicates(); + if (inits.size() == 0) + return; + moduleStringAppend("Init == "); + if (inits.size() > 1) + moduleStringAppend("\n\t/\\ "); + for (int i = 0; i < inits.size(); i++) { + Node init = inits.get(i); + if (init instanceof ADisjunctPredicate) { + moduleStringAppend("("); + } + init.apply(this); + if (init instanceof ADisjunctPredicate) { + moduleStringAppend(")"); + } + if (TLC4BGlobals.isPartialInvariantEvaluation()) { + moduleStringAppend(" /\\ last_action = Init_action"); + } + if (i < inits.size() - 1) + moduleStringAppend("\n\t/\\ "); + } + moduleStringAppend("\n\n"); + } + + private void printOperations() { + ArrayList<POperation> ops = this.tlaModule.getOperations(); + if (ops.size() == 0) { + ArrayList<Node> vars = tlaModule.getVariables(); + if (vars.size() > 0) { + moduleStringAppend("Next == 1 = 2 /\\ UNCHANGED <<"); + for (int i = 0; i < vars.size(); i++) { + vars.get(i).apply(this); + if (i < vars.size() - 1) { + moduleStringAppend(", "); + } + } + moduleStringAppend(">>\n"); + } + return; + } + for (int i = 0; i < ops.size(); i++) { + ops.get(i).apply(this); + } + moduleStringAppend("Next == \\/ "); + Iterator<Node> itr = this.machineContext.getOperations().values() + .iterator(); + while (itr.hasNext()) { + Node operation = itr.next(); + printOperationCall(operation); + + if (itr.hasNext()) { + moduleStringAppend("\n\t\\/ "); + } + } + moduleStringAppend("\n"); + } + + public void printOperationCall(Node operation) { + AOperation op = (AOperation) operation; + List<PExpression> newList = new ArrayList<PExpression>(); + newList.addAll(op.getParameters()); + // newList.addAll(op.getReturnValues()); + if (newList.size() > 0) { + moduleStringAppend("\\E "); + for (int i = 0; i < newList.size(); i++) { + PExpression e = newList.get(i); + e.apply(this); + moduleStringAppend(" \\in "); + typeRestrictor.getRestrictedNode(e).apply(this); + ; + if (i < newList.size() - 1) { + moduleStringAppend(", "); + } + } + moduleStringAppend(" : "); + } + + String opName = renamer.getNameOfRef(op); + moduleStringAppend(opName); + if (newList.size() > 0) { + moduleStringAppend("("); + for (int i = 0; i < newList.size(); i++) { + newList.get(i).apply(this); + if (i < newList.size() - 1) { + moduleStringAppend(", "); + } + + } + moduleStringAppend(")"); + } + } + + @Override + public void defaultIn(final Node node) { + if (precedenceCollector.getBrackets().contains(node)) { + moduleStringAppend("("); + } + } + + @Override + public void defaultOut(final Node node) { + if (precedenceCollector.getBrackets().contains(node)) { + moduleStringAppend(")"); + } + } + + /* + * Treewalker + */ + + @Override + public void caseAMachineHeader(AMachineHeader node) { + inAMachineHeader(node); + moduleStringAppend(node.toString()); + { + List<TIdentifierLiteral> copy = new ArrayList<TIdentifierLiteral>( + node.getName()); + for (TIdentifierLiteral e : copy) { + e.apply(this); + } + } + { + List<PExpression> copy = new ArrayList<PExpression>( + node.getParameters()); + for (PExpression e : copy) { + e.apply(this); + } + } + outAMachineHeader(node); + } + + @Override + public void caseAEnumeratedSetSet(AEnumeratedSetSet node) { + List<PExpression> copy = new ArrayList<PExpression>(node.getElements()); + moduleStringAppend(renamer.getNameOfRef(node) + " == {"); + for (int i = 0; i < copy.size(); i++) { + copy.get(i).apply(this); + if (i < copy.size() - 1) { + moduleStringAppend(", "); + } + } + moduleStringAppend("}\n"); + } + + @Override + public void caseADeferredSetSet(ADeferredSetSet node) { + String name = renamer.getName(node); + moduleStringAppend(name); + } + + /** + * Substitutions + * + */ + + @Override + public void caseABecomesElementOfSubstitution( + ABecomesElementOfSubstitution node) { + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (int i = 0; i < copy.size(); i++) { + if (i != 0) { + moduleStringAppend(" /\\ "); + } + copy.get(i).apply(this); + moduleStringAppend(" \\in "); + node.getSet().apply(this); + } + printUnchangedVariables(node, true); + } + + @Override + public void caseAAssignSubstitution(AAssignSubstitution node) { + List<PExpression> copy = new ArrayList<PExpression>( + node.getLhsExpression()); + List<PExpression> copy2 = new ArrayList<PExpression>( + node.getRhsExpressions()); + + for (int i = 0; i < copy.size(); i++) { + PExpression left = copy.get(i); + PExpression right = copy2.get(i); + + if (left instanceof AFunctionExpression) { + printFunctionAssignment(left, right); + + } else { + printNormalAssignment(left, right); + } + + if (i < copy.size() - 1) { + moduleStringAppend(" /\\ "); + } + } + + printUnchangedVariables(node, true); + } + + @Override + public void caseABecomesSuchSubstitution(ABecomesSuchSubstitution node) { + inABecomesSuchSubstitution(node); + if (node.getPredicate() instanceof AExistsPredicate) { + node.getPredicate().apply(this); + } else { + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + + for (int i = 0; i < copy.size(); i++) { + PExpression e = copy.get(i); + e.apply(this); + moduleStringAppend(" \\in "); + typeRestrictor.getRestrictedNode(e).apply(this); + if (i < copy.size() - 1) { + moduleStringAppend(" /\\ "); + } + } + + if (!typeRestrictor.isARemovedNode(node.getPredicate())) { + moduleStringAppend(" /\\ "); + node.getPredicate().apply(this); + } + } + + printUnchangedVariables(node, true); + outABecomesSuchSubstitution(node); + } + + private void printNormalAssignment(PExpression left, PExpression right) { + AIdentifierExpression id = (AIdentifierExpression) left; + String name = Utils.getTIdentifierListAsString(id.getIdentifier()); + if (!machineContext.getVariables().containsKey(name)) { + moduleStringAppend("TRUE"); + } else { + left.apply(this); + moduleStringAppend(" = "); + right.apply(this); + } + } + + private void printFunctionAssignment(PExpression left, PExpression right) { + PExpression var = ((AFunctionExpression) left).getIdentifier(); + LinkedList<PExpression> params = ((AFunctionExpression) left) + .getParameters(); + BType type = typechecker.getType(var); + if (type instanceof FunctionType) { + var.apply(this); + moduleStringAppend("' = "); + moduleStringAppend(FUNC_ASSIGN); + moduleStringAppend("("); + var.apply(this); + moduleStringAppend(", "); + if (params.size() > 1) { + moduleStringAppend("<<"); + } + for (Iterator<PExpression> iterator = params.iterator(); iterator + .hasNext();) { + PExpression pExpression = (PExpression) iterator.next(); + pExpression.apply(this); + if (iterator.hasNext()) { + moduleStringAppend(", "); + } + } + if (params.size() > 1) { + moduleStringAppend(">>"); + } + moduleStringAppend(", "); + right.apply(this); + moduleStringAppend(")"); + } else { + var.apply(this); + moduleStringAppend("' = "); + moduleStringAppend(REL_OVERRIDING + "("); + var.apply(this); + moduleStringAppend(", {<<"); + + if (params.size() > 1) { + moduleStringAppend("<<"); + for (Iterator<PExpression> iterator = params.iterator(); iterator + .hasNext();) { + PExpression pExpression = (PExpression) iterator.next(); + pExpression.apply(this); + if (iterator.hasNext()) { + moduleStringAppend(", "); + } + } + moduleStringAppend(">>"); + } else { + params.get(0).apply(this); + } + moduleStringAppend(", "); + right.apply(this); + moduleStringAppend(">>})"); + } + } + + public void printUnchangedVariables(Node node, boolean printAnd) { + HashSet<Node> unchangedVariablesSet = missingVariableFinder + .getUnchangedVariables(node); + if (null != unchangedVariablesSet) { + ArrayList<Node> unchangedVariables = new ArrayList<Node>( + unchangedVariablesSet); + if (unchangedVariables.size() > 0) { + if (printAnd) { + moduleStringAppend(" /\\"); + } + moduleStringAppend(" UNCHANGED <<"); + for (int i = 0; i < unchangedVariables.size(); i++) { + unchangedVariables.get(i).apply(this); + if (i < unchangedVariables.size() - 1) { + moduleStringAppend(", "); + } + } + moduleStringAppend(">>"); + } else { + if (!printAnd) { + // there is already a /\ + moduleStringAppend("TRUE"); + } + } + } + } + + @Override + public void caseAChoiceSubstitution(AChoiceSubstitution node) { + List<PSubstitution> copy = new ArrayList<PSubstitution>( + node.getSubstitutions()); + moduleStringAppend("("); + for (int i = 0; i < copy.size(); i++) { + moduleStringAppend("("); + copy.get(i).apply(this); + moduleStringAppend(")"); + if (i < copy.size() - 1) { + moduleStringAppend(" \\/ "); + } + + } + moduleStringAppend(")"); + printUnchangedVariables(node, true); + } + + @Override + public void caseASkipSubstitution(ASkipSubstitution node) { + printUnchangedVariables(node, false); + } + + @Override + public void caseAIfSubstitution(AIfSubstitution node) { + if (node.getElsifSubstitutions().size() > 0) { + printElseIFSubsitution(node); + return; + } + moduleStringAppend("(IF "); + node.getCondition().apply(this); + moduleStringAppend(" THEN "); + node.getThen().apply(this); + List<PSubstitution> copy = new ArrayList<PSubstitution>( + node.getElsifSubstitutions()); + for (PSubstitution e : copy) { + e.apply(this); + } + moduleStringAppend(" ELSE "); + if (node.getElse() != null) { + node.getElse().apply(this); + } else { + printUnchangedVariablesNull(node, false); + } + + moduleStringAppend(")"); + printUnchangedVariables(node, true); + } + + private void printElseIFSubsitution(AIfSubstitution node) { + moduleStringAppend("(CASE "); + node.getCondition().apply(this); + moduleStringAppend(" -> "); + node.getThen().apply(this); + List<PSubstitution> copy = new ArrayList<PSubstitution>( + node.getElsifSubstitutions()); + for (PSubstitution e : copy) { + moduleStringAppend(" [] "); + e.apply(this); + } + moduleStringAppend(" [] OTHER -> "); + if (node.getElse() != null) { + node.getElse().apply(this); + } else { + printUnchangedVariablesNull(node, false); + } + moduleStringAppend(")"); + printUnchangedVariables(node, true); + + } + + @Override + public void caseAIfElsifSubstitution(AIfElsifSubstitution node) { + node.getCondition().apply(this); + moduleStringAppend(" -> "); + node.getThenSubstitution().apply(this); + printUnchangedVariables(node, true); + + } + + public void printUnchangedVariablesNull(Node node, boolean printAnd) { + HashSet<Node> unchangedVariablesSet = missingVariableFinder + .getUnchangedVariablesNull(node); + if (null != unchangedVariablesSet) { + ArrayList<Node> unchangedVariables = new ArrayList<Node>( + unchangedVariablesSet); + if (unchangedVariables.size() > 0) { + if (printAnd) { + moduleStringAppend(" /\\"); + } + moduleStringAppend(" UNCHANGED <<"); + for (int i = 0; i < unchangedVariables.size(); i++) { + unchangedVariables.get(i).apply(this); + if (i < unchangedVariables.size() - 1) { + moduleStringAppend(", "); + } + } + moduleStringAppend(">>"); + } + } + } + + @Override + public void caseAParallelSubstitution(AParallelSubstitution node) { + inAParallelSubstitution(node); + for (Iterator<PSubstitution> itr = node.getSubstitutions().iterator(); itr + .hasNext();) { + PSubstitution e = itr.next(); + + e.apply(this); + + if (itr.hasNext()) { + moduleStringAppend(" /\\ "); + } + } + + printUnchangedVariables(node, true); + outAParallelSubstitution(node); + } + + @Override + public void caseAPreconditionSubstitution(APreconditionSubstitution node) { + inAPreconditionSubstitution(node); + if (!typeRestrictor.isARemovedNode(node.getPredicate())) { + node.getPredicate().apply(this); + moduleStringAppend("\n\t/\\ "); + } + node.getSubstitution().apply(this); + + outAPreconditionSubstitution(node); + } + + @Override + public void caseAAssertionSubstitution(AAssertionSubstitution node) { + inAAssertionSubstitution(node); + node.getPredicate().apply(this); + moduleStringAppend("\n\t/\\ "); + node.getSubstitution().apply(this); + outAAssertionSubstitution(node); + } + + @Override + public void caseASelectSubstitution(ASelectSubstitution node) { + inASelectSubstitution(node); + // TODO remove brackets + moduleStringAppend("("); + List<PSubstitution> copy = new ArrayList<PSubstitution>( + node.getWhenSubstitutions()); + + if (missingVariableFinder.hasUnchangedVariables(node) + && (copy.size() > 0 || node.getElse() != null)) { + moduleStringAppend("("); + } + if (!typeRestrictor.isARemovedNode(node.getCondition())) { + if (copy.size() > 0 || node.getElse() != null) { + moduleStringAppend("("); + } + node.getCondition().apply(this); + moduleStringAppend(" /\\ "); + } + node.getThen().apply(this); + if (!typeRestrictor.isARemovedNode(node.getCondition())) { + if (copy.size() > 0 || node.getElse() != null) { + moduleStringAppend(")"); + } + } + + for (PSubstitution e : copy) { + moduleStringAppend(" \\/ "); + e.apply(this); + } + if (node.getElse() != null) { + moduleStringAppend(" \\/ ("); + moduleStringAppend("~("); + for (PSubstitution e : copy) { + ASelectWhenSubstitution w = (ASelectWhenSubstitution) e; + moduleStringAppend(" \\/ "); + w.getCondition().apply(this); + } + moduleStringAppend(")"); + moduleStringAppend(" /\\ "); + node.getElse().apply(this); + moduleStringAppend(")"); + } + + if (missingVariableFinder.hasUnchangedVariables(node) + && (copy.size() > 0 || node.getElse() != null)) { + moduleStringAppend(")"); + } + moduleStringAppend(")"); + printUnchangedVariables(node, true); + + outASelectSubstitution(node); + } + + @Override + public void caseASelectWhenSubstitution(ASelectWhenSubstitution node) { + inASelectWhenSubstitution(node); + node.getCondition().apply(this); + moduleStringAppend(" /\\ "); + node.getSubstitution().apply(this); + outASelectWhenSubstitution(node); + } + + @Override + public void caseAAnySubstitution(AAnySubstitution node) { + inAAnySubstitution(node); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + if (copy.size() > 0) { + moduleStringAppend("\\E "); + for (int i = 0; i < copy.size(); i++) { + PExpression e = copy.get(i); + e.apply(this); + moduleStringAppend(" \\in "); + typeRestrictor.getRestrictedNode(e).apply(this); + // printTypeOfIdentifier(e, false); + if (i < copy.size() - 1) { + moduleStringAppend(", "); + } + } + moduleStringAppend(" : "); + } + + if (!typeRestrictor.isARemovedNode(node.getWhere())) { + node.getWhere().apply(this); + moduleStringAppend(" /\\ "); + } + + node.getThen().apply(this); + printUnchangedVariables(node, true); + outAAnySubstitution(node); + } + + @Override + public void caseALetSubstitution(ALetSubstitution node) { + inALetSubstitution(node); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + if (copy.size() > 0) { + moduleStringAppend("\\E "); + for (int i = 0; i < copy.size(); i++) { + PExpression e = copy.get(i); + e.apply(this); + moduleStringAppend(" \\in "); + typeRestrictor.getRestrictedNode(e).apply(this); + if (i < copy.size() - 1) { + moduleStringAppend(", "); + } + } + moduleStringAppend(" : "); + } + + if (typeRestrictor.isARemovedNode(node.getPredicate())) { + moduleStringAppend("TRUE"); + } else { + node.getPredicate().apply(this); + } + + moduleStringAppend(" /\\ "); + node.getSubstitution().apply(this); + printUnchangedVariables(node, true); + + outALetSubstitution(node); + } + + @Override + public void caseAOperation(AOperation node) { + String name = renamer.getNameOfRef(node); + moduleStringAppend(name); + + // TODO handle output parameter of a operation + // List<PExpression> output = new ArrayList<PExpression>( + // node.getReturnValues()); + List<PExpression> params = new ArrayList<PExpression>( + node.getParameters()); + List<PExpression> newList = new ArrayList<PExpression>(); + newList.addAll(params); + // newList.addAll(output); + + if (newList.size() > 0) { + moduleStringAppend("("); + for (int i = 0; i < newList.size(); i++) { + if (i != 0) { + moduleStringAppend(", "); + } + newList.get(i).apply(this); + } + moduleStringAppend(")"); + } + moduleStringAppend(" == "); + if (node.getOperationBody() != null) { + node.getOperationBody().apply(this); + } + + printUnchangedConstants(); + + if (TLC4BGlobals.isPartialInvariantEvaluation()) { + moduleStringAppend(" /\\ last_action' = "); + moduleStringAppend(name); + moduleStringAppend("_action"); + } + + moduleStringAppend("\n\n"); + } + + private void printUnchangedConstants() { + ArrayList<Node> vars = new ArrayList<Node>(tlaModule.getVariables()); + vars.removeAll(machineContext.getVariables().values()); + if (vars.size() > 0) { + moduleStringAppend(" /\\ UNCHANGED <<"); + for (int i = 0; i < vars.size(); i++) { + if (i != 0) + moduleStringAppend(", "); + vars.get(i).apply(this); + } + + moduleStringAppend(">>"); + } + } + + /** Expression **/ + + @Override + public void caseAIdentifierExpression(AIdentifierExpression node) { + inAIdentifierExpression(node); + String name = renamer.getNameOfRef(node); + if (name == null) { + name = Utils.getTIdentifierListAsString(node.getIdentifier()); + } + if (StandardMadules.isAbstractConstant(name)) { + // in order to pass the member check + moduleStringAppend("{}"); + return; + } + moduleStringAppend(name); + if (primedNodesMarker.isPrimed(node)) { + moduleStringAppend("'"); + } + outAIdentifierExpression(node); + } + + @Override + public void caseAPrimedIdentifierExpression(APrimedIdentifierExpression node) { + String name = renamer.getNameOfRef(node); + if (name == null) { + name = Utils.getTIdentifierListAsString(node.getIdentifier()); + } + moduleStringAppend(name); + } + + @Override + public void caseAStringExpression(AStringExpression node) { + inAStringExpression(node); + moduleStringAppend("\""); + moduleStringAppend(node.getContent().getText().toString()); + moduleStringAppend("\""); + outAStringExpression(node); + } + + @Override + public void caseAStringSetExpression(AStringSetExpression node) { + moduleStringAppend("STRING"); + } + + /** + * Logical Predicates + */ + + @Override + public void caseAEqualPredicate(AEqualPredicate node) { + inAEqualPredicate(node); + node.getLeft().apply(this); + moduleStringAppend(" = "); + node.getRight().apply(this); + outAEqualPredicate(node); + } + + @Override + public void caseANotEqualPredicate(ANotEqualPredicate node) { + inANotEqualPredicate(node); + node.getLeft().apply(this); + moduleStringAppend(" # "); + node.getRight().apply(this); + outANotEqualPredicate(node); + } + + @Override + public void caseAIfThenElseExpression(AIfThenElseExpression node) { + moduleStringAppend("(IF "); + node.getCondition().apply(this); + moduleStringAppend(" THEN "); + node.getThen().apply(this); + moduleStringAppend(" ELSE "); + node.getElse().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseAConjunctPredicate(AConjunctPredicate node) { + boolean left = typeRestrictor.isARemovedNode(node.getLeft()); + boolean right = typeRestrictor.isARemovedNode(node.getRight()); + + if (left && right) { + moduleStringAppend("TRUE"); + } else if (left) { + node.getRight().apply(this); + } else if (right) { + node.getLeft().apply(this); + } else { + inAConjunctPredicate(node); + node.getLeft().apply(this); + moduleStringAppend(" /\\ "); + node.getRight().apply(this); + outAConjunctPredicate(node); + } + } + + @Override + public void caseADisjunctPredicate(ADisjunctPredicate node) { + inADisjunctPredicate(node); + node.getLeft().apply(this); + moduleStringAppend(" \\/ "); + node.getRight().apply(this); + outADisjunctPredicate(node); + } + + @Override + public void caseAImplicationPredicate(AImplicationPredicate node) { + inAImplicationPredicate(node); + if (!typeRestrictor.isARemovedNode(node.getLeft())) { + node.getLeft().apply(this); + moduleStringAppend(" => "); + } + node.getRight().apply(this); + outAImplicationPredicate(node); + } + + @Override + public void caseAEquivalencePredicate(AEquivalencePredicate node) { + inAEquivalencePredicate(node); + node.getLeft().apply(this); + moduleStringAppend(" <=> "); + node.getRight().apply(this); + outAEquivalencePredicate(node); + } + + @Override + public void caseABoolSetExpression(ABoolSetExpression node) { + moduleStringAppend("BOOLEAN"); + } + + @Override + public void caseABooleanTrueExpression(ABooleanTrueExpression node) { + inABooleanTrueExpression(node); + moduleStringAppend("TRUE"); + outABooleanTrueExpression(node); + } + + @Override + public void caseABooleanFalseExpression(ABooleanFalseExpression node) { + inABooleanFalseExpression(node); + moduleStringAppend("FALSE"); + outABooleanFalseExpression(node); + } + + @Override + public void caseAForallPredicate(AForallPredicate node) { + /* + * B: !x,y(T => P) TLA: \A x \in type(x), y \in type(y): T => P + */ + inAForallPredicate(node); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + + int start = parameterCounter; + int end = parameterCounter + copy.size(); + parameterCounter = end + 1; + if (assertionMode) { + + moduleStringAppend("("); + moduleStringAppend("TLCSet("); + moduleStringAppend("" + start); + moduleStringAppend(", TRUE) /\\ "); + for (int i = start; i < end; i++) { + moduleStringAppend("TLCSet("); + moduleStringAppend("" + (i + 1)); + moduleStringAppend(", \"NULL\")"); + moduleStringAppend(" /\\ "); + } + } + + moduleStringAppend("\\A "); + for (int i = 0; i < copy.size(); i++) { + PExpression e = copy.get(i); + e.apply(this); + moduleStringAppend(" \\in "); + typeRestrictor.getRestrictedNode(e).apply(this); + if (i < copy.size() - 1) { + moduleStringAppend(", "); + } + } + moduleStringAppend(" : "); + if (assertionMode) { + for (int i = 0; i < copy.size(); i++) { + PExpression e = copy.get(i); + moduleStringAppend("TLCSet("); + moduleStringAppend("" + (i + 1)); + moduleStringAppend(", "); + e.apply(this); + moduleStringAppend(")"); + moduleStringAppend(" /\\ "); + } + + assertionMode = false; + + moduleStringAppend(" IF "); + node.getImplication().apply(this); + moduleStringAppend(" THEN TRUE "); + moduleStringAppend(" ELSE SaveValue(<< \""); + moduleStringAppend(assertionName); + moduleStringAppend("\", "); + for (int i = start; i < end; i++) { + moduleStringAppend("TLCGet("); + moduleStringAppend("" + (i + 1)); + moduleStringAppend(")"); + if (i < copy.size() - 1) { + moduleStringAppend(", "); + } + + } + moduleStringAppend(" >>) "); + moduleStringAppend("/\\ TLCSet("); + moduleStringAppend("" + start); + moduleStringAppend(", FALSE)"); + moduleStringAppend(")"); + moduleStringAppend(" /\\ TLCGet("); + moduleStringAppend("" + start); + moduleStringAppend(")"); + } else { + node.getImplication().apply(this); + } + + outAForallPredicate(node); + } + + @Override + public void caseAExistsPredicate(AExistsPredicate node) { + /* + * B: #x,y(T => P) TLA: \E x \in type(x), y \in type(y): T => P + */ + inAExistsPredicate(node); + moduleStringAppend("\\E "); + + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (int i = 0; i < copy.size(); i++) { + PExpression e = copy.get(i); + e.apply(this); + moduleStringAppend(" \\in "); + typeRestrictor.getRestrictedNode(e).apply(this); + if (i < copy.size() - 1) { + moduleStringAppend(", "); + } + } + moduleStringAppend(" : "); + if (typeRestrictor.isARemovedNode(node.getPredicate())) { + moduleStringAppend("TRUE"); + } else { + node.getPredicate().apply(this); + } + outAExistsPredicate(node); + } + + @Override + public void caseANegationPredicate(ANegationPredicate node) { + inANegationPredicate(node); + moduleStringAppend("\\neg("); + node.getPredicate().apply(this); + moduleStringAppend(")"); + outANegationPredicate(node); + } + + @Override + public void caseAIntegerExpression(AIntegerExpression node) { + inAIntegerExpression(node); + if (node.getLiteral() != null) { + moduleStringAppend(node.getLiteral().getText()); + // node.getLiteral().apply(this); + } + outAIntegerExpression(node); + } + + @Override + public void caseAPredicateDefinitionDefinition( + APredicateDefinitionDefinition node) { + String name = renamer.getNameOfRef(node); + if (null == name) { + name = node.getName().getText().trim(); + } + printBDefinition(name, node.getParameters(), node.getRhs()); + } + + @Override + public void caseAExpressionDefinitionDefinition( + AExpressionDefinitionDefinition node) { + String oldName = node.getName().getText().trim(); + if (StandardMadules.isKeywordInModuleExternalFunctions(oldName)) { + return; + } + String name = renamer.getName(node); + if (null == name) { + name = node.getName().getText().trim(); + } + moduleStringAppend(name); + List<PExpression> args = node.getParameters(); + if (args.size() > 0) { + moduleStringAppend("("); + for (int i = 0; i < args.size(); i++) { + if (i != 0) + moduleStringAppend(", "); + args.get(i).apply(this); + } + moduleStringAppend(")"); + } + + moduleStringAppend(" == "); + if (TLC4BGlobals.isForceTLCToEvalConstants()) { + moduleStringAppend("TLCEval("); + } + node.getRhs().apply(this); + if (TLC4BGlobals.isForceTLCToEvalConstants()) { + moduleStringAppend(")"); + } + moduleStringAppend("\n"); + // printBDefinition(name, node.getParameters(), node.getRhs()); + } + + @Override + public void caseASubstitutionDefinitionDefinition( + ASubstitutionDefinitionDefinition node) { + String name = renamer.getNameOfRef(node); + if (null == name) { + name = node.getName().getText().trim(); + } + printBDefinition(name, node.getParameters(), node.getRhs()); + } + + private void printBDefinition(String name, List<PExpression> args, + Node rightSide) { + if (StandardMadules.isKeywordInModuleExternalFunctions(name)) { + return; + } + moduleStringAppend(name); + if (args.size() > 0) { + moduleStringAppend("("); + for (int i = 0; i < args.size(); i++) { + if (i != 0) + moduleStringAppend(", "); + args.get(i).apply(this); + } + moduleStringAppend(")"); + } + + moduleStringAppend(" == "); + rightSide.apply(this); + moduleStringAppend("\n"); + } + + @Override + public void caseADefinitionExpression(ADefinitionExpression node) { + String name = renamer.getNameOfRef(node); + if (null == name) { + name = node.getDefLiteral().getText().trim(); + } + printBDefinitionCall(name, node.getParameters()); + } + + @Override + public void caseADefinitionPredicate(ADefinitionPredicate node) { + String name = renamer.getNameOfRef(node); + if (null == name) { + name = node.getDefLiteral().getText().trim(); + } + printBDefinitionCall(name, node.getParameters()); + } + + @Override + public void caseADefinitionSubstitution(ADefinitionSubstitution node) { + String name = renamer.getNameOfRef(node); + if (null == name) { + name = node.getDefLiteral().getText().trim(); + } + printBDefinitionCall(name, node.getParameters()); + } + + public void printBDefinitionCall(String name, List<PExpression> args) { + moduleStringAppend(name); + if (args.size() > 0) { + moduleStringAppend("("); + for (int i = 0; i < args.size(); i++) { + if (i != 0) + moduleStringAppend(", "); + args.get(i).apply(this); + + } + moduleStringAppend(")"); + } + } + + /** + * Numbers + */ + + @Override + public void caseAIntegerSetExpression(AIntegerSetExpression node) { + inAIntegerSetExpression(node); + moduleStringAppend("Int"); + outAIntegerSetExpression(node); + } + + @Override + public void caseANaturalSetExpression(ANaturalSetExpression node) { + inANaturalSetExpression(node); + moduleStringAppend("Nat"); + outANaturalSetExpression(node); + } + + @Override + public void caseANatural1SetExpression(ANatural1SetExpression node) { + inANatural1SetExpression(node); + moduleStringAppend("(Nat \\ {0})"); + outANatural1SetExpression(node); + } + + @Override + public void caseAIntSetExpression(AIntSetExpression node) { + inAIntSetExpression(node); + moduleStringAppend("(" + TLC4BGlobals.getMIN_INT() + ".." + + TLC4BGlobals.getMAX_INT() + ")"); + outAIntSetExpression(node); + } + + @Override + public void caseANatSetExpression(ANatSetExpression node) { + inANatSetExpression(node); + moduleStringAppend("(0.." + TLC4BGlobals.getMAX_INT() + ")"); + outANatSetExpression(node); + } + + @Override + public void caseANat1SetExpression(ANat1SetExpression node) { + inANat1SetExpression(node); + moduleStringAppend("(1.." + TLC4BGlobals.getMAX_INT() + ")"); + outANat1SetExpression(node); + } + + @Override + public void caseAIntervalExpression(AIntervalExpression node) { + inAIntervalExpression(node); + moduleStringAppend("("); + node.getLeftBorder().apply(this); + moduleStringAppend(" .. "); + node.getRightBorder().apply(this); + moduleStringAppend(")"); + outAIntervalExpression(node); + } + + @Override + public void caseAGreaterPredicate(AGreaterPredicate node) { + inAGreaterPredicate(node); + node.getLeft().apply(this); + moduleStringAppend(" > "); + node.getRight().apply(this); + outAGreaterPredicate(node); + } + + @Override + public void caseALessPredicate(ALessPredicate node) { + inALessPredicate(node); + node.getLeft().apply(this); + moduleStringAppend(" < "); + node.getRight().apply(this); + outALessPredicate(node); + } + + @Override + public void caseAGreaterEqualPredicate(AGreaterEqualPredicate node) { + inAGreaterEqualPredicate(node); + node.getLeft().apply(this); + moduleStringAppend(" >= "); + node.getRight().apply(this); + outAGreaterEqualPredicate(node); + } + + @Override + public void caseALessEqualPredicate(ALessEqualPredicate node) { + inALessEqualPredicate(node); + node.getLeft().apply(this); + moduleStringAppend(" =< "); + node.getRight().apply(this); + outALessEqualPredicate(node); + } + + @Override + public void caseAMinExpression(AMinExpression node) { + moduleStringAppend(MIN); + moduleStringAppend("("); + node.getExpression().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseAMaxExpression(AMaxExpression node) { + moduleStringAppend(MAX); + moduleStringAppend("("); + node.getExpression().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseAUnaryMinusExpression(AUnaryMinusExpression node) { + inAUnaryMinusExpression(node); + moduleStringAppend("-"); + node.getExpression().apply(this); + outAUnaryMinusExpression(node); + } + + @Override + public void caseAAddExpression(AAddExpression node) { + inAAddExpression(node); + node.getLeft().apply(this); + moduleStringAppend(" + "); + node.getRight().apply(this); + outAAddExpression(node); + } + + @Override + public void caseADivExpression(ADivExpression node) { + inADivExpression(node); + moduleStringAppend(B_DIVISION); + moduleStringAppend("("); + node.getLeft().apply(this); + moduleStringAppend(", "); + node.getRight().apply(this); + moduleStringAppend(")"); + outADivExpression(node); + } + + @Override + public void caseAPowerOfExpression(APowerOfExpression node) { + moduleStringAppend(B_POWER_Of); + moduleStringAppend("("); + node.getLeft().apply(this); + moduleStringAppend(", "); + node.getRight().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseAModuloExpression(AModuloExpression node) { + + inAModuloExpression(node); + moduleStringAppend(B_MODULO); + moduleStringAppend("("); + node.getLeft().apply(this); + moduleStringAppend(", "); + node.getRight().apply(this); + moduleStringAppend(")"); + outAModuloExpression(node); + } + + @Override + public void caseAGeneralProductExpression(AGeneralProductExpression node) { + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + moduleStringAppend("Pi("); + moduleStringAppend("{"); + moduleStringAppend("<<"); + moduleStringAppend("<<"); + printIdentifierList(copy); + moduleStringAppend(">>"); + moduleStringAppend(", "); + node.getExpression().apply(this); + moduleStringAppend(">>"); + moduleStringAppend(" : "); + + printIdentifierList(copy); + moduleStringAppend(" \\in "); + if (typeRestrictor.isARemovedNode(node.getPredicates())) { + printTypesOfIdentifierList(copy); + } else { + moduleStringAppend("{"); + printIdentifierList(copy); + moduleStringAppend(" \\in "); + printTypesOfIdentifierList(copy); + moduleStringAppend(" : "); + node.getPredicates().apply(this); + moduleStringAppend("}"); + } + moduleStringAppend("}"); + moduleStringAppend(")"); + } + + @Override + public void caseAGeneralSumExpression(AGeneralSumExpression node) { + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + moduleStringAppend("Sigma("); + moduleStringAppend("{"); + moduleStringAppend("<<"); + moduleStringAppend("<<"); + printIdentifierList(copy); + moduleStringAppend(">>"); + moduleStringAppend(", "); + node.getExpression().apply(this); + moduleStringAppend(">>"); + moduleStringAppend(" : "); + + printIdentifierList(copy); + moduleStringAppend(" \\in "); + if (typeRestrictor.isARemovedNode(node.getPredicates())) { + printTypesOfIdentifierList(copy); + } else { + moduleStringAppend("{"); + printIdentifierList(copy); + moduleStringAppend(" \\in "); + printTypesOfIdentifierList(copy); + moduleStringAppend(" : "); + node.getPredicates().apply(this); + moduleStringAppend("}"); + } + moduleStringAppend("}"); + moduleStringAppend(")"); + } + + @Override + public void caseASuccessorExpression(ASuccessorExpression node) { + inASuccessorExpression(node); + moduleStringAppend("succ"); + outASuccessorExpression(node); + } + + @Override + public void caseAPredecessorExpression(APredecessorExpression node) { + inAPredecessorExpression(node); + moduleStringAppend("pred"); + outAPredecessorExpression(node); + } + + @Override + public void caseAMaxIntExpression(AMaxIntExpression node) { + moduleStringAppend(String.valueOf(TLC4BGlobals.getMAX_INT())); + } + + @Override + public void caseAMinIntExpression(AMinIntExpression node) { + moduleStringAppend(String.valueOf(TLC4BGlobals.getMIN_INT())); + } + + /** + * Function + */ + + private void printIdentifierList(List<PExpression> copy) { + if (copy.size() == 1) { + copy.get(0).apply(this); + return; + } + moduleStringAppend("<<"); + for (int i = 0; i < copy.size(); i++) { + if (i != 0) { + moduleStringAppend(", "); + } + copy.get(i).apply(this); + } + moduleStringAppend(">>"); + } + + private void printTypesOfIdentifierList(List<PExpression> copy) { + if (copy.size() > 1) { + moduleStringAppend("("); + } + for (int i = 0; i < copy.size(); i++) { + moduleStringAppend("("); + typeRestrictor.getRestrictedNode(copy.get(i)).apply(this); + moduleStringAppend(")"); + if (i < copy.size() - 1) + moduleStringAppend(" \\times "); + } + if (copy.size() > 1) { + moduleStringAppend(")"); + } + } + + /***************************************************************************** + * Functions + *****************************************************************************/ + + @Override + public void caseALambdaExpression(ALambdaExpression node) { + /** + * B: %a,b.(P|e) TLA+ function: [<<a,b>> \in {<<a,b>> \in + * type(a)*type(b) : P}|e] relation: TLA+: {<< <<a,b>>, e>>: <<a,b>> \in + * {<<a,b>> \in type(a)*type(b): P}} + */ + inALambdaExpression(node); + if (this.typechecker.getType(node) instanceof SetType) { + moduleStringAppend("{<<"); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + printIdentifierList(copy); + moduleStringAppend(", "); + node.getExpression().apply(this); + moduleStringAppend(">> : "); + + printIdentifierList(copy); + + moduleStringAppend(" \\in "); + + if (typeRestrictor.isARemovedNode(node.getPredicate())) { + printTypesOfIdentifierList(copy); + } else { + moduleStringAppend("{"); + printIdentifierList(copy); + moduleStringAppend(" \\in "); + printTypesOfIdentifierList(copy); + moduleStringAppend(" : "); + node.getPredicate().apply(this); + moduleStringAppend("}"); + } + moduleStringAppend("}"); + + } else { + moduleStringAppend("["); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + printIdentifierList(copy); + + moduleStringAppend(" \\in "); + if (typeRestrictor.isARemovedNode(node.getPredicate())) { + printTypesOfIdentifierList(copy); + + } else { + moduleStringAppend("{"); + printIdentifierList(copy); + + moduleStringAppend(" \\in "); + printTypesOfIdentifierList(copy); + moduleStringAppend(" : "); + node.getPredicate().apply(this); + moduleStringAppend("}"); + } + moduleStringAppend(" |-> "); + node.getExpression().apply(this); + moduleStringAppend("]"); + } + outALambdaExpression(node); + } + + @Override + // Function call + public void caseAFunctionExpression(AFunctionExpression node) { + inAFunctionExpression(node); + + if (node.getIdentifier() instanceof AIdentifierExpression) { + AIdentifierExpression id = (AIdentifierExpression) node + .getIdentifier(); + String name = Utils.getTIdentifierListAsString(id.getIdentifier()); + if (StandardMadules.isAbstractConstant(name)) { + + moduleStringAppend(name); + // node.getIdentifier().apply(this); + moduleStringAppend("("); + List<PExpression> copy = new ArrayList<PExpression>( + node.getParameters()); + copy.get(0).apply(this); + moduleStringAppend(")"); + return; + + } + + } + + BType type = this.typechecker.getType(node.getIdentifier()); + if (type instanceof FunctionType) { + node.getIdentifier().apply(this); + moduleStringAppend("["); + List<PExpression> copy = new ArrayList<PExpression>( + node.getParameters()); + for (int i = 0; i < copy.size(); i++) { + if (i != 0) { + moduleStringAppend(", "); + } + copy.get(i).apply(this); + } + moduleStringAppend("]"); + } else { + + if (TLC4BGlobals.checkWelldefinedness()) { + moduleStringAppend(REL_CALL); + } else { + moduleStringAppend(REL_CALL_WITHOUT_WD_CHECK); + } + moduleStringAppend("("); + node.getIdentifier().apply(this); + moduleStringAppend(", "); + List<PExpression> copy = new ArrayList<PExpression>( + node.getParameters()); + if (copy.size() > 1) + moduleStringAppend("<<"); + for (int i = 0; i < copy.size(); i++) { + if (i != 0) { + moduleStringAppend(", "); + } + copy.get(i).apply(this); + } + if (copy.size() > 1) + moduleStringAppend(">>"); + moduleStringAppend(")"); + } + + outAFunctionExpression(node); + } + + @Override + public void caseARangeExpression(ARangeExpression node) { + if (typechecker.getType(node.getExpression()) instanceof FunctionType) { + moduleStringAppend(FUNC_RANGE); + } else { + moduleStringAppend(REL_RANGE); + } + moduleStringAppend("("); + node.getExpression().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseAImageExpression(AImageExpression node) { + if (typechecker.getType(node.getLeft()) instanceof FunctionType) { + moduleStringAppend(FUNC_IMAGE); + } else { + moduleStringAppend(REL_IMAGE); + } + moduleStringAppend("("); + node.getLeft().apply(this); + moduleStringAppend(", "); + node.getRight().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseATotalFunctionExpression(ATotalFunctionExpression node) { + BType type = this.typechecker.getType(node); + BType subtype = ((SetType) type).getSubtype(); + if (subtype instanceof FunctionType) { + moduleStringAppend("["); + node.getLeft().apply(this); + moduleStringAppend(" -> "); + node.getRight().apply(this); + moduleStringAppend("]"); + } else { + if (node.parent() instanceof AMemberPredicate + && !typeRestrictor.isARemovedNode(node.parent()) + && !this.tlaModule.getInitPredicates().contains( + node.parent())) { + moduleStringAppend(REL_TOTAL_FUNCTION_ELEMENT_OF); + } else { + moduleStringAppend(REL_TOTAL_FUNCTION); + } + moduleStringAppend("("); + node.getLeft().apply(this); + moduleStringAppend(", "); + node.getRight().apply(this); + moduleStringAppend(")"); + } + } + + private boolean recursiveIsElementOfTest(Node node) { + Node parent = node.parent(); + if (parent instanceof AMemberPredicate + && !typeRestrictor.isARemovedNode(parent) + && !this.tlaModule.getInitPredicates().contains(parent)) { + return true; + } else { + String clazz = parent.getClass().getName(); + // todo include all expressions which have an "element of" + // translation + if (clazz.contains("Total") || clazz.contains("Partial")) { + return recursiveIsElementOfTest(node.parent()); + } else + return false; + } + } + + private void setOfFuntions(Node node, String funcName, String relName, + String relEleOfName, Node left, Node right) { + BType type = this.typechecker.getType(node); + BType subtype = ((SetType) type).getSubtype(); + if (subtype instanceof FunctionType) { + moduleStringAppend(funcName); + } else { + if (recursiveIsElementOfTest(node)) { + moduleStringAppend(relEleOfName); + } else { + moduleStringAppend(relName); + } + } + moduleStringAppend("("); + left.apply(this); + moduleStringAppend(", "); + right.apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseATotalInjectionExpression(ATotalInjectionExpression node) { + setOfFuntions(node, TOTAL_INJECTIVE_FUNCTION, + REL_TOTAL_INJECTIVE_FUNCTION, + REL_TOTAL_INJECTIVE_FUNCTION_ELEMENT_OF, node.getLeft(), + node.getRight()); + } + + @Override + public void caseATotalSurjectionExpression(ATotalSurjectionExpression node) { + setOfFuntions(node, TOTAL_SURJECTIVE_FUNCTION, + REL_TOTAL_SURJECTIVE_FUNCTION, + REL_TOTAL_SURJECTIVE_FUNCTION_ELEMENT_OF, node.getLeft(), + node.getRight()); + } + + @Override + public void caseATotalBijectionExpression(ATotalBijectionExpression node) { + setOfFuntions(node, TOTAL_BIJECTIVE_FUNCTION, + REL_TOTAL_BIJECTIVE_FUNCTION, + REL_TOTAL_BIJECTIVE_FUNCTION_ELEMENT_OF, node.getLeft(), + node.getRight()); + } + + private void setOfPartialFuntions(Node node, String funcName, + String funcEleOfName, String relName, String relEleOfName, + Node left, Node right) { + BType type = this.typechecker.getType(node); + BType subtype = ((SetType) type).getSubtype(); + if (subtype instanceof FunctionType) { + Node parent = node.parent(); + if (parent instanceof AMemberPredicate + && !typeRestrictor.isARemovedNode(parent)) { + moduleStringAppend(funcEleOfName); + moduleStringAppend("("); + ((AMemberPredicate) parent).getLeft().apply(this); + moduleStringAppend(", "); + left.apply(this); + moduleStringAppend(", "); + right.apply(this); + moduleStringAppend(")"); + return; + } else { + moduleStringAppend(funcName); + } + } else { + if (recursiveIsElementOfTest(node)) { + moduleStringAppend(relEleOfName); + } else { + moduleStringAppend(relName); + } + } + moduleStringAppend("("); + left.apply(this); + moduleStringAppend(", "); + right.apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseAPartialFunctionExpression(APartialFunctionExpression node) { + setOfPartialFuntions(node, PARTIAL_FUNCTION, + PARTIAL_FUNCTION_ELEMENT_OF, REL_PARTIAL_FUNCTION, + REL_PARTIAL_FUNCTION_ELEMENT_OF, node.getLeft(), + node.getRight()); + } + + @Override + public void caseAPartialInjectionExpression(APartialInjectionExpression node) { + setOfPartialFuntions(node, PARTIAL_INJECTIVE_FUNCTION, + PARTIAL_INJECTIVE_FUNCTION_ELEMENT_OF, + REL_PARTIAL_INJECTIVE_FUNCTION, + REL_PARTIAL_INJECTIVE_FUNCTION_ELEMENT_OF, node.getLeft(), + node.getRight()); + } + + @Override + public void caseAPartialSurjectionExpression( + APartialSurjectionExpression node) { + setOfPartialFuntions(node, PARTIAL_SURJECTIVE_FUNCTION, + PARTIAL_SURJECTIVE_FUNCTION_ELEMENT_OF, + REL_PARTIAL_SURJECTIVE_FUNCTION, + REL_PARTIAL_SURJECTIVE_FUNCTION_ELEMENT_OF, node.getLeft(), + node.getRight()); + } + + @Override + public void caseAPartialBijectionExpression(APartialBijectionExpression node) { + setOfPartialFuntions(node, PARITAL_BIJECTIVE_FUNCTION, + PARITAL_BIJECTIVE_FUNCTION_ELEMENT_OF, + REL_PARTIAL_BIJECTIVE_FUNCTION, + REL_PARTIAL_BIJECTIVE_FUNCTION_ELEMENT_OF, node.getLeft(), + node.getRight()); + } + + /** + * Sets + */ + + @Override + public void caseASetExtensionExpression(ASetExtensionExpression node) { + if (typechecker.getType(node) instanceof FunctionType) { + // 1 :> 2 @@ 2 :> 2 + moduleStringAppend("("); + for (int i = 0; i < node.getExpressions().size(); i++) { + ACoupleExpression couple = (ACoupleExpression) node + .getExpressions().get(i); + Node left = couple.getList().get(0); + Node right = couple.getList().get(1); + left.apply(this); + moduleStringAppend(":>"); + right.apply(this); + + if (i < node.getExpressions().size() - 1) { + moduleStringAppend(" @@ "); + } + } + moduleStringAppend(")"); + return; + } + moduleStringAppend("{"); + { + List<PExpression> copy = new ArrayList<PExpression>( + node.getExpressions()); + for (int i = 0; i < copy.size(); i++) { + if (i != 0) { + moduleStringAppend(", "); + } + copy.get(i).apply(this); + } + } + moduleStringAppend("}"); + } + + @Override + public void caseAEmptySetExpression(AEmptySetExpression node) { + if (typechecker.getType(node) instanceof FunctionType) { + moduleStringAppend("<< >>"); + } else { + moduleStringAppend("{}"); + } + } + + @Override + public void caseAMemberPredicate(AMemberPredicate node) { + inAMemberPredicate(node); + node.getLeft().apply(this); + moduleStringAppend(" \\in "); + node.getRight().apply(this); + outAMemberPredicate(node); + } + + @Override + public void caseANotMemberPredicate(ANotMemberPredicate node) { + inANotMemberPredicate(node); + node.getLeft().apply(this); + moduleStringAppend(" \\notin "); + node.getRight().apply(this); + outANotMemberPredicate(node); + } + + @Override + public void caseAComprehensionSetExpression(AComprehensionSetExpression node) { + inAComprehensionSetExpression(node); + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + if (copy.size() < 3) { + moduleStringAppend("{"); + printIdentifierList(copy); + moduleStringAppend(" \\in "); + printTypesOfIdentifierList(copy); + moduleStringAppend(": "); + if (typeRestrictor.isARemovedNode(node.getPredicates())) { + moduleStringAppend("TRUE"); + } else { + node.getPredicates().apply(this); + } + moduleStringAppend("}"); + + } else { + moduleStringAppend("{"); + printAuxiliaryVariables(copy.size()); + moduleStringAppend(": t_ \\in "); + moduleStringAppend("{"); + printIdentifierList(copy); + moduleStringAppend(" \\in "); + for (int i = 0; i < copy.size(); i++) { + moduleStringAppend("("); + typeRestrictor.getRestrictedNode(copy.get(i)).apply(this); + moduleStringAppend(")"); + if (i < copy.size() - 1) + moduleStringAppend(" \\times "); + } + moduleStringAppend(": "); + if (typeRestrictor.isARemovedNode(node.getPredicates())) { + moduleStringAppend("TRUE"); + } else { + node.getPredicates().apply(this); + } + moduleStringAppend("}"); + moduleStringAppend("}"); + } + + outAComprehensionSetExpression(node); + } + + @Override + public void caseAEventBComprehensionSetExpression( + AEventBComprehensionSetExpression node) { + inAEventBComprehensionSetExpression(node); + + moduleStringAppend("{"); + node.getExpression().apply(this); + moduleStringAppend(": "); + node.getPredicates().apply(this); + moduleStringAppend("}"); + + outAEventBComprehensionSetExpression(node); + } + + private void printAuxiliaryVariables(int size) { + for (int i = 0; i < size - 1; i++) { + moduleStringAppend("<<"); + } + for (int i = 0; i < size; i++) { + if (i != 0) { + moduleStringAppend(", "); + } + moduleStringAppend("t_[" + (i + 1) + "]"); + if (i != 0) { + moduleStringAppend(">>"); + } + } + } + + @Override + public void caseAUnionExpression(AUnionExpression node) { + inAUnionExpression(node); + node.getLeft().apply(this); + moduleStringAppend(" \\cup "); + node.getRight().apply(this); + outAUnionExpression(node); + } + + @Override + public void caseAIntersectionExpression(AIntersectionExpression node) { + inAIntersectionExpression(node); + node.getLeft().apply(this); + moduleStringAppend(" \\cap "); + node.getRight().apply(this); + outAIntersectionExpression(node); + } + + @Override + public void caseASetSubtractionExpression(ASetSubtractionExpression node) { + inASetSubtractionExpression(node); + node.getLeft().apply(this); + moduleStringAppend(" \\ "); + node.getRight().apply(this); + outASetSubtractionExpression(node); + } + + @Override + public void caseAPowSubsetExpression(APowSubsetExpression node) { + inAPowSubsetExpression(node); + moduleStringAppend("SUBSET("); + node.getExpression().apply(this); + moduleStringAppend(")"); + outAPowSubsetExpression(node); + } + + @Override + public void caseAPow1SubsetExpression(APow1SubsetExpression node) { + moduleStringAppend(POW_1); + moduleStringAppend("("); + node.getExpression().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseAFinSubsetExpression(AFinSubsetExpression node) { + moduleStringAppend(FINITE_SUBSETS); + moduleStringAppend("("); + node.getExpression().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseAFin1SubsetExpression(AFin1SubsetExpression node) { + moduleStringAppend(FINITE_1_SUBSETS); + moduleStringAppend("("); + node.getExpression().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseACardExpression(ACardExpression node) { + BType type = typechecker.getType(node.getExpression()); + if (type instanceof FunctionType) { + moduleStringAppend("Cardinality(DOMAIN("); + node.getExpression().apply(this); + moduleStringAppend("))"); + } else { + moduleStringAppend("Cardinality("); + node.getExpression().apply(this); + moduleStringAppend(")"); + } + } + + @Override + public void caseASubsetPredicate(ASubsetPredicate node) { + inASubsetPredicate(node); + node.getLeft().apply(this); + // moduleStringAppend(" \\in SUBSET("); + moduleStringAppend(" \\subseteq "); + node.getRight().apply(this); + // moduleStringAppend(")"); + outASubsetPredicate(node); + } + + @Override + public void caseASubsetStrictPredicate(ASubsetStrictPredicate node) { + inASubsetStrictPredicate(node); + node.getLeft().apply(this); + moduleStringAppend(" \\in (SUBSET("); + node.getRight().apply(this); + moduleStringAppend(") \\ {"); + node.getRight().apply(this); + moduleStringAppend("})"); + outASubsetStrictPredicate(node); + } + + @Override + public void caseANotSubsetPredicate(ANotSubsetPredicate node) { + moduleStringAppend(NOT_SUBSET); + moduleStringAppend("("); + node.getLeft().apply(this); + moduleStringAppend(", "); + node.getRight().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseANotSubsetStrictPredicate(ANotSubsetStrictPredicate node) { + moduleStringAppend(NOT_STRICT_SUBSET); + moduleStringAppend("("); + node.getLeft().apply(this); + moduleStringAppend(", "); + node.getRight().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseAGeneralUnionExpression(AGeneralUnionExpression node) { + inAGeneralUnionExpression(node); + moduleStringAppend("UNION("); + node.getExpression().apply(this); + moduleStringAppend(")"); + outAGeneralUnionExpression(node); + } + + @Override + public void caseAGeneralIntersectionExpression( + AGeneralIntersectionExpression node) { + inAGeneralIntersectionExpression(node); + moduleStringAppend("Inter("); + node.getExpression().apply(this); + moduleStringAppend(")"); + outAGeneralIntersectionExpression(node); + } + + @Override + public void caseAQuantifiedUnionExpression(AQuantifiedUnionExpression node) { + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + + moduleStringAppend("UNION({"); + node.getExpression().apply(this); + moduleStringAppend(": "); + printIdentifierList(copy); + if (typeRestrictor.isARemovedNode(node.getPredicates())) { + moduleStringAppend(" \\in "); + printTypesOfIdentifierList(copy); + moduleStringAppend("})"); + return; + } else { + moduleStringAppend(" \\in {"); + printIdentifierList(copy); + moduleStringAppend(" \\in "); + printTypesOfIdentifierList(copy); + moduleStringAppend(": "); + node.getPredicates().apply(this); + moduleStringAppend("}"); + moduleStringAppend("})"); + } + + } + + @Override + public void caseAQuantifiedIntersectionExpression( + AQuantifiedIntersectionExpression node) { + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + + moduleStringAppend("Inter({"); + node.getExpression().apply(this); + moduleStringAppend(": "); + printIdentifierList(copy); + if (typeRestrictor.isARemovedNode(node.getPredicates())) { + moduleStringAppend(" \\in "); + printTypesOfIdentifierList(copy); + moduleStringAppend("})"); + return; + } else { + moduleStringAppend(" \\in {"); + printIdentifierList(copy); + moduleStringAppend(" \\in "); + printTypesOfIdentifierList(copy); + moduleStringAppend(": "); + node.getPredicates().apply(this); + moduleStringAppend("}"); + moduleStringAppend("})"); + } + } + + /** + * Relations + */ + + @Override + public void caseACoupleExpression(ACoupleExpression node) { + inACoupleExpression(node); + List<PExpression> copy = new ArrayList<PExpression>(node.getList()); + for (int i = 0; i < copy.size() - 1; i++) { + moduleStringAppend("<<"); + } + for (int i = 0; i < copy.size(); i++) { + if (i != 0) { + moduleStringAppend(", "); + } + copy.get(i).apply(this); + if (i != 0) { + moduleStringAppend(">>"); + } + } + outACoupleExpression(node); + } + + @Override + public void caseARelationsExpression(ARelationsExpression node) { + moduleStringAppend(RELATIONS + "("); + node.getLeft().apply(this); + moduleStringAppend(", "); + node.getRight().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseADomainExpression(ADomainExpression node) { + inADomainExpression(node); + if (typechecker.getType(node.getExpression()) instanceof FunctionType) { + moduleStringAppend("DOMAIN "); + node.getExpression().apply(this); + } else { + moduleStringAppend(REL_DOMAIN + "("); + node.getExpression().apply(this); + moduleStringAppend(")"); + } + outADomainExpression(node); + } + + @Override + public void caseAIdentityExpression(AIdentityExpression node) { + inAIdentityExpression(node); + if (typechecker.getType(node) instanceof FunctionType) { + moduleStringAppend(FUNC_ID); + } else { + moduleStringAppend(REL_ID); + } + moduleStringAppend("("); + node.getExpression().apply(this); + moduleStringAppend(")"); + outAIdentityExpression(node); + } + + @Override + public void caseADomainRestrictionExpression( + ADomainRestrictionExpression node) { + if (typechecker.getType(node) instanceof FunctionType) { + moduleStringAppend(FUNC_DOMAIN_RESTRICTION); + } else { + moduleStringAppend(REL_DOMAIN_RESTRICTION); + } + moduleStringAppend("("); + node.getLeft().apply(this); + moduleStringAppend(", "); + node.getRight().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseADomainSubtractionExpression( + ADomainSubtractionExpression node) { + if (typechecker.getType(node) instanceof FunctionType) { + moduleStringAppend(FUNC_DOMAIN_SUBSTRACTION); + } else { + moduleStringAppend(REL_DOMAIN_SUBSTRACTION); + } + moduleStringAppend("("); + node.getLeft().apply(this); + moduleStringAppend(", "); + node.getRight().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseARangeRestrictionExpression(ARangeRestrictionExpression node) { + if (typechecker.getType(node) instanceof FunctionType) { + moduleStringAppend(FUNC_RANGE_RESTRICTION); + } else { + moduleStringAppend(REL_RANGE_RESTRICTION); + } + moduleStringAppend("("); + node.getLeft().apply(this); + moduleStringAppend(", "); + node.getRight().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseARangeSubtractionExpression(ARangeSubtractionExpression node) { + if (typechecker.getType(node) instanceof FunctionType) { + moduleStringAppend(FUNC_RANGE_SUBSTRACTION); + } else { + moduleStringAppend(REL_RANGE_SUBSTRACTION); + } + moduleStringAppend("("); + node.getLeft().apply(this); + moduleStringAppend(", "); + node.getRight().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseAReverseExpression(AReverseExpression node) { + if (typechecker.getType(node.getExpression()) instanceof FunctionType) { + moduleStringAppend(FUNC_INVERSE); + } else { + moduleStringAppend(REL_INVERSE); + } + moduleStringAppend("("); + node.getExpression().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseAOverwriteExpression(AOverwriteExpression node) { + if (typechecker.getType(node) instanceof FunctionType) { + moduleStringAppend(FUNC_OVERRIDE); + } else { + moduleStringAppend(REL_OVERRIDING); + } + moduleStringAppend("("); + node.getLeft().apply(this); + moduleStringAppend(", "); + node.getRight().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseADirectProductExpression(ADirectProductExpression node) { + moduleStringAppend(REL_DIRECT_PRODUCT); + moduleStringAppend("("); + node.getLeft().apply(this); + moduleStringAppend(", "); + node.getRight().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseAParallelProductExpression(AParallelProductExpression node) { + moduleStringAppend(REL_PARALLEL_PRODUCT); + moduleStringAppend("("); + node.getLeft().apply(this); + moduleStringAppend(", "); + node.getRight().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseACompositionExpression(ACompositionExpression node) { + moduleStringAppend(REL_COMPOSITION); + moduleStringAppend("("); + node.getLeft().apply(this); + moduleStringAppend(", "); + node.getRight().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseAFirstProjectionExpression(AFirstProjectionExpression node) { + moduleStringAppend(REL_PROJECTION_FUNCTION_FIRST); + moduleStringAppend("("); + node.getExp1().apply(this); + moduleStringAppend(", "); + node.getExp2().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseASecondProjectionExpression(ASecondProjectionExpression node) { + moduleStringAppend(REL_PROJECTION_FUNCTION_SECOND); + moduleStringAppend("("); + node.getExp1().apply(this); + moduleStringAppend(", "); + node.getExp2().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseAIterationExpression(AIterationExpression node) { + moduleStringAppend(REL_ITERATE); + moduleStringAppend("("); + node.getLeft().apply(this); + moduleStringAppend(", "); + node.getRight().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseAClosureExpression(AClosureExpression node) { + moduleStringAppend(REL_CLOSURE1); + moduleStringAppend("("); + node.getExpression().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseAReflexiveClosureExpression(AReflexiveClosureExpression node) { + moduleStringAppend(REL_CLOSURE); + moduleStringAppend("("); + node.getExpression().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseATransFunctionExpression(ATransFunctionExpression node) { + moduleStringAppend(REL_FNC); + moduleStringAppend("("); + node.getExpression().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseATransRelationExpression(ATransRelationExpression node) { + moduleStringAppend(REL_REL); + moduleStringAppend("("); + node.getExpression().apply(this); + moduleStringAppend(")"); + } + + /** + * Sequences + */ + + @Override + public void caseASequenceExtensionExpression( + ASequenceExtensionExpression node) { + List<PExpression> copy = new ArrayList<PExpression>( + node.getExpression()); + BType type = typechecker.getType(node); + if (type instanceof FunctionType) { + moduleStringAppend("<<"); + + for (int i = 0; i < copy.size(); i++) { + copy.get(i).apply(this); + if (i < copy.size() - 1) + moduleStringAppend(", "); + } + moduleStringAppend(">>"); + } else { + moduleStringAppend("{"); + for (int i = 0; i < copy.size(); i++) { + moduleStringAppend("<<"); + moduleStringAppend(String.valueOf(i + 1)); + moduleStringAppend(", "); + copy.get(i).apply(this); + moduleStringAppend(">>"); + if (i < copy.size() - 1) + moduleStringAppend(", "); + } + moduleStringAppend("}"); + } + } + + private void evalFunctionOrRelation(Node node, String function, + String relation) { + BType type = typechecker.getType(node); + if (type instanceof FunctionType) { + moduleStringAppend(function); + } else { + moduleStringAppend(relation); + } + } + + @Override + public void caseAEmptySequenceExpression(AEmptySequenceExpression node) { + evalFunctionOrRelation(node, "<<>>", "{}"); + } + + @Override + public void caseASeqExpression(ASeqExpression node) { + SetType set = (SetType) typechecker.getType(node); + if (set.getSubtype() instanceof SetType) { + moduleStringAppend(REL_SET_OF_SEQUENCES); + } else { + moduleStringAppend("Seq"); + } + moduleStringAppend("("); + node.getExpression().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseASizeExpression(ASizeExpression node) { + printSequenceOrRelation(node.getExpression(), "Len", REL_SEQUENCE_SIZE, + node.getExpression(), null); + } + + @Override + public void caseAConcatExpression(AConcatExpression node) { + BType type = typechecker.getType(node); + if (type instanceof SetType) { + moduleStringAppend(REL_SEQUENCE_Concat); + moduleStringAppend("("); + node.getLeft().apply(this); + moduleStringAppend(", "); + node.getRight().apply(this); + moduleStringAppend(")"); + } else { + inAConcatExpression(node); + node.getLeft().apply(this); + moduleStringAppend(" \\o "); + node.getRight().apply(this); + outAConcatExpression(node); + } + } + + @Override + public void caseAInsertTailExpression(AInsertTailExpression node) { + printSequenceOrRelation(node, "Append", REL_SEQUENCE_APPEND, + node.getLeft(), node.getRight()); + } + + private void printSequenceOrRelation(Node node, String sequence, + String relation, Node left, Node right) { + BType type = typechecker.getType(node); + if (type instanceof SetType) { + moduleStringAppend(relation); + } else { + moduleStringAppend(sequence); + } + moduleStringAppend("("); + left.apply(this); + + if (right != null) { + moduleStringAppend(","); + right.apply(this); + } + moduleStringAppend(")"); + } + + @Override + public void caseAFirstExpression(AFirstExpression node) { + printSequenceOrRelation(node.getExpression(), "Head", + REL_SEQUENCE_FIRST_ELEMENT, node.getExpression(), null); + } + + @Override + public void caseATailExpression(ATailExpression node) { + printSequenceOrRelation(node.getExpression(), "Tail", + REL_SEQUENCE_TAIL, node.getExpression(), null); + } + + /** + * SequencesExtended + */ + + @Override + public void caseAIseqExpression(AIseqExpression node) { + SetType set = (SetType) typechecker.getType(node); + if (set.getSubtype() instanceof SetType) { + + if (recursiveIsElementOfTest(node.parent()) + && !typeRestrictor.isARemovedNode(node.parent())) { + moduleStringAppend(REL_INJECTIVE_SEQUENCE_ELEMENT_OF); + } else { + moduleStringAppend(REL_INJECTIVE_SEQUENCE); + } + } else { + if (node.parent() instanceof AMemberPredicate + && !typeRestrictor.isARemovedNode(node.parent())) { + moduleStringAppend(INJECTIVE_SEQUENCE_ELEMENT_OF); + } else { + moduleStringAppend(INJECTIVE_SEQUENCE); + } + } + moduleStringAppend("("); + node.getExpression().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseAIseq1Expression(AIseq1Expression node) { + SetType set = (SetType) typechecker.getType(node); + if (set.getSubtype() instanceof SetType) { + if (recursiveIsElementOfTest(node)) { + moduleStringAppend(REL_INJECTIVE_SEQUENCE_1_ELEMENT_OF); + } else { + moduleStringAppend(REL_INJECTIVE_SEQUENCE_1); + } + } else { + if (recursiveIsElementOfTest(node)) { + moduleStringAppend(INJECTIVE_SEQUENCE_1_ELEMENT_OF); + } else { + moduleStringAppend(INJECTIVE_SEQUENCE_1); + } + } + moduleStringAppend("("); + node.getExpression().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseASeq1Expression(ASeq1Expression node) { + SetType set = (SetType) typechecker.getType(node); + if (set.getSubtype() instanceof SetType) { + moduleStringAppend(REL_SET_OF_NON_EMPTY_SEQUENCES); + } else { + moduleStringAppend(SEQUENCE_1); + } + moduleStringAppend("("); + node.getExpression().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseALastExpression(ALastExpression node) { + printSequenceOrRelation(node.getExpression(), SEQUENCE_LAST_ELEMENT, + REL_SEQUENCE_LAST_ELEMENT, node.getExpression(), null); + } + + @Override + public void caseAInsertFrontExpression(AInsertFrontExpression node) { + printSequenceOrRelation(node.getRight(), SEQUENCE_PREPEND_ELEMENT, + REL_SEQUENCE_PREPAND, node.getLeft(), node.getRight()); + } + + @Override + public void caseAPermExpression(APermExpression node) { + SetType set = (SetType) typechecker.getType(node); + if (set.getSubtype() instanceof SetType) { + moduleStringAppend(REL_SEQUENCE_PERM); + } else { + moduleStringAppend(SEQUENCE_PERMUTATION); + } + moduleStringAppend("("); + node.getExpression().apply(this); + moduleStringAppend(")"); + } + + @Override + public void caseARevExpression(ARevExpression node) { + printSequenceOrRelation(node, SEQUENCE_REVERSE, REL_SEQUENCE_REVERSE, + node.getExpression(), null); + } + + @Override + public void caseAFrontExpression(AFrontExpression node) { + printSequenceOrRelation(node.getExpression(), SEQUENCE_FRONT, + REL_SEQUENCE_FRONT, node.getExpression(), null); + } + + @Override + public void caseAGeneralConcatExpression(AGeneralConcatExpression node) { + BType result = typechecker.getType(node.getExpression()); + + if (result instanceof FunctionType + && ((FunctionType) result).getRange() instanceof FunctionType) { + + } else { + BType expected2 = new SetType(new PairType( + IntegerType.getInstance(), new SetType(new PairType( + IntegerType.getInstance(), new UntypedType())))); + typechecker.unify(expected2, result, node); + } + + printSequenceOrRelation(node, SEQUENCE_GENERAL_CONCATINATION, + REL_SEQUENCE_GENERAL_CONCATINATION, node.getExpression(), null); + } + + @Override + public void caseARestrictFrontExpression(ARestrictFrontExpression node) { + printSequenceOrRelation(node, SEQUENCE_TAKE_FIRST_ELEMENTS, + REL_SEQUENCE_TAKE_FIRST_ELEMENTS, node.getLeft(), + node.getRight()); + } + + @Override + public void caseARestrictTailExpression(ARestrictTailExpression node) { + printSequenceOrRelation(node, SEQUENCE_DROP_FIRST_ELEMENTS, + REL_SEQUENCE_DROP_FIRST_ELEMENTS, node.getLeft(), + node.getRight()); + } + + /** + * Special Operator + */ + @Override + public void caseAMinusOrSetSubtractExpression( + AMinusOrSetSubtractExpression node) { + inAMinusOrSetSubtractExpression(node); + node.getLeft().apply(this); + + BType leftType = this.typechecker.getType(node.getLeft()); + if (leftType instanceof IntegerType) { + moduleStringAppend(" - "); + } else { + moduleStringAppend(" \\ "); + } + + node.getRight().apply(this); + outAMinusOrSetSubtractExpression(node); + } + + @Override + public void caseAMultOrCartExpression(AMultOrCartExpression node) { + inAMultOrCartExpression(node); + node.getLeft().apply(this); + + BType leftType = this.typechecker.getType(node.getLeft()); + if (leftType instanceof IntegerType) { + moduleStringAppend(" * "); + } else { + moduleStringAppend(" \\times "); + } + + node.getRight().apply(this); + outAMultOrCartExpression(node); + } + + @Override + public void caseACartesianProductExpression(ACartesianProductExpression node) { + inACartesianProductExpression(node); // TODO cartesianproduct vs + // AMultOrCartExpression + node.getLeft().apply(this); + moduleStringAppend(" \\times "); + node.getRight().apply(this); + outACartesianProductExpression(node); + } + + @Override + public void caseAConvertBoolExpression(AConvertBoolExpression node) { + inAConvertBoolExpression(node); + moduleStringAppend("("); + if (node.getPredicate() != null) { + node.getPredicate().apply(this); + } + moduleStringAppend(")"); + outAConvertBoolExpression(node); + } + + // Records + + @Override + public void caseARecExpression(ARecExpression node) { + moduleStringAppend("["); + List<PRecEntry> copy = new ArrayList<PRecEntry>(node.getEntries()); + for (int i = 0; i < copy.size(); i++) { + copy.get(i).apply(this); + if (i < copy.size() - 1) { + moduleStringAppend(", "); + } + } + moduleStringAppend("]"); + } + + @Override + public void caseARecEntry(ARecEntry node) { + node.getIdentifier().apply(this); + if (typechecker.getType(node.parent()) instanceof StructType) { + moduleStringAppend(" |-> "); + } else { + moduleStringAppend(" : "); + } + + node.getValue().apply(this); + } + + @Override + public void caseARecordFieldExpression(ARecordFieldExpression node) { + inARecordFieldExpression(node); + node.getRecord().apply(this); + moduleStringAppend("."); + node.getIdentifier().apply(this); + outARecordFieldExpression(node); + } + + @Override + public void caseAStructExpression(AStructExpression node) { + moduleStringAppend("["); + List<PRecEntry> copy = new ArrayList<PRecEntry>(node.getEntries()); + for (int i = 0; i < copy.size(); i++) { + copy.get(i).apply(this); + if (i < copy.size() - 1) { + moduleStringAppend(", "); + } + } + moduleStringAppend("]"); + } + + public String geTranslatedLTLFormula() { + return this.translatedLTLFormula.toString(); + } + + public TLAModule getTLAModule() { + return this.tlaModule; + } +} diff --git a/src/main/java/de/tlc4b/tla/ConfigFile.java b/src/main/java/de/tlc4b/tla/ConfigFile.java index 5288a676f98e41f3b2cc4bc65a8f28c628653f30..3f2ca06eb0eeafb17d8720bc39b2972664905f9e 100644 --- a/src/main/java/de/tlc4b/tla/ConfigFile.java +++ b/src/main/java/de/tlc4b/tla/ConfigFile.java @@ -1,88 +1,88 @@ -package de.tlc4b.tla; - -import java.util.ArrayList; - -import de.tlc4b.tla.config.ConfigFileAssignment; - - -public class ConfigFile { - - private final ArrayList<ConfigFileAssignment> assignments; - private int invariantNumber; - private boolean spec; - private boolean init; - private boolean next; - private int assertionsSize; - private boolean goal; - - - public ConfigFile(){ - this.assignments = new ArrayList<ConfigFileAssignment>(); - this.invariantNumber = 0; - } - - - public ArrayList<ConfigFileAssignment> getAssignments() { - return assignments; - } - - public boolean isSpec(){ - return spec; - } - - - public void setInvariantNumber(int number) { - this.invariantNumber = number; - } - - - public boolean isInit() { - return init; - } - - - public boolean isNext() { - return next; - } - - public void addAssignment(ConfigFileAssignment assignment){ - assignments.add(assignment); - } - - - public int getInvariantNumber() { - return this.invariantNumber; - } - - - public void setInit() { - this.init = true; - } - - - public void setNext() { - this.next = true; - } - - - public void setAssertionSize(int size) { - assertionsSize = size; - } - - public int getAssertionSize(){ - return assertionsSize; - } - - public void setSpec(){ - this.spec = true; - } - - public void setGoal(){ - this.goal = true; - } - - public boolean isGoal(){ - return this.goal; - } - -} +package de.tlc4b.tla; + +import java.util.ArrayList; + +import de.tlc4b.tla.config.ConfigFileAssignment; + + +public class ConfigFile { + + private final ArrayList<ConfigFileAssignment> assignments; + private int invariantNumber; + private boolean spec; + private boolean init; + private boolean next; + private int assertionsSize; + private boolean goal; + + + public ConfigFile(){ + this.assignments = new ArrayList<ConfigFileAssignment>(); + this.invariantNumber = 0; + } + + + public ArrayList<ConfigFileAssignment> getAssignments() { + return assignments; + } + + public boolean isSpec(){ + return spec; + } + + + public void setInvariantNumber(int number) { + this.invariantNumber = number; + } + + + public boolean isInit() { + return init; + } + + + public boolean isNext() { + return next; + } + + public void addAssignment(ConfigFileAssignment assignment){ + assignments.add(assignment); + } + + + public int getInvariantNumber() { + return this.invariantNumber; + } + + + public void setInit() { + this.init = true; + } + + + public void setNext() { + this.next = true; + } + + + public void setAssertionSize(int size) { + assertionsSize = size; + } + + public int getAssertionSize(){ + return assertionsSize; + } + + public void setSpec(){ + this.spec = true; + } + + public void setGoal(){ + this.goal = true; + } + + public boolean isGoal(){ + return this.goal; + } + +} diff --git a/src/main/java/de/tlc4b/tla/Generator.java b/src/main/java/de/tlc4b/tla/Generator.java index dbef5ec399014c2883028b4f6794af486217378c..79d2e2fc56c6cd8639116383de57a4873de9155c 100644 --- a/src/main/java/de/tlc4b/tla/Generator.java +++ b/src/main/java/de/tlc4b/tla/Generator.java @@ -1,369 +1,369 @@ -package de.tlc4b.tla; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Iterator; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map.Entry; - -import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; -import de.be4.classicalb.core.parser.node.AAssertionsMachineClause; -import de.be4.classicalb.core.parser.node.AConcreteVariablesMachineClause; -import de.be4.classicalb.core.parser.node.AConstraintsMachineClause; -import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause; -import de.be4.classicalb.core.parser.node.AEnumeratedSetSet; -import de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition; -import de.be4.classicalb.core.parser.node.AIdentifierExpression; -import de.be4.classicalb.core.parser.node.AInitialisationMachineClause; -import de.be4.classicalb.core.parser.node.AInvariantMachineClause; -import de.be4.classicalb.core.parser.node.AMemberPredicate; -import de.be4.classicalb.core.parser.node.AOperationsMachineClause; -import de.be4.classicalb.core.parser.node.APropertiesMachineClause; -import de.be4.classicalb.core.parser.node.ASetExtensionExpression; -import de.be4.classicalb.core.parser.node.AVariablesMachineClause; -import de.be4.classicalb.core.parser.node.Node; -import de.be4.classicalb.core.parser.node.PDefinition; -import de.be4.classicalb.core.parser.node.PExpression; -import de.be4.classicalb.core.parser.node.POperation; -import de.be4.classicalb.core.parser.node.PPredicate; -import de.tlc4b.TLC4BGlobals; -import de.tlc4b.analysis.ConstantsEvaluator; -import de.tlc4b.analysis.DefinitionsAnalyser; -import de.tlc4b.analysis.DefinitionsSorter; -import de.tlc4b.analysis.MachineContext; -import de.tlc4b.analysis.Typechecker; -import de.tlc4b.analysis.typerestriction.TypeRestrictor; -import de.tlc4b.tla.config.ModelValueAssignment; -import de.tlc4b.tla.config.SetOfModelValuesAssignment; - -public class Generator extends DepthFirstAdapter { - - private MachineContext machineContext; - private TypeRestrictor typeRestrictor; - private ConstantsEvaluator constantsEvaluator; - private DefinitionsAnalyser deferredSetSizeCalculator; - - private TLAModule tlaModule; - private ConfigFile configFile; - - public Generator(MachineContext machineContext, - TypeRestrictor typeRestrictor, - ConstantsEvaluator constantsEvaluator, - DefinitionsAnalyser deferredSetSizeCalculator, - Typechecker typechecker) { - this.machineContext = machineContext; - this.typeRestrictor = typeRestrictor; - this.constantsEvaluator = constantsEvaluator; - this.deferredSetSizeCalculator = deferredSetSizeCalculator; - - this.tlaModule = new TLAModule(); - this.configFile = new ConfigFile(); - - } - - public void generate() { - tlaModule.moduleName = machineContext.getMachineName(); - evalSetValuedParameter(); - evalScalarParameter(); - evalMachineSets(); - evalDefinitions(); - evalConstants(); - - evalInvariant(); - evalOperations(); - evalGoal(); - machineContext.getStartNode().apply(this); - - evalSpec(); - } - - private void evalInvariant() { - AInvariantMachineClause invariantClause = machineContext - .getInvariantMachineClause(); - if (invariantClause != null) { - this.tlaModule.invariants.addAll(constantsEvaluator - .getInvariantList()); - this.configFile.setInvariantNumber(tlaModule.invariants.size()); - } - } - - private void evalSpec() { - if (this.configFile.isInit() && this.configFile.isNext() - && TLC4BGlobals.isCheckLTL() - && machineContext.getLTLFormulas().size() > 0) { - this.configFile.setSpec(); - } - } - - private void evalGoal() { - if (TLC4BGlobals.isGOAL()) { - if (machineContext.getDefinitions().keySet().contains("GOAL")) { - this.configFile.setGoal(); - } - } - } - - private void evalSetValuedParameter() { - /** - * For each set-valued parameter (first letter in upper case) we create - * a TLA definition e.g. MACHINE Test(P) -> P == {P_1, P_2} - */ - Iterator<String> itr = machineContext.getSetParamter().keySet() - .iterator(); - while (itr.hasNext()) { - String parameter = itr.next(); - Node node = machineContext.getSetParamter().get(parameter); - tlaModule.constants.add(node); - configFile.addAssignment(new SetOfModelValuesAssignment(node, 3)); - } - - } - - private void evalScalarParameter() { - /** - * For each scalar-valued parameter we have to find out if it has a - * determined value in the CONSTRAINT clause (e.g. p = 1). In this case - * we create a TLA constant, in the other case we create a TLA variable - * and add the constraint predicate to the init clause - */ - - Collection<Node> params = machineContext.getScalarParameter().values(); - if (params.size() == 0) - return; - - LinkedHashMap<Node, Node> idValueTable = constantsEvaluator - .getValueOfIdentifierMap(); - - Iterator<Node> itr = params.iterator(); - boolean init = false; - while (itr.hasNext()) { - Node param = itr.next(); - - Node value = idValueTable.get(param); - if (value != null) { - tlaModule.addTLADefinition(new TLADefinition(param, value)); - continue; - } - Integer intValue = constantsEvaluator.getIntValue(param); - if (intValue != null) { - tlaModule.addTLADefinition(new TLADefinition(param, intValue)); - continue; - } - - Node restrictedNode = typeRestrictor.getRestrictedNode(param); - AMemberPredicate memberPredicate = new AMemberPredicate( - (PExpression) param, (PExpression) restrictedNode); - tlaModule.addInit(memberPredicate); - - init = true; - this.tlaModule.variables.add(param); - } - - AConstraintsMachineClause clause = machineContext - .getConstraintMachineClause(); - if (init) { - configFile.setInit(); - if (!typeRestrictor.isARemovedNode(clause.getPredicates())) { - tlaModule.addInit(clause.getPredicates()); - } - - } else { - if (!typeRestrictor.isARemovedNode(clause.getPredicates())) - tlaModule.addAssume(clause.getPredicates()); - } - } - - private void evalMachineSets() { - /* - * Deffered Sets - */ - LinkedHashMap<String, Node> map = machineContext.getDeferredSets(); - Iterator<Node> itr = map.values().iterator(); - while (itr.hasNext()) { - Node d = itr.next(); - tlaModule.constants.add(d); - Integer size; - size = deferredSetSizeCalculator.getSize(d); - if (size == null) { - size = constantsEvaluator.getIntValue(d); - } - - this.configFile.addAssignment(new SetOfModelValuesAssignment(d, - size)); - } - - /* - * Enumerated Sets - */ - - LinkedHashMap<String, Node> map2 = machineContext.getEnumeratedSets(); - Iterator<Node> itr2 = map2.values().iterator(); - while (itr2.hasNext()) { - Node n = itr2.next(); - AEnumeratedSetSet e = (AEnumeratedSetSet) n; - TLADefinition def = new TLADefinition(e, e); - this.tlaModule.addTLADefinition(def); - List<PExpression> copy = new ArrayList<PExpression>(e.getElements()); - for (PExpression element : copy) { - this.tlaModule.constants.add(element); - this.configFile - .addAssignment(new ModelValueAssignment(element)); - } - } - } - - private void evalDefinitions() { - ADefinitionsMachineClause node = machineContext - .getDefinitionMachineClause(); - if (node != null) { - ArrayList<PDefinition> bDefinitions = new ArrayList<PDefinition>( - node.getDefinitions()); - DefinitionsSorter defOrder = new DefinitionsSorter(machineContext, - bDefinitions); - this.tlaModule.allDefinitions.addAll(defOrder.getAllDefinitions()); - } - } - - private void evalOperations() { - AOperationsMachineClause node = machineContext - .getOperationMachineClause(); - if (null != node) { - configFile.setNext(); - List<POperation> copy = new ArrayList<POperation>( - node.getOperations()); - for (POperation e : copy) { - this.tlaModule.operations.add(e); - } - } - } - - private void evalConstants() { - if (machineContext.getPropertiesMachineClause() == null) - return; - LinkedHashMap<Node, Node> conValueTable = constantsEvaluator - .getValueOfIdentifierMap(); - Iterator<Entry<Node, Node>> iterator = conValueTable.entrySet() - .iterator(); - while (iterator.hasNext()) { - Entry<Node, Node> entry = iterator.next(); - AIdentifierExpression con = (AIdentifierExpression) entry.getKey(); - Node value = entry.getValue(); - - AExpressionDefinitionDefinition exprDef = new AExpressionDefinitionDefinition( - con.getIdentifier().get(0), new LinkedList<PExpression>(), - (PExpression) value);// .clone()); - machineContext.addReference(exprDef, con); - - this.tlaModule.addToAllDefinitions(exprDef); - } - - ArrayList<Node> remainingConstants = new ArrayList<Node>(); - remainingConstants.addAll(machineContext.getConstants().values()); - remainingConstants.removeAll(conValueTable.keySet()); - - Node propertiesPerdicate = machineContext.getPropertiesMachineClause() - .getPredicates(); - if (remainingConstants.size() > 0) { - boolean init = false; - int numberOfIteratedConstants = 0; - - for (int i = 0; i < remainingConstants.size(); i++) { - init = true; - Node con = remainingConstants.get(i); - this.tlaModule.variables.add(con); - - ArrayList<PExpression> rangeList = constantsEvaluator - .getRangeOfIdentifier(con); - if (rangeList.size() > 0) { - numberOfIteratedConstants++; - ArrayList<PExpression> clone = new ArrayList<PExpression>(); - for (PExpression pExpression : rangeList) { - clone.add((PExpression) pExpression.clone()); - } - ASetExtensionExpression set = new ASetExtensionExpression( - clone); - AMemberPredicate member = new AMemberPredicate( - (AIdentifierExpression) con, set); - tlaModule.addInit(member); - continue; - } - - Node restrictedNode = typeRestrictor.getRestrictedNode(con); - AMemberPredicate memberPredicate = new AMemberPredicate( - (PExpression) con, (PExpression) restrictedNode); - tlaModule.addInit(memberPredicate); - - } - - if (numberOfIteratedConstants > 1) { - tlaModule.addInit(machineContext.getConstantsSetup()); - } - - if (init) { - configFile.setInit(); - if (!typeRestrictor.isARemovedNode(propertiesPerdicate)) - tlaModule.addInit(propertiesPerdicate); - } - - } else { - if (machineContext.getConstantsSetup() == null) { - tlaModule.assumes - .addAll(constantsEvaluator.getPropertiesList()); - } - tlaModule.addAssume(propertiesPerdicate); - } - - } - - @Override - public void inAPropertiesMachineClause(APropertiesMachineClause node) { - if (!tlaModule.isInitPredicate(node.getPredicates())) { - // this.tlaModule.addAssume(node.getPredicates()); - } - } - - @Override - public void caseAVariablesMachineClause(AVariablesMachineClause node) { - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - this.tlaModule.variables.add(e); - } - } - - @Override - public void caseAConcreteVariablesMachineClause( - AConcreteVariablesMachineClause node) { - List<PExpression> copy = new ArrayList<PExpression>( - node.getIdentifiers()); - for (PExpression e : copy) { - this.tlaModule.variables.add(e); - } - } - - @Override - public void inAAssertionsMachineClause(AAssertionsMachineClause node) { - List<PPredicate> copy = new ArrayList<PPredicate>(node.getPredicates()); - for (PPredicate e : copy) { - this.tlaModule.addAssertion(e); - } - this.configFile.setAssertionSize(copy.size()); - } - - @Override - public void inAInitialisationMachineClause(AInitialisationMachineClause node) { - this.configFile.setInit(); - this.tlaModule.addInit(node.getSubstitutions()); - } - - public TLAModule getTlaModule() { - return tlaModule; - } - - public ConfigFile getConfigFile() { - return configFile; - } - -} +package de.tlc4b.tla; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map.Entry; + +import de.be4.classicalb.core.parser.analysis.DepthFirstAdapter; +import de.be4.classicalb.core.parser.node.AAssertionsMachineClause; +import de.be4.classicalb.core.parser.node.AConcreteVariablesMachineClause; +import de.be4.classicalb.core.parser.node.AConstraintsMachineClause; +import de.be4.classicalb.core.parser.node.ADefinitionsMachineClause; +import de.be4.classicalb.core.parser.node.AEnumeratedSetSet; +import de.be4.classicalb.core.parser.node.AExpressionDefinitionDefinition; +import de.be4.classicalb.core.parser.node.AIdentifierExpression; +import de.be4.classicalb.core.parser.node.AInitialisationMachineClause; +import de.be4.classicalb.core.parser.node.AInvariantMachineClause; +import de.be4.classicalb.core.parser.node.AMemberPredicate; +import de.be4.classicalb.core.parser.node.AOperationsMachineClause; +import de.be4.classicalb.core.parser.node.APropertiesMachineClause; +import de.be4.classicalb.core.parser.node.ASetExtensionExpression; +import de.be4.classicalb.core.parser.node.AVariablesMachineClause; +import de.be4.classicalb.core.parser.node.Node; +import de.be4.classicalb.core.parser.node.PDefinition; +import de.be4.classicalb.core.parser.node.PExpression; +import de.be4.classicalb.core.parser.node.POperation; +import de.be4.classicalb.core.parser.node.PPredicate; +import de.tlc4b.TLC4BGlobals; +import de.tlc4b.analysis.ConstantsEvaluator; +import de.tlc4b.analysis.DefinitionsAnalyser; +import de.tlc4b.analysis.DefinitionsSorter; +import de.tlc4b.analysis.MachineContext; +import de.tlc4b.analysis.Typechecker; +import de.tlc4b.analysis.typerestriction.TypeRestrictor; +import de.tlc4b.tla.config.ModelValueAssignment; +import de.tlc4b.tla.config.SetOfModelValuesAssignment; + +public class Generator extends DepthFirstAdapter { + + private MachineContext machineContext; + private TypeRestrictor typeRestrictor; + private ConstantsEvaluator constantsEvaluator; + private DefinitionsAnalyser deferredSetSizeCalculator; + + private TLAModule tlaModule; + private ConfigFile configFile; + + public Generator(MachineContext machineContext, + TypeRestrictor typeRestrictor, + ConstantsEvaluator constantsEvaluator, + DefinitionsAnalyser deferredSetSizeCalculator, + Typechecker typechecker) { + this.machineContext = machineContext; + this.typeRestrictor = typeRestrictor; + this.constantsEvaluator = constantsEvaluator; + this.deferredSetSizeCalculator = deferredSetSizeCalculator; + + this.tlaModule = new TLAModule(); + this.configFile = new ConfigFile(); + + } + + public void generate() { + tlaModule.moduleName = machineContext.getMachineName(); + evalSetValuedParameter(); + evalScalarParameter(); + evalMachineSets(); + evalDefinitions(); + evalConstants(); + + evalInvariant(); + evalOperations(); + evalGoal(); + machineContext.getStartNode().apply(this); + + evalSpec(); + } + + private void evalInvariant() { + AInvariantMachineClause invariantClause = machineContext + .getInvariantMachineClause(); + if (invariantClause != null) { + this.tlaModule.invariants.addAll(constantsEvaluator + .getInvariantList()); + this.configFile.setInvariantNumber(tlaModule.invariants.size()); + } + } + + private void evalSpec() { + if (this.configFile.isInit() && this.configFile.isNext() + && TLC4BGlobals.isCheckLTL() + && machineContext.getLTLFormulas().size() > 0) { + this.configFile.setSpec(); + } + } + + private void evalGoal() { + if (TLC4BGlobals.isGOAL()) { + if (machineContext.getDefinitions().keySet().contains("GOAL")) { + this.configFile.setGoal(); + } + } + } + + private void evalSetValuedParameter() { + /** + * For each set-valued parameter (first letter in upper case) we create + * a TLA definition e.g. MACHINE Test(P) -> P == {P_1, P_2} + */ + Iterator<String> itr = machineContext.getSetParamter().keySet() + .iterator(); + while (itr.hasNext()) { + String parameter = itr.next(); + Node node = machineContext.getSetParamter().get(parameter); + tlaModule.constants.add(node); + configFile.addAssignment(new SetOfModelValuesAssignment(node, 3)); + } + + } + + private void evalScalarParameter() { + /** + * For each scalar-valued parameter we have to find out if it has a + * determined value in the CONSTRAINT clause (e.g. p = 1). In this case + * we create a TLA constant, in the other case we create a TLA variable + * and add the constraint predicate to the init clause + */ + + Collection<Node> params = machineContext.getScalarParameter().values(); + if (params.size() == 0) + return; + + LinkedHashMap<Node, Node> idValueTable = constantsEvaluator + .getValueOfIdentifierMap(); + + Iterator<Node> itr = params.iterator(); + boolean init = false; + while (itr.hasNext()) { + Node param = itr.next(); + + Node value = idValueTable.get(param); + if (value != null) { + tlaModule.addTLADefinition(new TLADefinition(param, value)); + continue; + } + Integer intValue = constantsEvaluator.getIntValue(param); + if (intValue != null) { + tlaModule.addTLADefinition(new TLADefinition(param, intValue)); + continue; + } + + Node restrictedNode = typeRestrictor.getRestrictedNode(param); + AMemberPredicate memberPredicate = new AMemberPredicate( + (PExpression) param, (PExpression) restrictedNode); + tlaModule.addInit(memberPredicate); + + init = true; + this.tlaModule.variables.add(param); + } + + AConstraintsMachineClause clause = machineContext + .getConstraintMachineClause(); + if (init) { + configFile.setInit(); + if (!typeRestrictor.isARemovedNode(clause.getPredicates())) { + tlaModule.addInit(clause.getPredicates()); + } + + } else { + if (!typeRestrictor.isARemovedNode(clause.getPredicates())) + tlaModule.addAssume(clause.getPredicates()); + } + } + + private void evalMachineSets() { + /* + * Deffered Sets + */ + LinkedHashMap<String, Node> map = machineContext.getDeferredSets(); + Iterator<Node> itr = map.values().iterator(); + while (itr.hasNext()) { + Node d = itr.next(); + tlaModule.constants.add(d); + Integer size; + size = deferredSetSizeCalculator.getSize(d); + if (size == null) { + size = constantsEvaluator.getIntValue(d); + } + + this.configFile.addAssignment(new SetOfModelValuesAssignment(d, + size)); + } + + /* + * Enumerated Sets + */ + + LinkedHashMap<String, Node> map2 = machineContext.getEnumeratedSets(); + Iterator<Node> itr2 = map2.values().iterator(); + while (itr2.hasNext()) { + Node n = itr2.next(); + AEnumeratedSetSet e = (AEnumeratedSetSet) n; + TLADefinition def = new TLADefinition(e, e); + this.tlaModule.addTLADefinition(def); + List<PExpression> copy = new ArrayList<PExpression>(e.getElements()); + for (PExpression element : copy) { + this.tlaModule.constants.add(element); + this.configFile + .addAssignment(new ModelValueAssignment(element)); + } + } + } + + private void evalDefinitions() { + ADefinitionsMachineClause node = machineContext + .getDefinitionMachineClause(); + if (node != null) { + ArrayList<PDefinition> bDefinitions = new ArrayList<PDefinition>( + node.getDefinitions()); + DefinitionsSorter defOrder = new DefinitionsSorter(machineContext, + bDefinitions); + this.tlaModule.allDefinitions.addAll(defOrder.getAllDefinitions()); + } + } + + private void evalOperations() { + AOperationsMachineClause node = machineContext + .getOperationMachineClause(); + if (null != node) { + configFile.setNext(); + List<POperation> copy = new ArrayList<POperation>( + node.getOperations()); + for (POperation e : copy) { + this.tlaModule.operations.add(e); + } + } + } + + private void evalConstants() { + if (machineContext.getPropertiesMachineClause() == null) + return; + LinkedHashMap<Node, Node> conValueTable = constantsEvaluator + .getValueOfIdentifierMap(); + Iterator<Entry<Node, Node>> iterator = conValueTable.entrySet() + .iterator(); + while (iterator.hasNext()) { + Entry<Node, Node> entry = iterator.next(); + AIdentifierExpression con = (AIdentifierExpression) entry.getKey(); + Node value = entry.getValue(); + + AExpressionDefinitionDefinition exprDef = new AExpressionDefinitionDefinition( + con.getIdentifier().get(0), new LinkedList<PExpression>(), + (PExpression) value);// .clone()); + machineContext.addReference(exprDef, con); + + this.tlaModule.addToAllDefinitions(exprDef); + } + + ArrayList<Node> remainingConstants = new ArrayList<Node>(); + remainingConstants.addAll(machineContext.getConstants().values()); + remainingConstants.removeAll(conValueTable.keySet()); + + Node propertiesPerdicate = machineContext.getPropertiesMachineClause() + .getPredicates(); + if (remainingConstants.size() > 0) { + boolean init = false; + int numberOfIteratedConstants = 0; + + for (int i = 0; i < remainingConstants.size(); i++) { + init = true; + Node con = remainingConstants.get(i); + this.tlaModule.variables.add(con); + + ArrayList<PExpression> rangeList = constantsEvaluator + .getRangeOfIdentifier(con); + if (rangeList.size() > 0) { + numberOfIteratedConstants++; + ArrayList<PExpression> clone = new ArrayList<PExpression>(); + for (PExpression pExpression : rangeList) { + clone.add((PExpression) pExpression.clone()); + } + ASetExtensionExpression set = new ASetExtensionExpression( + clone); + AMemberPredicate member = new AMemberPredicate( + (AIdentifierExpression) con, set); + tlaModule.addInit(member); + continue; + } + + Node restrictedNode = typeRestrictor.getRestrictedNode(con); + AMemberPredicate memberPredicate = new AMemberPredicate( + (PExpression) con, (PExpression) restrictedNode); + tlaModule.addInit(memberPredicate); + + } + + if (numberOfIteratedConstants > 1) { + tlaModule.addInit(machineContext.getConstantsSetup()); + } + + if (init) { + configFile.setInit(); + if (!typeRestrictor.isARemovedNode(propertiesPerdicate)) + tlaModule.addInit(propertiesPerdicate); + } + + } else { + if (machineContext.getConstantsSetup() == null) { + tlaModule.assumes + .addAll(constantsEvaluator.getPropertiesList()); + } + tlaModule.addAssume(propertiesPerdicate); + } + + } + + @Override + public void inAPropertiesMachineClause(APropertiesMachineClause node) { + if (!tlaModule.isInitPredicate(node.getPredicates())) { + // this.tlaModule.addAssume(node.getPredicates()); + } + } + + @Override + public void caseAVariablesMachineClause(AVariablesMachineClause node) { + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + this.tlaModule.variables.add(e); + } + } + + @Override + public void caseAConcreteVariablesMachineClause( + AConcreteVariablesMachineClause node) { + List<PExpression> copy = new ArrayList<PExpression>( + node.getIdentifiers()); + for (PExpression e : copy) { + this.tlaModule.variables.add(e); + } + } + + @Override + public void inAAssertionsMachineClause(AAssertionsMachineClause node) { + List<PPredicate> copy = new ArrayList<PPredicate>(node.getPredicates()); + for (PPredicate e : copy) { + this.tlaModule.addAssertion(e); + } + this.configFile.setAssertionSize(copy.size()); + } + + @Override + public void inAInitialisationMachineClause(AInitialisationMachineClause node) { + this.configFile.setInit(); + this.tlaModule.addInit(node.getSubstitutions()); + } + + public TLAModule getTlaModule() { + return tlaModule; + } + + public ConfigFile getConfigFile() { + return configFile; + } + +} diff --git a/src/main/java/de/tlc4b/tla/TLADefinition.java b/src/main/java/de/tlc4b/tla/TLADefinition.java index 731193f96f39d22fe35a5f4b18585371ff9961e2..51c5df7e4a4994fdf66ef115a84eb9af5ab7d3fa 100644 --- a/src/main/java/de/tlc4b/tla/TLADefinition.java +++ b/src/main/java/de/tlc4b/tla/TLADefinition.java @@ -1,31 +1,31 @@ -package de.tlc4b.tla; - -import de.be4.classicalb.core.parser.node.Node; - -public class TLADefinition { - private Node name; - private Node definition; - private Integer intValue; - - public TLADefinition(Node name, Node definition){ - this.name = name; - this.definition = definition; - } - - public TLADefinition(Node con, Integer value) { - this.name = con; - this.intValue = value; - } - - public Node getDefName(){ - return name; - } - public Node getDefinition(){ - return definition; - } - - public Integer getInt(){ - return intValue; - } -} - +package de.tlc4b.tla; + +import de.be4.classicalb.core.parser.node.Node; + +public class TLADefinition { + private Node name; + private Node definition; + private Integer intValue; + + public TLADefinition(Node name, Node definition){ + this.name = name; + this.definition = definition; + } + + public TLADefinition(Node con, Integer value) { + this.name = con; + this.intValue = value; + } + + public Node getDefName(){ + return name; + } + public Node getDefinition(){ + return definition; + } + + public Integer getInt(){ + return intValue; + } +} + diff --git a/src/main/java/de/tlc4b/tla/TLAModule.java b/src/main/java/de/tlc4b/tla/TLAModule.java index 2135d0cabf3a506bac5888539a90c40cf2fdedd0..3d308319ec627616c6621f3630deb234438f4749 100644 --- a/src/main/java/de/tlc4b/tla/TLAModule.java +++ b/src/main/java/de/tlc4b/tla/TLAModule.java @@ -1,116 +1,116 @@ -package de.tlc4b.tla; - -import java.util.ArrayList; -import de.be4.classicalb.core.parser.node.Node; -import de.be4.classicalb.core.parser.node.PDefinition; -import de.be4.classicalb.core.parser.node.POperation; - -public class TLAModule { - - protected String moduleName; - - private final ArrayList<TLADefinition> tlaDefinitions; - protected final ArrayList<Node> constants; - protected final ArrayList<Node> assumes; - protected final ArrayList<Node> variables; - protected final ArrayList<Node> invariants; - private final ArrayList<Node> initPredicates; - protected final ArrayList<POperation> operations; - private ArrayList<PDefinition> bDefinitions; - private final ArrayList<Node> assertions; - - protected ArrayList<PDefinition> allDefinitions; - - public TLAModule() { - this.tlaDefinitions = new ArrayList<TLADefinition>(); - this.constants = new ArrayList<Node>(); - this.assumes = new ArrayList<Node>(); - this.variables = new ArrayList<Node>(); - this.initPredicates = new ArrayList<Node>(); - this.operations = new ArrayList<POperation>(); - this.bDefinitions = new ArrayList<PDefinition>(); - this.assertions = new ArrayList<Node>(); - this.invariants = new ArrayList<Node>(); - - this.allDefinitions = new ArrayList<PDefinition>(); - - } - - public void addToAllDefinitions(PDefinition def) { - this.allDefinitions.add(def); - } - - public ArrayList<PDefinition> getAllDefinitions() { - return allDefinitions; - } - - public ArrayList<Node> getAssertions() { - return assertions; - } - - public void addAssertion(Node node) { - assertions.add(node); - } - - public void addAssume(Node node) { - if (!assumes.contains(node)) - assumes.add(node); - } - - public void addInit(Node node) { - if (!initPredicates.contains(node)) - initPredicates.add(node); - } - - public boolean isInitPredicate(Node node) { - return initPredicates.contains(node); - } - - public String getModuleName() { - return moduleName; - } - - public ArrayList<TLADefinition> getTLADefinitions() { - return tlaDefinitions; - } - - public ArrayList<Node> getConstants() { - return constants; - } - - public ArrayList<Node> getAssume() { - return assumes; - } - - public ArrayList<Node> getVariables() { - return variables; - } - - public ArrayList<Node> getInitPredicates() { - return initPredicates; - } - - public ArrayList<POperation> getOperations() { - return operations; - } - - public ArrayList<Node> getInvariantList() { - return invariants; - } - - public void setBDefinitions(ArrayList<PDefinition> defs) { - this.bDefinitions = defs; - } - - public ArrayList<PDefinition> getBDefinitions() { - return bDefinitions; - } - - public boolean hasInitPredicate() { - return this.initPredicates.size() > 0; - } - - public void addTLADefinition(TLADefinition defintion) { - this.tlaDefinitions.add(defintion); - } -} +package de.tlc4b.tla; + +import java.util.ArrayList; +import de.be4.classicalb.core.parser.node.Node; +import de.be4.classicalb.core.parser.node.PDefinition; +import de.be4.classicalb.core.parser.node.POperation; + +public class TLAModule { + + protected String moduleName; + + private final ArrayList<TLADefinition> tlaDefinitions; + protected final ArrayList<Node> constants; + protected final ArrayList<Node> assumes; + protected final ArrayList<Node> variables; + protected final ArrayList<Node> invariants; + private final ArrayList<Node> initPredicates; + protected final ArrayList<POperation> operations; + private ArrayList<PDefinition> bDefinitions; + private final ArrayList<Node> assertions; + + protected ArrayList<PDefinition> allDefinitions; + + public TLAModule() { + this.tlaDefinitions = new ArrayList<TLADefinition>(); + this.constants = new ArrayList<Node>(); + this.assumes = new ArrayList<Node>(); + this.variables = new ArrayList<Node>(); + this.initPredicates = new ArrayList<Node>(); + this.operations = new ArrayList<POperation>(); + this.bDefinitions = new ArrayList<PDefinition>(); + this.assertions = new ArrayList<Node>(); + this.invariants = new ArrayList<Node>(); + + this.allDefinitions = new ArrayList<PDefinition>(); + + } + + public void addToAllDefinitions(PDefinition def) { + this.allDefinitions.add(def); + } + + public ArrayList<PDefinition> getAllDefinitions() { + return allDefinitions; + } + + public ArrayList<Node> getAssertions() { + return assertions; + } + + public void addAssertion(Node node) { + assertions.add(node); + } + + public void addAssume(Node node) { + if (!assumes.contains(node)) + assumes.add(node); + } + + public void addInit(Node node) { + if (!initPredicates.contains(node)) + initPredicates.add(node); + } + + public boolean isInitPredicate(Node node) { + return initPredicates.contains(node); + } + + public String getModuleName() { + return moduleName; + } + + public ArrayList<TLADefinition> getTLADefinitions() { + return tlaDefinitions; + } + + public ArrayList<Node> getConstants() { + return constants; + } + + public ArrayList<Node> getAssume() { + return assumes; + } + + public ArrayList<Node> getVariables() { + return variables; + } + + public ArrayList<Node> getInitPredicates() { + return initPredicates; + } + + public ArrayList<POperation> getOperations() { + return operations; + } + + public ArrayList<Node> getInvariantList() { + return invariants; + } + + public void setBDefinitions(ArrayList<PDefinition> defs) { + this.bDefinitions = defs; + } + + public ArrayList<PDefinition> getBDefinitions() { + return bDefinitions; + } + + public boolean hasInitPredicate() { + return this.initPredicates.size() > 0; + } + + public void addTLADefinition(TLADefinition defintion) { + this.tlaDefinitions.add(defintion); + } +} diff --git a/src/main/java/de/tlc4b/tla/config/ConfigFileAssignment.java b/src/main/java/de/tlc4b/tla/config/ConfigFileAssignment.java index 0bbc2d4eb0d118d691d2bb5126de82b786292d44..4c4face506d164b5405701287ab2af0b75a2a4d1 100644 --- a/src/main/java/de/tlc4b/tla/config/ConfigFileAssignment.java +++ b/src/main/java/de/tlc4b/tla/config/ConfigFileAssignment.java @@ -1,25 +1,25 @@ -package de.tlc4b.tla.config; - -import java.util.ArrayList; -import java.util.List; - -import de.be4.classicalb.core.parser.node.AIdentifierExpression; -import de.be4.classicalb.core.parser.node.TIdentifierLiteral; -import de.tlc4b.analysis.Renamer; - -public abstract class ConfigFileAssignment { - - public abstract String getString(Renamer renamer); - - public String getIdentifier(AIdentifierExpression node) { - StringBuffer res = new StringBuffer(); - - List<TIdentifierLiteral> copy = new ArrayList<TIdentifierLiteral>( - node.getIdentifier()); - for (TIdentifierLiteral e : copy) { - res.append(e.getText()); - } - return res.toString(); - } - -} +package de.tlc4b.tla.config; + +import java.util.ArrayList; +import java.util.List; + +import de.be4.classicalb.core.parser.node.AIdentifierExpression; +import de.be4.classicalb.core.parser.node.TIdentifierLiteral; +import de.tlc4b.analysis.Renamer; + +public abstract class ConfigFileAssignment { + + public abstract String getString(Renamer renamer); + + public String getIdentifier(AIdentifierExpression node) { + StringBuffer res = new StringBuffer(); + + List<TIdentifierLiteral> copy = new ArrayList<TIdentifierLiteral>( + node.getIdentifier()); + for (TIdentifierLiteral e : copy) { + res.append(e.getText()); + } + return res.toString(); + } + +} diff --git a/src/main/java/de/tlc4b/tla/config/ModelValueAssignment.java b/src/main/java/de/tlc4b/tla/config/ModelValueAssignment.java index 8b6ef2d13b282fac2e423181010c1e39f5f09bae..84c47528e2304e946c2a3deb4cf7b6dbd60a9c8b 100644 --- a/src/main/java/de/tlc4b/tla/config/ModelValueAssignment.java +++ b/src/main/java/de/tlc4b/tla/config/ModelValueAssignment.java @@ -1,21 +1,21 @@ -package de.tlc4b.tla.config; - -import de.be4.classicalb.core.parser.node.AIdentifierExpression; -import de.be4.classicalb.core.parser.node.Node; -import de.tlc4b.analysis.Renamer; - -public class ModelValueAssignment extends ConfigFileAssignment{ - private Node node; - - public ModelValueAssignment(Node node){ - this.node = node; - } - - public String getString(Renamer renamer) { - AIdentifierExpression id = (AIdentifierExpression) node; - String conString = getIdentifier(id); - conString = renamer.getNameOfRef(id); - return conString+ " = "+ conString +"\n"; - } - -} +package de.tlc4b.tla.config; + +import de.be4.classicalb.core.parser.node.AIdentifierExpression; +import de.be4.classicalb.core.parser.node.Node; +import de.tlc4b.analysis.Renamer; + +public class ModelValueAssignment extends ConfigFileAssignment{ + private Node node; + + public ModelValueAssignment(Node node){ + this.node = node; + } + + public String getString(Renamer renamer) { + AIdentifierExpression id = (AIdentifierExpression) node; + String conString = getIdentifier(id); + conString = renamer.getNameOfRef(id); + return conString+ " = "+ conString +"\n"; + } + +} diff --git a/src/main/java/de/tlc4b/tla/config/SetOfModelValuesAssignment.java b/src/main/java/de/tlc4b/tla/config/SetOfModelValuesAssignment.java index da43e2d1ed9e1ce40abcbde20d695b321e34212a..d69bd9fdc36adf5db317e256970bad5deb82eb27 100644 --- a/src/main/java/de/tlc4b/tla/config/SetOfModelValuesAssignment.java +++ b/src/main/java/de/tlc4b/tla/config/SetOfModelValuesAssignment.java @@ -1,62 +1,62 @@ -package de.tlc4b.tla.config; - -import java.util.List; - -import de.be4.classicalb.core.parser.node.ADeferredSetSet; -import de.be4.classicalb.core.parser.node.AIdentifierExpression; -import de.be4.classicalb.core.parser.node.Node; -import de.be4.classicalb.core.parser.node.TIdentifierLiteral; -import de.tlc4b.TLC4BGlobals; -import de.tlc4b.analysis.Renamer; - -/** - * - * This class represents an assignment in the configuration file. The left side - * of the assignment is a constant and the right side a set of model values. - * E.g. k = {k1, k2, k3} - */ - -public class SetOfModelValuesAssignment extends ConfigFileAssignment { - private Node node; - private int size; - - public SetOfModelValuesAssignment(Node node, Integer size) { - this.node = node; - if (size == null) { - this.size = TLC4BGlobals.getDEFERRED_SET_SIZE(); - } else { - this.size = size; - } - - } - - public String getString(Renamer renamer) { - StringBuffer res = new StringBuffer(); - - String conString; - if (node instanceof ADeferredSetSet) { - conString = ""; - List<TIdentifierLiteral> copy = ((ADeferredSetSet) node) - .getIdentifier(); - for (TIdentifierLiteral e : copy) { - conString += e.getText(); - } - conString = renamer.getName(node); - } else { - AIdentifierExpression id = (AIdentifierExpression) node; - conString = getIdentifier(id); - } - - res.append(conString).append(" = {"); - for (int j = 1; j < size + 1; j++) { - res.append(conString + j); - if (j < size) { - res.append(","); - } - } - res.append("}\n"); - - return res.toString(); - } - -} +package de.tlc4b.tla.config; + +import java.util.List; + +import de.be4.classicalb.core.parser.node.ADeferredSetSet; +import de.be4.classicalb.core.parser.node.AIdentifierExpression; +import de.be4.classicalb.core.parser.node.Node; +import de.be4.classicalb.core.parser.node.TIdentifierLiteral; +import de.tlc4b.TLC4BGlobals; +import de.tlc4b.analysis.Renamer; + +/** + * + * This class represents an assignment in the configuration file. The left side + * of the assignment is a constant and the right side a set of model values. + * E.g. k = {k1, k2, k3} + */ + +public class SetOfModelValuesAssignment extends ConfigFileAssignment { + private Node node; + private int size; + + public SetOfModelValuesAssignment(Node node, Integer size) { + this.node = node; + if (size == null) { + this.size = TLC4BGlobals.getDEFERRED_SET_SIZE(); + } else { + this.size = size; + } + + } + + public String getString(Renamer renamer) { + StringBuffer res = new StringBuffer(); + + String conString; + if (node instanceof ADeferredSetSet) { + conString = ""; + List<TIdentifierLiteral> copy = ((ADeferredSetSet) node) + .getIdentifier(); + for (TIdentifierLiteral e : copy) { + conString += e.getText(); + } + conString = renamer.getName(node); + } else { + AIdentifierExpression id = (AIdentifierExpression) node; + conString = getIdentifier(id); + } + + res.append(conString).append(" = {"); + for (int j = 1; j < size + 1; j++) { + res.append(conString + j); + if (j < size) { + res.append(","); + } + } + res.append("}\n"); + + return res.toString(); + } + +} diff --git a/src/main/java/de/tlc4b/tlc/ModuleMatcher.java b/src/main/java/de/tlc4b/tlc/ModuleMatcher.java index 086e32179dade827f7b479b14575b7bafe453058..477aee4e43b5c38722c094101aaa9ad7bfab5b65 100644 --- a/src/main/java/de/tlc4b/tlc/ModuleMatcher.java +++ b/src/main/java/de/tlc4b/tlc/ModuleMatcher.java @@ -1,91 +1,91 @@ -package de.tlc4b.tlc; - -import java.util.HashMap; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import tla2sany.drivers.SANY; -import tla2sany.modanalyzer.SpecObj; -import tla2sany.semantic.ModuleNode; -import tla2sany.semantic.OpDefNode; -import util.ToolIO; - -public class ModuleMatcher { - private final String fileName; - private final HashMap<Integer, String> lineToNameMap; - - public ModuleMatcher(String fileName, String path) { - this.fileName = fileName; - this.lineToNameMap = new HashMap<Integer, String>(); - ModuleNode moduleNode = parse(fileName, path); - evalActions(moduleNode); - } - - public String getName(String string){ - int line = getLine(string); - if(line == -1){ - return "Init"; - } - String res = lineToNameMap.get(line); - return res; - } - - private void evalActions(ModuleNode moduleNode) { - OpDefNode[] opdefs = moduleNode.getOpDefs(); - for (int i = 0; i < opdefs.length; i++) { - OpDefNode opdef = opdefs[i]; - - String module = opdef.getSource() - .getOriginallyDefinedInModuleNode().getName().toString(); - if (module.equalsIgnoreCase(fileName)) { - String opdefName = opdef.getName().toString(); - lineToNameMap.put(opdef.getLocation().beginLine(), opdefName); - } - } - } - - private int getLine(String s){ - Pattern pattern = Pattern.compile("(line\\s)(\\d+)"); - Matcher matcher = pattern.matcher(s); - boolean res = matcher.find(); - if(res){ - return Integer.parseInt(matcher.group(2)); - }else{ - return -1; - } - } - - private ModuleNode parse(String fileName, String path) { - ToolIO.reset(); - ToolIO.setUserDir(path); - SpecObj spec = new SpecObj(fileName, null); - try { - SANY.frontEndMain(spec, fileName, ToolIO.out); - } catch (tla2sany.drivers.FrontEndException e) { - System.out.println(e.getMessage()); - e.printStackTrace(); - } - - // RootModule - ModuleNode n = spec.getExternalModuleTable().rootModule; - if (spec.getInitErrors().isFailure()) { - System.err.println(spec.getInitErrors()); - return null; - } - - if (n == null) { // Parse Error - System.out.println("hier"); - // System.out.println("Rootmodule null"); - System.out.println(allMessagesToString(ToolIO.getAllMessages())); - } - return n; - } - - public static String allMessagesToString(String[] allMessages) { - StringBuilder sb = new StringBuilder(); - for (int i = 0; i < allMessages.length - 1; i++) { - sb.append(allMessages[i] + "\n"); - } - return sb.toString(); - } -} +package de.tlc4b.tlc; + +import java.util.HashMap; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import tla2sany.drivers.SANY; +import tla2sany.modanalyzer.SpecObj; +import tla2sany.semantic.ModuleNode; +import tla2sany.semantic.OpDefNode; +import util.ToolIO; + +public class ModuleMatcher { + private final String fileName; + private final HashMap<Integer, String> lineToNameMap; + + public ModuleMatcher(String fileName, String path) { + this.fileName = fileName; + this.lineToNameMap = new HashMap<Integer, String>(); + ModuleNode moduleNode = parse(fileName, path); + evalActions(moduleNode); + } + + public String getName(String string){ + int line = getLine(string); + if(line == -1){ + return "Init"; + } + String res = lineToNameMap.get(line); + return res; + } + + private void evalActions(ModuleNode moduleNode) { + OpDefNode[] opdefs = moduleNode.getOpDefs(); + for (int i = 0; i < opdefs.length; i++) { + OpDefNode opdef = opdefs[i]; + + String module = opdef.getSource() + .getOriginallyDefinedInModuleNode().getName().toString(); + if (module.equalsIgnoreCase(fileName)) { + String opdefName = opdef.getName().toString(); + lineToNameMap.put(opdef.getLocation().beginLine(), opdefName); + } + } + } + + private int getLine(String s){ + Pattern pattern = Pattern.compile("(line\\s)(\\d+)"); + Matcher matcher = pattern.matcher(s); + boolean res = matcher.find(); + if(res){ + return Integer.parseInt(matcher.group(2)); + }else{ + return -1; + } + } + + private ModuleNode parse(String fileName, String path) { + ToolIO.reset(); + ToolIO.setUserDir(path); + SpecObj spec = new SpecObj(fileName, null); + try { + SANY.frontEndMain(spec, fileName, ToolIO.out); + } catch (tla2sany.drivers.FrontEndException e) { + System.out.println(e.getMessage()); + e.printStackTrace(); + } + + // RootModule + ModuleNode n = spec.getExternalModuleTable().rootModule; + if (spec.getInitErrors().isFailure()) { + System.err.println(spec.getInitErrors()); + return null; + } + + if (n == null) { // Parse Error + System.out.println("hier"); + // System.out.println("Rootmodule null"); + System.out.println(allMessagesToString(ToolIO.getAllMessages())); + } + return n; + } + + public static String allMessagesToString(String[] allMessages) { + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < allMessages.length - 1; i++) { + sb.append(allMessages[i] + "\n"); + } + return sb.toString(); + } +} diff --git a/src/main/java/de/tlc4b/util/Ast2String.java b/src/main/java/de/tlc4b/util/Ast2String.java deleted file mode 100644 index b0007b4d6384316225a7f33604a0332ad3018ede..0000000000000000000000000000000000000000 --- a/src/main/java/de/tlc4b/util/Ast2String.java +++ /dev/null @@ -1,67 +0,0 @@ -package de.tlc4b.util; - -import de.be4.classicalb.core.parser.analysis.ExtendedDFAdapter; -import de.be4.classicalb.core.parser.node.Node; -import de.be4.classicalb.core.parser.node.Start; -import de.be4.classicalb.core.parser.node.Token; - -public class Ast2String extends ExtendedDFAdapter { - private final StringBuilder builder = new StringBuilder(); - - @Override - public String toString() { - return builder.toString(); - } - - @Override - public void defaultIn(final Node node) { - super.defaultIn(node); - builder.append(node.getClass().getSimpleName()); - builder.append("("); - } - - @Override - public void defaultCase(final Node node) { - super.defaultCase(node); - if (node instanceof Token) { - builder.append(((Token) node).getText()); - } else { - builder.append(node.toString()); - } - - } - - @Override - public void defaultOut(final Node node) { - super.defaultOut(node); - builder.append(")"); - } - - @Override - public void beginList(final Node parent) { - builder.append('['); - } - - @Override - public void betweenListElements(final Node parent) { - builder.append(','); - } - - @Override - public void endList(final Node parent) { - builder.append(']'); - } - - @Override - public void betweenChildren(final Node parent) { - builder.append(','); - } - - @Override - public void caseStart(final Start node) { - inStart(node); - node.getPParseUnit().apply(this); - node.getEOF().apply(this); - outStart(node); - } -} diff --git a/src/main/java/de/tlc4b/util/StopWatch.java b/src/main/java/de/tlc4b/util/StopWatch.java index b978519b87e94dea1c21db1a338940d5bc2cb50e..7ef4d84a568764b2b85c50979eeb05134b040d44 100644 --- a/src/main/java/de/tlc4b/util/StopWatch.java +++ b/src/main/java/de/tlc4b/util/StopWatch.java @@ -1,33 +1,33 @@ -package de.tlc4b.util; - -import java.util.Hashtable; - -public class StopWatch { - - - private static final Hashtable<Watches, Long> startTime = new Hashtable<Watches, Long>(); - private static final Hashtable<Watches, Long> runTime = new Hashtable<Watches, Long>(); - - public enum Watches{ - PARSING_TIME, TRANSLATION_TIME, TLC_TIME, OVERALL_TIME, MODEL_CHECKING_TIME - } - - public static void start(Watches watch){ - startTime.put(watch, System.currentTimeMillis()); - } - - public static long stop(Watches id) { - long stopTime = System.currentTimeMillis() - - startTime.remove(id); - runTime.put(id, stopTime); - return stopTime; - } - - public static long getRunTime(Watches id){ - return runTime.get(id); - } - - public static String getRunTimeAsString(Watches id){ - return runTime.get(id).toString(); - } +package de.tlc4b.util; + +import java.util.Hashtable; + +public class StopWatch { + + + private static final Hashtable<Watches, Long> startTime = new Hashtable<Watches, Long>(); + private static final Hashtable<Watches, Long> runTime = new Hashtable<Watches, Long>(); + + public enum Watches{ + PARSING_TIME, TRANSLATION_TIME, TLC_TIME, OVERALL_TIME, MODEL_CHECKING_TIME + } + + public static void start(Watches watch){ + startTime.put(watch, System.currentTimeMillis()); + } + + public static long stop(Watches id) { + long stopTime = System.currentTimeMillis() + - startTime.remove(id); + runTime.put(id, stopTime); + return stopTime; + } + + public static long getRunTime(Watches id){ + return runTime.get(id); + } + + public static String getRunTimeAsString(Watches id){ + return runTime.get(id).toString(); + } } \ No newline at end of file diff --git a/src/main/resources/standardModules/BBuiltIns.tla b/src/main/resources/standardModules/BBuiltIns.tla index afbfa2ebcb00948b8aefc1ca7174227695bc65eb..0545f637216bdab7344a65584e68ab2bb6e6f831 100644 --- a/src/main/resources/standardModules/BBuiltIns.tla +++ b/src/main/resources/standardModules/BBuiltIns.tla @@ -1,17 +1,17 @@ ------------------------------ MODULE BBuiltIns ----------------------------- +----------------------------- MODULE BBuiltIns ----------------------------- EXTENDS Integers, FiniteSets, TLC Max(S) == CHOOSE x \in S : \A p \in S : x >= p - \* The largest element of the set S + \* The largest element of the set S Min(S) == CHOOSE x \in S : \A p \in S : x =< p - \* The smallest element of the set S + \* The smallest element of the set S -succ[x \in Int] == x + 1 - \* The successor function - -pred[x \in Int] == x - 1 - \* The predecessor function +succ[x \in Int] == x + 1 + \* The successor function + +pred[x \in Int] == x - 1 + \* The predecessor function BPowerOf(a,b) == IF a = 0 /\ b = 0 THEN 1 ELSE a ^ b BDivision(a,b) == @@ -38,7 +38,7 @@ Sigma(S) == IF newS = {} THEN e[2] ELSE e[2] + Sigma(S \ {e}) - \* The sum of all second components of pairs which are elements of S + \* The sum of all second components of pairs which are elements of S RECURSIVE Pi(_) Pi(S) == @@ -51,27 +51,27 @@ Pi(S) == IF newS = {} THEN e[2] ELSE e[2] * Pi(S \ {e}) - \* The product of all second components of pairs which are elements of S - -Pow1(S) == (SUBSET S) \ {{}} - \* The set of non-empty subsets - -Fin(S) == {x \in SUBSET S: IsFiniteSet(x)} - \* The set of all finite subsets. - -Fin1(S) == {x \in SUBSET S: IsFiniteSet(x) /\ x # {}} - \* The set of all non-empty finite subsets - -S \subset T == S \subseteq T /\ S # T - \* The predicate becomes true if S is a strict subset of T - -NotSubset(S, T) == ~ (S \subseteq T) - \* The predicate becomes true if S is not a subset of T - -NotStrictSubset(S, T) == ~ (S \subset T) - \* The predicate becomes true if S is not a strict subset of T - -RECURSIVE Inter(_) + \* The product of all second components of pairs which are elements of S + +Pow1(S) == (SUBSET S) \ {{}} + \* The set of non-empty subsets + +Fin(S) == {x \in SUBSET S: IsFiniteSet(x)} + \* The set of all finite subsets. + +Fin1(S) == {x \in SUBSET S: IsFiniteSet(x) /\ x # {}} + \* The set of all non-empty finite subsets + +S \subset T == S \subseteq T /\ S # T + \* The predicate becomes true if S is a strict subset of T + +NotSubset(S, T) == ~ (S \subseteq T) + \* The predicate becomes true if S is not a subset of T + +NotStrictSubset(S, T) == ~ (S \subset T) + \* The predicate becomes true if S is not a strict subset of T + +RECURSIVE Inter(_) Inter(S) == IF Assert(S /= {}, "Error: Applied the inter operator to an empty set.") THEN @@ -79,6 +79,6 @@ Inter(S) == IN IF Cardinality(S) = 1 THEN e ELSE e \cap Inter(S \ {e}) - ELSE {} \* dummy value - \* The intersection of all elements of S. + ELSE {} \* dummy value + \* The intersection of all elements of S. ============================================================================= diff --git a/src/main/resources/standardModules/Functions.tla b/src/main/resources/standardModules/Functions.tla index 6cffb418835599804399a1503ac4cb4fecb9fafc..4b65eeb0da9a354c36ffab70d3fa53f134936511 100644 --- a/src/main/resources/standardModules/Functions.tla +++ b/src/main/resources/standardModules/Functions.tla @@ -1,88 +1,88 @@ ------------------------------ MODULE Functions ----------------------------- -EXTENDS FiniteSets, TLC - -Range(f) == {f[x] : x \in DOMAIN f} - \* The range of the function f - -Image(f,S) == {f[x] : x \in S \cap DOMAIN f} - \* The image of the set S for the function f - -Card(f) == Cardinality(DOMAIN f) - \* The Cardinality of the function f - -Id(S) == [x \in S|-> x] - \* The identity function on set S - -DomRes(S, f) == [x \in (S \cap DOMAIN f) |-> f[x]] - \* The restriction on the domain of f for set S - -DomSub(S, f) == [x \in DOMAIN f \ S |-> f[x]] - \* The subtraction on the domain of f for set S - -RanRes(f, S) == [x \in {y \in DOMAIN f: f[y] \in S} |-> f[x]] - \* The restriction on the range of f for set S - -RanSub(f, S) == [x \in {y \in DOMAIN f: f[y] \notin S} |-> f[x]] - \* The subtraction on the range of f for set S - -Inverse(f) == {<<f[x],x>>: x \in DOMAIN f} - \* The inverse relation of the function f - -Override(f, g) == [x \in (DOMAIN f) \cup DOMAIN g |-> IF x \in DOMAIN g THEN g[x] ELSE f[x]] - \* Overwriting of the function f with the function g - -FuncAssign(f, d, e) == d :> e @@ f - \* [x \in (DOMAIN f) \cup {d} |-> IF x = d THEN e ELSE f[x]] - \* Overwriting the function f at index d with value e - -TotalInjFunc(S, T) == {f \in [S -> T]: - Cardinality(DOMAIN f) = Cardinality(Range(f))} - \* The set of all total injective functions - -TotalSurFunc(S, T) == {f \in [S -> T]: T = Range(f)} - \* The set of all total surjective functions - -TotalBijFunc(S, T) == {f \in [S -> T]: T = Range(f) /\ - Cardinality(DOMAIN f) = Cardinality(Range(f))} - \* The set of all total bijective functions - -ParFunc(S, T) == UNION{[x -> T] :x \in SUBSET S} - \* The set of all partial functions - -ParFuncEleOf(f, S, T) == {x \in {f} : DOMAIN f \subseteq S /\ Range(f) \subseteq T} - \* The set containing f if f is a partial function - -isEleOfParFunc(f, S, T) == DOMAIN f \subseteq S /\ Range(f) \subseteq T - \* Test if the function f is a partial function - -ParInjFunc(S, T)== {f \in ParFunc(S, T): - Cardinality(DOMAIN f) = Cardinality(Range(f))} -\* The set of all partial injective functions - -ParInjFuncEleOf(f, S, T)== {x \in {f}: - /\ DOMAIN f \subseteq S - /\ Range(f) \subseteq T - /\ Cardinality(DOMAIN f) = Cardinality(Range(f))} -\* The set containing f if f is a partial injective function - -ParSurFunc(S, T)== {f \in ParFunc(S, T): T = Range(f)} -\* The set of all partial surjective function - -ParSurFuncEleOf(f, S, T)== {x \in {f}: - /\ DOMAIN f \subseteq S - /\ Range(f) \subseteq T - /\ T = Range(f)} -\* The set containing f if f is a partial surjective function - -ParBijFunc(S, T) == {f \in ParFunc(S, T): - /\ Range(f) = T - /\ Cardinality(DOMAIN f) = Cardinality(Range(f))} - \* The set of all partial bijective functions - -ParBijFuncEleOf(f, S, T) == {x \in {f}: - /\ DOMAIN f \subseteq S - /\ Range(f) \subseteq T - /\ Cardinality(DOMAIN f) = Cardinality(Range(f)) - /\ T = Range(f)} -\* The set containing f if f is a partial bijective function -============================================================================= +----------------------------- MODULE Functions ----------------------------- +EXTENDS FiniteSets, TLC + +Range(f) == {f[x] : x \in DOMAIN f} + \* The range of the function f + +Image(f,S) == {f[x] : x \in S \cap DOMAIN f} + \* The image of the set S for the function f + +Card(f) == Cardinality(DOMAIN f) + \* The Cardinality of the function f + +Id(S) == [x \in S|-> x] + \* The identity function on set S + +DomRes(S, f) == [x \in (S \cap DOMAIN f) |-> f[x]] + \* The restriction on the domain of f for set S + +DomSub(S, f) == [x \in DOMAIN f \ S |-> f[x]] + \* The subtraction on the domain of f for set S + +RanRes(f, S) == [x \in {y \in DOMAIN f: f[y] \in S} |-> f[x]] + \* The restriction on the range of f for set S + +RanSub(f, S) == [x \in {y \in DOMAIN f: f[y] \notin S} |-> f[x]] + \* The subtraction on the range of f for set S + +Inverse(f) == {<<f[x],x>>: x \in DOMAIN f} + \* The inverse relation of the function f + +Override(f, g) == [x \in (DOMAIN f) \cup DOMAIN g |-> IF x \in DOMAIN g THEN g[x] ELSE f[x]] + \* Overwriting of the function f with the function g + +FuncAssign(f, d, e) == d :> e @@ f + \* [x \in (DOMAIN f) \cup {d} |-> IF x = d THEN e ELSE f[x]] + \* Overwriting the function f at index d with value e + +TotalInjFunc(S, T) == {f \in [S -> T]: + Cardinality(DOMAIN f) = Cardinality(Range(f))} + \* The set of all total injective functions + +TotalSurFunc(S, T) == {f \in [S -> T]: T = Range(f)} + \* The set of all total surjective functions + +TotalBijFunc(S, T) == {f \in [S -> T]: T = Range(f) /\ + Cardinality(DOMAIN f) = Cardinality(Range(f))} + \* The set of all total bijective functions + +ParFunc(S, T) == UNION{[x -> T] :x \in SUBSET S} + \* The set of all partial functions + +ParFuncEleOf(f, S, T) == {x \in {f} : DOMAIN f \subseteq S /\ Range(f) \subseteq T} + \* The set containing f if f is a partial function + +isEleOfParFunc(f, S, T) == DOMAIN f \subseteq S /\ Range(f) \subseteq T + \* Test if the function f is a partial function + +ParInjFunc(S, T)== {f \in ParFunc(S, T): + Cardinality(DOMAIN f) = Cardinality(Range(f))} +\* The set of all partial injective functions + +ParInjFuncEleOf(f, S, T)== {x \in {f}: + /\ DOMAIN f \subseteq S + /\ Range(f) \subseteq T + /\ Cardinality(DOMAIN f) = Cardinality(Range(f))} +\* The set containing f if f is a partial injective function + +ParSurFunc(S, T)== {f \in ParFunc(S, T): T = Range(f)} +\* The set of all partial surjective function + +ParSurFuncEleOf(f, S, T)== {x \in {f}: + /\ DOMAIN f \subseteq S + /\ Range(f) \subseteq T + /\ T = Range(f)} +\* The set containing f if f is a partial surjective function + +ParBijFunc(S, T) == {f \in ParFunc(S, T): + /\ Range(f) = T + /\ Cardinality(DOMAIN f) = Cardinality(Range(f))} + \* The set of all partial bijective functions + +ParBijFuncEleOf(f, S, T) == {x \in {f}: + /\ DOMAIN f \subseteq S + /\ Range(f) \subseteq T + /\ Cardinality(DOMAIN f) = Cardinality(Range(f)) + /\ T = Range(f)} +\* The set containing f if f is a partial bijective function +============================================================================= diff --git a/src/main/resources/standardModules/FunctionsAsRelations.tla b/src/main/resources/standardModules/FunctionsAsRelations.tla index 6a5de15f71d262bf866f447e515eaf032da4ea95..903c7a296b6ecd6dda20ee388b7dbd9cec62d45e 100644 --- a/src/main/resources/standardModules/FunctionsAsRelations.tla +++ b/src/main/resources/standardModules/FunctionsAsRelations.tla @@ -1,86 +1,86 @@ ------------------------- MODULE FunctionsAsRelations ---------------------------------- -EXTENDS FiniteSets, Functions, TLC, Sequences - -LOCAL RelDom(f) == { x[1] :x \in f} \* The domain of the function -LOCAL RelRan(f) == { x[2] :x \in f} \* The range of the function -LOCAL MakeRel(f) == {<<x, f[x]>>: x \in DOMAIN f} - \* Converting a TLA+ function to a set of pairs -LOCAL Rel(S, T) == SUBSET (S \times T) \* The set of relations -LOCAL IsFunc(f) == Cardinality(RelDom(f)) = Cardinality(f) - \* Testing if f is a function -LOCAL IsTotal(f, dom) == RelDom(f) = dom - \* Testing if f is a total function -LOCAL IsInj(f) == Cardinality(RelRan(f)) = Cardinality(f) - \* Testing if f is a injective function -LOCAL IsSurj(f, ran) == RelRan(f) = ran - \* Testing if f is a surjective function - -RelCallWithoutWDCheck(f, x) == (CHOOSE y \in f: y[1] = x)[2] - -RelCall(f, x) == IF Cardinality(f) = Cardinality(RelDom(f)) /\ x \in RelDom(f) - THEN (CHOOSE y \in f: y[1] = x)[2] - ELSE PrintT("Error: Invalid function call to relation " - \o ToString(f) \o " and value " \o ToString(x) \o ".") - /\ Assert(Cardinality(f) # Cardinality(RelDom(f)), "Applied a function call to a relation.") - /\ Assert(x \notin RelDom(f), "Function applied outside domain.") - \* The function call applied to function f and argument x - -RelTotalFunc(S, T) == {MakeRel(f): f \in [S -> T]} - \* The set of total function - -RelTotalFuncEleOf(S, T) == {f \in Rel(S,T): IsFunc(f) /\ IsTotal(f,S)} - \* The set of total functions - \* (Optimized to test if a certain function is a element of this set.) - -RelTotalInjFunc(S, T) == {MakeRel(f): f \in TotalInjFunc(S, T)} - \* The set of total injective functions - -RelTotalInjFuncEleOf(S, T) == {f \in Rel(S,T): IsFunc(f) /\ IsTotal(f,S) /\ IsInj(f)} - \* The set of total injective functions - \* (Optimized to test if a certain function is a element of this set.) - -RelTotalSurFunc(S, T) == {MakeRel(f): f \in TotalSurFunc(S, T)} - \* The set of total surjective functions - -RelTotalSurFuncEleOf(S, T) == {f \in Rel(S,T): - /\ IsFunc(f) /\ IsTotal(f,S) /\ IsSurj(f, T)} - \* The set of total surjective functions - \* (Optimized to test if a certain function is a element of this set.) - -RelTotalBijFunc(S, T) == {MakeRel(f): f \in TotalBijFunc(S, T)} -\* The set of total bijective functions - -RelTotalBijFuncEleOf(S, T) == {f \in (SUBSET (S \times T)): - /\ IsFunc(f) /\ IsTotal(f,S) /\ IsInj(f) /\ IsSurj(f, T)} - \* The set of total bijective functions - \* (Optimized to test if a certain function is a element of this set.) - - -RelParFunc(S, T) == {MakeRel(f): f \in ParFunc(S, T)} - \* The set of partial functions - -RelParFuncEleOf(S, T) == {f \in Rel(S, T): IsFunc(f)} - \* The set of partial functions - \* (Optimized to test if a certain function is a element of this set.) - -RelParInjFunc(S, T) == {MakeRel(f): f \in ParInjFunc(S, T)} - \* The set of partial injective functions. - -RelParInjFuncEleOf(S, T) == {f \in Rel(S, T): IsFunc(f) /\ IsInj(f)} - \* The set of partial injective functions - \* (Optimized to test if a certain function is a element of this set.) - -RelParSurFunc(S, T) == {MakeRel(f): f \in ParSurFunc(S, T)} - \* The set of partial surjective functions - -RelParSurFuncEleOf(S, T) == {f \in Rel(S, T): IsFunc(f) /\ IsSurj(f, T)} - \* The set of partial surjective functions. - \* (Optimized to test if a certain function is a element of this set.) - -RelParBijFunc(S, T) == {MakeRel(f): f \in ParBijFunc(S, T)} - \* The set of partial bijective functions - -RelParBijFuncEleOf(S, T) == {f \in Rel(S, T): IsFunc(f) /\ IsSurj(f, T) /\ IsInj(f)} - \* The set of partial bijective functions - \* (Optimized to test if a certain function is a element of this set.) +------------------------ MODULE FunctionsAsRelations ---------------------------------- +EXTENDS FiniteSets, Functions, TLC, Sequences + +LOCAL RelDom(f) == { x[1] :x \in f} \* The domain of the function +LOCAL RelRan(f) == { x[2] :x \in f} \* The range of the function +LOCAL MakeRel(f) == {<<x, f[x]>>: x \in DOMAIN f} + \* Converting a TLA+ function to a set of pairs +LOCAL Rel(S, T) == SUBSET (S \times T) \* The set of relations +LOCAL IsFunc(f) == Cardinality(RelDom(f)) = Cardinality(f) + \* Testing if f is a function +LOCAL IsTotal(f, dom) == RelDom(f) = dom + \* Testing if f is a total function +LOCAL IsInj(f) == Cardinality(RelRan(f)) = Cardinality(f) + \* Testing if f is a injective function +LOCAL IsSurj(f, ran) == RelRan(f) = ran + \* Testing if f is a surjective function + +RelCallWithoutWDCheck(f, x) == (CHOOSE y \in f: y[1] = x)[2] + +RelCall(f, x) == IF Cardinality(f) = Cardinality(RelDom(f)) /\ x \in RelDom(f) + THEN (CHOOSE y \in f: y[1] = x)[2] + ELSE PrintT("Error: Invalid function call to relation " + \o ToString(f) \o " and value " \o ToString(x) \o ".") + /\ Assert(Cardinality(f) # Cardinality(RelDom(f)), "Applied a function call to a relation.") + /\ Assert(x \notin RelDom(f), "Function applied outside domain.") + \* The function call applied to function f and argument x + +RelTotalFunc(S, T) == {MakeRel(f): f \in [S -> T]} + \* The set of total function + +RelTotalFuncEleOf(S, T) == {f \in Rel(S,T): IsFunc(f) /\ IsTotal(f,S)} + \* The set of total functions + \* (Optimized to test if a certain function is a element of this set.) + +RelTotalInjFunc(S, T) == {MakeRel(f): f \in TotalInjFunc(S, T)} + \* The set of total injective functions + +RelTotalInjFuncEleOf(S, T) == {f \in Rel(S,T): IsFunc(f) /\ IsTotal(f,S) /\ IsInj(f)} + \* The set of total injective functions + \* (Optimized to test if a certain function is a element of this set.) + +RelTotalSurFunc(S, T) == {MakeRel(f): f \in TotalSurFunc(S, T)} + \* The set of total surjective functions + +RelTotalSurFuncEleOf(S, T) == {f \in Rel(S,T): + /\ IsFunc(f) /\ IsTotal(f,S) /\ IsSurj(f, T)} + \* The set of total surjective functions + \* (Optimized to test if a certain function is a element of this set.) + +RelTotalBijFunc(S, T) == {MakeRel(f): f \in TotalBijFunc(S, T)} +\* The set of total bijective functions + +RelTotalBijFuncEleOf(S, T) == {f \in (SUBSET (S \times T)): + /\ IsFunc(f) /\ IsTotal(f,S) /\ IsInj(f) /\ IsSurj(f, T)} + \* The set of total bijective functions + \* (Optimized to test if a certain function is a element of this set.) + + +RelParFunc(S, T) == {MakeRel(f): f \in ParFunc(S, T)} + \* The set of partial functions + +RelParFuncEleOf(S, T) == {f \in Rel(S, T): IsFunc(f)} + \* The set of partial functions + \* (Optimized to test if a certain function is a element of this set.) + +RelParInjFunc(S, T) == {MakeRel(f): f \in ParInjFunc(S, T)} + \* The set of partial injective functions. + +RelParInjFuncEleOf(S, T) == {f \in Rel(S, T): IsFunc(f) /\ IsInj(f)} + \* The set of partial injective functions + \* (Optimized to test if a certain function is a element of this set.) + +RelParSurFunc(S, T) == {MakeRel(f): f \in ParSurFunc(S, T)} + \* The set of partial surjective functions + +RelParSurFuncEleOf(S, T) == {f \in Rel(S, T): IsFunc(f) /\ IsSurj(f, T)} + \* The set of partial surjective functions. + \* (Optimized to test if a certain function is a element of this set.) + +RelParBijFunc(S, T) == {MakeRel(f): f \in ParBijFunc(S, T)} + \* The set of partial bijective functions + +RelParBijFuncEleOf(S, T) == {f \in Rel(S, T): IsFunc(f) /\ IsSurj(f, T) /\ IsInj(f)} + \* The set of partial bijective functions + \* (Optimized to test if a certain function is a element of this set.) ========================================================================================= \ No newline at end of file diff --git a/src/main/resources/standardModules/Relations.tla b/src/main/resources/standardModules/Relations.tla index 29a7e2f6b9b120ac2c3b43f9202955fc685f749c..80940e60a46e2fdb01cc7fa37eb91972d8b68c8d 100644 --- a/src/main/resources/standardModules/Relations.tla +++ b/src/main/resources/standardModules/Relations.tla @@ -1,92 +1,92 @@ ----------------------------- MODULE Relations ---------------------------- -EXTENDS FiniteSets, Naturals, Sequences, TLC - -Relations(S, T) == SUBSET (S \times T) - \* The set of all relations - -RelDomain(R) == {x[1]: x \in R} - \* The domain of the relation R - -RelRange(R) == {x[2]: x \in R} - \* The range of the relation R - -RelId(S) == {<<x,x>>: x \in S} - \* The identity relation of set S - -RelDomRes(S, R) == {x \in R: x[1] \in S} - \* The restriction on the domain of R for set S - -RelDomSub(S, R) == {x \in R: x[1] \notin S} - \* The subtraction on the domain of R for set S - -RelRanRes(R, S) == {x \in R: x[2] \in S} - \* The restriction on the range of R for set S - -RelRanSub(R, S) == {x \in R: x[2] \notin S} - \* The subtraction on the range of R for set S - -RelInverse(R) == {<<x[2],x[1]>>: x \in R} - \* The reverse relation of R - -RelImage(R, S) =={y[2] :y \in {x \in R: x[1] \in S}} - \* The image of R for set S - -RelOverride(R1, R2) == {x \in R1: x[1] \notin RelDomain(R2)} \cup R2 - \* Overwriting relation R1 with R2 - -RelComposition(R1, R2) == {<<u[1][1],u[2][2]>> : u \in - {x \in RelRanRes(R1, RelDomain(R2)) \times RelDomRes(RelRange(R1) ,R2): - x[1][2] = x[2][1]}} - \* The relational composition of R1 and R2 - -RelDirectProduct(R1, R2) == {<<x, u>> \in RelDomain(R1) \times (RelRange(R1) \times RelRange(R2) ): - /\ <<x,u[1]>> \in R1 - /\ <<x,u[2]>> \in R2} - \* The direct product of relation R1 and R2 - -RelParallelProduct(R1, R2) == {<<a, b>> \in (RelDomain(R1) \times RelDomain(R2)) - \times (RelRange(R1) \times RelRange(R2)) - : <<a[1],b[1]>> \in R1 /\ <<a[2],b[2]>> \in R2 } - \* The parallel product of R1 and R2 - -RelPrj1(S, T) == {<<<<a,b>>, a>> : a \in S, b \in T} - \* The first projection relation - -RelPrj2(S, T) == {<<<<a,b>>, b>> : a \in S, b \in T} - \* The second projection relation - +---------------------------- MODULE Relations ---------------------------- +EXTENDS FiniteSets, Naturals, Sequences, TLC + +Relations(S, T) == SUBSET (S \times T) + \* The set of all relations + +RelDomain(R) == {x[1]: x \in R} + \* The domain of the relation R + +RelRange(R) == {x[2]: x \in R} + \* The range of the relation R + +RelId(S) == {<<x,x>>: x \in S} + \* The identity relation of set S + +RelDomRes(S, R) == {x \in R: x[1] \in S} + \* The restriction on the domain of R for set S + +RelDomSub(S, R) == {x \in R: x[1] \notin S} + \* The subtraction on the domain of R for set S + +RelRanRes(R, S) == {x \in R: x[2] \in S} + \* The restriction on the range of R for set S + +RelRanSub(R, S) == {x \in R: x[2] \notin S} + \* The subtraction on the range of R for set S + +RelInverse(R) == {<<x[2],x[1]>>: x \in R} + \* The reverse relation of R + +RelImage(R, S) =={y[2] :y \in {x \in R: x[1] \in S}} + \* The image of R for set S + +RelOverride(R1, R2) == {x \in R1: x[1] \notin RelDomain(R2)} \cup R2 + \* Overwriting relation R1 with R2 + +RelComposition(R1, R2) == {<<u[1][1],u[2][2]>> : u \in + {x \in RelRanRes(R1, RelDomain(R2)) \times RelDomRes(RelRange(R1) ,R2): + x[1][2] = x[2][1]}} + \* The relational composition of R1 and R2 + +RelDirectProduct(R1, R2) == {<<x, u>> \in RelDomain(R1) \times (RelRange(R1) \times RelRange(R2) ): + /\ <<x,u[1]>> \in R1 + /\ <<x,u[2]>> \in R2} + \* The direct product of relation R1 and R2 + +RelParallelProduct(R1, R2) == {<<a, b>> \in (RelDomain(R1) \times RelDomain(R2)) + \times (RelRange(R1) \times RelRange(R2)) + : <<a[1],b[1]>> \in R1 /\ <<a[2],b[2]>> \in R2 } + \* The parallel product of R1 and R2 + +RelPrj1(S, T) == {<<<<a,b>>, a>> : a \in S, b \in T} + \* The first projection relation + +RelPrj2(S, T) == {<<<<a,b>>, b>> : a \in S, b \in T} + \* The second projection relation + RECURSIVE RelIterate(_,_) RelIterate(R, n) == CASE n < 0 -> Assert(FALSE, "") [] n = 0 -> RelId(RelDomain(R) \cup RelRange(R)) [] n = 1 -> R - [] OTHER -> RelComposition(R,RelIterate(R, n-1)) - \* The relation R iterated n times in relation to the composition operator - -RelClosure1(R) == \* Warshall algorithm from Leslie Lamport's Hyperbook - LET NR == { r[1] : r \in R} \cup { r[2] : r \in R} - RECURSIVE W(_) - W(L) == IF L = {} - THEN R - ELSE LET n == CHOOSE node \in L : TRUE - WM == W(L \ {n}) - IN TLCEval(WM \cup {rs \in NR \times NR : - (<<rs[1],n>> \in WM) \land (<<n, rs[2]>> \in WM)}) - IN W(NR) - \* The transitive closure of R - -RelClosure(R) == RelClosure1( R \cup {<<x[1],x[1]>>: x \in R} \cup RelIterate(R, 0)) - \* The transitive and reflexive closure of R. - -RelFnc(R) == {<<x, RelImage(R, {x})>> :x \in RelDomain(R)} - \* The transformation of R into a function - \* e.g. RelFnc({(0,1), (0,2), (1,1)}) = {(0,{1, 2}), (1, {1})} - -RECURSIVE RelRel(_) -RelRel(Fct) == IF Fct = {} - THEN {} - ELSE LET e == CHOOSE x \in Fct: TRUE - IN {<<e[1], y>>: y \in e[2]} \cup RelRel(Fct\{e}) - \* The transformation of the function Fct into a relation - \* e.g. RelRel({(0,{1, 2}), (1, {1})}) = {(0,1), (0,2), (1,1)}) + [] OTHER -> RelComposition(R,RelIterate(R, n-1)) + \* The relation R iterated n times in relation to the composition operator + +RelClosure1(R) == \* Warshall algorithm from Leslie Lamport's Hyperbook + LET NR == { r[1] : r \in R} \cup { r[2] : r \in R} + RECURSIVE W(_) + W(L) == IF L = {} + THEN R + ELSE LET n == CHOOSE node \in L : TRUE + WM == W(L \ {n}) + IN TLCEval(WM \cup {rs \in NR \times NR : + (<<rs[1],n>> \in WM) \land (<<n, rs[2]>> \in WM)}) + IN W(NR) + \* The transitive closure of R + +RelClosure(R) == RelClosure1( R \cup {<<x[1],x[1]>>: x \in R} \cup RelIterate(R, 0)) + \* The transitive and reflexive closure of R. + +RelFnc(R) == {<<x, RelImage(R, {x})>> :x \in RelDomain(R)} + \* The transformation of R into a function + \* e.g. RelFnc({(0,1), (0,2), (1,1)}) = {(0,{1, 2}), (1, {1})} + +RECURSIVE RelRel(_) +RelRel(Fct) == IF Fct = {} + THEN {} + ELSE LET e == CHOOSE x \in Fct: TRUE + IN {<<e[1], y>>: y \in e[2]} \cup RelRel(Fct\{e}) + \* The transformation of the function Fct into a relation + \* e.g. RelRel({(0,{1, 2}), (1, {1})}) = {(0,1), (0,2), (1,1)}) ============================================================================= - + diff --git a/src/main/resources/standardModules/SequencesExtended.tla b/src/main/resources/standardModules/SequencesExtended.tla index a1c0bcefaccfe7ea3604294a4ef5ed6c64580367..95ed43d9602a2aad2d9c9c404aaad43226d07d67 100644 --- a/src/main/resources/standardModules/SequencesExtended.tla +++ b/src/main/resources/standardModules/SequencesExtended.tla @@ -1,68 +1,68 @@ -------------------------- MODULE SequencesExtended ------------------------- -EXTENDS Naturals, FiniteSets, Sequences, TLC - -LOCAL Range(f) == {f[x] :x \in DOMAIN f} - -Last(s) == s[Len(s)] - \* The last element of the sequence s - -Front(s) == [i \in 1..(Len(s)-1) |-> s[i]] - \* The sequence s without its last element. - -Prepend(e, s) == [i \in 1..(Len(s)+1) |-> IF i = 1 THEN e ELSE s[i-1]] - \* The Sequence obtained by inserting e at the front of sequence s - -Reverse(s) == LET l == Len(s) - IN [i \in 1..l |-> s[l-i+1]] -\* Sequence s in reverse order - -BoundedSeq(S, n) == UNION{[1..x -> S]: x \in 0..n} - \* The set of sequences with maximum length n - -Seq1(S) == Seq(S) \ {<<>>} - \* The set of sequences without the empty sequence - -ISeq(S) == - UNION {{x \in [(1..n) -> S]: Cardinality(Range(x)) = Cardinality(DOMAIN x)} - : n \in 0..Cardinality(S)} - \* The set of injective sequences - -ISeqEleOf(S) == {x \in Seq(S): Len(x) = Cardinality(Range(x)) } - (* The set of injective sequences *) - (* optimized to test if a certain sequence is in this set.*) - -ISeq1(S) == ISeq(S) \ {<<>>} - \* The set of injective sequences without the empty sequence - -ISeq1EleOf(S) == {x \in Seq(S): x # <<>> /\ Len(x) = Cardinality(Range(x)) } - (* The set of injective sequences without the empty sequence*) - (* optimized to test if a certain sequence is in this set. *) - -RECURSIVE Perm(_) -Perm(S) == IF S = {} - THEN {<<>>} - ELSE LET ps == [x \in S |-> {Append(s, x): s \in Perm(S\{x})}] - IN UNION {ps[x]: x \in S} -\* The set of permutations (bijective sequences) - -RECURSIVE Conc(_) -Conc(S) == IF S = <<>> - THEN <<>> - ELSE Head(S) \o Conc(Tail(S)) - (* The sequence obtained by concatenating all sequences *) - (* which are elements of the sequence S. *) - -TakeFirstElements(s, n) == - IF n \in 0..Len(s) - THEN [i \in 1..n |-> s[i]] - ELSE Assert(n \in 0..Cardinality(s), - "The second argument of the take-first-operator is an invalid number.") - \* Taking the first n elements of the sequence s. - -DropFirstElements(s, n) == - IF n \in 0..Len(s) - THEN [i \in 1..(Len(s)-n) |-> s[n + i]] - ELSE Assert(n \in 0..Cardinality(s), - "The second argument of the drop-first-operator is an invalid number.") - \* Dropping the first n elements of the sequence s -============================================================================= +------------------------- MODULE SequencesExtended ------------------------- +EXTENDS Naturals, FiniteSets, Sequences, TLC + +LOCAL Range(f) == {f[x] :x \in DOMAIN f} + +Last(s) == s[Len(s)] + \* The last element of the sequence s + +Front(s) == [i \in 1..(Len(s)-1) |-> s[i]] + \* The sequence s without its last element. + +Prepend(e, s) == [i \in 1..(Len(s)+1) |-> IF i = 1 THEN e ELSE s[i-1]] + \* The Sequence obtained by inserting e at the front of sequence s + +Reverse(s) == LET l == Len(s) + IN [i \in 1..l |-> s[l-i+1]] +\* Sequence s in reverse order + +BoundedSeq(S, n) == UNION{[1..x -> S]: x \in 0..n} + \* The set of sequences with maximum length n + +Seq1(S) == Seq(S) \ {<<>>} + \* The set of sequences without the empty sequence + +ISeq(S) == + UNION {{x \in [(1..n) -> S]: Cardinality(Range(x)) = Cardinality(DOMAIN x)} + : n \in 0..Cardinality(S)} + \* The set of injective sequences + +ISeqEleOf(S) == {x \in Seq(S): Len(x) = Cardinality(Range(x)) } + (* The set of injective sequences *) + (* optimized to test if a certain sequence is in this set.*) + +ISeq1(S) == ISeq(S) \ {<<>>} + \* The set of injective sequences without the empty sequence + +ISeq1EleOf(S) == {x \in Seq(S): x # <<>> /\ Len(x) = Cardinality(Range(x)) } + (* The set of injective sequences without the empty sequence*) + (* optimized to test if a certain sequence is in this set. *) + +RECURSIVE Perm(_) +Perm(S) == IF S = {} + THEN {<<>>} + ELSE LET ps == [x \in S |-> {Append(s, x): s \in Perm(S\{x})}] + IN UNION {ps[x]: x \in S} +\* The set of permutations (bijective sequences) + +RECURSIVE Conc(_) +Conc(S) == IF S = <<>> + THEN <<>> + ELSE Head(S) \o Conc(Tail(S)) + (* The sequence obtained by concatenating all sequences *) + (* which are elements of the sequence S. *) + +TakeFirstElements(s, n) == + IF n \in 0..Len(s) + THEN [i \in 1..n |-> s[i]] + ELSE Assert(n \in 0..Cardinality(s), + "The second argument of the take-first-operator is an invalid number.") + \* Taking the first n elements of the sequence s. + +DropFirstElements(s, n) == + IF n \in 0..Len(s) + THEN [i \in 1..(Len(s)-n) |-> s[n + i]] + ELSE Assert(n \in 0..Cardinality(s), + "The second argument of the drop-first-operator is an invalid number.") + \* Dropping the first n elements of the sequence s +============================================================================= diff --git a/src/test/java/de/tlc4b/analysis/ConstantsEvaluatorTest.java b/src/test/java/de/tlc4b/analysis/ConstantsEvaluatorTest.java index 7ab9fd5dcf4c6f54fb60a04676547b3a6384fa04..f36ca649699f7576764724d1ba2ab718444b1a23 100644 --- a/src/test/java/de/tlc4b/analysis/ConstantsEvaluatorTest.java +++ b/src/test/java/de/tlc4b/analysis/ConstantsEvaluatorTest.java @@ -1,37 +1,37 @@ -package de.tlc4b.analysis; - -import static de.tlc4b.util.TestUtil.compare; - -import org.junit.Test; - -public class ConstantsEvaluatorTest { - - - @Test - public void testConstants() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2 \n" - + "PROPERTIES k = k2 & k2 = 1 \n" + "END"; - - String expected = "---- MODULE test----\n" - + "k2 == 1 \n" - + "k == k2 \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testConstants2() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2, k3 \n" - + "PROPERTIES k = k2 + 1 & k2 = k3 & k3 = 1 \n" + "END"; - - String expected = "---- MODULE test----\n" - + "EXTENDS Naturals\n" - + "k3 == 1 \n" - + "k2 == k3 \n" - + "k == k2 + 1 \n" - + "======"; - compare(expected, machine); - } -} +package de.tlc4b.analysis; + +import static de.tlc4b.util.TestUtil.compare; + +import org.junit.Test; + +public class ConstantsEvaluatorTest { + + + @Test + public void testConstants() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2 \n" + + "PROPERTIES k = k2 & k2 = 1 \n" + "END"; + + String expected = "---- MODULE test----\n" + + "k2 == 1 \n" + + "k == k2 \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testConstants2() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2, k3 \n" + + "PROPERTIES k = k2 + 1 & k2 = k3 & k3 = 1 \n" + "END"; + + String expected = "---- MODULE test----\n" + + "EXTENDS Naturals\n" + + "k3 == 1 \n" + + "k2 == k3 \n" + + "k == k2 + 1 \n" + + "======"; + compare(expected, machine); + } +} diff --git a/src/test/java/de/tlc4b/analysis/ConstantsTest.java b/src/test/java/de/tlc4b/analysis/ConstantsTest.java index 11231b3764f532be4a5e90701236fba955dd80e5..ccd9b9cd60b9d3493400590188e2937e7714aeb2 100644 --- a/src/test/java/de/tlc4b/analysis/ConstantsTest.java +++ b/src/test/java/de/tlc4b/analysis/ConstantsTest.java @@ -1,138 +1,138 @@ -package de.tlc4b.analysis; - - - -import static de.tlc4b.util.TestUtil.compare; - -import org.junit.Ignore; -import org.junit.Test; - -public class ConstantsTest { - - @Test - public void testConstants() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2 \n" - + "PROPERTIES k = 1 & k2 : {k} \n" + "END"; - - String expected = "---- MODULE test----\n" - + "k == 1 \n" - + "VARIABLES k2 \n" - + "Init == k2 \\in {k} \n" - + "Next == 1 = 2 /\\ UNCHANGED <<k2>>\n" - + "======"; - compare(expected, machine); - } - - @Test - public void testSimpleConstant() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = 1 & 1 = 1 \n" + "END"; - - String expected = "---- MODULE test----\n" - + "k == 1 \n" - + "ASSUME 1 = 1\n" - + "======"; - compare(expected, machine); - } - - @Test - public void testConstantMultiplePossipleValues() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k : {1} \n" + "END"; - - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "VARIABLES k \n" - + "Init == k \\in {1} \n" - + "Next == 1 = 2 /\\ UNCHANGED <<k>>\n" - + "======"; - compare(expected, machine); - } - - @Test - public void testConstantOneValues() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = 1 \n" + "END"; - - - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "k == 1 \n" - + "======"; - compare(expected, machine); - } - - @Ignore - @Test - public void testConstantGreaterThan() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k > 1 \n" + "END"; - - String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" - + "k == 2 \n" - + "ASSUME k > 1 \n" - + "======"; - compare(expected, machine); - } - - @Ignore - @Test - public void testConstantGreaterThan2() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES 2 > k \n" + "END"; - - - String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" - + "k == 1 \n" - + "ASSUME 2 > k \n" - + "======"; - compare(expected, machine); - } - - @Ignore - @Test - public void testScalarParameter() throws Exception { - String machine = "MACHINE test(t)\n" - + "CONSTRAINTS t > 2 \n" + "END"; - - String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" - + "t == 3 \n" - + "ASSUME t > 2 \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testConstants2() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS N \n" - + "PROPERTIES N <: NATURAL & N={1,2,3,4}\n" - + "END"; - - String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" - + "N == {1,2,3,4}\n" - + "ASSUME N \\subseteq Nat \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testConstants3() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS n\n" - + "PROPERTIES n <: {1,2,3}\n" - + "END"; - - String expected = "---- MODULE test----\n" - + "VARIABLES n\n" - + "Init == n \\in SUBSET({1, 2, 3})\n" - + "Next == 1 = 2 /\\ UNCHANGED <<n>>\n" - + "======"; - compare(expected, machine); - } - -} +package de.tlc4b.analysis; + + + +import static de.tlc4b.util.TestUtil.compare; + +import org.junit.Ignore; +import org.junit.Test; + +public class ConstantsTest { + + @Test + public void testConstants() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2 \n" + + "PROPERTIES k = 1 & k2 : {k} \n" + "END"; + + String expected = "---- MODULE test----\n" + + "k == 1 \n" + + "VARIABLES k2 \n" + + "Init == k2 \\in {k} \n" + + "Next == 1 = 2 /\\ UNCHANGED <<k2>>\n" + + "======"; + compare(expected, machine); + } + + @Test + public void testSimpleConstant() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = 1 & 1 = 1 \n" + "END"; + + String expected = "---- MODULE test----\n" + + "k == 1 \n" + + "ASSUME 1 = 1\n" + + "======"; + compare(expected, machine); + } + + @Test + public void testConstantMultiplePossipleValues() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k : {1} \n" + "END"; + + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "VARIABLES k \n" + + "Init == k \\in {1} \n" + + "Next == 1 = 2 /\\ UNCHANGED <<k>>\n" + + "======"; + compare(expected, machine); + } + + @Test + public void testConstantOneValues() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = 1 \n" + "END"; + + + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "k == 1 \n" + + "======"; + compare(expected, machine); + } + + @Ignore + @Test + public void testConstantGreaterThan() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k > 1 \n" + "END"; + + String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" + + "k == 2 \n" + + "ASSUME k > 1 \n" + + "======"; + compare(expected, machine); + } + + @Ignore + @Test + public void testConstantGreaterThan2() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES 2 > k \n" + "END"; + + + String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" + + "k == 1 \n" + + "ASSUME 2 > k \n" + + "======"; + compare(expected, machine); + } + + @Ignore + @Test + public void testScalarParameter() throws Exception { + String machine = "MACHINE test(t)\n" + + "CONSTRAINTS t > 2 \n" + "END"; + + String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" + + "t == 3 \n" + + "ASSUME t > 2 \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testConstants2() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS N \n" + + "PROPERTIES N <: NATURAL & N={1,2,3,4}\n" + + "END"; + + String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" + + "N == {1,2,3,4}\n" + + "ASSUME N \\subseteq Nat \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testConstants3() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS n\n" + + "PROPERTIES n <: {1,2,3}\n" + + "END"; + + String expected = "---- MODULE test----\n" + + "VARIABLES n\n" + + "Init == n \\in SUBSET({1, 2, 3})\n" + + "Next == 1 = 2 /\\ UNCHANGED <<n>>\n" + + "======"; + compare(expected, machine); + } + +} diff --git a/src/test/java/de/tlc4b/analysis/DeferredSetSizeTest.java b/src/test/java/de/tlc4b/analysis/DeferredSetSizeTest.java index b83222309c31d06bd25722644eabea0e9d09a166..ebd3193d910182cd768a353f6ae844507e5182fa 100644 --- a/src/test/java/de/tlc4b/analysis/DeferredSetSizeTest.java +++ b/src/test/java/de/tlc4b/analysis/DeferredSetSizeTest.java @@ -1,49 +1,49 @@ -package de.tlc4b.analysis; - -import static de.tlc4b.util.TestUtil.compareModuleAndConfig; - -import org.junit.Test; - -public class DeferredSetSizeTest { - @Test - public void testDeferredSetStandard() throws Exception { - String machine = "MACHINE test\n" - + "SETS S \n" - + "END"; - String expectedModule = "---- MODULE test----\n" - + "CONSTANTS S\n" - + "======"; - String expectedConfig = "CONSTANTS S = {S1, S2, S3} "; - compareModuleAndConfig(expectedModule, expectedConfig, machine); - } - - @Test - public void testDeferredSet() throws Exception { - String machine = "MACHINE test\n" - + "SETS S \n" - + "PROPERTIES card(S) = 4" - + "END"; - String expectedModule = "---- MODULE test----\n" - + "EXTENDS FiniteSets \n" - + "CONSTANTS S\n" - + "ASSUME Cardinality(S) = 4 \n" - + "======"; - String expectedConfig = "CONSTANTS S = {S1, S2, S3, S4} "; - compareModuleAndConfig(expectedModule, expectedConfig, machine); - } - - @Test - public void testDeferredSet2() throws Exception { - String machine = "MACHINE test\n" - + "SETS S \n" - + "PROPERTIES 4 = card(S)" - + "END"; - String expectedModule = "---- MODULE test----\n" - + "EXTENDS FiniteSets \n" - + "CONSTANTS S\n" - + "ASSUME 4 = Cardinality(S) \n" - + "======"; - String expectedConfig = "CONSTANTS S = {S1, S2, S3, S4} "; - compareModuleAndConfig(expectedModule, expectedConfig, machine); - } -} +package de.tlc4b.analysis; + +import static de.tlc4b.util.TestUtil.compareModuleAndConfig; + +import org.junit.Test; + +public class DeferredSetSizeTest { + @Test + public void testDeferredSetStandard() throws Exception { + String machine = "MACHINE test\n" + + "SETS S \n" + + "END"; + String expectedModule = "---- MODULE test----\n" + + "CONSTANTS S\n" + + "======"; + String expectedConfig = "CONSTANTS S = {S1, S2, S3} "; + compareModuleAndConfig(expectedModule, expectedConfig, machine); + } + + @Test + public void testDeferredSet() throws Exception { + String machine = "MACHINE test\n" + + "SETS S \n" + + "PROPERTIES card(S) = 4" + + "END"; + String expectedModule = "---- MODULE test----\n" + + "EXTENDS FiniteSets \n" + + "CONSTANTS S\n" + + "ASSUME Cardinality(S) = 4 \n" + + "======"; + String expectedConfig = "CONSTANTS S = {S1, S2, S3, S4} "; + compareModuleAndConfig(expectedModule, expectedConfig, machine); + } + + @Test + public void testDeferredSet2() throws Exception { + String machine = "MACHINE test\n" + + "SETS S \n" + + "PROPERTIES 4 = card(S)" + + "END"; + String expectedModule = "---- MODULE test----\n" + + "EXTENDS FiniteSets \n" + + "CONSTANTS S\n" + + "ASSUME 4 = Cardinality(S) \n" + + "======"; + String expectedConfig = "CONSTANTS S = {S1, S2, S3, S4} "; + compareModuleAndConfig(expectedModule, expectedConfig, machine); + } +} diff --git a/src/test/java/de/tlc4b/analysis/DefinitionsTest.java b/src/test/java/de/tlc4b/analysis/DefinitionsTest.java index c2c1ceda0384aa1384b5d3eb4f45d6f60e2e9d58..8e70a7282161a8e1b4fb448ac29fbbe823402aea 100644 --- a/src/test/java/de/tlc4b/analysis/DefinitionsTest.java +++ b/src/test/java/de/tlc4b/analysis/DefinitionsTest.java @@ -66,7 +66,7 @@ public class DefinitionsTest { + "END"; String expected = "---- MODULE test----\n" + "VARIABLES x \n" - + "Invariant == x = 1\n" + + "Invariant1 == x = 1\n" + "Init == x = 1\n" + "Next == 1 = 2 /\\ UNCHANGED <<x>>\n" + "======"; diff --git a/src/test/java/de/tlc4b/analysis/ExpressionConstantTest.java b/src/test/java/de/tlc4b/analysis/ExpressionConstantTest.java index 0e18c33e1acd03d18ee0638ba59951cd893ff400..60fd64fdc42ba860e48f9e09c146576d61edc0c1 100644 --- a/src/test/java/de/tlc4b/analysis/ExpressionConstantTest.java +++ b/src/test/java/de/tlc4b/analysis/ExpressionConstantTest.java @@ -1,60 +1,60 @@ -package de.tlc4b.analysis; - -import static de.tlc4b.util.TestUtil.compare; - -import org.junit.Test; - -import de.tlc4b.exceptions.NotSupportedException; - -public class ExpressionConstantTest { - - @Test - public void testAConstantIsconstant() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = 1 & !x.(x = k => 1 = 1)\n" + "END"; - - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "k == 1 \n" - + "ASSUME \\A x \\in {k} : 1 = 1 \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testAConstantIsconstant2() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2 \n" - + "PROPERTIES k = k2 & k2 = 1 \n" + "END"; - - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "k2 == 1 \n" - + "k == k2 \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testBoundedVariable() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES !x.(x = 1 => !y.(y= x => 1 = 1))\n" + "END"; - - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "ASSUME \\A x \\in {1} : \\A y \\in {x} : 1 = 1 \n" - + "======"; - compare(expected, machine); - } - - @Test (expected = NotSupportedException.class) - public void testNotConstantBoundedVariable() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES !x,y.(x = y & y = 1 => 1 = 1)\n" + "END"; - - String expected = "---- MODULE test----\n" - + "EXTENDS Integers \n" - + "ASSUME \\A x \\in Int, y \\in {1} : x = y => 1 = 1 \n" - + "======"; - compare(expected, machine); - } - -} +package de.tlc4b.analysis; + +import static de.tlc4b.util.TestUtil.compare; + +import org.junit.Test; + +import de.tlc4b.exceptions.NotSupportedException; + +public class ExpressionConstantTest { + + @Test + public void testAConstantIsconstant() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = 1 & !x.(x = k => 1 = 1)\n" + "END"; + + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "k == 1 \n" + + "ASSUME \\A x \\in {k} : 1 = 1 \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testAConstantIsconstant2() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2 \n" + + "PROPERTIES k = k2 & k2 = 1 \n" + "END"; + + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "k2 == 1 \n" + + "k == k2 \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testBoundedVariable() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES !x.(x = 1 => !y.(y= x => 1 = 1))\n" + "END"; + + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "ASSUME \\A x \\in {1} : \\A y \\in {x} : 1 = 1 \n" + + "======"; + compare(expected, machine); + } + + @Test (expected = NotSupportedException.class) + public void testNotConstantBoundedVariable() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES !x,y.(x = y & y = 1 => 1 = 1)\n" + "END"; + + String expected = "---- MODULE test----\n" + + "EXTENDS Integers \n" + + "ASSUME \\A x \\in Int, y \\in {1} : x = y => 1 = 1 \n" + + "======"; + compare(expected, machine); + } + +} diff --git a/src/test/java/de/tlc4b/analysis/PrecedenceTest.java b/src/test/java/de/tlc4b/analysis/PrecedenceTest.java index 57892beb9eda2cc6e7b6840163942a913f22b95f..0851024e32801e40317228484ac7631e98a5fc15 100644 --- a/src/test/java/de/tlc4b/analysis/PrecedenceTest.java +++ b/src/test/java/de/tlc4b/analysis/PrecedenceTest.java @@ -1,100 +1,100 @@ -package de.tlc4b.analysis; - -import static de.tlc4b.util.TestUtil.compare; - -import org.junit.Test; - -public class PrecedenceTest { - - @Test - public void testInterval() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k\n" - + "PROPERTIES k = (1..3) * (1..3) \n" - + "END"; - - String expected = "---- MODULE test----\n" - + "EXTENDS Naturals\n" - + "k == (1 .. 3) \\times (1 .. 3)\n" - + "======"; - compare(expected, machine); - } - - @Test - public void testPlusMinus() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES 1 - 2 + 3 = 0 \n" - + "END"; - - String expected = "---- MODULE test----\n" - + "EXTENDS Naturals\n" - + "ASSUME 1 - 2 + 3 = 0 \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testPlusMinus2() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES 1 - (2 + 1) = -2 \n" - + "END"; - - String expected = "---- MODULE test----\n" - + "EXTENDS Integers\n" - + "ASSUME 1 - (2 + 1) = -2 \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testMult() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES 1 * 2 * 3 = 6 \n" - + "END"; - - String expected = "---- MODULE test----\n" - + "EXTENDS Integers\n" - + "ASSUME 1 * 2 * 3 = 6\n" - + "======"; - compare(expected, machine); - } - - @Test - public void testAndOr() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = 1 & 1 = 1 or 1 = 1 \n" - + "END"; - - String expected = "---- MODULE test----\n" - + "EXTENDS Integers\n" - + "ASSUME (1 = 1 /\\ 1 = 1) \\/ 1 = 1 \n" - + "======"; - compare(expected, machine); - } - - - @Test - public void testGreaterThan() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES TRUE = bool(2 > 1)\n" - + "END"; - String expected = "---- MODULE test----\n" - + "EXTENDS Naturals\n" - + "ASSUME TRUE = (2 > 1)\n" - + "======"; - compare(expected, machine); - } - - @Test - public void testNatural1() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {1} = NATURAL - NATURAL1\n" - + "END"; - String expected = "---- MODULE test----\n" - + "EXTENDS Naturals\n" - + "ASSUME {1} = Nat \\ (Nat \\ {0})\n" - + "======"; - compare(expected, machine); - } - -} +package de.tlc4b.analysis; + +import static de.tlc4b.util.TestUtil.compare; + +import org.junit.Test; + +public class PrecedenceTest { + + @Test + public void testInterval() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k\n" + + "PROPERTIES k = (1..3) * (1..3) \n" + + "END"; + + String expected = "---- MODULE test----\n" + + "EXTENDS Naturals\n" + + "k == (1 .. 3) \\times (1 .. 3)\n" + + "======"; + compare(expected, machine); + } + + @Test + public void testPlusMinus() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES 1 - 2 + 3 = 0 \n" + + "END"; + + String expected = "---- MODULE test----\n" + + "EXTENDS Naturals\n" + + "ASSUME 1 - 2 + 3 = 0 \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testPlusMinus2() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES 1 - (2 + 1) = -2 \n" + + "END"; + + String expected = "---- MODULE test----\n" + + "EXTENDS Integers\n" + + "ASSUME 1 - (2 + 1) = -2 \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testMult() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES 1 * 2 * 3 = 6 \n" + + "END"; + + String expected = "---- MODULE test----\n" + + "EXTENDS Integers\n" + + "ASSUME 1 * 2 * 3 = 6\n" + + "======"; + compare(expected, machine); + } + + @Test + public void testAndOr() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = 1 & 1 = 1 or 1 = 1 \n" + + "END"; + + String expected = "---- MODULE test----\n" + + "EXTENDS Integers\n" + + "ASSUME (1 = 1 /\\ 1 = 1) \\/ 1 = 1 \n" + + "======"; + compare(expected, machine); + } + + + @Test + public void testGreaterThan() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES TRUE = bool(2 > 1)\n" + + "END"; + String expected = "---- MODULE test----\n" + + "EXTENDS Naturals\n" + + "ASSUME TRUE = (2 > 1)\n" + + "======"; + compare(expected, machine); + } + + @Test + public void testNatural1() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {1} = NATURAL - NATURAL1\n" + + "END"; + String expected = "---- MODULE test----\n" + + "EXTENDS Naturals\n" + + "ASSUME {1} = Nat \\ (Nat \\ {0})\n" + + "======"; + compare(expected, machine); + } + +} diff --git a/src/test/java/de/tlc4b/analysis/RenamerTest.java b/src/test/java/de/tlc4b/analysis/RenamerTest.java index 40061430d2733f61aa5cdce272dcb96150b927c8..4150660b493346827c938976e0dd5f3606147fb7 100644 --- a/src/test/java/de/tlc4b/analysis/RenamerTest.java +++ b/src/test/java/de/tlc4b/analysis/RenamerTest.java @@ -1,110 +1,110 @@ -package de.tlc4b.analysis; - -import static de.tlc4b.util.TestUtil.*; - -import org.junit.Test; - -public class RenamerTest { - - - @Test - public void testRenameConstant() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS WITH\n" - + "PROPERTIES WITH = 1 \n" + "END"; - String expected = "---- MODULE test ----\n" - + "WITH_1 == 1\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testRenameVariable() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES WITH\n" - + "INVARIANT WITH = 1\n" - + "INITIALISATION WITH := 1 \n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "VARIABLES WITH_1 \n" - + "Invariant1 == WITH_1 = 1\n" - + "Init == WITH_1 = 1 \n\n" - + "Next == 1 = 2 /\\ UNCHANGED <<WITH_1>>\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testRenameOperation() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x\n" - + "INVARIANT x = 1\n" - + "INITIALISATION x := 1 \n" - + "OPERATIONS\n" - + "WITH = x:= 2 \n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "VARIABLES x \n" - + "Invariant1 == x = 1\n" - + "Init == x = 1 \n" - + "WITH_1 == x' = 2\n" - + "Next == WITH_1 \n" - + "===="; - compare(expected, machine); - } - - @Test - public void testRenameDefinition() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES WITH = 1 \n" - + "DEFINITIONS WITH == 1" - + "END"; - - String expected = "---- MODULE test ----\n" - + "ASSUME 1 = 1\n" - + "===="; - compare(expected, machine); - } - - - @Test - public void testDefinitionParameterHasSameNameAsConstant() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS x\n" - + "DEFINITIONS foo(x) == x = 1 " - + "PROPERTIES x = 1 & foo(1) \n" + "END"; - String expected = "---- MODULE test ----\n" - + "x == 1\n" - + "ASSUME 1 = 1\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testBoundedVariableHasSameNameAsConstant() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS x\n" - + "PROPERTIES x = 1 & #x.(x = 1) \n" + "END"; - String expected = "---- MODULE test ----\n" - + "x == 1\n" - + "ASSUME (\\E x_1 \\in {1} : TRUE)\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testBoundedVariableHasSameNameAsElementOfEnumeratedSet() throws Exception { - String machine = "MACHINE test\n" - + "SETS S={aa} \n" - + "PROPERTIES #aa.(aa = 1)\n" + "END"; - String expected = "---- MODULE test ----\n" - + "CONSTANTS aa\n" - + "S == {aa}\n" - + "ASSUME \\E aa_1 \\in {1} : TRUE\n" - + "===="; - compareEquals(expected, machine); - } - -} +package de.tlc4b.analysis; + +import static de.tlc4b.util.TestUtil.*; + +import org.junit.Test; + +public class RenamerTest { + + + @Test + public void testRenameConstant() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS WITH\n" + + "PROPERTIES WITH = 1 \n" + "END"; + String expected = "---- MODULE test ----\n" + + "WITH_1 == 1\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testRenameVariable() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES WITH\n" + + "INVARIANT WITH = 1\n" + + "INITIALISATION WITH := 1 \n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "VARIABLES WITH_1 \n" + + "Invariant1 == WITH_1 = 1\n" + + "Init == WITH_1 = 1 \n\n" + + "Next == 1 = 2 /\\ UNCHANGED <<WITH_1>>\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testRenameOperation() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x\n" + + "INVARIANT x = 1\n" + + "INITIALISATION x := 1 \n" + + "OPERATIONS\n" + + "WITH = x:= 2 \n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "VARIABLES x \n" + + "Invariant1 == x = 1\n" + + "Init == x = 1 \n" + + "WITH_1 == x' = 2\n" + + "Next == WITH_1 \n" + + "===="; + compare(expected, machine); + } + + @Test + public void testRenameDefinition() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES WITH = 1 \n" + + "DEFINITIONS WITH == 1" + + "END"; + + String expected = "---- MODULE test ----\n" + + "ASSUME 1 = 1\n" + + "===="; + compare(expected, machine); + } + + + @Test + public void testDefinitionParameterHasSameNameAsConstant() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS x\n" + + "DEFINITIONS foo(x) == x = 1 " + + "PROPERTIES x = 1 & foo(1) \n" + "END"; + String expected = "---- MODULE test ----\n" + + "x == 1\n" + + "ASSUME 1 = 1\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testBoundedVariableHasSameNameAsConstant() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS x\n" + + "PROPERTIES x = 1 & #x.(x = 1) \n" + "END"; + String expected = "---- MODULE test ----\n" + + "x == 1\n" + + "ASSUME (\\E x_1 \\in {1} : TRUE)\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testBoundedVariableHasSameNameAsElementOfEnumeratedSet() throws Exception { + String machine = "MACHINE test\n" + + "SETS S={aa} \n" + + "PROPERTIES #aa.(aa = 1)\n" + "END"; + String expected = "---- MODULE test ----\n" + + "CONSTANTS aa\n" + + "S == {aa}\n" + + "ASSUME \\E aa_1 \\in {1} : TRUE\n" + + "===="; + compareEquals(expected, machine); + } + +} diff --git a/src/test/java/de/tlc4b/analysis/TypeRestrictionsTest.java b/src/test/java/de/tlc4b/analysis/TypeRestrictionsTest.java index e0c15b1a0bf5648e5f38f6d330ef37cf3de793ad..3c45ca730653f768412f8527cf4af98f26d9f83a 100644 --- a/src/test/java/de/tlc4b/analysis/TypeRestrictionsTest.java +++ b/src/test/java/de/tlc4b/analysis/TypeRestrictionsTest.java @@ -1,270 +1,270 @@ -package de.tlc4b.analysis; - -import static de.tlc4b.util.TestUtil.compare; - -import org.junit.Ignore; -import org.junit.Test; - -public class TypeRestrictionsTest { - @Test - public void testSetComprehensionEquals() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = {x | x = 1}\n" + "END"; - - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "k == {x \\in {1}: x = 1} \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testExistentielQuantification() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES #x.(x = 1 & 1 = 1)\n" + "END"; - - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "ASSUME \\E x \\in {1}: 1 = 1 \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testExistentielQuantification2() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES #x.(x = 1)\n" + "END"; - - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "ASSUME \\E x \\in {1}: TRUE \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testSetComprehensionMemberOf() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = {x | x : {1,2}}\n" + "END"; - String expected = "---- MODULE test----\n" - + "k == {x \\in {1,2}: x \\in {1,2}} \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testSetComprehensionConjunctionEquals() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = {x | x : {1,2} & 1 = 1}\n" + "END"; - String expected = "---- MODULE test----\n" - + "k == {x \\in {1,2}: x \\in {1,2} /\\ 1 = 1} \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testSetComprehensionEquals2Variables() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = {x,y | x : {1,2} & y = 1}\n" + "END"; - - String expected = "---- MODULE test----\n" - + " k == {<<x, y>> \\in ({1, 2} \\times {1}): x \\in {1, 2} /\\ y = 1} \n" - + "======"; - compare(expected, machine); - } - - @Ignore - @Test - public void testExistQuantification2VariablesNotConstant() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES #x,y.(x = 1 & x = y) \n" + "END"; - - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "ASSUME \\E x \\in {1}, y \\in Int: x = y \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testSubsetEq() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES #x.(x <: {1,2,3} & 1 = 1) \n" + "END"; - - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "ASSUME \\E x \\in SUBSET({1, 2, 3}): 1 = 1 \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testExist2VariablesConstant() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = 1 & #x,y.(x = 1 & y = k + 1)\n" + "END"; - - String expected = "---- MODULE test ----\n" + "EXTENDS Integers\n" - + "k == 1 \n" - + "ASSUME \\E x \\in {1}, y \\in {k +1}: TRUE \n" - + "===="; - compare(expected, machine); - } - - @Test - public void testNestedQuantifications() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES #x.(#y.(x = 1 & y = x))\n" + "END"; - - String expected = "---- MODULE test ----\n" + "EXTENDS Integers\n" - + "k == 1 \n" - + "ASSUME \\E x \\in {1} : (\\E y \\in {x} : TRUE) \n" - + "===="; - compare(expected, machine); - } - - @Test - public void testQuantificationsInSetComprehension() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {1} = {x| #y.(x = 1 & y = x) & 1=1}\n" + "END"; - - String expected = "---- MODULE test ----\n" + "EXTENDS Integers\n" - + "k == 1 \n" - + "ASSUME {1} = {x \\in ({1}): (\\E y \\in {x} : TRUE) /\\ 1 = 1}\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testQuantification() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = 1 & !x.(x = k => 1 = 1)\n" + "END"; - - String expected = "---- MODULE test ----\n" + "EXTENDS Integers\n" - + "k == 1 \n" - + "ASSUME \\A x \\in {k} : 1 = 1 \n" - + "===="; - compare(expected, machine); - } - - @Test - public void testConstant() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = 1 & !x.(x = k => 1 = 1)\n" + "END"; - - String expected = "---- MODULE test ----\n" + "EXTENDS Integers\n" - + "k == 1 \n" - + "ASSUME \\A x \\in {k} : 1 = 1 \n" - + "===="; - compare(expected, machine); - } - - @Test - public void testSelectParams() throws Exception { - String machine = "MACHINE test\n" - + "CONSTANTS k\n" - + "PROPERTIES k = 1..4" - + "VARIABLES x\n" - + "INVARIANT x = 1\n" - + "INITIALISATION x := 1\n" - + "OPERATIONS\n" - + "foo(a) = SELECT a : k THEN x:= a END\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "EXTENDS Naturals\n" - + "VARIABLES x \n" - + "k == 1 .. 4\n" - + "Invariant == x = 1\n" - + "Init == x = 1 \n" - + "foo(a) == x' = a\n" - + "Next == \\E a \\in k: foo(a) \n" - + "===="; - compare(expected, machine); - } - - @Test - public void testExist2Restrictions() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES #x.(x = 1 & x = 2)" - + "END"; - - String expected = "---- MODULE test ----\n" - + "ASSUME \\E x \\in {1} \\cap {2} : TRUE\n" - + "===="; - compare(expected, machine); - } - - @Ignore - @Test - public void testExistDependingVariables() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES #x,y.(x = 1 & y = x)" - + "END"; - - String expected = "---- MODULE test ----\n" - + "EXTENDS Integers \n" - + "ASSUME \\E x \\in {1}, y \\in Int : y = x \n" - + "===="; - compare(expected, machine); - } - - @Test - public void testExist3() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES #x.(x = 1 & x = x)" - + "END"; - - String expected = "---- MODULE test ----\n" - + "ASSUME \\E x \\in {1} : x = x \n" - + "===="; - compare(expected, machine); - } - - @Test - public void testPreParams() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x\n" - + "INVARIANT x = 1\n" - + "INITIALISATION x := 1\n" - + "OPERATIONS\n" - + "foo(a) = PRE a = 1 & a = a THEN x:= 3 END\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "VARIABLES x \n" - + "Invariant == x = 1\n" - + "Init == x = 1 \n" - + "foo(a) == (a = a) /\\ x' = 3\n" - + "Next == \\E a \\in {1} : foo(a) \n" - + "===="; - compare(expected, machine); - } - - @Ignore - @Test - public void testCoupleOfParameters() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES #a,b.( (a,b) : {(1,1)})\n" + "END"; - - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "ASSUME \\E <<a,b>> \\in {<<1,1>>} : TRUE \n" - + "======"; - compare(expected, machine); - } - - @Ignore // TODO improve type restriction algorithm - @Test - public void test2Variables() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES #a,b.( a : {1} & b : {a})\n" + "END"; - - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "ASSUME \\E <<a,b>> \\in {<<1,1>>} : TRUE \n" - + "======"; - compare(expected, machine); - } - - -} +package de.tlc4b.analysis; + +import static de.tlc4b.util.TestUtil.compare; + +import org.junit.Ignore; +import org.junit.Test; + +public class TypeRestrictionsTest { + @Test + public void testSetComprehensionEquals() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = {x | x = 1}\n" + "END"; + + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "k == {x \\in {1}: x = 1} \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testExistentielQuantification() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES #x.(x = 1 & 1 = 1)\n" + "END"; + + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "ASSUME \\E x \\in {1}: 1 = 1 \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testExistentielQuantification2() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES #x.(x = 1)\n" + "END"; + + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "ASSUME \\E x \\in {1}: TRUE \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testSetComprehensionMemberOf() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = {x | x : {1,2}}\n" + "END"; + String expected = "---- MODULE test----\n" + + "k == {x \\in {1,2}: x \\in {1,2}} \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testSetComprehensionConjunctionEquals() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = {x | x : {1,2} & 1 = 1}\n" + "END"; + String expected = "---- MODULE test----\n" + + "k == {x \\in {1,2}: x \\in {1,2} /\\ 1 = 1} \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testSetComprehensionEquals2Variables() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = {x,y | x : {1,2} & y = 1}\n" + "END"; + + String expected = "---- MODULE test----\n" + + " k == {<<x, y>> \\in ({1, 2} \\times {1}): x \\in {1, 2} /\\ y = 1} \n" + + "======"; + compare(expected, machine); + } + + @Ignore + @Test + public void testExistQuantification2VariablesNotConstant() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES #x,y.(x = 1 & x = y) \n" + "END"; + + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "ASSUME \\E x \\in {1}, y \\in Int: x = y \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testSubsetEq() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES #x.(x <: {1,2,3} & 1 = 1) \n" + "END"; + + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "ASSUME \\E x \\in SUBSET({1, 2, 3}): 1 = 1 \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testExist2VariablesConstant() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = 1 & #x,y.(x = 1 & y = k + 1)\n" + "END"; + + String expected = "---- MODULE test ----\n" + "EXTENDS Integers\n" + + "k == 1 \n" + + "ASSUME \\E x \\in {1}, y \\in {k +1}: TRUE \n" + + "===="; + compare(expected, machine); + } + + @Test + public void testNestedQuantifications() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES #x.(#y.(x = 1 & y = x))\n" + "END"; + + String expected = "---- MODULE test ----\n" + "EXTENDS Integers\n" + + "k == 1 \n" + + "ASSUME \\E x \\in {1} : (\\E y \\in {x} : TRUE) \n" + + "===="; + compare(expected, machine); + } + + @Test + public void testQuantificationsInSetComprehension() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {1} = {x| #y.(x = 1 & y = x) & 1=1}\n" + "END"; + + String expected = "---- MODULE test ----\n" + "EXTENDS Integers\n" + + "k == 1 \n" + + "ASSUME {1} = {x \\in ({1}): (\\E y \\in {x} : TRUE) /\\ 1 = 1}\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testQuantification() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = 1 & !x.(x = k => 1 = 1)\n" + "END"; + + String expected = "---- MODULE test ----\n" + "EXTENDS Integers\n" + + "k == 1 \n" + + "ASSUME \\A x \\in {k} : 1 = 1 \n" + + "===="; + compare(expected, machine); + } + + @Test + public void testConstant() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = 1 & !x.(x = k => 1 = 1)\n" + "END"; + + String expected = "---- MODULE test ----\n" + "EXTENDS Integers\n" + + "k == 1 \n" + + "ASSUME \\A x \\in {k} : 1 = 1 \n" + + "===="; + compare(expected, machine); + } + + @Test + public void testSelectParams() throws Exception { + String machine = "MACHINE test\n" + + "CONSTANTS k\n" + + "PROPERTIES k = 1..4" + + "VARIABLES x\n" + + "INVARIANT x = 1\n" + + "INITIALISATION x := 1\n" + + "OPERATIONS\n" + + "foo(a) = SELECT a : k THEN x:= a END\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "EXTENDS Naturals\n" + + "VARIABLES x \n" + + "k == 1 .. 4\n" + + "Invariant1 == x = 1\n" + + "Init == x = 1 \n" + + "foo(a) == x' = a\n" + + "Next == \\E a \\in k: foo(a) \n" + + "===="; + compare(expected, machine); + } + + @Test + public void testExist2Restrictions() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES #x.(x = 1 & x = 2)" + + "END"; + + String expected = "---- MODULE test ----\n" + + "ASSUME \\E x \\in {1} \\cap {2} : TRUE\n" + + "===="; + compare(expected, machine); + } + + @Ignore + @Test + public void testExistDependingVariables() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES #x,y.(x = 1 & y = x)" + + "END"; + + String expected = "---- MODULE test ----\n" + + "EXTENDS Integers \n" + + "ASSUME \\E x \\in {1}, y \\in Int : y = x \n" + + "===="; + compare(expected, machine); + } + + @Test + public void testExist3() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES #x.(x = 1 & x = x)" + + "END"; + + String expected = "---- MODULE test ----\n" + + "ASSUME \\E x \\in {1} : x = x \n" + + "===="; + compare(expected, machine); + } + + @Test + public void testPreParams() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x\n" + + "INVARIANT x = 1\n" + + "INITIALISATION x := 1\n" + + "OPERATIONS\n" + + "foo(a) = PRE a = 1 & a = a THEN x:= 3 END\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "VARIABLES x \n" + + "Invariant1 == x = 1\n" + + "Init == x = 1 \n" + + "foo(a) == (a = a) /\\ x' = 3\n" + + "Next == \\E a \\in {1} : foo(a) \n" + + "===="; + compare(expected, machine); + } + + @Ignore + @Test + public void testCoupleOfParameters() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES #a,b.( (a,b) : {(1,1)})\n" + "END"; + + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "ASSUME \\E <<a,b>> \\in {<<1,1>>} : TRUE \n" + + "======"; + compare(expected, machine); + } + + @Ignore // TODO improve type restriction algorithm + @Test + public void test2Variables() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES #a,b.( a : {1} & b : {a})\n" + "END"; + + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "ASSUME \\E <<a,b>> \\in {<<1,1>>} : TRUE \n" + + "======"; + compare(expected, machine); + } + + +} diff --git a/src/test/java/de/tlc4b/ltl/LTLFormulaTest.java b/src/test/java/de/tlc4b/ltl/LTLFormulaTest.java index 235e4456042a51012adec5b317308b55ed26bb03..8e4ead8e8d8ce6ff24aafb03f723f86f6a9b72e2 100644 --- a/src/test/java/de/tlc4b/ltl/LTLFormulaTest.java +++ b/src/test/java/de/tlc4b/ltl/LTLFormulaTest.java @@ -182,7 +182,7 @@ public class LTLFormulaTest { String machine = "MACHINE test\n" + "OPERATIONS foo = skip; bar = skip; bazz = skip\n" + "END"; - String expected = "((ENABLED(foo) => \\neg(ENABLED(bar) \\/ ENABLED(bazz))) /\\ (ENABLED(bar) => \\neg(ENABLED(bazz))))"; + String expected = "((ENABLED(foo) => \\neg(ENABLED(bar) \\/ ENABLED(bazz))) /\\ (ENABLED(bar) => \\neg(ENABLED(bazz))))"; compareLTLFormula(expected, machine, "deterministic(foo,bar,bazz)"); } @@ -192,7 +192,7 @@ public class LTLFormulaTest { String machine = "MACHINE test\n" + "OPERATIONS foo = skip; bar = skip; bazz = skip\n" + "END"; - String expected = "(ENABLED(foo) => \\neg(ENABLED(bar) \\/ ENABLED(bazz)))"; + String expected = "(ENABLED(foo) => \\neg(ENABLED(bar) \\/ ENABLED(bazz)))"; compareLTLFormula(expected, machine, "deterministic(foo)"); } @@ -201,7 +201,7 @@ public class LTLFormulaTest { String machine = "MACHINE test\n" + "OPERATIONS foo = skip; bar = skip; bazz = skip\n" + "END"; - String expected = "\\neg(ENABLED(Next))"; + String expected = "\\neg(ENABLED(Next))"; compareLTLFormula(expected, machine, "deadlock"); } @@ -210,7 +210,7 @@ public class LTLFormulaTest { String machine = "MACHINE test\n" + "OPERATIONS foo(a) = SELECT a : 1..3 THEN skip END\n" + "END"; - String expected = "\\neg(ENABLED(Next))"; + String expected = "\\neg(ENABLED(Next))"; compareLTLFormula(expected, machine, "deadlock"); } diff --git a/src/test/java/de/tlc4b/prettyprint/ArithmeticTest.java b/src/test/java/de/tlc4b/prettyprint/ArithmeticTest.java index 961ad750f281b348837d57e690b795aad4083ad5..61c1ce3048f81c68da122ca61f4347e2af752639 100644 --- a/src/test/java/de/tlc4b/prettyprint/ArithmeticTest.java +++ b/src/test/java/de/tlc4b/prettyprint/ArithmeticTest.java @@ -1,166 +1,166 @@ -package de.tlc4b.prettyprint; - -/** - * Test of arithmetic operators. - * Modulo and Division are not tested here because their translation is defined in the module BBuiltins - * and they are only tested via integration tests. - */ -import static de.tlc4b.util.TestUtil.compare; - -import org.junit.Test; - -public class ArithmeticTest { - - @Test - public void testInteger() throws Exception { - String machine = "MACHINE test\n" + "PROPERTIES INTEGER = INTEGER\n" - + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "ASSUME Int = Int\n" + "======"; - compare(expected, machine); - } - - @Test - public void testNatural() throws Exception { - String machine = "MACHINE test\n" + "PROPERTIES NATURAL = NATURAL\n" - + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" - + "ASSUME Nat = Nat\n" + "======"; - compare(expected, machine); - } - - @Test - public void testNatural1() throws Exception { - String machine = "MACHINE test\n" + "PROPERTIES NATURAL1 = NATURAL1\n" - + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" - + "ASSUME Nat \\ {0} = Nat \\ {0}\n" + "======"; - compare(expected, machine); - } - - @Test - public void testInt() throws Exception { - String machine = "MACHINE test\n" + "PROPERTIES INT = INT\n" + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "ASSUME (-1..3) = (-1..3)\n" + "======"; - compare(expected, machine); - } - - @Test - public void testNat() throws Exception { - String machine = "MACHINE test\n" + "PROPERTIES NAT = NAT\n" + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" - + "ASSUME (0..3) = (0..3)\n" + "======"; - compare(expected, machine); - } - - @Test - public void testNat1() throws Exception { - String machine = "MACHINE test\n" + "PROPERTIES NAT1 = NAT1\n" + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" - + "ASSUME (1..3) = (1..3)\n" + "======"; - compare(expected, machine); - } - - @Test - public void testInterval() throws Exception { - String machine = "MACHINE test\n" + "PROPERTIES {1,2,3} = 1..3\n" - + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" - + "ASSUME {1,2,3} = 1..3\n" + "======"; - compare(expected, machine); - } - - @Test - public void testGreaterThan() throws Exception { - String machine = "MACHINE test\n" + "PROPERTIES 2 > 1\n" + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" - + "ASSUME 2 > 1\n" + "======"; - compare(expected, machine); - } - - @Test - public void testLessThan() throws Exception { - String machine = "MACHINE test\n" + "PROPERTIES 1 < 2\n" + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" - + "ASSUME 1 < 2\n" + "======"; - compare(expected, machine); - } - - @Test - public void testGreaterThanEquals() throws Exception { - String machine = "MACHINE test\n" + "PROPERTIES 1 >= 2\n" + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" - + "ASSUME 1 >= 2\n" + "======"; - compare(expected, machine); - } - - @Test - public void testLessThanEquals() throws Exception { - String machine = "MACHINE test\n" + "PROPERTIES 1 <= 2\n" + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" - + "ASSUME 1 =< 2\n" + "======"; - compare(expected, machine); - } - - @Test - public void testAdd() throws Exception { - String machine = "MACHINE test\n" + "PROPERTIES 2 = 1 + 1\n" + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Naturals \n" - + "ASSUME 2 = 1 + 1 \n" + "======"; - compare(expected, machine); - } - - @Test - public void testMinus() throws Exception { - String machine = "MACHINE test\n" + "PROPERTIES 1 = 2 - 1\n" + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Naturals \n" - + "ASSUME 1 = 2 - 1 \n" + "======"; - compare(expected, machine); - } - - @Test - public void testMult() throws Exception { - String machine = "MACHINE test\n" + "PROPERTIES 1 = 1 * 1\n" + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Naturals \n" - + "ASSUME 1 = 1 * 1 \n" + "======"; - compare(expected, machine); - } - - - @Test - public void testUnaryMinus() throws Exception { - String machine = "MACHINE test\n" + "PROPERTIES -1 = 1 \n" + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "ASSUME -1 = 1\n" + "======"; - compare(expected, machine); - } - - @Test - public void testMinInt() throws Exception { - String machine = "MACHINE test\n" + "PROPERTIES MININT = MININT \n" - + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "ASSUME -1 = -1\n" + "======"; - compare(expected, machine); - } - - @Test - public void testMaxInt() throws Exception { - String machine = "MACHINE test\n" + "PROPERTIES MAXINT = MAXINT \n" - + "END"; - String expected = "---- MODULE test----\n" + "ASSUME 3 = 3\n" - + "======"; - compare(expected, machine); - } - - @Test - public void testSetComprehensionInt() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {x| 1=1 => x = 1} = {} \n" + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "ASSUME {x \\in (Int): 1 = 1 => x = 1} = {}\n" + "======"; - compare(expected, machine); - } - -} +package de.tlc4b.prettyprint; + +/** + * Test of arithmetic operators. + * Modulo and Division are not tested here because their translation is defined in the module BBuiltins + * and they are only tested via integration tests. + */ +import static de.tlc4b.util.TestUtil.compare; + +import org.junit.Test; + +public class ArithmeticTest { + + @Test + public void testInteger() throws Exception { + String machine = "MACHINE test\n" + "PROPERTIES INTEGER = INTEGER\n" + + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "ASSUME Int = Int\n" + "======"; + compare(expected, machine); + } + + @Test + public void testNatural() throws Exception { + String machine = "MACHINE test\n" + "PROPERTIES NATURAL = NATURAL\n" + + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" + + "ASSUME Nat = Nat\n" + "======"; + compare(expected, machine); + } + + @Test + public void testNatural1() throws Exception { + String machine = "MACHINE test\n" + "PROPERTIES NATURAL1 = NATURAL1\n" + + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" + + "ASSUME Nat \\ {0} = Nat \\ {0}\n" + "======"; + compare(expected, machine); + } + + @Test + public void testInt() throws Exception { + String machine = "MACHINE test\n" + "PROPERTIES INT = INT\n" + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "ASSUME (-1..3) = (-1..3)\n" + "======"; + compare(expected, machine); + } + + @Test + public void testNat() throws Exception { + String machine = "MACHINE test\n" + "PROPERTIES NAT = NAT\n" + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" + + "ASSUME (0..3) = (0..3)\n" + "======"; + compare(expected, machine); + } + + @Test + public void testNat1() throws Exception { + String machine = "MACHINE test\n" + "PROPERTIES NAT1 = NAT1\n" + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" + + "ASSUME (1..3) = (1..3)\n" + "======"; + compare(expected, machine); + } + + @Test + public void testInterval() throws Exception { + String machine = "MACHINE test\n" + "PROPERTIES {1,2,3} = 1..3\n" + + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" + + "ASSUME {1,2,3} = 1..3\n" + "======"; + compare(expected, machine); + } + + @Test + public void testGreaterThan() throws Exception { + String machine = "MACHINE test\n" + "PROPERTIES 2 > 1\n" + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" + + "ASSUME 2 > 1\n" + "======"; + compare(expected, machine); + } + + @Test + public void testLessThan() throws Exception { + String machine = "MACHINE test\n" + "PROPERTIES 1 < 2\n" + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" + + "ASSUME 1 < 2\n" + "======"; + compare(expected, machine); + } + + @Test + public void testGreaterThanEquals() throws Exception { + String machine = "MACHINE test\n" + "PROPERTIES 1 >= 2\n" + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" + + "ASSUME 1 >= 2\n" + "======"; + compare(expected, machine); + } + + @Test + public void testLessThanEquals() throws Exception { + String machine = "MACHINE test\n" + "PROPERTIES 1 <= 2\n" + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Naturals\n" + + "ASSUME 1 =< 2\n" + "======"; + compare(expected, machine); + } + + @Test + public void testAdd() throws Exception { + String machine = "MACHINE test\n" + "PROPERTIES 2 = 1 + 1\n" + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Naturals \n" + + "ASSUME 2 = 1 + 1 \n" + "======"; + compare(expected, machine); + } + + @Test + public void testMinus() throws Exception { + String machine = "MACHINE test\n" + "PROPERTIES 1 = 2 - 1\n" + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Naturals \n" + + "ASSUME 1 = 2 - 1 \n" + "======"; + compare(expected, machine); + } + + @Test + public void testMult() throws Exception { + String machine = "MACHINE test\n" + "PROPERTIES 1 = 1 * 1\n" + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Naturals \n" + + "ASSUME 1 = 1 * 1 \n" + "======"; + compare(expected, machine); + } + + + @Test + public void testUnaryMinus() throws Exception { + String machine = "MACHINE test\n" + "PROPERTIES -1 = 1 \n" + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "ASSUME -1 = 1\n" + "======"; + compare(expected, machine); + } + + @Test + public void testMinInt() throws Exception { + String machine = "MACHINE test\n" + "PROPERTIES MININT = MININT \n" + + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "ASSUME -1 = -1\n" + "======"; + compare(expected, machine); + } + + @Test + public void testMaxInt() throws Exception { + String machine = "MACHINE test\n" + "PROPERTIES MAXINT = MAXINT \n" + + "END"; + String expected = "---- MODULE test----\n" + "ASSUME 3 = 3\n" + + "======"; + compare(expected, machine); + } + + @Test + public void testSetComprehensionInt() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {x| 1=1 => x = 1} = {} \n" + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "ASSUME {x \\in (Int): 1 = 1 => x = 1} = {}\n" + "======"; + compare(expected, machine); + } + +} diff --git a/src/test/java/de/tlc4b/prettyprint/ClausesTest.java b/src/test/java/de/tlc4b/prettyprint/ClausesTest.java index 895d7a6e964cb591a9108e653cfb53bd2612cf29..f9d7a20a1ac1be3c57cf4809473854d002594b0f 100644 --- a/src/test/java/de/tlc4b/prettyprint/ClausesTest.java +++ b/src/test/java/de/tlc4b/prettyprint/ClausesTest.java @@ -1,57 +1,57 @@ -package de.tlc4b.prettyprint; - -import static de.tlc4b.util.TestUtil.compare; - -import org.junit.Test; - -public class ClausesTest { - - - @Test - public void testAssertion() throws Exception { - String machine = "MACHINE test\n" - + "ASSERTIONS 1 = 1\n" - + "END"; - String expected = "---- MODULE test ----\n" - + "ASSUME Assertion1 == 1 = 1\n" - + "======"; - compare(expected, machine); - } - - @Test - public void testAssertion2() throws Exception { - String machine = "MACHINE test\n" - + "ASSERTIONS 1 = 1; 2 = 2\n" - + "END"; - String expected = "---- MODULE test ----\n" - + "ASSUME Assertion1 == 1 = 1\n" - + "ASSUME Assertion2 == 2 = 2\n" - + "======"; - compare(expected, machine); - } - - @Test - public void testAbstractConstants() throws Exception { - String machine = "MACHINE test\n" - + "ABSTRACT_CONSTANTS k\n" - + "PROPERTIES k = 1\n" - + "END"; - String expected = "---- MODULE test ----\n" - + "k == 1 " - + "======"; - compare(expected, machine); - } - - @Test - public void testConcreteConstants() throws Exception { - String machine = "MACHINE test\n" - + "CONCRETE_CONSTANTS k\n" - + "PROPERTIES k = 1\n" - + "END"; - String expected = "---- MODULE test ----\n" - + "k == 1 " - + "======"; - compare(expected, machine); - } - -} +package de.tlc4b.prettyprint; + +import static de.tlc4b.util.TestUtil.compare; + +import org.junit.Test; + +public class ClausesTest { + + + @Test + public void testAssertion() throws Exception { + String machine = "MACHINE test\n" + + "ASSERTIONS 1 = 1\n" + + "END"; + String expected = "---- MODULE test ----\n" + + "ASSUME Assertion1 == 1 = 1\n" + + "======"; + compare(expected, machine); + } + + @Test + public void testAssertion2() throws Exception { + String machine = "MACHINE test\n" + + "ASSERTIONS 1 = 1; 2 = 2\n" + + "END"; + String expected = "---- MODULE test ----\n" + + "ASSUME Assertion1 == 1 = 1\n" + + "ASSUME Assertion2 == 2 = 2\n" + + "======"; + compare(expected, machine); + } + + @Test + public void testAbstractConstants() throws Exception { + String machine = "MACHINE test\n" + + "ABSTRACT_CONSTANTS k\n" + + "PROPERTIES k = 1\n" + + "END"; + String expected = "---- MODULE test ----\n" + + "k == 1 " + + "======"; + compare(expected, machine); + } + + @Test + public void testConcreteConstants() throws Exception { + String machine = "MACHINE test\n" + + "CONCRETE_CONSTANTS k\n" + + "PROPERTIES k = 1\n" + + "END"; + String expected = "---- MODULE test ----\n" + + "k == 1 " + + "======"; + compare(expected, machine); + } + +} diff --git a/src/test/java/de/tlc4b/prettyprint/DataTypesTest.java b/src/test/java/de/tlc4b/prettyprint/DataTypesTest.java index 482419a0ae5df436ccbccebb0cf73cf0abd16151..e09c7b52b20afd5a212c297cd77d991caaffc581 100644 --- a/src/test/java/de/tlc4b/prettyprint/DataTypesTest.java +++ b/src/test/java/de/tlc4b/prettyprint/DataTypesTest.java @@ -1,46 +1,46 @@ -package de.tlc4b.prettyprint; - -import static de.tlc4b.util.TestUtil.compare; - -import org.junit.Test; - -public class DataTypesTest { - - @Test - public void testString() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES \"abc\" = \"abc\" " - + "END"; - - String expected = "---- MODULE test----\n" - + "ASSUME \"abc\" = \"abc\" \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testPair() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES (3,4) = (3,4) \n" - + "END"; - - String expected = "---- MODULE test----\n" - + "ASSUME <<3, 4>> = <<3, 4>> \n" - + "======"; - compare(expected, machine); - } - - - @Test - public void testSequence() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES [3,4] = [3,4] \n" - + "END"; - - String expected = "---- MODULE test----\n" - + "ASSUME <<3, 4>> = <<3, 4>> \n" - + "======"; - compare(expected, machine); - } - -} +package de.tlc4b.prettyprint; + +import static de.tlc4b.util.TestUtil.compare; + +import org.junit.Test; + +public class DataTypesTest { + + @Test + public void testString() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES \"abc\" = \"abc\" " + + "END"; + + String expected = "---- MODULE test----\n" + + "ASSUME \"abc\" = \"abc\" \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testPair() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES (3,4) = (3,4) \n" + + "END"; + + String expected = "---- MODULE test----\n" + + "ASSUME <<3, 4>> = <<3, 4>> \n" + + "======"; + compare(expected, machine); + } + + + @Test + public void testSequence() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES [3,4] = [3,4] \n" + + "END"; + + String expected = "---- MODULE test----\n" + + "ASSUME <<3, 4>> = <<3, 4>> \n" + + "======"; + compare(expected, machine); + } + +} diff --git a/src/test/java/de/tlc4b/prettyprint/EnumeratedSetsTest.java b/src/test/java/de/tlc4b/prettyprint/EnumeratedSetsTest.java index 4a3e57327ccd597a123e7b05e5155272042c3daa..f610ead1fccd087b10f4b04e8edf232755d8222d 100644 --- a/src/test/java/de/tlc4b/prettyprint/EnumeratedSetsTest.java +++ b/src/test/java/de/tlc4b/prettyprint/EnumeratedSetsTest.java @@ -1,22 +1,22 @@ -package de.tlc4b.prettyprint; - -import static de.tlc4b.util.TestUtil.*; - -import org.junit.Test; - -public class EnumeratedSetsTest { - @Test - public void testTwoEnumeratedSets() throws Exception { - String machine = "MACHINE test\n" - + "SETS set = {a,b,c}; set2 = {d}\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "CONSTANTS a, b, c, d\n" - + "set == {a, b, c}\n" - + "set2 == {d}\n" - + "===="; - final String config = "CONSTANTS\na = a\nb = b\nc = c\nd = d\n"; - compareEqualsConfig(expected, config, machine); - } -} +package de.tlc4b.prettyprint; + +import static de.tlc4b.util.TestUtil.*; + +import org.junit.Test; + +public class EnumeratedSetsTest { + @Test + public void testTwoEnumeratedSets() throws Exception { + String machine = "MACHINE test\n" + + "SETS set = {a,b,c}; set2 = {d}\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "CONSTANTS a, b, c, d\n" + + "set == {a, b, c}\n" + + "set2 == {d}\n" + + "===="; + final String config = "CONSTANTS\na = a\nb = b\nc = c\nd = d\n"; + compareEqualsConfig(expected, config, machine); + } +} diff --git a/src/test/java/de/tlc4b/prettyprint/FunctionTest.java b/src/test/java/de/tlc4b/prettyprint/FunctionTest.java index b3cfc02a8c6b2ac6f864d0b1e364a1c1370b270e..f191f7bb19c380a3b33cb287b64628c2801a7c88 100644 --- a/src/test/java/de/tlc4b/prettyprint/FunctionTest.java +++ b/src/test/java/de/tlc4b/prettyprint/FunctionTest.java @@ -1,115 +1,115 @@ -package de.tlc4b.prettyprint; - -import static de.tlc4b.util.TestUtil.*; - -import org.junit.Test; - - - -public class FunctionTest { - - @Test - public void testLambdaAbstraction() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES [1] = %x.(x = 1 | 1)\n" - + "END"; - String expected = "---- MODULE test----\n" - + "EXTENDS Integers\n" - + "ASSUME <<1>> = [x \\in {1} |-> 1 ]\n" - + "======"; - compare(expected, machine); - } - - @Test - public void testLambdaAbstraction2() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES [1] = %x.(x = 1 & 1 = 1| 1)\n" - + "END"; - String expected = "---- MODULE test----\n" - + "EXTENDS Integers\n" - + "ASSUME <<1>> = [x \\in {x \\in {1}: 1=1} |-> 1 ]\n" - + "======"; - compare(expected, machine); - } - - @Test - public void testFunctionApplication() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = %x.(x = 1 | 1)(1)\n" - + "END"; - String expected = "---- MODULE test----\n" - + "ASSUME 1 = [x \\in {1} |-> 1 ][1]\n" - + "======"; - compare(expected, machine); - } - - @Test - public void testFunctionApplicationMoreArguments() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES 4 = %a,b.(a=b | a+b)(2,2)\n" - + "END"; - String expected = "---- MODULE test ----\n" - + "EXTENDS Integers\n" - + "ASSUME 4 = [<<a, b>> \\in { <<a, b>> \\in ((Int) \\times (Int)) : a = b} |-> a + b][2, 2]\n" - + "===="; - compare(expected, machine); - } - - - @Test - public void testFunctionVsRelation2() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {(1|->2|->3)} = %a,b.(a = b | a+b)\n" - + "END"; - String expected = "---- MODULE test ----\n" - + "EXTENDS Integers, TLC\n" - + "ASSUME (<<1, 2>>:>3) = [<<a, b>> \\in {<<a, b>> \\in ((Int) \\times (Int)) : a = b} |-> a + b] \n" - + "===="; - compare(expected, machine); - } - - @Test - public void testDomain() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {1} = dom(%x.(x = 1 | 1))\n" - + "END"; - String expected = "---- MODULE test----\n" - + "ASSUME {1} = DOMAIN [x \\in {1} |-> 1 ]\n" - + "======"; - compare(expected, machine); - } - - @Test - public void testSequenceFunctionCall() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES [1,2](1) = 1\n" - + "END"; - String expected = "---- MODULE test----\n" - + "ASSUME <<1, 2>>[1] = 1\n" - + "======"; - compare(expected, machine); - } - - @Test - public void testTotalFunction() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {1} --> {1} = {1} --> {1}\n" + "END"; - String expected = "---- MODULE test ----\n" - + "ASSUME [{1} -> {1}] = [{1} -> {1}]\n" - + "===="; - compareEquals(expected, machine); - } - - - @Test - public void testPartialFunction() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {} = {1,2} +-> {1,2}\n" + "END"; - String expected = "---- MODULE test ----\n" - + "EXTENDS Functions\n" - + "ASSUME {} = ParFunc({1, 2}, {1, 2})\n" - + "===="; - compareEquals(expected, machine); - } - -} +package de.tlc4b.prettyprint; + +import static de.tlc4b.util.TestUtil.*; + +import org.junit.Test; + + + +public class FunctionTest { + + @Test + public void testLambdaAbstraction() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES [1] = %x.(x = 1 | 1)\n" + + "END"; + String expected = "---- MODULE test----\n" + + "EXTENDS Integers\n" + + "ASSUME <<1>> = [x \\in {1} |-> 1 ]\n" + + "======"; + compare(expected, machine); + } + + @Test + public void testLambdaAbstraction2() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES [1] = %x.(x = 1 & 1 = 1| 1)\n" + + "END"; + String expected = "---- MODULE test----\n" + + "EXTENDS Integers\n" + + "ASSUME <<1>> = [x \\in {x \\in {1}: 1=1} |-> 1 ]\n" + + "======"; + compare(expected, machine); + } + + @Test + public void testFunctionApplication() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = %x.(x = 1 | 1)(1)\n" + + "END"; + String expected = "---- MODULE test----\n" + + "ASSUME 1 = [x \\in {1} |-> 1 ][1]\n" + + "======"; + compare(expected, machine); + } + + @Test + public void testFunctionApplicationMoreArguments() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES 4 = %a,b.(a=b | a+b)(2,2)\n" + + "END"; + String expected = "---- MODULE test ----\n" + + "EXTENDS Integers\n" + + "ASSUME 4 = [<<a, b>> \\in { <<a, b>> \\in ((Int) \\times (Int)) : a = b} |-> a + b][2, 2]\n" + + "===="; + compare(expected, machine); + } + + + @Test + public void testFunctionVsRelation2() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {(1|->2|->3)} = %a,b.(a = b | a+b)\n" + + "END"; + String expected = "---- MODULE test ----\n" + + "EXTENDS Integers, TLC\n" + + "ASSUME (<<1, 2>>:>3) = [<<a, b>> \\in {<<a, b>> \\in ((Int) \\times (Int)) : a = b} |-> a + b] \n" + + "===="; + compare(expected, machine); + } + + @Test + public void testDomain() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {1} = dom(%x.(x = 1 | 1))\n" + + "END"; + String expected = "---- MODULE test----\n" + + "ASSUME {1} = DOMAIN [x \\in {1} |-> 1 ]\n" + + "======"; + compare(expected, machine); + } + + @Test + public void testSequenceFunctionCall() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES [1,2](1) = 1\n" + + "END"; + String expected = "---- MODULE test----\n" + + "ASSUME <<1, 2>>[1] = 1\n" + + "======"; + compare(expected, machine); + } + + @Test + public void testTotalFunction() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {1} --> {1} = {1} --> {1}\n" + "END"; + String expected = "---- MODULE test ----\n" + + "ASSUME [{1} -> {1}] = [{1} -> {1}]\n" + + "===="; + compareEquals(expected, machine); + } + + + @Test + public void testPartialFunction() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {} = {1,2} +-> {1,2}\n" + "END"; + String expected = "---- MODULE test ----\n" + + "EXTENDS Functions\n" + + "ASSUME {} = ParFunc({1, 2}, {1, 2})\n" + + "===="; + compareEquals(expected, machine); + } + +} diff --git a/src/test/java/de/tlc4b/prettyprint/LogicalPredicates.java b/src/test/java/de/tlc4b/prettyprint/LogicalPredicates.java index 7708162c49f7de444e4872d09625dc3f6fb9a3f0..9048a78815cac42393c916a39095465151f4ced3 100644 --- a/src/test/java/de/tlc4b/prettyprint/LogicalPredicates.java +++ b/src/test/java/de/tlc4b/prettyprint/LogicalPredicates.java @@ -1,54 +1,54 @@ -package de.tlc4b.prettyprint; - -import static de.tlc4b.util.TestUtil.compare; - -import org.junit.Test; - -public class LogicalPredicates { - - @Test - public void testEquals() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = 1" + "END"; - - String expected = "---- MODULE test----\n" - + "ASSUME 1 = 1 \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testConvert() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES TRUE = bool(1=1)" + "END"; - - String expected = "---- MODULE test----\n" - + "ASSUME TRUE = (1=1) \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testNotEquals() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES 1 /= 1" + "END"; - - String expected = "---- MODULE test----\n" - + "ASSUME 1 # 1 \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testImplication() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = 1 => 1 = 1 \n" - + "END"; - - String expected = "---- MODULE test----\n" - + "ASSUME 1 = 1 => 1 = 1 \n" - + "======"; - compare(expected, machine); - } - -} +package de.tlc4b.prettyprint; + +import static de.tlc4b.util.TestUtil.compare; + +import org.junit.Test; + +public class LogicalPredicates { + + @Test + public void testEquals() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = 1" + "END"; + + String expected = "---- MODULE test----\n" + + "ASSUME 1 = 1 \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testConvert() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES TRUE = bool(1=1)" + "END"; + + String expected = "---- MODULE test----\n" + + "ASSUME TRUE = (1=1) \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testNotEquals() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES 1 /= 1" + "END"; + + String expected = "---- MODULE test----\n" + + "ASSUME 1 # 1 \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testImplication() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = 1 => 1 = 1 \n" + + "END"; + + String expected = "---- MODULE test----\n" + + "ASSUME 1 = 1 => 1 = 1 \n" + + "======"; + compare(expected, machine); + } + +} diff --git a/src/test/java/de/tlc4b/prettyprint/MachineParameterTest.java b/src/test/java/de/tlc4b/prettyprint/MachineParameterTest.java index c26f8ceadf80386dd5db1b028bf9d5b225d8d70c..2ee04a8252b9371af16bb1eefc7bcc9580acb020 100644 --- a/src/test/java/de/tlc4b/prettyprint/MachineParameterTest.java +++ b/src/test/java/de/tlc4b/prettyprint/MachineParameterTest.java @@ -1,76 +1,76 @@ -package de.tlc4b.prettyprint; - -import static de.tlc4b.util.TestUtil.*; - -import org.junit.Test; - -public class MachineParameterTest { - - @Test - public void testScalarParameterToConstant() throws Exception { - String machine = "MACHINE test(a)\n" - + "CONSTRAINTS a = 1\n" - + "END"; - - String expected = "---- MODULE test----\n" - + "a == 1\n" - + "======"; - compare(expected, machine); - } - - @Test - public void testScalarParameterToVariable() throws Exception { - String machine = "MACHINE test(a)\n" - + "CONSTRAINTS a : {1,2,3}\n" - + "END"; - - String expectedModule = "---- MODULE test----\n" - + "VARIABLES a\n" - + "Init == a \\in {1,2,3}\n" - + "Next == 1 = 2 /\\ UNCHANGED <<a>>\n" - + "======"; - String expectedConfig = "INIT Init\nNEXT Next"; - compareModuleAndConfig(expectedModule, expectedConfig, machine); - } - - @Test - public void testTwoScalarParameter() throws Exception { - String machine = "MACHINE test(a,b)\n" - + "CONSTRAINTS a = 1 & b = 2 \n" - + "END"; - - String expected = "---- MODULE test----\n" - + "a == 1\n" - + "b == 2 \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testParameter() throws Exception { - String machine = "MACHINE test(AA)\n" - + "END"; - - String expectedModule = "---- MODULE test----\n" - + "CONSTANTS AA\n" - + "======"; - String expectedConfig = "CONSTANTS AA = {AA1, AA2, AA3}"; - compareModuleAndConfig(expectedModule, expectedConfig, machine); - } - - @Test - public void testMixedParameter() throws Exception { - String machine = "MACHINE test(a, B)\n" - + "CONSTRAINTS a = 1 & card(B)= 2 \n" - + "END"; - String expectedModule = "---- MODULE test ----\n" - + "EXTENDS FiniteSets\n" - + "CONSTANTS B\n" - + "a == 1\n" - + "ASSUME Cardinality(B) = 2\n" - + "===="; - String expectedConfig = "CONSTANTS B = {B1, B2, B3}"; - compareModuleAndConfig(expectedModule, expectedConfig, machine); - } - -} +package de.tlc4b.prettyprint; + +import static de.tlc4b.util.TestUtil.*; + +import org.junit.Test; + +public class MachineParameterTest { + + @Test + public void testScalarParameterToConstant() throws Exception { + String machine = "MACHINE test(a)\n" + + "CONSTRAINTS a = 1\n" + + "END"; + + String expected = "---- MODULE test----\n" + + "a == 1\n" + + "======"; + compare(expected, machine); + } + + @Test + public void testScalarParameterToVariable() throws Exception { + String machine = "MACHINE test(a)\n" + + "CONSTRAINTS a : {1,2,3}\n" + + "END"; + + String expectedModule = "---- MODULE test----\n" + + "VARIABLES a\n" + + "Init == a \\in {1,2,3}\n" + + "Next == 1 = 2 /\\ UNCHANGED <<a>>\n" + + "======"; + String expectedConfig = "INIT Init\nNEXT Next"; + compareModuleAndConfig(expectedModule, expectedConfig, machine); + } + + @Test + public void testTwoScalarParameter() throws Exception { + String machine = "MACHINE test(a,b)\n" + + "CONSTRAINTS a = 1 & b = 2 \n" + + "END"; + + String expected = "---- MODULE test----\n" + + "a == 1\n" + + "b == 2 \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testParameter() throws Exception { + String machine = "MACHINE test(AA)\n" + + "END"; + + String expectedModule = "---- MODULE test----\n" + + "CONSTANTS AA\n" + + "======"; + String expectedConfig = "CONSTANTS AA = {AA1, AA2, AA3}"; + compareModuleAndConfig(expectedModule, expectedConfig, machine); + } + + @Test + public void testMixedParameter() throws Exception { + String machine = "MACHINE test(a, B)\n" + + "CONSTRAINTS a = 1 & card(B)= 2 \n" + + "END"; + String expectedModule = "---- MODULE test ----\n" + + "EXTENDS FiniteSets\n" + + "CONSTANTS B\n" + + "a == 1\n" + + "ASSUME Cardinality(B) = 2\n" + + "===="; + String expectedConfig = "CONSTANTS B = {B1, B2, B3}"; + compareModuleAndConfig(expectedModule, expectedConfig, machine); + } + +} diff --git a/src/test/java/de/tlc4b/prettyprint/OperationsTest.java b/src/test/java/de/tlc4b/prettyprint/OperationsTest.java index 6c333f503188a87f15960f394cf8cf206832505e..ceafde9351a7f4a24630ca1797772793a840af86 100644 --- a/src/test/java/de/tlc4b/prettyprint/OperationsTest.java +++ b/src/test/java/de/tlc4b/prettyprint/OperationsTest.java @@ -1,404 +1,409 @@ -package de.tlc4b.prettyprint; - -import static de.tlc4b.util.TestUtil.compare; - -import org.junit.Test; - -import de.tlc4b.exceptions.SubstitutionException; - -public class OperationsTest { - - @Test - public void testBecomesEqual() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x\n" - + "INVARIANT x = 1\n" - + "INITIALISATION x := 1 \n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "VARIABLES x \n" - + "Invariant1 == x = 1\n" - + "Init == x = 1 \n" - + "Next == 1 = 2 /\\ UNCHANGED <<x>>\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testBecomesEqual2() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x\n" - + "INVARIANT x = 1\n" - + "INITIALISATION x := 1 \n" - + "OPERATIONS\n" - + "foo = x:= 2 \n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "VARIABLES x \n" - + "Invariant1 == x = 1\n" - + "Init == x = 1 \n" - + "foo == x' = 2\n" - + "Next == foo \n" - + "===="; - compare(expected, machine); - } - - - @Test (expected = SubstitutionException.class) - public void testParallelSubstitution() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES a,b,c\n" - + "INVARIANT a = 1 & b = 1 & c = 1\n" - + "INITIALISATION a,b,c := 1,1,1 \n" - + "OPERATIONS foo = a := 2 || a := 3 \n" - + "END"; - compare(null, machine); - } - - @Test - public void testBlockSubstitution() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x\n" - + "INVARIANT x = 1\n" - + "INITIALISATION BEGIN x := 1 END\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "VARIABLES x \n" - + "Invariant == x = 1\n" - + "Init == x = 1 \n" - + "Next == 1 = 2 /\\ UNCHANGED <<x>>\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testBecomesSuchThat() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x,y\n" - + "INVARIANT x = 1 & y = 1\n" - + "INITIALISATION x,y:(x = 1 & y = 1)\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "VARIABLES x, y \n" - + "Invariant == x = 1 /\\ y = 1\n" - + "Init == x \\in {1} /\\ y \\in {1} \n" - + "Next == 1 = 2 /\\ UNCHANGED <<x, y>>\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testBecomesSuchThatInOperations() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x,y\n" - + "INVARIANT x = 1 & y = 1\n" - + "INITIALISATION x,y:(x = 1 & y = 1)\n" - + "OPERATIONS\n" - + " foo = x,y:(x = 1 & y = 1)\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "VARIABLES x, y \n" - + "Invariant == x = 1 /\\ y = 1\n" - + "Init == x \\in {1} /\\ y \\in {1}\n" - + "foo == x' \\in {1} /\\ y' \\in {1}\n" - + "Next == foo\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testBecomesSuchPreviousValue() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x,y\n" - + "INVARIANT x = 1 & y = 1\n" - + "INITIALISATION x,y:(x = 1 & y = 1)\n" - + "OPERATIONS\n" - + " foo = x:(x = x$0 + 1)\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "EXTENDS Naturals\n" - + "VARIABLES x, y \n" - + "Invariant == x = 1 /\\ y = 1\n" - + "Init == x \\in {1} /\\ y \\in {1} \n" - + "foo == x' \\in {x + 1} /\\ UNCHANGED <<y>>\n" - + "Next == foo\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testOperationParameter() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x\n" - + "INVARIANT x = 1\n" - + "INITIALISATION BEGIN x := 1 END\n" - + "OPERATIONS\n" - + "foo(p) = PRE p = 1 THEN x:= p END\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "VARIABLES x \n" - + "Invariant == x = 1\n" - + "Init == x = 1 \n" - + "foo(p) == x' = p\n" - + "Next == \\E p \\in {1} : foo(p)\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testAny() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x\n" - + "INVARIANT x = 1\n" - + "INITIALISATION BEGIN x := 1 END\n" - + "OPERATIONS\n" - + "foo = ANY p WHERE p = 1 THEN x := p END\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "VARIABLES x \n" - + "Invariant == x = 1\n" - + "Init == x = 1 \n" - + "foo == \\E p \\in {1} : x' = p\n" - + "Next == foo\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testOpParamterAny() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x\n" - + "INVARIANT x = 1\n" - + "INITIALISATION BEGIN x := 1 END\n" - + "OPERATIONS\n" - + "foo(p) = ANY p2 WHERE p = 1 & p2 = 1THEN x:= p+p2 END\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "EXTENDS Naturals\n" - + "VARIABLES x \n" - + "Invariant == x = 1\n" - + "Init == x = 1 \n" - + "foo(p) == \\E p2 \\in {1} : x' = p + p2\n" - + "Next == \\E p \\in {1} : foo(p)\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testSkip() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x\n" - + "INVARIANT x = 1\n" - + "INITIALISATION x := 1\n" - + "OPERATIONS\n" - + "foo = skip\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "VARIABLES x \n" - + "Invariant == x = 1\n" - + "Init == x = 1 \n" - + "foo == UNCHANGED <<x>>\n" - + "Next == foo\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testSkip2() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x\n" - + "INVARIANT x = 1\n" - + "INITIALISATION x := 1\n" - + "OPERATIONS\n" - + "foo = PRE 1 = 1 THEN skip END\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "VARIABLES x \n" - + "Invariant == x = 1\n" - + "Init == x = 1 \n" - + "foo == 1 = 1 /\\ UNCHANGED <<x>>\n" - + "Next == foo\n" - + "===="; - compare(expected, machine); - } - - - @Test - public void testSelect() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x\n" - + "INVARIANT x = 1\n" - + "INITIALISATION x := 1\n" - + "OPERATIONS\n" - + "foo = SELECT x = 1 THEN x:= x + 1 END\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "EXTENDS Naturals\n" - + "VARIABLES x \n" - + "Invariant == x = 1\n" - + "Init == x = 1 \n" - + "foo == x = 1 /\\ x' = x + 1\n" - + "Next == foo \n" - + "===="; - compare(expected, machine); - } - - @Test - public void testSelectParams() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x\n" - + "INVARIANT x = 1\n" - + "INITIALISATION x := 1\n" - + "OPERATIONS\n" - + "foo(a) = SELECT a = 1 THEN x:= a END\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "EXTENDS Naturals\n" - + "VARIABLES x \n" - + "Invariant == x = 1\n" - + "Init == x = 1 \n" - + "foo(a) == x' = a\n" - + "Next == \\E a \\in {1}: foo(a) \n" - + "===="; - compare(expected, machine); - } - - @Test - public void testBecomesElement() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x\n" - + "INVARIANT x = 1\n" - + "INITIALISATION x :: {1}\n" - + "OPERATIONS\n" - + "foo = x :: {2} \n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "VARIABLES x \n" - + "Invariant == x = 1\n" - + "Init == x \\in {1} \n" - + "foo == x' \\in {2} \n" - + "Next == foo\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testIfThen() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x\n" - + "INVARIANT x = 1\n" - + "INITIALISATION x := 1\n" - + "OPERATIONS\n" - + "foo = IF 1 = 1 THEN x := 1 END\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "VARIABLES x \n" - + "Invariant == x = 1\n" - + "Init == x = 1 \n" - + "foo == (IF 1 = 1 THEN x' = 1 ELSE UNCHANGED <<x>>)\n" - + "Next == foo \n" - + "===="; - compare(expected, machine); - } - - @Test - public void testSelectWhen() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x\n" - + "INVARIANT x = 1\n" - + "INITIALISATION x := 1\n" - + "OPERATIONS\n" - + "foo = SELECT x = 1 THEN x:= 1 WHEN x = 2 THEN x := 2 END\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "EXTENDS Naturals\n" - + "VARIABLES x \n" - + "Invariant == x = 1\n" - + "Init == x = 1 \n" - + "foo == (( ((x = 1) /\\ (x' = 1)) \\/ (x = 2 /\\ x' = 2)))\n" - + "Next == foo \n" - + "===="; - compare(expected, machine); - } - - - @Test - public void testSelectWhen2() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x,y\n" - + "INVARIANT x = 1 & y = 1\n" - + "INITIALISATION x,y := 1,1\n" - + "OPERATIONS\n" - + "foo = SELECT x = 1 THEN x:= 1 WHEN x = 2 THEN skip END\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "EXTENDS Naturals\n" - + "VARIABLES x,y \n" - + "Invariant == x = 1 /\\ y = 1\n" - + "Init == x = 1 /\\ y = 1\n" - + "foo == (( ((x = 1) /\\ (x' = 1)) \\/ (x = 2 /\\ UNCHANGED <<x>>)) /\\ UNCHANGED <<y>>)\n" - + "Next == foo \n" - + "===="; - compare(expected, machine); - } - - @Test - public void testSelectWhen3() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x,y\n" - + "INVARIANT x = 1 & y = 1\n" - + "INITIALISATION x,y := 1,1\n" - + "OPERATIONS\n" - + "foo = PRE x= 1 THEN SELECT x = 1 THEN x:= 1 WHEN x = 2 THEN skip END || y:= 1 END\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "VARIABLES x, y \n" - + "Invariant == x = 1 /\\ y = 1\n" - + "Init == x = 1 /\\ y = 1\n" - + "foo == x = 1 \n" - + "/\\ (((x = 1 /\\ x' = 1) \\/ (x = 2 /\\ UNCHANGED <<x>>)) /\\ y' = 1)\n" - + "Next == foo \n" - + "===="; - compare(expected, machine); - } - - @Test - public void testOutputParams() throws Exception { - String machine = "MACHINE test\n" - + "VARIABLES x\n" - + "INVARIANT x = 1\n" - + "INITIALISATION x := 1\n" - + "OPERATIONS\n" - + "res <-- foo = res:= x\n" - + "END"; - - String expected = "---- MODULE test ----\n" - + "EXTENDS Naturals\n" - + "VARIABLES x \n" - + "Invariant == x = 1\n" - + "Init == x = 1 \n" - + "foo == TRUE /\\ UNCHANGED <<x>>\n" - + "Next == foo \n" - + "===="; - compare(expected, machine); - } - -} +package de.tlc4b.prettyprint; + +import static de.tlc4b.util.TestUtil.compare; + +import org.junit.Test; + +import de.tlc4b.exceptions.SubstitutionException; + +public class OperationsTest { + + @Test + public void testBecomesEqual() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x\n" + + "INVARIANT x = 1\n" + + "INITIALISATION x := 1 \n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "VARIABLES x \n" + + "Invariant1 == x = 1\n" + + "Init == x = 1 \n" + + "Next == 1 = 2 /\\ UNCHANGED <<x>>\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testBecomesEqual2() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x\n" + + "INVARIANT x = 1\n" + + "INITIALISATION x := 1 \n" + + "OPERATIONS\n" + + "foo = x:= 2 \n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "VARIABLES x \n" + + "Invariant1 == x = 1\n" + + "Init == x = 1 \n" + + "foo == x' = 2\n" + + "Next == foo \n" + + "===="; + compare(expected, machine); + } + + + @Test (expected = SubstitutionException.class) + public void testParallelSubstitution() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES a,b,c\n" + + "INVARIANT a = 1 & b = 1 & c = 1\n" + + "INITIALISATION a,b,c := 1,1,1 \n" + + "OPERATIONS foo = a := 2 || a := 3 \n" + + "END"; + compare(null, machine); + } + + @Test + public void testBlockSubstitution() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x\n" + + "INVARIANT x = 1\n" + + "INITIALISATION BEGIN x := 1 END\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "VARIABLES x \n" + + "Invariant1 == x = 1\n" + + "Init == x = 1 \n" + + "Next == 1 = 2 /\\ UNCHANGED <<x>>\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testBecomesSuchThat() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x,y\n" + + "INVARIANT x = 1 & y = 1\n" + + "INITIALISATION x,y:(x = 1 & y = 1)\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "VARIABLES x, y \n" + + "Invariant1 == x = 1\n" + + "Invariant2 == y = 1\n" + + "Init == x \\in {1} /\\ y \\in {1} \n" + + "Next == 1 = 2 /\\ UNCHANGED <<x, y>>\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testBecomesSuchThatInOperations() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x,y\n" + + "INVARIANT x = 1 & y = 1\n" + + "INITIALISATION x,y:(x = 1 & y = 1)\n" + + "OPERATIONS\n" + + " foo = x,y:(x = 1 & y = 1)\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "VARIABLES x, y \n" + + "Invariant1 == x = 1\n" + + "Invariant2 == y = 1\n" + + "Init == x \\in {1} /\\ y \\in {1}\n" + + "foo == x' \\in {1} /\\ y' \\in {1}\n" + + "Next == foo\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testBecomesSuchPreviousValue() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x,y\n" + + "INVARIANT x = 1 & y = 1\n" + + "INITIALISATION x,y:(x = 1 & y = 1)\n" + + "OPERATIONS\n" + + " foo = x:(x = x$0 + 1)\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "EXTENDS Naturals\n" + + "VARIABLES x, y \n" + + "Invariant1 == x = 1\n" + + "Invariant2 == y = 1\n" + + "Init == x \\in {1} /\\ y \\in {1} \n" + + "foo == x' \\in {x + 1} /\\ UNCHANGED <<y>>\n" + + "Next == foo\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testOperationParameter() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x\n" + + "INVARIANT x = 1\n" + + "INITIALISATION BEGIN x := 1 END\n" + + "OPERATIONS\n" + + "foo(p) = PRE p = 1 THEN x:= p END\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "VARIABLES x \n" + + "Invariant1 == x = 1\n" + + "Init == x = 1 \n" + + "foo(p) == x' = p\n" + + "Next == \\E p \\in {1} : foo(p)\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testAny() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x\n" + + "INVARIANT x = 1\n" + + "INITIALISATION BEGIN x := 1 END\n" + + "OPERATIONS\n" + + "foo = ANY p WHERE p = 1 THEN x := p END\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "VARIABLES x \n" + + "Invariant1 == x = 1\n" + + "Init == x = 1 \n" + + "foo == \\E p \\in {1} : x' = p\n" + + "Next == foo\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testOpParamterAny() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x\n" + + "INVARIANT x = 1\n" + + "INITIALISATION BEGIN x := 1 END\n" + + "OPERATIONS\n" + + "foo(p) = ANY p2 WHERE p = 1 & p2 = 1THEN x:= p+p2 END\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "EXTENDS Naturals\n" + + "VARIABLES x \n" + + "Invariant1 == x = 1\n" + + "Init == x = 1 \n" + + "foo(p) == \\E p2 \\in {1} : x' = p + p2\n" + + "Next == \\E p \\in {1} : foo(p)\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testSkip() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x\n" + + "INVARIANT x = 1\n" + + "INITIALISATION x := 1\n" + + "OPERATIONS\n" + + "foo = skip\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "VARIABLES x \n" + + "Invariant1 == x = 1\n" + + "Init == x = 1 \n" + + "foo == UNCHANGED <<x>>\n" + + "Next == foo\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testSkip2() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x\n" + + "INVARIANT x = 1\n" + + "INITIALISATION x := 1\n" + + "OPERATIONS\n" + + "foo = PRE 1 = 1 THEN skip END\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "VARIABLES x \n" + + "Invariant1 == x = 1\n" + + "Init == x = 1 \n" + + "foo == 1 = 1 /\\ UNCHANGED <<x>>\n" + + "Next == foo\n" + + "===="; + compare(expected, machine); + } + + + @Test + public void testSelect() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x\n" + + "INVARIANT x = 1\n" + + "INITIALISATION x := 1\n" + + "OPERATIONS\n" + + "foo = SELECT x = 1 THEN x:= x + 1 END\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "EXTENDS Naturals\n" + + "VARIABLES x \n" + + "Invariant1 == x = 1\n" + + "Init == x = 1 \n" + + "foo == x = 1 /\\ x' = x + 1\n" + + "Next == foo \n" + + "===="; + compare(expected, machine); + } + + @Test + public void testSelectParams() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x\n" + + "INVARIANT x = 1\n" + + "INITIALISATION x := 1\n" + + "OPERATIONS\n" + + "foo(a) = SELECT a = 1 THEN x:= a END\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "EXTENDS Naturals\n" + + "VARIABLES x \n" + + "Invariant1 == x = 1\n" + + "Init == x = 1 \n" + + "foo(a) == x' = a\n" + + "Next == \\E a \\in {1}: foo(a) \n" + + "===="; + compare(expected, machine); + } + + @Test + public void testBecomesElement() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x\n" + + "INVARIANT x = 1\n" + + "INITIALISATION x :: {1}\n" + + "OPERATIONS\n" + + "foo = x :: {2} \n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "VARIABLES x \n" + + "Invariant1 == x = 1\n" + + "Init == x \\in {1} \n" + + "foo == x' \\in {2} \n" + + "Next == foo\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testIfThen() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x\n" + + "INVARIANT x = 1\n" + + "INITIALISATION x := 1\n" + + "OPERATIONS\n" + + "foo = IF 1 = 1 THEN x := 1 END\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "VARIABLES x \n" + + "Invariant1 == x = 1\n" + + "Init == x = 1 \n" + + "foo == (IF 1 = 1 THEN x' = 1 ELSE UNCHANGED <<x>>)\n" + + "Next == foo \n" + + "===="; + compare(expected, machine); + } + + @Test + public void testSelectWhen() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x\n" + + "INVARIANT x = 1\n" + + "INITIALISATION x := 1\n" + + "OPERATIONS\n" + + "foo = SELECT x = 1 THEN x:= 1 WHEN x = 2 THEN x := 2 END\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "EXTENDS Naturals\n" + + "VARIABLES x \n" + + "Invariant1 == x = 1\n" + + "Init == x = 1 \n" + + "foo == (( ((x = 1) /\\ (x' = 1)) \\/ (x = 2 /\\ x' = 2)))\n" + + "Next == foo \n" + + "===="; + compare(expected, machine); + } + + + @Test + public void testSelectWhen2() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x,y\n" + + "INVARIANT x = 1 & y = 1\n" + + "INITIALISATION x,y := 1,1\n" + + "OPERATIONS\n" + + "foo = SELECT x = 1 THEN x:= 1 WHEN x = 2 THEN skip END\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "EXTENDS Naturals\n" + + "VARIABLES x,y \n" + + "Invariant1 == x = 1\n" + + "Invariant2 == y = 1\n" + + "Init == x = 1 /\\ y = 1\n" + + "foo == (( ((x = 1) /\\ (x' = 1)) \\/ (x = 2 /\\ UNCHANGED <<x>>)) /\\ UNCHANGED <<y>>)\n" + + "Next == foo \n" + + "===="; + compare(expected, machine); + } + + @Test + public void testSelectWhen3() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x,y\n" + + "INVARIANT x = 1 & y = 1\n" + + "INITIALISATION x,y := 1,1\n" + + "OPERATIONS\n" + + "foo = PRE x= 1 THEN SELECT x = 1 THEN x:= 1 WHEN x = 2 THEN skip END || y:= 1 END\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "VARIABLES x, y \n" + + "Invariant1 == x = 1\n" + + "Invariant2 == y = 1\n" + + "Init == x = 1 /\\ y = 1\n" + + "foo == x = 1 \n" + + "/\\ (((x = 1 /\\ x' = 1) \\/ (x = 2 /\\ UNCHANGED <<x>>)) /\\ y' = 1)\n" + + "Next == foo \n" + + "===="; + compare(expected, machine); + } + + @Test + public void testOutputParams() throws Exception { + String machine = "MACHINE test\n" + + "VARIABLES x\n" + + "INVARIANT x = 1\n" + + "INITIALISATION x := 1\n" + + "OPERATIONS\n" + + "res <-- foo = res:= x\n" + + "END"; + + String expected = "---- MODULE test ----\n" + + "EXTENDS Naturals\n" + + "VARIABLES x \n" + + "Invariant1 == x = 1\n" + + "Init == x = 1 \n" + + "foo == TRUE /\\ UNCHANGED <<x>>\n" + + "Next == foo \n" + + "===="; + compare(expected, machine); + } + +} diff --git a/src/test/java/de/tlc4b/prettyprint/RelationTest.java b/src/test/java/de/tlc4b/prettyprint/RelationTest.java index 1f3a08f6d8e4206a43aef8a7c6432833768024fd..20a7749d92ec6ca92d3bce08f60c130d6e6e61fa 100644 --- a/src/test/java/de/tlc4b/prettyprint/RelationTest.java +++ b/src/test/java/de/tlc4b/prettyprint/RelationTest.java @@ -1,40 +1,40 @@ -package de.tlc4b.prettyprint; - -import static de.tlc4b.util.TestUtil.*; - -import org.junit.Test; - -public class RelationTest { - - - @Test - public void testCouple() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES (1,2) = (1|->2) \n" + "END"; - String expected = "---- MODULE test----\n" - + "ASSUME <<1,2>> = <<1,2>>\n" - + "======"; - compare(expected, machine); - } - - @Test - public void testCouple3() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES (1,2,3) = ((1,2),3) \n" + "END"; - String expected = "---- MODULE test ----\n" - + "ASSUME <<<<1, 2>>, 3>> = <<<<1, 2>>, 3>>\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testCouple4() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES (1,2,3,4) = (((1,2),3),4) \n" + "END"; - String expected = "---- MODULE test ----\n" - + "ASSUME <<<<<<1, 2>>, 3>>, 4>> = <<<<<<1, 2>>, 3>>, 4>>\n" - + "===="; - compare(expected, machine); - } - -} +package de.tlc4b.prettyprint; + +import static de.tlc4b.util.TestUtil.*; + +import org.junit.Test; + +public class RelationTest { + + + @Test + public void testCouple() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES (1,2) = (1|->2) \n" + "END"; + String expected = "---- MODULE test----\n" + + "ASSUME <<1,2>> = <<1,2>>\n" + + "======"; + compare(expected, machine); + } + + @Test + public void testCouple3() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES (1,2,3) = ((1,2),3) \n" + "END"; + String expected = "---- MODULE test ----\n" + + "ASSUME <<<<1, 2>>, 3>> = <<<<1, 2>>, 3>>\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testCouple4() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES (1,2,3,4) = (((1,2),3),4) \n" + "END"; + String expected = "---- MODULE test ----\n" + + "ASSUME <<<<<<1, 2>>, 3>>, 4>> = <<<<<<1, 2>>, 3>>, 4>>\n" + + "===="; + compare(expected, machine); + } + +} diff --git a/src/test/java/de/tlc4b/prettyprint/SetTest.java b/src/test/java/de/tlc4b/prettyprint/SetTest.java index 5b087cb448bd69ee180d5ed04ed34081cdb6fb11..8e66fcbcffe6ea34316fdaccc832551c2cbc4a09 100644 --- a/src/test/java/de/tlc4b/prettyprint/SetTest.java +++ b/src/test/java/de/tlc4b/prettyprint/SetTest.java @@ -1,208 +1,207 @@ -package de.tlc4b.prettyprint; - -import static de.tlc4b.util.TestUtil.*; -import static org.junit.Assert.*; - -import org.junit.Test; - -public class SetTest { - - @Test - public void testEmptySet() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {} = {} \n" + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "ASSUME {} = {}\n" - + "======"; - compare(expected, machine); - } - - @Test - public void testSetExtension() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {3,2,1} = {1,2,3} \n" + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "ASSUME {3,2,1} = {1,2,3}\n" - + "======"; - compare(expected, machine); - } - - @Test - public void testSetComprehension() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {1} = {x | x = 1} \n" + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "ASSUME {1} = {x \\in {1}: TRUE} \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testSetComprehension2() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {1} = {x | x = 1 & 1 = 1} \n" + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "ASSUME {1} = {x \\in {1}: 1 = 1 } \n" - + "======"; - compare(expected, machine); - } - - - @Test - public void testPowerSet() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {{},{1}} = POW({1}) \n" + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" - + "ASSUME {{},{1}} = SUBSET {1} \n" - + "======"; - compare(expected, machine); - } - - - @Test - public void testCard() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES 2 = card({1,2}) \n" + "END"; - String expected = "---- MODULE test----\n" + "EXTENDS FiniteSets\n" - + "ASSUME 2 = Cardinality({1,2}) \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testCartesianProduct() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {1}*{2} = {(1,2)} \n" + "END"; - String expected = "---- MODULE test ----\n" - + "ASSUME {1} \\times {2} = {<<1, 2>>}\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testCartesianProduct2() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {1}*{2}*{3} = {(1,2,3)} \n" + "END"; - String expected = "---- MODULE test ----\n" - + "ASSUME ({1} \\times {2}) \\times {3} = {<<<<1, 2>>, 3>>}\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testUnion() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {1} \\/ {2} = {1,2} \n" + "END"; - String expected = "---- MODULE test----\n" - + "ASSUME {1} \\cup {2} = {1,2} \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testIntersection() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {1,2} /\\ {2} = {2} \n" + "END"; - String expected = "---- MODULE test----\n" - + "ASSUME {1,2} \\cap {2} = {2} \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testSetSubstraction() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {1,2} \\ {2} = {1} \n" + "END"; - String expected = "---- MODULE test ----\n" - + "ASSUME {1,2} \\ {2} = {1}\n" - + "===="; - compare(expected, machine); - } - - @Test - public void testDifference() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {1,2} - {2} = {1} \n" + "END"; - String expected = "---- MODULE test----\n" - + "ASSUME {1,2} \\ {2} = {1} \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testElementOf() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES 1 : {1} \n" + "END"; - String expected = "---- MODULE test----\n" - + "ASSUME 1 \\in {1} \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testNotElementOf() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES 1 /: {1} \n" + "END"; - String expected = "---- MODULE test----\n" - + "ASSUME 1 \\notin {1} \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testSubsetEq() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES {1} <: {1} \n" + "END"; - String expected = "---- MODULE test----\n" - + "ASSUME {1} \\subseteq {1} \n" - + "======"; - compare(expected, machine); - } - - - @Test - public void testGeneralisedUnion() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES union({{1},{2}}) = {1,2} \n" + "END"; - String expected = "---- MODULE test ----\n" - + "ASSUME UNION({{1}, {2}}) = {1, 2}\n" - + "===="; - assertEquals(expected, translate(machine)); - } - - - @Test - public void testGeneralisedIntersection() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES inter({{1},{1,2}}) = {1} \n" + "END"; - String expected = "---- MODULE test ----\n" - + "EXTENDS BBuiltIns\n" - + "ASSUME Inter({{1}, {1, 2}}) = {1}\n" - + "===="; - assertEquals(expected, translate(machine)); - } - - @Test - public void testQuantifiedUnion() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES UNION(z).(z: {1,2} & 1 = 1| {z}) = {1,2} \n" + "END"; - String expected = "---- MODULE test ----\n" - + "ASSUME UNION({{z}: z \\in {z \\in ({1, 2}): 1 = 1}}) = {1, 2}\n" - + "===="; - //TODO ERROR in TLA2B - compareEquals(expected, machine); - } - - @Test - public void testQuantifiedIntersection() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES INTER(z).(z: {1,2} & 1 = 1| {z}) = {} \n" + "END"; - String expected = "---- MODULE test ----\n" - + "EXTENDS BBuiltIns\n" - + "ASSUME Inter({{z}: z \\in {z \\in ({1, 2}): 1 = 1}}) = {}\n" - + "===="; - System.out.println(expected); - compareEquals(expected, machine); - } - -} +package de.tlc4b.prettyprint; + +import static de.tlc4b.util.TestUtil.*; +import static org.junit.Assert.*; + +import org.junit.Test; + +public class SetTest { + + @Test + public void testEmptySet() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {} = {} \n" + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "ASSUME {} = {}\n" + + "======"; + compare(expected, machine); + } + + @Test + public void testSetExtension() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {3,2,1} = {1,2,3} \n" + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "ASSUME {3,2,1} = {1,2,3}\n" + + "======"; + compare(expected, machine); + } + + @Test + public void testSetComprehension() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {1} = {x | x = 1} \n" + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "ASSUME {1} = {x \\in {1}: TRUE} \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testSetComprehension2() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {1} = {x | x = 1 & 1 = 1} \n" + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "ASSUME {1} = {x \\in {1}: 1 = 1 } \n" + + "======"; + compare(expected, machine); + } + + + @Test + public void testPowerSet() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {{},{1}} = POW({1}) \n" + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS Integers\n" + + "ASSUME {{},{1}} = SUBSET {1} \n" + + "======"; + compare(expected, machine); + } + + + @Test + public void testCard() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES 2 = card({1,2}) \n" + "END"; + String expected = "---- MODULE test----\n" + "EXTENDS FiniteSets\n" + + "ASSUME 2 = Cardinality({1,2}) \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testCartesianProduct() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {1}*{2} = {(1,2)} \n" + "END"; + String expected = "---- MODULE test ----\n" + + "ASSUME {1} \\times {2} = {<<1, 2>>}\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testCartesianProduct2() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {1}*{2}*{3} = {(1,2,3)} \n" + "END"; + String expected = "---- MODULE test ----\n" + + "ASSUME ({1} \\times {2}) \\times {3} = {<<<<1, 2>>, 3>>}\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testUnion() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {1} \\/ {2} = {1,2} \n" + "END"; + String expected = "---- MODULE test----\n" + + "ASSUME {1} \\cup {2} = {1,2} \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testIntersection() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {1,2} /\\ {2} = {2} \n" + "END"; + String expected = "---- MODULE test----\n" + + "ASSUME {1,2} \\cap {2} = {2} \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testSetSubstraction() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {1,2} \\ {2} = {1} \n" + "END"; + String expected = "---- MODULE test ----\n" + + "ASSUME {1,2} \\ {2} = {1}\n" + + "===="; + compare(expected, machine); + } + + @Test + public void testDifference() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {1,2} - {2} = {1} \n" + "END"; + String expected = "---- MODULE test----\n" + + "ASSUME {1,2} \\ {2} = {1} \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testElementOf() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES 1 : {1} \n" + "END"; + String expected = "---- MODULE test----\n" + + "ASSUME 1 \\in {1} \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testNotElementOf() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES 1 /: {1} \n" + "END"; + String expected = "---- MODULE test----\n" + + "ASSUME 1 \\notin {1} \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testSubsetEq() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES {1} <: {1} \n" + "END"; + String expected = "---- MODULE test----\n" + + "ASSUME {1} \\subseteq {1} \n" + + "======"; + compare(expected, machine); + } + + + @Test + public void testGeneralisedUnion() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES union({{1},{2}}) = {1,2} \n" + "END"; + String expected = "---- MODULE test ----\n" + + "ASSUME UNION({{1}, {2}}) = {1, 2}\n" + + "===="; + assertEquals(expected, translate(machine)); + } + + + @Test + public void testGeneralisedIntersection() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES inter({{1},{1,2}}) = {1} \n" + "END"; + String expected = "---- MODULE test ----\n" + + "EXTENDS BBuiltIns\n" + + "ASSUME Inter({{1}, {1, 2}}) = {1}\n" + + "===="; + assertEquals(expected, translate(machine)); + } + + @Test + public void testQuantifiedUnion() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES UNION(z).(z: {1,2} & 1 = 1| {z}) = {1,2} \n" + "END"; + String expected = "---- MODULE test ----\n" + + "ASSUME UNION({{z}: z \\in {z \\in ({1, 2}): 1 = 1}}) = {1, 2}\n" + + "===="; + //TODO ERROR in TLA2B + compareEquals(expected, machine); + } + + @Test + public void testQuantifiedIntersection() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES INTER(z).(z: {1,2} & 1 = 1| {z}) = {} \n" + "END"; + String expected = "---- MODULE test ----\n" + + "EXTENDS BBuiltIns\n" + + "ASSUME Inter({{z}: z \\in {z \\in ({1, 2}): 1 = 1}}) = {}\n" + + "===="; + compareEquals(expected, machine); + } + +} diff --git a/src/test/java/de/tlc4b/prettyprint/SetsClauseTest.java b/src/test/java/de/tlc4b/prettyprint/SetsClauseTest.java index b5faf7e61d667ba89e97d2b1a16b19236cbc27e1..2d12db49152344912eb7f14fbd4edd2d8011fe23 100644 --- a/src/test/java/de/tlc4b/prettyprint/SetsClauseTest.java +++ b/src/test/java/de/tlc4b/prettyprint/SetsClauseTest.java @@ -1,50 +1,50 @@ -package de.tlc4b.prettyprint; - -import static de.tlc4b.util.TestUtil.*; - -import org.junit.Test; - -public class SetsClauseTest { - @Test - public void testDeferredSet() throws Exception { - String machine = "MACHINE test\n" - + "SETS d \n" - + "END"; - String expectedModule = "---- MODULE test----\n" - + "CONSTANTS d\n" - + "======"; - String expectedConfig = "CONSTANTS\n" + - "d = {d1, d2, d3}\n"; - - compareModuleAndConfig(expectedModule, expectedConfig, machine); - } - - @Test - public void testDeferredSet2() throws Exception { - String machine = "MACHINE test\n" - + "SETS d \n" - + "CONSTANTS k \n" - + "PROPERTIES k : d \n" - + "END"; - String expectedModule = "---- MODULE test----\n" - + "CONSTANTS d2asisdfapsdjfa\n" - + "======"; - String expectedConfig = "CONSTANTS\n" + - "d = {d1, d2, d3}\n"; - - compareModuleAndConfig(expectedModule, expectedConfig, machine); - } - - @Test - public void testEnumeratedSet() throws Exception { - String machine = "MACHINE test\n" - + "SETS S = {a,b,c} \n" - + "END"; - String expectedModule = "---- MODULE test----\n" - + "CONSTANTS a, b, c\n" - + "S == {a, b, c}" - + "======"; - String expectedConfig = "CONSTANTS a = a\n b = b \n c = c"; - compareModuleAndConfig(expectedModule, expectedConfig, machine); - } -} +package de.tlc4b.prettyprint; + +import static de.tlc4b.util.TestUtil.*; + +import org.junit.Test; + +public class SetsClauseTest { + @Test + public void testDeferredSet() throws Exception { + String machine = "MACHINE test\n" + + "SETS d \n" + + "END"; + String expectedModule = "---- MODULE test----\n" + + "CONSTANTS d\n" + + "======"; + String expectedConfig = "CONSTANTS\n" + + "d = {d1, d2, d3}\n"; + + compareModuleAndConfig(expectedModule, expectedConfig, machine); + } + + @Test + public void testDeferredSet2() throws Exception { + String machine = "MACHINE test\n" + + "SETS d \n" + + "CONSTANTS k \n" + + "PROPERTIES k : d \n" + + "END"; + String expectedModule = "---- MODULE test----\n" + + "CONSTANTS d2asisdfapsdjfa\n" + + "======"; + String expectedConfig = "CONSTANTS\n" + + "d = {d1, d2, d3}\n"; + + compareModuleAndConfig(expectedModule, expectedConfig, machine); + } + + @Test + public void testEnumeratedSet() throws Exception { + String machine = "MACHINE test\n" + + "SETS S = {a,b,c} \n" + + "END"; + String expectedModule = "---- MODULE test----\n" + + "CONSTANTS a, b, c\n" + + "S == {a, b, c}" + + "======"; + String expectedConfig = "CONSTANTS a = a\n b = b \n c = c"; + compareModuleAndConfig(expectedModule, expectedConfig, machine); + } +} diff --git a/src/test/java/de/tlc4b/prettyprint/StringTest.java b/src/test/java/de/tlc4b/prettyprint/StringTest.java index a89df695730bc9ec3cec438591c3701b26dfea89..58d351d241d494960762a38088155e784aa6f0ed 100644 --- a/src/test/java/de/tlc4b/prettyprint/StringTest.java +++ b/src/test/java/de/tlc4b/prettyprint/StringTest.java @@ -1,31 +1,31 @@ -package de.tlc4b.prettyprint; - -import static de.tlc4b.util.TestUtil.compare; - -import org.junit.Test; - -public class StringTest { - - @Test - public void testString() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES \"abc\" = \"abc\" " + "END"; - - String expected = "---- MODULE test----\n" - + "ASSUME \"abc\" = \"abc\" \n" - + "======"; - compare(expected, machine); - } - - @Test - public void testString2() throws Exception { - String machine = "MACHINE test\n" - + "PROPERTIES #x.(x: STRING)" + "END"; - - String expected = "---- MODULE test----\n" - + "ASSUME \\E x \\in STRING : TRUE \n" - + "======"; - compare(expected, machine); - } - -} +package de.tlc4b.prettyprint; + +import static de.tlc4b.util.TestUtil.compare; + +import org.junit.Test; + +public class StringTest { + + @Test + public void testString() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES \"abc\" = \"abc\" " + "END"; + + String expected = "---- MODULE test----\n" + + "ASSUME \"abc\" = \"abc\" \n" + + "======"; + compare(expected, machine); + } + + @Test + public void testString2() throws Exception { + String machine = "MACHINE test\n" + + "PROPERTIES #x.(x: STRING)" + "END"; + + String expected = "---- MODULE test----\n" + + "ASSUME \\E x \\in STRING : TRUE \n" + + "======"; + compare(expected, machine); + } + +} diff --git a/src/test/java/de/tlc4b/prettyprint/SubstitutionsTest.java b/src/test/java/de/tlc4b/prettyprint/SubstitutionsTest.java index 9a4946dd4e9bf156d4695a560dd63a250b159dd9..3965d7d575b53aff3ae73d8e891f9b4ff9e27c55 100644 --- a/src/test/java/de/tlc4b/prettyprint/SubstitutionsTest.java +++ b/src/test/java/de/tlc4b/prettyprint/SubstitutionsTest.java @@ -54,7 +54,7 @@ public class SubstitutionsTest { String expected = "---- MODULE test ----\n" + "EXTENDS Naturals \n" + "VARIABLES x \n" - + "Invariant == x = 1\n" + + "Invariant1 == x = 1\n" + "Init == \\E a \\in {1}, b \\in {2} : x = a + b \n" + "Next == 1 = 2 /\\ UNCHANGED <<x>>\n" + "===="; @@ -107,7 +107,7 @@ public class SubstitutionsTest { String expected = "---- MODULE test ----\n" + "EXTENDS Naturals \n" + "VARIABLES x \n" - + "Invariant == x = 1\n" + + "Invariant1 == x = 1\n" + "Init == x \\in {1}\n" + "Next == 1 = 2 /\\ UNCHANGED <<x>>\n" + "===="; @@ -125,7 +125,7 @@ public class SubstitutionsTest { String expected = "---- MODULE test ----\n" + "EXTENDS Naturals \n" + "VARIABLES x \n" - + "Invariant == x = 1\n" + + "Invariant1 == x = 1\n" + "Init == (CASE 1 = 1 -> x = 1 [] 1 = 2 -> x = 2 [] OTHER -> x = 4)\n" + "Next == 1 = 2 /\\ UNCHANGED <<x>>\n" + "===="; diff --git a/src/test/java/de/tlc4b/tlc/integration/ErrorTest.java b/src/test/java/de/tlc4b/tlc/integration/ErrorTest.java index 8d192c0d6d0b00903cd0de596edc690f47bddc8a..1a85190a9bc34b6cb627874997562adbffddeb56 100644 --- a/src/test/java/de/tlc4b/tlc/integration/ErrorTest.java +++ b/src/test/java/de/tlc4b/tlc/integration/ErrorTest.java @@ -1,92 +1,92 @@ -package de.tlc4b.tlc.integration; - -import static org.junit.Assert.*; - -import org.junit.Ignore; -import org.junit.Test; - -import static de.tlc4b.tlc.TLCResults.TLCResult.*; -import static de.tlc4b.util.TestUtil.test; - -public class ErrorTest { - - @Test - public void testTraceValues() throws Exception { - String[] a = new String[] { "./src/test/resources/errors/TraceValues.mch" }; - assertEquals(Deadlock, test(a)); - } - - @Test - public void testInvariantError() throws Exception { - String[] a = new String[] { "./src/test/resources/errors/InvariantError.mch" }; - assertEquals(InvariantViolation, test(a)); - } - - @Test - public void testDeadlock() throws Exception { - String[] a = new String[] { "./src/test/resources/errors/Deadlock.mch" }; - assertEquals(Deadlock, test(a)); - } - - @Test - public void testPropertiesError() throws Exception { - String[] a = new String[] { "./src/test/resources/errors/PropertiesError.mch" }; - assertEquals(PropertiesError, test(a)); - } - - @Test - public void testNoFile() throws Exception { - String[] a = new String[] { "./src/test/resources/errors/NoFile.mch" }; - assertEquals(null, test(a)); - } - - @Test - public void testNoError() throws Exception { - String[] a = new String[] { "./src/test/resources/errors/NoError.mch" }; - assertEquals(NoError, test(a)); - } - - @Ignore - @Test - public void testEnumerationError() throws Exception { - String[] a = new String[] { "./src/test/resources/errors/EnumerationError.mch" }; - assertEquals(EnumerationError, test(a)); - } - - @Test - public void testAssertionError() throws Exception { - String[] a = new String[] { "./src/test/resources/errors/AssertionError.mch" }; - assertEquals(AssertionError, test(a)); - } - - - @Test - public void testConstantAssertionError() throws Exception { - String[] a = new String[] { "./src/test/resources/errors/AssertionError2.mch" }; - assertEquals(AssertionError, test(a)); - } - - @Test - public void testTemporalPropertyError() throws Exception { - String[] a = new String[] { "./src/test/resources/errors/LTLError.mch" }; - assertEquals(TemporalPropertyViolation, test(a)); - } - - @Test - public void testWelldefinednessError1() throws Exception { - String[] a = new String[] { "./src/test/resources/errors/WelldefinednessError1.mch" }; - assertEquals(WellDefinednessError, test(a)); - } - - @Test - public void testWelldefinednessError2() throws Exception { - String[] a = new String[] { "./src/test/resources/errors/WelldefinednessError2.mch" }; - assertEquals(WellDefinednessError, test(a)); - } - - @Test - public void testWelldefinednessError3() throws Exception { - String[] a = new String[] { "./src/test/resources/errors/WelldefinednessError3.mch" }; - assertEquals(WellDefinednessError, test(a)); - } -} +package de.tlc4b.tlc.integration; + +import static org.junit.Assert.*; + +import org.junit.Ignore; +import org.junit.Test; + +import static de.tlc4b.tlc.TLCResults.TLCResult.*; +import static de.tlc4b.util.TestUtil.test; + +public class ErrorTest { + + @Test + public void testTraceValues() throws Exception { + String[] a = new String[] { "./src/test/resources/errors/TraceValues.mch" }; + assertEquals(Deadlock, test(a)); + } + + @Test + public void testInvariantError() throws Exception { + String[] a = new String[] { "./src/test/resources/errors/InvariantError.mch" }; + assertEquals(InvariantViolation, test(a)); + } + + @Test + public void testDeadlock() throws Exception { + String[] a = new String[] { "./src/test/resources/errors/Deadlock.mch" }; + assertEquals(Deadlock, test(a)); + } + + @Test + public void testPropertiesError() throws Exception { + String[] a = new String[] { "./src/test/resources/errors/PropertiesError.mch" }; + assertEquals(PropertiesError, test(a)); + } + + @Test + public void testNoFile() throws Exception { + String[] a = new String[] { "./src/test/resources/errors/NoFile.mch" }; + assertEquals(null, test(a)); + } + + @Test + public void testNoError() throws Exception { + String[] a = new String[] { "./src/test/resources/errors/NoError.mch" }; + assertEquals(NoError, test(a)); + } + + @Ignore + @Test + public void testEnumerationError() throws Exception { + String[] a = new String[] { "./src/test/resources/errors/EnumerationError.mch" }; + assertEquals(EnumerationError, test(a)); + } + + @Test + public void testAssertionError() throws Exception { + String[] a = new String[] { "./src/test/resources/errors/AssertionError.mch" }; + assertEquals(AssertionError, test(a)); + } + + + @Test + public void testConstantAssertionError() throws Exception { + String[] a = new String[] { "./src/test/resources/errors/AssertionError2.mch" }; + assertEquals(AssertionError, test(a)); + } + + @Test + public void testTemporalPropertyError() throws Exception { + String[] a = new String[] { "./src/test/resources/errors/LTLError.mch" }; + assertEquals(TemporalPropertyViolation, test(a)); + } + + @Test + public void testWelldefinednessError1() throws Exception { + String[] a = new String[] { "./src/test/resources/errors/WelldefinednessError1.mch" }; + assertEquals(WellDefinednessError, test(a)); + } + + @Test + public void testWelldefinednessError2() throws Exception { + String[] a = new String[] { "./src/test/resources/errors/WelldefinednessError2.mch" }; + assertEquals(WellDefinednessError, test(a)); + } + + @Test + public void testWelldefinednessError3() throws Exception { + String[] a = new String[] { "./src/test/resources/errors/WelldefinednessError3.mch" }; + assertEquals(WellDefinednessError, test(a)); + } +} diff --git a/src/test/java/de/tlc4b/tlc/integration/probprivate/AssertionErrorTest.java b/src/test/java/de/tlc4b/tlc/integration/probprivate/AssertionErrorTest.java index 03b294910763772b6bdc0b6d1669d7896f9daea5..4f405b4476a061e80438526416d6fb3b563b706d 100644 --- a/src/test/java/de/tlc4b/tlc/integration/probprivate/AssertionErrorTest.java +++ b/src/test/java/de/tlc4b/tlc/integration/probprivate/AssertionErrorTest.java @@ -1,21 +1,21 @@ package de.tlc4b.tlc.integration.probprivate; -import static de.tlc4b.tlc.TLCResults.TLCResult.*; -import static de.tlc4b.util.TestUtil.test; -import static org.junit.Assert.assertEquals; - import java.io.File; import java.util.ArrayList; -import org.junit.Test; -import org.junit.runner.RunWith; - import de.tlc4b.tlc.TLCResults.TLCResult; import de.tlc4b.util.AbstractParseMachineTest; import de.tlc4b.util.PolySuite; -import de.tlc4b.util.TestPair; import de.tlc4b.util.PolySuite.Config; import de.tlc4b.util.PolySuite.Configuration; +import de.tlc4b.util.TestPair; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static de.tlc4b.tlc.TLCResults.TLCResult.AssertionError; +import static de.tlc4b.util.TestUtil.test; +import static org.junit.Assert.assertEquals; @RunWith(PolySuite.class) public class AssertionErrorTest extends AbstractParseMachineTest { @@ -37,7 +37,7 @@ public class AssertionErrorTest extends AbstractParseMachineTest { @Config public static Configuration getConfig() { final ArrayList<TestPair> list = new ArrayList<TestPair>(); - list.add(new TestPair(AssertionError, "public_examples/TLC/AssertionError")); + list.add(new TestPair(AssertionError, "build/prob_examples/public_examples/TLC/AssertionError")); return getConfiguration(list); } } diff --git a/src/test/java/de/tlc4b/coverage/CoverageTest.java b/src/test/java/de/tlc4b/tlc/integration/probprivate/CoverageTest.java similarity index 67% rename from src/test/java/de/tlc4b/coverage/CoverageTest.java rename to src/test/java/de/tlc4b/tlc/integration/probprivate/CoverageTest.java index f5d7ca539988f540f5d0d07506970b49e8767ce2..4461c50d825d25c9fb9d27352b62e7b4345bdfa9 100644 --- a/src/test/java/de/tlc4b/coverage/CoverageTest.java +++ b/src/test/java/de/tlc4b/tlc/integration/probprivate/CoverageTest.java @@ -1,11 +1,8 @@ -package de.tlc4b.coverage; +package de.tlc4b.tlc.integration.probprivate; import java.io.File; import java.util.ArrayList; -import org.junit.Test; -import org.junit.runner.RunWith; - import de.tlc4b.TLC4B; import de.tlc4b.tlc.TLCResults.TLCResult; import de.tlc4b.util.AbstractParseMachineTest; @@ -13,6 +10,11 @@ import de.tlc4b.util.PolySuite; import de.tlc4b.util.PolySuite.Config; import de.tlc4b.util.PolySuite.Configuration; +import org.junit.Test; +import org.junit.runner.RunWith; + +import tlc2.TLCGlobals; + @RunWith(PolySuite.class) public class CoverageTest extends AbstractParseMachineTest { @@ -24,6 +26,12 @@ public class CoverageTest extends AbstractParseMachineTest { @Test public void testRunTLC() throws Exception { + // The subdirectories of the states directory are named after the time when TLC was started. + // Old versions of TLC (like the one we use) format the time with second precision only, + // leading to name conflicts when two tests are started within the same second. + // This line works around the issue by instead using a millisecond timestamp as the name. + TLCGlobals.metaDir = TLCGlobals.metaRoot + File.separator + System.currentTimeMillis() + File.separator; + String[] a = new String[] { machine.getPath(), "-notlc" }; TLC4B.test(a, true); } @@ -32,7 +40,7 @@ public class CoverageTest extends AbstractParseMachineTest { public static Configuration getConfig() { final ArrayList<String> list = new ArrayList<String>(); final ArrayList<String> ignoreList = new ArrayList<String>(); - list.add("public_examples/TLC/"); + list.add("build/prob_examples/public_examples/TLC/"); list.add("./src/test/resources/"); ignoreList.add("./src/test/resources/compound/"); diff --git a/src/test/java/de/tlc4b/tlc/integration/probprivate/DeadlockTest.java b/src/test/java/de/tlc4b/tlc/integration/probprivate/DeadlockTest.java index bce24e39ce418ee58b83947c263ce5e8b1c71507..6d01d2a02ec6dab732efdce7bb7e081fba9d8698 100644 --- a/src/test/java/de/tlc4b/tlc/integration/probprivate/DeadlockTest.java +++ b/src/test/java/de/tlc4b/tlc/integration/probprivate/DeadlockTest.java @@ -38,7 +38,7 @@ public class DeadlockTest extends AbstractParseMachineTest { public static Configuration getConfig() { final ArrayList<TestPair> list = new ArrayList<TestPair>(); list.add(new TestPair(Deadlock, - "public_examples/TLC/Deadlock")); + "build/prob_examples/public_examples/TLC/Deadlock")); return getConfiguration(list); } } diff --git a/src/test/java/de/tlc4b/tlc/integration/probprivate/GoalTest.java b/src/test/java/de/tlc4b/tlc/integration/probprivate/GoalTest.java index 8692465f62a6bc765abd6cf140749a2f905c9779..d026d9c9ecb8eb25c3353b71b6664562ab953265 100644 --- a/src/test/java/de/tlc4b/tlc/integration/probprivate/GoalTest.java +++ b/src/test/java/de/tlc4b/tlc/integration/probprivate/GoalTest.java @@ -38,7 +38,7 @@ public class GoalTest extends AbstractParseMachineTest { public static Configuration getConfig() { final ArrayList<TestPair> list = new ArrayList<TestPair>(); list.add(new TestPair(Goal, - "public_examples/TLC/GOAL")); + "build/prob_examples/public_examples/TLC/GOAL")); return getConfiguration(list); } } diff --git a/src/test/java/de/tlc4b/tlc/integration/probprivate/InvariantViolationTest.java b/src/test/java/de/tlc4b/tlc/integration/probprivate/InvariantViolationTest.java index 32b3aca18b90989cff6cc387419d0c6231f5d78a..c395f3908b0deebacfc50b1591c7a383f53b7b04 100644 --- a/src/test/java/de/tlc4b/tlc/integration/probprivate/InvariantViolationTest.java +++ b/src/test/java/de/tlc4b/tlc/integration/probprivate/InvariantViolationTest.java @@ -38,7 +38,7 @@ public class InvariantViolationTest extends AbstractParseMachineTest { public static Configuration getConfig() { final ArrayList<TestPair> list = new ArrayList<TestPair>(); list.add(new TestPair(InvariantViolation, - "public_examples/TLC/InvariantViolation")); + "build/prob_examples/public_examples/TLC/InvariantViolation")); return getConfiguration(list); } } diff --git a/src/test/java/de/tlc4b/tlc/integration/probprivate/LawsTest.java b/src/test/java/de/tlc4b/tlc/integration/probprivate/LawsTest.java index 0a48252e85825bf62a0e9edd82de3c6e28441785..fc8eb3208005a666981a864cd51e4e8280807a52 100644 --- a/src/test/java/de/tlc4b/tlc/integration/probprivate/LawsTest.java +++ b/src/test/java/de/tlc4b/tlc/integration/probprivate/LawsTest.java @@ -1,86 +1,83 @@ -package de.tlc4b.tlc.integration.probprivate; - -import static de.tlc4b.tlc.TLCResults.TLCResult.*; -import static de.tlc4b.util.TestUtil.test; -import static org.junit.Assert.assertEquals; - - - - - -import org.junit.Test; - -import de.tlc4b.TLC4BGlobals; - -public class LawsTest { - - @Test - public void BoolLaws() throws Exception { - TLC4BGlobals.setDeleteOnExit(true); - String[] a = new String[] { "public_examples/TLC/Laws/BoolLaws.mch"}; - assertEquals(NoError, test(a)); - } - - @Test - public void BoolWithArithLaws() throws Exception { - TLC4BGlobals.setDeleteOnExit(true); - String[] a = new String[] { "public_examples/TLC/Laws/BoolWithArithLaws.mch", "-nodead"}; - assertEquals(NoError, test(a)); - } - - @Test - public void FunLaws() throws Exception { - TLC4BGlobals.setDeleteOnExit(true); - String[] a = new String[] { "public_examples/TLC/Laws/FunLaws.mch"}; - assertEquals(NoError, test(a)); - } - - @Test - public void FunLawsWithLambda() throws Exception { - TLC4BGlobals.setDeleteOnExit(true); - String[] a = new String[] { "public_examples/TLC/Laws/FunLawsWithLambda.mch"}; - assertEquals(NoError, test(a)); - } - - @Test - public void RelLaws_TLC() throws Exception { - TLC4BGlobals.setDeleteOnExit(true); - String[] a = new String[] { "public_examples/TLC/Laws/RelLaws_TLC.mch"}; - assertEquals(Goal, test(a)); - } - - @Test - public void BoolLaws_SetCompr() throws Exception { - TLC4BGlobals.setDeleteOnExit(true); - String[] a = new String[] { "public_examples/TLC/Laws/BoolLaws_SetCompr.mch"}; - assertEquals(NoError, test(a)); - } - - @Test - public void BoolLaws_SetComprCLPFD() throws Exception { - TLC4BGlobals.setDeleteOnExit(true); - String[] a = new String[] { "public_examples/TLC/Laws/BoolLaws_SetComprCLPFD.mch"}; - assertEquals(NoError, test(a)); - } - - @Test - public void CardinalityLaws_TLC() throws Exception { - TLC4BGlobals.setDeleteOnExit(true); - String[] a = new String[] { "public_examples/TLC/Laws/CardinalityLaws_TLC.mch", "-nodead"}; - assertEquals(NoError, test(a)); - } - - @Test - public void EqualityLaws() throws Exception { - TLC4BGlobals.setDeleteOnExit(true); - String[] a = new String[] { "public_examples/TLC/Laws/EqualityLaws.mch", "-nodead"}; - assertEquals(NoError, test(a)); - } - - @Test - public void SubsetLaws() throws Exception { - TLC4BGlobals.setDeleteOnExit(true); - String[] a = new String[] { "public_examples/TLC/Laws/SubsetLaws.mch", "-nodead"}; - assertEquals(NoError, test(a)); - } -} +package de.tlc4b.tlc.integration.probprivate; + +import de.tlc4b.TLC4BGlobals; + +import org.junit.Test; + +import static de.tlc4b.tlc.TLCResults.TLCResult.Goal; +import static de.tlc4b.tlc.TLCResults.TLCResult.NoError; +import static de.tlc4b.util.TestUtil.test; +import static org.junit.Assert.assertEquals; + +public class LawsTest { + + @Test + public void BoolLaws() throws Exception { + TLC4BGlobals.setDeleteOnExit(true); + String[] a = new String[] { "build/prob_examples/public_examples/TLC/Laws/BoolLaws.mch"}; + assertEquals(NoError, test(a)); + } + + @Test + public void BoolWithArithLaws() throws Exception { + TLC4BGlobals.setDeleteOnExit(true); + String[] a = new String[] { "build/prob_examples/public_examples/TLC/Laws/BoolWithArithLaws.mch", "-nodead"}; + assertEquals(NoError, test(a)); + } + + @Test + public void FunLaws() throws Exception { + TLC4BGlobals.setDeleteOnExit(true); + String[] a = new String[] { "build/prob_examples/public_examples/TLC/Laws/FunLaws.mch"}; + assertEquals(NoError, test(a)); + } + + @Test + public void FunLawsWithLambda() throws Exception { + TLC4BGlobals.setDeleteOnExit(true); + String[] a = new String[] { "build/prob_examples/public_examples/TLC/Laws/FunLawsWithLambda.mch"}; + assertEquals(NoError, test(a)); + } + + @Test + public void RelLaws_TLC() throws Exception { + TLC4BGlobals.setDeleteOnExit(true); + String[] a = new String[] { "build/prob_examples/public_examples/TLC/Laws/RelLaws_TLC.mch"}; + assertEquals(Goal, test(a)); + } + + @Test + public void BoolLaws_SetCompr() throws Exception { + TLC4BGlobals.setDeleteOnExit(true); + String[] a = new String[] { "build/prob_examples/public_examples/TLC/Laws/BoolLaws_SetCompr.mch"}; + assertEquals(NoError, test(a)); + } + + @Test + public void BoolLaws_SetComprCLPFD() throws Exception { + TLC4BGlobals.setDeleteOnExit(true); + String[] a = new String[] { "build/prob_examples/public_examples/TLC/Laws/BoolLaws_SetComprCLPFD.mch"}; + assertEquals(NoError, test(a)); + } + + @Test + public void CardinalityLaws_TLC() throws Exception { + TLC4BGlobals.setDeleteOnExit(true); + String[] a = new String[] { "build/prob_examples/public_examples/TLC/Laws/CardinalityLaws_TLC.mch", "-nodead"}; + assertEquals(NoError, test(a)); + } + + @Test + public void EqualityLaws() throws Exception { + TLC4BGlobals.setDeleteOnExit(true); + String[] a = new String[] { "build/prob_examples/public_examples/TLC/Laws/EqualityLaws.mch", "-nodead"}; + assertEquals(NoError, test(a)); + } + + @Test + public void SubsetLaws() throws Exception { + TLC4BGlobals.setDeleteOnExit(true); + String[] a = new String[] { "build/prob_examples/public_examples/TLC/Laws/SubsetLaws.mch", "-nodead"}; + assertEquals(NoError, test(a)); + } +} diff --git a/src/test/java/de/tlc4b/tlc/integration/probprivate/NoErrorTest.java b/src/test/java/de/tlc4b/tlc/integration/probprivate/NoErrorTest.java index 8605ab1f7c6196d2dd345385d36bb1d24f6b9c84..e5c0fe4d6c31cd8fe9f8b68deb26340bfcfa6615 100644 --- a/src/test/java/de/tlc4b/tlc/integration/probprivate/NoErrorTest.java +++ b/src/test/java/de/tlc4b/tlc/integration/probprivate/NoErrorTest.java @@ -38,7 +38,7 @@ public class NoErrorTest extends AbstractParseMachineTest { public static Configuration getConfig() { final ArrayList<TestPair> list = new ArrayList<TestPair>(); list.add(new TestPair(NoError, - "public_examples/TLC/NoError")); + "build/prob_examples/public_examples/TLC/NoError")); return getConfiguration(list); } diff --git a/src/test/java/de/tlc4b/tlc/integration/probprivate/WellDefinednessTest.java b/src/test/java/de/tlc4b/tlc/integration/probprivate/WellDefinednessTest.java index f92a4e25538e6a9295ea9f1dede517f93846b66f..2004cd1f1d4e88bf6a9a2d450cd0f771b868db01 100644 --- a/src/test/java/de/tlc4b/tlc/integration/probprivate/WellDefinednessTest.java +++ b/src/test/java/de/tlc4b/tlc/integration/probprivate/WellDefinednessTest.java @@ -1,21 +1,21 @@ package de.tlc4b.tlc.integration.probprivate; -import static de.tlc4b.tlc.TLCResults.TLCResult.*; -import static de.tlc4b.util.TestUtil.test; -import static org.junit.Assert.assertEquals; - import java.io.File; import java.util.ArrayList; -import org.junit.Test; -import org.junit.runner.RunWith; - import de.tlc4b.tlc.TLCResults.TLCResult; import de.tlc4b.util.AbstractParseMachineTest; import de.tlc4b.util.PolySuite; -import de.tlc4b.util.TestPair; import de.tlc4b.util.PolySuite.Config; import de.tlc4b.util.PolySuite.Configuration; +import de.tlc4b.util.TestPair; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static de.tlc4b.tlc.TLCResults.TLCResult.WellDefinednessError; +import static de.tlc4b.util.TestUtil.test; +import static org.junit.Assert.assertEquals; @RunWith(PolySuite.class) public class WellDefinednessTest extends AbstractParseMachineTest { @@ -37,7 +37,7 @@ public class WellDefinednessTest extends AbstractParseMachineTest { @Config public static Configuration getConfig() { final ArrayList<TestPair> list = new ArrayList<TestPair>(); - list.add(new TestPair(WellDefinednessError, "public_examples/TLC/WellDefinednessError")); + list.add(new TestPair(WellDefinednessError, "build/prob_examples/public_examples/TLC/WellDefinednessError")); return getConfiguration(list); } } diff --git a/src/test/java/de/tlc4b/typechecking/ArithmeticOperatorTest.java b/src/test/java/de/tlc4b/typechecking/ArithmeticOperatorTest.java index 0c1684186f2b7dd249b16406df4eaca94f45138f..8378d1e1f12a21697cf6f141d4a6afaef000a497 100644 --- a/src/test/java/de/tlc4b/typechecking/ArithmeticOperatorTest.java +++ b/src/test/java/de/tlc4b/typechecking/ArithmeticOperatorTest.java @@ -1,344 +1,344 @@ -package de.tlc4b.typechecking; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - - - -import de.be4.classicalb.core.parser.exceptions.BException; -import de.tlc4b.exceptions.TypeErrorException; - -public class ArithmeticOperatorTest { - - @Test - public void testInteger() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = INTEGER \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testIntegerException() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES 1 = INTEGER \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testNatural() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = NATURAL \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testNaturalException() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES 1 = NATURAL \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testNatural1() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = NATURAL1 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testNatural1Exception() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES 1 = NATURAL1 \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testInt() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = INT \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testIntException() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES 1 = INT \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testNat() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = NAT \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testNatException() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES 1 = NAT \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testNat1() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = NAT1 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testNat1Exception() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES 1 = NAT1 \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testInterval() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = 1..3 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testIntervalException() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES 1 = 1..3 \n" + "END"; - new TestTypechecker(machine); - } - - @Test(expected = TypeErrorException.class) - public void testIntervalException2() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = TRUE..3 \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testMaxInt() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = MAXINT \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testMaxIntException() throws BException { - String machine = "MACHINE test\n" + "PROPERTIES {} = MAXINT \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testMinInt() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = MININT \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testMinIntException() throws BException { - String machine = "MACHINE test\n" + "PROPERTIES {} = MININT \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testGreaterThan() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" - + "PROPERTIES k > k2 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("INTEGER", t.constants.get("k2").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testGreaterThanException() throws BException { - String machine = "MACHINE test\n" + "PROPERTIES TRUE > 1 \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testLessThan() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" - + "PROPERTIES k < k2 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("INTEGER", t.constants.get("k2").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testLessThanException() throws BException { - String machine = "MACHINE test\n" + "PROPERTIES TRUE < 1 \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testGreaterEquals() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" - + "PROPERTIES k >= k2 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("INTEGER", t.constants.get("k2").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testGreaterEqualsException() throws BException { - String machine = "MACHINE test\n" + "PROPERTIES TRUE >= 1 \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testLessEquals() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" - + "PROPERTIES k <= k2 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("INTEGER", t.constants.get("k2").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testLessEqualsException() throws BException { - String machine = "MACHINE test\n" + "PROPERTIES TRUE <= 1 \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testMin() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" - + "PROPERTIES k = min(k2) \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testMinException() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k\n" - + "PROPERTIES TRUE = min(k) \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testMax() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" - + "PROPERTIES k = max(k2) \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testMaxException() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k\n" - + "PROPERTIES TRUE = max(k) \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testAdd() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2,k3 \n" - + "PROPERTIES k = k2 + k3 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("INTEGER", t.constants.get("k2").toString()); - assertEquals("INTEGER", t.constants.get("k3").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testAddException() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k\n" - + "PROPERTIES TRUE = 1 + 1 \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testDivision() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2,k3 \n" - + "PROPERTIES k = k2 / k3 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("INTEGER", t.constants.get("k2").toString()); - assertEquals("INTEGER", t.constants.get("k3").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testDivisionException() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k\n" - + "PROPERTIES TRUE = 1 / 1 \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testPowerOf() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2,k3 \n" - + "PROPERTIES k = k2 ** k3 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("INTEGER", t.constants.get("k2").toString()); - assertEquals("INTEGER", t.constants.get("k3").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testPowerOfException() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k\n" - + "PROPERTIES TRUE = 1 ** 1 \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testModulo() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2,k3 \n" - + "PROPERTIES k = k2 mod k3 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("INTEGER", t.constants.get("k2").toString()); - assertEquals("INTEGER", t.constants.get("k3").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testModuloException() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k\n" - + "PROPERTIES TRUE = 1 mod 1 \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testSuccessor() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = succ \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testSuccsessorException() throws BException { - String machine = "MACHINE test\n" + "PROPERTIES TRUE = succ \n" - + "END"; - new TestTypechecker(machine); - } - - @Test - public void testPredecessor() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = pred \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testPredecessorException() throws BException { - String machine = "MACHINE test\n" + "PROPERTIES TRUE = pred \n" - + "END"; - new TestTypechecker(machine); - } - -} +package de.tlc4b.typechecking; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + + + +import de.be4.classicalb.core.parser.exceptions.BException; +import de.tlc4b.exceptions.TypeErrorException; + +public class ArithmeticOperatorTest { + + @Test + public void testInteger() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = INTEGER \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testIntegerException() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES 1 = INTEGER \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testNatural() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = NATURAL \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testNaturalException() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES 1 = NATURAL \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testNatural1() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = NATURAL1 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testNatural1Exception() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES 1 = NATURAL1 \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testInt() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = INT \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testIntException() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES 1 = INT \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testNat() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = NAT \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testNatException() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES 1 = NAT \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testNat1() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = NAT1 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testNat1Exception() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES 1 = NAT1 \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testInterval() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = 1..3 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testIntervalException() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES 1 = 1..3 \n" + "END"; + new TestTypechecker(machine); + } + + @Test(expected = TypeErrorException.class) + public void testIntervalException2() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = TRUE..3 \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testMaxInt() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = MAXINT \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testMaxIntException() throws BException { + String machine = "MACHINE test\n" + "PROPERTIES {} = MAXINT \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testMinInt() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = MININT \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testMinIntException() throws BException { + String machine = "MACHINE test\n" + "PROPERTIES {} = MININT \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testGreaterThan() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" + + "PROPERTIES k > k2 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("INTEGER", t.constants.get("k2").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testGreaterThanException() throws BException { + String machine = "MACHINE test\n" + "PROPERTIES TRUE > 1 \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testLessThan() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" + + "PROPERTIES k < k2 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("INTEGER", t.constants.get("k2").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testLessThanException() throws BException { + String machine = "MACHINE test\n" + "PROPERTIES TRUE < 1 \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testGreaterEquals() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" + + "PROPERTIES k >= k2 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("INTEGER", t.constants.get("k2").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testGreaterEqualsException() throws BException { + String machine = "MACHINE test\n" + "PROPERTIES TRUE >= 1 \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testLessEquals() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" + + "PROPERTIES k <= k2 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("INTEGER", t.constants.get("k2").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testLessEqualsException() throws BException { + String machine = "MACHINE test\n" + "PROPERTIES TRUE <= 1 \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testMin() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" + + "PROPERTIES k = min(k2) \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testMinException() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k\n" + + "PROPERTIES TRUE = min(k) \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testMax() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" + + "PROPERTIES k = max(k2) \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testMaxException() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k\n" + + "PROPERTIES TRUE = max(k) \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testAdd() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2,k3 \n" + + "PROPERTIES k = k2 + k3 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("INTEGER", t.constants.get("k2").toString()); + assertEquals("INTEGER", t.constants.get("k3").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testAddException() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k\n" + + "PROPERTIES TRUE = 1 + 1 \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testDivision() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2,k3 \n" + + "PROPERTIES k = k2 / k3 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("INTEGER", t.constants.get("k2").toString()); + assertEquals("INTEGER", t.constants.get("k3").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testDivisionException() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k\n" + + "PROPERTIES TRUE = 1 / 1 \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testPowerOf() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2,k3 \n" + + "PROPERTIES k = k2 ** k3 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("INTEGER", t.constants.get("k2").toString()); + assertEquals("INTEGER", t.constants.get("k3").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testPowerOfException() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k\n" + + "PROPERTIES TRUE = 1 ** 1 \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testModulo() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2,k3 \n" + + "PROPERTIES k = k2 mod k3 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("INTEGER", t.constants.get("k2").toString()); + assertEquals("INTEGER", t.constants.get("k3").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testModuloException() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k\n" + + "PROPERTIES TRUE = 1 mod 1 \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testSuccessor() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = succ \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testSuccsessorException() throws BException { + String machine = "MACHINE test\n" + "PROPERTIES TRUE = succ \n" + + "END"; + new TestTypechecker(machine); + } + + @Test + public void testPredecessor() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = pred \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testPredecessorException() throws BException { + String machine = "MACHINE test\n" + "PROPERTIES TRUE = pred \n" + + "END"; + new TestTypechecker(machine); + } + +} diff --git a/src/test/java/de/tlc4b/typechecking/BooleansTest.java b/src/test/java/de/tlc4b/typechecking/BooleansTest.java index 9873e9081d7b4b8a8be0cbb5a791f0c376b4aad8..cb59521b3001f72a42537a1ece7afebdb6343e04 100644 --- a/src/test/java/de/tlc4b/typechecking/BooleansTest.java +++ b/src/test/java/de/tlc4b/typechecking/BooleansTest.java @@ -1,75 +1,75 @@ -package de.tlc4b.typechecking; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - - - -import de.be4.classicalb.core.parser.exceptions.BException; -import de.tlc4b.exceptions.TypeErrorException; - -public class BooleansTest { - - @Test - public void testTrue() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = TRUE \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("BOOL", t.constants.get("k").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testTrueException() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = TRUE \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testFalse() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = FALSE \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("BOOL", t.constants.get("k").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testFalseException() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = FALSE \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testBool() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = BOOL \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(BOOL)", t.constants.get("k").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testBoolException() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = BOOL \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testConvertPredicate() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = bool(1=1) \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("BOOL", t.constants.get("k").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testConvertPredicateException() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = bool(1=1) \n" + "END"; - new TestTypechecker(machine); - } - - -} +package de.tlc4b.typechecking; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + + + +import de.be4.classicalb.core.parser.exceptions.BException; +import de.tlc4b.exceptions.TypeErrorException; + +public class BooleansTest { + + @Test + public void testTrue() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = TRUE \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("BOOL", t.constants.get("k").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testTrueException() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = TRUE \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testFalse() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = FALSE \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("BOOL", t.constants.get("k").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testFalseException() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = FALSE \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testBool() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = BOOL \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(BOOL)", t.constants.get("k").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testBoolException() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = BOOL \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testConvertPredicate() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = bool(1=1) \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("BOOL", t.constants.get("k").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testConvertPredicateException() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = bool(1=1) \n" + "END"; + new TestTypechecker(machine); + } + + +} diff --git a/src/test/java/de/tlc4b/typechecking/FunctionTest.java b/src/test/java/de/tlc4b/typechecking/FunctionTest.java index 8a815cc45214ac715e2eb1146473871e9e0f9e56..c7068bd4ca36b2120a89f598dd98967cf376f9b4 100644 --- a/src/test/java/de/tlc4b/typechecking/FunctionTest.java +++ b/src/test/java/de/tlc4b/typechecking/FunctionTest.java @@ -1,207 +1,207 @@ -package de.tlc4b.typechecking; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - - - -import de.be4.classicalb.core.parser.exceptions.BException; -import de.tlc4b.exceptions.TypeErrorException; - -public class FunctionTest { - - - @Test - public void testLambda() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = %x.(x : {1} | 1) \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); - } - - @Test - public void testOverride() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k,k2,p \n" - + "PROPERTIES p = 1 & k = %x.(x : {1} | 1) & k2 = k <+ {1|->2}\n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); - assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k2").toString()); - } - - - @Test - public void testSetOperatorOnFunction() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = %x.(x : {1} | 1) \\/ %x.(x : {1} | 1) \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER*INTEGER)", t.constants.get("k").toString()); - } - - @Test - public void testSetOperatorOnFunction2() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = k \\/ k & k(1) = 1 \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER*INTEGER)", t.constants.get("k").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testLambdaException() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES %x.(x : {1} | TRUE) = %x.(x : {1} | 1) \n" - + "END"; - new TestTypechecker(machine); - } - - - @Test - public void testFunctionCall() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k(TRUE) = 1 \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("FUNC(BOOL,INTEGER)", t.constants.get("k").toString()); - } - - @Test - public void testFunctionCall2Arguments() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k(TRUE,1) = 1 \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("FUNC(BOOL*INTEGER,INTEGER)", t.constants.get("k").toString()); - } - - @Test - public void testFunctionCallPair() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k(TRUE|->1) = 1 \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("FUNC(BOOL*INTEGER,INTEGER)", t.constants.get("k").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testFunctionCallException() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = %x.(x : {1} | TRUE) & k(1,1) = 1 \n" - + "END"; - new TestTypechecker(machine); - } - - @Test - public void testFunctionCallSucc() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k,k2 \n" - + "PROPERTIES k = succ(k2) \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("INTEGER", t.constants.get("k2").toString()); - } - - @Test - public void testTotalFunction() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = INT --> INT \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(FUNC(INTEGER,INTEGER))", t.constants.get("k").toString()); - } - - @Test - public void testTotalFunction2() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2 \n" - + "PROPERTIES k = INT --> INT & k2 : k & k2 = k2 \\/ k2 \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(POW(INTEGER*INTEGER))", t.constants.get("k").toString()); - } - - @Test - public void testDomain() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2 \n" - + "PROPERTIES k : INT --> INT & k2 = dom(k) \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); - } - - @Test - public void testDomain2() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = dom(%x.(x = 1| 1)) \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testDomainException() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = dom(%x.(x = 1| 1)) \n" - + "END"; - new TestTypechecker(machine); - } - - - @Test - public void testRange() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2 \n" - + "PROPERTIES k : INT --> INT & k2 = ran(k) \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); - } - - @Test - public void testRange2() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = ran(%x.(x = 1| 1)) \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testRangeException() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = ran(%x.(x = 1| 1)) \n" - + "END"; - new TestTypechecker(machine); - } - - - @Test - public void testPartialFunction() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = INT +-> INT \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(FUNC(INTEGER,INTEGER))", t.constants.get("k").toString()); - } - - -} +package de.tlc4b.typechecking; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + + + +import de.be4.classicalb.core.parser.exceptions.BException; +import de.tlc4b.exceptions.TypeErrorException; + +public class FunctionTest { + + + @Test + public void testLambda() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = %x.(x : {1} | 1) \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); + } + + @Test + public void testOverride() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k,k2,p \n" + + "PROPERTIES p = 1 & k = %x.(x : {1} | 1) & k2 = k <+ {1|->2}\n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); + assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k2").toString()); + } + + + @Test + public void testSetOperatorOnFunction() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = %x.(x : {1} | 1) \\/ %x.(x : {1} | 1) \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER*INTEGER)", t.constants.get("k").toString()); + } + + @Test + public void testSetOperatorOnFunction2() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = k \\/ k & k(1) = 1 \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER*INTEGER)", t.constants.get("k").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testLambdaException() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES %x.(x : {1} | TRUE) = %x.(x : {1} | 1) \n" + + "END"; + new TestTypechecker(machine); + } + + + @Test + public void testFunctionCall() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k(TRUE) = 1 \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("FUNC(BOOL,INTEGER)", t.constants.get("k").toString()); + } + + @Test + public void testFunctionCall2Arguments() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k(TRUE,1) = 1 \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("FUNC(BOOL*INTEGER,INTEGER)", t.constants.get("k").toString()); + } + + @Test + public void testFunctionCallPair() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k(TRUE|->1) = 1 \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("FUNC(BOOL*INTEGER,INTEGER)", t.constants.get("k").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testFunctionCallException() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = %x.(x : {1} | TRUE) & k(1,1) = 1 \n" + + "END"; + new TestTypechecker(machine); + } + + @Test + public void testFunctionCallSucc() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k,k2 \n" + + "PROPERTIES k = succ(k2) \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("INTEGER", t.constants.get("k2").toString()); + } + + @Test + public void testTotalFunction() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = INT --> INT \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(FUNC(INTEGER,INTEGER))", t.constants.get("k").toString()); + } + + @Test + public void testTotalFunction2() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2 \n" + + "PROPERTIES k = INT --> INT & k2 : k & k2 = k2 \\/ k2 \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(POW(INTEGER*INTEGER))", t.constants.get("k").toString()); + } + + @Test + public void testDomain() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2 \n" + + "PROPERTIES k : INT --> INT & k2 = dom(k) \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); + } + + @Test + public void testDomain2() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = dom(%x.(x = 1| 1)) \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testDomainException() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = dom(%x.(x = 1| 1)) \n" + + "END"; + new TestTypechecker(machine); + } + + + @Test + public void testRange() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2 \n" + + "PROPERTIES k : INT --> INT & k2 = ran(k) \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); + } + + @Test + public void testRange2() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = ran(%x.(x = 1| 1)) \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testRangeException() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = ran(%x.(x = 1| 1)) \n" + + "END"; + new TestTypechecker(machine); + } + + + @Test + public void testPartialFunction() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = INT +-> INT \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(FUNC(INTEGER,INTEGER))", t.constants.get("k").toString()); + } + + +} diff --git a/src/test/java/de/tlc4b/typechecking/LogicalOperatorTest.java b/src/test/java/de/tlc4b/typechecking/LogicalOperatorTest.java index 335f7d0bc889a9ddf173cd0950f611b4be379243..3b59e3bdb98534fcbda8d8f80b5959b0db987342 100644 --- a/src/test/java/de/tlc4b/typechecking/LogicalOperatorTest.java +++ b/src/test/java/de/tlc4b/typechecking/LogicalOperatorTest.java @@ -1,48 +1,48 @@ -package de.tlc4b.typechecking; - -import org.junit.Test; - -import de.be4.classicalb.core.parser.exceptions.BException; - -public class LogicalOperatorTest { - - @Test - public void testAnd() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = 1 & 1 = 1 \n" - + "END"; - new TestTypechecker(machine); - } - - @Test - public void testOr() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = 1 or 1 = 1 \n" - + "END"; - new TestTypechecker(machine); - } - - @Test - public void testImplication() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = 1 => 1 = 1 \n" - + "END"; - new TestTypechecker(machine); - } - - @Test - public void testEquivalence() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = 1 <=> 1 = 1 \n" - + "END"; - new TestTypechecker(machine); - } - - @Test - public void testNot() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES not(1 = 1) \n" - + "END"; - new TestTypechecker(machine); - } -} +package de.tlc4b.typechecking; + +import org.junit.Test; + +import de.be4.classicalb.core.parser.exceptions.BException; + +public class LogicalOperatorTest { + + @Test + public void testAnd() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = 1 & 1 = 1 \n" + + "END"; + new TestTypechecker(machine); + } + + @Test + public void testOr() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = 1 or 1 = 1 \n" + + "END"; + new TestTypechecker(machine); + } + + @Test + public void testImplication() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = 1 => 1 = 1 \n" + + "END"; + new TestTypechecker(machine); + } + + @Test + public void testEquivalence() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = 1 <=> 1 = 1 \n" + + "END"; + new TestTypechecker(machine); + } + + @Test + public void testNot() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES not(1 = 1) \n" + + "END"; + new TestTypechecker(machine); + } +} diff --git a/src/test/java/de/tlc4b/typechecking/MachineClausesTest.java b/src/test/java/de/tlc4b/typechecking/MachineClausesTest.java index 10f6d984c41901a6a4ca5b222a43d41f760dcdc6..c789f6737409967d3971b2f4d72224dc1ff452e8 100644 --- a/src/test/java/de/tlc4b/typechecking/MachineClausesTest.java +++ b/src/test/java/de/tlc4b/typechecking/MachineClausesTest.java @@ -1,99 +1,99 @@ -package de.tlc4b.typechecking; - -import static org.junit.Assert.*; - -import org.junit.Test; - - - -import de.be4.classicalb.core.parser.exceptions.BException; -import de.tlc4b.exceptions.TypeErrorException; - -public class MachineClausesTest { - - @Test(expected = TypeErrorException.class) - public void testUntypedConstant() throws BException { - String machine = "MACHINE test \n" + "CONSTANTS k\n" - + "PROPERTIES 1 = 1 \n" + "END"; - new TestTypechecker(machine); - } - - @Test(expected = TypeErrorException.class) - public void testUntypedVariable() throws BException { - String machine = "MACHINE test \n" + "VARIABLES x\n" - + "INVARIANT 1 = 1 \n" + "INITIALISATION x := 1 \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testVariable() throws BException { - String machine = "MACHINE test \n" + "VARIABLES x\n" - + "INVARIANT x = 1 \n" + "INITIALISATION x := 1 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.variables.get("x").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testUntypedParameter() throws BException { - String machine = "MACHINE test(a) \n" + "CONSTRAINTS 1 = 1 \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testScalarParameter() throws BException { - String machine = "MACHINE test(a) \n" + "CONSTRAINTS a = 1 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.parameters.get("a").toString()); - } - - @Test - public void testParameter() throws BException { - String machine = "MACHINE test(A) \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(A)", t.parameters.get("A").toString()); - } - - - @Test (expected = TypeErrorException.class) - public void testInitialisationError() throws BException { - String machine = "MACHINE test \n" + "VARIABLES x\n" - + "INVARIANT x = 1 \n" + "INITIALISATION x := TRUE \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testInitialisation() throws BException { - String machine = "MACHINE test \n" + "VARIABLES x\n" - + "INVARIANT x = 1 \n" + "INITIALISATION x := 1 \n" + "END"; - new TestTypechecker(machine); - } - - - @Test - public void testOperations() throws BException { - String machine = "MACHINE test \n" + "VARIABLES x\n" - + "INVARIANT x = 1 \n" + "INITIALISATION x := 1 \n" - + "OPERATIONS foo = PRE 1 = 1 THEN x := 1 END \n" - + "END"; - new TestTypechecker(machine); - } - - @Test (expected = TypeErrorException.class) - public void testOperationsError() throws BException { - String machine = "MACHINE test \n" + "VARIABLES x\n" - + "INVARIANT x = 1 \n" + "INITIALISATION x := 1 \n" - + "OPERATIONS foo = PRE 1 = TRUE THEN x := 1 END \n" - + "END"; - new TestTypechecker(machine); - } - - @Test (expected = TypeErrorException.class) - public void testSubstitution() throws BException { - String machine = "MACHINE test \n" + "VARIABLES x,y \n" - + "INVARIANT x = 1 & y = 1 \n" + "INITIALISATION x,y := 1,TRUE \n" - + "END"; - new TestTypechecker(machine); - } - - -} +package de.tlc4b.typechecking; + +import static org.junit.Assert.*; + +import org.junit.Test; + + + +import de.be4.classicalb.core.parser.exceptions.BException; +import de.tlc4b.exceptions.TypeErrorException; + +public class MachineClausesTest { + + @Test(expected = TypeErrorException.class) + public void testUntypedConstant() throws BException { + String machine = "MACHINE test \n" + "CONSTANTS k\n" + + "PROPERTIES 1 = 1 \n" + "END"; + new TestTypechecker(machine); + } + + @Test(expected = TypeErrorException.class) + public void testUntypedVariable() throws BException { + String machine = "MACHINE test \n" + "VARIABLES x\n" + + "INVARIANT 1 = 1 \n" + "INITIALISATION x := 1 \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testVariable() throws BException { + String machine = "MACHINE test \n" + "VARIABLES x\n" + + "INVARIANT x = 1 \n" + "INITIALISATION x := 1 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.variables.get("x").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testUntypedParameter() throws BException { + String machine = "MACHINE test(a) \n" + "CONSTRAINTS 1 = 1 \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testScalarParameter() throws BException { + String machine = "MACHINE test(a) \n" + "CONSTRAINTS a = 1 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.parameters.get("a").toString()); + } + + @Test + public void testParameter() throws BException { + String machine = "MACHINE test(A) \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(A)", t.parameters.get("A").toString()); + } + + + @Test (expected = TypeErrorException.class) + public void testInitialisationError() throws BException { + String machine = "MACHINE test \n" + "VARIABLES x\n" + + "INVARIANT x = 1 \n" + "INITIALISATION x := TRUE \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testInitialisation() throws BException { + String machine = "MACHINE test \n" + "VARIABLES x\n" + + "INVARIANT x = 1 \n" + "INITIALISATION x := 1 \n" + "END"; + new TestTypechecker(machine); + } + + + @Test + public void testOperations() throws BException { + String machine = "MACHINE test \n" + "VARIABLES x\n" + + "INVARIANT x = 1 \n" + "INITIALISATION x := 1 \n" + + "OPERATIONS foo = PRE 1 = 1 THEN x := 1 END \n" + + "END"; + new TestTypechecker(machine); + } + + @Test (expected = TypeErrorException.class) + public void testOperationsError() throws BException { + String machine = "MACHINE test \n" + "VARIABLES x\n" + + "INVARIANT x = 1 \n" + "INITIALISATION x := 1 \n" + + "OPERATIONS foo = PRE 1 = TRUE THEN x := 1 END \n" + + "END"; + new TestTypechecker(machine); + } + + @Test (expected = TypeErrorException.class) + public void testSubstitution() throws BException { + String machine = "MACHINE test \n" + "VARIABLES x,y \n" + + "INVARIANT x = 1 & y = 1 \n" + "INITIALISATION x,y := 1,TRUE \n" + + "END"; + new TestTypechecker(machine); + } + + +} diff --git a/src/test/java/de/tlc4b/typechecking/MinusTest.java b/src/test/java/de/tlc4b/typechecking/MinusTest.java index f1d93ba1e9281560ead85302e7aa5e982b52e56c..d6f09d572778814871c1c93a50a8dd1cfdbc552e 100644 --- a/src/test/java/de/tlc4b/typechecking/MinusTest.java +++ b/src/test/java/de/tlc4b/typechecking/MinusTest.java @@ -1,102 +1,102 @@ -package de.tlc4b.typechecking; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - - - -import de.be4.classicalb.core.parser.exceptions.BException; -import de.tlc4b.exceptions.TypeErrorException; - -public class MinusTest { - - @Test - public void testMinus() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" - + "PROPERTIES k = k2 - 1 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("INTEGER", t.constants.get("k2").toString()); - } - - @Test - public void testMinus2() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" - + "PROPERTIES 1 = k - k2 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("INTEGER", t.constants.get("k2").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testMinusException() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k\n" - + "PROPERTIES TRUE = 1 - 1 \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testSetSubstraction() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" - + "PROPERTIES {1} = k - k2 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); - } - - @Test - public void testSetSubstraction2() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" - + "PROPERTIES k = k2 - {1} \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testSetSubstractionVsMinus() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = 1 - {1} \n" + "END"; - new TestTypechecker(machine); - } - - @Test(expected = TypeErrorException.class) - public void testSetSubstractionVsMinus2() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES 1 = k - {1} \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testSetSubstraction3() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2,k3 \n" - + "PROPERTIES k = k2 - k3 & k3 = {1} \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k3").toString()); - } - - @Test - public void testSetSubstraction4() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2,k3 \n" - + "PROPERTIES k = k2 - k3 - {1} \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k3").toString()); - } - - @Test - public void testSetSubstraction5() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2,k3,k4 \n" - + "PROPERTIES k - k2 - k3 = k4 - {1} \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k3").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k4").toString()); - } - -} +package de.tlc4b.typechecking; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + + + +import de.be4.classicalb.core.parser.exceptions.BException; +import de.tlc4b.exceptions.TypeErrorException; + +public class MinusTest { + + @Test + public void testMinus() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" + + "PROPERTIES k = k2 - 1 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("INTEGER", t.constants.get("k2").toString()); + } + + @Test + public void testMinus2() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" + + "PROPERTIES 1 = k - k2 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("INTEGER", t.constants.get("k2").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testMinusException() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k\n" + + "PROPERTIES TRUE = 1 - 1 \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testSetSubstraction() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" + + "PROPERTIES {1} = k - k2 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); + } + + @Test + public void testSetSubstraction2() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" + + "PROPERTIES k = k2 - {1} \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testSetSubstractionVsMinus() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = 1 - {1} \n" + "END"; + new TestTypechecker(machine); + } + + @Test(expected = TypeErrorException.class) + public void testSetSubstractionVsMinus2() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES 1 = k - {1} \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testSetSubstraction3() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2,k3 \n" + + "PROPERTIES k = k2 - k3 & k3 = {1} \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k3").toString()); + } + + @Test + public void testSetSubstraction4() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2,k3 \n" + + "PROPERTIES k = k2 - k3 - {1} \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k3").toString()); + } + + @Test + public void testSetSubstraction5() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2,k3,k4 \n" + + "PROPERTIES k - k2 - k3 = k4 - {1} \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k3").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k4").toString()); + } + +} diff --git a/src/test/java/de/tlc4b/typechecking/ModelValuesTest.java b/src/test/java/de/tlc4b/typechecking/ModelValuesTest.java index 83709a0c8b51656e1af8ce0dcbb85b5218f6c61a..4c6121e83545d3cf891a7e373a320df73ccbd759 100644 --- a/src/test/java/de/tlc4b/typechecking/ModelValuesTest.java +++ b/src/test/java/de/tlc4b/typechecking/ModelValuesTest.java @@ -1,31 +1,30 @@ -package de.tlc4b.typechecking; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - -import de.be4.classicalb.core.parser.exceptions.BException; - -public class ModelValuesTest { - - @Test - public void testEnumeratedSet() throws BException { - String machine = "MACHINE test\n" - + "SETS S = {a,b}" - + "CONSTANTS k \n" - + "PROPERTIES k = a \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - System.out.println(t.constants.get("k").toString()); - assertEquals("S", t.constants.get("k").toString()); - } - - @Test - public void testEnumeratedSet1() throws BException { - String machine = "MACHINE test\n" - + "SETS S = {a,b}" - + "CONSTANTS k \n" - + "PROPERTIES k = S \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(S)", t.constants.get("k").toString()); - } -} +package de.tlc4b.typechecking; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +import de.be4.classicalb.core.parser.exceptions.BException; + +public class ModelValuesTest { + + @Test + public void testEnumeratedSet() throws BException { + String machine = "MACHINE test\n" + + "SETS S = {a,b}" + + "CONSTANTS k \n" + + "PROPERTIES k = a \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("S", t.constants.get("k").toString()); + } + + @Test + public void testEnumeratedSet1() throws BException { + String machine = "MACHINE test\n" + + "SETS S = {a,b}" + + "CONSTANTS k \n" + + "PROPERTIES k = S \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(S)", t.constants.get("k").toString()); + } +} diff --git a/src/test/java/de/tlc4b/typechecking/MultTest.java b/src/test/java/de/tlc4b/typechecking/MultTest.java index d0797032d2e15fa4229329ec5de4f614e45240b3..b5a97a360cb8340e1ce582f0adcae406027bab81 100644 --- a/src/test/java/de/tlc4b/typechecking/MultTest.java +++ b/src/test/java/de/tlc4b/typechecking/MultTest.java @@ -1,173 +1,173 @@ -package de.tlc4b.typechecking; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - - - -import de.be4.classicalb.core.parser.exceptions.BException; -import de.tlc4b.exceptions.TypeErrorException; - -public class MultTest{ - - - @Test - public void testMult() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES 1 * 2 = k \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - } - - @Test - public void testMult2() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES 1 * 2 * 3 = k \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - } - - @Test - public void testMult3() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2, k3 \n" - + "PROPERTIES k * k2 * k3 = 4 \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("INTEGER", t.constants.get("k2").toString()); - assertEquals("INTEGER", t.constants.get("k3").toString()); - } - - @Test - public void testMult4() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2, k3 \n" - + "PROPERTIES k * 1 * k2 = k3 \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("INTEGER", t.constants.get("k2").toString()); - assertEquals("INTEGER", t.constants.get("k3").toString()); - } - - @Test - public void testMult5() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2, k3, k4 \n" - + "PROPERTIES k * k2 * k3 = k4 * 1 \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("INTEGER", t.constants.get("k2").toString()); - assertEquals("INTEGER", t.constants.get("k3").toString()); - assertEquals("INTEGER", t.constants.get("k4").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testMultException() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2 \n" - + "PROPERTIES TRUE = k * k2 \n" - + "END"; - new TestTypechecker(machine); - } - - @Test (expected = TypeErrorException.class) - public void testMultException2() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2 \n" - + "PROPERTIES k = TRUE * k2 \n" - + "END"; - new TestTypechecker(machine); - } - - @Test - public void testCart1() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2, k3 \n" - + "PROPERTIES k = k2 * k3 & k2 = {1} & k3 = {TRUE} \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER*BOOL)", t.constants.get("k").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); - assertEquals("POW(BOOL)", t.constants.get("k3").toString()); - } - - @Test - public void testCart2() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2 \n" - + "PROPERTIES k * k2 = {1} * {TRUE} \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - assertEquals("POW(BOOL)", t.constants.get("k2").toString()); - } - - @Test - public void testCart3() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2, k3 \n" - + "PROPERTIES k * k2 * k3 = {TRUE} * {1} * {TRUE} \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(BOOL)", t.constants.get("k").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); - assertEquals("POW(BOOL)", t.constants.get("k3").toString()); - } - - @Test - public void testCart4() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2, k3 \n" - + "PROPERTIES k * k2 * k3 = k2 * k3 * {1} \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k3").toString()); - } - - @Test - public void testCart5() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2, k3, k4 \n" - + "PROPERTIES k * k2 = k3 * k4 & k4 = {1} & k = {1} \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k3").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k4").toString()); - - } - - @Test - public void testCart6() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2 \n" - + "PROPERTIES k * k2 = k2 * {1} \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); - } - - @Test - public void testCart7() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2 \n" - + "PROPERTIES k2 * k = k * {1} \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); - } - -} +package de.tlc4b.typechecking; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + + + +import de.be4.classicalb.core.parser.exceptions.BException; +import de.tlc4b.exceptions.TypeErrorException; + +public class MultTest{ + + + @Test + public void testMult() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES 1 * 2 = k \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + } + + @Test + public void testMult2() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES 1 * 2 * 3 = k \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + } + + @Test + public void testMult3() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2, k3 \n" + + "PROPERTIES k * k2 * k3 = 4 \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("INTEGER", t.constants.get("k2").toString()); + assertEquals("INTEGER", t.constants.get("k3").toString()); + } + + @Test + public void testMult4() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2, k3 \n" + + "PROPERTIES k * 1 * k2 = k3 \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("INTEGER", t.constants.get("k2").toString()); + assertEquals("INTEGER", t.constants.get("k3").toString()); + } + + @Test + public void testMult5() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2, k3, k4 \n" + + "PROPERTIES k * k2 * k3 = k4 * 1 \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("INTEGER", t.constants.get("k2").toString()); + assertEquals("INTEGER", t.constants.get("k3").toString()); + assertEquals("INTEGER", t.constants.get("k4").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testMultException() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2 \n" + + "PROPERTIES TRUE = k * k2 \n" + + "END"; + new TestTypechecker(machine); + } + + @Test (expected = TypeErrorException.class) + public void testMultException2() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2 \n" + + "PROPERTIES k = TRUE * k2 \n" + + "END"; + new TestTypechecker(machine); + } + + @Test + public void testCart1() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2, k3 \n" + + "PROPERTIES k = k2 * k3 & k2 = {1} & k3 = {TRUE} \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER*BOOL)", t.constants.get("k").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); + assertEquals("POW(BOOL)", t.constants.get("k3").toString()); + } + + @Test + public void testCart2() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2 \n" + + "PROPERTIES k * k2 = {1} * {TRUE} \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + assertEquals("POW(BOOL)", t.constants.get("k2").toString()); + } + + @Test + public void testCart3() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2, k3 \n" + + "PROPERTIES k * k2 * k3 = {TRUE} * {1} * {TRUE} \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(BOOL)", t.constants.get("k").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); + assertEquals("POW(BOOL)", t.constants.get("k3").toString()); + } + + @Test + public void testCart4() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2, k3 \n" + + "PROPERTIES k * k2 * k3 = k2 * k3 * {1} \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k3").toString()); + } + + @Test + public void testCart5() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2, k3, k4 \n" + + "PROPERTIES k * k2 = k3 * k4 & k4 = {1} & k = {1} \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k3").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k4").toString()); + + } + + @Test + public void testCart6() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2 \n" + + "PROPERTIES k * k2 = k2 * {1} \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); + } + + @Test + public void testCart7() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2 \n" + + "PROPERTIES k2 * k = k * {1} \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); + } + +} diff --git a/src/test/java/de/tlc4b/typechecking/RecordTest.java b/src/test/java/de/tlc4b/typechecking/RecordTest.java index 6a90251f3059eebdd18000da7e5fbc27852c6ed2..97979c47c6bdfb1ea9a38349ad6ff6c7ea10d870 100644 --- a/src/test/java/de/tlc4b/typechecking/RecordTest.java +++ b/src/test/java/de/tlc4b/typechecking/RecordTest.java @@ -1,108 +1,108 @@ -package de.tlc4b.typechecking; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - - - -import de.be4.classicalb.core.parser.exceptions.BException; -import de.tlc4b.exceptions.TypeErrorException; - -public class RecordTest { - - - @Test - public void testRecord() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = rec(a:1 , b : TRUE) \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("struct(a:INTEGER,b:BOOL)", t.constants.get("k").toString()); - } - - @Test - public void testRecord2() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" - + "PROPERTIES rec(a: k, b:TRUE) = rec(a:1 , b : k2) \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("BOOL", t.constants.get("k2").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testRecordException() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = rec(a:1) \n" + "END"; - new TestTypechecker(machine); - } - - @Test (expected = TypeErrorException.class) - public void testRecordException2() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES rec(a:1) = rec(b:1) \n" + "END"; - new TestTypechecker(machine); - } - - @Test (expected = TypeErrorException.class) - public void testRecordException3() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES rec(a:TRUE) = rec(a:1) \n" + "END"; - new TestTypechecker(machine); - } - - @Test (expected = TypeErrorException.class) - public void testRecordException4() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES rec(a:1,b:1) = rec(a:1) \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testRecordSelect() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = rec(a: 1)'a \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - } - - @Test - public void testRecordSelect2() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES 1 = rec(a: k)'a \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - } - - @Test - public void testRecordSelect3() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k'a = 1 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("struct(a:INTEGER)", t.constants.get("k").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testRecordSelectException() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES TRUE = rec(a:1)'a \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testStruct() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = struct(a: INT) \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(struct(a:INTEGER))", t.constants.get("k").toString()); - } - - @Test - public void testStruct2() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k, k2 \n" - + "PROPERTIES struct(a: k, b:BOOL) = struct(a: INT, b:k2) \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - assertEquals("POW(BOOL)", t.constants.get("k2").toString()); - } - -} +package de.tlc4b.typechecking; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + + + +import de.be4.classicalb.core.parser.exceptions.BException; +import de.tlc4b.exceptions.TypeErrorException; + +public class RecordTest { + + + @Test + public void testRecord() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = rec(a:1 , b : TRUE) \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("struct(a:INTEGER,b:BOOL)", t.constants.get("k").toString()); + } + + @Test + public void testRecord2() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" + + "PROPERTIES rec(a: k, b:TRUE) = rec(a:1 , b : k2) \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("BOOL", t.constants.get("k2").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testRecordException() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = rec(a:1) \n" + "END"; + new TestTypechecker(machine); + } + + @Test (expected = TypeErrorException.class) + public void testRecordException2() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES rec(a:1) = rec(b:1) \n" + "END"; + new TestTypechecker(machine); + } + + @Test (expected = TypeErrorException.class) + public void testRecordException3() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES rec(a:TRUE) = rec(a:1) \n" + "END"; + new TestTypechecker(machine); + } + + @Test (expected = TypeErrorException.class) + public void testRecordException4() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES rec(a:1,b:1) = rec(a:1) \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testRecordSelect() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = rec(a: 1)'a \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + } + + @Test + public void testRecordSelect2() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES 1 = rec(a: k)'a \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + } + + @Test + public void testRecordSelect3() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k'a = 1 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("struct(a:INTEGER)", t.constants.get("k").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testRecordSelectException() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES TRUE = rec(a:1)'a \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testStruct() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = struct(a: INT) \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(struct(a:INTEGER))", t.constants.get("k").toString()); + } + + @Test + public void testStruct2() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k, k2 \n" + + "PROPERTIES struct(a: k, b:BOOL) = struct(a: INT, b:k2) \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + assertEquals("POW(BOOL)", t.constants.get("k2").toString()); + } + +} diff --git a/src/test/java/de/tlc4b/typechecking/RelationsTest.java b/src/test/java/de/tlc4b/typechecking/RelationsTest.java index 8216e686eaf156cb846aad91b93477c96cd283aa..9ac6efc03f59694fd558a2380bf03af6af00b7e2 100644 --- a/src/test/java/de/tlc4b/typechecking/RelationsTest.java +++ b/src/test/java/de/tlc4b/typechecking/RelationsTest.java @@ -1,94 +1,94 @@ -package de.tlc4b.typechecking; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - - - -import de.be4.classicalb.core.parser.exceptions.BException; -import de.tlc4b.exceptions.TypeErrorException; - -public class RelationsTest { - - @Test - public void testCouple() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k\n" - + "PROPERTIES k = (1|->1) \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER*INTEGER", t.constants.get("k").toString()); - } - - @Test - public void testCouple2() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2 \n" - + "PROPERTIES (k|->TRUE) = (1|->k2) \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("BOOL", t.constants.get("k2").toString()); - } - - @Test - public void testCouple3() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = (1,2,3) \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("(INTEGER*INTEGER)*INTEGER", t.constants.get("k").toString()); - } - - @Test - public void testCouple4() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES (1|->1) = (1,1) \n" - + "END"; - new TestTypechecker(machine); - } - - @Test (expected = TypeErrorException.class) - public void testCoupleWithDifferentNumberOfComponents() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES (1,2) = (1,2,3) \n" - + "END"; - new TestTypechecker(machine); - } - - @Test - public void testRelation() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k = INT <-> INT \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(POW(INTEGER*INTEGER))", t.constants.get("k").toString()); - } - - @Test - public void testIdentity() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k\n" - + "PROPERTIES k = id({1,2}) \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); - } - - @Test - public void testDomainRestriction() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k, k2\n" - + "PROPERTIES k = {1} <| {(k2, TRUE)} \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("FUNC(INTEGER,BOOL)", t.constants.get("k").toString()); - assertEquals("INTEGER", t.constants.get("k2").toString()); - } - - - -} +package de.tlc4b.typechecking; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + + + +import de.be4.classicalb.core.parser.exceptions.BException; +import de.tlc4b.exceptions.TypeErrorException; + +public class RelationsTest { + + @Test + public void testCouple() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k\n" + + "PROPERTIES k = (1|->1) \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER*INTEGER", t.constants.get("k").toString()); + } + + @Test + public void testCouple2() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2 \n" + + "PROPERTIES (k|->TRUE) = (1|->k2) \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("BOOL", t.constants.get("k2").toString()); + } + + @Test + public void testCouple3() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = (1,2,3) \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("(INTEGER*INTEGER)*INTEGER", t.constants.get("k").toString()); + } + + @Test + public void testCouple4() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES (1|->1) = (1,1) \n" + + "END"; + new TestTypechecker(machine); + } + + @Test (expected = TypeErrorException.class) + public void testCoupleWithDifferentNumberOfComponents() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES (1,2) = (1,2,3) \n" + + "END"; + new TestTypechecker(machine); + } + + @Test + public void testRelation() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k = INT <-> INT \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(POW(INTEGER*INTEGER))", t.constants.get("k").toString()); + } + + @Test + public void testIdentity() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k\n" + + "PROPERTIES k = id({1,2}) \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); + } + + @Test + public void testDomainRestriction() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k, k2\n" + + "PROPERTIES k = {1} <| {(k2, TRUE)} \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("FUNC(INTEGER,BOOL)", t.constants.get("k").toString()); + assertEquals("INTEGER", t.constants.get("k2").toString()); + } + + + +} diff --git a/src/test/java/de/tlc4b/typechecking/SequenceTest.java b/src/test/java/de/tlc4b/typechecking/SequenceTest.java index 231862995f9b6affb9bb80944903972fb669ed16..0438fa758c95d1e71ce007489f8b8d935306dfa9 100644 --- a/src/test/java/de/tlc4b/typechecking/SequenceTest.java +++ b/src/test/java/de/tlc4b/typechecking/SequenceTest.java @@ -1,183 +1,183 @@ -package de.tlc4b.typechecking; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - - - -import de.be4.classicalb.core.parser.exceptions.BException; -import de.tlc4b.exceptions.TypeErrorException; - -public class SequenceTest { - - @Test - public void testSequence() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = [1] \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); - } - - @Test - public void testSequence2() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k, k2 \n" - + "PROPERTIES k = [1,2,k2] \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testSequenceException() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = [1, TRUE] \n" + "END"; - new TestTypechecker(machine); - } - - @Test(expected = TypeErrorException.class) - public void testSequenceException2() throws BException { - String machine = "MACHINE test\n" + "PROPERTIES 1 = [1] \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testSetOperatorOnSequence() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = [1] \\/ {} \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER*INTEGER)", t.constants.get("k").toString()); - } - - @Test - public void testConcatenation() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = [1] ^ [2] \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); - } - - @Test - public void testConcatenationOnSet() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = [3] ^ {(1,4)} \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); - } - - @Test - public void testSize() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = size([1]) \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - } - - @Test(expected = TypeErrorException.class) - public void testSizeException() throws BException { - String machine = "MACHINE test\n" + "PROPERTIES TRUE = size([1]) \n" - + "END"; - new TestTypechecker(machine); - } - - @Test(expected = TypeErrorException.class) - public void testSizeException2() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = size(1) \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testPrepend() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = 1 -> [] \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); - } - - @Test - public void testPrepend2() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k, k2 \n" - + "PROPERTIES [1] = k -> k2 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k2").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testPrependException() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k, k2 \n" - + "PROPERTIES 1 = k -> k2 \n" + "END"; - new TestTypechecker(machine); - } - - - @Test //TODO sequence type - public void testAppend() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = [] <- 1 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); - } - - @Test - public void testAppend2() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k, k2 \n" - + "PROPERTIES [1] = k <- k2 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k2").toString()); - assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testAppendException() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k, k2 \n" - + "PROPERTIES 1 = k <- k2 \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testReverse() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = rev([1]) \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testReverseException() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = rev([1]) \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testFirst() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = first([1]) \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testFirstException() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES TRUE = first([1]) \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testLast() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = last([1]) \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testLastException() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES TRUE = last([1]) \n" + "END"; - new TestTypechecker(machine); - } - -} +package de.tlc4b.typechecking; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + + + +import de.be4.classicalb.core.parser.exceptions.BException; +import de.tlc4b.exceptions.TypeErrorException; + +public class SequenceTest { + + @Test + public void testSequence() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = [1] \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); + } + + @Test + public void testSequence2() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k, k2 \n" + + "PROPERTIES k = [1,2,k2] \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testSequenceException() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = [1, TRUE] \n" + "END"; + new TestTypechecker(machine); + } + + @Test(expected = TypeErrorException.class) + public void testSequenceException2() throws BException { + String machine = "MACHINE test\n" + "PROPERTIES 1 = [1] \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testSetOperatorOnSequence() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = [1] \\/ {} \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER*INTEGER)", t.constants.get("k").toString()); + } + + @Test + public void testConcatenation() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = [1] ^ [2] \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); + } + + @Test + public void testConcatenationOnSet() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = [3] ^ {(1,4)} \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); + } + + @Test + public void testSize() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = size([1]) \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + } + + @Test(expected = TypeErrorException.class) + public void testSizeException() throws BException { + String machine = "MACHINE test\n" + "PROPERTIES TRUE = size([1]) \n" + + "END"; + new TestTypechecker(machine); + } + + @Test(expected = TypeErrorException.class) + public void testSizeException2() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = size(1) \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testPrepend() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = 1 -> [] \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); + } + + @Test + public void testPrepend2() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k, k2 \n" + + "PROPERTIES [1] = k -> k2 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k2").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testPrependException() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k, k2 \n" + + "PROPERTIES 1 = k -> k2 \n" + "END"; + new TestTypechecker(machine); + } + + + @Test //TODO sequence type + public void testAppend() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = [] <- 1 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); + } + + @Test + public void testAppend2() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k, k2 \n" + + "PROPERTIES [1] = k <- k2 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k2").toString()); + assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testAppendException() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k, k2 \n" + + "PROPERTIES 1 = k <- k2 \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testReverse() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = rev([1]) \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testReverseException() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = rev([1]) \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testFirst() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = first([1]) \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testFirstException() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES TRUE = first([1]) \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testLast() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = last([1]) \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testLastException() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES TRUE = last([1]) \n" + "END"; + new TestTypechecker(machine); + } + +} diff --git a/src/test/java/de/tlc4b/typechecking/SetsClauseTest.java b/src/test/java/de/tlc4b/typechecking/SetsClauseTest.java index 90fdd909635144ddf6739aaa3c44c3ff599fce13..2b3619a858008d3dacf61ec77f5e9b3ccd0c39a1 100644 --- a/src/test/java/de/tlc4b/typechecking/SetsClauseTest.java +++ b/src/test/java/de/tlc4b/typechecking/SetsClauseTest.java @@ -1,35 +1,35 @@ -package de.tlc4b.typechecking; - -import static org.junit.Assert.assertEquals; - -import org.junit.Ignore; -import org.junit.Test; - -import de.be4.classicalb.core.parser.exceptions.BException; - -public class SetsClauseTest { - - - @Test - public void testDeferredSet() throws BException { - String machine = "MACHINE test\n" - + "SETS DEF \n" - + "CONSTANTS k \n" - + "PROPERTIES k : DEF \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("DEF", t.constants.get("k").toString()); - } - - @Ignore - @Test - public void testDeferredSet2() throws BException { - String machine = "MACHINE test(DEF)\n" - + "CONSTANTS k \n" - + "PROPERTIES k : DEF \n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("DEF", t.constants.get("k").toString()); - } - -} +package de.tlc4b.typechecking; + +import static org.junit.Assert.assertEquals; + +import org.junit.Ignore; +import org.junit.Test; + +import de.be4.classicalb.core.parser.exceptions.BException; + +public class SetsClauseTest { + + + @Test + public void testDeferredSet() throws BException { + String machine = "MACHINE test\n" + + "SETS DEF \n" + + "CONSTANTS k \n" + + "PROPERTIES k : DEF \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("DEF", t.constants.get("k").toString()); + } + + @Ignore + @Test + public void testDeferredSet2() throws BException { + String machine = "MACHINE test(DEF)\n" + + "CONSTANTS k \n" + + "PROPERTIES k : DEF \n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("DEF", t.constants.get("k").toString()); + } + +} diff --git a/src/test/java/de/tlc4b/typechecking/SetsTest.java b/src/test/java/de/tlc4b/typechecking/SetsTest.java index 2d5303a58ed412970681eea6bd37ae022b207f47..65bb3ca8475b3a84be45068e32122d80d299510a 100644 --- a/src/test/java/de/tlc4b/typechecking/SetsTest.java +++ b/src/test/java/de/tlc4b/typechecking/SetsTest.java @@ -1,168 +1,168 @@ -package de.tlc4b.typechecking; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - - - -import de.be4.classicalb.core.parser.exceptions.BException; -import de.tlc4b.exceptions.TypeErrorException; - -public class SetsTest { - - @Test - public void testEmptySet() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES {} = {} \n" + "END"; - new TestTypechecker(machine); - } - - @Test (expected = TypeErrorException.class) - public void testEmptySetException() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = {} \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testSetExtension() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = {1} \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testSetExtensionException() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES 1 = {1} \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testSetExtension2() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" - + "PROPERTIES k = {k2,1} \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - assertEquals("INTEGER", t.constants.get("k2").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testSetExtensionException2() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = {1,TRUE} \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testSetComprehension() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = {x| x = 1} \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - } - - @Test - public void testSetComprehension2() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = {x,y| x = 1 & y = TRUE} \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER*BOOL)", t.constants.get("k").toString()); - } - - @Test - public void testEventBSetComprehension() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k,k2,k3 \n" - + "PROPERTIES k = {x,y| x = k2(k3) & y : {TRUE}} & k2(2)=1\n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER*BOOL)", t.constants.get("k").toString()); - assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k2").toString()); - assertEquals("INTEGER", t.constants.get("k3").toString()); - } - - @Test - public void testEventBSetComprehension2() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k,k2 \n" - + "PROPERTIES k = {a,b| a : k2 & b = a'foo} & k2={rec(foo:\"123\",bar:TRUE)}\n" - + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(struct(foo:STRING,bar:BOOL)*STRING)", t.constants.get("k").toString()); - assertEquals("POW(struct(foo:STRING,bar:BOOL))", t.constants.get("k2").toString()); - } - - - @Test (expected = TypeErrorException.class) - public void testSetComprehensionException() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = {x| x = 1} \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER*BOOL)", t.constants.get("k").toString()); - } - - @Test - public void testPowerSet() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = POW({1}) \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(POW(INTEGER))", t.constants.get("k").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testPowerSetException() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = POW({1}) \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testUnion() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k, k2 \n" - + "PROPERTIES k = {1} \\/ k2 \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testUnionException() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k, k2 \n" - + "PROPERTIES k = {1} \\/ 1 \n" + "END"; - new TestTypechecker(machine); - } - - @Test (expected = TypeErrorException.class) - public void testUnionException2() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k, k2 \n" - + "PROPERTIES 1 = {1} \\/ k \n" + "END"; - new TestTypechecker(machine); - } - - @Test - public void testCard() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = card({1}) \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("INTEGER", t.constants.get("k").toString()); - } - - @Test - public void testGerneralUnion() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = union({{1}, {2}}) \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("POW(INTEGER)", t.constants.get("k").toString()); - } - - @Test (expected = TypeErrorException.class) - public void testGerneralUnionException() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = union({1}) \n" + "END"; - new TestTypechecker(machine); - } - -} +package de.tlc4b.typechecking; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + + + +import de.be4.classicalb.core.parser.exceptions.BException; +import de.tlc4b.exceptions.TypeErrorException; + +public class SetsTest { + + @Test + public void testEmptySet() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES {} = {} \n" + "END"; + new TestTypechecker(machine); + } + + @Test (expected = TypeErrorException.class) + public void testEmptySetException() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = {} \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testSetExtension() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = {1} \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testSetExtensionException() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES 1 = {1} \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testSetExtension2() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k,k2 \n" + + "PROPERTIES k = {k2,1} \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + assertEquals("INTEGER", t.constants.get("k2").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testSetExtensionException2() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = {1,TRUE} \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testSetComprehension() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = {x| x = 1} \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + } + + @Test + public void testSetComprehension2() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = {x,y| x = 1 & y = TRUE} \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER*BOOL)", t.constants.get("k").toString()); + } + + @Test + public void testEventBSetComprehension() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k,k2,k3 \n" + + "PROPERTIES k = {x,y| x = k2(k3) & y : {TRUE}} & k2(2)=1\n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER*BOOL)", t.constants.get("k").toString()); + assertEquals("FUNC(INTEGER,INTEGER)", t.constants.get("k2").toString()); + assertEquals("INTEGER", t.constants.get("k3").toString()); + } + + @Test + public void testEventBSetComprehension2() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k,k2 \n" + + "PROPERTIES k = {a,b| a : k2 & b = a'foo} & k2={rec(foo:\"123\",bar:TRUE)}\n" + + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(struct(foo:STRING,bar:BOOL)*STRING)", t.constants.get("k").toString()); + assertEquals("POW(struct(foo:STRING,bar:BOOL))", t.constants.get("k2").toString()); + } + + + @Test (expected = TypeErrorException.class) + public void testSetComprehensionException() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = {x| x = 1} \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER*BOOL)", t.constants.get("k").toString()); + } + + @Test + public void testPowerSet() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = POW({1}) \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(POW(INTEGER))", t.constants.get("k").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testPowerSetException() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = POW({1}) \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testUnion() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k, k2 \n" + + "PROPERTIES k = {1} \\/ k2 \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + assertEquals("POW(INTEGER)", t.constants.get("k2").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testUnionException() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k, k2 \n" + + "PROPERTIES k = {1} \\/ 1 \n" + "END"; + new TestTypechecker(machine); + } + + @Test (expected = TypeErrorException.class) + public void testUnionException2() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k, k2 \n" + + "PROPERTIES 1 = {1} \\/ k \n" + "END"; + new TestTypechecker(machine); + } + + @Test + public void testCard() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = card({1}) \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("INTEGER", t.constants.get("k").toString()); + } + + @Test + public void testGerneralUnion() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = union({{1}, {2}}) \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("POW(INTEGER)", t.constants.get("k").toString()); + } + + @Test (expected = TypeErrorException.class) + public void testGerneralUnionException() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = union({1}) \n" + "END"; + new TestTypechecker(machine); + } + +} diff --git a/src/test/java/de/tlc4b/typechecking/StringTest.java b/src/test/java/de/tlc4b/typechecking/StringTest.java index 2a1cdfa6459e394205b1e02817792725d7b19952..4c3a4f44354e0135fce452c19c3dee8e952ea958 100644 --- a/src/test/java/de/tlc4b/typechecking/StringTest.java +++ b/src/test/java/de/tlc4b/typechecking/StringTest.java @@ -1,36 +1,36 @@ -package de.tlc4b.typechecking; - -import static org.junit.Assert.assertEquals; - -import org.junit.Test; - - - -import de.be4.classicalb.core.parser.exceptions.BException; -import de.tlc4b.exceptions.TypeErrorException; - -public class StringTest { - - - @Test - public void testString1() throws BException { - String machine = "MACHINE test\n" + "CONSTANTS k \n" - + "PROPERTIES k = \"abc\" \n" + "END"; - TestTypechecker t = new TestTypechecker(machine); - assertEquals("STRING", t.constants.get("k").toString()); - } - - @Test - public void testString2() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES \"abc\" = \"abc\" \n" + "END"; - new TestTypechecker(machine); - } - - @Test (expected = TypeErrorException.class) - public void testStringException() throws BException { - String machine = "MACHINE test\n" - + "PROPERTIES 1 = \"abc\" \n" + "END"; - new TestTypechecker(machine); - } -} +package de.tlc4b.typechecking; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + + + +import de.be4.classicalb.core.parser.exceptions.BException; +import de.tlc4b.exceptions.TypeErrorException; + +public class StringTest { + + + @Test + public void testString1() throws BException { + String machine = "MACHINE test\n" + "CONSTANTS k \n" + + "PROPERTIES k = \"abc\" \n" + "END"; + TestTypechecker t = new TestTypechecker(machine); + assertEquals("STRING", t.constants.get("k").toString()); + } + + @Test + public void testString2() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES \"abc\" = \"abc\" \n" + "END"; + new TestTypechecker(machine); + } + + @Test (expected = TypeErrorException.class) + public void testStringException() throws BException { + String machine = "MACHINE test\n" + + "PROPERTIES 1 = \"abc\" \n" + "END"; + new TestTypechecker(machine); + } +} diff --git a/src/test/java/de/tlc4b/typechecking/TestTypechecker.java b/src/test/java/de/tlc4b/typechecking/TestTypechecker.java index d26e7ccd1d03a9eef76ab2e64a75f593ec583f29..cab56aadf119a6e31054dc3b823c1bbd0f506c9f 100644 --- a/src/test/java/de/tlc4b/typechecking/TestTypechecker.java +++ b/src/test/java/de/tlc4b/typechecking/TestTypechecker.java @@ -1,57 +1,54 @@ -package de.tlc4b.typechecking; - -import java.util.Hashtable; - -import de.be4.classicalb.core.parser.BParser; -import de.be4.classicalb.core.parser.exceptions.BCompoundException; -import de.be4.classicalb.core.parser.exceptions.BException; -import de.be4.classicalb.core.parser.node.Start; -import de.tlc4b.analysis.MachineContext; -import de.tlc4b.analysis.Typechecker; -import de.tlc4b.btypes.BType; -import de.tlc4b.util.Ast2String; - -public class TestTypechecker { - - Hashtable<String, BType> parameters; - Hashtable<String, BType> constants; - Hashtable<String, BType> variables; - - public TestTypechecker(String machine) throws BException { - parameters = new Hashtable<String, BType>(); - constants = new Hashtable<String, BType>(); - variables = new Hashtable<String, BType>(); - - BParser parser = new BParser("Test"); - Start start; - try { - start = parser.parse(machine, false); - } catch (BCompoundException e) { - throw e.getFirstException(); - } - final Ast2String ast2String2 = new Ast2String(); - start.apply(ast2String2); - // System.out.println(ast2String2.toString()); - MachineContext c = new MachineContext(null, start); - c.analyseMachine(); - Typechecker t = new Typechecker(c); - - for (String name : c.getSetParamter().keySet()) { - parameters.put(name, t.getType(c.getSetParamter().get(name))); - } - - for (String name : c.getScalarParameter().keySet()) { - parameters.put(name, t.getType(c.getScalarParameter().get(name))); - } - - for (String name : c.getConstants().keySet()) { - constants.put(name, t.getType(c.getConstants().get(name))); - } - - for (String name : c.getVariables().keySet()) { - variables.put(name, t.getType(c.getVariables().get(name))); - } - - } - -} +package de.tlc4b.typechecking; + +import java.util.Hashtable; + +import de.be4.classicalb.core.parser.BParser; +import de.be4.classicalb.core.parser.exceptions.BCompoundException; +import de.be4.classicalb.core.parser.exceptions.BException; +import de.be4.classicalb.core.parser.node.Start; +import de.tlc4b.analysis.MachineContext; +import de.tlc4b.analysis.Typechecker; +import de.tlc4b.btypes.BType; + +public class TestTypechecker { + + Hashtable<String, BType> parameters; + Hashtable<String, BType> constants; + Hashtable<String, BType> variables; + + public TestTypechecker(String machine) throws BException { + parameters = new Hashtable<String, BType>(); + constants = new Hashtable<String, BType>(); + variables = new Hashtable<String, BType>(); + + BParser parser = new BParser("Test"); + Start start; + try { + start = parser.parse(machine, false); + } catch (BCompoundException e) { + throw e.getFirstException(); + } + + MachineContext c = new MachineContext(null, start); + c.analyseMachine(); + Typechecker t = new Typechecker(c); + + for (String name : c.getSetParamter().keySet()) { + parameters.put(name, t.getType(c.getSetParamter().get(name))); + } + + for (String name : c.getScalarParameter().keySet()) { + parameters.put(name, t.getType(c.getScalarParameter().get(name))); + } + + for (String name : c.getConstants().keySet()) { + constants.put(name, t.getType(c.getConstants().get(name))); + } + + for (String name : c.getVariables().keySet()) { + variables.put(name, t.getType(c.getVariables().get(name))); + } + + } + +} diff --git a/src/test/java/de/tlc4b/typechecking/TypeErrosTest.java b/src/test/java/de/tlc4b/typechecking/TypeErrosTest.java index 05efcef3b9b1be9461740003aa0582161f4d8e29..5957fc7a061750788c51e89b6656622004fec863 100644 --- a/src/test/java/de/tlc4b/typechecking/TypeErrosTest.java +++ b/src/test/java/de/tlc4b/typechecking/TypeErrosTest.java @@ -1,38 +1,38 @@ -package de.tlc4b.typechecking; - -import org.junit.Test; - - - -import de.be4.classicalb.core.parser.exceptions.BException; -import de.tlc4b.exceptions.TypeErrorException; - -public class TypeErrosTest { - - @Test (expected = TypeErrorException.class) - public void test1() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES k : k \n" - + "END"; - new TestTypechecker(machine); - } - - @Test (expected = TypeErrorException.class) - public void test2() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES {k} : {k} \n" - + "END"; - new TestTypechecker(machine); - } - - @Test (expected = TypeErrorException.class) - public void test3() throws BException { - String machine = "MACHINE test\n" - + "CONSTANTS k \n" - + "PROPERTIES {k} : {{k}} \n" - + "END"; - new TestTypechecker(machine); - } -} +package de.tlc4b.typechecking; + +import org.junit.Test; + + + +import de.be4.classicalb.core.parser.exceptions.BException; +import de.tlc4b.exceptions.TypeErrorException; + +public class TypeErrosTest { + + @Test (expected = TypeErrorException.class) + public void test1() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES k : k \n" + + "END"; + new TestTypechecker(machine); + } + + @Test (expected = TypeErrorException.class) + public void test2() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES {k} : {k} \n" + + "END"; + new TestTypechecker(machine); + } + + @Test (expected = TypeErrorException.class) + public void test3() throws BException { + String machine = "MACHINE test\n" + + "CONSTANTS k \n" + + "PROPERTIES {k} : {{k}} \n" + + "END"; + new TestTypechecker(machine); + } +} diff --git a/src/test/java/de/tlc4b/util/PolySuite.java b/src/test/java/de/tlc4b/util/PolySuite.java index 0fb12b7fd1c60f8083dd5e0339b76adc1efdc621..81574f75af9ba9e307da6a57697169a5392e5fad 100644 --- a/src/test/java/de/tlc4b/util/PolySuite.java +++ b/src/test/java/de/tlc4b/util/PolySuite.java @@ -20,121 +20,121 @@ import org.junit.runners.model.TestClass; public class PolySuite extends Suite { - // ////////////////////////////// - // Public helper interfaces - - /** - * Annotation for a method which returns a {@link Configuration} - * to be injected into the test class constructor - */ - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - public static @interface Config { - } - - public static interface Configuration { - int size(); - Object getTestValue(int index); - Object getExpectedValue(int index); - String getTestName(int index); - } - - // ////////////////////////////// - // Fields - - private final List<Runner> runners; - - // ////////////////////////////// - // Constructor - - /** - * Only called reflectively. Do not use programmatically. - * @param c the test class - * @throws Throwable if something bad happens - */ - public PolySuite(Class<?> c) throws Throwable { - super(c, Collections.<Runner>emptyList()); - TestClass testClass = getTestClass(); - Class<?> jTestClass = testClass.getJavaClass(); - Configuration configuration = getConfiguration(testClass); - List<Runner> runners = new ArrayList<Runner>(); - for (int i = 0, size = configuration.size(); i < size; i++) { - SingleRunner runner = new SingleRunner(jTestClass, configuration.getTestValue(i), configuration.getTestName(i), configuration.getExpectedValue(i)); - runners.add(runner); - } - this.runners = runners; - } - - // ////////////////////////////// - // Overrides - - @Override - protected List<Runner> getChildren() { - return runners; - } - - // ////////////////////////////// - // Private - - private Configuration getConfiguration(TestClass testClass) throws Throwable { - return (Configuration) getConfigMethod(testClass).invokeExplosively(null); - } - - private FrameworkMethod getConfigMethod(TestClass testClass) { - List<FrameworkMethod> methods = testClass.getAnnotatedMethods(Config.class); - if (methods.isEmpty()) { - throw new IllegalStateException("@" + Config.class.getSimpleName() + " method not found"); - } - if (methods.size() > 1) { - throw new IllegalStateException("Too many @" + Config.class.getSimpleName() + " methods"); - } - FrameworkMethod method = methods.get(0); - int modifiers = method.getMethod().getModifiers(); - if (!(Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { - throw new IllegalStateException("@" + Config.class.getSimpleName() + " method \"" + method.getName() + "\" must be public static"); - } - return method; - } - - // ////////////////////////////// - // Helper classes - - private static class SingleRunner extends BlockJUnit4ClassRunner { - - private final Object testVal; - private final Object expectedVal; - private final String testName; - - SingleRunner(Class<?> testClass, Object testVal, String testName, Object expectedVal) throws InitializationError { - super(testClass); - this.testVal = testVal; - this.expectedVal = expectedVal; - this.testName = testName; - } - - @Override - protected Object createTest() throws Exception { - return getTestClass().getOnlyConstructor().newInstance(testVal, expectedVal); - } - - @Override - protected String getName() { - return testName; - } - - @Override - protected String testName(FrameworkMethod method) { - return testName + ": " + method.getName(); - } - - @Override - protected void validateConstructor(List<Throwable> errors) { - validateOnlyOneConstructor(errors); - } - - @Override - protected Statement classBlock(RunNotifier notifier) { - return childrenInvoker(notifier); - } - } - } \ No newline at end of file + // ////////////////////////////// + // Public helper interfaces + + /** + * Annotation for a method which returns a {@link Configuration} + * to be injected into the test class constructor + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public static @interface Config { + } + + public static interface Configuration { + int size(); + Object getTestValue(int index); + Object getExpectedValue(int index); + String getTestName(int index); + } + + // ////////////////////////////// + // Fields + + private final List<Runner> runners; + + // ////////////////////////////// + // Constructor + + /** + * Only called reflectively. Do not use programmatically. + * @param c the test class + * @throws Throwable if something bad happens + */ + public PolySuite(Class<?> c) throws Throwable { + super(c, Collections.<Runner>emptyList()); + TestClass testClass = getTestClass(); + Class<?> jTestClass = testClass.getJavaClass(); + Configuration configuration = getConfiguration(testClass); + List<Runner> runners = new ArrayList<Runner>(); + for (int i = 0, size = configuration.size(); i < size; i++) { + SingleRunner runner = new SingleRunner(jTestClass, configuration.getTestValue(i), configuration.getTestName(i), configuration.getExpectedValue(i)); + runners.add(runner); + } + this.runners = runners; + } + + // ////////////////////////////// + // Overrides + + @Override + protected List<Runner> getChildren() { + return runners; + } + + // ////////////////////////////// + // Private + + private Configuration getConfiguration(TestClass testClass) throws Throwable { + return (Configuration) getConfigMethod(testClass).invokeExplosively(null); + } + + private FrameworkMethod getConfigMethod(TestClass testClass) { + List<FrameworkMethod> methods = testClass.getAnnotatedMethods(Config.class); + if (methods.isEmpty()) { + throw new IllegalStateException("@" + Config.class.getSimpleName() + " method not found"); + } + if (methods.size() > 1) { + throw new IllegalStateException("Too many @" + Config.class.getSimpleName() + " methods"); + } + FrameworkMethod method = methods.get(0); + int modifiers = method.getMethod().getModifiers(); + if (!(Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) { + throw new IllegalStateException("@" + Config.class.getSimpleName() + " method \"" + method.getName() + "\" must be public static"); + } + return method; + } + + // ////////////////////////////// + // Helper classes + + private static class SingleRunner extends BlockJUnit4ClassRunner { + + private final Object testVal; + private final Object expectedVal; + private final String testName; + + SingleRunner(Class<?> testClass, Object testVal, String testName, Object expectedVal) throws InitializationError { + super(testClass); + this.testVal = testVal; + this.expectedVal = expectedVal; + this.testName = testName; + } + + @Override + protected Object createTest() throws Exception { + return getTestClass().getOnlyConstructor().newInstance(testVal, expectedVal); + } + + @Override + protected String getName() { + return testName; + } + + @Override + protected String testName(FrameworkMethod method) { + return testName + ": " + method.getName(); + } + + @Override + protected void validateConstructor(List<Throwable> errors) { + validateOnlyOneConstructor(errors); + } + + @Override + protected Statement classBlock(RunNotifier notifier) { + return childrenInvoker(notifier); + } + } +} \ No newline at end of file diff --git a/src/test/java/de/tlc4b/util/TLC4BRunnerTestString.java b/src/test/java/de/tlc4b/util/TLC4BRunnerTestString.java index 477da9de6eb72e470e6ca7396ec1eff2ce7b6519..a59e2217320786428d618bcaa75d8398c86113b0 100644 --- a/src/test/java/de/tlc4b/util/TLC4BRunnerTestString.java +++ b/src/test/java/de/tlc4b/util/TLC4BRunnerTestString.java @@ -1,11 +1,22 @@ package de.tlc4b.util; +import java.io.File; + import de.tlc4b.TLC4B; +import tlc2.TLCGlobals; + public class TLC4BRunnerTestString { public static void main(String[] args) throws Exception { System.setProperty("apple.awt.UIElement", "true"); // avoiding pop up windows + + // The subdirectories of the states directory are named after the time when TLC was started. + // Old versions of TLC (like the one we use) format the time with second precision only, + // leading to name conflicts when two tests are started within the same second. + // This line works around the issue by instead using a millisecond timestamp as the name. + TLCGlobals.metaDir = TLCGlobals.metaRoot + File.separator + System.currentTimeMillis() + File.separator; + TLC4B.testString(args[0],true); } } diff --git a/src/test/java/de/tlc4b/util/TLC4BTester.java b/src/test/java/de/tlc4b/util/TLC4BTester.java index acf6c516c7990d40234a0e0b0247a3899d92b7a0..a695a5160271c084d409d645a240a13a93699dcc 100644 --- a/src/test/java/de/tlc4b/util/TLC4BTester.java +++ b/src/test/java/de/tlc4b/util/TLC4BTester.java @@ -1,14 +1,21 @@ package de.tlc4b.util; +import java.io.File; import de.tlc4b.TLC4B; +import tlc2.TLCGlobals; + public class TLC4BTester { - - public static void main(String[] args) throws Exception { - System.setProperty("apple.awt.UIElement", "true"); // avoiding pop up windows - TLC4B.test(args,true); - } + public static void main(String[] args) throws Exception { + System.setProperty("apple.awt.UIElement", "true"); // avoiding pop up windows + // The subdirectories of the states directory are named after the time when TLC was started. + // Old versions of TLC (like the one we use) format the time with second precision only, + // leading to name conflicts when two tests are started within the same second. + // This line works around the issue by instead using a millisecond timestamp as the name. + TLCGlobals.metaDir = TLCGlobals.metaRoot + File.separator + System.currentTimeMillis() + File.separator; + TLC4B.test(args,true); + } } diff --git a/src/test/java/de/tlc4b/util/TestUtil.java b/src/test/java/de/tlc4b/util/TestUtil.java index 7fc8d56af27894e54968f8a95cf2f088495f0e45..765859b5fa4fc9507f268216c9a4d6164c127b4e 100644 --- a/src/test/java/de/tlc4b/util/TestUtil.java +++ b/src/test/java/de/tlc4b/util/TestUtil.java @@ -1,274 +1,241 @@ -package de.tlc4b.util; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - -import java.io.BufferedReader; -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; - -import util.ToolIO; -import de.be4.classicalb.core.parser.exceptions.BCompoundException; -import de.be4.classicalb.core.parser.exceptions.BException; -import de.be4.classicalb.core.parser.node.Start; -import de.tla2b.exceptions.TLA2BException; -import de.tlc4b.TLC4B; -import de.tlc4b.TLC4BGlobals; -import de.tlc4b.Translator; -import de.tlc4b.tlc.TLCResults.TLCResult; - -public class TestUtil { - - public static void compare(final String expectedModule, final String machineString) throws Exception { - TLC4BGlobals.setForceTLCToEvalConstants(false); - ToolIO.setMode(ToolIO.TOOL); - - Translator b2tlaTranslator = new Translator(machineString); - b2tlaTranslator.translate(); - System.out.println(b2tlaTranslator.getModuleString()); - - // TODO create standard modules BBuildins - - String moduleName = b2tlaTranslator.getMachineName(); - String str1 = de.tla2bAst.Translator.translateModuleString(moduleName, b2tlaTranslator.getModuleString(), null); - - String str2 = de.tla2bAst.Translator.translateModuleString(moduleName, expectedModule, null); - // StringBuilder sb1 = de.tla2b.translation.Tla2BTranslator - // .translateString(name, b2tlaTranslator.getModuleString(), null); - // StringBuilder sb2 = de.tla2b.translation.Tla2BTranslator - // .translateString(name, expectedModule, null); - if (!str1.equals(str2)) { - // assertEquals(expected, actual); - - fail("expected:\n" + expectedModule + "\nbut was:\n" + b2tlaTranslator.getModuleString()); - } - // assertEquals(sb2.toString(), sb1.toString()); - } - - public static void tryTranslating(final String machineString) throws BException { - TLC4BGlobals.setForceTLCToEvalConstants(false); - ToolIO.setMode(ToolIO.TOOL); - Translator b2tlaTranslator; - try { - b2tlaTranslator = new Translator(machineString); - b2tlaTranslator.translate(); - } catch (BCompoundException e) { - throw e.getFirstException(); - } - - } - - public static String translateTLA2B(String moduleName, String tlaString) throws TLA2BException { - return de.tla2bAst.Translator.translateModuleString(moduleName, tlaString, null); - } - - public static String translateTLA2B(String moduleName, String tlaString, String configString) - throws TLA2BException { - return de.tla2bAst.Translator.translateModuleString(moduleName, tlaString, configString); - } - - public static void compareLTLFormula(String expected, String machine, String ltlFormula) throws Exception { - Translator b2tlaTranslator = new Translator(machine, ltlFormula); - b2tlaTranslator.translate(); - String translatedLTLFormula = b2tlaTranslator.getTranslatedLTLFormula(); - translatedLTLFormula = translatedLTLFormula.replaceAll("\\s", ""); - expected = expected.replaceAll("\\s", ""); - System.out.println(translatedLTLFormula); - System.out.println(b2tlaTranslator.getModuleString()); - assertEquals(expected, translatedLTLFormula); - } - - public static void checkMachine(String machine) throws Exception { - Translator b2tlaTranslator = new Translator(machine); - b2tlaTranslator.translate(); - System.out.println(b2tlaTranslator.getModuleString()); - - String name = b2tlaTranslator.getMachineName(); - translateTLA2B(name, b2tlaTranslator.getModuleString()); - // de.tla2b.translation.Tla2BTranslator.translateString(name, - // b2tlaTranslator.getModuleString(), null); - } - - public static void print(Start start) { - final Ast2String ast2String2 = new Ast2String(); - start.apply(ast2String2); - System.out.println(ast2String2.toString()); - } - - public static void compareEqualsConfig(String expectedModule, String expectedConfig, String machine) - throws Exception { - Translator b2tlaTranslator = new Translator(machine); - b2tlaTranslator.translate(); - // print(b2tlaTranslator.getStart()); - System.out.println(b2tlaTranslator.getModuleString()); - System.out.println(b2tlaTranslator.getConfigString()); - - String name = b2tlaTranslator.getMachineName(); - - // parse check - translateTLA2B(name, b2tlaTranslator.getModuleString(), b2tlaTranslator.getConfigString()); - - assertEquals(expectedModule, b2tlaTranslator.getModuleString()); - assertEquals(expectedConfig, b2tlaTranslator.getConfigString()); - } - - public static void compareModuleAndConfig(String expectedModule, String expectedConfig, String machine) - throws Exception { - Translator b2tlaTranslator = new Translator(machine); - b2tlaTranslator.translate(); - // print(b2tlaTranslator.getStart()); - System.out.println(b2tlaTranslator.getModuleString()); - System.out.println(b2tlaTranslator.getConfigString()); - - // TODO include config file in back translation from TLA+ to B - - // String name = b2tlaTranslator.getMachineName(); - // StringBuilder sb1 = de.tla2b.translation.Tla2BTranslator - // .translateString(name, b2tlaTranslator.getModuleString(), - // b2tlaTranslator.getConfigString()); - // StringBuilder sb2 = de.tla2b.translation.Tla2BTranslator - // .translateString(name, expectedModule, expectedConfig); - // if (!sb2.toString().equals(sb1.toString())) { - // fail("expected:\n" + expectedModule + "\nbut was:\n" - // + b2tlaTranslator.getModuleString() + "\n\nexpected:\n" - // + expectedConfig + "\nbut was:\n" - // + b2tlaTranslator.getConfigString()); - // } - } - - public static void compareEquals(String expected, String machine) throws BException { - try { - Translator b2tlaTranslator = new Translator(machine); - b2tlaTranslator.translate(); - System.out.println(b2tlaTranslator.getModuleString()); - assertEquals(expected, b2tlaTranslator.getModuleString()); - } catch (BCompoundException e) { - throw e.getFirstException(); - } - - } - - public static String translate(String machine) throws BException { - try { - Translator translator = new Translator(machine); - translator.translate(); - System.out.println(translator.getModuleString()); - return translator.getModuleString(); - } catch (BCompoundException e) { - throw e.getFirstException(); - } - } - - public static TLCResult testString(String machineString) throws IOException { - String runnerClassName = TLC4BRunnerTestString.class.getCanonicalName(); - String[] args = new String[] { machineString }; - return runTLC(runnerClassName, args); - } - - public static TLCResult test(String[] args) throws IOException { - String runnerClassName = TLC4BTester.class.getCanonicalName(); - return runTLC(runnerClassName, args); - } - - private static TLCResult runTLC(String runnerClassName, String[] args) throws IOException { - System.out.println("Starting JVM..."); - final Process p = startJVM("", runnerClassName, args); - StreamGobbler stdOut = new StreamGobbler(p.getInputStream()); - stdOut.start(); - StreamGobbler errOut = new StreamGobbler(p.getErrorStream()); - errOut.start(); - try { - p.waitFor(); - } catch (InterruptedException e) { - e.printStackTrace(); - } - - for (int i = stdOut.getLog().size() - 1; i > 1; i--) { - String s = stdOut.getLog().get(i); - // System.out.println(s); - if (s.startsWith("Result:")) { - String resultString = s.substring(s.indexOf(':') + 2); - resultString = resultString.replaceAll("\\s+", ""); - System.out.println(resultString); - return TLCResult.valueOf(resultString); - } - } - System.out.println("No result found."); - return null; - - } - - private static Process startJVM(final String optionsAsString, final String mainClass, final String[] arguments) - throws IOException { - - String separator = System.getProperty("file.separator"); - - String jvm = System.getProperty("java.home") + separator + "bin" + separator + "java"; - String classpath = System.getProperty("java.class.path"); - - List<String> command = new ArrayList<String>(); - command.add(jvm); - command.add("-cp"); - command.add(classpath); - command.add(mainClass); - command.addAll(Arrays.asList(arguments)); - - ProcessBuilder processBuilder = new ProcessBuilder(command); - Process process = processBuilder.start(); - return process; - } - - public static void testParse(String[] args, boolean deleteFiles) throws Exception { - TLC4BGlobals.resetGlobals(); - TLC4BGlobals.setDeleteOnExit(deleteFiles); - TLC4BGlobals.setCreateTraceFile(false); - TLC4BGlobals.setTestingMode(true); - // B2TLAGlobals.setCleanup(true); - TLC4B tlc4b = new TLC4B(); - try { - tlc4b.process(args); - } catch (Exception e) { - e.printStackTrace(); - System.err.println(e.getMessage()); - throw e; - } - File module = new File(tlc4b.getBuildDir(), tlc4b.getMachineFileNameWithoutFileExtension() + ".tla"); - - // parse result - new de.tla2bAst.Translator(module.getCanonicalPath()); - } - -} - -class StreamGobbler extends Thread { - private InputStream is; - private ArrayList<String> log; - - public ArrayList<String> getLog() { - return log; - } - - StreamGobbler(InputStream is) { - this.is = is; - this.log = new ArrayList<String>(); - } - - public void run() { - try { - InputStreamReader isr = new InputStreamReader(is, "UTF-8"); - BufferedReader br = new BufferedReader(isr); - String line = null; - while ((line = br.readLine()) != null) { - System.out.println("> " + line); - log.add(line); - } - } catch (IOException e) { - e.printStackTrace(); - } - } -} +package de.tlc4b.util; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import de.be4.classicalb.core.parser.exceptions.BCompoundException; +import de.be4.classicalb.core.parser.exceptions.BException; +import de.tla2b.exceptions.FrontEndException; +import de.tla2b.exceptions.TLA2BException; +import de.tlc4b.TLC4B; +import de.tlc4b.TLC4BGlobals; +import de.tlc4b.Translator; +import de.tlc4b.tlc.TLCResults.TLCResult; + +import util.ToolIO; + +import static org.junit.Assert.assertEquals; + +public class TestUtil { + + public static void compare(final String expectedModule, final String machineString) throws BCompoundException, TLA2BException { + TLC4BGlobals.setForceTLCToEvalConstants(false); + ToolIO.setMode(ToolIO.TOOL); + + Translator b2tlaTranslator = new Translator(machineString); + b2tlaTranslator.translate(); + System.out.println("Input B machine:"); + System.out.println(machineString); + System.out.println("Expected TLA+ module:"); + System.out.println(expectedModule); + System.out.println("Translated TLA+ module:"); + System.out.println(b2tlaTranslator.getModuleString()); + + // TODO create standard modules BBuildins + + String moduleName = b2tlaTranslator.getMachineName(); + String actualB = de.tla2bAst.Translator.translateModuleString(moduleName, b2tlaTranslator.getModuleString(), b2tlaTranslator.getConfigString()); + String expectedB = de.tla2bAst.Translator.translateModuleString(moduleName, expectedModule, b2tlaTranslator.getConfigString()); + if (!expectedB.equals(actualB)) { + System.out.println("Expected TLA+ module translated to B machine:"); + System.out.println(expectedB); + System.out.println("Actual translated TLA+ module translated back to B machine:"); + System.out.println(actualB); + } + assertEquals(expectedB, actualB); + } + + public static void tryTranslating(final String machineString) throws BException { + TLC4BGlobals.setForceTLCToEvalConstants(false); + ToolIO.setMode(ToolIO.TOOL); + Translator b2tlaTranslator; + try { + b2tlaTranslator = new Translator(machineString); + b2tlaTranslator.translate(); + } catch (BCompoundException e) { + throw e.getFirstException(); + } + + } + + public static String translateTLA2B(String moduleName, String tlaString, String configString) + throws TLA2BException { + return de.tla2bAst.Translator.translateModuleString(moduleName, tlaString, configString); + } + + public static void compareLTLFormula(String expected, String machine, String ltlFormula) throws BCompoundException { + Translator b2tlaTranslator = new Translator(machine, ltlFormula); + b2tlaTranslator.translate(); + String translatedLTLFormula = b2tlaTranslator.getTranslatedLTLFormula(); + translatedLTLFormula = translatedLTLFormula.replaceAll("\\s", ""); + expected = expected.replaceAll("\\s", ""); + assertEquals(expected, translatedLTLFormula); + } + + public static void checkMachine(String machine) throws Exception { + Translator b2tlaTranslator = new Translator(machine); + b2tlaTranslator.translate(); + + String name = b2tlaTranslator.getMachineName(); + translateTLA2B(name, b2tlaTranslator.getModuleString(), b2tlaTranslator.getConfigString()); + } + + public static void compareEqualsConfig(String expectedModule, String expectedConfig, String machine) + throws Exception { + Translator b2tlaTranslator = new Translator(machine); + b2tlaTranslator.translate(); + + String name = b2tlaTranslator.getMachineName(); + + // parse check + translateTLA2B(name, b2tlaTranslator.getModuleString(), b2tlaTranslator.getConfigString()); + + assertEquals(expectedModule, b2tlaTranslator.getModuleString()); + assertEquals(expectedConfig, b2tlaTranslator.getConfigString()); + } + + public static void compareModuleAndConfig(String expectedModule, String expectedConfig, String machine) + throws BCompoundException, TLA2BException { + Translator b2tlaTranslator = new Translator(machine); + b2tlaTranslator.translate(); + + // TODO include config file in back translation from TLA+ to B + + // String name = b2tlaTranslator.getMachineName(); + // StringBuilder sb1 = de.tla2b.translation.Tla2BTranslator + // .translateString(name, b2tlaTranslator.getModuleString(), + // b2tlaTranslator.getConfigString()); + // StringBuilder sb2 = de.tla2b.translation.Tla2BTranslator + // .translateString(name, expectedModule, expectedConfig); + // if (!sb2.toString().equals(sb1.toString())) { + // fail("expected:\n" + expectedModule + "\nbut was:\n" + // + b2tlaTranslator.getModuleString() + "\n\nexpected:\n" + // + expectedConfig + "\nbut was:\n" + // + b2tlaTranslator.getConfigString()); + // } + } + + public static void compareEquals(String expected, String machine) throws BException { + try { + Translator b2tlaTranslator = new Translator(machine); + b2tlaTranslator.translate(); + assertEquals(expected, b2tlaTranslator.getModuleString()); + } catch (BCompoundException e) { + throw e.getFirstException(); + } + + } + + public static String translate(String machine) throws BException { + try { + Translator translator = new Translator(machine); + translator.translate(); + return translator.getModuleString(); + } catch (BCompoundException e) { + throw e.getFirstException(); + } + } + + public static TLCResult testString(String machineString) throws IOException { + String runnerClassName = TLC4BRunnerTestString.class.getCanonicalName(); + String[] args = new String[] { machineString }; + return runTLC(runnerClassName, args); + } + + public static TLCResult test(String[] args) throws IOException { + String runnerClassName = TLC4BTester.class.getCanonicalName(); + return runTLC(runnerClassName, args); + } + + private static TLCResult runTLC(String runnerClassName, String[] args) throws IOException { + final Process p = startJVM(runnerClassName, args); + StreamGobbler stdOut = new StreamGobbler(p.getInputStream()); + stdOut.start(); + try { + p.waitFor(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + + for (int i = stdOut.getLog().size() - 1; i > 1; i--) { + String s = stdOut.getLog().get(i); + if (s.startsWith("Result:")) { + String resultString = s.substring(s.indexOf(':') + 2); + resultString = resultString.replaceAll("\\s+", ""); + return TLCResult.valueOf(resultString); + } + } + return null; + + } + + private static Process startJVM(final String mainClass, final String[] arguments) + throws IOException { + + String separator = System.getProperty("file.separator"); + + String jvm = System.getProperty("java.home") + separator + "bin" + separator + "java"; + String classpath = System.getProperty("java.class.path"); + + List<String> command = new ArrayList<String>(); + command.add(jvm); + command.add("-cp"); + command.add(classpath); + command.add(mainClass); + command.addAll(Arrays.asList(arguments)); + + ProcessBuilder processBuilder = new ProcessBuilder(command); + processBuilder.redirectErrorStream(true); + Process process = processBuilder.start(); + return process; + } + + public static void testParse(String[] args, boolean deleteFiles) throws IOException, BCompoundException, FrontEndException { + TLC4BGlobals.resetGlobals(); + TLC4BGlobals.setDeleteOnExit(deleteFiles); + TLC4BGlobals.setCreateTraceFile(false); + TLC4BGlobals.setTestingMode(true); + // B2TLAGlobals.setCleanup(true); + TLC4B tlc4b = new TLC4B(); + tlc4b.process(args); + File module = new File(tlc4b.getBuildDir(), tlc4b.getMachineFileNameWithoutFileExtension() + ".tla"); + + // parse result + new de.tla2bAst.Translator(module.getCanonicalPath()); + } + +} + +class StreamGobbler extends Thread { + private InputStream is; + private ArrayList<String> log; + + public ArrayList<String> getLog() { + return log; + } + + StreamGobbler(InputStream is) { + this.is = is; + this.log = new ArrayList<String>(); + } + + public void run() { + try { + InputStreamReader isr = new InputStreamReader(is, "UTF-8"); + BufferedReader br = new BufferedReader(isr); + String line = null; + while ((line = br.readLine()) != null) { + System.out.println("> " + line); + log.add(line); + } + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/src/test/resources/compound/M1.mch b/src/test/resources/compound/M1.mch index 1288c0c6ba3ed6fcb367755811e2e84cc54aa0d9..3f8cb6563ce2847137af5017cab417a7800e850e 100644 --- a/src/test/resources/compound/M1.mch +++ b/src/test/resources/compound/M1.mch @@ -1,5 +1,5 @@ -MACHINE M1 -INCLUDES M2 -OPERATIONS -op1 = BEGIN op2 END +MACHINE M1 +INCLUDES M2 +OPERATIONS +op1 = BEGIN op2 END END \ No newline at end of file diff --git a/src/test/resources/compound/M2.mch b/src/test/resources/compound/M2.mch index e1c1bedb78ce4773739bcb4dfd9be9adfd35f071..3d2285f5fc220969fdbc206f89cdb8a623f7c855 100644 --- a/src/test/resources/compound/M2.mch +++ b/src/test/resources/compound/M2.mch @@ -1,7 +1,7 @@ -MACHINE M2 -VARIABLES x2 -INVARIANT x2 : INT -INITIALISATION x2 := 1 -OPERATIONS -op2 = x2 := 2 +MACHINE M2 +VARIABLES x2 +INVARIANT x2 : INT +INITIALISATION x2 := 1 +OPERATIONS +op2 = x2 := 2 END \ No newline at end of file diff --git a/src/test/resources/errors/EnumerationError.mch b/src/test/resources/errors/EnumerationError.mch index a71a1843f49caba6614939ebc4bcaa6ede91ea41..5fe0fb9084793393413b801302824e396e017dd8 100644 --- a/src/test/resources/errors/EnumerationError.mch +++ b/src/test/resources/errors/EnumerationError.mch @@ -1,5 +1,5 @@ -MACHINE EnumerationError -VARIABLES x -INVARIANT x = [1] -INITIALISATION x:(x: seq({1}) & x^x = [1,1]) +MACHINE EnumerationError +VARIABLES x +INVARIANT x = [1] +INITIALISATION x:(x: seq({1}) & x^x = [1,1]) END \ No newline at end of file diff --git a/src/test/resources/errors/PropertiesError.mch b/src/test/resources/errors/PropertiesError.mch index 5cc94da6a9ca7b9a3b132519c1892c37be66589e..bd73bc83c92a8c8564069a9ca0314a1fa5010cdf 100644 --- a/src/test/resources/errors/PropertiesError.mch +++ b/src/test/resources/errors/PropertiesError.mch @@ -1,3 +1,3 @@ -MACHINE PropertiesError -PROPERTIES 1 = 2 +MACHINE PropertiesError +PROPERTIES 1 = 2 END \ No newline at end of file diff --git a/src/test/resources/laws/FunctionsTest.mch b/src/test/resources/laws/FunctionsTest.mch index f05d0f82678eff0aacccc1fef067f85f2ba2da7c..2aa53b1ed12bc82050f80016835c18b982f6ba9c 100644 --- a/src/test/resources/laws/FunctionsTest.mch +++ b/src/test/resources/laws/FunctionsTest.mch @@ -1,36 +1,36 @@ -MACHINE FunctionsTest -DEFINITIONS -f == %x.(x : 1..10 | x+1) -VARIABLES x -INVARIANT x : 1..3 -INITIALISATION x := 1 -OPERATIONS -foo = PRE 1 = 1 THEN x := 2 END -ASSERTIONS - dom(%x.(x:{1,2,3}| 1)) = {1,2,3}; - ran(%x.(x:{1,2,3}| x)) = {1,2,3}; - - %x.(x:{1,2,3}|1) : {1,2,3} --> {1}; - %x.(x:{1,2}|x) : {1,2} >-> {1,2,3}; - %x.(x:{1,2,3}|1) : {1,2,3} -->> {1}; - %x.(x:{1,2}|x) : {1,2} >->> {1,2}; - %x,y.(x : 1..3 & y : 1..3| x+ y)(1,2) = 3; - %x.(x : 1..2| x ) : 1..3 +-> 1..3; - %x.(x:{1,2}|1) : {1,2,3} +-> {1}; - %x.(x:{1,2} & 1=1|1) : {1,2,3} +-> {1}; - %x.(x:{1}|1) : {1,2,3} >+> {1}; - %x.(x:{1,2}|1) : {1,2,3} +->> {1}; - %x.(x:{1,2}|x) : {1,2,3} >+>> {1,2}; - - dom(f) = 1..10; - ran(f) = 2..11; - id(1..3) = %x.(x : 1..3 | x); - 1..3 <| f = %x.(x : 1..3 | x + 1); - 1..3 <<| f = %x.(x : 4..10 | x + 1); - f |> 1..3 = %x.(x : 1..2 | x + 1); - f |>> 1..3 = %x.(x : 3..10 | x + 1); - f~= %x.(x : 2..11 | x-1); - f[1..3] = 2..4; - f <+ %x.(x : 10..11 | x+1) = %x.(x : 1..11 | x + 1); - f <+ %x.(x : 1..11 | x-1) = %x.(x : 1..11 | x - 1) +MACHINE FunctionsTest +DEFINITIONS +f == %x.(x : 1..10 | x+1) +VARIABLES x +INVARIANT x : 1..3 +INITIALISATION x := 1 +OPERATIONS +foo = PRE 1 = 1 THEN x := 2 END +ASSERTIONS + dom(%x.(x:{1,2,3}| 1)) = {1,2,3}; + ran(%x.(x:{1,2,3}| x)) = {1,2,3}; + + %x.(x:{1,2,3}|1) : {1,2,3} --> {1}; + %x.(x:{1,2}|x) : {1,2} >-> {1,2,3}; + %x.(x:{1,2,3}|1) : {1,2,3} -->> {1}; + %x.(x:{1,2}|x) : {1,2} >->> {1,2}; + %x,y.(x : 1..3 & y : 1..3| x+ y)(1,2) = 3; + %x.(x : 1..2| x ) : 1..3 +-> 1..3; + %x.(x:{1,2}|1) : {1,2,3} +-> {1}; + %x.(x:{1,2} & 1=1|1) : {1,2,3} +-> {1}; + %x.(x:{1}|1) : {1,2,3} >+> {1}; + %x.(x:{1,2}|1) : {1,2,3} +->> {1}; + %x.(x:{1,2}|x) : {1,2,3} >+>> {1,2}; + + dom(f) = 1..10; + ran(f) = 2..11; + id(1..3) = %x.(x : 1..3 | x); + 1..3 <| f = %x.(x : 1..3 | x + 1); + 1..3 <<| f = %x.(x : 4..10 | x + 1); + f |> 1..3 = %x.(x : 1..2 | x + 1); + f |>> 1..3 = %x.(x : 3..10 | x + 1); + f~= %x.(x : 2..11 | x-1); + f[1..3] = 2..4; + f <+ %x.(x : 10..11 | x+1) = %x.(x : 1..11 | x + 1); + f <+ %x.(x : 1..11 | x-1) = %x.(x : 1..11 | x - 1) END \ No newline at end of file diff --git a/src/test/resources/laws/RelVsFuncTest.mch b/src/test/resources/laws/RelVsFuncTest.mch index 4ce46998d8ba6cb22c0f5f0187e4e9a8c7c3453f..2acf92801513a067432df70c3c2b06fa9682d662 100644 --- a/src/test/resources/laws/RelVsFuncTest.mch +++ b/src/test/resources/laws/RelVsFuncTest.mch @@ -1,32 +1,32 @@ -MACHINE RelVsFuncTest -VARIABLES x -INVARIANT x : 1..3 -INITIALISATION x := 1 -OPERATIONS -foo = PRE 1 = 1 THEN x := 2 END -ASSERTIONS - {(1,2)}(1) = 2; - {{(1,1),(2,1)}} = {1,2} --> {1}; - {(1,1),(2,1)} : {1,2} --> {1}; - - {{(1,1)},{(1,2)}} = {1} >-> {1,2}; - {(1,1)} : {1} >-> {1,2}; - - {{(1,2),(2,2)}} = {1,2} -->> {2}; - {(1,2),(2,2)} : {1,2} -->> {2}; - - {{(1,2)}} = {1} >->> {2}; - {(1,2)} : {1} >->> {2}; - - {{(1,1)}, {}} = {1} +-> {1}; - {} : {1} +-> {1}; - - {{(1,1)},{}} = {1} >+> {1}; - {} : {1} >+> {1}; - - {{(1,2)}} = {1} +->> {2}; - {(1,2)} : {1} +->> {2}; - - {{(1,3)},{(2,3)}} = {1,2} >+>> {3}; - {(1,3)} : {1,2} >+>> {3} +MACHINE RelVsFuncTest +VARIABLES x +INVARIANT x : 1..3 +INITIALISATION x := 1 +OPERATIONS +foo = PRE 1 = 1 THEN x := 2 END +ASSERTIONS + {(1,2)}(1) = 2; + {{(1,1),(2,1)}} = {1,2} --> {1}; + {(1,1),(2,1)} : {1,2} --> {1}; + + {{(1,1)},{(1,2)}} = {1} >-> {1,2}; + {(1,1)} : {1} >-> {1,2}; + + {{(1,2),(2,2)}} = {1,2} -->> {2}; + {(1,2),(2,2)} : {1,2} -->> {2}; + + {{(1,2)}} = {1} >->> {2}; + {(1,2)} : {1} >->> {2}; + + {{(1,1)}, {}} = {1} +-> {1}; + {} : {1} +-> {1}; + + {{(1,1)},{}} = {1} >+> {1}; + {} : {1} >+> {1}; + + {{(1,2)}} = {1} +->> {2}; + {(1,2)} : {1} +->> {2}; + + {{(1,3)},{(2,3)}} = {1,2} >+>> {3}; + {(1,3)} : {1,2} >+>> {3} END \ No newline at end of file diff --git a/src/test/resources/laws/RelationsTest.mch b/src/test/resources/laws/RelationsTest.mch index a38ab60bf31533c96fda69e98e68629b02ee9c30..cd6158b39ef34b08b3ca992410c87589cf08b9c3 100644 --- a/src/test/resources/laws/RelationsTest.mch +++ b/src/test/resources/laws/RelationsTest.mch @@ -1,29 +1,29 @@ -MACHINE RelationsTest -VARIABLES x -INVARIANT x : 1..3 -INITIALISATION x := 1 -OPERATIONS -foo = PRE 1 = 1 THEN x := 2 END -ASSERTIONS - {(1,2)} = {1}*{2}; - dom({(1,2)}) = {1}; - ran({(1,2)}) = {2}; - id({3,5}) = {(3,3), (5,5)}; - {1} <| {(1,2), (2,3)} = {(1,2)}; - {1} <<| {(1,2), (2,3)} = {(2,3)}; - {(1,2), (2,3)} |> {2} = {(1,2)}; - {(1,2), (2,3)} |>> {2} = {(2,3)}; - {(1,2)}~ = {(2,1)}; - {(1,2),(1,3)}[{1}] = {2,3}; - {(1,2),(3,4)} <+ {(3,5)} = {(1,2),(3,5)}; - {(0,1)} >< {(0,2)} = {(0,(1,2))}; - ({(0,1)} || {(2,3)}) = {((0,2),(1,3))}; - ({(1,2)} ; {(2,3)}) = {(1,3)}; - prj1({1},{2}) = {((1,2),1)}; - prj2({1},{2}) = {((1,2),2)}; - iterate({(1,3),(2,1),(2,2),(3,3)}, 2) = {(1,3),(2,1),(2,2),(2,3),(3,3)}; - closure1({(1,3),(2,1),(2,2),(3,3)}) = {(1,3),(2,1),(2,2),(2,3),(3,3)}; - closure({(1,3),(2,1),(2,2),(3,3)}) = {(1,1),(1,3),(2,1),(2,2),(2,3),(3,3)}; - fnc({(0,1),(0,2)}) = {(0,{1,2})}; - rel({(0,{1,2})}) = {(0,1),(0,2)} +MACHINE RelationsTest +VARIABLES x +INVARIANT x : 1..3 +INITIALISATION x := 1 +OPERATIONS +foo = PRE 1 = 1 THEN x := 2 END +ASSERTIONS + {(1,2)} = {1}*{2}; + dom({(1,2)}) = {1}; + ran({(1,2)}) = {2}; + id({3,5}) = {(3,3), (5,5)}; + {1} <| {(1,2), (2,3)} = {(1,2)}; + {1} <<| {(1,2), (2,3)} = {(2,3)}; + {(1,2), (2,3)} |> {2} = {(1,2)}; + {(1,2), (2,3)} |>> {2} = {(2,3)}; + {(1,2)}~ = {(2,1)}; + {(1,2),(1,3)}[{1}] = {2,3}; + {(1,2),(3,4)} <+ {(3,5)} = {(1,2),(3,5)}; + {(0,1)} >< {(0,2)} = {(0,(1,2))}; + ({(0,1)} || {(2,3)}) = {((0,2),(1,3))}; + ({(1,2)} ; {(2,3)}) = {(1,3)}; + prj1({1},{2}) = {((1,2),1)}; + prj2({1},{2}) = {((1,2),2)}; + iterate({(1,3),(2,1),(2,2),(3,3)}, 2) = {(1,3),(2,1),(2,2),(2,3),(3,3)}; + closure1({(1,3),(2,1),(2,2),(3,3)}) = {(1,3),(2,1),(2,2),(2,3),(3,3)}; + closure({(1,3),(2,1),(2,2),(3,3)}) = {(1,1),(1,3),(2,1),(2,2),(2,3),(3,3)}; + fnc({(0,1),(0,2)}) = {(0,{1,2})}; + rel({(0,{1,2})}) = {(0,1),(0,2)} END \ No newline at end of file diff --git a/src/test/resources/laws/RelationsTest2.mch b/src/test/resources/laws/RelationsTest2.mch index e9314109a9a07fa08233cc99972a80538aec76d3..517b876e58c0231c9e2500148c0d24da80a2aa05 100644 --- a/src/test/resources/laws/RelationsTest2.mch +++ b/src/test/resources/laws/RelationsTest2.mch @@ -1,19 +1,19 @@ -MACHINE RelationsTest2 -VARIABLES x -INVARIANT x : 1..3 -INITIALISATION x := 1 -OPERATIONS -foo = PRE 1 = 1 THEN x := 2 END -ASSERTIONS - {1} <-> {2} = {{}, {(1,2)}}; - dom({(1,2)}) = {1}; - dom({(1,2,3)}) = {(1,2)}; - ran({(1,2)}) = {2}; - ran({(1,2,3)}) = {3}; - id({1,2}) = {(1,1),(2,2)}; - {1} <| {(1,2),(3,4)} = {(1,2)}; - {1} <<| {(1,2), (3,4)} = {(3,4)}; - {(3,TRUE)}[{3}] = {TRUE}; - {(1,TRUE)}~ = {(TRUE,1)}; - {(1,2)} <+ {(1,3)} ={(1,3)} -END +MACHINE RelationsTest2 +VARIABLES x +INVARIANT x : 1..3 +INITIALISATION x := 1 +OPERATIONS +foo = PRE 1 = 1 THEN x := 2 END +ASSERTIONS + {1} <-> {2} = {{}, {(1,2)}}; + dom({(1,2)}) = {1}; + dom({(1,2,3)}) = {(1,2)}; + ran({(1,2)}) = {2}; + ran({(1,2,3)}) = {3}; + id({1,2}) = {(1,1),(2,2)}; + {1} <| {(1,2),(3,4)} = {(1,2)}; + {1} <<| {(1,2), (3,4)} = {(3,4)}; + {(3,TRUE)}[{3}] = {TRUE}; + {(1,TRUE)}~ = {(TRUE,1)}; + {(1,2)} <+ {(1,3)} ={(1,3)} +END diff --git a/src/test/resources/laws/SequencesAsRelationsTest.mch b/src/test/resources/laws/SequencesAsRelationsTest.mch index 27e77ccc20f8ced8b90a2b4021418b3593a8dc27..e787121e0dd60c2043b941e622556e4eea3e05a3 100644 --- a/src/test/resources/laws/SequencesAsRelationsTest.mch +++ b/src/test/resources/laws/SequencesAsRelationsTest.mch @@ -1,94 +1,94 @@ -MACHINE SequencesAsRelationsTest -PROPERTIES - {} = [] -& {(1+0,1)} = [1] - -/* Set of sequences */ -& {(1+0,1)} : seq({1}) -& {(1+0,2)} /: seq({1}) -& not({(1+0,1)} /: seq({1})) -& {} : seq({1+0}) -& {} : seq({}) - -& {x,y| x : 1..10 & y : {3}} : seq({3}) -& {} \/ {} : seq({1}) -& {x,y| x : 1..10 & y : {3}} : seq1({3}) -& {} \/ {} /: seq1({1}) - - -/* Set of sequences */ -& {(1+0,1)} : seq1({1}) -& {} /: seq1({}) -& {(1+0,2)} /: seq1({1}) -& not({} : seq1({1+0})) -& not({} : seq1({})) - -/* Set of injective sequences */ -& iseq({}) = {{}} -& iseq({1}) = {{},{(1+0,1)}} - -/* Set of non empty injective sequences */ -& iseq1({}) = {} -& iseq1({1}) = {{(1+0,1)}} - -/* Size */ -& size({}) = 0 -& size({(1+0,1),(2,2)}) = 2 - -/* Concatenation */ -& {(1+0,1),(2,2)}^{(1,3)} = {(1,1),(2,2),(3,3)} -& {(1+0,1),(2,2)}^{} = {(1,1),(2,2)} -& {}^{(1+0,1),(2,2)} = {(1,1),(2,2)} -& {}^{} = {} - -/* Prepand */ -& 1 -> {(1+0,2),(2,3)} = {(1,1),(2,2),(3,3)} -& 1 -> {} = {(1+0,1)} - -/* Append */ -& {(1+0,1),(2,2)} <- 3 = {(1,1),(2,2),(3,3)} -& {} <- 1 = {(1+0,1)} - -/* Front */ -& front({(1+0,1)}) = {} -& front({(1+0,1),(2,2),(3,3)}) = {(1,1),(2,2)} - -/* First */ -& first({(1+0,1)}) = 1 -& first({(1+0,1),(2,2)}) = 1 - -/* Tail */ -& tail({(1+0,1)}) = {} -& tail({(1+0,1),(2,2),(3,3)}) = {(1,2),(2,3)} - -/* Last */ -& last({(1+0,1)}) = 1 -& last({(1+0,1),(2,2)}) = 2 - -/* Reverse */ -& rev({}) = {} -& rev({(1+0,1)}) = {(1,1)} -& rev({(1+0,1),(2,2),(3,3)}) = {(1,3),(2,2),(3,1)} - -/* Generalized Concatenation */ -& conc({(1,{(1,1),(2,2)}),(2,{(1,3)})}) = {(1,1),(2,2),(3,3)} -& conc({(1,{(1,1),(2,2)}),(2,{})}) = {(1,1),(2,2)} -& conc({(1,{}), (2,{(1,1),(2,2)})}) = {(1,1),(2,2)} -& conc({(1,{}),(2,{})}) = {} -& conc([{}, {(1,1),(2,2)}]) = {(1,1),(2,2)} - -/* Perm */ -& perm({3,4}) = {{(1,3),(2,4)},{(1,4),(2,3)}} -& perm({}) = {{}} - -/* Take first elements */ -& {(1+0,1),(2,2)} /|\ 1 = {(1,1)} -& {(1+0,1),(2,2)} /|\ 2 = {(1,1),(2,2)} -& {(1+0,1)} /|\ 0 = {} -& {} /|\ 0 = {} - -& {(1+0,1),(2,2)} \|/ 1 = {(1,2)} -& {(1+0,1),(2,2)} \|/ 0 = {(1,1),(2,2)} -& {(1+0,1)} \|/ 1 = {} -& {} \|/ 0 = {} +MACHINE SequencesAsRelationsTest +PROPERTIES + {} = [] +& {(1+0,1)} = [1] + +/* Set of sequences */ +& {(1+0,1)} : seq({1}) +& {(1+0,2)} /: seq({1}) +& not({(1+0,1)} /: seq({1})) +& {} : seq({1+0}) +& {} : seq({}) + +& {x,y| x : 1..10 & y : {3}} : seq({3}) +& {} \/ {} : seq({1}) +& {x,y| x : 1..10 & y : {3}} : seq1({3}) +& {} \/ {} /: seq1({1}) + + +/* Set of sequences */ +& {(1+0,1)} : seq1({1}) +& {} /: seq1({}) +& {(1+0,2)} /: seq1({1}) +& not({} : seq1({1+0})) +& not({} : seq1({})) + +/* Set of injective sequences */ +& iseq({}) = {{}} +& iseq({1}) = {{},{(1+0,1)}} + +/* Set of non empty injective sequences */ +& iseq1({}) = {} +& iseq1({1}) = {{(1+0,1)}} + +/* Size */ +& size({}) = 0 +& size({(1+0,1),(2,2)}) = 2 + +/* Concatenation */ +& {(1+0,1),(2,2)}^{(1,3)} = {(1,1),(2,2),(3,3)} +& {(1+0,1),(2,2)}^{} = {(1,1),(2,2)} +& {}^{(1+0,1),(2,2)} = {(1,1),(2,2)} +& {}^{} = {} + +/* Prepand */ +& 1 -> {(1+0,2),(2,3)} = {(1,1),(2,2),(3,3)} +& 1 -> {} = {(1+0,1)} + +/* Append */ +& {(1+0,1),(2,2)} <- 3 = {(1,1),(2,2),(3,3)} +& {} <- 1 = {(1+0,1)} + +/* Front */ +& front({(1+0,1)}) = {} +& front({(1+0,1),(2,2),(3,3)}) = {(1,1),(2,2)} + +/* First */ +& first({(1+0,1)}) = 1 +& first({(1+0,1),(2,2)}) = 1 + +/* Tail */ +& tail({(1+0,1)}) = {} +& tail({(1+0,1),(2,2),(3,3)}) = {(1,2),(2,3)} + +/* Last */ +& last({(1+0,1)}) = 1 +& last({(1+0,1),(2,2)}) = 2 + +/* Reverse */ +& rev({}) = {} +& rev({(1+0,1)}) = {(1,1)} +& rev({(1+0,1),(2,2),(3,3)}) = {(1,3),(2,2),(3,1)} + +/* Generalized Concatenation */ +& conc({(1,{(1,1),(2,2)}),(2,{(1,3)})}) = {(1,1),(2,2),(3,3)} +& conc({(1,{(1,1),(2,2)}),(2,{})}) = {(1,1),(2,2)} +& conc({(1,{}), (2,{(1,1),(2,2)})}) = {(1,1),(2,2)} +& conc({(1,{}),(2,{})}) = {} +& conc([{}, {(1,1),(2,2)}]) = {(1,1),(2,2)} + +/* Perm */ +& perm({3,4}) = {{(1,3),(2,4)},{(1,4),(2,3)}} +& perm({}) = {{}} + +/* Take first elements */ +& {(1+0,1),(2,2)} /|\ 1 = {(1,1)} +& {(1+0,1),(2,2)} /|\ 2 = {(1,1),(2,2)} +& {(1+0,1)} /|\ 0 = {} +& {} /|\ 0 = {} + +& {(1+0,1),(2,2)} \|/ 1 = {(1,2)} +& {(1+0,1),(2,2)} \|/ 0 = {(1,1),(2,2)} +& {(1+0,1)} \|/ 1 = {} +& {} \|/ 0 = {} END \ No newline at end of file diff --git a/src/test/resources/laws/SequencesExtendedTest.mch b/src/test/resources/laws/SequencesExtendedTest.mch index e9e37af036e1538146b0e4629511f01252ac5535..cb536bac3c99a30596c442c93203efb7f374596c 100644 --- a/src/test/resources/laws/SequencesExtendedTest.mch +++ b/src/test/resources/laws/SequencesExtendedTest.mch @@ -1,21 +1,21 @@ -MACHINE SequencesExtendedTest -VARIABLES x -INVARIANT x : 1..2 -INITIALISATION x := 1 -OPERATIONS -foo = PRE 1 = 1 THEN x := 2 END -ASSERTIONS - [] /: seq1({1,2}); - iseq({1,2}) ={[], [1], [2], [1, 2], [2, 1]}; - [1] : iseq({1,2}); - iseq1({1,2}) ={[1], [2], [1, 2], [2, 1]}; - [1] : iseq1({1,2}); - perm({1,2}) = {[1,2], [2,1]}; - rev([1,2,3]) = [3,2,1]; - conc([[1,2],[3],[4,5]]) = [1,2,3,4,5]; - [1,2,3,4] /|\ 3 = [1,2,3]; - [1,2,3,4] \|/ 3 = [4]; - 1 -> [2,3] = [1,2,3]; - last([1,2]) = 2; - front([1,2,3]) = [1,2] +MACHINE SequencesExtendedTest +VARIABLES x +INVARIANT x : 1..2 +INITIALISATION x := 1 +OPERATIONS +foo = PRE 1 = 1 THEN x := 2 END +ASSERTIONS + [] /: seq1({1,2}); + iseq({1,2}) ={[], [1], [2], [1, 2], [2, 1]}; + [1] : iseq({1,2}); + iseq1({1,2}) ={[1], [2], [1, 2], [2, 1]}; + [1] : iseq1({1,2}); + perm({1,2}) = {[1,2], [2,1]}; + rev([1,2,3]) = [3,2,1]; + conc([[1,2],[3],[4,5]]) = [1,2,3,4,5]; + [1,2,3,4] /|\ 3 = [1,2,3]; + [1,2,3,4] \|/ 3 = [4]; + 1 -> [2,3] = [1,2,3]; + last([1,2]) = 2; + front([1,2,3]) = [1,2] END \ No newline at end of file diff --git a/src/test/resources/laws/SequencesTest.mch b/src/test/resources/laws/SequencesTest.mch index 8c02f9b76985d2c80c584b162235d281fbb0bc6f..9732986483b1d467624a2254d69d086e21f36402 100644 --- a/src/test/resources/laws/SequencesTest.mch +++ b/src/test/resources/laws/SequencesTest.mch @@ -1,16 +1,16 @@ -MACHINE SequencesTest -VARIABLES x -INVARIANT x : 1..3 -INITIALISATION x := 1 -OPERATIONS -foo = PRE 1 = 1 THEN x := 2 END -ASSERTIONS - [1,2,3] = %x.(x: {1,2,3}|x); - [] = <>; - [1] : seq({1,2,3}); - size([1,2,3]) = 3; - [1,2] ^ [3] = [1,2,3]; - [1,2] <- 3 = [1,2,3]; - first([1,2]) = 1; - tail([1,2,3]) = [2,3] +MACHINE SequencesTest +VARIABLES x +INVARIANT x : 1..3 +INITIALISATION x := 1 +OPERATIONS +foo = PRE 1 = 1 THEN x := 2 END +ASSERTIONS + [1,2,3] = %x.(x: {1,2,3}|x); + [] = <>; + [1] : seq({1,2,3}); + size([1,2,3]) = 3; + [1,2] ^ [3] = [1,2,3]; + [1,2] <- 3 = [1,2,3]; + first([1,2]) = 1; + tail([1,2,3]) = [2,3] END \ No newline at end of file diff --git a/src/test/resources/test/M1.mch b/src/test/resources/test/M1.mch index f783daae6d1e4073a60266b1fe9f1cba2419be9e..2b99967e27740a5814583bcb0442d213b5e3b1be 100644 --- a/src/test/resources/test/M1.mch +++ b/src/test/resources/test/M1.mch @@ -1,4 +1,4 @@ -MACHINE M1 -SEES M2 -INVARIANT k = 1 & x = 1 +MACHINE M1 +SEES M2 +INVARIANT k = 1 & x = 1 END \ No newline at end of file diff --git a/src/test/resources/test/M2.mch b/src/test/resources/test/M2.mch index b96a579c22b23a57d9d9b48d57222260fceacfc4..455de0b011f193152af4e653bfdf7ef9eddaa871 100644 --- a/src/test/resources/test/M2.mch +++ b/src/test/resources/test/M2.mch @@ -1,7 +1,7 @@ -MACHINE M2 -CONSTANTS k -PROPERTIES k = 1 -VARIABLES x -INVARIANT x = 1 -INITIALISATION x := 1 +MACHINE M2 +CONSTANTS k +PROPERTIES k = 1 +VARIABLES x +INVARIANT x = 1 +INITIALISATION x := 1 END \ No newline at end of file