Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overloaded Operators for KeY lang #3032

Draft
wants to merge 56 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
fac35af
allow multi-char operators
wadoon Feb 4, 2022
9689360
add metadata information to functions and predicates
wadoon Feb 4, 2022
2876402
add MixFitInfo to capture information
wadoon Feb 4, 2022
a30b91e
change the loopup functions
wadoon Feb 4, 2022
58ab4f0
remove seq +, use annotation
wadoon Feb 4, 2022
3790027
remove old lookup and add metadata
wadoon Feb 6, 2022
6c4f1a6
NotationInfo recognizes MixFitInfos
wadoon Feb 6, 2022
d059b75
fix clash with <->
wadoon Feb 6, 2022
eecbccf
minors
wadoon Feb 6, 2022
0222157
fixes failing tests
wadoon Feb 8, 2022
c3708ae
Merge branch 'master' into weigl/overop
wadoon Feb 8, 2022
9baeb5b
remove prefix from neglit
wadoon Feb 13, 2022
fd4963a
Merge branch 'master' into weigl/overop
wadoon Feb 13, 2022
4ff4563
add prefix at negDouble
wadoon Feb 13, 2022
b14b741
fix tests, add whitepsaces
wadoon Feb 13, 2022
9b54c0b
Merge branch 'master' into weigl/overop
wadoon Feb 16, 2022
dda6ea1
allow multi-char operators
wadoon Feb 4, 2022
b9fd5a6
add metadata information to functions and predicates
wadoon Feb 4, 2022
ab2a6be
add MixFitInfo to capture information
wadoon Feb 4, 2022
2aa5097
change the loopup functions
wadoon Feb 4, 2022
75efea8
remove seq +, use annotation
wadoon Feb 4, 2022
36efc6b
remove old lookup and add metadata
wadoon Feb 6, 2022
e7d9172
NotationInfo recognizes MixFitInfos
wadoon Feb 6, 2022
e59b436
fix clash with <->
wadoon Feb 6, 2022
c5abd20
minors
wadoon Feb 6, 2022
241cd20
fixes failing tests
wadoon Feb 8, 2022
41c5fb6
remove prefix from neglit
wadoon Feb 13, 2022
b388f45
add prefix at negDouble
wadoon Feb 13, 2022
0f2788b
fix tests, add whitepsaces
wadoon Feb 13, 2022
dcdaf04
fix merge
wadoon Apr 17, 2022
2e48d16
Merge remote-tracking branch 'origin/weigl/overop' into weigl/overop
wadoon Apr 17, 2022
9188f0c
adts to KeY grammar
wadoon Apr 17, 2022
097994a
wip
wadoon Apr 26, 2022
91abf3d
Merge remote-tracking branch 'origin/master' into weigl/overop
wadoon Jun 24, 2022
62c5c50
spotless apply
wadoon Feb 7, 2023
470be0a
Merge remote-tracking branch 'origin/main' into weigl/overop
wadoon Feb 8, 2023
20b3020
spotless
wadoon Feb 8, 2023
29fda88
Merge remote-tracking branch 'origin/main' into weigl/overop
wadoon Jul 23, 2023
8f5e534
wip
wadoon Jul 24, 2023
953a33f
fix last problems
wadoon Jul 30, 2023
dc11e4c
Merge remote-tracking branch 'origin/main' into weigl/overop
wadoon Jul 30, 2023
06f7acb
fix parser
wadoon Aug 2, 2023
ccbe4c1
Merge branch 'main' into weigl/overop
wadoon Aug 27, 2023
1247f70
Merge branch 'main' into weigl/overop
wadoon Oct 12, 2023
2b5d499
Merge remote-tracking branch 'origin/main' into weigl/overop
wadoon Nov 19, 2023
ea65e16
fix compile errors & spotless
wadoon Nov 19, 2023
f9975f2
Merge branch 'main' into weigl/overop
wadoon Nov 27, 2023
48ca4e7
Merge branch 'main' into weigl/overop
wadoon Dec 16, 2023
a723d29
Merge branch 'main' into weigl/overop
wadoon Dec 29, 2023
77eab70
fix merge error
wadoon Dec 29, 2023
4c44e9a
Merge remote-tracking branch 'origin/main' into weigl/overop
wadoon Dec 29, 2023
9c1dd90
fix merge error
wadoon Dec 29, 2023
bbe9db4
wip
wadoon Dec 29, 2023
8157393
Merge branch 'main' into weigl/overop
wadoon Feb 3, 2024
71354b6
Merge branch 'main' into weigl/overop
wadoon Feb 11, 2024
3053fc1
Merge remote-tracking branch 'origin/main' into weigl/overop
wadoon Feb 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
426 changes: 281 additions & 145 deletions key/key.core/src/main/antlr4/KeYLexer.g4

Large diffs are not rendered by default.

51 changes: 41 additions & 10 deletions key/key.core/src/main/antlr4/KeYParser.g4
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ decls
| schema_var_decls
| pred_decls
| func_decls
| adt_decls
| transform_decls
| ruleset_decls
| contracts // for problems
Expand Down Expand Up @@ -212,6 +213,7 @@ pred_decl
pred_name = funcpred_name
(whereToBind=where_to_bind)?
argSorts=arg_sorts
functionMetaData?
SEMI
;

Expand All @@ -228,18 +230,47 @@ func_decl
func_name = funcpred_name
whereToBind=where_to_bind?
argSorts = arg_sorts
functionMetaData?
SEMI
;

/**
\datatypes {
List = Nil | Cons(any, List);
}
*/
adt_decl
wadoon marked this conversation as resolved.
Show resolved Hide resolved
:
doc=DOC_COMMENT? (UNIQUE)?
name=funcpred_name
EQUALS
adt_constructor (OR adt_constructor)*
SEMI
;

adt_constructor
:
doc=DOC_COMMENT? funcpred_name #adt_constructor_base
| doc=DOC_COMMENT? funcpred_name LPAREN sortId (COMMA sortId)* RPAREN #adt_constructor_recursion
;

functionMetaData
:
INFIX LPAREN op=(PLUS|STAR|SLASH|MINUS|EXP|PERCENT|LESS|LESSEQUAL|GREATER|GREATEREQUAL|LGUILLEMETS) RPAREN
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seams to deviate from the PR description

| PREFIX LPAREN op=(MINUS|TILDE) RPAREN
| POSTFIX LPAREN (/*currently no overloaded operator*/) RPAREN
| SHORTCUT LPAREN IDENT RPAREN
;

func_decls
:
FUNCTIONS
LBRACE
(
func_decl
) *
RBRACE
;
:
FUNCTIONS LBRACE (func_decl)* RBRACE
;

adt_decls
:
DATATYPES LBRACE adt_decl* RBRACE
;


// like arg_sorts but admits also the keyword "\formula"
Expand Down Expand Up @@ -346,10 +377,10 @@ unary_formula:
| MODALITY sub=term60 #modality_term
;
equality_term: a=comparison_term ((NOT_EQUALS|EQUALS) b=comparison_term)?;
comparison_term: a=weak_arith_term ((LESS|LESSEQUAL|GREATER|GREATEREQUAL) b=weak_arith_term)?;
comparison_term: a=weak_arith_term (op=(LESS|LESSEQUAL|GREATER|GREATEREQUAL) b=weak_arith_term)?;
weak_arith_term: a=strong_arith_term_1 (op+=(PLUS|MINUS) b+=strong_arith_term_1)*;
strong_arith_term_1: a=strong_arith_term_2 (STAR b+=strong_arith_term_2)*;
strong_arith_term_2: a=atom_prefix ((PERCENT|SLASH) b=strong_arith_term_2)?;
strong_arith_term_2: a=atom_prefix (op=(PERCENT|SLASH) b=strong_arith_term_2)?;
update_term: (LBRACE u=term RBRACE) (atom_prefix | unary_formula);
substitution_term:
LBRACE SUBST bv=one_bound_variable SEMI
Expand Down
82 changes: 41 additions & 41 deletions key/key.core/src/main/java/de/uka/ilkd/key/java/TypeConverter.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@
import de.uka.ilkd.key.util.Debug;
import org.key_project.util.ExtList;
import org.key_project.util.collection.ImmutableArray;
import org.key_project.util.collection.ImmutableList;
import org.key_project.util.collection.ImmutableSLList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import recoder.service.ConstantEvaluator;
import recoder.service.KeYCrossReferenceSourceInfo;

import java.util.Collection;
import java.util.Collections;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

Expand Down Expand Up @@ -112,10 +112,6 @@ public CharListLDT getCharListLDT() {
return (CharListLDT) getLDT(CharListLDT.NAME);
}

public Collection<LDT> getLDTs() {
return LDTs.values();
}

private Term translateOperator(de.uka.ilkd.key.java.expression.Operator op, ExecutionContext ec) {

final Term[] subs = new Term[op.getArity()];
Expand Down Expand Up @@ -395,6 +391,7 @@ private Term convertLiteralExpression(Literal lit) {


// TODO Adapt for @Reals

/**
* performs binary numeric promotion on the argument types
*/
Expand Down Expand Up @@ -444,39 +441,39 @@ else if ((t1 == PrimitiveType.JAVA_BOOLEAN &&
return type1;
} else if (type2.equals(services.getJavaInfo().getKeYJavaType("java.lang.String"))) {
return type2;
} else if ((t2 == PrimitiveType.JAVA_FLOAT) &&
(t1 == PrimitiveType.JAVA_BYTE||
t1 == PrimitiveType.JAVA_SHORT||
t1 == PrimitiveType.JAVA_INT||
t1 == PrimitiveType.JAVA_CHAR||
t1 == PrimitiveType.JAVA_LONG||
t1 == PrimitiveType.JAVA_FLOAT)) {
} else if ((t2 == PrimitiveType.JAVA_FLOAT) &&
(t1 == PrimitiveType.JAVA_BYTE ||
t1 == PrimitiveType.JAVA_SHORT ||
t1 == PrimitiveType.JAVA_INT ||
t1 == PrimitiveType.JAVA_CHAR ||
t1 == PrimitiveType.JAVA_LONG ||
t1 == PrimitiveType.JAVA_FLOAT)) {
return services.getJavaInfo().getKeYJavaType(PrimitiveType.JAVA_FLOAT);
} else if ((t1 == PrimitiveType.JAVA_FLOAT) &&
(t2 == PrimitiveType.JAVA_BYTE||
t2 == PrimitiveType.JAVA_SHORT||
t2 == PrimitiveType.JAVA_INT||
t2 == PrimitiveType.JAVA_CHAR||
t2 == PrimitiveType.JAVA_LONG||
t2 == PrimitiveType.JAVA_FLOAT)) {
} else if ((t1 == PrimitiveType.JAVA_FLOAT) &&
(t2 == PrimitiveType.JAVA_BYTE ||
t2 == PrimitiveType.JAVA_SHORT ||
t2 == PrimitiveType.JAVA_INT ||
t2 == PrimitiveType.JAVA_CHAR ||
t2 == PrimitiveType.JAVA_LONG ||
t2 == PrimitiveType.JAVA_FLOAT)) {
return services.getJavaInfo().getKeYJavaType(PrimitiveType.JAVA_FLOAT);
} else if ((t2 == PrimitiveType.JAVA_DOUBLE) &&
(t1 == PrimitiveType.JAVA_BYTE||
t1 == PrimitiveType.JAVA_SHORT||
t1 == PrimitiveType.JAVA_INT||
t1 == PrimitiveType.JAVA_CHAR||
t1 == PrimitiveType.JAVA_LONG||
t1 == PrimitiveType.JAVA_FLOAT||
t1 == PrimitiveType.JAVA_DOUBLE)) {
} else if ((t2 == PrimitiveType.JAVA_DOUBLE) &&
(t1 == PrimitiveType.JAVA_BYTE ||
t1 == PrimitiveType.JAVA_SHORT ||
t1 == PrimitiveType.JAVA_INT ||
t1 == PrimitiveType.JAVA_CHAR ||
t1 == PrimitiveType.JAVA_LONG ||
t1 == PrimitiveType.JAVA_FLOAT ||
t1 == PrimitiveType.JAVA_DOUBLE)) {
return services.getJavaInfo().getKeYJavaType(PrimitiveType.JAVA_DOUBLE);
} else if ((t1 == PrimitiveType.JAVA_DOUBLE) &&
(t2 == PrimitiveType.JAVA_BYTE||
t2 == PrimitiveType.JAVA_SHORT||
t2 == PrimitiveType.JAVA_INT||
t2 == PrimitiveType.JAVA_CHAR||
t2 == PrimitiveType.JAVA_LONG||
t2 == PrimitiveType.JAVA_FLOAT||
t2 == PrimitiveType.JAVA_DOUBLE)) {
} else if ((t1 == PrimitiveType.JAVA_DOUBLE) &&
(t2 == PrimitiveType.JAVA_BYTE ||
t2 == PrimitiveType.JAVA_SHORT ||
t2 == PrimitiveType.JAVA_INT ||
t2 == PrimitiveType.JAVA_CHAR ||
t2 == PrimitiveType.JAVA_LONG ||
t2 == PrimitiveType.JAVA_FLOAT ||
t2 == PrimitiveType.JAVA_DOUBLE)) {
return services.getJavaInfo().getKeYJavaType(PrimitiveType.JAVA_DOUBLE);
} else {
throw new RuntimeException("Could not determine promoted type "
Expand Down Expand Up @@ -511,10 +508,10 @@ else if (t1 == PrimitiveType.JAVA_BIGINT)
return services.getJavaInfo().getKeYJavaType(PrimitiveType.JAVA_BIGINT);
else if (t1 == PrimitiveType.JAVA_REAL)
return services.getJavaInfo().getKeYJavaType(PrimitiveType.JAVA_REAL);
else if (t1 == PrimitiveType.JAVA_FLOAT)
return services.getJavaInfo().getKeYJavaType(PrimitiveType.JAVA_FLOAT);
else if (t1 == PrimitiveType.JAVA_DOUBLE)
return services.getJavaInfo().getKeYJavaType(PrimitiveType.JAVA_DOUBLE);
else if (t1 == PrimitiveType.JAVA_FLOAT)
return services.getJavaInfo().getKeYJavaType(PrimitiveType.JAVA_FLOAT);
else if (t1 == PrimitiveType.JAVA_DOUBLE)
return services.getJavaInfo().getKeYJavaType(PrimitiveType.JAVA_DOUBLE);
else throw new RuntimeException("Could not determine promoted type " +
"of " + type1);
}
Expand Down Expand Up @@ -1024,4 +1021,7 @@ private LDT getResponsibleLDT(de.uka.ilkd.key.java.expression.Operator op, Term[
return null;
}

public Collection<LDT> getLDTs() {
return Collections.unmodifiableCollection(LDTs.values());
}
}
14 changes: 5 additions & 9 deletions key/key.core/src/main/java/de/uka/ilkd/key/ldt/CharListLDT.java
Original file line number Diff line number Diff line change
Expand Up @@ -252,13 +252,9 @@ public final Type getType(Term t) {
return null;
}

@Nullable
@Override
public Function getFunctionFor(String operationName, Services services) {
switch (operationName) {
// This is not very elegant; but seqConcat is actually in the SeqLDT.
case "add": return services.getNamespaces().functions().lookup("seqConcat");
default: return null;
}
}
@Nullable
@Override
public Function getFunctionFor(String operatorSymbol, Services services) {
return services.getTypeConverter().getSeqLDT().getFunctionFor(operatorSymbol, services);
}
}
16 changes: 3 additions & 13 deletions key/key.core/src/main/java/de/uka/ilkd/key/ldt/DoubleLDT.java
Original file line number Diff line number Diff line change
Expand Up @@ -164,19 +164,9 @@ public Term translateLiteral(Literal lit, Services services) {
return services.getTermBuilder().dfpTerm(doubleVal);
}

@Override
public Function getFunctionFor(String op, Services services) {
switch (op) {
case "gt": return getGreaterThan();
case "geq": return getGreaterOrEquals();
case "lt": return getLessThan();
case "leq": return getLessOrEquals();
case "div": return getDiv();
case "mul": return getMul();
case "add": return getAdd();
case "sub": return getSub();
case "neg": return getNeg();

/* @Override
public Function getFunctionFor(String operatorSymbol, Services services) {
// Floating point extensions with "\fp_"
case "nan": return getIsNaN();
case "zero": return getIsZero();
Expand All @@ -189,7 +179,7 @@ public Function getFunctionFor(String op, Services services) {
case "normal": return getIsNormal();
}
return null;
}
}*/

@Override
public Function getFunctionFor(de.uka.ilkd.key.java.expression.Operator op,
Expand Down
20 changes: 6 additions & 14 deletions key/key.core/src/main/java/de/uka/ilkd/key/ldt/FloatLDT.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,19 +174,8 @@ public Function getFunctionFor(de.uka.ilkd.key.java.expression.Operator op,
}
}

@Override
public Function getFunctionFor(String op, Services services) {
switch (op) {
case "gt": return getGreaterThan();
case "geq": return getGreaterOrEquals();
case "lt": return getLessThan();
case "leq": return getLessOrEquals();
case "div": return getDiv();
case "mul": return getMul();
case "add": return getAdd();
case "sub": return getSub();
case "neg": return getNeg();
// Floating point extensions with "\fp_"
/* @Override
public Function getFunctionFor(String operatorSymbol, Services services) {
case "nan": return getIsNaN();
case "zero": return getIsZero();
case "infinite": return getIsInfinite();
Expand All @@ -195,10 +184,13 @@ public Function getFunctionFor(String op, Services services) {
case "negative": return getIsNegative();
case "positive": return getIsPositive();
case "subnormal": return getIsSubnormal();
case "normal": return getIsNormal();

case "normal": return getIsNormal();

}
return null;
}
*/

@Override
public boolean hasLiteralFunction(Function f) {
Expand Down
17 changes: 0 additions & 17 deletions key/key.core/src/main/java/de/uka/ilkd/key/ldt/IntegerLDT.java
Original file line number Diff line number Diff line change
Expand Up @@ -484,23 +484,6 @@ public Function getFunctionFor(
}
}

@Nullable
@Override
public Function getFunctionFor(String op, Services services) {
switch (op) {
case "gt": return getGreaterThan();
case "geq": return getGreaterOrEquals();
case "lt": return getLessThan();
case "leq": return getLessOrEquals();
case "div": return getDiv();
case "mul": return getMul();
case "add": return getAdd();
case "sub": return getSub();
case "mod": return getMod();
case "neg": return getNeg();
}
return null;
}

@Override
public boolean isResponsible(de.uka.ilkd.key.java.expression.Operator op,
Expand Down
28 changes: 24 additions & 4 deletions key/key.core/src/main/java/de/uka/ilkd/key/ldt/LDT.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package de.uka.ilkd.key.ldt;

import java.util.Collection;
import java.util.Map;
import java.util.TreeMap;

import de.uka.ilkd.key.logic.op.MixFitInfo;
import org.key_project.util.ExtList;

import de.uka.ilkd.key.java.Expression;
Expand Down Expand Up @@ -235,21 +237,35 @@ public abstract Function getFunctionFor(

/**
* get the function in this LDT for an operation identified by generic
* operationName. If the LDT does not support this named function, it should
* operatorSymbol. If the LDT does not support this named function, it should
* return null.
*
* This is used to resolve overloaded symbols.
*
* For example: "+" may map to "add" for integers, and to "addFloat" for
* floats.
*
* @param operationName non-null operationName for a generic function
* @param operatorSymbol non-null operatorSymbol for a generic function
* @param services services to use
* @return reference to the respective LDT-specific function for the
* operation, null if not available
*/
public @Nullable Function getFunctionFor(String operationName, Services services) {
// by default an LDT does not support overloaded symbols
public @Nullable Function getFunctionFor(String operatorSymbol, Services services) {
return getFunctionFor(operatorSymbol, MixFitInfo.Kind.INFIX, services);

}
public @Nullable Function getFunctionFor(String operatorSymbol, MixFitInfo.Kind kind, Services services) {
for (Operator operator : functions.allElements()) {
if(operator instanceof Function) {
var op = (Function) operator;
if (op.getMixFitInfo() != null) {
var mfi = op.getMixFitInfo();
if (kind == mfi.getKind() && mfi.symbol.equals(operatorSymbol)) {
return op;
}
}
}
}
return null;
}

Expand All @@ -259,4 +275,8 @@ public abstract Function getFunctionFor(
public abstract Expression translateTerm(Term t, ExtList children, Services services);

public abstract Type getType(Term t);

public Collection<Operator> getFunctions() {
return functions.allElements();
}
}
Loading