Skip to content

Commit cdd24fe

Browse files
committed
Implement basic simplifications for string comparison expr
1 parent f51ce2e commit cdd24fe

3 files changed

Lines changed: 72 additions & 4 deletions

File tree

ksmt-core/src/main/kotlin/io/ksmt/expr/rewrite/simplify/StringSimplification.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,22 +40,22 @@ fun KContext.simplifyStringPrefixOf(
4040
fun KContext.simplifyStringLt(
4141
arg0: KExpr<KStringSort>,
4242
arg1: KExpr<KStringSort>
43-
): KExpr<KBoolSort> = mkStringLtNoSimplify(arg0, arg1) // Temporarily
43+
): KExpr<KBoolSort> = simplifyStringBasicLtExpr(arg0, arg1, ::mkStringLtNoSimplify)
4444

4545
fun KContext.simplifyStringLe(
4646
arg0: KExpr<KStringSort>,
4747
arg1: KExpr<KStringSort>
48-
): KExpr<KBoolSort> = mkStringLeNoSimplify(arg0, arg1) // Temporarily
48+
): KExpr<KBoolSort> = simplifyStringBasicLeExpr(arg0, arg1, ::mkStringLeNoSimplify)
4949

5050
fun KContext.simplifyStringGt(
5151
arg0: KExpr<KStringSort>,
5252
arg1: KExpr<KStringSort>
53-
): KExpr<KBoolSort> = mkStringGtNoSimplify(arg0, arg1) // Temporarily
53+
): KExpr<KBoolSort> = simplifyStringBasicGtExpr(arg0, arg1, ::mkStringGtNoSimplify)
5454

5555
fun KContext.simplifyStringGe(
5656
arg0: KExpr<KStringSort>,
5757
arg1: KExpr<KStringSort>
58-
): KExpr<KBoolSort> = mkStringGeNoSimplify(arg0, arg1) // Temporarily
58+
): KExpr<KBoolSort> = simplifyStringBasicGeExpr(arg0, arg1, ::mkStringGeNoSimplify)
5959

6060
fun KContext.simplifyStringContains(
6161
arg0: KExpr<KStringSort>,

ksmt-core/src/main/kotlin/io/ksmt/expr/rewrite/simplify/StringSimplificationRules.kt

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,54 @@ inline fun KContext.simplifyStringBasicPrefixOfExpr(
109109
cont(arg0, arg1)
110110
}
111111

112+
/*
113+
* String comparison expression simplifications
114+
* */
115+
116+
/** Simplifies string "less than" comparison expressions
117+
* (str_lt strConst1 strConst2) ==> boolConst */
118+
inline fun KContext.simplifyStringBasicLtExpr(
119+
arg0: KExpr<KStringSort>,
120+
arg1: KExpr<KStringSort>,
121+
cont: (KExpr<KStringSort>, KExpr<KStringSort>) -> KExpr<KBoolSort>
122+
): KExpr<KBoolSort> =
123+
tryEvalStringLiteralOperation(arg0, arg1, { a0, a1 -> StringUtils.stringLt(a0, a1) }) {
124+
cont(arg0, arg1)
125+
}
126+
127+
/** Simplifies string "less than or equal" comparison expressions
128+
* (str_le strConst1 strConst2) ==> boolConst */
129+
inline fun KContext.simplifyStringBasicLeExpr(
130+
arg0: KExpr<KStringSort>,
131+
arg1: KExpr<KStringSort>,
132+
cont: (KExpr<KStringSort>, KExpr<KStringSort>) -> KExpr<KBoolSort>
133+
): KExpr<KBoolSort> =
134+
tryEvalStringLiteralOperation(arg0, arg1, { a0, a1 -> StringUtils.stringLe(a0, a1) }) {
135+
cont(arg0, arg1)
136+
}
137+
138+
/** Simplifies string "greater than" comparison expressions
139+
* (str_gt strConst1 strConst2) ==> boolConst */
140+
inline fun KContext.simplifyStringBasicGtExpr(
141+
arg0: KExpr<KStringSort>,
142+
arg1: KExpr<KStringSort>,
143+
cont: (KExpr<KStringSort>, KExpr<KStringSort>) -> KExpr<KBoolSort>
144+
): KExpr<KBoolSort> =
145+
tryEvalStringLiteralOperation(arg0, arg1, { a0, a1 -> StringUtils.stringGt(a0, a1) }) {
146+
cont(arg0, arg1)
147+
}
148+
149+
/** Simplifies string "greater than or equal" comparison expressions
150+
* (str_ge strConst1 strConst2) ==> boolConst */
151+
inline fun KContext.simplifyStringBasicGeExpr(
152+
arg0: KExpr<KStringSort>,
153+
arg1: KExpr<KStringSort>,
154+
cont: (KExpr<KStringSort>, KExpr<KStringSort>) -> KExpr<KBoolSort>
155+
): KExpr<KBoolSort> =
156+
tryEvalStringLiteralOperation(arg0, arg1, { a0, a1 -> StringUtils.stringGe(a0, a1) }) {
157+
cont(arg0, arg1)
158+
}
159+
112160
inline fun <K : KSort> tryEvalStringLiteralOperation(
113161
arg: KExpr<KStringSort>,
114162
operation: (KStringLiteralExpr) -> KInterpretedValue<K>,

ksmt-core/src/main/kotlin/io/ksmt/utils/StringUtils.kt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,24 @@ object StringUtils {
2020
fun isStringPrefix(arg0: KStringLiteralExpr, arg1: KStringLiteralExpr): KInterpretedValue<KBoolSort> = with (arg0.ctx) {
2121
mkBool(arg1.value.startsWith(arg0.value)).uncheckedCast()
2222
}
23+
24+
@JvmStatic
25+
fun stringLt(arg0: KStringLiteralExpr, arg1: KStringLiteralExpr): KInterpretedValue<KBoolSort> = with (arg0.ctx) {
26+
mkBool(arg0.value < arg1.value).uncheckedCast()
27+
}
28+
29+
@JvmStatic
30+
fun stringLe(arg0: KStringLiteralExpr, arg1: KStringLiteralExpr): KInterpretedValue<KBoolSort> = with (arg0.ctx) {
31+
mkBool(arg0.value <= arg1.value).uncheckedCast()
32+
}
33+
34+
@JvmStatic
35+
fun stringGt(arg0: KStringLiteralExpr, arg1: KStringLiteralExpr): KInterpretedValue<KBoolSort> = with (arg0.ctx) {
36+
mkBool(arg0.value > arg1.value).uncheckedCast()
37+
}
38+
39+
@JvmStatic
40+
fun stringGe(arg0: KStringLiteralExpr, arg1: KStringLiteralExpr): KInterpretedValue<KBoolSort> = with (arg0.ctx) {
41+
mkBool(arg0.value >= arg1.value).uncheckedCast()
42+
}
2343
}

0 commit comments

Comments
 (0)