├── .git-blame-ignore-revs ├── .github └── workflows │ └── maven.yml ├── .gitignore ├── .pre-commit-config.yaml ├── .vscode └── settings.json ├── README.md ├── docs └── design │ ├── README.md │ ├── evaluation_survey │ ├── LiquidJava Evaluation with Hands-on Study.md │ ├── README.md │ └── trafficLight.png │ ├── figs │ └── banner.gif │ └── syntax_survey │ ├── Refinements_Syntax.md │ ├── analysis.html │ └── analysis.ipynb ├── liquidjava-api ├── pom.xml └── src │ └── main │ └── java │ ├── example │ ├── NumericExample.java │ ├── Simple.java │ └── ToSimple.java │ └── liquidjava │ ├── Main.java │ ├── infer │ └── InducedRefinementsParser.java │ ├── specification │ ├── ExternalRefinementsFor.java │ ├── Ghost.java │ ├── GhostMultiple.java │ ├── Refinement.java │ ├── RefinementAlias.java │ ├── RefinementAliasMultiple.java │ ├── RefinementPredicate.java │ ├── RefinementPredicateMultiple.java │ ├── StateRefinement.java │ ├── StateRefinementMultiple.java │ ├── StateSet.java │ └── StateSets.java │ └── utils │ ├── Prettify.java │ └── Processor.java ├── liquidjava-example ├── pom.xml ├── src │ └── main │ │ └── java │ │ ├── test │ │ └── currentlyTesting │ │ │ ├── Account.java │ │ │ ├── AccountClient.java │ │ │ └── SimpleTest.java │ │ ├── testSuite │ │ ├── CorrectAfterIfUsingScope.java │ │ ├── CorrectAlias.java │ │ ├── CorrectAliasExpressions.java │ │ ├── CorrectAliasMultiple.java │ │ ├── CorrectArithmeticBinaryOperations.java │ │ ├── CorrectAssignementAfterDeclaration.java │ │ ├── CorrectBooleanLitAndInvocations.java │ │ ├── CorrectChainedVariableReferences.java │ │ ├── CorrectDependentRefinements.java │ │ ├── CorrectFPArithmetic.java │ │ ├── CorrectFunctionCallSameVariableName.java │ │ ├── CorrectFunctionDeclarations.java │ │ ├── CorrectFunctionInInvocation.java │ │ ├── CorrectFunctionInvocation.java │ │ ├── CorrectFunctionsTutorial.java │ │ ├── CorrectIfThen.java │ │ ├── CorrectImplies.java │ │ ├── CorrectLongUsage.java │ │ ├── CorrectMethodInvocation.java │ │ ├── CorrectNoRefinements.java │ │ ├── CorrectPrimitiveNumbersTypes.java │ │ ├── CorrectReadSpecificAssignment.java │ │ ├── CorrectRecursion.java │ │ ├── CorrectSearchIndexIntArray.java │ │ ├── CorrectSearchValueIndexArray.java │ │ ├── CorrectSimpleAssignment.java │ │ ├── CorrectSimpleIfElse.java │ │ ├── CorrectSpecificFunctionInvocation.java │ │ ├── CorrectTernaryExpression.java │ │ ├── CorrectTrafficLightRGB.java │ │ ├── CorrectUnaryOperators.java │ │ ├── CorrectUsingAfterIf.java │ │ ├── ErrorAfterIf.java │ │ ├── ErrorAfterIf2.java │ │ ├── ErrorAlias.java │ │ ├── ErrorAliasArgumentSize.java │ │ ├── ErrorAliasSimple.java │ │ ├── ErrorAliasTypeMismatch.java │ │ ├── ErrorArithmeticBinaryOperations.java │ │ ├── ErrorArithmeticFP1.java │ │ ├── ErrorArithmeticFP2.java │ │ ├── ErrorArithmeticFP3.java │ │ ├── ErrorArithmeticFP4.java │ │ ├── ErrorAssignementAfterDeclaration.java │ │ ├── ErrorBooleanFunInvocation.java │ │ ├── ErrorBooleanLiteral.java │ │ ├── ErrorDependentRefinement.java │ │ ├── ErrorFunctionDeclarations.java │ │ ├── ErrorFunctionInvocation.java │ │ ├── ErrorFunctionInvocation1.java │ │ ├── ErrorFunctionInvocationParams.java │ │ ├── ErrorGhostArgsTypes.java │ │ ├── ErrorGhostNumberArgs.java │ │ ├── ErrorIfAssignment.java │ │ ├── ErrorIfAssignment2.java │ │ ├── ErrorImplementationSearchValueIntArray.java │ │ ├── ErrorLenZeroIntArray.java │ │ ├── ErrorLongUsage1.java │ │ ├── ErrorLongUsage2.java │ │ ├── ErrorNoRefinementsInVar.java │ │ ├── ErrorRecursion1.java │ │ ├── ErrorSearchIntArray.java │ │ ├── ErrorSearchValueIntArray1.java │ │ ├── ErrorSearchValueIntArray2.java │ │ ├── ErrorSimpleAssignment.java │ │ ├── ErrorSpecificArithmetic.java │ │ ├── ErrorSpecificValuesIf.java │ │ ├── ErrorSpecificValuesIf2.java │ │ ├── ErrorSpecificVarInRefinement.java │ │ ├── ErrorSpecificVarInRefinementIf.java │ │ ├── ErrorSyntax1.java │ │ ├── ErrorTernaryExpression.java │ │ ├── ErrorTrafficLightRGB.java │ │ ├── ErrorTypeInRefinements.java │ │ ├── ErrorUnaryOpMinus.java │ │ ├── ErrorUnaryOperators.java │ │ ├── SimpleTest.java │ │ ├── classes │ │ │ ├── ErrorGhostState.java │ │ │ ├── arraylist_correct │ │ │ │ ├── ArrayListRefinements.java │ │ │ │ └── SimpleTest.java │ │ │ ├── car_correct │ │ │ │ ├── Car.java │ │ │ │ └── Test.java │ │ │ ├── email_correct │ │ │ │ ├── Email.java │ │ │ │ └── TestEmail.java │ │ │ ├── email_error │ │ │ │ ├── Email.java │ │ │ │ └── TestEmail.java │ │ │ ├── input_reader_correct │ │ │ │ ├── InputStreamReaderRefs.java │ │ │ │ └── Test.java │ │ │ ├── input_reader_error │ │ │ │ ├── InputStreamReaderRefinements.java │ │ │ │ └── Test.java │ │ │ ├── input_reader_error2 │ │ │ │ ├── InputStreamReaderRefinements.java │ │ │ │ └── Test.java │ │ │ ├── iterator_correct │ │ │ │ ├── Iterator.java │ │ │ │ └── Test.java │ │ │ ├── iterator_error │ │ │ │ ├── Iterator.java │ │ │ │ └── Test.java │ │ │ ├── order_gift_correct │ │ │ │ ├── Order.java │ │ │ │ └── SimpleTest.java │ │ │ ├── order_gift_error │ │ │ │ ├── Order.java │ │ │ │ └── SimpleTest.java │ │ │ ├── refs_from_interface_error │ │ │ │ ├── Bus.java │ │ │ │ ├── ICar.java │ │ │ │ └── SimpleTest.java │ │ │ ├── refs_from_superclass_error │ │ │ │ ├── Bus.java │ │ │ │ ├── Car.java │ │ │ │ └── SimpleTest.java │ │ │ ├── refs_from_superclasses_correct │ │ │ │ ├── Bus.java │ │ │ │ └── Car.java │ │ │ ├── socket_error │ │ │ │ ├── SocketRefinements.java │ │ │ │ └── Test.java │ │ │ ├── state_from_superclass_correct │ │ │ │ ├── Bus.java │ │ │ │ ├── Car.java │ │ │ │ └── SimpleTest.java │ │ │ ├── state_multiple_cases_correct │ │ │ │ ├── InputStreamReaderRefinements.java │ │ │ │ └── SimpleTest.java │ │ │ ├── state_multiple_error │ │ │ │ ├── InputStreamReaderRefinements.java │ │ │ │ └── SimpleTest.java │ │ │ └── traffic_light_correct │ │ │ │ ├── SimpleTest.java │ │ │ │ └── TrafficLight.java │ │ ├── field_updates │ │ │ ├── CorrectFieldUpdate.java │ │ │ └── ErrorFieldUpdate.java │ │ └── math │ │ │ ├── correctInvocation │ │ │ ├── InvocationFromMathLibrary.java │ │ │ └── MathRefinements.java │ │ │ ├── errorAbs │ │ │ ├── MathAbs.java │ │ │ └── MathRefinements.java │ │ │ ├── errorMax │ │ │ ├── MathAbs.java │ │ │ └── MathRefinements.java │ │ │ └── errorMultiplyExact │ │ │ ├── MathMultiplyExact.java │ │ │ └── MathRefinements.java │ │ └── testingInProgress │ │ ├── Account.java │ │ ├── ArrayListRefinements.java │ │ ├── Car.java │ │ ├── Email.java │ │ ├── InputStreamReaderRefinements.java │ │ ├── MyList.java │ │ ├── Order.java │ │ ├── OrderSimple.java │ │ ├── SimpleTest.java │ │ ├── StringBuilderRefinements.java │ │ └── TrafficLight.java └── test1.txt ├── liquidjava-verifier ├── .gitignore ├── checkstyle.xml ├── lib │ ├── ModelCC.r2015.jar │ └── antlr-4.7.1-complete.jar ├── pom.xml └── src │ ├── main │ ├── antlr4 │ │ └── rj │ │ │ └── grammar │ │ │ └── RJ.g4 │ └── java │ │ └── liquidjava │ │ ├── api │ │ └── CommandLineLauncher.java │ │ ├── errors │ │ ├── ErrorEmitter.java │ │ ├── ErrorHandler.java │ │ └── ErrorPosition.java │ │ ├── processor │ │ ├── RefinementProcessor.java │ │ ├── TestInsideClasses.java │ │ ├── VCImplication.java │ │ ├── ann_generation │ │ │ └── FieldGhostsGeneration.java │ │ ├── context │ │ │ ├── AliasWrapper.java │ │ │ ├── Context.java │ │ │ ├── GhostFunction.java │ │ │ ├── GhostParentState.java │ │ │ ├── GhostState.java │ │ │ ├── ObjectState.java │ │ │ ├── PlacementInCode.java │ │ │ ├── Refined.java │ │ │ ├── RefinedFunction.java │ │ │ ├── RefinedVariable.java │ │ │ ├── Variable.java │ │ │ └── VariableInstance.java │ │ ├── facade │ │ │ ├── AliasDTO.java │ │ │ └── GhostDTO.java │ │ └── refinement_checker │ │ │ ├── ExternalRefinementTypeChecker.java │ │ │ ├── MethodsFirstChecker.java │ │ │ ├── RefinementTypeChecker.java │ │ │ ├── TypeChecker.java │ │ │ ├── TypeCheckingUtils.java │ │ │ ├── VCChecker.java │ │ │ ├── general_checkers │ │ │ ├── MethodsFunctionsChecker.java │ │ │ └── OperationsChecker.java │ │ │ └── object_checkers │ │ │ ├── AuxHierarchyRefinememtsPassage.java │ │ │ └── AuxStateHandler.java │ │ ├── rj_language │ │ ├── BuiltinFunctionPredicate.java │ │ ├── Predicate.java │ │ ├── ast │ │ │ ├── AliasInvocation.java │ │ │ ├── BinaryExpression.java │ │ │ ├── Expression.java │ │ │ ├── FunctionInvocation.java │ │ │ ├── GroupExpression.java │ │ │ ├── Ite.java │ │ │ ├── LiteralBoolean.java │ │ │ ├── LiteralInt.java │ │ │ ├── LiteralReal.java │ │ │ ├── LiteralString.java │ │ │ ├── UnaryExpression.java │ │ │ ├── Var.java │ │ │ └── typing │ │ │ │ └── TypeInfer.java │ │ ├── parsing │ │ │ ├── ParsingException.java │ │ │ ├── RJErrorListener.java │ │ │ └── RefinementsParser.java │ │ └── visitors │ │ │ ├── AliasVisitor.java │ │ │ ├── CreateASTVisitor.java │ │ │ └── GhostVisitor.java │ │ ├── smt │ │ ├── GhostFunctionError.java │ │ ├── NotFoundError.java │ │ ├── SMTEvaluator.java │ │ ├── TranslatorContextToZ3.java │ │ ├── TranslatorToZ3.java │ │ ├── TypeCheckError.java │ │ └── TypeMismatchError.java │ │ └── utils │ │ ├── Pair.java │ │ └── Utils.java │ └── test │ └── java │ └── liquidjava │ └── api │ └── tests │ └── TestExamples.java └── pom.xml /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | 012a81397062e33d44d9dbc5974c44483ca4763b 2 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven, and cache/restore any dependencies to improve the workflow execution time 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-maven 3 | 4 | # This workflow uses actions that are not certified by GitHub. 5 | # They are provided by a third-party and are governed by 6 | # separate terms of service, privacy policy, and support 7 | # documentation. 8 | 9 | name: Java CI with Maven 10 | 11 | on: 12 | push: 13 | branches: [ "main" ] 14 | pull_request: 15 | branches: [ "main" ] 16 | 17 | 18 | 19 | jobs: 20 | build: 21 | name: Maven test on Java ${{ matrix.java }} 22 | runs-on: ubuntu-latest 23 | env: 24 | SEGMENT_DOWNLOAD_TIMEOUT_MINS: '15' 25 | strategy: 26 | matrix: 27 | java: ['20'] 28 | steps: 29 | # Checkout the repository code 30 | - uses: actions/checkout@v3 31 | 32 | # Set up JDK 20 33 | - name: Set up JDK 20 34 | uses: actions/setup-java@v3 35 | with: 36 | java-version: ${{ matrix.java }} 37 | distribution: 'temurin' 38 | cache: maven 39 | 40 | # Cache Maven dependencies (adjust cache key to optimize) 41 | - name: Cache Maven dependencies 42 | uses: actions/cache@v3 43 | with: 44 | path: ~/.m2/repository 45 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} # Cache dependencies based on pom.xml changes 46 | restore-keys: | 47 | ${{ runner.os }}-maven- 48 | 49 | # Build the project (compiles and packages the code) 50 | - name: Build the project 51 | run: mvn -B -X -e clean install --file pom.xml --batch-mode --fail-fast 52 | 53 | # Run tests 54 | - name: Run tests 55 | run: mvn test -B -X -e --file pom.xml --batch-mode --fail-fast 56 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | # See https://pre-commit.com for more information 2 | # See https://pre-commit.com/hooks.html for more hooks 3 | repos: 4 | - repo: https://github.com/pre-commit/pre-commit-hooks 5 | rev: v5.0.0 6 | hooks: 7 | - id: trailing-whitespace 8 | - id: end-of-file-fixer 9 | - id: check-yaml 10 | - id: check-added-large-files 11 | - repo: https://github.com/macisamuele/language-formatters-pre-commit-hooks 12 | rev: v2.14.0 13 | hooks: 14 | - id: pretty-format-java 15 | args: [--palantir, --autofix] 16 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "java.configuration.updateBuildConfiguration": "automatic" 3 | } 4 | -------------------------------------------------------------------------------- /docs/design/README.md: -------------------------------------------------------------------------------- 1 | The full artifact for the design of initial version od the LiquidJava language is available at https://zenodo.org/record/7632872 2 | -------------------------------------------------------------------------------- /docs/design/evaluation_survey/README.md: -------------------------------------------------------------------------------- 1 | Find the examples described in the Study in https://github.com/CatarinaGamboa/liquidjava-examples 2 | -------------------------------------------------------------------------------- /docs/design/evaluation_survey/trafficLight.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CatarinaGamboa/liquidjava/79afe64e54b247fb1fd8a740188977baf43bb0aa/docs/design/evaluation_survey/trafficLight.png -------------------------------------------------------------------------------- /docs/design/figs/banner.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CatarinaGamboa/liquidjava/79afe64e54b247fb1fd8a740188977baf43bb0aa/docs/design/figs/banner.gif -------------------------------------------------------------------------------- /liquidjava-api/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 4.0.0 5 | 6 | 7 | liquidjava 8 | liquidjava-umbrella 9 | 1.0 10 | 11 | 12 | liquidjava-api 13 | liquidjava-api 14 | 0.0.2-SNAPSHOT 15 | liquidjava-api 16 | jar 17 | 18 | 19 | 20 | 21 | 34 | 35 | org.apache.maven.plugins 36 | maven-compiler-plugin 37 | 3.8.1 38 | 39 | 20 40 | 20 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 20 49 | 20 50 | 20 51 | 52 | 53 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/example/NumericExample.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014, United States Government, as represented by the 3 | * Administrator of the National Aeronautics and Space Administration. 4 | * All rights reserved. 5 | * 6 | * Symbolic Pathfinder (jpf-symbc) is licensed under the Apache License, 7 | * Version 2.0 (the "License"); you may not use this file except 8 | * in compliance with the License. You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0. 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package example; 20 | 21 | public class NumericExample { 22 | 23 | public static int test(int a, int b) { 24 | int c = a / (b + a - 2); 25 | if (c > 0) System.out.println(">0"); 26 | else System.out.println("<=0"); 27 | 28 | return c; 29 | } 30 | 31 | public static void main(String[] args) { 32 | test(0, 0); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/example/Simple.java: -------------------------------------------------------------------------------- 1 | package example; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @Refinement("super.x > 10") 6 | public class Simple extends ToSimple { 7 | 8 | @Refinement("z > 0 && z > super.x") 9 | private int z; 10 | 11 | @Refinement("\\return == x + 1") 12 | public static int function1(@Refinement("x > 0") final int x) { 13 | 14 | @Refinement("y > 0") 15 | int y = x + 1; 16 | 17 | return y; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/example/ToSimple.java: -------------------------------------------------------------------------------- 1 | package example; 2 | 3 | public class ToSimple { 4 | 5 | protected int x; 6 | } 7 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/liquidjava/Main.java: -------------------------------------------------------------------------------- 1 | package liquidjava; 2 | 3 | import example.Simple; 4 | import java.util.List; 5 | import liquidjava.infer.InducedRefinementsParser; 6 | import liquidjava.utils.Processor; 7 | 8 | /** Main class for the Repair system */ 9 | public class Main { 10 | 11 | public static void main(String[] args) throws Exception { 12 | 13 | List refinements = (new Processor()).getRefinement(new Simple()); 14 | 15 | List inducedRefinements = InducedRefinementsParser.parseRefinements("output3"); 16 | 17 | System.out.println(refinements); 18 | System.out.println(inducedRefinements); 19 | 20 | String finalRefinement = ""; 21 | 22 | if (!refinements.isEmpty()) { 23 | finalRefinement += String.join(" && ", refinements); 24 | 25 | if (!refinements.isEmpty()) finalRefinement += " && " + String.join(" && ", inducedRefinements); 26 | } else if (!inducedRefinements.isEmpty()) finalRefinement = String.join(" && ", inducedRefinements); 27 | 28 | System.out.println(finalRefinement); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/liquidjava/infer/InducedRefinementsParser.java: -------------------------------------------------------------------------------- 1 | package liquidjava.infer; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.FileReader; 5 | import java.io.IOException; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | 9 | public class InducedRefinementsParser { 10 | 11 | private static final String STARTER = "====================================================== search started:"; 12 | private static final String ENDER = "*************Summary***************"; 13 | 14 | public InducedRefinementsParser() { 15 | // Does nothing 16 | } 17 | 18 | public static List parseRefinements(String file) throws IOException { 19 | 20 | List result = new ArrayList<>(); 21 | 22 | try (BufferedReader reader = new BufferedReader(new FileReader(file))) { 23 | 24 | String line = reader.readLine(); 25 | 26 | boolean start = false; 27 | boolean end = false; 28 | 29 | while ((line = reader.readLine()) != null && !end) { 30 | if (!start) { 31 | start = line.startsWith(STARTER); 32 | continue; 33 | } else end = line.startsWith(ENDER); 34 | 35 | if (start && !end) 36 | if (line.contains("NPC constraint")) { 37 | 38 | line = reader.readLine(); 39 | 40 | while (line.endsWith("&&") || line.endsWith("||")) line += reader.readLine(); 41 | 42 | if (line.startsWith("%")) line = line.substring(line.indexOf("%", 2) + 1); 43 | 44 | result.add(line); 45 | } 46 | } 47 | 48 | } catch (IOException e) { 49 | e.printStackTrace(); 50 | } 51 | 52 | return result; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/liquidjava/specification/ExternalRefinementsFor.java: -------------------------------------------------------------------------------- 1 | package liquidjava.specification; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Annotation to create refinements for an external library. The annotation receives the path of the 10 | * library e.g. @ExternalRefinementsFor("java.lang.Math") 11 | * 12 | * @author catarina gamboa 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target({ElementType.TYPE}) 16 | public @interface ExternalRefinementsFor { 17 | /** 18 | * The prefix of the external method 19 | * 20 | * @return 21 | */ 22 | public String value(); 23 | } 24 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/liquidjava/specification/Ghost.java: -------------------------------------------------------------------------------- 1 | package liquidjava.specification; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Repeatable; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | /** 10 | * Annotation to create a ghost variable for a class. The annotation receives 11 | * the type and name of 12 | * the ghost within a string e.g. @Ghost("int size") 13 | * 14 | * @author catarina gamboa 15 | */ 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Target({ElementType.TYPE}) 18 | @Repeatable(GhostMultiple.class) 19 | public @interface Ghost { 20 | public String value(); 21 | } 22 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/liquidjava/specification/GhostMultiple.java: -------------------------------------------------------------------------------- 1 | package liquidjava.specification; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Annotation to allow the creation of multiple @Ghost 10 | * 11 | * @author catarina gamboa 12 | */ 13 | @Retention(RetentionPolicy.RUNTIME) 14 | @Target({ElementType.TYPE}) 15 | public @interface GhostMultiple { 16 | Ghost[] value(); 17 | } 18 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/liquidjava/specification/Refinement.java: -------------------------------------------------------------------------------- 1 | package liquidjava.specification; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Annotation to add a refinement to variables, class fields, method's parameters and method's 10 | * return value e.g. @Refinement("x > 0") int x; 11 | * 12 | * @author catarina gamboa 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target({ElementType.METHOD, ElementType.FIELD, ElementType.LOCAL_VARIABLE, ElementType.PARAMETER, ElementType.TYPE}) 16 | public @interface Refinement { 17 | 18 | public String value(); 19 | } 20 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/liquidjava/specification/RefinementAlias.java: -------------------------------------------------------------------------------- 1 | package liquidjava.specification; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Repeatable; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | /** 10 | * Annotation to create a ghost variable for a class. The annotation receives the type and name of 11 | * the ghost within a string e.g. @RefinementAlias("Nat(int x) {x > 0}") 12 | * 13 | * @author catarina gamboa 14 | */ 15 | @Retention(RetentionPolicy.RUNTIME) 16 | @Target({ElementType.TYPE}) 17 | @Repeatable(RefinementAliasMultiple.class) 18 | public @interface RefinementAlias { 19 | public String value(); 20 | } 21 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/liquidjava/specification/RefinementAliasMultiple.java: -------------------------------------------------------------------------------- 1 | package liquidjava.specification; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Annotation to create a multiple Alias in a class 10 | * 11 | * @author catarina gamboa 12 | */ 13 | @Retention(RetentionPolicy.RUNTIME) 14 | @Target({ElementType.TYPE}) 15 | public @interface RefinementAliasMultiple { 16 | RefinementAlias[] value(); 17 | } 18 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/liquidjava/specification/RefinementPredicate.java: -------------------------------------------------------------------------------- 1 | package liquidjava.specification; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Repeatable; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | @Retention(RetentionPolicy.RUNTIME) 10 | @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) 11 | @Repeatable(RefinementPredicateMultiple.class) 12 | public @interface RefinementPredicate { 13 | public String value(); 14 | } 15 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/liquidjava/specification/RefinementPredicateMultiple.java: -------------------------------------------------------------------------------- 1 | package liquidjava.specification; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Retention(RetentionPolicy.RUNTIME) 9 | @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) 10 | public @interface RefinementPredicateMultiple { 11 | RefinementPredicate[] value(); 12 | } 13 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/liquidjava/specification/StateRefinement.java: -------------------------------------------------------------------------------- 1 | package liquidjava.specification; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Repeatable; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | /** 10 | * Annotation to create state transitions in a method. The annotation has two arguments: from : the 11 | * state in which the object needs to be for the method to be invoked correctly to : the state in 12 | * which the object will be after the execution of the method 13 | * e.g. @StateRefinement(from="open(this)", to="closed(this)") 14 | * 15 | * @author catarina gamboa 16 | */ 17 | @Retention(RetentionPolicy.RUNTIME) 18 | @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) 19 | @Repeatable(StateRefinementMultiple.class) 20 | public @interface StateRefinement { 21 | public String from() default ""; 22 | 23 | public String to() default ""; 24 | } 25 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/liquidjava/specification/StateRefinementMultiple.java: -------------------------------------------------------------------------------- 1 | package liquidjava.specification; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Interface to allow multiple state refinements in a method. A method can have a state refinement 10 | * for each set of different source and destination states 11 | * 12 | * @author catarina gamboa 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) 16 | public @interface StateRefinementMultiple { 17 | StateRefinement[] value(); 18 | } 19 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/liquidjava/specification/StateSet.java: -------------------------------------------------------------------------------- 1 | package liquidjava.specification; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Repeatable; 5 | import java.lang.annotation.Retention; 6 | import java.lang.annotation.RetentionPolicy; 7 | import java.lang.annotation.Target; 8 | 9 | /** 10 | * Annotation to create the disjoint states in which class objects can be. The annotation receives a 11 | * list of strings representing the names of the states. e.g. @StateSet({"open", "reading", 12 | * "closed"}) 13 | * 14 | * @author catarina gamboa 15 | */ 16 | @Retention(RetentionPolicy.RUNTIME) 17 | @Target({ElementType.TYPE}) 18 | @Repeatable(StateSets.class) 19 | public @interface StateSet { 20 | public String[] value(); 21 | } 22 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/liquidjava/specification/StateSets.java: -------------------------------------------------------------------------------- 1 | package liquidjava.specification; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | /** 9 | * Interface to allow multiple StateSets in a class. 10 | * 11 | * @author catarina gamboa 12 | */ 13 | @Retention(RetentionPolicy.RUNTIME) 14 | @Target({ElementType.TYPE}) 15 | public @interface StateSets { 16 | StateSet[] value(); 17 | } 18 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/liquidjava/utils/Prettify.java: -------------------------------------------------------------------------------- 1 | package liquidjava.utils; 2 | 3 | public class Prettify {} 4 | -------------------------------------------------------------------------------- /liquidjava-api/src/main/java/liquidjava/utils/Processor.java: -------------------------------------------------------------------------------- 1 | package liquidjava.utils; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | import liquidjava.specification.Refinement; 7 | 8 | public class Processor { 9 | 10 | public List getRefinement(Object object) throws Exception { 11 | 12 | List result = new ArrayList<>(); 13 | 14 | Class clazz = object.getClass(); 15 | 16 | for (Method method : clazz.getDeclaredMethods()) { 17 | method.setAccessible(true); 18 | 19 | if (method.isAnnotationPresent(Refinement.class)) 20 | result.add(method.getAnnotation(Refinement.class).value().toString()); 21 | } 22 | 23 | return result; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /liquidjava-example/pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 4.0.0 6 | 7 | liquidjava 8 | liquidjava-umbrella 9 | 1.0 10 | 11 | 12 | liquidjava-example 13 | liquidjava-example 14 | 0.0.1-SNAPSHOT 15 | liquidjava-example 16 | jar 17 | 18 | 19 | 20 | 21 | org.apache.maven.plugins 22 | maven-compiler-plugin 23 | ${pVersion.compiler} 24 | 25 | 20 26 | 20 27 | 28 | 29 | 30 | 31 | 32 | 33 | UTF-8 34 | 20 35 | 20 36 | 37 | 4.13.1 38 | 1.3.0 39 | 40 | 3.8.0 41 | 2.22.1 42 | 43 | 44 | 45 | 46 | org.mdkt.compiler 47 | InMemoryJavaCompiler 48 | ${version.memcompiler} 49 | 50 | 51 | liquidjava-api 52 | liquidjava-api 53 | 0.0.2-SNAPSHOT 54 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/test/currentlyTesting/Account.java: -------------------------------------------------------------------------------- 1 | package test.currentlyTesting; 2 | 3 | // import liquidjava.specification.Ghost; 4 | // import liquidjava.specification.StateRefinement; 5 | // import liquidjava.specification.StateSet; 6 | 7 | // @Ghost("int amount") 8 | // @StateSet({"positive", "negative"}) 9 | public class Account { 10 | // int qnt; 11 | // 12 | // @StateRefinement(from="positive(this)", 13 | // to="(amount(this) == amount(old(this)) - x) && " + 14 | // "(amount(this) < 0? negative(this):positive(this))") 15 | //// @StateRefinement(to="(amount(this) == amount(old(this)) - x)") 16 | // public int withdraw(int x) { 17 | // qnt -= x; 18 | // return qnt; 19 | // } 20 | // 21 | // @StateRefinement(to="amount(this) == amount(old(this)) + x") 22 | // public void add(int x) { 23 | // qnt += x; 24 | // } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/test/currentlyTesting/AccountClient.java: -------------------------------------------------------------------------------- 1 | package test.currentlyTesting; 2 | 3 | // @StateSet({"active", "inactive"}) 4 | public class AccountClient { 5 | 6 | // @StateRefinement(from="active(this)", to="active(this)") 7 | // public boolean transfer(Account from, Account to, @Refinement("amount(from) >= value") int 8 | // value) { 9 | // from.withdraw(value); 10 | // to.add(value); 11 | // return true; 12 | // } 13 | 14 | } 15 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/test/currentlyTesting/SimpleTest.java: -------------------------------------------------------------------------------- 1 | package test.currentlyTesting; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | class SimpleTest { 6 | 7 | @Refinement("return > 0") 8 | public int test() { 9 | return 10; 10 | } 11 | } 12 | 13 | // @RefinementAlias("Percentage(int x) { 0 <= x && x <= 100 }") 14 | // @Refinement("Percentage(_)") 15 | // public static int addBonus( 16 | // @Refinement("Percentage(grade)") int grade, 17 | // @Refinement("Percentage(bonus) && (bonus < grade)") 18 | // int bonus) { 19 | // 20 | // if((grade + bonus) > 100) 21 | // return 100; 22 | // 23 | // else 24 | // return grade+bonus; 25 | // } 26 | // 27 | 28 | // @Refinement("_ > 10") 29 | // int i = 10; 30 | 31 | // @Refinement("sum(_) > 30") 32 | // Account a = new Account(50); 33 | // a.deposit(60); 34 | 35 | // Account b = new Account(138); 36 | // b = a.transferTo(b, 10); 37 | // 38 | // @Refinement("sum(_) == 148") 39 | // Account c = b; 40 | 41 | // Order o = new Order(); 42 | // 43 | // Order f = o.addItem("shirt", 60).addGift(); 44 | // .getNewOrderPayThis().addItem("t", 6).addItem("t", 1); 45 | // o.addGift(); 46 | // f.addItem("l", 1).pay(000).addGift().pay(000);//.addTransportCosts().sendToAddress("home"); 47 | 48 | // TrafficLight tl = new TrafficLight(); 49 | // tl.transitionToAmber(); 50 | // 51 | 52 | // TrafficLight tl2 = tl.getTrafficLightStartingRed(); 53 | // tl2.transitionToFlashingAmber(); 54 | 55 | // tl.transitionToAmber(); 56 | // tl.transitionToAmber(); 57 | 58 | // tl.passagersCross(); 59 | // tl.intermitentMalfunction(); 60 | 61 | // tl.transitionToFlashingAmber(); 62 | 63 | // @Refinement("size(al) < 4") 64 | // ArrayList al = new ArrayList(); 65 | // al.add(1); 66 | // al.add(1); 67 | // al.get(2); 68 | 69 | // @Refinement("size(t) == 3") 70 | // ArrayList t = al; 71 | 72 | // 73 | // Order o = new Order(); 74 | // o.addItem("shirt", 5) 75 | // .addItem("shirt", 10) 76 | // .addItem("h", 20) 77 | // .addItem("h", 6); 78 | 79 | // InputStreamReader isr = new InputStreamReader(System.in); 80 | // isr.read(); 81 | // isr.read(); 82 | // isr.read(); 83 | // isr.close(); 84 | // 85 | // //... 86 | // isr.read(); 87 | 88 | // @Refinement("_ > 0") 89 | // public int fun (int[] arr) { 90 | // return max(arr[0], 1); 91 | // } 92 | // 93 | 94 | // //@Refinement("_.length(x) >= 0") == 95 | //// @Refinement("length(_, x) >= 0") 96 | //// int[] a1 = new int[5]; 97 | // K(.., ..) 98 | 99 | // } 100 | 101 | // See error NaN 102 | // @Refinement("true") 103 | // double b = 0/0; 104 | // @Refinement("_ > 5") 105 | // double c = b; 106 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectAfterIfUsingScope.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectAfterIfUsingScope { 7 | public static void main(String[] args) { 8 | // Example 1 9 | @Refinement("_ < 100") 10 | int ielse = 90; 11 | 12 | @Refinement("_ < 10") 13 | int then = 7; 14 | if (then > 6) then = then - 2; 15 | else ielse = 5; 16 | 17 | @Refinement("_ == 7 || _ == 5") 18 | int some = then; 19 | @Refinement("_ == 5 || _==90") 20 | int thing = ielse; 21 | 22 | // EXAMPLE 2 23 | @Refinement("_ < 100") 24 | int value = 90; 25 | 26 | if (value > 6) { 27 | @Refinement("_ > 10") 28 | int innerScope = 30; 29 | value = innerScope; 30 | } 31 | 32 | @Refinement("_ == 30 || _ == 90") 33 | int some2 = value; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectAlias.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementAlias; 5 | 6 | @SuppressWarnings("unused") 7 | @RefinementAlias("type PtGrade(int x) { x >= 0 && x <= 20}") 8 | public class CorrectAlias { 9 | 10 | public static void main(String[] args) { 11 | @Refinement("PtGrade(_) && _ >= 10") 12 | int positiveGrade = 15; 13 | 14 | @Refinement("_ > 5 && _ < 18") 15 | int nGrade = 10; 16 | @Refinement("PtGrade(_) && PtGrade(nGrade)") 17 | int positiveGrade2 = 15; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectAliasExpressions.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementAlias; 5 | 6 | @RefinementAlias("InRange(int val, int low, int up) {low < val && val < up}") 7 | public class CorrectAliasExpressions { 8 | 9 | @Refinement("InRange( _, 10, 16)") 10 | public static int getNum() { 11 | return 15; 12 | } 13 | 14 | @SuppressWarnings("unused") 15 | public static void main(String[] args) { 16 | 17 | @Refinement("InRange( _, 10, 122+5)") 18 | int j = getNum(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectAliasMultiple.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementAlias; 5 | 6 | @SuppressWarnings("unused") 7 | @RefinementAlias("type Positive(double x) { x > 0}") 8 | @RefinementAlias("type PtGrade(double x) { x >= 0 && x <= 20}") 9 | public class CorrectAliasMultiple { 10 | 11 | public static void main(String[] args) { 12 | @Refinement("PtGrade(_)") 13 | double positiveGrade2 = 20 * 0.5 + 20 * 0.5; 14 | 15 | @Refinement("Positive(_)") 16 | double positive = positiveGrade2; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectArithmeticBinaryOperations.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectArithmeticBinaryOperations { 7 | public static void main(String[] args) { 8 | // Arithmetic Binary Operations 9 | @Refinement("a == 10") 10 | int a = 10; 11 | @Refinement("b != 10") 12 | int b = 5; 13 | @Refinement("t > 0") 14 | int t = a + 1; 15 | @Refinement("_ >= 9") 16 | int k = a - 1; 17 | @Refinement("_ >= 5") 18 | int l = k * t; 19 | @Refinement("_ > 0") 20 | int m = l / 2; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectAssignementAfterDeclaration.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectAssignementAfterDeclaration { 7 | public static void main(String[] args) { 8 | @Refinement("(z > 0) && (z < 50)") 9 | int z = 1; 10 | @Refinement("u < 100") 11 | int u = 10; 12 | u = 11 + z; 13 | u = z * 2; 14 | u = 30 + z; 15 | @Refinement("_ > 0") 16 | int n = 1; 17 | n = z + n + 1 * n; 18 | @Refinement("y > 0") 19 | int y = 15; 20 | y = y * y; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectBooleanLitAndInvocations.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectBooleanLitAndInvocations { 7 | @Refinement("_ == (n > 10)") 8 | public static boolean greaterThanTen(int n) { 9 | return n > 10; 10 | } 11 | 12 | public static void main(String[] args) { 13 | 14 | @Refinement("_ < 10") 15 | int a = 5; 16 | 17 | @Refinement("_ == true") 18 | boolean k = (a < 11); 19 | 20 | @Refinement("_ == true") 21 | boolean o = !(a == 12); 22 | 23 | @Refinement("_ == false") 24 | boolean m = greaterThanTen(a); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectChainedVariableReferences.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectChainedVariableReferences { 7 | public static void main(String[] args) { 8 | @Refinement("_ < 10") 9 | int a = 5; 10 | 11 | @Refinement("_ > a && _ < 20") 12 | int b = 18; 13 | 14 | @Refinement("_ > b && _ < 60") 15 | int c = 40; 16 | 17 | @Refinement("true") 18 | int d = c; 19 | 20 | @Refinement("_ > c") 21 | int e = 80; 22 | 23 | @Refinement("_ > (c+c)") 24 | int f = 8000; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectDependentRefinements.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectDependentRefinements { 7 | public static void main(String[] args) { 8 | 9 | @Refinement("_ < 10") 10 | int smaller = 5; 11 | @Refinement("bigger > 20") 12 | int bigger = 50; 13 | @Refinement("_ > smaller && _ < bigger") 14 | int middle = 15; 15 | 16 | @Refinement("_ >= smaller") 17 | int k = 10; 18 | @Refinement("_ <= bigger") 19 | int y = 10; 20 | 21 | @Refinement("_ == 20") 22 | int x1 = 20; 23 | @Refinement("_ == x1 + 1") 24 | int x2 = 21; 25 | @Refinement("_ == x1 - 1") 26 | int x3 = 19; 27 | @Refinement("_ == x1 * 5") 28 | int x4 = x1 * 5; 29 | @Refinement("_ == x1 / 2") 30 | int x5 = 10; 31 | @Refinement("_ == x1 % 2") 32 | int x6 = 0; 33 | @Refinement("(-x7) < x1") 34 | int x7 = 0; 35 | @Refinement("_ != x1") 36 | int x8 = 0; 37 | 38 | @Refinement("_ == 30") 39 | int o = 30; 40 | @Refinement("_ == x1 || _ == o ") 41 | int x9 = 20; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectFPArithmetic.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectFPArithmetic { 7 | public static void main(String[] args) { 8 | @Refinement("_ > 5.0") 9 | double a = 5.5; 10 | 11 | @Refinement("_ == 10.0") 12 | double b = 10.0; 13 | 14 | @Refinement("_ != 10.0") 15 | double c = 5.0; 16 | 17 | @Refinement("t > 0.0") 18 | double t = a + 1.0; 19 | 20 | @Refinement("_ >= 3.0") 21 | double k = a - 1.0; 22 | 23 | @Refinement("_ > 0.0") 24 | double l = k * t; 25 | 26 | @Refinement("_ > 0.0") 27 | double m = l / 2.0; 28 | 29 | @Refinement("_ < 4.0") 30 | double n = 6.0 % 4.0; 31 | 32 | @Refinement("_ < 0.0") 33 | double p = -5.0; 34 | 35 | @Refinement("_ <= 0.0") 36 | double p1 = -a; 37 | 38 | @Refinement("_ < -1.0") 39 | double p3 = p; 40 | 41 | @Refinement("_ < -5.5") 42 | double d = (-a) - 2.0; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectFunctionCallSameVariableName.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectFunctionCallSameVariableName { 7 | @Refinement(" _ == a + 1") 8 | private static int addOnes(@Refinement("a > 20") int a) { 9 | return a + 1; 10 | } 11 | 12 | public static void main(String[] args) { 13 | @Refinement("_ > 0") 14 | int a = 6; 15 | 16 | @Refinement("_ > 20") 17 | int b = addOnes(50) + a; 18 | 19 | @Refinement("_ > 10") 20 | int c = addOnes(a + 90); 21 | 22 | @Refinement("_ < 0") 23 | int d = -addOnes(a + 90); 24 | 25 | @Refinement("_ > 0") 26 | int e = addOnes(a + 100); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectFunctionDeclarations.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | public class CorrectFunctionDeclarations { 6 | 7 | @Refinement("_ >= a") 8 | public static int posMult(@Refinement("a == 10") int a, @Refinement("_ < a && _ > 0") int b) { 9 | @Refinement("y > 30") 10 | int y = 50; 11 | return y - 10; 12 | } 13 | 14 | @Refinement("_ > 10") 15 | public static int positive() { 16 | return 100; 17 | } 18 | 19 | @Refinement("_ >= d && _ < i") 20 | private static int range(@Refinement("d >= 0") int d, @Refinement("i > d") int i) { 21 | return d; 22 | } 23 | 24 | @Refinement("_ == 3 * x") 25 | private static int triplePositives(@Refinement("x > 0") int x) { 26 | return x + x + x; 27 | } 28 | 29 | @Refinement("(_ == -1) || (_ == a*b)") 30 | public int getPositiveMult(int a, int b) { 31 | int result; 32 | if (a > 0 && b > 0) result = a * b; 33 | else result = -1; 34 | return result; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectFunctionInInvocation.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectFunctionInInvocation { 7 | @Refinement("_ >= a") 8 | public static int posMult(@Refinement("a == 10") int a, @Refinement("_ < a && _ > 0") int b) { 9 | @Refinement("y > 30") 10 | int y = 50; 11 | return y - 10; 12 | } 13 | 14 | @Refinement("_ == 10") 15 | public static int ten() { 16 | return 10; 17 | } 18 | 19 | @Refinement("_ == b*2") 20 | private static int multTwo(int b) { 21 | return b * 2; 22 | } 23 | 24 | public static void main(String[] args) { 25 | @Refinement("_ >= 0") 26 | int p = 10; 27 | p = posMult(ten(), 4); 28 | 29 | @Refinement("_ < 6") 30 | int z = 5; 31 | 32 | @Refinement("_ > 6") 33 | int x = multTwo(z); 34 | 35 | @Refinement("_ == 20") 36 | int y = multTwo(x); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectFunctionInvocation.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectFunctionInvocation { 7 | @Refinement("_ >= a") 8 | public static int posMult(@Refinement("a == 10") int a, @Refinement("_ < a && _ > 0") int b) { 9 | @Refinement("y > 30") 10 | int y = 50; 11 | return y - 10; 12 | } 13 | 14 | public static void main(String[] args) { 15 | @Refinement("_ >= 0") 16 | int p = 10; 17 | p = posMult(10, 3); 18 | p = posMult(10, 15 - 6); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectFunctionsTutorial.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | public class CorrectFunctionsTutorial { 6 | 7 | @Refinement("_ >= 0 && _ >= n") 8 | public static int sum(int n) { 9 | if (n <= 0) return 0; 10 | else { 11 | int t1 = sum(n - 1); 12 | return n + t1; 13 | } 14 | } 15 | 16 | @Refinement("_ >= 0 && _ >= n") 17 | public static int absolute(int n) { 18 | if (0 <= n) return n; 19 | else return 0 - n; 20 | } 21 | 22 | // From LiquidHaskell tutorial 23 | @Refinement("length(_) == length(vec1)") 24 | static int[] sumVectors(int[] vec1, @Refinement("length(vec1) == length(vec2)") int[] vec2) { 25 | int[] add = new int[vec1.length]; 26 | if (vec1.length > 0) auxSum(add, vec1, vec2, 0); 27 | return add; 28 | } 29 | 30 | private static void auxSum( 31 | int[] add, 32 | int[] vec1, 33 | @Refinement("length(vec1) == length(vec2) && length(_) == length(add)") int[] vec2, 34 | @Refinement("_ >= 0 && _ < length(vec2)") int i) { 35 | add[i] = vec1[i] + vec2[i]; 36 | if (i < add.length - 1) auxSum(add, vec1, vec2, i + 1); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectIfThen.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectIfThen { 7 | 8 | public void have2(int a, int b) { 9 | @Refinement("pos > 0") 10 | int pos = 10; 11 | if (a > 0) { 12 | if (a > b) pos = a - b; 13 | } 14 | } 15 | 16 | public void have1(int a) { 17 | @Refinement("pos > 0") 18 | int pos = 10; 19 | if (a > 0) { 20 | pos = 5; 21 | pos = 8; 22 | pos = 30; 23 | } 24 | @Refinement("_ == 30 || _ == 10") 25 | int u = pos; 26 | } 27 | 28 | public static void main(String[] args) { 29 | @Refinement("_ < 10") 30 | int a = 5; 31 | 32 | if (a > 0) { 33 | @Refinement("b > 0") 34 | int b = a; 35 | b++; 36 | if (b > 10) { 37 | @Refinement("_ > 0") 38 | int c = a; 39 | @Refinement("_ > 11") 40 | int d = b + 1; 41 | } 42 | if (a > b) { 43 | @Refinement("_ > b") 44 | int c = a; 45 | } 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectImplies.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectImplies { 7 | @Refinement("((arg0 < 0) --> (_ == (-arg0*2))) && ((arg0 >= 0) --> (_ == arg0*2))") 8 | private static int getPositiveDouble(int arg0) { 9 | if (arg0 < 0) return -arg0 * 2; 10 | else return arg0 * 2; 11 | } 12 | 13 | public static void main(String[] args) { 14 | @Refinement("_ > 5") 15 | int x = 10; 16 | 17 | // @Refinement("(x > 50) --> (y > 50)") 18 | // int y = x; 19 | // 20 | // @Refinement("y > 1 --> z > 2") 21 | // int z = y*2; 22 | 23 | @Refinement("_ == 12") 24 | int z0 = getPositiveDouble(6); 25 | 26 | // @Refinement("z > 0 --> _ > 0") //works but takes 1min to run 27 | // int z1 = getPositiveDouble(z); 28 | 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectLongUsage.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectLongUsage { 7 | 8 | @Refinement("_ > 10") 9 | public static long doubleBiggerThanTen(@Refinement("a > 10") int a) { 10 | return a * 2; 11 | } 12 | 13 | @Refinement("_ > 40") 14 | public static long doubleBiggerThanTwenty(@Refinement("a > 20") long a) { 15 | return a * 2; 16 | } 17 | 18 | public static void main(String[] args) { 19 | @Refinement("a > 5") 20 | long a = 9L; 21 | 22 | if (a > 5) { 23 | @Refinement("b > 50") 24 | long b = a * 10; 25 | 26 | @Refinement("c < 0") 27 | long c = -a; 28 | } 29 | 30 | @Refinement("d > 10") 31 | long d = doubleBiggerThanTen(100); 32 | 33 | @Refinement("e > 10") 34 | long e = doubleBiggerThanTwenty(d * 2); 35 | 36 | @Refinement("_ > 10") 37 | long f = doubleBiggerThanTwenty(2 * 80); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectMethodInvocation.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectMethodInvocation { 7 | 8 | @Refinement("_ == 2") 9 | private static int getTwo() { 10 | return 1 + 1; 11 | } 12 | 13 | @Refinement("_ == 0") 14 | private static int getZero() { 15 | return 0; 16 | } 17 | 18 | @Refinement("_ == 1") 19 | private static int getOne() { 20 | @Refinement("_ == 0") 21 | int a = getZero(); 22 | return a + 1; 23 | } 24 | 25 | public static void main(String[] args) { 26 | @Refinement("_ < 1") 27 | int b = getZero(); 28 | 29 | @Refinement("_ > 0") 30 | int c = getOne(); 31 | c = getTwo(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectNoRefinements.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | @SuppressWarnings("unused") 4 | public class CorrectNoRefinements { 5 | private static int addOne(int i) { 6 | return i + 1; 7 | } 8 | 9 | private static int one() { 10 | return 1; 11 | } 12 | 13 | public static void main(String[] args) { 14 | 15 | int a = one(); 16 | int b = a; 17 | int c = a * b + 50 + addOne(5); 18 | b = 5; 19 | int s = a + 10; 20 | s++; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectPrimitiveNumbersTypes.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectPrimitiveNumbersTypes { 7 | @Refinement("_ < i && _ > 0") 8 | private static double fromType(@Refinement("_ > 0") int i) { 9 | return i * 0.1; 10 | } 11 | 12 | @Refinement(" _ < i && _ > 0") 13 | private static double fromType(@Refinement("_ > 0") long i) { 14 | return i * 0.1; 15 | } 16 | 17 | @Refinement(" _ < i && _ > 0") 18 | private static double fromType(@Refinement("_ > 0") short i) { 19 | return i * 0.1; 20 | } 21 | 22 | @Refinement("_ > i") 23 | private static float twice(@Refinement("i > 0") short i) { 24 | return i * 2f; 25 | } 26 | 27 | public static void main(String[] args) { 28 | @Refinement("_ > 5") 29 | int a = 10; 30 | 31 | @Refinement("_ > 5") 32 | long b = 100; 33 | 34 | @Refinement("_ > 5") 35 | short c = 10; 36 | 37 | @Refinement("_ > 5") 38 | float d = 7.4f; 39 | 40 | @Refinement("_ > 0") 41 | double e = fromType(a); 42 | e = fromType(b); 43 | e = fromType(c); 44 | 45 | @Refinement("f > 0") 46 | float f = twice(c); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectReadSpecificAssignment.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectReadSpecificAssignment { 7 | public void testAssignements() { 8 | @Refinement("_ > 10") 9 | int a = 15; 10 | 11 | @Refinement("_ > 14") 12 | int b = a; 13 | 14 | a = 12; 15 | 16 | @Refinement("_ >= 15") 17 | int c = b; 18 | b = 16; 19 | 20 | @Refinement("_ > 14") 21 | int d = c; 22 | } 23 | 24 | public void testIfs() { 25 | @Refinement("_ > 10") 26 | int a = 15; 27 | if (a > 14) { 28 | @Refinement("_ > 14") 29 | int b = a; 30 | a = 12; 31 | @Refinement("_ < 14") 32 | int c = a; 33 | } 34 | } 35 | 36 | public static void addZ(@Refinement("a > 0") int a) { 37 | @Refinement("_ > 0") 38 | int d = a; 39 | if (d > 5) { 40 | @Refinement("b > 5") 41 | int b = d; 42 | } else { 43 | @Refinement("_ <= 5") 44 | int c = d; 45 | d = 10; 46 | @Refinement("b > 9") 47 | int b = d; 48 | } 49 | } 50 | 51 | public void testWithBinOperations() { 52 | @Refinement("_ > 5") 53 | int a = 10; 54 | @Refinement("_ > 10") 55 | int b = a + 1; 56 | a = 6; 57 | b = a * 2; 58 | @Refinement("_ > 20") 59 | int c = b * 2; 60 | } 61 | 62 | public static void main(String[] args) {} 63 | } 64 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectRecursion.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | public class CorrectRecursion { 6 | @Refinement("_ == 0") 7 | public static int untilZero(@Refinement("k >= 0") int k) { 8 | if (k == 0) return 0; 9 | else return untilZero(k - 1); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectSearchIndexIntArray.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | public class CorrectSearchIndexIntArray { 6 | 7 | public static void searchIndex(@Refinement("length(l) > 0") int[] l, @Refinement("i >= 0") int i) { 8 | if (i >= l.length) return; 9 | else { 10 | @Refinement(" _ <= length(l)") 11 | int p = i + 1; 12 | searchIndex(l, p); 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectSearchValueIndexArray.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementPredicate; 5 | 6 | public class CorrectSearchValueIndexArray { 7 | 8 | @RefinementPredicate("ghost int length(int[])") 9 | @Refinement("(_ >= -1) && (_ < length(l))") 10 | public static int getIndexWithValue( 11 | @Refinement("length(l) > 0") int[] l, @Refinement("i >= 0 && i < length(l)") int i, int val) { 12 | if (l[i] == val) return i; 13 | if (i >= l.length - 1) return -1; 14 | else return getIndexWithValue(l, i + 1, val); 15 | } 16 | 17 | public static void main(String[] args) { 18 | int[] arr = new int[10]; 19 | getIndexWithValue(arr, 0, 1000); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectSimpleAssignment.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectSimpleAssignment { 7 | public static void main(String[] args) { 8 | @Refinement("a > 0") 9 | int a = 1; 10 | 11 | @Refinement("b == 2 || b == 3 || b == 4") 12 | int b = 2; 13 | 14 | @Refinement("d >= 2") 15 | int d = b; // should be okay 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectSimpleIfElse.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectSimpleIfElse { 7 | 8 | @Refinement("_ > 0") 9 | public static int toPositive(@Refinement("a < 0") int a) { 10 | return -a; 11 | } 12 | 13 | @Refinement("_ < 0") 14 | public static int toNegative(@Refinement("a > 0") int a) { 15 | return -a; 16 | } 17 | 18 | public static void main(String[] args) { 19 | @Refinement("_ < 10") 20 | int a = 5; 21 | 22 | if (a < 0) { 23 | @Refinement("b < 0") 24 | int b = a; 25 | } else { 26 | @Refinement("b >= 0") 27 | int b = a; 28 | } 29 | 30 | // EXAMPLE 2 31 | @Refinement("_ < 10") 32 | int ex_a = 5; 33 | if (ex_a < 0) { 34 | @Refinement("_ >= 10") 35 | int ex_b = toPositive(ex_a) * 10; 36 | } else { 37 | if (ex_a != 0) { 38 | @Refinement("_ < 0") 39 | int ex_d = toNegative(ex_a); 40 | } 41 | @Refinement("_ < ex_a") 42 | int ex_c = -10; 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectSpecificFunctionInvocation.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectSpecificFunctionInvocation { 7 | @Refinement(" _ > 0") 8 | public static int doubleBiggerThanTen(@Refinement("a > 10") int a) { 9 | return a * 2; 10 | } 11 | 12 | public static void main(String[] args) { 13 | @Refinement("a > 0") 14 | int a = 50; 15 | int b = doubleBiggerThanTen(a); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectTernaryExpression.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectTernaryExpression { 7 | @Refinement("_ == 3") 8 | public static int three() { 9 | return 3; 10 | } 11 | 12 | public static void main(String[] args) { 13 | @Refinement("_ < 10") 14 | int a = 5; 15 | @Refinement("_ > 0") 16 | int b = 3; 17 | a = (a == 2) ? 6 : 9; 18 | a = (b > 2) ? 8 : -1; 19 | b = (a < 100) ? three() : three() - 1; 20 | @Refinement("c < 100") 21 | int c = (a < 100) ? three() : a; 22 | c = (a < 100) ? three() * 3 : a * 5; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectTrafficLightRGB.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.StateRefinement; 5 | import liquidjava.specification.StateSet; 6 | 7 | @StateSet({"green", "amber", "red"}) 8 | public class CorrectTrafficLightRGB { 9 | 10 | @Refinement("r >= 0 && r <= 255") 11 | int r; 12 | 13 | @Refinement("g >= 0 && g <= 255") 14 | int g; 15 | 16 | @Refinement("b >= 0 && b <= 255") 17 | int b; 18 | 19 | @StateRefinement(to = "green(this)") 20 | public CorrectTrafficLightRGB() { 21 | r = 255; 22 | g = 0; 23 | b = 0; 24 | } 25 | 26 | @StateRefinement(from = "green(this)", to = "amber(this)") 27 | public void transitionToAmber() { 28 | r = 255; 29 | g = 120; 30 | b = 0; 31 | } 32 | 33 | @StateRefinement(from = "red(this)", to = "green(this)") 34 | public void transitionToGreen() { 35 | r = 76; 36 | g = 187; 37 | b = 23; 38 | } 39 | 40 | @StateRefinement(from = "amber(this)", to = "red(this)") 41 | public void transitionToRed() { 42 | r = 230; 43 | g = 0; 44 | b = 1; 45 | } 46 | 47 | public static void name() { 48 | CorrectTrafficLightRGB tl = new CorrectTrafficLightRGB(); 49 | tl.transitionToAmber(); 50 | tl.transitionToRed(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectUnaryOperators.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectUnaryOperators { 7 | public static void main(String[] args) { 8 | @Refinement("_ < 10") 9 | int v = 3; 10 | v--; 11 | @Refinement("_ >= 10") 12 | int s = 100; 13 | s++; 14 | 15 | @Refinement("_ < 0") 16 | int a = -6; 17 | @Refinement("b > 0") 18 | int b = 8; 19 | 20 | a = -3; 21 | a = -(6 + 5); 22 | b = -a; 23 | b = -(-10); 24 | b = +3; 25 | b = +s; 26 | 27 | @Refinement("_ <= 0") 28 | int c = 5 * (-10); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/CorrectUsingAfterIf.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class CorrectUsingAfterIf { 7 | public void have2(int a, int b) { 8 | @Refinement("pos > 0") 9 | int pos = 10; 10 | 11 | if (a > 0 && b > 0) { 12 | pos = a; 13 | } else if (b > 0) pos = b; 14 | 15 | @Refinement("_ == a || _ == b || _ == 10") 16 | int r = pos; 17 | } 18 | 19 | public static void main(String[] args) { 20 | // Example 1 21 | @Refinement("_ > 5") 22 | int a = 6; 23 | if (a > 8) a = 20; 24 | else a = 30; 25 | @Refinement("_ == 30") 26 | int b = a; 27 | 28 | // Example 2 29 | @Refinement("y < 100") 30 | int y = 50; 31 | if (y > 2) y = 3; 32 | else y = 6; 33 | 34 | @Refinement("z < 7") 35 | int z = y; 36 | 37 | // Example 3 38 | @Refinement("_ < 100") 39 | int changedInThenAndElse = 10; 40 | @Refinement("_ > 6") 41 | int changeOnlyInThen = 7; 42 | if (changedInThenAndElse > 2) { 43 | changedInThenAndElse = 3; 44 | changeOnlyInThen = 8; 45 | } else { 46 | changedInThenAndElse = 6; 47 | } 48 | @Refinement("_ < 7") 49 | int ze1 = changedInThenAndElse; 50 | @Refinement("_ < 9") 51 | int ze2 = changeOnlyInThen; 52 | 53 | // Example 4 54 | @Refinement("_ < 100") 55 | int initializedInThen; 56 | if (true) initializedInThen = 7; 57 | @Refinement("_ == 35") 58 | int hello = initializedInThen * 5; 59 | 60 | // Example 5 61 | @Refinement("_ < 100") 62 | int initializedInElse; 63 | int asds; 64 | if (false) asds = 5; 65 | else initializedInElse = 8; 66 | @Refinement("_ == 40") 67 | int world = initializedInElse * 5; 68 | 69 | // Example 7 70 | @Refinement("k > 0 && k < 100") 71 | int k = 5; 72 | if (k > 7) { 73 | k = 9; 74 | } 75 | @Refinement("_ < 10") 76 | int m = k; 77 | k = 50; 78 | @Refinement("_ == 50") 79 | int m2 = k; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorAfterIf.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorAfterIf { 7 | public void have2(int a, int b) { 8 | @Refinement("pos > 0") 9 | int pos = 10; 10 | 11 | if (a > 0 && b > 0) { 12 | pos = a; 13 | } else { 14 | if (b > 0) pos = b; 15 | } 16 | @Refinement("_ == a || _ == b") 17 | int r = pos; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorAfterIf2.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorAfterIf2 { 7 | public static void main(String[] args) { 8 | @Refinement("k > 0 && k < 100") 9 | int k = 5; 10 | if (k > 7) { 11 | k = 9; 12 | } 13 | k = 50; 14 | @Refinement("_ < 10") 15 | int m = k; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorAlias.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementAlias; 5 | 6 | @SuppressWarnings("unused") 7 | @RefinementAlias("InRange(int val, int low, int up) {low < val && val < up}") 8 | public class ErrorAlias { 9 | 10 | @Refinement("InRange( _, 10, 16)") 11 | public static int getNum() { 12 | return 14; 13 | } 14 | 15 | public static void main(String[] args) { 16 | @Refinement("InRange( _, 10, 15)") 17 | int j = getNum(); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorAliasArgumentSize.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementAlias; 5 | 6 | @SuppressWarnings("unused") 7 | @RefinementAlias("InRange(int val, int low, int up) {low < val && val < up}") 8 | public class ErrorAliasArgumentSize { 9 | 10 | public static void main(String[] args) { 11 | @Refinement("InRange( _, 10)") 12 | int j = 15; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorAliasSimple.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementAlias; 5 | 6 | @SuppressWarnings("unused") 7 | @RefinementAlias("type PtGrade(double x) { x >= 0 && x <= 20}") 8 | public class ErrorAliasSimple { 9 | 10 | public static void main(String[] args) { 11 | @Refinement("PtGrade(_)") 12 | double positiveGrade2 = 20 * 0.5 + 20 * 0.6; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorAliasTypeMismatch.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementAlias; 5 | 6 | @SuppressWarnings("unused") 7 | @RefinementAlias("type Positive(int x) { x > 0}") 8 | @RefinementAlias("type PtGrade(double x) { x >= 0 && x <= 20}") 9 | public class ErrorAliasTypeMismatch { 10 | 11 | public static void main(String[] args) { 12 | @Refinement("PtGrade(_)") 13 | double positiveGrade2 = 20 * 0.5 + 20 * 0.5; 14 | 15 | @Refinement("Positive(_)") 16 | double positive = positiveGrade2; 17 | // Positive(_) fica positive > 0 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorArithmeticBinaryOperations.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorArithmeticBinaryOperations { 7 | public static void main(String[] args) { 8 | @Refinement("_ < 100") 9 | int y = 50; 10 | @Refinement("_ > 0") 11 | int z = y - 51; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorArithmeticFP1.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorArithmeticFP1 { 7 | 8 | public static void main(String[] args) { 9 | @Refinement("_ > 5.0") 10 | double a = 5.0; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorArithmeticFP2.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorArithmeticFP2 { 7 | 8 | public static void main(String[] args) { 9 | @Refinement("_ > 5.0") 10 | double a = 5.5; 11 | 12 | @Refinement("_ == 10.0") 13 | double c = a * 2.0; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorArithmeticFP3.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorArithmeticFP3 { 7 | public static void main(String[] args) { 8 | @Refinement("_ > 5.0") 9 | double a = 5.5; 10 | @Refinement("_ < -5.5") 11 | double d = -a; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorArithmeticFP4.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorArithmeticFP4 { 7 | public static void main(String[] args) { 8 | @Refinement("_ > 5.0") 9 | double a = 5.5; 10 | 11 | @Refinement("_ < -5.5") 12 | double d = -(a - 2.0); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorAssignementAfterDeclaration.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorAssignementAfterDeclaration { 7 | public static void main(String[] args) { 8 | @Refinement("(z > 0) && (z < 50)") 9 | int z = 1; 10 | @Refinement("u < 100") 11 | int u = 10; 12 | u = 11 + z; 13 | u = z * 2; 14 | u = 30 + z; 15 | u = 500; // error 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorBooleanFunInvocation.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorBooleanFunInvocation { 7 | 8 | @Refinement("_ == (n > 10)") 9 | public static boolean greaterThanTen(int n) { 10 | return n > 10; 11 | } 12 | 13 | public static void main(String[] args) { 14 | @Refinement("_ < 10") 15 | int a = 5; 16 | 17 | @Refinement("_ == true") 18 | boolean k = (a < 11); 19 | 20 | @Refinement("_ == true") 21 | boolean o = !(a == 12); 22 | 23 | @Refinement("_ == true") 24 | boolean m = greaterThanTen(a); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorBooleanLiteral.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorBooleanLiteral { 7 | public static void main(String[] args) { 8 | @Refinement("_ < 10") 9 | int a = 5; 10 | 11 | @Refinement("_ == true") 12 | boolean k = (a < 11); 13 | 14 | @Refinement("_ == false") 15 | boolean t = !(a == 12); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorDependentRefinement.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorDependentRefinement { 7 | public static void main(String[] args) { 8 | @Refinement("_ < 10") 9 | int smaller = 5; 10 | @Refinement("bigger > 20") 11 | int bigger = 50; 12 | @Refinement("_ > smaller && _ < bigger") 13 | int middle = 21; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorFunctionDeclarations.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | public class ErrorFunctionDeclarations { 6 | @Refinement("_ >= d && _ < i") 7 | private static int range(@Refinement("d >= 0") int d, @Refinement("i > d") int i) { 8 | return i + 1; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorFunctionInvocation.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorFunctionInvocation { 7 | @Refinement(" _ >= a") 8 | public static int posMult(@Refinement("a == 10") int a, @Refinement("_ < a && _ > 0") int b) { 9 | @Refinement("y > 30") 10 | int y = 50; 11 | return y - 10; 12 | } 13 | 14 | public static void main(String[] args) { 15 | @Refinement("_ > 10") 16 | int p = 10; 17 | p = posMult(10, 4); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorFunctionInvocation1.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorFunctionInvocation1 { 7 | @Refinement("_ == 2") 8 | private static int getTwo() { 9 | return 1 + 1; 10 | } 11 | 12 | @Refinement(" _ == 0") 13 | private static int getZero() { 14 | return 0; 15 | } 16 | 17 | @Refinement("_ == 1") 18 | private static int getOne() { 19 | @Refinement("_ == 0") 20 | int a = getZero(); 21 | return a + 1; 22 | } 23 | 24 | public static void main(String[] args) { 25 | @Refinement("_ < 1") 26 | int b = getZero(); 27 | 28 | @Refinement("_ > 0") 29 | int c = getOne(); 30 | c = getZero(); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorFunctionInvocationParams.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorFunctionInvocationParams { 7 | @Refinement("_ >= a") 8 | public static int posMult(@Refinement("a == 10") int a, @Refinement("_ < a && _ > 0") int b) { 9 | @Refinement("y > 30") 10 | int y = 50; 11 | return y - 10; 12 | } 13 | 14 | public static void main(String[] args) { 15 | @Refinement("_ >= 0") 16 | int p = 10; 17 | p = posMult(10, 12); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorGhostArgsTypes.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementPredicate; 5 | 6 | public class ErrorGhostArgsTypes { 7 | @RefinementPredicate("ghost boolean open(int)") 8 | @Refinement("open(4.5) == true") 9 | public int one() { 10 | return 1; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorGhostNumberArgs.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementPredicate; 5 | 6 | public class ErrorGhostNumberArgs { 7 | 8 | @RefinementPredicate("ghost boolean open(int)") 9 | @Refinement("open(1,2) == true") 10 | public int one() { 11 | return 1; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorIfAssignment.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorIfAssignment { 7 | public static void main(String[] args) { 8 | @Refinement("_ < 10") 9 | int a = 5; 10 | 11 | if (a > 0) { 12 | @Refinement("b > 0") 13 | int b = a; 14 | b++; 15 | a = 10; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorIfAssignment2.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | public class ErrorIfAssignment2 { 6 | public static void main(String[] args) { 7 | @Refinement("_ < 10") 8 | int a = 5; 9 | if (a < 0) a = 100; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorImplementationSearchValueIntArray.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementPredicate; 5 | 6 | public class ErrorImplementationSearchValueIntArray { 7 | 8 | @RefinementPredicate("ghost int length(int[])") 9 | @Refinement("(_ >= -1) && (_ < length(l))") 10 | public static int getIndexWithValue( 11 | @Refinement("length(l) > 0") int[] l, @Refinement("i >= 0 && i < length(l)") int i, int val) { 12 | if (l[i] == val) return i; 13 | if (i >= l.length) // with or without -1 14 | return -1; 15 | else return getIndexWithValue(l, i + 1, val); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorLenZeroIntArray.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | public class ErrorLenZeroIntArray { 6 | 7 | public static int getIndexWithVal( 8 | @Refinement("length(l) > 0") int[] l, @Refinement("i >= 0 && i <= length(l)") int i, int val) { 9 | if (l[i] == val) return i; 10 | if (i >= l.length) return -1; 11 | else return getIndexWithVal(l, i + 1, val); 12 | } 13 | 14 | public static void main(String[] args) { 15 | int[] a = new int[0]; 16 | getIndexWithVal(a, 0, 6); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorLongUsage1.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorLongUsage1 { 7 | public static void main(String[] args) { 8 | @Refinement("a > 5") 9 | long a = 9L; 10 | 11 | if (a > 5) { 12 | @Refinement("b < 50") 13 | long b = a * 10; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorLongUsage2.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorLongUsage2 { 7 | 8 | @Refinement(" _ > 40") 9 | public static long doubleBiggerThanTwenty(@Refinement("a > 20") long a) { 10 | return a * 2; 11 | } 12 | 13 | public static void main(String[] args) { 14 | @Refinement("a > 5") 15 | long a = 9L; 16 | 17 | @Refinement("c > 40") 18 | long c = doubleBiggerThanTwenty(a * 2); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorNoRefinementsInVar.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorNoRefinementsInVar { 7 | public static void main(String[] args) { 8 | int a = 11; 9 | @Refinement("b < 10") 10 | int b = a; 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorRecursion1.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | public class ErrorRecursion1 { 6 | 7 | @Refinement(" _ == 0") 8 | public static int untilZero(@Refinement("k >= 0") int k) { 9 | if (k == 1) return 0; 10 | else return untilZero(k - 1); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorSearchIntArray.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | public class ErrorSearchIntArray { 6 | 7 | public static void searchIndex( 8 | @Refinement("length(l) > 0") int[] l, @Refinement("i >= 0 && i <= length(l)") int i) { 9 | if (i > l.length) return; 10 | else searchIndex(l, i + 1); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorSearchValueIntArray1.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementPredicate; 5 | 6 | public class ErrorSearchValueIntArray1 { 7 | 8 | @RefinementPredicate("ghost int length(int[])") 9 | @Refinement("(_ >= -1) && (_ < length(l))") 10 | public static int getIndexWithValue( 11 | @Refinement("length(l) > 0") int[] l, @Refinement("i >= 0 && i < length(l)") int i, int val) { 12 | if (l[i] == val) return i; 13 | if (i >= l.length - 1) return -1; 14 | else return getIndexWithValue(l, i + 1, val); 15 | } 16 | 17 | public static void main(String[] args) { 18 | int[] arr = new int[0]; 19 | getIndexWithValue(arr, 0, 1000); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorSearchValueIntArray2.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementPredicate; 5 | 6 | public class ErrorSearchValueIntArray2 { 7 | 8 | @RefinementPredicate("ghost int length(int[])") 9 | @Refinement("(_ >= -1) && (_ < length(l))") 10 | public static int getIndexWithValue( 11 | @Refinement("length(l) > 0") int[] l, @Refinement("i >= 0 && i < length(l)") int i, int val) { 12 | if (l[i] == val) return i; 13 | if (i >= l.length - 1) return -1; 14 | else return getIndexWithValue(l, i + 1, val); 15 | } 16 | 17 | public static void main(String[] args) { 18 | int[] arr = new int[10]; 19 | getIndexWithValue(arr, arr.length, 1000); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorSimpleAssignment.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorSimpleAssignment { 7 | public static void main(String[] args) { 8 | @Refinement("c > 2") 9 | int c = 2; // should emit error 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorSpecificArithmetic.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorSpecificArithmetic { 7 | public static void main(String[] args) { 8 | @Refinement("_ > 5") 9 | int a = 10; 10 | @Refinement("_ > 10") 11 | int b = a + 1; 12 | a = 6; 13 | b = a * 2; 14 | @Refinement("_ > 20") 15 | int c = b * -1; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorSpecificValuesIf.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorSpecificValuesIf { 7 | 8 | public static void addZ(@Refinement("a > 0") int a) { 9 | @Refinement("_ > 0") 10 | int d = a; 11 | if (d > 5) { 12 | @Refinement("b > 5") 13 | int b = d; 14 | } else { 15 | @Refinement("_ <= 5") 16 | int c = d; 17 | d = 10; 18 | @Refinement("b > 10") 19 | int b = d; 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorSpecificValuesIf2.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorSpecificValuesIf2 { 7 | public static void main(String[] args) { 8 | @Refinement("_ > 10") 9 | int a = 15; 10 | if (a > 14) { 11 | a = 12; 12 | @Refinement("_ < 11") 13 | int c = a; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorSpecificVarInRefinement.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorSpecificVarInRefinement { 7 | public static void main(String[] args) { 8 | @Refinement("_ < 10") 9 | int a = 6; 10 | 11 | @Refinement("_ > a") 12 | int b = 9; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorSpecificVarInRefinementIf.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorSpecificVarInRefinementIf { 7 | public static void main(String[] args) { 8 | @Refinement("_ < 10") 9 | int a = 6; 10 | if (a > 0) { 11 | a = -2; 12 | @Refinement("b < a") 13 | int b = -3; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorSyntax1.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorSyntax1 { 7 | public static void main(String[] args) { 8 | @Refinement("_ < 100 +") 9 | int value = 90 + 4; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorTernaryExpression.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | public class ErrorTernaryExpression { 6 | @Refinement(" _ == 3") 7 | public static int three() { 8 | return 3; 9 | } 10 | 11 | public static void main(String[] args) { 12 | @Refinement("_ < 10") 13 | int a = 5; 14 | a = (a == 2) ? 6 + three() : 4 * three(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorTrafficLightRGB.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.StateRefinement; 5 | import liquidjava.specification.StateSet; 6 | 7 | @StateSet({"green", "amber", "red"}) 8 | public class ErrorTrafficLightRGB { 9 | 10 | @Refinement("r >= 0 && r <= 255") 11 | int r; 12 | 13 | @Refinement("g >= 0 && g <= 255") 14 | int g; 15 | 16 | @Refinement("b >= 0 && b <= 255") 17 | int b; 18 | 19 | @StateRefinement(to = "green(this)") 20 | public ErrorTrafficLightRGB() { 21 | r = 255; 22 | g = 0; 23 | b = 0; 24 | } 25 | 26 | @StateRefinement(from = "green(this)", to = "amber(this)") 27 | public void transitionToAmber() { 28 | r = 255; 29 | g = 120; 30 | b = 0; 31 | } 32 | 33 | @StateRefinement(from = "red(this)", to = "green(this)") 34 | public void transitionToGreen() { 35 | r = 76; 36 | g = 187; 37 | b = 23; 38 | } 39 | 40 | @StateRefinement(from = "amber(this)", to = "red(this)") 41 | public void transitionToRed() { 42 | r = 230; 43 | g = 0; 44 | b = 1; 45 | } 46 | 47 | public static void name() { 48 | ErrorTrafficLightRGB tl = new ErrorTrafficLightRGB(); 49 | tl.transitionToAmber(); 50 | tl.transitionToRed(); 51 | tl.transitionToAmber(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorTypeInRefinements.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorTypeInRefinements { 7 | 8 | public static void main(String[] args) { 9 | int a = 10; 10 | 11 | @Refinement("(b == 6)") 12 | boolean b = true; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorUnaryOpMinus.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | public class ErrorUnaryOpMinus { 6 | public static void main(String[] args) { 7 | @Refinement("b > 0") 8 | int b = 8; 9 | b = -b; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/ErrorUnaryOperators.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class ErrorUnaryOperators { 7 | public static void main(String[] args) { 8 | @Refinement("_ < 10") 9 | int v = 3; 10 | v--; 11 | @Refinement("_ >= 10") 12 | int s = 10; 13 | s--; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/SimpleTest.java: -------------------------------------------------------------------------------- 1 | package testSuite; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class SimpleTest { 7 | public static void main(String[] args) { 8 | // Arithmetic Binary Operations 9 | @Refinement("a >= 10") 10 | int a = 10; 11 | @Refinement("t > 0") 12 | int t = a + 1; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/ErrorGhostState.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes; 2 | 3 | import liquidjava.specification.Ghost; 4 | import liquidjava.specification.StateRefinement; 5 | import liquidjava.specification.StateSet; 6 | 7 | @StateSet({"empty", "addingItems", "checkout", "closed"}) 8 | @Ghost("int totalPrice(int x)") // Should have no parameters 9 | public class ErrorGhostState { 10 | 11 | @StateRefinement(to = "(totalPrice(this) == 0) && empty(this)") 12 | public ErrorGhostState() {} 13 | } 14 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/arraylist_correct/ArrayListRefinements.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.arraylist_correct; 2 | 3 | import liquidjava.specification.ExternalRefinementsFor; 4 | import liquidjava.specification.RefinementPredicate; 5 | import liquidjava.specification.StateRefinement; 6 | 7 | @ExternalRefinementsFor("java.util.ArrayList") 8 | public interface ArrayListRefinements { 9 | 10 | @RefinementPredicate("int size(ArrayList l)") 11 | @StateRefinement(to = "size(this) == 0") 12 | public void ArrayList(); 13 | 14 | @StateRefinement(to = "size(this) == (size(old(this)) + 1)") 15 | public void add(E e); 16 | 17 | // @Refinement("size(_) == size(this)") 18 | // public Object clone(); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/arraylist_correct/SimpleTest.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.arraylist_correct; 2 | 3 | import java.io.IOException; 4 | import java.util.ArrayList; 5 | import liquidjava.specification.Refinement; 6 | 7 | @SuppressWarnings("unused") 8 | public class SimpleTest { 9 | 10 | public static void main(String[] args) throws IOException { 11 | 12 | @Refinement("size(al) < 4") 13 | ArrayList al = new ArrayList(); 14 | al.add(1); 15 | al.add(1); 16 | al.add(1); 17 | 18 | @Refinement("size(t) == 3") 19 | ArrayList t = al; 20 | 21 | // Order o = new Order(); 22 | // o.addItem("shirt", 5) 23 | // .addItem("shirt", 10) 24 | // .addItem("h", 20) 25 | // .hasThree(); 26 | // .addItem("h", 6); 27 | 28 | } 29 | 30 | // InputStreamReader isr = new InputStreamReader(System.in); 31 | // isr.read(); 32 | // isr.read(); 33 | // isr.read(); 34 | // isr.close(); 35 | // 36 | // //... 37 | // isr.read(); 38 | 39 | // @Refinement("_ > 0") 40 | // public int fun (int[] arr) { 41 | // return max(arr[0], 1); 42 | // } 43 | // 44 | 45 | // //@Refinement("_.length(x) >= 0") == 46 | //// @Refinement("length(_, x) >= 0") 47 | //// int[] a1 = new int[5]; 48 | // K(.., ..) 49 | 50 | // } 51 | 52 | // See error NaN 53 | // @Refinement("true") 54 | // double b = 0/0; 55 | // @Refinement("_ > 5") 56 | // double c = b; 57 | 58 | } 59 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/car_correct/Car.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.car_correct; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementAlias; 5 | 6 | @RefinementAlias("Positive(int x) { x > 0}") 7 | @RefinementAlias("type CarAcceptableYears(int x) { x > 1800 && x < 2050}") 8 | @RefinementAlias("GreaterThan(int x, int y) {x > y}") 9 | public class Car { 10 | 11 | @Refinement("CarAcceptableYears(year)") 12 | private int year; 13 | 14 | @Refinement("Positive(_)") 15 | private int seats; 16 | 17 | public void setYear(@Refinement("CarAcceptableYears(_)") int year) { 18 | this.year = year; 19 | } 20 | 21 | @Refinement("CarAcceptableYears(_)") 22 | public int getYear() { 23 | return year; 24 | } 25 | 26 | // @Refinement("_ == GreaterThan(year, y)") 27 | // public boolean isOlderThan(int y) { 28 | // return this.year > y; 29 | // } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/car_correct/Test.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.car_correct; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class Test { 7 | 8 | @Refinement("_ > 2020") 9 | public static int getYear() { 10 | return 2024; 11 | } 12 | 13 | public static void main(String[] args) { 14 | int a = 1998; 15 | Car c = new Car(); 16 | c.setYear(a); 17 | 18 | @Refinement("_ > 1800") 19 | int j = c.getYear(); 20 | 21 | @Refinement("_ > 2020") 22 | int k = getYear(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/email_correct/Email.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.email_correct; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import liquidjava.specification.RefinementAlias; 6 | import liquidjava.specification.RefinementPredicate; 7 | import liquidjava.specification.StateRefinement; 8 | 9 | // https://blog.sigplan.org/2021/03/02/fluent-api-practice-and-theory/ 10 | // Suppose there is only one acceptable order to construct the email 11 | // add sender -> add multiple receivers -> add subject -> add body -> build() 12 | @SuppressWarnings("unused") 13 | @RefinementAlias("EmptyEmail (Email e) { state(e) == 1}") 14 | @RefinementAlias("SenderSet (Email e) { state(e) == 2}") 15 | @RefinementAlias("ReceiverSet(Email e) { state(e) == 3}") 16 | @RefinementAlias("BodySet (Email e) { state(e) == 4}") 17 | public class Email { 18 | private String sender; 19 | private List receiver; 20 | private String subject; 21 | private String body; 22 | 23 | @RefinementPredicate("int state(Email e)") 24 | @StateRefinement(to = "EmptyEmail(this)") 25 | public Email() { 26 | receiver = new ArrayList<>(); 27 | } 28 | 29 | @StateRefinement(from = "EmptyEmail(this)", to = "SenderSet(this)") 30 | public void from(String s) { 31 | sender = s; 32 | } 33 | 34 | @StateRefinement(from = "(SenderSet(this)) || (ReceiverSet(this))", to = "ReceiverSet(this)") 35 | public void to(String s) { 36 | receiver.add(s); 37 | } 38 | 39 | @StateRefinement(from = "ReceiverSet(this)", to = "ReceiverSet(this)") 40 | public void subject(String s) { // optional 41 | subject = s; 42 | } 43 | 44 | @StateRefinement(from = "ReceiverSet(this)", to = "BodySet(this)") 45 | public void body(String s) { 46 | body = s; 47 | } 48 | 49 | @StateRefinement(from = "BodySet(this)", to = "BodySet(this)") 50 | public String build() { 51 | return "email..."; // string with all the email 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/email_correct/TestEmail.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.email_correct; 2 | 3 | public class TestEmail { 4 | 5 | public static void main(String[] args) { 6 | 7 | Email e = new Email(); 8 | e.from("me"); 9 | e.to("you"); 10 | e.to("you2"); 11 | e.to("you3"); 12 | e.subject("not important"); 13 | e.body("body"); 14 | e.build(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/email_error/Email.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.email_error; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import liquidjava.specification.RefinementPredicate; 6 | import liquidjava.specification.StateRefinement; 7 | 8 | // https://blog.sigplan.org/2021/03/02/fluent-api-practice-and-theory/ 9 | // Suppose there is only one acceptable order to construct the email 10 | // add sender -> add multiple receivers -> add subject -> add body -> build() 11 | // @RefinementAlias("EmptyEmail(Email e) { state(e) == 1}") 12 | @SuppressWarnings("unused") 13 | public class Email { 14 | private String sender; 15 | private List receiver; 16 | private String subject; 17 | private String body; 18 | 19 | @RefinementPredicate("int state(Email e)") 20 | @StateRefinement(to = "state(this) == 1") 21 | public Email() { 22 | receiver = new ArrayList<>(); 23 | } 24 | 25 | @StateRefinement(from = "state(this) == 1", to = "state(this) == 2") 26 | public void from(String s) { 27 | sender = s; 28 | } 29 | 30 | @StateRefinement(from = "(state(this) == 2) || (state(this) == 3)", to = "state(this) == 3") 31 | public void to(String s) { 32 | receiver.add(s); 33 | } 34 | 35 | @StateRefinement(from = "state(this) == 3", to = "state(this) == 3") 36 | public void subject(String s) { // optional 37 | subject = s; 38 | } 39 | 40 | @StateRefinement(from = "state(this) == 3", to = "state(this) == 4") 41 | public void body(String s) { 42 | body = s; 43 | } 44 | 45 | @StateRefinement(from = "state(this) == 4", to = "state(this) == 4") 46 | public String build() { 47 | return "email..."; // string with all the email 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/email_error/TestEmail.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.email_error; 2 | 3 | public class TestEmail { 4 | 5 | public static void main(String[] args) { 6 | 7 | Email e = new Email(); 8 | e.from("me"); 9 | // missing to 10 | e.subject("not important"); 11 | e.body("body"); 12 | e.build(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/input_reader_correct/InputStreamReaderRefs.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.input_reader_correct; 2 | 3 | import java.io.InputStream; 4 | import liquidjava.specification.ExternalRefinementsFor; 5 | import liquidjava.specification.Refinement; 6 | import liquidjava.specification.RefinementPredicate; 7 | import liquidjava.specification.StateRefinement; 8 | 9 | // https://docs.oracle.com/javase/7/docs/api/java/io/InputStreamReader.html 10 | @ExternalRefinementsFor("java.io.InputStreamReader") 11 | public interface InputStreamReaderRefs { 12 | 13 | @RefinementPredicate("boolean open(InputStreamReader i)") 14 | @StateRefinement(to = "open(this)") 15 | public void InputStreamReader(InputStream in); 16 | 17 | @StateRefinement(from = "open(this)", to = "open(this)") 18 | @Refinement("(_ >= -1) && (_ <= 127)") 19 | public int read(); 20 | 21 | @StateRefinement(from = "open(this)", to = "!open(this)") 22 | public void close(); 23 | 24 | @StateRefinement(from = "open(this)", to = "open(this)") 25 | @Refinement("_ >= -1") 26 | public int read( 27 | @Refinement("length(cbuf) > 0") char[] cbuf, 28 | @Refinement("_ >= 0") int offset, 29 | @Refinement("(_ >= 0) && (_ + offset) <= length(cbuf)") int length); 30 | // 31 | // @StateRefinement(from="open(this)", to="open(this)") 32 | // public int ready(); 33 | // 34 | // @StateRefinement(from="open(this)", to="open(this)") 35 | // public String getEncoding(); 36 | 37 | } 38 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/input_reader_correct/Test.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.input_reader_correct; 2 | 3 | @SuppressWarnings("unused") 4 | public class Test { 5 | public static void main(String[] args) throws Exception { 6 | // Arrays are not well supported in LiquidJava 7 | 8 | // InputStreamReader isr = new InputStreamReader(new FileInputStream("test1.txt")); 9 | // @Refinement("_ > -9") 10 | // int a = isr.read(); 11 | // char[] arr = new char[20]; 12 | // int b = isr.read(arr, 10, 5); 13 | // System.out.println(arr); 14 | // isr.close(); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/input_reader_error/InputStreamReaderRefinements.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.input_reader_error; 2 | 3 | import java.io.InputStream; 4 | import liquidjava.specification.ExternalRefinementsFor; 5 | import liquidjava.specification.RefinementPredicate; 6 | import liquidjava.specification.StateRefinement; 7 | 8 | // https://docs.oracle.com/javase/7/docs/api/java/io/InputStreamReader.html 9 | @ExternalRefinementsFor("java.io.InputStreamReader") 10 | public interface InputStreamReaderRefinements { 11 | @RefinementPredicate("boolean open(InputStreamReader i)") 12 | @StateRefinement(to = "open(this)") 13 | public void InputStreamReader(InputStream in); 14 | 15 | @StateRefinement(from = "open(this)", to = "open(this)") 16 | public int read(); 17 | 18 | @StateRefinement(from = "open(this)", to = "!open(this)") 19 | public void close(); 20 | 21 | // faster 22 | // @StateRefinement(from="open(this)", to="open(this)") 23 | // public int read(char[] cbuf, int offset, int length); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/input_reader_error/Test.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.input_reader_error; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStreamReader; 5 | 6 | public class Test { 7 | 8 | public static void main(String[] args) throws IOException { 9 | // java.io.InputStreamReader.InputStreamReader 10 | InputStreamReader is = new InputStreamReader(System.in); 11 | is.read(); 12 | is.read(); 13 | is.close(); 14 | is.read(); // should not be able to read 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/input_reader_error2/InputStreamReaderRefinements.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.input_reader_error2; 2 | 3 | import java.io.InputStream; 4 | import liquidjava.specification.ExternalRefinementsFor; 5 | import liquidjava.specification.RefinementPredicate; 6 | import liquidjava.specification.StateRefinement; 7 | 8 | // https://docs.oracle.com/javase/7/docs/api/java/io/InputStreamReader.html 9 | @ExternalRefinementsFor("java.io.InputStreamReader") 10 | public interface InputStreamReaderRefinements { 11 | @RefinementPredicate("boolean open(InputStreamReader i)") 12 | @StateRefinement(to = "open(this)") 13 | public void InputStreamReader(InputStream in); 14 | 15 | @StateRefinement(from = "open(this)", to = "open(this)") 16 | public int read(); 17 | 18 | @StateRefinement(from = "open(this)", to = "!open(this)") 19 | public void close(); 20 | } 21 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/input_reader_error2/Test.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.input_reader_error2; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStreamReader; 5 | 6 | public class Test { 7 | public static void main(String[] args) throws IOException { 8 | InputStreamReader isr = new InputStreamReader(System.in); 9 | isr.read(); 10 | isr.close(); 11 | isr.getEncoding(); 12 | isr.read(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/iterator_correct/Iterator.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.iterator_correct; 2 | 3 | import liquidjava.specification.StateRefinement; 4 | import liquidjava.specification.StateSet; 5 | 6 | @StateSet({"notready", "ready", "finished"}) 7 | public class Iterator { 8 | 9 | boolean hn; 10 | 11 | @StateRefinement(from = "notready(this)", to = "ready(this)") 12 | boolean hasNext(boolean hn) { 13 | return hn; 14 | } 15 | 16 | @StateRefinement(from = "ready(this)", to = "finished(this)") 17 | int next(boolean hn) { 18 | int r; 19 | if (hn) r = 1; 20 | else r = -1; 21 | return r; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/iterator_correct/Test.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.iterator_correct; 2 | 3 | public class Test { 4 | 5 | @SuppressWarnings("unused") 6 | public static void main(String[] args) { 7 | Iterator i = new Iterator(); 8 | boolean hn = true; 9 | i.hasNext(true); 10 | int x = i.next(hn); 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/iterator_error/Iterator.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.iterator_error; 2 | 3 | import liquidjava.specification.StateRefinement; 4 | import liquidjava.specification.StateSet; 5 | 6 | @StateSet({"notready", "ready", "finished"}) 7 | public class Iterator { 8 | 9 | boolean hn; 10 | 11 | @StateRefinement(from = "notready(this)", to = "ready(this)") 12 | boolean hasNext(boolean hn) { 13 | return hn; 14 | } 15 | 16 | @StateRefinement(from = "ready(this)", to = "finished(this)") 17 | int next(boolean hn) { 18 | int r; 19 | if (hn) r = 1; 20 | else r = -1; 21 | return r; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/iterator_error/Test.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.iterator_error; 2 | 3 | public class Test { 4 | 5 | @SuppressWarnings("unused") 6 | public static void main(String[] args) { 7 | Iterator i = new Iterator(); 8 | int x = i.next(true); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/order_gift_correct/Order.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.order_gift_correct; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementPredicate; 5 | import liquidjava.specification.StateRefinement; 6 | import liquidjava.specification.StateSet; 7 | 8 | @StateSet({"empty", "addingItems", "checkout", "closed"}) 9 | public class Order { 10 | 11 | @RefinementPredicate("int totalPrice(Order o)") 12 | @StateRefinement(to = "(totalPrice(this) == 0) && empty(this)") 13 | public Order() {} 14 | 15 | @StateRefinement( 16 | from = "(empty(this) || addingItems(this))", 17 | to = "((totalPrice(this) == (totalPrice(old(this)) + price)) && addingItems(this))") 18 | @Refinement("_ == this") 19 | public Order addItem(String itemName, @Refinement("_ > 0") int price) { 20 | return this; 21 | } 22 | 23 | @StateRefinement(from = "addingItems(this)", to = "checkout(this) && (totalPrice(this) == totalPrice(old(this)))") 24 | @Refinement("_ == this") 25 | public Order pay(int cardNumber) { 26 | return this; 27 | } 28 | 29 | @StateRefinement(from = "checkout(this) && totalPrice(this) > 20", to = "checkout(this)") 30 | @Refinement("_ == this") 31 | public Order addGift() { 32 | return this; 33 | } 34 | 35 | @StateRefinement(from = "checkout(this)", to = "closed(this)") 36 | @Refinement("_ == this") 37 | public Order sendToAddress(String a) { 38 | return this; 39 | } 40 | 41 | @StateRefinement(to = "checkout(this) && (totalPrice(this) == totalPrice(old(this)))") 42 | @Refinement("(totalPrice(_) == 0) && empty(_)") 43 | public Order getNewOrderPayThis() { 44 | return new Order(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/order_gift_correct/SimpleTest.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.order_gift_correct; 2 | 3 | import java.io.IOException; 4 | 5 | public class SimpleTest { 6 | 7 | public static void main(String[] args) throws IOException { 8 | Order o = new Order(); 9 | Order f = o.addItem("shirt", 60).getNewOrderPayThis().addItem("t", 6).addItem("t", 1); 10 | o.addGift(); 11 | f.addItem("l", 1); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/order_gift_error/Order.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.order_gift_error; 2 | 3 | import liquidjava.specification.Ghost; 4 | import liquidjava.specification.Refinement; 5 | import liquidjava.specification.StateRefinement; 6 | import liquidjava.specification.StateSet; 7 | 8 | @StateSet({"empty", "addingItems", "checkout", "closed"}) 9 | @Ghost("int totalPrice") 10 | public class Order { 11 | 12 | @StateRefinement(to = "(totalPrice(this) == 0) && empty(this)") 13 | public Order() {} 14 | 15 | @StateRefinement( 16 | from = "(empty(this) || addingItems(this))", 17 | to = "((totalPrice(this) == (totalPrice(old(this)) + price)) && addingItems(this))") 18 | @Refinement("_ == this") 19 | public Order addItem(String itemName, @Refinement("_ > 0") int price) { 20 | return this; 21 | } 22 | 23 | @StateRefinement(from = "addingItems(this)", to = "checkout(this)") 24 | @Refinement("_ == this") 25 | public Order pay(int cardNumber) { 26 | return this; 27 | } 28 | 29 | @StateRefinement(from = "checkout(this) && totalPrice(this) > 20", to = "checkout(this)") 30 | @Refinement("_ == this") 31 | public Order addGift() { 32 | return this; 33 | } 34 | 35 | @StateRefinement(from = "checkout(this)", to = "closed(this)") 36 | @Refinement("_ == this") 37 | public Order sendToAddress(String a) { 38 | return this; 39 | } 40 | 41 | @StateRefinement(to = "checkout(this)") 42 | @Refinement("(totalPrice(_) == 0) && empty(_)") 43 | public Order getNewOrderPayThis() { 44 | return new Order(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/order_gift_error/SimpleTest.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.order_gift_error; 2 | 3 | import java.io.IOException; 4 | 5 | public class SimpleTest { 6 | 7 | public static void main(String[] args) throws IOException { 8 | Order o = new Order(); 9 | Order f = o.addItem("shirt", 60).getNewOrderPayThis().addItem("t", 6).addItem("t", 1); 10 | o.addGift(); 11 | f.addItem("l", 1).addGift(); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/refs_from_interface_error/Bus.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.refs_from_interface_error; 2 | 3 | public class Bus implements ICar { 4 | int year; 5 | 6 | public void setYear(int x) { 7 | year = x; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/refs_from_interface_error/ICar.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.refs_from_interface_error; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementAlias; 5 | 6 | @RefinementAlias("IntBetween(int val, int lo, int hi) { lo <= val && val <= hi}") 7 | public interface ICar { 8 | public void setYear(@Refinement("IntBetween(_, 1600, 2050)") int y); 9 | } 10 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/refs_from_interface_error/SimpleTest.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.refs_from_interface_error; 2 | 3 | import java.io.IOException; 4 | 5 | public class SimpleTest { 6 | 7 | public static void main(String[] args) throws IOException { 8 | Bus b = new Bus(); 9 | b.setYear(1500); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/refs_from_superclass_error/Bus.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.refs_from_superclass_error; 2 | 3 | public class Bus extends Car { 4 | int year; 5 | 6 | @Override 7 | public void setYear(int x) { 8 | year = x; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/refs_from_superclass_error/Car.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.refs_from_superclass_error; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementAlias; 5 | 6 | @RefinementAlias("IntBetween(int val, int lo, int hi) { lo <= val && val <= hi}") 7 | public class Car { 8 | 9 | public void setYear(@Refinement("IntBetween(_, 1600, 2050)") int x) {} 10 | ; 11 | } 12 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/refs_from_superclass_error/SimpleTest.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.refs_from_superclass_error; 2 | 3 | import java.io.IOException; 4 | 5 | public class SimpleTest { 6 | 7 | public static void main(String[] args) throws IOException { 8 | Bus b = new Bus(); 9 | b.setYear(1400); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/refs_from_superclasses_correct/Bus.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.refs_from_superclasses_correct; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class Bus extends Car { 7 | 8 | private int year; 9 | 10 | @Refinement("_ > 20") 11 | private int seats; 12 | 13 | @Override 14 | public void setYear(@Refinement("IntBetween(x, 1000, 2100)") int x) { 15 | year = x; 16 | } 17 | 18 | @Refinement(" _ > 20 && _ < h") 19 | @Override 20 | public int getSeats(int h) { 21 | if (seats < h) return seats; 22 | else return 21; // dummy 23 | } 24 | 25 | // @PrivateRefinement("this.year == k")//verified in visitCtReturn after 26 | // @Refinement(" _ >= 50") 27 | // public void setSeats(int k) { 28 | // seats = k; 29 | // } 30 | // 31 | 32 | } 33 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/refs_from_superclasses_correct/Car.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.refs_from_superclasses_correct; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementAlias; 5 | 6 | @RefinementAlias("IntBetween(int val, int lo, int hi) { lo <= val && val <= hi}") 7 | public abstract class Car { 8 | 9 | public abstract void setYear(@Refinement("IntBetween(y, 1600, 2050)") int y); 10 | 11 | @Refinement("_ >= 1 && _ < ceil") 12 | public abstract int getSeats(@Refinement("_ == 50") int ceil); 13 | } 14 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/socket_error/SocketRefinements.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.socket_error; 2 | 3 | import java.net.SocketAddress; 4 | import liquidjava.specification.ExternalRefinementsFor; 5 | import liquidjava.specification.StateRefinement; 6 | import liquidjava.specification.StateSet; 7 | 8 | @ExternalRefinementsFor("java.net.Socket") 9 | @StateSet({"unconnected", "binded", "connected", "closed"}) 10 | public interface SocketRefinements { 11 | 12 | @StateRefinement(to = "unconnected(this)") 13 | public void Socket(); 14 | 15 | @StateRefinement(from = "unconnected(this)", to = "binded(this)") 16 | public void bind(SocketAddress add); 17 | 18 | @StateRefinement(from = "binded(this)", to = "connected(this)") 19 | public void connect(SocketAddress add); 20 | 21 | @StateRefinement(from = "connected(this)") 22 | public void sendUrgentData(int n); 23 | 24 | @StateRefinement(to = "closed(this)") 25 | public void close(); 26 | } 27 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/socket_error/Test.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.socket_error; 2 | 3 | import java.io.IOException; 4 | import java.net.InetAddress; 5 | import java.net.InetSocketAddress; 6 | import java.net.Socket; 7 | 8 | public class Test { 9 | 10 | public static void main(String[] args) throws IOException { 11 | 12 | int port = 5000; 13 | InetAddress inetAddress = InetAddress.getByName("localhost"); 14 | 15 | Socket socket = new Socket(); 16 | socket.bind(new InetSocketAddress(inetAddress, port)); 17 | // socket.connect(new InetSocketAddress(inetAddress, port)); 18 | socket.sendUrgentData(90); 19 | socket.close(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/state_from_superclass_correct/Bus.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.state_from_superclass_correct; 2 | 3 | import liquidjava.specification.StateRefinement; 4 | 5 | public class Bus extends Car { 6 | 7 | @StateRefinement(to = "close(this)") 8 | public Bus() {} 9 | 10 | @Override 11 | public void open() {} 12 | 13 | @Override 14 | public void close() {} 15 | } 16 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/state_from_superclass_correct/Car.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.state_from_superclass_correct; 2 | 3 | import liquidjava.specification.StateRefinement; 4 | import liquidjava.specification.StateSet; 5 | 6 | @StateSet({"open", "close"}) 7 | public abstract class Car { 8 | 9 | // @RefinementPredicate("boolean isOpen(Car c)") 10 | @StateRefinement(from = "close(this)", to = "open(this)") 11 | public abstract void open(); 12 | 13 | @StateRefinement(from = "open(this)", to = "close(this)") 14 | public abstract void close(); 15 | } 16 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/state_from_superclass_correct/SimpleTest.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.state_from_superclass_correct; 2 | 3 | import java.io.IOException; 4 | 5 | public class SimpleTest { 6 | 7 | public static void main(String[] args) throws IOException { 8 | Bus b = new Bus(); 9 | // b.close();//error: not yet open, not possible to close 10 | b.open(); 11 | b.close(); 12 | } 13 | 14 | // InputStreamReader isr = new InputStreamReader(System.in); 15 | // isr.read(); 16 | // isr.read(); 17 | // isr.read(); 18 | // isr.close(); 19 | // 20 | // //... 21 | // isr.read(); 22 | 23 | // @Refinement("_ > 0") 24 | // public int fun (int[] arr) { 25 | // return max(arr[0], 1); 26 | // } 27 | // 28 | 29 | // //@Refinement("_.length(x) >= 0") == 30 | //// @Refinement("length(_, x) >= 0") 31 | //// int[] a1 = new int[5]; 32 | // K(.., ..) 33 | 34 | // } 35 | 36 | // See error NaN 37 | // @Refinement("true") 38 | // double b = 0/0; 39 | // @Refinement("_ > 5") 40 | // double c = b; 41 | 42 | } 43 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/state_multiple_cases_correct/InputStreamReaderRefinements.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.state_multiple_cases_correct; 2 | 3 | import java.io.InputStream; 4 | import liquidjava.specification.ExternalRefinementsFor; 5 | import liquidjava.specification.Refinement; 6 | import liquidjava.specification.StateRefinement; 7 | import liquidjava.specification.StateSet; 8 | 9 | // https://docs.oracle.com/javase/7/docs/api/java/io/InputStreamReader.html 10 | @ExternalRefinementsFor("java.io.InputStreamReader") 11 | @StateSet({"open", "close"}) 12 | @StateSet({"nothingRead", "alreadyRead"}) 13 | public interface InputStreamReaderRefinements { 14 | 15 | public void InputStreamReader(InputStream in); 16 | 17 | @StateRefinement(from = "open(this)", to = "open(this) && alreadyRead(this)") 18 | @Refinement("(_ >= -1) && (_ <= 127)") 19 | public int read(); 20 | 21 | @StateRefinement(from = "close(this)", to = "close(this)") 22 | @StateRefinement(from = "open(this)", to = "close(this)") 23 | public void close(); 24 | } 25 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/state_multiple_cases_correct/SimpleTest.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.state_multiple_cases_correct; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStreamReader; 5 | import liquidjava.specification.Refinement; 6 | 7 | @SuppressWarnings("unused") 8 | public class SimpleTest { 9 | 10 | public static void main(String[] args) throws IOException { 11 | InputStreamReader isr = new InputStreamReader(System.in); 12 | @Refinement("a > -90") 13 | int a = isr.read(); 14 | isr.close(); 15 | // isr.close(); 16 | 17 | } 18 | 19 | // InputStreamReader isr = new InputStreamReader(System.in); 20 | // isr.read(); 21 | // isr.read(); 22 | // isr.read(); 23 | // isr.close(); 24 | // 25 | // //... 26 | // isr.read(); 27 | 28 | // @Refinement("_ > 0") 29 | // public int fun (int[] arr) { 30 | // return max(arr[0], 1); 31 | // } 32 | // 33 | 34 | // //@Refinement("_.length(x) >= 0") == 35 | //// @Refinement("length(_, x) >= 0") 36 | //// int[] a1 = new int[5]; 37 | // K(.., ..) 38 | 39 | // } 40 | 41 | // See error NaN 42 | // @Refinement("true") 43 | // double b = 0/0; 44 | // @Refinement("_ > 5") 45 | // double c = b; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/state_multiple_error/InputStreamReaderRefinements.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.state_multiple_error; 2 | 3 | import java.io.InputStream; 4 | import liquidjava.specification.ExternalRefinementsFor; 5 | import liquidjava.specification.Refinement; 6 | import liquidjava.specification.StateRefinement; 7 | import liquidjava.specification.StateSet; 8 | 9 | // https://docs.oracle.com/javase/7/docs/api/java/io/InputStreamReader.html 10 | @ExternalRefinementsFor("java.io.InputStreamReader") 11 | @StateSet({"open", "close"}) 12 | @StateSet({"alreadyRead", "nothingRead"}) 13 | public interface InputStreamReaderRefinements { 14 | 15 | @StateRefinement(to = "open(this) && close(this)") 16 | public void InputStreamReader(InputStream in); 17 | 18 | @StateRefinement(from = "open(this)", to = "open(this) && alreadyRead(this)") 19 | @Refinement("(_ >= -1) && (_ <= 127)") 20 | public int read(); 21 | 22 | @StateRefinement(from = "close(this)", to = "close(this)") 23 | @StateRefinement(from = "open(this)", to = "close(this)") 24 | public void close(); 25 | } 26 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/state_multiple_error/SimpleTest.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.state_multiple_error; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStreamReader; 5 | 6 | public class SimpleTest { 7 | 8 | public static void main(String[] args) throws IOException { 9 | InputStreamReader isr = new InputStreamReader(System.in); 10 | isr.read(); 11 | isr.close(); 12 | isr.close(); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/traffic_light_correct/SimpleTest.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.traffic_light_correct; 2 | 3 | import java.io.IOException; 4 | 5 | public class SimpleTest { 6 | 7 | public static void main(String[] args) throws IOException { 8 | 9 | TrafficLight tl = new TrafficLight(); 10 | tl.transitionToAmber(); // correct 11 | tl.transitionToRed(); // correct 12 | tl.transitionToFlashingAmber(); 13 | 14 | TrafficLight tl2 = tl.getTrafficLightStartingRed(); 15 | tl2.transitionToFlashingAmber(); 16 | } 17 | 18 | // InputStreamReader isr = new InputStreamReader(System.in); 19 | // isr.read(); 20 | // isr.read(); 21 | // isr.read(); 22 | // isr.close(); 23 | // 24 | // //... 25 | // isr.read(); 26 | 27 | // @Refinement("_ > 0") 28 | // public int fun (int[] arr) { 29 | // return max(arr[0], 1); 30 | // } 31 | // 32 | 33 | // //@Refinement("_.length(x) >= 0") == 34 | //// @Refinement("length(_, x) >= 0") 35 | //// int[] a1 = new int[5]; 36 | // K(.., ..) 37 | 38 | // } 39 | 40 | // See error NaN 41 | // @Refinement("true") 42 | // double b = 0/0; 43 | // @Refinement("_ > 5") 44 | // double c = b; 45 | 46 | } 47 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/classes/traffic_light_correct/TrafficLight.java: -------------------------------------------------------------------------------- 1 | package testSuite.classes.traffic_light_correct; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.StateRefinement; 5 | import liquidjava.specification.StateSet; 6 | 7 | @StateSet({"green", "solidAmber", "red", "flashingAmber"}) 8 | @StateSet({"buttonTouched", "buttonNotTouched"}) 9 | public class TrafficLight { 10 | // StateRefinement -> refines the state of the present object 11 | // independently of the arguments or the return of the method 12 | 13 | public TrafficLight() {} 14 | 15 | @StateRefinement(from = "green(this)", to = "solidAmber(this)") 16 | public void transitionToAmber() {} 17 | 18 | @StateRefinement(from = "solidAmber(this)", to = "red(this)") 19 | public void transitionToRed() {} 20 | 21 | @StateRefinement(from = "red(this)", to = "flashingAmber(this)") 22 | public void transitionToFlashingAmber() {} 23 | 24 | @StateRefinement(from = "flashingAmber(this)", to = "green(this)") 25 | public void transitionToGreen() {} 26 | 27 | @Refinement("red(_)") 28 | public TrafficLight getTrafficLightStartingRed() { 29 | TrafficLight t = new TrafficLight(); 30 | t.transitionToAmber(); 31 | t.transitionToRed(); 32 | return t; 33 | } 34 | 35 | // @StateRefinement(from="green(this)", to="solidAmber(this)") 36 | // @Refinement("this == _") 37 | // public TrafficLight transitionToAmber2() { 38 | // //... 39 | // return this; 40 | // } 41 | 42 | // @StateRefinement(to="green(this)") 43 | // @Refinement("_ >= 0") 44 | // public int getTotalChangesReset() { 45 | // return 0;//count 46 | // } 47 | // 48 | 49 | // @StateRefinement(from="red(this)") 50 | // public void passagersCross() {} 51 | // 52 | // @StateRefinement(to = "flashingAmber(this)") 53 | // public void intermitentMalfunction() {} 54 | 55 | // @StateRefinement(from="green(this)", to="solidAmber(this)") 56 | // @StateRefinement(from="solidAmber(this)", to="red(this)") 57 | // @StateRefinement(from="red(this)", to="flashingAmber(this)") 58 | // @StateRefinement(from="flashingAmber(this)", to="green(this)") 59 | // public void transition() {} 60 | // 61 | // @Refinement("_ == green(this)") 62 | // public boolean carsPass() { 63 | // return true; 64 | // } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/field_updates/CorrectFieldUpdate.java: -------------------------------------------------------------------------------- 1 | package testSuite.field_updates; 2 | 3 | import liquidjava.specification.StateRefinement; 4 | 5 | public class CorrectFieldUpdate { 6 | public int n = 0; 7 | 8 | @StateRefinement(from = "n(this) > 0", to = "n(this) == n(old(this))") 9 | public void shouldSucceedIfFieldIsPositive() {} 10 | 11 | public static void main(String[] args) { 12 | 13 | CorrectFieldUpdate t = new CorrectFieldUpdate(); 14 | t.n = 1; 15 | t.shouldSucceedIfFieldIsPositive(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/field_updates/ErrorFieldUpdate.java: -------------------------------------------------------------------------------- 1 | package testSuite.field_updates; 2 | 3 | import liquidjava.specification.StateRefinement; 4 | 5 | public class ErrorFieldUpdate { 6 | public int n; 7 | 8 | @StateRefinement(from = "n(this) > 0", to = "n(this) == n(old(this))") 9 | public void shouldFailIfFieldIsNegative() {} 10 | 11 | public static void main(String[] args) { 12 | 13 | ErrorFieldUpdate t = new ErrorFieldUpdate(); 14 | t.n = -1; 15 | t.shouldFailIfFieldIsNegative(); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/math/correctInvocation/MathRefinements.java: -------------------------------------------------------------------------------- 1 | package testSuite.math.correctInvocation; 2 | 3 | import liquidjava.specification.ExternalRefinementsFor; 4 | import liquidjava.specification.Refinement; 5 | 6 | @ExternalRefinementsFor("java.lang.Math") 7 | public interface MathRefinements { 8 | 9 | @Refinement("_ == 3.141592653589793") 10 | public double PI = 0; 11 | 12 | @Refinement("_ == 2.7182818284590452354") 13 | public double E = 0; 14 | 15 | @Refinement("(arg0 > 0)?( _ == arg0):(_ == -arg0)") 16 | public int abs(int arg0); 17 | 18 | @Refinement("(arg0 > 0)?( _ == arg0):(_ == -arg0)") 19 | public int abs(long arg0); 20 | 21 | @Refinement("(arg0 > 0)?( _ == arg0):(_ == -arg0)") 22 | public int abs(float arg0); 23 | 24 | @Refinement("(arg0 > 0)?( _ == arg0):(_ == -arg0)") 25 | public int abs(double arg0); 26 | 27 | @Refinement(" _ == a+b") 28 | public int addExact(int a, int b); 29 | 30 | @Refinement(" _ == a+b") 31 | public long addExact(long a, long b); 32 | 33 | @Refinement(" _ == a-b") 34 | public int subtractExact(int a, int b); 35 | 36 | @Refinement(" _ == a*b") 37 | public int multiplyExact(int a, int b); 38 | 39 | @Refinement("_ == (-a)") 40 | public int negateExact(int a); 41 | 42 | @Refinement("_ == (a-1)") 43 | public int decrementExact(int a); 44 | 45 | @Refinement("_ == (a-1)") 46 | public int decrementExact(long a); 47 | 48 | @Refinement("_ == (a+1)") 49 | public int incrementExact(int a); 50 | 51 | @Refinement("_ == (a+1)") 52 | public int incrementExact(long a); 53 | 54 | @Refinement("(a > b)? (_ == a):(_ == b)") 55 | public int max(int a, int b); 56 | 57 | @Refinement("(a > b)? (_ == b):(_ == a)") 58 | public int min(int a, int b); 59 | 60 | @Refinement(" _ > 0.0 && _ < 1.0") 61 | public long random(long a, long b); 62 | 63 | @Refinement("((sig > 0)?(_ > 0):(_ < 0)) && (( _ == arg)||(_ == -arg))") 64 | public float copySign(float arg, float sig); 65 | } 66 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/math/errorAbs/MathAbs.java: -------------------------------------------------------------------------------- 1 | package testSuite.math.errorAbs; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class MathAbs { 7 | public static void main(String[] args) { 8 | @Refinement("true") 9 | int ab = Math.abs(-9); 10 | 11 | @Refinement("_ == 9") 12 | int ab1 = -ab; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/math/errorAbs/MathRefinements.java: -------------------------------------------------------------------------------- 1 | package testSuite.math.errorAbs; 2 | 3 | import liquidjava.specification.ExternalRefinementsFor; 4 | import liquidjava.specification.Refinement; 5 | 6 | @ExternalRefinementsFor("java.lang.Math") 7 | public interface MathRefinements { 8 | 9 | @Refinement("_ == 3.141592653589793") 10 | public double PI = 0; 11 | 12 | @Refinement("_ == 2.7182818284590452354") 13 | public double E = 0; 14 | 15 | @Refinement("(arg0 > 0)?( _ == arg0):(_ == -arg0)") 16 | public int abs(int arg0); 17 | 18 | @Refinement("(arg0 > 0)?( _ == arg0):(_ == -arg0)") 19 | public int abs(long arg0); 20 | 21 | @Refinement("(arg0 > 0)?( _ == arg0):(_ == -arg0)") 22 | public int abs(float arg0); 23 | 24 | @Refinement("(arg0 > 0)?( _ == arg0):(_ == -arg0)") 25 | public int abs(double arg0); 26 | 27 | @Refinement(" _ == a+b") 28 | public int addExact(int a, int b); 29 | 30 | @Refinement(" _ == a+b") 31 | public long addExact(long a, long b); 32 | 33 | @Refinement(" _ == a-b") 34 | public int subtractExact(int a, int b); 35 | 36 | @Refinement(" _ == a*b") 37 | public int multiplyExact(int a, int b); 38 | 39 | @Refinement("_ == (-a)") 40 | public int negateExact(int a); 41 | 42 | @Refinement("_ == (a-1)") 43 | public int decrementExact(int a); 44 | 45 | @Refinement("_ == (a-1)") 46 | public int decrementExact(long a); 47 | 48 | @Refinement("_ == (a+1)") 49 | public int incrementExact(int a); 50 | 51 | @Refinement("_ == (a+1)") 52 | public int incrementExact(long a); 53 | 54 | @Refinement("(a > b)? (_ == a):(_ == b)") 55 | public int max(int a, int b); 56 | 57 | @Refinement("(a > b)? (_ == b):(_ == a)") 58 | public int min(int a, int b); 59 | 60 | @Refinement(" _ > 0.0 && _ < 1.0") 61 | public long random(long a, long b); 62 | 63 | @Refinement("((sig > 0)?(_ > 0):(_ < 0)) && (( _ == arg)||(_ == -arg))") 64 | public float copySign(float arg, float sig); 65 | } 66 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/math/errorMax/MathAbs.java: -------------------------------------------------------------------------------- 1 | package testSuite.math.errorMax; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class MathAbs { 7 | public static void main(String[] args) { 8 | @Refinement("true") 9 | int ab = Math.abs(-9); 10 | 11 | @Refinement("_ == 9") 12 | int ab1 = -ab; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/math/errorMax/MathRefinements.java: -------------------------------------------------------------------------------- 1 | package testSuite.math.errorMax; 2 | 3 | import liquidjava.specification.ExternalRefinementsFor; 4 | import liquidjava.specification.Refinement; 5 | 6 | @ExternalRefinementsFor("java.lang.Math") 7 | public interface MathRefinements { 8 | 9 | @Refinement("_ == 3.141592653589793") 10 | public double PI = 0; 11 | 12 | @Refinement("_ == 2.7182818284590452354") 13 | public double E = 0; 14 | 15 | @Refinement("(arg0 > 0)?( _ == arg0):(_ == -arg0)") 16 | public int abs(int arg0); 17 | 18 | @Refinement("(arg0 > 0)?( _ == arg0):(_ == -arg0)") 19 | public int abs(long arg0); 20 | 21 | @Refinement("(arg0 > 0)?( _ == arg0):(_ == -arg0)") 22 | public int abs(float arg0); 23 | 24 | @Refinement("(arg0 > 0)?( _ == arg0):(_ == -arg0)") 25 | public int abs(double arg0); 26 | 27 | @Refinement(" _ == a+b") 28 | public int addExact(int a, int b); 29 | 30 | @Refinement(" _ == a+b") 31 | public long addExact(long a, long b); 32 | 33 | @Refinement(" _ == a-b") 34 | public int subtractExact(int a, int b); 35 | 36 | @Refinement(" _ == a*b") 37 | public int multiplyExact(int a, int b); 38 | 39 | @Refinement("_ == (-a)") 40 | public int negateExact(int a); 41 | 42 | @Refinement("_ == (a-1)") 43 | public int decrementExact(int a); 44 | 45 | @Refinement("_ == (a-1)") 46 | public int decrementExact(long a); 47 | 48 | @Refinement("_ == (a+1)") 49 | public int incrementExact(int a); 50 | 51 | @Refinement("_ == (a+1)") 52 | public int incrementExact(long a); 53 | 54 | @Refinement("(a > b)? (_ == a):(_ == b)") 55 | public int max(int a, int b); 56 | 57 | @Refinement("(a > b)? (_ == b):(_ == a)") 58 | public int min(int a, int b); 59 | 60 | @Refinement(" _ > 0.0 && _ < 1.0") 61 | public long random(long a, long b); 62 | 63 | @Refinement("((sig > 0)?(_ > 0):(_ < 0)) && (( _ == arg)||(_ == -arg))") 64 | public float copySign(float arg, float sig); 65 | } 66 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/math/errorMultiplyExact/MathMultiplyExact.java: -------------------------------------------------------------------------------- 1 | package testSuite.math.errorMultiplyExact; 2 | 3 | import liquidjava.specification.Refinement; 4 | 5 | @SuppressWarnings("unused") 6 | public class MathMultiplyExact { 7 | public static void main(String[] args) { 8 | @Refinement("_ == 40") 9 | int mul = Math.multiplyExact(5, 8); 10 | @Refinement("_ == -mul") 11 | int mul1 = Math.multiplyExact(mul, -1); 12 | @Refinement("_ < 0") 13 | int mul2 = Math.multiplyExact(mul1, mul1); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testSuite/math/errorMultiplyExact/MathRefinements.java: -------------------------------------------------------------------------------- 1 | package testSuite.math.errorMultiplyExact; 2 | 3 | import liquidjava.specification.ExternalRefinementsFor; 4 | import liquidjava.specification.Refinement; 5 | 6 | @ExternalRefinementsFor("java.lang.Math") 7 | public interface MathRefinements { 8 | 9 | @Refinement("_ == 3.141592653589793") 10 | public double PI = 0; 11 | 12 | @Refinement("_ == 2.7182818284590452354") 13 | public double E = 0; 14 | 15 | @Refinement("(arg0 > 0)?( _ == arg0):(_ == -arg0)") 16 | public int abs(int arg0); 17 | 18 | @Refinement("(arg0 > 0)?( _ == arg0):(_ == -arg0)") 19 | public int abs(long arg0); 20 | 21 | @Refinement("(arg0 > 0)?( _ == arg0):(_ == -arg0)") 22 | public int abs(float arg0); 23 | 24 | @Refinement("(arg0 > 0)?( _ == arg0):(_ == -arg0)") 25 | public int abs(double arg0); 26 | 27 | @Refinement(" _ == a+b") 28 | public int addExact(int a, int b); 29 | 30 | @Refinement(" _ == a+b") 31 | public long addExact(long a, long b); 32 | 33 | @Refinement(" _ == a-b") 34 | public int subtractExact(int a, int b); 35 | 36 | @Refinement(" _ == a*b") 37 | public int multiplyExact(int a, int b); 38 | 39 | @Refinement("_ == (-a)") 40 | public int negateExact(int a); 41 | 42 | @Refinement("_ == (a-1)") 43 | public int decrementExact(int a); 44 | 45 | @Refinement("_ == (a-1)") 46 | public int decrementExact(long a); 47 | 48 | @Refinement("_ == (a+1)") 49 | public int incrementExact(int a); 50 | 51 | @Refinement("_ == (a+1)") 52 | public int incrementExact(long a); 53 | 54 | @Refinement("(a > b)? (_ == a):(_ == b)") 55 | public int max(int a, int b); 56 | 57 | @Refinement("(a > b)? (_ == b):(_ == a)") 58 | public int min(int a, int b); 59 | 60 | @Refinement(" _ > 0.0 && _ < 1.0") 61 | public long random(long a, long b); 62 | 63 | @Refinement("((sig > 0)?(_ > 0):(_ < 0)) && (( _ == arg)||(_ == -arg))") 64 | public float copySign(float arg, float sig); 65 | } 66 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testingInProgress/Account.java: -------------------------------------------------------------------------------- 1 | package testingInProgress; 2 | 3 | import liquidjava.specification.Ghost; 4 | import liquidjava.specification.Refinement; 5 | import liquidjava.specification.StateRefinement; 6 | 7 | @Ghost("int sum") 8 | public class Account { 9 | 10 | @Refinement("balance >= 0") 11 | private int balance; 12 | 13 | public Account() { 14 | balance = 0; 15 | } 16 | 17 | @StateRefinement(to = "sum(this) == v") 18 | public Account(@Refinement("v >= 0") int v) { 19 | balance = v; 20 | } 21 | 22 | @StateRefinement(to = "(sum(old(this)) > v)? (sum(this) == (sum(old(this)) - v)) : (sum(this) == 0)") 23 | public void withdraw(int v) { 24 | if (v > balance) balance = 0; 25 | else balance = balance - v; 26 | } 27 | 28 | @StateRefinement(to = "sum(this) == (sum(old(this)) + v)") 29 | public void deposit(int v) { 30 | balance += v; 31 | } 32 | 33 | // @StateRefinement(from="(amount <= sum(this)) && (sum(this) == sum(old(this)))", to="...") 34 | // @Refinement("sum(_) == (sum(old(_)) + amount)") 35 | // public Account transferTo(Account other, @Refinement("_ < sum(this)")int amount) { 36 | // this.withdraw(amount); 37 | // other.deposit(amount); 38 | // return other; 39 | // } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testingInProgress/ArrayListRefinements.java: -------------------------------------------------------------------------------- 1 | package testingInProgress; 2 | 3 | import liquidjava.specification.ExternalRefinementsFor; 4 | import liquidjava.specification.Refinement; 5 | import liquidjava.specification.RefinementPredicate; 6 | 7 | @ExternalRefinementsFor("java.util.ArrayList") 8 | public interface ArrayListRefinements { 9 | 10 | @RefinementPredicate("int size(ArrayList l)") 11 | @Refinement("size(this) == 0") 12 | public void ArrayList(); 13 | 14 | @Refinement("size(this) == (size(old(this)) + 1)") 15 | public void add(E e); 16 | 17 | // @Refinement("size(this) == (size(old(this)) - 1)") 18 | // public void remove(int index); 19 | 20 | // public E get(@Refinement("index >= 0 && index < size(this)") int index); 21 | 22 | // @Refinement("size(_) == size(this)") 23 | // public Object clone(); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testingInProgress/Car.java: -------------------------------------------------------------------------------- 1 | package testingInProgress; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementAlias; 5 | 6 | @SuppressWarnings("unused") 7 | @RefinementAlias("IntBetween(int val, int lo, int hi) { lo <= val && val <= hi}") 8 | public class Car { 9 | 10 | @Refinement("IntBetween(_, 1800, 2050)") 11 | private int year; 12 | 13 | private boolean isOpen; 14 | 15 | public void setYear(@Refinement("IntBetween(_, 1900, 2010)") int year) { 16 | this.year = year; 17 | } 18 | 19 | @Refinement("IntBetween(_, 1800, 2050)") 20 | public int getYear() { 21 | return year; 22 | } 23 | 24 | @Refinement("_ == (this.year > c.year))") 25 | public boolean isOlderThan(Car c) { 26 | return this.year > c.year; 27 | } 28 | 29 | // @StateRefinement(to = "year == old(year)+i") 30 | // @Refinement("_ == old(year) + i") 31 | // public int addYear(int i) { 32 | // year = year + i; 33 | // return year; 34 | // } 35 | 36 | // REFINE STATE 37 | // 38 | // @StateRefinement(to = "!open(this)") 39 | // public Car() { 40 | // isOpen = false; 41 | // } 42 | // 43 | // @StateRefinement(from = "!open(this)", to = "open(this) != open(#old)") 44 | // public void openCar() { 45 | // isOpen = true; 46 | // } 47 | // 48 | // 49 | // @StateRefinement(from = "open(this)") 50 | // public void passagerEnters() { 51 | // //... 52 | // } 53 | // 54 | // int a = 10; 55 | // a 56 | // instances a1, ..., an 57 | // a1 == 10 58 | // an = 15; 59 | 60 | } 61 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testingInProgress/Email.java: -------------------------------------------------------------------------------- 1 | package testingInProgress; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import liquidjava.specification.RefinementPredicate; 6 | import liquidjava.specification.StateRefinement; 7 | 8 | // https://blog.sigplan.org/2021/03/02/fluent-api-practice-and-theory/ 9 | // Suppose there is only one acceptable order to construct the email 10 | // add sender -> add multiple receivers -> add subject -> add body -> build() 11 | @SuppressWarnings("unused") 12 | public class Email { 13 | private String sender; 14 | private List receiver; 15 | private String subject; 16 | private String body; 17 | 18 | @RefinementPredicate("int state(Email e)") 19 | @StateRefinement(to = "state(this) == 1") 20 | public Email() { 21 | receiver = new ArrayList<>(); 22 | } 23 | 24 | @StateRefinement(from = "state(this) == 1", to = "state(this) == 2") 25 | public void from(String s) { 26 | sender = s; 27 | } 28 | 29 | @StateRefinement(from = "(state(this) == 2) || (state(this) == 3)", to = "state(this) == 3") 30 | public void to(String s) { 31 | receiver.add(s); 32 | } 33 | 34 | @StateRefinement(from = "state(this) == 3", to = "state(this) == 3") 35 | public void subject(String s) { // optional 36 | subject = s; 37 | } 38 | 39 | @StateRefinement(from = "state(this) == 3", to = "state(this) == 4") 40 | public void body(String s) { 41 | body = s; 42 | } 43 | 44 | @StateRefinement(from = "state(this) == 4", to = "state(this) == 4") 45 | public String build() { 46 | return "email..."; // string with all the email 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testingInProgress/InputStreamReaderRefinements.java: -------------------------------------------------------------------------------- 1 | package testingInProgress; 2 | 3 | import java.io.InputStream; 4 | import liquidjava.specification.ExternalRefinementsFor; 5 | import liquidjava.specification.Refinement; 6 | import liquidjava.specification.StateRefinement; 7 | import liquidjava.specification.StateSet; 8 | 9 | // https://docs.oracle.com/javase/7/docs/api/java/io/InputStreamReader.html 10 | @ExternalRefinementsFor("java.io.InputStreamReader") 11 | @StateSet({"open", "close"}) 12 | @StateSet({"alreadyRead", "nothingRead"}) 13 | public interface InputStreamReaderRefinements { 14 | 15 | @StateRefinement(to = "open(this)") 16 | public void InputStreamReader(InputStream in); 17 | 18 | @StateRefinement(from = "open(this)", to = "open(this) && alreadyRead(this)") 19 | @Refinement("(_ >= -1) && (_ <= 127)") 20 | public int read(); 21 | 22 | @StateRefinement(from = "close(this)", to = "close(this)") 23 | @StateRefinement(from = "open(this)", to = "close(this)") 24 | public void close(); 25 | } 26 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testingInProgress/MyList.java: -------------------------------------------------------------------------------- 1 | package testingInProgress; 2 | 3 | import java.util.ArrayList; 4 | import liquidjava.specification.Refinement; 5 | 6 | public class MyList { 7 | 8 | int[] arr = new int[20]; 9 | 10 | @Refinement("lengthA(_) == 0") 11 | public ArrayList createList() { 12 | return new ArrayList(); 13 | } 14 | 15 | @Refinement("lengthA(_) == (1 + lengthA(xs))") 16 | public ArrayList append(ArrayList xs, int k) { 17 | return null; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testingInProgress/Order.java: -------------------------------------------------------------------------------- 1 | package testingInProgress; 2 | 3 | import liquidjava.specification.Ghost; 4 | import liquidjava.specification.Refinement; 5 | import liquidjava.specification.StateRefinement; 6 | import liquidjava.specification.StateSet; 7 | 8 | @StateSet({"empty", "addingItems", "checkout", "closed"}) 9 | @Ghost("int totalPrice") 10 | public class Order { 11 | 12 | @StateRefinement(to = "(totalPrice(this) == 0) && empty(this)") 13 | public Order() {} 14 | 15 | @StateRefinement( 16 | from = "(empty(this) || addingItems(this))", 17 | to = "((totalPrice(this) == (totalPrice(old(this)) + price)) && addingItems(this))") 18 | @Refinement("_ == this") 19 | public Order addItem(String itemName, @Refinement("_ > 0") int price) { 20 | return this; 21 | } 22 | 23 | @StateRefinement(from = "addingItems(this)", to = "checkout(this)") 24 | @Refinement("_ == this") 25 | public Order pay(int cardNumber) { 26 | return this; 27 | } 28 | 29 | @StateRefinement(from = "checkout(this) && totalPrice(this) > 20", to = "checkout(this)") 30 | @Refinement("_ == this") 31 | public Order addGift() { 32 | return this; 33 | } 34 | 35 | @StateRefinement(from = "checkout(this)", to = "closed(this)") 36 | @Refinement("_ == this") 37 | public Order sendToAddress(String a) { 38 | return this; 39 | } 40 | 41 | @StateRefinement(to = "checkout(this)") 42 | @Refinement("(totalPrice(_) == 0) && empty(_)") 43 | public Order getNewOrderPayThis() { 44 | return new Order(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testingInProgress/OrderSimple.java: -------------------------------------------------------------------------------- 1 | package testingInProgress; 2 | 3 | import liquidjava.specification.RefinementPredicate; 4 | import liquidjava.specification.StateRefinement; 5 | import liquidjava.specification.StateSet; 6 | 7 | @StateSet({"empty", "addingItems", "checkout", "closed"}) 8 | public class OrderSimple { 9 | 10 | @RefinementPredicate("int countItems(OrderSimple o)") 11 | @StateRefinement(to = "(countItems(this) == 0) && empty(this)") 12 | public OrderSimple() {} 13 | 14 | @StateRefinement( 15 | from = "(empty(this) || addingItems(this))", 16 | to = "((countItems(this) == (countItems(old(this)) + 1)) && addingItems(this))") 17 | // @Refinement("_ == this") 18 | public OrderSimple addItem(String itemName, int price) { 19 | return this; 20 | } 21 | 22 | @StateRefinement(from = "((addingItems(this)) && (countItems(this) > 20))") 23 | public boolean hasGift() { 24 | return true; 25 | } 26 | 27 | // @StateRefinement(from="addingItems(this)", to = "checkout(this)") 28 | // public Order pay(int cardNumber) { 29 | // return this; 30 | // } 31 | 32 | // @StateRefinement(from="checkout(this) && priceNow(this) > 20", to = "checkout(this)") 33 | // public Order addGift() { 34 | // return this; 35 | // } 36 | // 37 | // @StateRefinement(from="checkout(this)", to = "closed(this)") 38 | // public Order sendToAddress(String a) { 39 | // return this; 40 | // } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testingInProgress/SimpleTest.java: -------------------------------------------------------------------------------- 1 | package testingInProgress; 2 | 3 | import java.io.IOException; 4 | 5 | public class SimpleTest { 6 | 7 | public static void main(String[] args) throws IOException { 8 | // Order 9 | 10 | } 11 | 12 | // InputStreamReader isr = new InputStreamReader(System.in); 13 | // isr.read(); 14 | // isr.read(); 15 | // isr.read(); 16 | // isr.close(); 17 | // 18 | // //... 19 | // isr.read(); 20 | 21 | // @Refinement("_ > 0") 22 | // public int fun (int[] arr) { 23 | // return max(arr[0], 1); 24 | // } 25 | // 26 | 27 | // //@Refinement("_.length(x) >= 0") == 28 | //// @Refinement("length(_, x) >= 0") 29 | //// int[] a1 = new int[5]; 30 | // K(.., ..) 31 | 32 | // } 33 | 34 | // See error NaN 35 | // @Refinement("true") 36 | // double b = 0/0; 37 | // @Refinement("_ > 5") 38 | // double c = b; 39 | 40 | } 41 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testingInProgress/StringBuilderRefinements.java: -------------------------------------------------------------------------------- 1 | package testingInProgress; 2 | 3 | import liquidjava.specification.RefinementPredicate; 4 | import liquidjava.specification.StateRefinement; 5 | 6 | public interface StringBuilderRefinements { 7 | @RefinementPredicate("int lengthS(StringBuilder s)") 8 | @StateRefinement(to = "lengthS() == 0") 9 | public void StringBuilder(); 10 | 11 | @StateRefinement(from = "#i == lengthS()", to = "lengthS() == (#i + 1)") 12 | public StringBuilder append(char c); 13 | } 14 | -------------------------------------------------------------------------------- /liquidjava-example/src/main/java/testingInProgress/TrafficLight.java: -------------------------------------------------------------------------------- 1 | package testingInProgress; 2 | 3 | import liquidjava.specification.Refinement; 4 | import liquidjava.specification.RefinementAlias; 5 | import liquidjava.specification.StateRefinement; 6 | import liquidjava.specification.StateSet; 7 | 8 | @StateSet({"green", "yellow", "red"}) 9 | @RefinementAlias("RGB(int x) {x >= 0 && x <= 255}") 10 | public class TrafficLight { 11 | 12 | @Refinement("RGB(r)") 13 | private int r; 14 | 15 | @Refinement("RGB(g)") 16 | private int g; 17 | 18 | @Refinement("RGB(b)") 19 | private int b; 20 | 21 | @StateRefinement(to = "green(this)") 22 | public TrafficLight() { 23 | r = 255; 24 | g = 0; 25 | b = 0; 26 | } 27 | 28 | @StateRefinement(from = "green(this)", to = "amber(this)") 29 | public void transitionToAmber() { 30 | r = 255; 31 | g = 120; 32 | b = 0; 33 | } 34 | 35 | @StateRefinement(from = "ref(this)", to = "green(this)") 36 | public void transitionToGreen() { 37 | r = 76; 38 | g = 187; 39 | b = 23; 40 | } 41 | 42 | @StateRefinement(from = "yellow(this)", to = "red(this)") 43 | public void transitionToRed() { 44 | r = 230; 45 | g = 0; 46 | b = 1 - 1; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /liquidjava-example/test1.txt: -------------------------------------------------------------------------------- 1 | akbadoasfnncnksa 2 | pspifdlnksac 3 | apsfdnlckx 4 | laigdknz.m,cxieakfsdmcx 5 | aipfsdlzkn.cmx 6 | -------------------------------------------------------------------------------- /liquidjava-verifier/.gitignore: -------------------------------------------------------------------------------- 1 | spooned 2 | -------------------------------------------------------------------------------- /liquidjava-verifier/lib/ModelCC.r2015.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CatarinaGamboa/liquidjava/79afe64e54b247fb1fd8a740188977baf43bb0aa/liquidjava-verifier/lib/ModelCC.r2015.jar -------------------------------------------------------------------------------- /liquidjava-verifier/lib/antlr-4.7.1-complete.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CatarinaGamboa/liquidjava/79afe64e54b247fb1fd8a740188977baf43bb0aa/liquidjava-verifier/lib/antlr-4.7.1-complete.jar -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/antlr4/rj/grammar/RJ.g4: -------------------------------------------------------------------------------- 1 | grammar RJ; 2 | 3 | 4 | prog: start | ; 5 | start: 6 | pred #startPred 7 | | alias #startAlias 8 | | ghost #startGhost 9 | ; 10 | 11 | 12 | pred: 13 | '(' pred ')' #predGroup 14 | | '!' pred #predNegate 15 | | pred LOGOP pred #predLogic 16 | | pred '?' pred ':' pred #ite 17 | | exp #predExp 18 | ; 19 | 20 | exp: 21 | '(' exp ')' #expGroup 22 | | exp BOOLOP exp #expBool 23 | | operand #expOperand 24 | ; 25 | 26 | operand: 27 | literalExpression #opLiteral 28 | | operand ARITHOP operand #opArith 29 | | operand '-' operand #opSub 30 | | '-' operand #opMinus 31 | | '!' operand #opNot 32 | | '(' operand ')' #opGroup 33 | ; 34 | 35 | 36 | literalExpression: 37 | '(' literalExpression ')' #litGroup 38 | | literal #lit 39 | | ID #var 40 | | ID '.' functionCall #targetInvocation 41 | | functionCall #invocation 42 | ; 43 | 44 | functionCall: 45 | ghostCall 46 | | aliasCall; 47 | 48 | ghostCall: 49 | ID '(' args? ')'; 50 | 51 | aliasCall: 52 | ID_UPPER '(' args? ')'; 53 | 54 | args: pred (',' pred)* ; 55 | 56 | 57 | literal: 58 | BOOL 59 | | STRING 60 | | INT 61 | | REAL; 62 | 63 | //----------------------- Declarations ----------------------- 64 | 65 | alias: 66 | 'type'? ID_UPPER '(' argDeclID ')' '{' pred '}'; 67 | 68 | ghost: 69 | 'ghost'? type ID ('(' argDecl? ')')?; 70 | 71 | argDecl: 72 | type ID? (',' argDecl)?; 73 | 74 | argDeclID: 75 | type ID (',' argDeclID)?; 76 | 77 | type: 78 | 'int' 79 | | 'double' 80 | | 'float' 81 | | 'boolean' 82 | | ID_UPPER 83 | | OBJECT_TYPE 84 | | type '[]'; 85 | 86 | 87 | LOGOP : '&&'|'||'| '-->'; 88 | BOOLOP : '=='|'!='|'>='|'>'|'<='|'<'; 89 | ARITHOP : '+'|'*'|'/'|'%';//|'-'; 90 | 91 | BOOL : 'true' | 'false'; 92 | ID_UPPER: ([A-Z][a-zA-Z0-9]*); 93 | OBJECT_TYPE: 94 | (([a-zA-Z][a-zA-Z0-9]+) ('.' [a-zA-Z][a-zA-Z0-9]*)+); 95 | ID : '#'*[a-zA-Z_][a-zA-Z0-9_#]*; 96 | STRING : '"'(~["])*'"'; 97 | INT : (([0-9]+) | ([0-9]+('_'[0-9]+)*)); 98 | REAL : (([0-9]+('.'[0-9]+)?) | '.'[0-9]+); 99 | 100 | WS : (' '|'\t'|'\n'|'\r')+ -> channel(HIDDEN); 101 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/api/CommandLineLauncher.java: -------------------------------------------------------------------------------- 1 | package liquidjava.api; 2 | 3 | import java.io.File; 4 | 5 | import liquidjava.errors.ErrorEmitter; 6 | import liquidjava.processor.RefinementProcessor; 7 | import spoon.Launcher; 8 | import spoon.processing.ProcessingManager; 9 | import spoon.reflect.declaration.CtPackage; 10 | import spoon.reflect.factory.Factory; 11 | import spoon.support.QueueProcessingManager; 12 | 13 | public class CommandLineLauncher { 14 | public static void main(String[] args) { 15 | String allPath = "./liquidjava-example/src/main/java/test/currentlyTesting"; 16 | 17 | // String allPath = "C://Regen/test-projects/src/Main.java"; 18 | // In eclipse only needed this:"../liquidjava-example/src/main/java/" 19 | // In VSCode needs: 20 | // "../liquidjava/liquidjava-umbrella/liquidjava-example/src/main/java/liquidjava/test/project"; 21 | String file = args.length == 0 ? allPath : args[0]; 22 | ErrorEmitter ee = launch(file); 23 | System.out.println(ee.foundError() ? (ee.getFullMessage()) : ("Correct! Passed Verification.")); 24 | } 25 | 26 | public static ErrorEmitter launchTest(String file) { 27 | ErrorEmitter ee = launch(file); 28 | return ee; 29 | } 30 | 31 | public static ErrorEmitter launch(String file) { 32 | System.out.println("Running LiquidJava on: " + file); 33 | Launcher launcher = new Launcher(); 34 | launcher.addInputResource(file); 35 | launcher.getEnvironment().setNoClasspath(true); 36 | 37 | // Get the current classpath from the system 38 | // String classpath = System.getProperty("java.class.path"); 39 | // launcher.getEnvironment().setSourceClasspath(classpath.split(File.pathSeparator)); 40 | 41 | // optional 42 | // launcher.getEnvironment().setSourceClasspath( 43 | // "lib1.jar:lib2.jar".split(":")); 44 | launcher.getEnvironment().setComplianceLevel(8); 45 | 46 | launcher.run(); 47 | 48 | final Factory factory = launcher.getFactory(); 49 | final ProcessingManager processingManager = new QueueProcessingManager(factory); 50 | 51 | ErrorEmitter ee = new ErrorEmitter(); 52 | final RefinementProcessor processor = new RefinementProcessor(factory, ee); 53 | processingManager.addProcessor(processor); 54 | 55 | try { 56 | // To only search the last package - less time spent 57 | CtPackage v = factory.Package().getAll().stream().reduce((first, second) -> second).orElse(null); 58 | if (v != null) 59 | processingManager.process(v); 60 | // To search all previous packages 61 | // processingManager.process(factory.Package().getRootPackage()); 62 | } catch (Exception e) { 63 | e.printStackTrace(); 64 | throw e; 65 | } 66 | 67 | return ee; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/errors/ErrorPosition.java: -------------------------------------------------------------------------------- 1 | package liquidjava.errors; 2 | 3 | public class ErrorPosition { 4 | 5 | private int lineStart; 6 | private int colStart; 7 | 8 | private int lineEnd; 9 | private int colEnd; 10 | 11 | public ErrorPosition(int line1, int col1, int line2, int col2) { 12 | lineStart = line1; 13 | colStart = col1; 14 | lineEnd = line2; 15 | colEnd = col2; 16 | } 17 | 18 | public int getLineStart() { 19 | return lineStart; 20 | } 21 | 22 | public int getColStart() { 23 | return colStart; 24 | } 25 | 26 | public int getLineEnd() { 27 | return lineEnd; 28 | } 29 | 30 | public int getColEnd() { 31 | return colEnd; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/processor/RefinementProcessor.java: -------------------------------------------------------------------------------- 1 | package liquidjava.processor; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import liquidjava.errors.ErrorEmitter; 6 | import liquidjava.processor.ann_generation.FieldGhostsGeneration; 7 | import liquidjava.processor.context.Context; 8 | import liquidjava.processor.refinement_checker.ExternalRefinementTypeChecker; 9 | import liquidjava.processor.refinement_checker.MethodsFirstChecker; 10 | import liquidjava.processor.refinement_checker.RefinementTypeChecker; 11 | import spoon.processing.AbstractProcessor; 12 | import spoon.reflect.declaration.CtPackage; 13 | import spoon.reflect.factory.Factory; 14 | 15 | /** Finds circular dependencies between packages */ 16 | public class RefinementProcessor extends AbstractProcessor { 17 | 18 | List visitedPackages = new ArrayList<>(); 19 | Factory factory; 20 | ErrorEmitter errorEmitter; 21 | 22 | public RefinementProcessor(Factory factory, ErrorEmitter ee) { 23 | this.factory = factory; 24 | errorEmitter = ee; 25 | } 26 | 27 | @Override 28 | public void process(CtPackage pkg) { 29 | if (!visitedPackages.contains(pkg)) { 30 | visitedPackages.add(pkg); 31 | Context c = Context.getInstance(); 32 | c.reinitializeAllContext(); 33 | 34 | pkg.accept(new FieldGhostsGeneration(c, factory, errorEmitter)); // generate annotations for field ghosts 35 | 36 | // void spoon.reflect.visitor.CtVisitable.accept(CtVisitor arg0) 37 | pkg.accept(new ExternalRefinementTypeChecker(c, factory, errorEmitter)); 38 | 39 | pkg.accept(new MethodsFirstChecker(c, factory, errorEmitter)); // double passing idea (instead of headers) 40 | 41 | pkg.accept(new RefinementTypeChecker(c, factory, errorEmitter)); 42 | if (errorEmitter.foundError()) 43 | return; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/processor/TestInsideClasses.java: -------------------------------------------------------------------------------- 1 | package liquidjava.processor; 2 | 3 | import spoon.Launcher; 4 | 5 | public class TestInsideClasses { 6 | public static void main(String[] args) { 7 | 8 | Launcher launcher = new Launcher(); 9 | launcher.getEnvironment().setComplianceLevel(8); 10 | launcher.run(); 11 | 12 | // final Factory factory = launcher.getFactory(); 13 | // RefinedVariable vi2 = new Variable("a",factory.Type().INTEGER_PRIMITIVE, new Predicate("a > 14 | // 0")); 15 | // CtTypeReference intt = factory.Type().INTEGER_PRIMITIVE; 16 | // List> l = new ArrayList<>(); 17 | // l.add(intt); 18 | // GhostState s = new GhostState("green", l, intt, "A"); 19 | // GhostState ss = new GhostState("yellow", l, intt, "A"); 20 | // GhostState sss = new GhostState("red", l, intt, "A"); 21 | // List gh = new ArrayList<>(); 22 | // gh.add(s);gh.add(ss);gh.add(sss); 23 | // Predicate p = new Predicate("green(this) && red(this) == iio && u(3)"); 24 | // System.out.println(p.getVariableNames()); 25 | 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/processor/VCImplication.java: -------------------------------------------------------------------------------- 1 | package liquidjava.processor; 2 | 3 | import liquidjava.rj_language.Predicate; 4 | import spoon.reflect.reference.CtTypeReference; 5 | 6 | /** 7 | * @author cgamboa 8 | */ 9 | public class VCImplication { 10 | String name; 11 | CtTypeReference type; 12 | Predicate refinement; 13 | VCImplication next; 14 | 15 | public VCImplication(String name, CtTypeReference type, Predicate ref) { 16 | this.name = name; 17 | this.type = type; 18 | this.refinement = ref; 19 | } 20 | 21 | public VCImplication(Predicate ref) { 22 | this.refinement = ref; 23 | } 24 | 25 | public void setNext(VCImplication c) { 26 | next = c; 27 | } 28 | 29 | public String toString() { 30 | if (name != null && type != null) { 31 | String qualType = type.getQualifiedName(); 32 | String simpleType = qualType.contains(".") ? qualType.substring(qualType.lastIndexOf(".") + 1) : qualType; 33 | return String.format("%-20s %s %s", "∀" + name + ":" + simpleType + ",", refinement.toString(), 34 | next != null ? " => \n" + next.toString() : ""); 35 | } else 36 | return String.format("%-20s %s", "", refinement.toString()); 37 | } 38 | 39 | public Predicate toConjunctions() { 40 | Predicate c = new Predicate(); 41 | if (name == null && type == null && next == null) 42 | return c; 43 | c = auxConjunction(c); 44 | return c; 45 | } 46 | 47 | private Predicate auxConjunction(Predicate c) { 48 | Predicate t = Predicate.createConjunction(c, refinement); 49 | if (next == null) 50 | return t; 51 | t = next.auxConjunction(t); 52 | return t; 53 | } 54 | 55 | public VCImplication clone() { 56 | VCImplication vc = new VCImplication(this.name, this.type, this.refinement.clone()); 57 | if (this.next != null) 58 | vc.next = this.next.clone(); 59 | return vc; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/processor/ann_generation/FieldGhostsGeneration.java: -------------------------------------------------------------------------------- 1 | package liquidjava.processor.ann_generation; 2 | 3 | import liquidjava.errors.ErrorEmitter; 4 | import liquidjava.processor.context.Context; 5 | import liquidjava.specification.Ghost; 6 | import spoon.reflect.declaration.*; 7 | import spoon.reflect.factory.Factory; 8 | import spoon.reflect.reference.CtTypeReference; 9 | import spoon.reflect.visitor.CtScanner; 10 | 11 | public class FieldGhostsGeneration extends CtScanner { 12 | Context context; 13 | Factory factory; 14 | ErrorEmitter errorEmitter; 15 | 16 | public FieldGhostsGeneration(Context c, Factory fac, ErrorEmitter errorEmitter) { 17 | this.context = c; 18 | this.factory = fac; 19 | this.errorEmitter = errorEmitter; 20 | } 21 | 22 | public Context getContext() { 23 | return context; 24 | } 25 | 26 | public Factory getFactory() { 27 | return factory; 28 | } 29 | 30 | @Override 31 | public void visitCtClass(CtClass ctClass) { 32 | if (errorEmitter.foundError()) { 33 | return; 34 | } 35 | 36 | ctClass.getDeclaredFields().stream().filter(fld -> fld.getType().getQualifiedName().equals("int")) 37 | .forEach(fld -> { 38 | CtTypeReference fld_type = fld.getType(); 39 | CtAnnotation gen_ann = factory.createAnnotation(factory.createCtTypeReference(Ghost.class)); 40 | gen_ann.addValue("value", fld_type.getSimpleName() + " " + fld.getSimpleName()); 41 | ctClass.addAnnotation(gen_ann); 42 | }); 43 | 44 | super.visitCtClass(ctClass); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/processor/context/GhostFunction.java: -------------------------------------------------------------------------------- 1 | package liquidjava.processor.context; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import liquidjava.processor.facade.GhostDTO; 6 | import liquidjava.utils.Utils; 7 | import spoon.reflect.factory.Factory; 8 | import spoon.reflect.reference.CtTypeReference; 9 | 10 | public class GhostFunction { 11 | 12 | private String name; 13 | private List> param_types; 14 | private CtTypeReference return_type; 15 | 16 | private String klassName; 17 | 18 | public GhostFunction(GhostDTO f, Factory factory, String path, String klass) { 19 | name = f.getName(); 20 | return_type = Utils.getType(f.getReturn_type().equals(klass) ? path : f.getReturn_type(), factory); 21 | param_types = new ArrayList<>(); 22 | for (String t : f.getParam_types()) { 23 | param_types.add(Utils.getType(t.equals(klass) ? path : t, factory)); 24 | } 25 | } 26 | 27 | public GhostFunction(String name, List param_types, CtTypeReference return_type, Factory factory, 28 | String path, String klass) { 29 | this.name = name; 30 | this.return_type = Utils.getType(return_type.toString().equals(klass) ? path : return_type.toString(), factory); 31 | this.param_types = new ArrayList<>(); 32 | for (int i = 0; i < param_types.size(); i++) { 33 | String mType = param_types.get(i).toString(); 34 | this.param_types.add(Utils.getType(mType.equals(klass) ? path : mType, factory)); 35 | } 36 | this.klassName = klass; 37 | } 38 | 39 | protected GhostFunction(String name, List> list, CtTypeReference return_type, String klass) { 40 | this.name = name; 41 | this.return_type = return_type; 42 | this.param_types = new ArrayList<>(); 43 | this.param_types = list; 44 | this.klassName = klass; 45 | } 46 | 47 | public String getName() { 48 | return name; 49 | } 50 | 51 | public CtTypeReference getReturnType() { 52 | return return_type; 53 | } 54 | 55 | public List> getParametersTypes() { 56 | return param_types; 57 | } 58 | 59 | public String toString() { 60 | StringBuilder sb = new StringBuilder(); 61 | sb.append("ghost " + return_type.toString() + " " + name + "("); 62 | for (CtTypeReference t : param_types) { 63 | sb.append(t.toString() + " ,"); 64 | } 65 | sb.delete(sb.length() - 2, sb.length()); 66 | sb.append(")"); 67 | return sb.toString(); 68 | } 69 | 70 | public String getParentClassName() { 71 | return klassName; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/processor/context/GhostParentState.java: -------------------------------------------------------------------------------- 1 | package liquidjava.processor.context; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import spoon.reflect.factory.Factory; 6 | import spoon.reflect.reference.CtTypeReference; 7 | 8 | public class GhostParentState extends GhostFunction { 9 | 10 | private ArrayList states; 11 | 12 | public GhostParentState(String name, List params, CtTypeReference ret, Factory factory, 13 | String qualifiedName, String simpleName) { 14 | super(name, params, ret, factory, qualifiedName, simpleName); 15 | states = new ArrayList<>(); 16 | } 17 | 18 | public void addState(GhostState s) { 19 | states.add(s); 20 | } 21 | 22 | public GhostState getFirstState() { 23 | return states.get(0); 24 | } 25 | 26 | public ArrayList getStates() { 27 | return states; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/processor/context/GhostState.java: -------------------------------------------------------------------------------- 1 | package liquidjava.processor.context; 2 | 3 | import java.util.List; 4 | import liquidjava.rj_language.Predicate; 5 | import spoon.reflect.reference.CtTypeReference; 6 | 7 | public class GhostState extends GhostFunction { 8 | 9 | private GhostFunction parent; 10 | private Predicate refinement; 11 | 12 | public GhostState(String name, List> list, CtTypeReference return_type, String klass) { 13 | super(name, list, return_type, klass); 14 | } 15 | 16 | public void setGhostParent(GhostFunction parent) { 17 | this.parent = parent; 18 | } 19 | 20 | public void setRefinement(Predicate c) { 21 | refinement = c; 22 | } 23 | 24 | public GhostFunction getParent() { 25 | return parent; 26 | } 27 | 28 | public Predicate getRefinement() { 29 | return refinement; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/processor/context/ObjectState.java: -------------------------------------------------------------------------------- 1 | package liquidjava.processor.context; 2 | 3 | import liquidjava.rj_language.Predicate; 4 | 5 | public class ObjectState { 6 | 7 | Predicate from; 8 | Predicate to; 9 | 10 | public ObjectState() { 11 | } 12 | 13 | public ObjectState(Predicate from, Predicate to) { 14 | this.from = from; 15 | this.to = to; 16 | } 17 | 18 | public void setFrom(Predicate from) { 19 | this.from = from; 20 | } 21 | 22 | public void setTo(Predicate to) { 23 | this.to = to; 24 | } 25 | 26 | public boolean hasFrom() { 27 | return from != null; 28 | } 29 | 30 | public boolean hasTo() { 31 | return to != null; 32 | } 33 | 34 | public Predicate getFrom() { 35 | return from != null ? from : new Predicate(); 36 | } 37 | 38 | public Predicate getTo() { 39 | return to != null ? to : new Predicate(); 40 | } 41 | 42 | public ObjectState clone() { 43 | return new ObjectState(from.clone(), to.clone()); 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return "ObjectState [from=" + from + ", to=" + to + "]"; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/processor/context/PlacementInCode.java: -------------------------------------------------------------------------------- 1 | package liquidjava.processor.context; 2 | 3 | import java.lang.annotation.Annotation; 4 | import spoon.reflect.code.CtComment; 5 | import spoon.reflect.cu.SourcePosition; 6 | import spoon.reflect.declaration.CtAnnotation; 7 | import spoon.reflect.declaration.CtElement; 8 | 9 | public class PlacementInCode { 10 | private String text; 11 | private SourcePosition position; 12 | 13 | private PlacementInCode(String t, SourcePosition s) { 14 | this.text = t; 15 | this.position = s; 16 | } 17 | 18 | public String getText() { 19 | return text; 20 | } 21 | 22 | public SourcePosition getPosition() { 23 | return position; 24 | } 25 | 26 | public void setText(String text) { 27 | this.text = text; 28 | } 29 | 30 | public void setPosition(SourcePosition position) { 31 | this.position = position; 32 | } 33 | 34 | public static PlacementInCode createPlacement(CtElement elem) { 35 | CtElement elemCopy = elem.clone(); 36 | // cleanup annotations 37 | if (elem.getAnnotations().size() > 0) { 38 | for (CtAnnotation a : elem.getAnnotations()) { 39 | elemCopy.removeAnnotation(a); 40 | } 41 | } 42 | // cleanup comments 43 | if (elem.getComments().size() > 0) { 44 | for (CtComment a : elem.getComments()) { 45 | elemCopy.removeComment(a); 46 | } 47 | } 48 | String elemText = elemCopy.toString(); 49 | return new PlacementInCode(elemText, elem.getPosition()); 50 | } 51 | 52 | public String getSimplePosition() { 53 | if (position.getFile() == null) { 54 | return "No position provided. Possibly asking for generated code"; 55 | } 56 | return position.getFile().getName() + ":" + position.getLine() + ", " + position.getColumn(); 57 | } 58 | 59 | public String toString() { 60 | if (position.getFile() == null) { 61 | return "No position provided. Possibly asking for generated code"; 62 | } 63 | return text + " at:" + position.getFile().getName() + ":" + position.getLine() + ", " + position.getColumn(); 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/processor/context/Refined.java: -------------------------------------------------------------------------------- 1 | package liquidjava.processor.context; 2 | 3 | import liquidjava.rj_language.Predicate; 4 | import spoon.reflect.reference.CtTypeReference; 5 | 6 | public abstract class Refined { 7 | 8 | private String name; // y 9 | private CtTypeReference type; // int 10 | private Predicate refinement; // 9 <= y && y <= 100 11 | 12 | public Refined() { 13 | } 14 | 15 | public Refined(String name, CtTypeReference type, Predicate refinement) { 16 | this.name = name; 17 | this.type = type; 18 | this.refinement = refinement; 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public void setName(String name) { 26 | this.name = name; 27 | } 28 | 29 | public CtTypeReference getType() { 30 | return type; 31 | } 32 | 33 | public void setType(CtTypeReference type) { 34 | this.type = type; 35 | } 36 | 37 | public void setRefinement(Predicate c) { 38 | this.refinement = c; 39 | } 40 | 41 | public Predicate getRefinement() { 42 | if (refinement != null) 43 | return refinement; 44 | return new Predicate(); 45 | } 46 | 47 | public Predicate getRenamedRefinements(String toReplace) { 48 | return refinement.substituteVariable(name, toReplace); 49 | } 50 | 51 | @Override 52 | public String toString() { 53 | return "Refined [name=" + name + ", type=" + type + ", refinement=" + refinement + "]"; 54 | } 55 | 56 | @Override 57 | public int hashCode() { 58 | final int prime = 31; 59 | int result = 1; 60 | result = prime * result + ((name == null) ? 0 : name.hashCode()); 61 | result = prime * result + ((refinement == null) ? 0 : refinement.hashCode()); 62 | result = prime * result + ((type == null) ? 0 : type.hashCode()); 63 | return result; 64 | } 65 | 66 | @Override 67 | public boolean equals(Object obj) { 68 | if (this == obj) 69 | return true; 70 | if (obj == null) 71 | return false; 72 | if (getClass() != obj.getClass()) 73 | return false; 74 | Refined other = (Refined) obj; 75 | if (name == null) { 76 | if (other.name != null) 77 | return false; 78 | } else if (!name.equals(other.name)) 79 | return false; 80 | if (type == null) { 81 | if (other.type != null) 82 | return false; 83 | } else if (!type.equals(other.type)) 84 | return false; 85 | return true; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/processor/context/RefinedVariable.java: -------------------------------------------------------------------------------- 1 | package liquidjava.processor.context; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.Set; 6 | import liquidjava.rj_language.Predicate; 7 | import spoon.reflect.reference.CtTypeReference; 8 | 9 | public abstract class RefinedVariable extends Refined { 10 | private List> supertypes; 11 | private PlacementInCode placementInCode; 12 | 13 | public RefinedVariable(String name, CtTypeReference type, Predicate c) { 14 | super(name, type, c); 15 | supertypes = new ArrayList<>(); 16 | } 17 | 18 | public abstract Predicate getMainRefinement(); 19 | 20 | public void addSuperType(CtTypeReference t) { 21 | if (!supertypes.contains(t)) 22 | supertypes.add(t); 23 | } 24 | 25 | public List> getSuperTypes() { 26 | return supertypes; 27 | } 28 | 29 | public void addSuperTypes(CtTypeReference ts, Set> sts) { 30 | if (ts != null && !supertypes.contains(ts)) 31 | supertypes.add(ts); 32 | for (CtTypeReference ct : sts) 33 | if (ct != null && !supertypes.contains(ct)) 34 | supertypes.add(ct); 35 | } 36 | 37 | public void addPlacementInCode(PlacementInCode s) { 38 | placementInCode = s; 39 | } 40 | 41 | public PlacementInCode getPlacementInCode() { 42 | return placementInCode; 43 | } 44 | 45 | @Override 46 | public int hashCode() { 47 | final int prime = 31; 48 | int result = super.hashCode(); 49 | result = prime * result + ((supertypes == null) ? 0 : supertypes.hashCode()); 50 | return result; 51 | } 52 | 53 | @Override 54 | public boolean equals(Object obj) { 55 | if (this == obj) 56 | return true; 57 | if (!super.equals(obj)) 58 | return false; 59 | if (getClass() != obj.getClass()) 60 | return false; 61 | RefinedVariable other = (RefinedVariable) obj; 62 | if (supertypes == null) { 63 | if (other.supertypes != null) 64 | return false; 65 | } else if (!supertypes.equals(other.supertypes)) 66 | return false; 67 | return true; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/processor/context/VariableInstance.java: -------------------------------------------------------------------------------- 1 | package liquidjava.processor.context; 2 | 3 | import java.util.Optional; 4 | import liquidjava.rj_language.Predicate; 5 | import spoon.reflect.reference.CtTypeReference; 6 | 7 | public class VariableInstance extends RefinedVariable { 8 | 9 | // private Predicate state; 10 | private Variable parent; 11 | 12 | public VariableInstance(String name, CtTypeReference type, Predicate c) { 13 | super(name, type, c); 14 | this.parent = null; 15 | } 16 | 17 | public VariableInstance(String name, CtTypeReference type, Predicate c, Variable parent) { 18 | super(name, type, c); 19 | this.parent = parent; 20 | } 21 | 22 | @Override 23 | public Predicate getMainRefinement() { 24 | return super.getRefinement(); 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | return "VariableInstance [name=" + super.getName() + ", type=" + super.getType() + ", refinement=" 30 | + super.getRefinement() + "]"; 31 | } 32 | 33 | public void setParent(Variable p) { 34 | parent = p; 35 | } 36 | 37 | public Optional getParent() { 38 | return parent == null ? Optional.empty() : Optional.of(parent); 39 | } 40 | 41 | // public void setState(Predicate c) { 42 | // state = c; 43 | // } 44 | // public Predicate getState() { 45 | // return state; 46 | // } 47 | // 48 | 49 | } 50 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/processor/facade/AliasDTO.java: -------------------------------------------------------------------------------- 1 | package liquidjava.processor.facade; 2 | 3 | import java.util.List; 4 | import java.util.stream.Collectors; 5 | import liquidjava.rj_language.ast.Expression; 6 | import liquidjava.rj_language.parsing.ParsingException; 7 | import liquidjava.rj_language.parsing.RefinementsParser; 8 | import spoon.reflect.reference.CtTypeReference; 9 | 10 | public class AliasDTO { 11 | private String name; 12 | private List varTypes; 13 | private List varNames; 14 | private Expression expression; 15 | 16 | public AliasDTO(String name, List> varTypes, List varNames, Expression expression) { 17 | super(); 18 | this.name = name; 19 | this.varTypes = varTypes.stream().map(m -> m.getQualifiedName()).collect(Collectors.toList()); 20 | this.varNames = varNames; 21 | this.expression = expression; 22 | } 23 | 24 | public AliasDTO(String name2, List varTypes2, List varNames2, String ref) throws ParsingException { 25 | super(); 26 | this.name = name2; 27 | this.varTypes = varTypes2; 28 | this.varNames = varNames2; 29 | this.expression = RefinementsParser.createAST(ref); 30 | } 31 | 32 | public String getName() { 33 | return name; 34 | } 35 | 36 | public List getVarTypes() { 37 | return varTypes; 38 | } 39 | 40 | public List getVarNames() { 41 | return varNames; 42 | } 43 | 44 | public Expression getExpression() { 45 | return expression; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/processor/facade/GhostDTO.java: -------------------------------------------------------------------------------- 1 | package liquidjava.processor.facade; 2 | 3 | import java.util.List; 4 | 5 | public class GhostDTO { 6 | 7 | private String name; 8 | private List param_types; 9 | private String return_type; 10 | 11 | public GhostDTO(String name, List param_types, String return_type) { 12 | super(); 13 | this.name = name; 14 | this.param_types = param_types; 15 | this.return_type = return_type; 16 | } 17 | 18 | public String getName() { 19 | return name; 20 | } 21 | 22 | public List getParam_types() { 23 | return param_types; 24 | } 25 | 26 | public String getReturn_type() { 27 | return return_type; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/processor/refinement_checker/TypeCheckingUtils.java: -------------------------------------------------------------------------------- 1 | package liquidjava.processor.refinement_checker; 2 | 3 | import spoon.reflect.code.CtBinaryOperator; 4 | import spoon.reflect.code.CtExpression; 5 | import spoon.reflect.code.CtLiteral; 6 | import spoon.reflect.reference.CtTypeReference; 7 | 8 | public class TypeCheckingUtils { 9 | 10 | public static String getStringFromAnnotation(CtExpression ce) { 11 | if (ce instanceof CtLiteral) { 12 | CtLiteral cl = (CtLiteral) ce; 13 | CtTypeReference r = ce.getType(); 14 | if (r.getSimpleName().equals("String")) 15 | return (String) cl.getValue(); 16 | 17 | } else if (ce instanceof CtBinaryOperator) { 18 | CtBinaryOperator cbo = (CtBinaryOperator) ce; 19 | String l = getStringFromAnnotation(cbo.getLeftHandOperand()); 20 | String r = getStringFromAnnotation(cbo.getRightHandOperand()); 21 | return l + r; 22 | } 23 | return null; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/rj_language/BuiltinFunctionPredicate.java: -------------------------------------------------------------------------------- 1 | package liquidjava.rj_language; 2 | 3 | import liquidjava.errors.ErrorEmitter; 4 | import liquidjava.rj_language.parsing.ParsingException; 5 | import spoon.reflect.declaration.CtElement; 6 | 7 | public class BuiltinFunctionPredicate extends Predicate { 8 | 9 | public BuiltinFunctionPredicate(ErrorEmitter ee, CtElement elem, String functionName, String... params) 10 | throws ParsingException { 11 | super(functionName + "(" + getFormattedParams(params) + ")", elem, ee); 12 | } 13 | 14 | public static BuiltinFunctionPredicate builtin_length(String param, CtElement elem, ErrorEmitter ee) 15 | throws ParsingException { 16 | return new BuiltinFunctionPredicate(ee, elem, "length", param); 17 | } 18 | 19 | public static BuiltinFunctionPredicate builtin_addToIndex(String array, String index, String value, CtElement elem, 20 | ErrorEmitter ee) throws ParsingException { 21 | return new BuiltinFunctionPredicate(ee, elem, "addToIndex", index, value); 22 | } 23 | 24 | private static String getFormattedParams(String... params) { 25 | StringBuilder sb = new StringBuilder(); 26 | for (int i = 0; i < params.length; i++) { 27 | sb.append(params[i]); 28 | if (i < params.length - 1) 29 | sb.append(", "); 30 | } 31 | return sb.toString(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/rj_language/ast/GroupExpression.java: -------------------------------------------------------------------------------- 1 | package liquidjava.rj_language.ast; 2 | 3 | import com.microsoft.z3.Expr; 4 | import java.util.List; 5 | import liquidjava.smt.TranslatorToZ3; 6 | 7 | public class GroupExpression extends Expression { 8 | 9 | public GroupExpression(Expression e) { 10 | addChild(e); 11 | } 12 | 13 | public Expression getExpression() { 14 | return children.get(0); 15 | } 16 | 17 | @Override 18 | public Expr eval(TranslatorToZ3 ctx) throws Exception { 19 | return getExpression().eval(ctx); 20 | } 21 | 22 | public String toString() { 23 | return "(" + getExpression().toString() + ")"; 24 | } 25 | 26 | @Override 27 | public void getVariableNames(List toAdd) { 28 | getExpression().getVariableNames(toAdd); 29 | } 30 | 31 | @Override 32 | public void getStateInvocations(List toAdd, List all) { 33 | getExpression().getStateInvocations(toAdd, all); 34 | } 35 | 36 | @Override 37 | public Expression clone() { 38 | return new GroupExpression(getExpression().clone()); 39 | } 40 | 41 | @Override 42 | public boolean isBooleanTrue() { 43 | return getExpression().isBooleanTrue(); 44 | } 45 | 46 | @Override 47 | public int hashCode() { 48 | final int prime = 31; 49 | int result = 1; 50 | result = prime * result + ((getExpression() == null) ? 0 : getExpression().hashCode()); 51 | return result; 52 | } 53 | 54 | @Override 55 | public boolean equals(Object obj) { 56 | if (this == obj) 57 | return true; 58 | if (obj == null) 59 | return false; 60 | if (getClass() != obj.getClass()) 61 | return false; 62 | GroupExpression other = (GroupExpression) obj; 63 | if (getExpression() == null) { 64 | if (other.getExpression() != null) 65 | return false; 66 | } else if (!getExpression().equals(other.getExpression())) 67 | return false; 68 | return true; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/rj_language/ast/LiteralBoolean.java: -------------------------------------------------------------------------------- 1 | package liquidjava.rj_language.ast; 2 | 3 | import com.microsoft.z3.Expr; 4 | import java.util.List; 5 | import liquidjava.smt.TranslatorToZ3; 6 | 7 | public class LiteralBoolean extends Expression { 8 | 9 | boolean value; 10 | 11 | public LiteralBoolean(boolean value) { 12 | this.value = value; 13 | } 14 | 15 | public LiteralBoolean(String value) { 16 | this.value = Boolean.parseBoolean(value); 17 | } 18 | 19 | public Expr eval(TranslatorToZ3 ctx) { 20 | return ctx.makeBooleanLiteral(value); 21 | } 22 | 23 | public String toString() { 24 | return Boolean.toString(value); 25 | } 26 | 27 | @Override 28 | public void getVariableNames(List toAdd) { 29 | // end leaf 30 | } 31 | 32 | @Override 33 | public void getStateInvocations(List toAdd, List all) { 34 | // end leaf 35 | 36 | } 37 | 38 | @Override 39 | public Expression clone() { 40 | return new LiteralBoolean(value); 41 | } 42 | 43 | @Override 44 | public boolean isBooleanTrue() { 45 | return value; 46 | } 47 | 48 | @Override 49 | public int hashCode() { 50 | final int prime = 31; 51 | int result = 1; 52 | result = prime * result + (value ? 1231 : 1237); 53 | return result; 54 | } 55 | 56 | @Override 57 | public boolean equals(Object obj) { 58 | if (this == obj) 59 | return true; 60 | if (obj == null) 61 | return false; 62 | if (getClass() != obj.getClass()) 63 | return false; 64 | LiteralBoolean other = (LiteralBoolean) obj; 65 | if (value != other.value) 66 | return false; 67 | return true; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/rj_language/ast/LiteralInt.java: -------------------------------------------------------------------------------- 1 | package liquidjava.rj_language.ast; 2 | 3 | import com.microsoft.z3.Expr; 4 | import java.util.List; 5 | import liquidjava.smt.TranslatorToZ3; 6 | 7 | public class LiteralInt extends Expression { 8 | 9 | private int value; 10 | 11 | public LiteralInt(int v) { 12 | value = v; 13 | } 14 | 15 | public LiteralInt(String v) { 16 | value = Integer.parseInt(v); 17 | } 18 | 19 | @Override 20 | public Expr eval(TranslatorToZ3 ctx) { 21 | return ctx.makeIntegerLiteral(value); 22 | } 23 | 24 | public String toString() { 25 | return Integer.toString(value); 26 | } 27 | 28 | @Override 29 | public void getVariableNames(List toAdd) { 30 | // end leaf 31 | 32 | } 33 | 34 | @Override 35 | public void getStateInvocations(List toAdd, List all) { 36 | // end leaf 37 | 38 | } 39 | 40 | @Override 41 | public Expression clone() { 42 | return new LiteralInt(value); 43 | } 44 | 45 | @Override 46 | public boolean isBooleanTrue() { 47 | return false; 48 | } 49 | 50 | @Override 51 | public int hashCode() { 52 | final int prime = 31; 53 | int result = 1; 54 | result = prime * result + value; 55 | return result; 56 | } 57 | 58 | @Override 59 | public boolean equals(Object obj) { 60 | if (this == obj) 61 | return true; 62 | if (obj == null) 63 | return false; 64 | if (getClass() != obj.getClass()) 65 | return false; 66 | LiteralInt other = (LiteralInt) obj; 67 | if (value != other.value) 68 | return false; 69 | return true; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/rj_language/ast/LiteralReal.java: -------------------------------------------------------------------------------- 1 | package liquidjava.rj_language.ast; 2 | 3 | import com.microsoft.z3.Expr; 4 | import java.util.List; 5 | import liquidjava.smt.TranslatorToZ3; 6 | 7 | public class LiteralReal extends Expression { 8 | 9 | private double value; 10 | 11 | public LiteralReal(double v) { 12 | value = v; 13 | } 14 | 15 | public LiteralReal(String v) { 16 | value = Double.parseDouble(v); 17 | } 18 | 19 | @Override 20 | public Expr eval(TranslatorToZ3 ctx) { 21 | return ctx.makeDoubleLiteral(value); 22 | } 23 | 24 | public String toString() { 25 | return Double.toString(value); 26 | } 27 | 28 | @Override 29 | public void getVariableNames(List toAdd) { 30 | // end leaf 31 | 32 | } 33 | 34 | @Override 35 | public void getStateInvocations(List toAdd, List all) { 36 | // end leaf 37 | 38 | } 39 | 40 | @Override 41 | public Expression clone() { 42 | return new LiteralReal(value); 43 | } 44 | 45 | @Override 46 | public boolean isBooleanTrue() { 47 | return false; 48 | } 49 | 50 | @Override 51 | public int hashCode() { 52 | final int prime = 31; 53 | int result = 1; 54 | long temp; 55 | temp = Double.doubleToLongBits(value); 56 | result = prime * result + (int) (temp ^ (temp >>> 32)); 57 | return result; 58 | } 59 | 60 | @Override 61 | public boolean equals(Object obj) { 62 | if (this == obj) 63 | return true; 64 | if (obj == null) 65 | return false; 66 | if (getClass() != obj.getClass()) 67 | return false; 68 | LiteralReal other = (LiteralReal) obj; 69 | if (Double.doubleToLongBits(value) != Double.doubleToLongBits(other.value)) 70 | return false; 71 | return true; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/rj_language/ast/LiteralString.java: -------------------------------------------------------------------------------- 1 | package liquidjava.rj_language.ast; 2 | 3 | import com.microsoft.z3.Expr; 4 | import java.util.List; 5 | import liquidjava.smt.TranslatorToZ3; 6 | 7 | public class LiteralString extends Expression { 8 | private String value; 9 | 10 | public LiteralString(String v) { 11 | value = v; 12 | } 13 | 14 | @Override 15 | public Expr eval(TranslatorToZ3 ctx) { 16 | return ctx.makeString(value); 17 | } 18 | 19 | public String toString() { 20 | return value; 21 | } 22 | 23 | @Override 24 | public void getVariableNames(List toAdd) { 25 | // end leaf 26 | 27 | } 28 | 29 | @Override 30 | public void getStateInvocations(List toAdd, List all) { 31 | // end leaf 32 | 33 | } 34 | 35 | @Override 36 | public Expression clone() { 37 | return new LiteralString(value); 38 | } 39 | 40 | @Override 41 | public boolean isBooleanTrue() { 42 | return false; 43 | } 44 | 45 | @Override 46 | public int hashCode() { 47 | final int prime = 31; 48 | int result = 1; 49 | result = prime * result + ((value == null) ? 0 : value.hashCode()); 50 | return result; 51 | } 52 | 53 | @Override 54 | public boolean equals(Object obj) { 55 | if (this == obj) 56 | return true; 57 | if (obj == null) 58 | return false; 59 | if (getClass() != obj.getClass()) 60 | return false; 61 | LiteralString other = (LiteralString) obj; 62 | if (value == null) { 63 | if (other.value != null) 64 | return false; 65 | } else if (!value.equals(other.value)) 66 | return false; 67 | return true; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/rj_language/ast/UnaryExpression.java: -------------------------------------------------------------------------------- 1 | package liquidjava.rj_language.ast; 2 | 3 | import com.microsoft.z3.Expr; 4 | import java.util.List; 5 | import liquidjava.smt.TranslatorToZ3; 6 | 7 | public class UnaryExpression extends Expression { 8 | 9 | private String op; 10 | 11 | public UnaryExpression(String op, Expression e) { 12 | this.op = op; 13 | addChild(e); 14 | } 15 | 16 | public Expression getExpression() { 17 | return children.get(0); 18 | } 19 | 20 | public String getOp() { 21 | return op; 22 | } 23 | 24 | @Override 25 | public Expr eval(TranslatorToZ3 ctx) throws Exception { 26 | switch (op) { 27 | case "-": 28 | return ctx.makeMinus(getExpression().eval(ctx)); 29 | case "!": 30 | return ctx.mkNot(getExpression().eval(ctx)); 31 | } 32 | return null; 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return op + getExpression().toString(); 38 | } 39 | 40 | @Override 41 | public void getVariableNames(List toAdd) { 42 | getExpression().getVariableNames(toAdd); 43 | } 44 | 45 | @Override 46 | public void getStateInvocations(List toAdd, List all) { 47 | getExpression().getStateInvocations(toAdd, all); 48 | } 49 | 50 | @Override 51 | public Expression clone() { 52 | return new UnaryExpression(op, getExpression().clone()); 53 | } 54 | 55 | @Override 56 | public boolean isBooleanTrue() { 57 | return false; 58 | } 59 | 60 | @Override 61 | public int hashCode() { 62 | final int prime = 31; 63 | int result = 1; 64 | result = prime * result + ((getExpression() == null) ? 0 : getExpression().hashCode()); 65 | result = prime * result + ((op == null) ? 0 : op.hashCode()); 66 | return result; 67 | } 68 | 69 | @Override 70 | public boolean equals(Object obj) { 71 | if (this == obj) 72 | return true; 73 | if (obj == null) 74 | return false; 75 | if (getClass() != obj.getClass()) 76 | return false; 77 | UnaryExpression other = (UnaryExpression) obj; 78 | if (getExpression() == null) { 79 | if (other.getExpression() != null) 80 | return false; 81 | } else if (!getExpression().equals(other.getExpression())) 82 | return false; 83 | if (op == null) { 84 | if (other.op != null) 85 | return false; 86 | } else if (!op.equals(other.op)) 87 | return false; 88 | return true; 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/rj_language/ast/Var.java: -------------------------------------------------------------------------------- 1 | package liquidjava.rj_language.ast; 2 | 3 | import com.microsoft.z3.Expr; 4 | import java.util.List; 5 | import liquidjava.smt.TranslatorToZ3; 6 | 7 | public class Var extends Expression { 8 | 9 | private String name; 10 | 11 | public Var(String name) { 12 | this.name = name; 13 | } 14 | 15 | public String getName() { 16 | return name; 17 | } 18 | 19 | @Override 20 | public Expr eval(TranslatorToZ3 ctx) throws Exception { 21 | return ctx.makeVariable(name); 22 | } 23 | 24 | public String toString() { 25 | return name; 26 | } 27 | 28 | @Override 29 | public void getVariableNames(List toAdd) { 30 | if (!toAdd.contains(name)) 31 | toAdd.add(name); 32 | } 33 | 34 | @Override 35 | public void getStateInvocations(List toAdd, List all) { 36 | // end leaf 37 | } 38 | 39 | @Override 40 | public Expression clone() { 41 | return new Var(name); 42 | } 43 | 44 | @Override 45 | public boolean isBooleanTrue() { 46 | return false; 47 | } 48 | 49 | @Override 50 | public int hashCode() { 51 | final int prime = 31; 52 | int result = 1; 53 | result = prime * result + ((name == null) ? 0 : name.hashCode()); 54 | return result; 55 | } 56 | 57 | @Override 58 | public boolean equals(Object obj) { 59 | if (this == obj) 60 | return true; 61 | if (obj == null) 62 | return false; 63 | if (getClass() != obj.getClass()) 64 | return false; 65 | Var other = (Var) obj; 66 | if (name == null) { 67 | if (other.name != null) 68 | return false; 69 | } else if (!name.equals(other.name)) 70 | return false; 71 | return true; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/rj_language/parsing/ParsingException.java: -------------------------------------------------------------------------------- 1 | package liquidjava.rj_language.parsing; 2 | 3 | public class ParsingException extends Exception { 4 | 5 | /** */ 6 | private static final long serialVersionUID = 1L; 7 | 8 | public ParsingException(String errorMessage) { 9 | super(errorMessage); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/rj_language/parsing/RJErrorListener.java: -------------------------------------------------------------------------------- 1 | package liquidjava.rj_language.parsing; 2 | 3 | import java.util.ArrayList; 4 | import java.util.BitSet; 5 | import java.util.List; 6 | import org.antlr.v4.runtime.ANTLRErrorListener; 7 | import org.antlr.v4.runtime.LexerNoViableAltException; 8 | import org.antlr.v4.runtime.Parser; 9 | import org.antlr.v4.runtime.RecognitionException; 10 | import org.antlr.v4.runtime.Recognizer; 11 | import org.antlr.v4.runtime.atn.ATNConfigSet; 12 | import org.antlr.v4.runtime.dfa.DFA; 13 | 14 | public class RJErrorListener implements ANTLRErrorListener { 15 | 16 | private int errors; 17 | public List msgs; 18 | 19 | public RJErrorListener() { 20 | super(); 21 | errors = 0; 22 | msgs = new ArrayList(); 23 | } 24 | 25 | @Override 26 | public void syntaxError(Recognizer recognizer, Object offendingSymbol, int line, int charPositionInLine, 27 | String msg, RecognitionException e) { 28 | // Hint for == instead of = 29 | String hint = null; 30 | if (e instanceof LexerNoViableAltException) { 31 | LexerNoViableAltException l = (LexerNoViableAltException) e; 32 | char c = l.getInputStream().toString().charAt(charPositionInLine); 33 | if (c == '=') 34 | hint = "Predicates must be compared with == instead of ="; 35 | } 36 | errors++; 37 | String ms = "Error in " + msg + ", in the position " + charPositionInLine; 38 | msgs.add(ms + (hint == null ? "" : "\n\tHint: " + hint)); 39 | } 40 | 41 | @Override 42 | public void reportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, boolean exact, 43 | BitSet ambigAlts, ATNConfigSet configs) { 44 | } 45 | 46 | @Override 47 | public void reportAttemptingFullContext(Parser recognizer, DFA dfa, int startIndex, int stopIndex, 48 | BitSet conflictingAlts, ATNConfigSet configs) { 49 | } 50 | 51 | @Override 52 | public void reportContextSensitivity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, int prediction, 53 | ATNConfigSet configs) { 54 | } 55 | 56 | public int getErrors() { 57 | return errors; 58 | } 59 | 60 | public String getMessages() { 61 | StringBuilder sb = new StringBuilder(); 62 | String pl = errors == 1 ? "" : "s"; 63 | sb.append("Found ").append(errors).append(" error" + pl).append(", with the message" + pl + ":\n"); 64 | for (String s : msgs) 65 | sb.append("* " + s + "\n"); 66 | return sb.toString(); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/rj_language/visitors/AliasVisitor.java: -------------------------------------------------------------------------------- 1 | package liquidjava.rj_language.visitors; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | import liquidjava.processor.facade.AliasDTO; 7 | import liquidjava.rj_language.parsing.ParsingException; 8 | import liquidjava.utils.Pair; 9 | import org.antlr.v4.runtime.CodePointCharStream; 10 | import org.antlr.v4.runtime.TokenStreamRewriter; 11 | import org.antlr.v4.runtime.misc.Interval; 12 | import org.antlr.v4.runtime.tree.ParseTree; 13 | import rj.grammar.RJParser.AliasContext; 14 | import rj.grammar.RJParser.ArgDeclIDContext; 15 | import rj.grammar.RJParser.PredContext; 16 | 17 | public class AliasVisitor { 18 | TokenStreamRewriter rewriter; 19 | CodePointCharStream input; 20 | 21 | public AliasVisitor(CodePointCharStream input) { 22 | this.input = input; 23 | } 24 | 25 | /** 26 | * Gets information about the alias 27 | * 28 | * @param rc 29 | * 30 | * @return 31 | * 32 | * @throws ParsingException 33 | */ 34 | public AliasDTO getAlias(ParseTree rc) throws ParsingException { 35 | if (rc instanceof AliasContext) { 36 | AliasContext ac = (AliasContext) rc; 37 | String name = ac.ID_UPPER().getText(); 38 | String ref = getText(ac.pred()); 39 | List> args = getArgsDecl(ac.argDeclID()); 40 | 41 | List varNames = args.stream().map(p -> p.getSecond()).collect(Collectors.toList()); 42 | List varTypes = args.stream().map(p -> p.getFirst()).collect(Collectors.toList()); 43 | return new AliasDTO(name, varTypes, varNames, ref); 44 | 45 | } else if (rc.getChildCount() > 0) { 46 | int i = rc.getChildCount(); 47 | if (i > 0) { 48 | return getAlias(rc.getChild(0)); 49 | } 50 | } 51 | return null; 52 | } 53 | 54 | /** 55 | * Returns text with whitespaces 56 | * 57 | * @param pred 58 | * 59 | * @return 60 | */ 61 | private String getText(PredContext pred) { 62 | int a = pred.start.getStartIndex(); 63 | int b = pred.stop.getStopIndex(); 64 | Interval interval = new Interval(a, b); 65 | return input.getText(interval); 66 | } 67 | 68 | private List> getArgsDecl(ArgDeclIDContext argDeclID) { 69 | List> l = new ArrayList>(); 70 | auxGetArgsDecl(argDeclID, l); 71 | return l; 72 | } 73 | 74 | private void auxGetArgsDecl(ArgDeclIDContext argDeclID, List> l) { 75 | String type = argDeclID.type().getText(); 76 | String name = argDeclID.ID().getText(); 77 | l.add(new Pair<>(type, name)); 78 | if (argDeclID.argDeclID() != null) 79 | auxGetArgsDecl(argDeclID.argDeclID(), l); 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/rj_language/visitors/GhostVisitor.java: -------------------------------------------------------------------------------- 1 | package liquidjava.rj_language.visitors; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | import liquidjava.processor.facade.GhostDTO; 7 | import liquidjava.utils.Pair; 8 | import org.antlr.v4.runtime.tree.ParseTree; 9 | import rj.grammar.RJParser.ArgDeclContext; 10 | import rj.grammar.RJParser.GhostContext; 11 | 12 | public class GhostVisitor { 13 | 14 | public static GhostDTO getGhostDecl(ParseTree rc) { 15 | if (rc instanceof GhostContext) { 16 | GhostContext gc = (GhostContext) rc; 17 | String type = gc.type().getText(); 18 | String name = gc.ID().getText(); 19 | List> args = getArgsDecl(gc.argDecl()); 20 | List ls = args.stream().map(m -> m.getFirst()).collect(Collectors.toList()); 21 | if (ls == null) 22 | ls = new ArrayList<>(); 23 | return new GhostDTO(name, ls, type); 24 | // return new Triple>>(type, name, args); 25 | } else if (rc.getChildCount() > 0) { 26 | int i = rc.getChildCount(); 27 | if (i > 0) 28 | return getGhostDecl(rc.getChild(0)); 29 | } 30 | return null; 31 | } 32 | 33 | private static List> getArgsDecl(ArgDeclContext argDecl) { 34 | List> l = new ArrayList>(); 35 | if (argDecl != null) 36 | auxGetArgsDecl(argDecl, l); 37 | return l; 38 | } 39 | 40 | private static void auxGetArgsDecl(ArgDeclContext argDecl, List> l) { 41 | String type = argDecl.type().getText(); 42 | String name = argDecl.ID() != null ? argDecl.ID().getText() : ""; 43 | l.add(new Pair<>(type, name)); 44 | if (argDecl.argDecl() != null) 45 | auxGetArgsDecl(argDecl.argDecl(), l); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/smt/GhostFunctionError.java: -------------------------------------------------------------------------------- 1 | package liquidjava.smt; 2 | 3 | import spoon.reflect.declaration.CtElement; 4 | 5 | public class GhostFunctionError extends Exception { 6 | 7 | /** */ 8 | private static final long serialVersionUID = 1L; 9 | 10 | private CtElement location; 11 | 12 | public GhostFunctionError(String message) { 13 | super(message); 14 | } 15 | 16 | public CtElement getLocation() { 17 | return location; 18 | } 19 | 20 | public void setLocation(CtElement location) { 21 | this.location = location; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/smt/NotFoundError.java: -------------------------------------------------------------------------------- 1 | package liquidjava.smt; 2 | 3 | import spoon.reflect.declaration.CtElement; 4 | 5 | public class NotFoundError extends Exception { 6 | private CtElement location; 7 | 8 | public NotFoundError(String message) { 9 | super(message); 10 | } 11 | 12 | public CtElement getLocation() { 13 | return location; 14 | } 15 | 16 | public void setLocation(CtElement location) { 17 | this.location = location; 18 | } 19 | 20 | /** */ 21 | private static final long serialVersionUID = 1L; 22 | } 23 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/smt/SMTEvaluator.java: -------------------------------------------------------------------------------- 1 | package liquidjava.smt; 2 | 3 | import com.martiansoftware.jsap.SyntaxException; 4 | import com.microsoft.z3.Expr; 5 | import com.microsoft.z3.Status; 6 | import com.microsoft.z3.Z3Exception; 7 | import liquidjava.processor.context.Context; 8 | import liquidjava.rj_language.Predicate; 9 | import liquidjava.rj_language.ast.Expression; 10 | 11 | public class SMTEvaluator { 12 | 13 | public void verifySubtype(Predicate subRef, Predicate supRef, Context c) 14 | throws TypeCheckError, GhostFunctionError, Exception { 15 | // Creates a parser for our SMT-ready refinement language 16 | // Discharges the verification to z3 17 | 18 | Predicate toVerify = Predicate.createConjunction(subRef, supRef.negate()); 19 | // System.out.println("verification query: " + toVerify); // TODO remove 20 | 21 | try { 22 | Expression exp = toVerify.getExpression(); 23 | Status s; 24 | try (TranslatorToZ3 tz3 = new TranslatorToZ3(c)) { 25 | // com.microsoft.z3.Expr 26 | Expr e = exp.eval(tz3); 27 | s = tz3.verifyExpression(e); 28 | 29 | if (s.equals(Status.SATISFIABLE)) { 30 | // System.out.println("result of SMT: Not Ok!"); 31 | throw new TypeCheckError(subRef + " not a subtype of " + supRef); 32 | } 33 | } 34 | // System.out.println("result of SMT: Ok!"); 35 | 36 | } catch (SyntaxException e1) { 37 | System.out.println("Could not parse: " + toVerify); 38 | e1.printStackTrace(); 39 | } catch (Z3Exception e) { 40 | if (e.getLocalizedMessage().substring(0, 24).equals("Wrong number of argument") 41 | || e.getLocalizedMessage().substring(0, 13).equals("Sort mismatch")) 42 | throw new GhostFunctionError(e.getLocalizedMessage()); 43 | else 44 | throw new Z3Exception(e.getLocalizedMessage()); 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/smt/TypeCheckError.java: -------------------------------------------------------------------------------- 1 | package liquidjava.smt; 2 | 3 | import spoon.reflect.declaration.CtElement; 4 | 5 | public class TypeCheckError extends Exception { 6 | 7 | private CtElement location; 8 | 9 | public TypeCheckError(String message) { 10 | super(message); 11 | } 12 | 13 | public CtElement getLocation() { 14 | return location; 15 | } 16 | 17 | public void setLocation(CtElement location) { 18 | this.location = location; 19 | } 20 | 21 | /** */ 22 | private static final long serialVersionUID = 1L; 23 | } 24 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/smt/TypeMismatchError.java: -------------------------------------------------------------------------------- 1 | package liquidjava.smt; 2 | 3 | import spoon.reflect.declaration.CtElement; 4 | 5 | public class TypeMismatchError extends Exception { 6 | 7 | private CtElement location; 8 | 9 | public TypeMismatchError(String message) { 10 | super(message); 11 | } 12 | 13 | public CtElement getLocation() { 14 | return location; 15 | } 16 | 17 | public void setLocation(CtElement location) { 18 | this.location = location; 19 | } 20 | 21 | /** */ 22 | private static final long serialVersionUID = 1L; 23 | } 24 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/utils/Pair.java: -------------------------------------------------------------------------------- 1 | package liquidjava.utils; 2 | 3 | public class Pair { 4 | private K k; 5 | private V v; 6 | 7 | public Pair(K k, V v) { 8 | this.k = k; 9 | this.v = v; 10 | } 11 | 12 | public K getFirst() { 13 | return k; 14 | } 15 | 16 | public V getSecond() { 17 | return v; 18 | } 19 | 20 | public String toString() { 21 | return "Pair [" + k.toString() + ", " + v.toString() + "]"; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /liquidjava-verifier/src/main/java/liquidjava/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package liquidjava.utils; 2 | 3 | import spoon.reflect.factory.Factory; 4 | import spoon.reflect.reference.CtTypeReference; 5 | 6 | public class Utils { 7 | 8 | public static final String AND = "&&"; 9 | public static final String OR = "||"; 10 | 11 | public static final String EQ = "=="; 12 | public static final String NEQ = "!="; 13 | public static final String GT = ">"; 14 | public static final String GE = ">="; 15 | public static final String LT = "<"; 16 | public static final String LE = "<="; 17 | 18 | public static final String PLUS = "+"; 19 | public static final String MINUS = "-"; 20 | public static final String MUL = "*"; 21 | public static final String DIV = "/"; 22 | public static final String MOD = "%"; 23 | 24 | public static final String WILD_VAR = "_"; 25 | public static final String OLD = "old"; 26 | 27 | public static final String INT = "int"; 28 | public static final String DOUBLE = "double"; 29 | public static final String STRING = "String"; 30 | public static final String BOOLEAN = "boolean"; 31 | public static final String INT_LIST = "int[]"; 32 | public static final String LIST = "List"; 33 | public static final String SHORT = "short"; 34 | public static final String LONG = "long"; 35 | public static final String FLOAT = "float"; 36 | 37 | public static CtTypeReference getType(String type, Factory factory) { 38 | // TODO complete 39 | switch (type) { 40 | case INT: 41 | return factory.Type().INTEGER_PRIMITIVE; 42 | case DOUBLE: 43 | return factory.Type().DOUBLE_PRIMITIVE; 44 | case BOOLEAN: 45 | return factory.Type().BOOLEAN_PRIMITIVE; 46 | case INT_LIST: 47 | return factory.createArrayReference(getType("int", factory)); 48 | case STRING: 49 | return factory.Type().STRING; 50 | case LIST: 51 | return factory.Type().LIST; 52 | default: 53 | // return factory.Type().OBJECT; 54 | return factory.createReference(type); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 4.0.0 6 | 7 | liquidjava 8 | liquidjava-umbrella 9 | 1.0 10 | 11 | pom 12 | 13 | 14 | liquidjava-api 15 | liquidjava-verifier 16 | liquidjava-example 17 | 18 | 19 | 20 | UTF-8 21 | 1.8 22 | 1.8 23 | 24 | 25 | --------------------------------------------------------------------------------