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

Add support for Strings and Rationals to the Princess backend #391

Open
wants to merge 107 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 95 commits
Commits
Show all changes
107 commits
Select commit Hold shift + click to select a range
ccc281a
Start working on string theory for Princess
serras Dec 6, 2021
1f7be15
Rationals in Princess
serras Dec 6, 2021
99337b7
formatting code.
kfriedberger Dec 15, 2021
625a0b6
Merge remote-tracking branch 'origin/master' into 'serras/master'
kfriedberger Dec 15, 2021
b7bbc3c
Princess: revert from Scala 2.13 to Scala 2.12.
kfriedberger Dec 15, 2021
53a1885
adding dependency for Ostrich into JavaSMT.
kfriedberger Dec 16, 2021
6f62e05
Use Ostrich for strings
serras Dec 16, 2021
d59e56c
Do not use 'floor' for rationals in Princess
serras Dec 16, 2021
adaa89c
add Ostrich library into IntelliJ config.
kfriedberger Jan 14, 2022
27faaa7
formatting and smaller cleanup
kfriedberger Jan 14, 2022
f8b0c3d
Princess: allow FLOOR for plain Integer theory.
kfriedberger Jan 14, 2022
5df33fe
Princess: improve MULT and DIV for Rationals.
kfriedberger Jan 14, 2022
9a7e920
Princess: improve support and model evaluation for Rationals.
kfriedberger Jan 14, 2022
451b0f3
Princess: fix for last commit.
kfriedberger Jan 14, 2022
3aaf54b
small update on internal documentation.
kfriedberger Jan 16, 2022
34b71ed
update copyright notice for IntelliJ.
kfriedberger Jan 16, 2022
0ad41d3
Princess/Ostrich: add Automaton library into IntelliJ module-/classpath.
kfriedberger Jan 16, 2022
e9707d1
Princess: improve support for string values in the model.
kfriedberger Jan 16, 2022
f7f9da5
adding improved model test for Real theory with formula evaluation.
kfriedberger Jan 16, 2022
53c0b4b
Merge remote-tracking branch 'origin/master' into HEAD
kfriedberger Nov 12, 2023
ebe926f
change Scala from 2.12 to 2.13
kfriedberger Nov 18, 2023
8b906ec
OpenSMT: exclude OpenSMT from some rational-based tests.
kfriedberger Nov 19, 2023
1936c40
improve precondition checks non formula-creation and make them more v…
kfriedberger Nov 19, 2023
dac5ac4
Princess: fix Checkstyle warnings and rename method for better docume…
kfriedberger Nov 19, 2023
2df018b
Princess: disable some tests for formula structure with rational/real…
kfriedberger Nov 19, 2023
449a87c
Princess: fix UF application on non-rational arguments like integers.
kfriedberger Nov 19, 2023
2eb9dbf
Princess: move utility method to one place.
kfriedberger Nov 19, 2023
4871bdc
Princess: exclude Princess from division-by-zero-tests.
kfriedberger Nov 19, 2023
4652de9
Princess: improve tests on nested arrays.
kfriedberger Nov 19, 2023
2dde64b
Princess: fix model-evaluation for integral rationals.
kfriedberger Nov 19, 2023
8c9f2b8
Princess: improve string-theory.
kfriedberger Nov 19, 2023
d680735
fix Compiler warning for ambiguous type usage.
kfriedberger Nov 19, 2023
a40f42a
Princess: improve visitation of constant rational and string-based te…
kfriedberger Nov 19, 2023
13c01a6
Princess: improve visitation of string operation STR_LE.
kfriedberger Nov 19, 2023
ec6ebaf
Merge branch 'master' into 257-more-theories-for-princess
daniel-raffler Sep 6, 2024
262bb96
Princess: Fetch Ostrich 1.3.5 from Maven. This is a temporary fix tha…
daniel-raffler Sep 6, 2024
b503024
Princess: Disable two tests in StringFormulaManagerTest that will tim…
daniel-raffler Sep 6, 2024
3175cf1
Princess: Add missing dependencies for parsing
daniel-raffler Sep 7, 2024
0210289
Princess: Fix StringFormulaManager.concat(..) when there are more tha…
daniel-raffler Sep 7, 2024
29d25c3
Princess: Disable String test that use (escaped) Unicode literals. Pr…
daniel-raffler Sep 7, 2024
85ebb3d
Princess: Use str.< to define PrincessStringFormulaManager.lessThan d…
daniel-raffler Sep 7, 2024
f99740d
Princess: Add a native test class for Princess to help with debugging
daniel-raffler Sep 7, 2024
8eee565
Princess: Fix two issues from earlier commits
daniel-raffler Sep 7, 2024
abc11e5
Princess: Replace "a str.<= b" with "a str.< b | a == b" to work arou…
daniel-raffler Sep 7, 2024
1610229
Princess: Added native tests for str.contains
daniel-raffler Sep 7, 2024
076d626
Princess: Added more native tests
daniel-raffler Sep 7, 2024
5df2ce6
Princess: Fix handling of unicode escape sequences
daniel-raffler Sep 7, 2024
9c6ca0e
Princess: Avoid using Scala Seq in PrincessStringFormulaManager to av…
daniel-raffler Sep 8, 2024
c546357
Princess: Rewrite a line of code to avoid CI complaints
daniel-raffler Sep 8, 2024
7767d2a
Princess: Add a missing dot
daniel-raffler Sep 8, 2024
51bec64
Princess: Add test cases from the bug reports written by @kfriedberge…
daniel-raffler Sep 8, 2024
fd9ae85
Princess: Moved a comment to the right test
daniel-raffler Sep 9, 2024
0ea532a
Princess: Add missing assertions for the tests
daniel-raffler Sep 10, 2024
9f4d16c
Princess: Add workarounds for the broken rational theory tests
daniel-raffler Sep 10, 2024
c89c6ac
Princess: Disable a test in ArrayFormulaManagerTest for Princess. The…
daniel-raffler Sep 10, 2024
a65769c
Princess: Clean up code in PrincessNativeAPITest
daniel-raffler Sep 10, 2024
47def53
Princess: Removed default arguments for OFlags in PrincessNativeAPITe…
daniel-raffler Sep 10, 2024
96c4d61
Princess: Disable a test in SolverTheoriesTest that uses rational num…
daniel-raffler Sep 10, 2024
296d8e4
Princess: Renamed list of (non-boolean) variables in PrincessAbstract…
daniel-raffler Sep 10, 2024
5b77984
Princess: Add a workaround to evaluate rational formulas with Princes…
daniel-raffler Sep 10, 2024
da11b8f
Princess: Remove unnecessary parenthesis
daniel-raffler Sep 11, 2024
0ea2941
Princess: Fix some bugs from 5b7798454aa0f7708be85770dc7030a18b2a237c
daniel-raffler Sep 11, 2024
6eb0f67
Princess: Fix two more bugs
daniel-raffler Sep 11, 2024
f5dffee
Princess: Remove an unnecessary cast
daniel-raffler Sep 11, 2024
30c1fe7
Princess: Fix format
daniel-raffler Sep 11, 2024
9569292
Princess: Disable all tests that require use operations with only non…
daniel-raffler Sep 11, 2024
f843131
Princess: Re-enable testStringPrefixSuffix from StringFormulaManagerT…
daniel-raffler Sep 11, 2024
76efd95
Princess: Re-enable native prefixSuffixTest in PrincessNativeAPITest.…
daniel-raffler Sep 11, 2024
f661c10
Princess: Fix makeNumberImpl for integer arguments
daniel-raffler Sep 11, 2024
2e570a2
Princess: Removed `Rational.int` and `Rational.frac` from the list of…
daniel-raffler Sep 11, 2024
d761b17
Princess: Add a case for (IFunApp "true" []) in convertValue
daniel-raffler Sep 11, 2024
2d7df5f
Princess: Fix handling of if-then-else expressions in getFormulaType
daniel-raffler Sep 11, 2024
3bc04a8
Princess: Disable term abbreviations as they seem to cause Princess t…
daniel-raffler Sep 12, 2024
2c06c70
Princess: Remove parameters 14 and 15 for the OFlags constructor. Tho…
daniel-raffler Sep 12, 2024
c83063e
Princess: Remove workaround for a bug in Ostrich. The str.<= operatio…
daniel-raffler Sep 12, 2024
a1764de
Princess: Added a note about rational values in the model
daniel-raffler Sep 12, 2024
3b7229a
Princess: Fix evalImpl() for formulas that are equations over rationa…
daniel-raffler Sep 12, 2024
4c78733
Merge remote-tracking branch 'origin/master' into 257-more-theories-f…
daniel-raffler Sep 12, 2024
2636f5e
Princess: Added a todo
daniel-raffler Sep 12, 2024
1e8176f
Princess: Remove the native API test
daniel-raffler Sep 12, 2024
3e1dad8
Princess: Cleaned up some function names
daniel-raffler Sep 13, 2024
bbf9b9c
Princess: Added a todo
daniel-raffler Sep 13, 2024
e950269
Princess: Added missing dots for checkstyle
daniel-raffler Sep 13, 2024
872944f
Princess: Fix visitors for rational values
daniel-raffler Sep 13, 2024
c161f00
Princess: Resolve checkstyle issues
daniel-raffler Sep 15, 2024
f3a277e
Revert "Princess: Fix evalImpl() for formulas that are equations over…
daniel-raffler Sep 15, 2024
c2b685b
Princess: Move comments to their own if-then-else branch
daniel-raffler Sep 16, 2024
6beb6f5
Princess: Fix PrincessRationalFormulaManager.makeNumberImpl() for int…
daniel-raffler Sep 16, 2024
9e1d69d
Princess: Renamed IntegerFormulaManager in PrincessRationalFormulaMan…
daniel-raffler Sep 16, 2024
ea21421
Princess: Work around a bug in princess where multiplying a rational …
daniel-raffler Sep 16, 2024
6351613
Princess: Enabled tests for arrays with rational indices/elements. Th…
daniel-raffler Sep 18, 2024
6fc4b9a
Princess: Add two comments about failed tests in FomulaClassifierTest…
daniel-raffler Sep 18, 2024
43c2c83
Princess: Added a comment to testDivisionByZero test. Princess does s…
daniel-raffler Sep 18, 2024
3b6102d
Princess: Fix evaluation of (boolean) formulas
daniel-raffler Sep 18, 2024
fa38940
Revert "Princess: Disable term abbreviations as they seem to cause Pr…
daniel-raffler Sep 21, 2024
e075090
Princess: Clean up dependencies and prepare for upgrading Princess/Os…
daniel-raffler Oct 16, 2024
ce2e7f9
Princess: Add a comment about the default values for OFlags
daniel-raffler Oct 16, 2024
52fd628
Princess: Throw and UnsupportedOperationExcpetion in PrincessRational…
daniel-raffler Oct 16, 2024
98e49f7
Princess: Remove a duplicate requireRationalFloor()
daniel-raffler Oct 16, 2024
bcb696d
Princess: Add unit tests for PrincessStringFormulaManager.unescapeString
daniel-raffler Oct 19, 2024
9320257
Princess: Fix handling of broken Unicode sequences "\\u{" with no clo…
daniel-raffler Oct 19, 2024
3648bf0
Princess: Throw an exception in PrincessStringFormulaManager.unescape…
daniel-raffler Oct 19, 2024
441e947
Princess: Fix spelling
daniel-raffler Oct 19, 2024
0e949d7
Princess: Skip internal variable "Rat_denom" when generating the model
daniel-raffler Oct 19, 2024
ba486a5
Princess: Removed an outdated note
daniel-raffler Oct 20, 2024
21abead
Princess: Stopped using the partial model for Model.evaluate()
daniel-raffler Oct 20, 2024
5cfbef7
Solved a concurrent modification issues in AbstractProver when models…
daniel-raffler Oct 20, 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
4 changes: 4 additions & 0 deletions .classpath
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,10 @@ SPDX-License-Identifier: Apache-2.0
<classpathentry kind="lib" path="lib/java/runtime-princess/scala-library.jar"/>
<classpathentry kind="lib" path="lib/java/runtime-princess/princess-smt-parser_2.13.jar"/>
<classpathentry kind="lib" path="lib/java/runtime-princess/java-cup-runtime.jar"/>
<classpathentry kind="lib" path="lib/java/runtime-princess/automaton.jar"/>
<classpathentry kind="lib" path="lib/java/runtime-princess/org.sat4j.core.jar"/>
<classpathentry kind="lib" path="lib/java/runtime-princess/ostrich_2.13.jar"/>
<classpathentry kind="lib" path="lib/java/runtime-princess/ostrich-ecma2020-parser_2.13.jar"/>
<classpathentry kind="lib" path="lib/java/runtime-z3/com.microsoft.z3.jar" sourcepath="lib/java-contrib/com.microsoft.z3-sources.jar"/>
<classpathentry kind="lib" path="lib/java/runtime-cvc4/CVC4.jar"/>
<classpathentry kind="lib" path="lib/java/runtime-cvc5/cvc5.jar"/>
Expand Down
18 changes: 18 additions & 0 deletions .idea/JavaSMT.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 11 additions & 5 deletions build/ivysettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,20 @@ SPDX-License-Identifier: Apache-2.0
Keep this file synchronized with
https://gitlab.com/sosy-lab/software/java-project-template
-->
<settings defaultResolver="Sosy-Lab"/>
<settings defaultResolver="Repos"/>
<property name="repo.dir" value="${basedir}/repository"/>
<resolvers>
<!-- Resolver for downloading dependencies -->
<url name="Sosy-Lab" descriptor="required">
<ivy pattern="${ivy.repo.url}/[organisation]/[module]/ivy-[revision].xml" />
<artifact pattern="${ivy.repo.url}/[organisation]/[module]/[artifact]-[revision](-[classifier]).[ext]" />
</url>
<chain name="Repos">
<url name="Sosy-Lab">
<ivy pattern="${ivy.repo.url}/[organisation]/[module]/ivy-[revision].xml"/>
<artifact pattern="${ivy.repo.url}/[organisation]/[module]/[artifact]-[revision](-[classifier]).[ext]"/>
</url>
<url name="Maven-Repo" m2compatible="true">
<ivy pattern="https://repo1.maven.org/maven2/[organisation]/[module]/ivy-[revision].xml"/>
<artifact pattern="https://repo1.maven.org/maven2/[organisation]/[module]/[revision]/[artifact]-[revision].[ext]"/>
</url>
</chain>

<!-- Resolver for publishing this project -->
<filesystem name="Sosy-Lab-Publish">
Expand Down
18 changes: 14 additions & 4 deletions lib/ivy.xml
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ SPDX-License-Identifier: Apache-2.0
<dependency org="org.apache.ivy" name="ivy" rev="${ivy.target_version}" conf="build->default"/>

<!-- Google Auto-Value
Library for auto-generating value types. --><dependency org="com.google.auto.value" name="auto-value" rev="1.11.0" conf="build->default"/>
Library for auto-generating value types. -->
<dependency org="com.google.auto.value" name="auto-value" rev="1.11.0" conf="build->default"/>
<dependency org="com.google.auto.value" name="auto-value-annotations" rev="1.11.0" conf="build->default; contrib->sources"/>

<!-- Annotations we use for @Nullable etc. -->
Expand Down Expand Up @@ -149,9 +150,18 @@ SPDX-License-Identifier: Apache-2.0
<dependency org="de.uni-freiburg.informatik.ultimate" name="smtinterpol" rev="2.5-1242-g5c50fb6d" conf="runtime-smtinterpol->master; contrib->sources"/>

<!-- Princess for our Maven release -->
<dependency org="io.github.uuverifiers" name="princess_2.13" rev="2024-01-12" conf="runtime-princess-with-javacup->default; contrib->sources"/>
<!-- Princess for our Ivy release-->
<dependency org="io.github.uuverifiers" name="princess_2.13" rev="2024-01-12" conf="runtime-princess->default; contrib->sources">
<dependency org="io.github.uuverifiers" name="princess_2.13" rev="2024-03-22" conf="runtime-princess-with-javacup->default" />

<!-- Princess and Ostrich for our Ivy release -->
<dependency org="org.scala-lang" name="scala-library" rev="2.13.8" conf="runtime-princess->default"/>
<dependency org="io.github.uuverifiers" name="princess-parser_2.13" rev="2024-03-22" conf="runtime-princess->default"/>
<dependency org="io.github.uuverifiers" name="princess-smt-parser_2.13" rev="2024-03-22"/>
<dependency org="io.github.uuverifiers" name="princess_2.13" rev="2024-03-22" conf="runtime-princess->default"/>
<dependency org="org.sat4j" name="org.sat4j.core" rev="2.3.1" conf="runtime-princess->default"/>
<dependency org="org.scalacheck" name="scalacheck_2.13" rev="1.14.0" conf="runtime-princess->default"/>
<dependency org="dk.brics.automaton" name="automaton" rev="1.11-8" conf="runtime-princess->default"/>
<dependency org="io.github.uuverifiers" name="ostrich-ecma2020-parser_2.13" rev="1.3" conf="runtime-princess->default"/>
<dependency org="io.github.uuverifiers" name="ostrich_2.13" rev="1.3.5" conf="runtime-princess->default">
<!-- Exclude dependency on java-cup and replace it with java-cup-runtime, which is enough.
We use the JAR that is published by us instead of the one from net.sf.squirrel-sql.thirdparty-non-maven
because the latter does not provide a separate JAR for java-cup-runtime. -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ protected final FormulaCreator<TFormulaInfo, TType, TEnv, TFuncDecl> getFormulaC
return formulaCreator;
}

final TFormulaInfo extractInfo(Formula pBits) {
protected final TFormulaInfo extractInfo(Formula pBits) {
return getFormulaCreator().extractInfo(pBits);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,11 @@ protected AbstractStringFormulaManager(
super(pCreator);
}

private StringFormula wrapString(TFormulaInfo formulaInfo) {
protected StringFormula wrapString(TFormulaInfo formulaInfo) {
return getFormulaCreator().encapsulateString(formulaInfo);
}

private RegexFormula wrapRegex(TFormulaInfo formulaInfo) {
protected RegexFormula wrapRegex(TFormulaInfo formulaInfo) {
return getFormulaCreator().encapsulateRegex(formulaInfo);
}

Expand Down
50 changes: 34 additions & 16 deletions src/org/sosy_lab/java_smt/basicimpl/FormulaCreator.java
Original file line number Diff line number Diff line change
Expand Up @@ -137,43 +137,59 @@ public final TType getRegexType() {
public abstract TFormulaInfo makeVariable(TType type, String varName);

public BooleanFormula encapsulateBoolean(TFormulaInfo pTerm) {
assert getFormulaType(pTerm).isBooleanType();
checkArgument(
getFormulaType(pTerm).isBooleanType(),
"Boolean formula has unexpected type: %s",
getFormulaType(pTerm));
return new BooleanFormulaImpl<>(pTerm);
}

protected BitvectorFormula encapsulateBitvector(TFormulaInfo pTerm) {
assert getFormulaType(pTerm).isBitvectorType();
checkArgument(
getFormulaType(pTerm).isBitvectorType(),
"Bitvector formula has unexpected type: %s",
getFormulaType(pTerm));
return new BitvectorFormulaImpl<>(pTerm);
}

protected FloatingPointFormula encapsulateFloatingPoint(TFormulaInfo pTerm) {
assert getFormulaType(pTerm).isFloatingPointType();
checkArgument(
getFormulaType(pTerm).isFloatingPointType(),
"Floatingpoint formula has unexpected type: %s",
getFormulaType(pTerm));
return new FloatingPointFormulaImpl<>(pTerm);
}

protected <TI extends Formula, TE extends Formula> ArrayFormula<TI, TE> encapsulateArray(
TFormulaInfo pTerm, FormulaType<TI> pIndexType, FormulaType<TE> pElementType) {
assert getFormulaType(pTerm).equals(FormulaType.getArrayType(pIndexType, pElementType))
: "Expected: "
+ getFormulaType(pTerm)
+ " but found: "
+ FormulaType.getArrayType(pIndexType, pElementType);

checkArgument(
getFormulaType(pTerm).equals(FormulaType.getArrayType(pIndexType, pElementType)),
"Array formula has unexpected type: %s",
getFormulaType(pTerm));
return new ArrayFormulaImpl<>(pTerm, pIndexType, pElementType);
}

protected StringFormula encapsulateString(TFormulaInfo pTerm) {
assert getFormulaType(pTerm).isStringType();
checkArgument(
getFormulaType(pTerm).isStringType(),
"String formula has unexpected type: %s",
getFormulaType(pTerm));
return new StringFormulaImpl<>(pTerm);
}

protected RegexFormula encapsulateRegex(TFormulaInfo pTerm) {
assert getFormulaType(pTerm).isRegexType();
checkArgument(
getFormulaType(pTerm).isRegexType(),
"Regex formula has unexpected type: %s",
getFormulaType(pTerm));
return new RegexFormulaImpl<>(pTerm);
}

protected EnumerationFormula encapsulateEnumeration(TFormulaInfo pTerm) {
assert getFormulaType(pTerm).isEnumerationType();
checkArgument(
getFormulaType(pTerm).isEnumerationType(),
"Enumeration formula has unexpected type: %s",
getFormulaType(pTerm));
return new EnumerationFormulaImpl<>(pTerm);
}

Expand All @@ -183,10 +199,12 @@ public Formula encapsulateWithTypeOf(TFormulaInfo pTerm) {

@SuppressWarnings("unchecked")
public <T extends Formula> T encapsulate(FormulaType<T> pType, TFormulaInfo pTerm) {
assert pType.equals(getFormulaType(pTerm))
: String.format(
"Trying to encapsulate formula %s of type %s as %s",
pTerm, getFormulaType(pTerm), pType);
checkArgument(
pType.equals(getFormulaType(pTerm)),
"Trying to encapsulate formula %s of type %s as %s",
pTerm,
getFormulaType(pTerm),
pType);
if (pType.isBooleanType()) {
return (T) new BooleanFormulaImpl<>(pTerm);
} else if (pType.isIntegerType()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ protected void popImpl() {
// we have to recreate symbols on lower levels, because JavaSMT assumes "global" symbols.
Level level = trackingStack.pop();
api.addBooleanVariables(asScala(level.booleanSymbols));
api.addConstants(asScala(level.intSymbols));
api.addConstants(asScala(level.theorySymbols));
level.functionSymbols.forEach(api::addFunction);
if (!trackingStack.isEmpty()) {
trackingStack.peek().mergeWithHigher(level);
Expand Down Expand Up @@ -213,12 +213,12 @@ void addSymbol(IFormula f) {
}
}

/** add external definition: integer variable. */
/** add external definition: theory variable (integer, rational, string, etc). */
void addSymbol(ITerm f) {
Preconditions.checkState(!closed);
api.addConstant(f);
if (!trackingStack.isEmpty()) {
trackingStack.peek().intSymbols.add(f);
trackingStack.peek().theorySymbols.add(f);
}
}

Expand All @@ -233,21 +233,21 @@ void addSymbol(IFunction f) {

static class Level {
final List<IFormula> booleanSymbols = new ArrayList<>();
final List<ITerm> intSymbols = new ArrayList<>();
final List<ITerm> theorySymbols = new ArrayList<>();
final List<IFunction> functionSymbols = new ArrayList<>();

Level() {}

/** add higher level to current level, we keep the order of creating symbols. */
void mergeWithHigher(Level other) {
this.booleanSymbols.addAll(other.booleanSymbols);
this.intSymbols.addAll(other.intSymbols);
this.theorySymbols.addAll(other.theorySymbols);
this.functionSymbols.addAll(other.functionSymbols);
}

@Override
public String toString() {
return String.format("{%s, %s, %s}", booleanSymbols, intSymbols, functionSymbols);
return String.format("{%s, %s, %s}", booleanSymbols, theorySymbols, functionSymbols);
}
}
}
Loading