2021-04-12 12:31:43 -07:00
|
|
|
/******************************************************************************
|
|
|
|
|
* Top contributors (to current version):
|
2022-04-05 13:38:57 -07:00
|
|
|
* Mudathir Mohamed, Gereon Kremer, Andres Noetzli
|
2021-04-12 12:31:43 -07:00
|
|
|
*
|
|
|
|
|
* This file is part of the cvc5 project.
|
|
|
|
|
*
|
2022-04-05 13:38:57 -07:00
|
|
|
* Copyright (c) 2009-2022 by the authors listed in the file AUTHORS
|
2021-04-12 12:31:43 -07:00
|
|
|
* in the top-level source directory and their institutional affiliations.
|
|
|
|
|
* All rights reserved. See the file COPYING in the top-level source
|
|
|
|
|
* directory for licensing information.
|
|
|
|
|
* ****************************************************************************
|
|
|
|
|
*
|
2021-11-16 12:13:19 -06:00
|
|
|
* An example of accessing cvc5's statistics using the Java API.
|
2021-04-12 12:31:43 -07:00
|
|
|
*/
|
2019-05-16 00:18:48 +00:00
|
|
|
|
2022-03-30 21:09:03 -07:00
|
|
|
import static io.github.cvc5.Kind.*;
|
2019-05-16 00:18:48 +00:00
|
|
|
|
2022-03-30 21:09:03 -07:00
|
|
|
import io.github.cvc5.*;
|
2021-10-01 18:21:02 -05:00
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
2019-05-16 00:18:48 +00:00
|
|
|
|
2021-10-01 18:21:02 -05:00
|
|
|
public class Statistics
|
|
|
|
|
{
|
|
|
|
|
public static void main(String[] args)
|
|
|
|
|
{
|
2022-10-04 12:06:02 -05:00
|
|
|
Solver solver = new Solver();
|
2021-10-01 18:21:02 -05:00
|
|
|
{
|
2021-11-03 16:32:10 -05:00
|
|
|
// Get the statistics from the `Solver` and iterate over them. The
|
|
|
|
|
// `Statistics` class implements the `Iterable<Pair<String, Stat>>` interface.
|
2022-03-30 21:09:03 -07:00
|
|
|
io.github.cvc5.Statistics stats = solver.getStatistics();
|
2021-11-03 16:32:10 -05:00
|
|
|
// short version
|
|
|
|
|
System.out.println("Short version:");
|
|
|
|
|
System.out.println(stats);
|
|
|
|
|
|
|
|
|
|
System.out.println("-------------------------------------------------------");
|
|
|
|
|
|
|
|
|
|
System.out.println("Long version:");
|
|
|
|
|
|
|
|
|
|
// long version
|
2022-03-23 23:59:23 +01:00
|
|
|
for (Map.Entry<String, Stat> pair : stats)
|
2021-10-01 18:21:02 -05:00
|
|
|
{
|
2022-03-23 23:59:23 +01:00
|
|
|
Stat stat = pair.getValue();
|
2021-11-03 16:32:10 -05:00
|
|
|
if (stat.isInt())
|
2021-10-01 18:21:02 -05:00
|
|
|
{
|
2022-03-23 23:59:23 +01:00
|
|
|
System.out.println(pair.getKey() + " = " + stat.getInt());
|
2021-11-03 16:32:10 -05:00
|
|
|
}
|
|
|
|
|
else if (stat.isDouble())
|
|
|
|
|
{
|
2022-03-23 23:59:23 +01:00
|
|
|
System.out.println(pair.getKey() + " = " + stat.getDouble());
|
2021-11-03 16:32:10 -05:00
|
|
|
}
|
|
|
|
|
else if (stat.isString())
|
|
|
|
|
{
|
2022-03-23 23:59:23 +01:00
|
|
|
System.out.println(pair.getKey() + " = " + stat.getString());
|
2021-11-03 16:32:10 -05:00
|
|
|
}
|
|
|
|
|
else if (stat.isHistogram())
|
|
|
|
|
{
|
|
|
|
|
System.out.println("-------------------------------------------------------");
|
2022-03-23 23:59:23 +01:00
|
|
|
System.out.println(pair.getKey() + " : Map");
|
2021-11-03 16:32:10 -05:00
|
|
|
for (Map.Entry<String, Long> entry : stat.getHistogram().entrySet())
|
|
|
|
|
{
|
|
|
|
|
System.out.println(entry.getKey() + " = " + entry.getValue());
|
|
|
|
|
}
|
|
|
|
|
System.out.println("-------------------------------------------------------");
|
2021-10-01 18:21:02 -05:00
|
|
|
}
|
|
|
|
|
}
|
2019-05-16 00:18:48 +00:00
|
|
|
}
|
|
|
|
|
}
|
2021-10-01 18:21:02 -05:00
|
|
|
|
|
|
|
|
private static Solver getSolver()
|
|
|
|
|
{
|
|
|
|
|
Solver solver = new Solver();
|
|
|
|
|
|
|
|
|
|
// String type
|
|
|
|
|
Sort string = solver.getStringSort();
|
|
|
|
|
|
|
|
|
|
// std::string
|
|
|
|
|
String str_ab = "ab";
|
|
|
|
|
// String constants
|
|
|
|
|
Term ab = solver.mkString(str_ab);
|
|
|
|
|
Term abc = solver.mkString("abc");
|
|
|
|
|
// String variables
|
|
|
|
|
Term x = solver.mkConst(string, "x");
|
|
|
|
|
Term y = solver.mkConst(string, "y");
|
|
|
|
|
Term z = solver.mkConst(string, "z");
|
|
|
|
|
|
|
|
|
|
// String concatenation: x.ab.y
|
|
|
|
|
Term lhs = solver.mkTerm(STRING_CONCAT, x, ab, y);
|
|
|
|
|
// String concatenation: abc.z
|
|
|
|
|
Term rhs = solver.mkTerm(STRING_CONCAT, abc, z);
|
|
|
|
|
// x.ab.y = abc.z
|
|
|
|
|
Term formula1 = solver.mkTerm(EQUAL, lhs, rhs);
|
|
|
|
|
|
|
|
|
|
// Length of y: |y|
|
|
|
|
|
Term leny = solver.mkTerm(STRING_LENGTH, y);
|
|
|
|
|
// |y| >= 0
|
|
|
|
|
Term formula2 = solver.mkTerm(GEQ, leny, solver.mkInteger(0));
|
|
|
|
|
|
|
|
|
|
// Regular expression: (ab[c-e]*f)|g|h
|
|
|
|
|
Term r = solver.mkTerm(REGEXP_UNION,
|
|
|
|
|
solver.mkTerm(REGEXP_CONCAT,
|
|
|
|
|
solver.mkTerm(STRING_TO_REGEXP, solver.mkString("ab")),
|
|
|
|
|
solver.mkTerm(REGEXP_STAR,
|
|
|
|
|
solver.mkTerm(REGEXP_RANGE, solver.mkString("c"), solver.mkString("e"))),
|
|
|
|
|
solver.mkTerm(STRING_TO_REGEXP, solver.mkString("f"))),
|
|
|
|
|
solver.mkTerm(STRING_TO_REGEXP, solver.mkString("g")),
|
|
|
|
|
solver.mkTerm(STRING_TO_REGEXP, solver.mkString("h")));
|
|
|
|
|
|
|
|
|
|
// String variables
|
|
|
|
|
Term s1 = solver.mkConst(string, "s1");
|
|
|
|
|
Term s2 = solver.mkConst(string, "s2");
|
|
|
|
|
// String concatenation: s1.s2
|
|
|
|
|
Term s = solver.mkTerm(STRING_CONCAT, s1, s2);
|
|
|
|
|
|
|
|
|
|
// s1.s2 in (ab[c-e]*f)|g|h
|
|
|
|
|
Term formula3 = solver.mkTerm(STRING_IN_REGEXP, s, r);
|
|
|
|
|
|
|
|
|
|
// Make a query
|
|
|
|
|
Term q = solver.mkTerm(AND, formula1, formula2, formula3);
|
|
|
|
|
|
|
|
|
|
// options
|
|
|
|
|
solver.setOption("produce-models", "true");
|
|
|
|
|
solver.setOption("finite-model-find", "true");
|
|
|
|
|
solver.setOption("sets-ext", "true");
|
|
|
|
|
solver.setOption("output-language", "smt2");
|
|
|
|
|
|
|
|
|
|
// (declare-sort Person 0)
|
|
|
|
|
Sort personSort = solver.mkUninterpretedSort("Person");
|
|
|
|
|
|
|
|
|
|
// (Tuple Person)
|
|
|
|
|
Sort tupleArity1 = solver.mkTupleSort(new Sort[] {personSort});
|
2022-04-13 13:54:27 -05:00
|
|
|
// (Relation Person)
|
2021-10-01 18:21:02 -05:00
|
|
|
Sort relationArity1 = solver.mkSetSort(tupleArity1);
|
|
|
|
|
|
|
|
|
|
// (Tuple Person Person)
|
|
|
|
|
Sort tupleArity2 = solver.mkTupleSort(new Sort[] {personSort, personSort});
|
2022-04-13 13:54:27 -05:00
|
|
|
// (Relation Person Person)
|
2021-10-01 18:21:02 -05:00
|
|
|
Sort relationArity2 = solver.mkSetSort(tupleArity2);
|
|
|
|
|
|
|
|
|
|
// empty set
|
|
|
|
|
Term emptySetTerm = solver.mkEmptySet(relationArity1);
|
|
|
|
|
|
|
|
|
|
// empty relation
|
|
|
|
|
Term emptyRelationTerm = solver.mkEmptySet(relationArity2);
|
|
|
|
|
|
|
|
|
|
// universe set
|
|
|
|
|
Term universeSet = solver.mkUniverseSet(relationArity1);
|
|
|
|
|
|
|
|
|
|
// variables
|
|
|
|
|
Term people = solver.mkConst(relationArity1, "people");
|
|
|
|
|
Term males = solver.mkConst(relationArity1, "males");
|
|
|
|
|
Term females = solver.mkConst(relationArity1, "females");
|
|
|
|
|
Term father = solver.mkConst(relationArity2, "father");
|
|
|
|
|
Term mother = solver.mkConst(relationArity2, "mother");
|
|
|
|
|
Term parent = solver.mkConst(relationArity2, "parent");
|
|
|
|
|
Term ancestor = solver.mkConst(relationArity2, "ancestor");
|
|
|
|
|
Term descendant = solver.mkConst(relationArity2, "descendant");
|
|
|
|
|
|
|
|
|
|
Term isEmpty1 = solver.mkTerm(EQUAL, males, emptySetTerm);
|
|
|
|
|
Term isEmpty2 = solver.mkTerm(EQUAL, females, emptySetTerm);
|
|
|
|
|
|
2022-04-13 13:54:27 -05:00
|
|
|
// (assert (= people (as set.universe (Relation Person))))
|
2021-10-01 18:21:02 -05:00
|
|
|
Term peopleAreTheUniverse = solver.mkTerm(EQUAL, people, universeSet);
|
2022-04-13 13:54:27 -05:00
|
|
|
// (assert (not (= males (as set.empty (Relation Person)))))
|
2021-10-01 18:21:02 -05:00
|
|
|
Term maleSetIsNotEmpty = solver.mkTerm(NOT, isEmpty1);
|
2022-04-13 13:54:27 -05:00
|
|
|
// (assert (not (= females (as set.empty (Relation Person)))))
|
2021-10-01 18:21:02 -05:00
|
|
|
Term femaleSetIsNotEmpty = solver.mkTerm(NOT, isEmpty2);
|
|
|
|
|
|
2021-11-16 12:13:19 -06:00
|
|
|
// (assert (= (set.inter males females) (as set.empty (Set (Tuple
|
2021-10-01 18:21:02 -05:00
|
|
|
// Person)))))
|
2021-11-16 12:13:19 -06:00
|
|
|
Term malesFemalesIntersection = solver.mkTerm(SET_INTER, males, females);
|
2021-10-01 18:21:02 -05:00
|
|
|
Term malesAndFemalesAreDisjoint = solver.mkTerm(EQUAL, malesFemalesIntersection, emptySetTerm);
|
|
|
|
|
|
2022-04-13 13:54:27 -05:00
|
|
|
// (assert (not (= father (as set.empty (Relation Person Person)))))
|
|
|
|
|
// (assert (not (= mother (as set.empty (Relation Person Person)))))
|
2021-10-01 18:21:02 -05:00
|
|
|
Term isEmpty3 = solver.mkTerm(EQUAL, father, emptyRelationTerm);
|
|
|
|
|
Term isEmpty4 = solver.mkTerm(EQUAL, mother, emptyRelationTerm);
|
|
|
|
|
Term fatherIsNotEmpty = solver.mkTerm(NOT, isEmpty3);
|
|
|
|
|
Term motherIsNotEmpty = solver.mkTerm(NOT, isEmpty4);
|
|
|
|
|
|
|
|
|
|
// fathers are males
|
2021-11-16 12:13:19 -06:00
|
|
|
// (assert (set.subset (rel.join father people) males))
|
|
|
|
|
Term fathers = solver.mkTerm(RELATION_JOIN, father, people);
|
|
|
|
|
Term fathersAreMales = solver.mkTerm(SET_SUBSET, fathers, males);
|
2021-10-01 18:21:02 -05:00
|
|
|
|
|
|
|
|
// mothers are females
|
2021-11-16 12:13:19 -06:00
|
|
|
// (assert (set.subset (rel.join mother people) females))
|
|
|
|
|
Term mothers = solver.mkTerm(RELATION_JOIN, mother, people);
|
|
|
|
|
Term mothersAreFemales = solver.mkTerm(SET_SUBSET, mothers, females);
|
2021-10-01 18:21:02 -05:00
|
|
|
|
2021-11-16 12:13:19 -06:00
|
|
|
// (assert (= parent (set.union father mother)))
|
|
|
|
|
Term unionFatherMother = solver.mkTerm(SET_UNION, father, mother);
|
2021-10-01 18:21:02 -05:00
|
|
|
Term parentIsFatherOrMother = solver.mkTerm(EQUAL, parent, unionFatherMother);
|
|
|
|
|
|
2021-11-16 12:13:19 -06:00
|
|
|
// (assert (= descendant (rel.tclosure parent)))
|
|
|
|
|
Term transitiveClosure = solver.mkTerm(RELATION_TCLOSURE, parent);
|
2021-10-01 18:21:02 -05:00
|
|
|
Term descendantFormula = solver.mkTerm(EQUAL, descendant, transitiveClosure);
|
|
|
|
|
|
2021-11-16 12:13:19 -06:00
|
|
|
// (assert (= ancestor (rel.transpose descendant)))
|
|
|
|
|
Term transpose = solver.mkTerm(RELATION_TRANSPOSE, descendant);
|
2021-10-01 18:21:02 -05:00
|
|
|
Term ancestorFormula = solver.mkTerm(EQUAL, ancestor, transpose);
|
|
|
|
|
|
2021-11-16 12:13:19 -06:00
|
|
|
// (assert (forall ((x Person)) (not (set.member (mkTuple x x) ancestor))))
|
2021-10-01 18:21:02 -05:00
|
|
|
Term var = solver.mkVar(personSort, "x");
|
|
|
|
|
DatatypeConstructor constructor = tupleArity2.getDatatype().getConstructor(0);
|
2022-04-02 11:57:50 -07:00
|
|
|
Term xxTuple = solver.mkTerm(APPLY_CONSTRUCTOR, constructor.getTerm(), var, var);
|
2021-11-16 12:13:19 -06:00
|
|
|
Term member = solver.mkTerm(SET_MEMBER, xxTuple, ancestor);
|
2021-10-01 18:21:02 -05:00
|
|
|
Term notMember = solver.mkTerm(NOT, member);
|
|
|
|
|
|
2021-11-15 08:10:26 -08:00
|
|
|
Term quantifiedVariables = solver.mkTerm(VARIABLE_LIST, var);
|
2021-10-01 18:21:02 -05:00
|
|
|
Term noSelfAncestor = solver.mkTerm(FORALL, quantifiedVariables, notMember);
|
|
|
|
|
|
|
|
|
|
// formulas
|
|
|
|
|
solver.assertFormula(peopleAreTheUniverse);
|
|
|
|
|
solver.assertFormula(maleSetIsNotEmpty);
|
|
|
|
|
solver.assertFormula(femaleSetIsNotEmpty);
|
|
|
|
|
solver.assertFormula(malesAndFemalesAreDisjoint);
|
|
|
|
|
solver.assertFormula(fatherIsNotEmpty);
|
|
|
|
|
solver.assertFormula(motherIsNotEmpty);
|
|
|
|
|
solver.assertFormula(fathersAreMales);
|
|
|
|
|
solver.assertFormula(mothersAreFemales);
|
|
|
|
|
solver.assertFormula(parentIsFatherOrMother);
|
|
|
|
|
solver.assertFormula(descendantFormula);
|
|
|
|
|
solver.assertFormula(ancestorFormula);
|
|
|
|
|
solver.assertFormula(noSelfAncestor);
|
|
|
|
|
|
|
|
|
|
// check sat
|
|
|
|
|
solver.checkSatAssuming(q);
|
|
|
|
|
|
|
|
|
|
return solver;
|
|
|
|
|
}
|
2019-05-16 00:18:48 +00:00
|
|
|
}
|