Skip to content

Commit f51ce2e

Browse files
committed
Implement basic simplifications for suffixOf and prefixOf expressions
1 parent cefcd15 commit f51ce2e

3 files changed

Lines changed: 43 additions & 2 deletions

File tree

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,12 @@ fun KContext.simplifyStringInRegex(
3030
fun KContext.simplifyStringSuffixOf(
3131
arg0: KExpr<KStringSort>,
3232
arg1: KExpr<KStringSort>
33-
): KExpr<KBoolSort> = mkStringSuffixOfNoSimplify(arg0, arg1) // Temporarily
33+
): KExpr<KBoolSort> = simplifyStringBasicSuffixOfExpr(arg0, arg1, ::mkStringSuffixOfNoSimplify)
3434

3535
fun KContext.simplifyStringPrefixOf(
3636
arg0: KExpr<KStringSort>,
3737
arg1: KExpr<KStringSort>
38-
): KExpr<KBoolSort> = mkStringPrefixOfNoSimplify(arg0, arg1) // Temporarily
38+
): KExpr<KBoolSort> = simplifyStringBasicPrefixOfExpr(arg0, arg1, ::mkStringPrefixOfNoSimplify)
3939

4040
fun KContext.simplifyStringLt(
4141
arg0: KExpr<KStringSort>,

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import io.ksmt.expr.KExpr
55
import io.ksmt.expr.KInterpretedValue
66
import io.ksmt.expr.KStringConcatExpr
77
import io.ksmt.expr.KStringLiteralExpr
8+
import io.ksmt.sort.KBoolSort
89
import io.ksmt.sort.KIntSort
910
import io.ksmt.sort.KSort
1011
import io.ksmt.sort.KStringSort
@@ -70,6 +71,8 @@ inline fun KContext.simplifyStringNestedConcat(
7071
* String length expression simplification
7172
* */
7273

74+
/**
75+
* Eval length of string constant. */
7376
inline fun KContext.simplifyStringLenExpr(
7477
arg: KExpr<KStringSort>,
7578
cont: (KExpr<KStringSort>) -> KExpr<KIntSort>
@@ -80,6 +83,32 @@ inline fun KContext.simplifyStringLenExpr(
8083
cont(arg)
8184
}
8285

86+
/*
87+
* SuffixOf and PrefixOf expression simplifications
88+
* */
89+
90+
/** Simplifies string suffix checking expressions
91+
* (str_suffix_of strConst1 strConst2) ==> boolConst */
92+
inline fun KContext.simplifyStringBasicSuffixOfExpr(
93+
arg0: KExpr<KStringSort>,
94+
arg1: KExpr<KStringSort>,
95+
cont: (KExpr<KStringSort>, KExpr<KStringSort>) -> KExpr<KBoolSort>
96+
): KExpr<KBoolSort> =
97+
tryEvalStringLiteralOperation(arg0, arg1, { a0, a1 -> StringUtils.isStringSuffix(a0, a1) }) {
98+
cont(arg0, arg1)
99+
}
100+
101+
/** Simplifies string prefix checking expressions
102+
* (str_prefix_of strConst1 strConst2) ==> boolConst */
103+
inline fun KContext.simplifyStringBasicPrefixOfExpr(
104+
arg0: KExpr<KStringSort>,
105+
arg1: KExpr<KStringSort>,
106+
cont: (KExpr<KStringSort>, KExpr<KStringSort>) -> KExpr<KBoolSort>
107+
): KExpr<KBoolSort> =
108+
tryEvalStringLiteralOperation(arg0, arg1, { a0, a1 -> StringUtils.isStringPrefix(a0, a1) }) {
109+
cont(arg0, arg1)
110+
}
111+
83112
inline fun <K : KSort> tryEvalStringLiteralOperation(
84113
arg: KExpr<KStringSort>,
85114
operation: (KStringLiteralExpr) -> KInterpretedValue<K>,
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
package io.ksmt.utils
22

3+
import io.ksmt.expr.KInterpretedValue
34
import io.ksmt.expr.KStringLiteralExpr
5+
import io.ksmt.sort.KBoolSort
46

57
object StringUtils {
68

79
@JvmStatic
810
fun concatStrings(lhs: KStringLiteralExpr, rhs: KStringLiteralExpr): KStringLiteralExpr = with (lhs.ctx) {
911
mkStringLiteral(lhs.value + rhs.value)
1012
}
13+
14+
@JvmStatic
15+
fun isStringSuffix(arg0: KStringLiteralExpr, arg1: KStringLiteralExpr): KInterpretedValue<KBoolSort> = with (arg0.ctx) {
16+
mkBool(arg1.value.endsWith(arg0.value)).uncheckedCast()
17+
}
18+
19+
@JvmStatic
20+
fun isStringPrefix(arg0: KStringLiteralExpr, arg1: KStringLiteralExpr): KInterpretedValue<KBoolSort> = with (arg0.ctx) {
21+
mkBool(arg1.value.startsWith(arg0.value)).uncheckedCast()
22+
}
1123
}

0 commit comments

Comments
 (0)