diff --git a/pom.xml b/pom.xml index 3d0e61a..54b07ce 100644 --- a/pom.xml +++ b/pom.xml @@ -26,16 +26,58 @@ + + + org.cprover.util + cprover-api + 1.0.0 + compile + + + core-models + + maven-dependency-plugin + 2.8 + + + generate-sources + + build-classpath + + + maven.compile.classpath + + + + copy-dependencies + package + + copy + + + + + org.cprover.util + cprover-api + ${project.build.directory} + cprover-api.jar + + + + + + + org.apache.maven.plugins maven-compiler-plugin 3.6.1 - ${java.home}/lib/rt.jar + ${java.home}/lib/rt.jar${path.separator}${maven.compile.classpath} 1.8 1.8 diff --git a/src/main/java/org/cprover/CProver.java b/src/main/java/org/cprover/CProver.java deleted file mode 100644 index 8295a39..0000000 --- a/src/main/java/org/cprover/CProver.java +++ /dev/null @@ -1,368 +0,0 @@ -package org.cprover; - -import java.io.BufferedInputStream; -import java.io.PrintStream; -import java.lang.reflect.Array; - -public final class CProver -{ - public static final boolean enableAssume=true; - public static final boolean enableNondet=true; - public static final boolean enableConcurrency=true; - - public static boolean nondetBoolean() - { - if (enableNondet) - { - throw new RuntimeException( - "Cannot execute program with CProver.nondetBoolean()"); - } - - return false; - } - - public static byte nondetByte() - { - if (enableNondet) - { - throw new RuntimeException( - "Cannot execute program with CProver.nondetByte()"); - } - - return 0; - } - - public static char nondetChar() - { - if (enableNondet) - { - throw new RuntimeException( - "Cannot execute program with CProver.nondetChar()"); - } - - return '\0'; - } - - public static short nondetShort() - { - if (enableNondet) - { - throw new RuntimeException( - "Cannot execute program with CProver.nondetShort()"); - } - - return 0; - } - - public static int nondetInt() - { - if (enableNondet) - { - throw new RuntimeException( - "Cannot execute program with CProver.nondetInt()"); - } - - return 0; - } - - public static long nondetLong() - { - if (enableNondet) - { - throw new RuntimeException( - "Cannot execute program with CProver.nondetLong()"); - } - - return 0; - } - - public static float nondetFloat() - { - if (enableNondet) - { - throw new RuntimeException( - "Cannot execute program with CProver.nondetFloat()"); - } - - return 0; - } - - public static double nondetDouble() - { - if (enableNondet) - { - throw new RuntimeException( - "Cannot execute program with CProver.nondetDouble()"); - } - - return 0; - } - - private static T nondetWithNull() - { - if (enableNondet) - { - throw new RuntimeException( - "Cannot execute program with CProver.nondetWithNull(T)"); - } - - return null; - } - - /** - * - * @param instance an instance of the type T, this is not used but is there - * to make sure the class T is loaded. The parameter should - * not be `null`. - * @param class of the object to return - * @return a non-deterministic object of type T, possibly `null`. - */ - public static T nondetWithNull(T instance) - { - return nondetWithNull(); - } - - private static T nondetWithoutNull() - { - T t = nondetWithNull(); - assume(t != null); - return t; - } - - /** - * - * @param instance an instance of the type T, this is not used but is there - * to make sure the class T is loaded. The parameter should - * not be `null`. - * @param class of the object to return - * @return a non-deterministic object of type T, assumed to be non-null. - */ - public static T nondetWithoutNull(T instance) - { - return nondetWithoutNull(); - } - - public static T nondetWithNullForNotModelled() { - return nondetWithNull(); - } - - public static T nondetWithoutNullForNotModelled() { - return nondetWithoutNull(); - } - - /** - * Return a non-deterministic PrintStream. - * It is not recommended to use it, since it will not enforce that PrintStream - * is loaded, but is necessary for initializing System.out and System.err. - */ - public static PrintStream nondetPrintStream() - { - return nondetWithoutNull(); - } - - /** - * Return a non-deterministic BufferedInputStream. - * It is not recommended to use it, since it will not enforce that - * BufferedInputStream is loaded, but is necessary for initializing System.in. - */ - public static BufferedInputStream nondetBufferedInputStream() - { - return nondetWithoutNull(); - } - - public static void assume(boolean condition) - { - if(enableAssume) - { - throw new RuntimeException( - "Cannot execute program with CProver.assume()"); - } - } - - /** - * This method is used by JBMC to detect the start of a new thread and - * create a multithreaded bmc equation. - * Refer to the method `start` in the model for the class `java.lang.Thread` - * in the JBMC sources to see an example of usage - */ - public static void startThread(int id) - { - if(enableConcurrency) - { - throw new RuntimeException( - "Cannot execute program with CProver.startThread()"); - } - } - - /** - * This method is used by JBMC to detect the end of a new thread to - * manage a multithreaded bmc equation - * Refer to the method `start` in the model for the class `java.lang.Thread` - * in the JBMC sources to see an example of usage - */ - public static void endThread(int id) - { - if(enableConcurrency) - { - throw new RuntimeException( - "Cannot execute program with CProver.endThread()"); - } - } - - /** - * This method is used by JBMC to return the ID of the executing thread. - */ - public static int getCurrentThreadID() - { - if(enableConcurrency) - { - throw new RuntimeException( - "Cannot execute program with CProver.getCurrentThreadID()"); - } - return 0; - } - - /** - * This method is used by JBMC to indicate an atomic section which enforces - * the bmc equation to avoid interleavings of the code inside the section - */ - public static void atomicBegin() - { - if(enableConcurrency) - { - throw new RuntimeException( - "Cannot execute program with CProver.atomicBegin()"); - } - } - - /** - * This method is used by JBMC to indicate the end of an atomic section - * (see atomicBegin). - */ - public static void atomicEnd() - { - if(enableConcurrency) - { - throw new RuntimeException( - "Cannot execute program with CProver.atomicEnd()"); - } - } - - /** - * If this method is found in the test-gen trace for a particular trace, - * that test will be discarded with a message explaining that the test - * calls a non-modelled method. - * This allows us to copy full classes from the JDK, and insert this function - * call into non-modelled methods. We can then model a handful of the - * methods on the class, ensuring that tests will only be generated for - * 'known-good' models. - */ - public static void notModelled() - { - assume(false); - } - - /** - * Array copy for byte arrays. Does not check for exceptions. - * Use instead of System.arraycopy when the bounds are ensured to be - * respected, that is, the following should be false: - * srcPos < 0 || destPos < 0 || length < 0 || - * srcPos + length > src.length || destPos + length > dest.length - * - * @param src the source array. - * @param srcPos starting position in the source array. - * @param dest the destination array. - * @param destPos starting position in the destination data. - * @param length the number of array elements to be copied. - */ - public static void arraycopy(byte[] src, int srcPos, byte[] dest, - int destPos, int length) { - byte[] temp = new byte[length]; - for (int i = 0; i < length; i++) { - temp[i] = src[srcPos + i]; - } - for (int i = 0; i < length; i++) { - dest[destPos + i] = temp[i]; - } - } - - /** - * Array copy for byte arrays. Does not check for exceptions, - * and assumes that `src` and `dest`. - * Use instead of System.arraycopy when `src` and `dest` are guaranteed to be - * different and the bounds are ensured to be - * respected, that is, the following should be false: - * src == dest || srcPos < 0 || destPos < 0 || length < 0 || - * srcPos + length > src.length || destPos + length > dest.length - * - * @param src the source array. - * @param srcPos starting position in the source array. - * @param dest the destination array. - * @param destPos starting position in the destination data. - * @param length the number of array elements to be copied. - */ - public static void arraycopyInPlace(byte[] src, int srcPos, byte[] dest, - int destPos, int length) { - for (int i = 0; i < length; i++) { - dest[destPos + i] = src[srcPos + i]; - } - } - - /** - * Retrieves the current locking count for 'object'. - */ - public static int getMonitorCount(Object object) - { - return object.cproverMonitorCount; - } - - /** - * Class identifier of an Object. For instance "java.lang.String", - * "java.lang.Integer". This gives direct read access to the - * {@code @class_identifier} field used internally by JBMC and test-generator. - * The body of this function is replaced by preprocessing of the java - * bytecode, it is only meant to give meaningful output in case the model is - * executed. - */ - public static String classIdentifier(Object object) - { - return object.getClass().getCanonicalName(); - } - - /** - * This method converts a double to a float and adds assumes that the conversion - * did not result any loss of precision. Calling this method is useful when we - * need to call a certain complicated operation on double, but we only have it - * implemented for floats. - * - * The method is a workaround for the current limitations of the string solver, - * which is able to convert float to String but not double to String. Once this - * limitation goes away, the method and its usages can be removed. - * - * The method itself has limitations: - * * There are doubles that can't be converted to float and back without loss - * of precision, so the assertion will sometimes be violated - * * Even if the assertion is satisfied for numbers d and converted, these - * might not have the same String representation. - */ - public static float doubleToFloat(double d) - { - float converted = nondetFloat(); - CProver.assume(d == (double) converted); - return converted; - } - - /** - * Instantiates (but does not populate) an array with type matching a given array, - * but with a potentially different length. Used by ArrayList.toArray, for example, - * whose internal array is an Object[] but must provide that array as a user-supplied - * T[], copying the runtime type of whatever array the user provided as a template. - * - * The implementation given here is correct, but JBMC cannot currently understand these - * reflective methods and therefore replaces this function with its own implementation. - */ - public static T[] createArrayWithType(int length, T[] type) { - Class typeClass = type.getClass(); - return (T[])Array.newInstance(typeClass.getComponentType(), length); - } -} diff --git a/src/main/java/org/cprover/CProverString.java b/src/main/java/org/cprover/CProverString.java deleted file mode 100644 index 34f4f86..0000000 --- a/src/main/java/org/cprover/CProverString.java +++ /dev/null @@ -1,479 +0,0 @@ -package org.cprover; - -/** - * This class provides an interface with string functions modeled internally - * in CProver, for which the CProver model differs from the JDK actual behavior. - * This is in particular the case for functions that throw exceptions. - */ -public final class CProverString -{ - /** - * Returns the character (Unicode code point) at the specified - * index. - * - * @param instance the String instance - * @param index the index to the {@code char} values - * @return the code point value of the character at the - * {@code index} - */ - public static int codePointAt(String instance, int index) { - return CProver.nondetInt(); - } - - /** - * Returns the character (Unicode code point) before the specified - * index. - * - * @param instance the String instance - * @param index the index following the code point that should be returned - * @return the code point value of the character before the - * {@code index} - */ - public static int codePointBefore(String instance, int index) { - return CProver.nondetInt(); - } - - /** - * Returns the number of Unicode code points in the specified text - * range of this {@code String}. - * - * @param instance the String instance - * @param beginIndex the index to the first {@code char} of - * the text range. - * @param endIndex the index after the last {@code char} of - * the text range. - * @return the number of Unicode code points in the specified text - * range - */ - public static int codePointCount( - String instance, int beginIndex, int endIndex) { - return CProver.nondetInt(); - } - - /** - * Returns the index within this {@code String} that is - * offset from the given {@code index} by - * {@code codePointOffset} code points. - * - * @param instance the String instance - * @param index the index to be offset - * @param codePointOffset the offset in code points - * @return the index within this {@code String} - */ - public static int offsetByCodePoints( - String instance, int index, int codePointOffset) { - return CProver.nondetInt(); - } - - /** - * Modeled internally in CBMC. - * @return '\u0000' if index is out of bounds and behave as s.charAt(i) - * otherwise. - */ - public static char charAt(String s, int i) { - return CProver.nondetChar(); - } - - /** - * Modeled internally in CBMC. - * @return empty string if index is too large, s if index too small and - * behave as s.substring(i) otherwise. - */ - public static String substring(String s, int i) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Modeled internally in CBMC. - * @return empty string if i >= j, s.substring(k, l) where k = max(0, i) - * and l = min(s.length() - 1, j) otherwise. - */ - public static String substring(String s, int i, int j) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Returns a character sequence that is a subsequence of this sequence. - * - * @param instance the String instance - * @param beginIndex the begin index, inclusive. - * @param endIndex the end index, exclusive. - * @return the specified subsequence. - */ - public static CharSequence subSequence( - String instance, int beginIndex, int endIndex) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Appends a subsequence of the specified {@code CharSequence} to this - * sequence. - * - * @param instance the StringBuilder instance - * @param cs the sequence to append. - * @param start the starting index of the subsequence to be appended. - * @param end the end index of the subsequence to be appended. - * @return the modified StringBuilder. - */ - public static StringBuilder append( - StringBuilder instance, CharSequence cs, int start, int end) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Removes the characters in a substring of this sequence. - * - * @param instance the StringBuilder instance - * @param start The beginning index, inclusive. - * @param end The ending index, exclusive. - * @return the modified StringBuilder. - */ - public static StringBuilder delete( - StringBuilder instance, int start, int end) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Removes the {@code char} at the specified position in this - * sequence. This sequence is shortened by one {@code char}. - * - * @param instance the StringBuilder instance - * @param index Index of {@code char} to remove - * @return the modified StringBuilder. - */ - public static StringBuilder deleteCharAt( - StringBuilder instance, int index) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Equality of two strings. Should be much more efficient for - * test-genaration than String.equals because the type is known at - * compilation time. - */ - public static boolean equals(String a, String b) - { - if (a == null) { - return b == null; - } - return a.length() == b.length() && a.startsWith(b); - } - - /** - * Inserts the string into this character sequence. - * - * @param instance the StringBuilder instance - * @param offset the offset. - * @param str a string. - * @return the modified StringBuilder. - */ - public static StringBuilder insert( - StringBuilder instance, int offset, String str) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Sets the length of the character sequence. - * - * @param instance the StringBuffer instance - * @param newLength the new length - */ - public static void setLength(StringBuffer instance, int newLength) { - } - - /** - * Sets the length of the character sequence. - * - * @param instance the StringBuilder instance - * @param newLength the new length - */ - public static void setLength(StringBuilder instance, int newLength) { - } - - /** - * Returns the {@code char} value in this sequence at the specified index. - * - * @param instance the StringBuffer instance - * @param index the index of the desired {@code char} value. - * @return the {@code char} value at the specified index. - */ - public static char charAt(StringBuffer instance, int index) { - return CProver.nondetChar(); - } - - /** - * The character at the specified index is set to {@code ch}. - * - * @param instance the StringBuffer instance - * @param index the index of the character to modify. - * @param c the new character. - */ - public static void setCharAt(StringBuffer instance, int index, char c) { - } - - /** - * The character at the specified index is set to {@code ch}. - * - * @param instance the StringBuilder instance - * @param index the index of the character to modify. - * @param c the new character. - */ - public static void setCharAt(StringBuilder instance, int index, char c) { - } - - /** - * Removes the characters in a substring of this sequence. - * - * @param instance the StringBuffer instance - * @param start the beginning index, inclusive. - * @param end the ending index, exclusive. - * @return The modified StringBuffer. - */ - public static StringBuffer delete( - StringBuffer instance, int start, int end) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Removes the {@code char} at the specified position in this - * sequence. This sequence is shortened by one {@code char}. - * - *

Note: If the character at the given index is a supplementary - * character, this method does not remove the entire character. If - * correct handling of supplementary characters is required, - * determine the number of {@code char}s to remove by calling - * {@code Character.charCount(thisSequence.codePointAt(index))}, - * where {@code thisSequence} is this sequence. - * - * @param instance the StringBuffer instance. - * @param index index of {@code char} to remove - * @return this object. - */ - public static StringBuffer deleteCharAt(StringBuffer instance, int index) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Returns a new {@code String} that contains a subsequence of - * characters currently contained in this sequence. - * - * @param instance the StringBuffer instance. - * @param start the beginning index, inclusive. - * @param end the ending index, exclusive. - * @return The new string. - */ - public static String substring(StringBuffer instance, int start, int end) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Inserts the string into this character sequence. - * - * @param instance the StringBuffer instance. - * @param offset the offset. - * @param str a string. - * @return The modified StringBuffer. - */ - public static StringBuffer insert( - StringBuffer instance, int offset, String str) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Inserts the string representation of the {@code boolean} - * argument into this sequence. - * - * @param offset the offset. - * @param b a {@code boolean}. - * @return a reference to this object. - */ - public static StringBuffer insert( - StringBuffer instance, int offset, boolean b) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Inserts the string representation of the {@code char} - * argument into this sequence. - * - * @param offset the offset. - * @param c a {@code char}. - * @return a reference to this object. - */ - public static StringBuffer insert( - StringBuffer instance, int offset, char c) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Inserts the string representation of the {@code int} - * argument into this sequence. - * - * @param offset the offset. - * @param i a {@code int}. - * @return a reference to this object. - */ - public static StringBuffer insert( - StringBuffer instance, int offset, int i) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Inserts the string representation of the {@code long} - * argument into this sequence. - * - * @param offset the offset. - * @param l a {@code long}. - * @return a reference to this object. - */ - public static StringBuffer insert( - StringBuffer instance, int offset, long l) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Converts an array of characters to a string. This uses a loop and - * therefore in test-generation the {@code count} will be limited by the - * unwind parameter. - * This constrains {@code value} to not be null, its length to be greater - * or equal to {@code offset + count} and {@code offset} and {@code count} - * to be non-negative. - * - * @param value array of characters which is the source to copy from - * @param offset index in {@code value} of the first character to copy - * @param count number of characters to copy - * @return The created String - */ - public static String ofCharArray(char value[], int offset, int count) { - CProver.assume(value != null); - CProver.assume(value.length - count >= offset - && offset >= 0 && count >= 0); - StringBuilder builder = new StringBuilder(); - for(int i = 0; i < count; i++) { - builder.append(value[offset + i]); - } - return builder.toString(); - } - - /** - * Format a string according to the given {@param formatString}. - * Unlike the JDK version, all arguments are given by strings, there is - * a fixed number of them and they should not be null. - * This fixed number corresponds to the constant {@code MAX_FORMAT_ARGS} defined in - * {@code java_string_library_preprocess.h} from JBMC. - */ - public static String format( - String formatString, String arg0, String arg1, String arg2, String arg3, - String arg4, String arg5, String arg6, String arg7, String arg8, String arg9) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Returns a {@code String} object representing the - * specified integer. The argument is converted to signed decimal - * representation and returned as a string. - * - * @param i an integer to be converted. - * @return a string representation of the argument in base 10. - */ - public static String toString(int i) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Returns a string representation of the first argument in the - * radix specified by the second argument. - * - * @param i an integer to be converted to a string. - * @param radix the radix to use in the string representation. - * @return a string representation of the argument in the specified radix. - */ - public static String toString(int i, int radix) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Returns a {@code String} object representing the specified - * {@code long}. The argument is converted to signed decimal - * representation and returned as a string. - * - * @param l a {@code long} to be converted. - * @return a string representation of the argument in base 10. - */ - public static String toString(long l) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Returns a string representation of the first argument in the - * radix specified by the second argument. - * - * @param l a {@code long} to be converted to a string. - * @param radix the radix to use in the string representation. - * @return a string representation of the argument in the specified radix. - */ - public static String toString(long l, int radix) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Returns a string representation of the {@code float} - * argument. - * - * @param f the float to be converted. - * @return a string representation of the argument. - */ - public static String toString(float f) { - return CProver.nondetWithoutNullForNotModelled(); - } - - /** - * Returns a string representation of the {@code double} - * argument. - * - * The double is converted to a float first as the string solver currently - * can convert float to String but not double to String. - * - * @param d the double to be converted. - * @return a string representation of the argument. - */ - public static String toString(double d) { - return toString(CProver.doubleToFloat(d)); - } - - /** - * Exactly as Integer.parseInt, except s is already checked non-null, the - * radix is already checked in-range and 's' is known to be a valid integer - * according to isValidInt below - */ - public static int parseInt(String s, int radix) { - return CProver.nondetInt(); - } - - /** - * Exactly as Long.parseLong, except s is already checked non-null, the - * radix is already checked in-range and 's' is known to be a valid integer - * according to isValidLong below - */ - public static long parseLong(String s, int radix) { - return CProver.nondetLong(); - } - - /** - * Returns true if string 's' is a valid integer: contains at least one - * digit, perhaps a leading '+' or '-', and doesn't contain invalid chars - * for the given radix. - */ - public static boolean isValidInt(String s, int radix) { - return CProver.nondetBoolean(); - } - - /** - * Returns true if string 's' is a valid long: contains at least one - * digit, perhaps a leading '+' or '-', and doesn't contain invalid chars - * for the given radix. - */ - public static boolean isValidLong(String s, int radix) { - return CProver.nondetBoolean(); - } -} diff --git a/src/main/java/org/cprover/MustNotThrow.java b/src/main/java/org/cprover/MustNotThrow.java deleted file mode 100644 index 7be14b1..0000000 --- a/src/main/java/org/cprover/MustNotThrow.java +++ /dev/null @@ -1,8 +0,0 @@ -package org.cprover; - -/** - * This can be added to methods to indicate they aren't allowed to throw - * exceptions. JBMC and related tools will truncate any execution path on which - * they do with an ASSUME FALSE instruction. - */ -public @interface MustNotThrow { }