Notes on CVC4's CVC language parser. This language parser attempts to maintain some backward compatibility with previous versions of the language. However, as the language evolves, new features need to be supported, and deprecated, difficult-to-maintain, or grammar-conflicting syntax and features need to be removed. In order to support our users, we have tried to parse what CVC3 could and (at least) offer an error when a feature is unavailable or unimplemented. But this is not always possible. Please report a bug if a particular discrepancy between CVC3 and CVC4 handling of the CVC language is a concern to you; we may be able to add a compatibility mode, or at least offer better warnings or errors. Below is a list of the known differences between CVC3's and CVC4's version of the CVC language. This is the list of differences in language design and parsing ONLY. The featureset of CVC4 is rapidly expanding, but does not match CVC3's breadth yet. However, CVC4 should tell you of an unimplemented feature if you try to use it (rather than giving a cryptic parse or assertion error). * CVC4 does not add the current assumptions to the scope after SAT/INVALID responses like CVC3 did. * CVC4 no longer supports the "old" function syntax: f : [INT -> INT]; This syntax was deprecated in CVC3, and will no longer be supported. Functions are now written as follows: unary : INT -> INT; binary : (INT, INT) -> INT; ternary : (INT, INT, INT) -> INT; * QUERY and CHECKSAT do not add their argument to the current list of assertions like CVC3 did. * CVC4 allows datatypes to hold complex types that contain self- or mutual references. For example, DATATYPE tree = node(children:ARRAY INT OF tree) | leaf(data:INT) END; is permissible in CVC4 but not in CVC3. * CVC4 supports parameterized types in datatype definitions, e.g. DATATYPE list[T] = cons(car:T) | nil END; You can then declare "x : list[INT];" or "x : list[list[INT]];", for example. * CVC4 supports type ascriptions, e.g. U : TYPE; f : INT -> U; QUERY f(5) : U = f(6); QUERY f(5) : U = f(6) : U; QUERY ( f(5) = f(6) ) : BOOLEAN; QUERY f(5) : U = f(6) : U : BOOLEAN; You probably won't need it that much, but it can be handy for debugging. If a term (or formula) isn't the same type as its ascription, and it cannot be "up-casted" safely, an error is immediately generated at parse time. Sometimes this up-cast is necessary; consider the "nil" constructor of list[T] above. To use "nil," you must cast it to something: DATATYPE Item = Carrots | Butter | Milk | Bread END; groceries : list[Item] = cons(Butter, cons(Bread, nil:list[INT])); * CVC4 supports stronger distinction between type and variable names. This means that CVC4 may allow you to declare things that CVC3 does not: a : TYPE; a : INT; % CVC3 complains a : a; % CVC4 complains, `a' cannot both be INT and `a' b : a; % No problem, `a' is both the type of `b', and an INT * CVC4 supports a command-level LET syntax, e.g.: LET double = LAMBDA(x:INT) : 2*x IN QUERY double(5) = 10; It works for types also, and mixes of the two: LET x = INT, y = 5, z = x IN w : x = y; QUERY y = 5; % error: y undefined QUERY w = 5; % valid The scope of such a LET is exactly one command (until a semicolon). (It would conflict with POP_SCOPE if it lasted longer.) -- Morgan Deters Wed, 20 Apr 2011 18:32:32 -0400