Files
cvc5/examples/api/java/Relations.java

198 lines
7.6 KiB
Java
Raw Normal View History

/******************************************************************************
* Top contributors (to current version):
* Mudathir Mohamed, Andres Noetzli
*
* This file is part of the cvc5 project.
*
* Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
* 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.
* ****************************************************************************
*
* A simple demonstration of reasoning about relations with CVC4 via Java API.
*/
2020-02-25 11:47:24 -06:00
import static io.github.cvc5.api.Kind.*;
import io.github.cvc5.api.*;
2020-02-25 11:47:24 -06:00
/*
This file uses the API to make a sat call equivalent to the following benchmark:
(set-logic ALL)
(set-option :finite-model-find true)
(set-option :produce-models true)
(set-option :sets-ext true)
(set-option :output-language "smt2")
(declare-sort Person 0)
(declare-fun people () (Set (Tuple Person)))
(declare-fun males () (Set (Tuple Person)))
(declare-fun females() (Set (Tuple Person)))
(declare-fun father () (Set (Tuple Person Person)))
(declare-fun mother () (Set (Tuple Person Person)))
(declare-fun parent () (Set (Tuple Person Person)))
(declare-fun ancestor () (Set (Tuple Person Person)))
(declare-fun descendant () (Set (Tuple Person Person)))
(assert (= people (as univset (Set (Tuple Person)))))
(assert (not (= males (as emptyset (Set (Tuple Person))))))
(assert (not (= females (as emptyset (Set (Tuple Person))))))
(assert (= (intersection males females) (as emptyset (Set (Tuple Person)))))
; father relation is not empty
(assert (not (= father (as emptyset (Set (Tuple Person Person))))))
; mother relation is not empty
(assert (not (= mother (as emptyset (Set (Tuple Person Person))))))
; fathers are males
(assert (subset (join father people) males))
; mothers are females
(assert (subset (join mother people) females))
; parent
(assert (= parent (union father mother)))
; no self ancestor
(assert (forall ((x Person)) (not (member (mkTuple x x) ancestor))))
; descendant
(assert (= descendant (tclosure parent)))
; ancestor
(assert (= ancestor (transpose descendant)))
(check-sat)
(get-model)
*/
public class Relations
{
public static void main(String[] args) throws CVC5ApiException
{
Solver solver = new Solver();
2020-02-25 11:47:24 -06:00
// Set the logic
solver.setLogic("ALL");
2020-02-25 11:47:24 -06:00
// options
solver.setOption("produce-models", "true");
solver.setOption("finite-model-find", "true");
solver.setOption("sets-ext", "true");
solver.setOption("output-language", "smt2");
2020-02-25 11:47:24 -06:00
// (declare-sort Person 0)
Sort personSort = solver.mkUninterpretedSort("Person");
2020-02-25 11:47:24 -06:00
// (Tuple Person)
Sort tupleArity1 = solver.mkTupleSort(new Sort[] {personSort});
2020-02-25 11:47:24 -06:00
// (Set (Tuple Person))
Sort relationArity1 = solver.mkSetSort(tupleArity1);
2020-02-25 11:47:24 -06:00
// (Tuple Person Person)
Sort tupleArity2 = solver.mkTupleSort(new Sort[] {personSort, personSort});
2020-02-25 11:47:24 -06:00
// (Set (Tuple Person Person))
Sort relationArity2 = solver.mkSetSort(tupleArity2);
2020-02-25 11:47:24 -06:00
// empty set
Term emptySetTerm = solver.mkEmptySet(relationArity1);
2020-02-25 11:47:24 -06:00
// empty relation
Term emptyRelationTerm = solver.mkEmptySet(relationArity2);
2020-02-25 11:47:24 -06:00
// universe set
Term universeSet = solver.mkUniverseSet(relationArity1);
2020-02-25 11:47:24 -06:00
// 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");
2020-02-25 11:47:24 -06:00
Term isEmpty1 = solver.mkTerm(EQUAL, males, emptySetTerm);
Term isEmpty2 = solver.mkTerm(EQUAL, females, emptySetTerm);
2020-02-25 11:47:24 -06:00
// (assert (= people (as univset (Set (Tuple Person)))))
Term peopleAreTheUniverse = solver.mkTerm(EQUAL, people, universeSet);
2020-02-25 11:47:24 -06:00
// (assert (not (= males (as emptyset (Set (Tuple Person))))))
Term maleSetIsNotEmpty = solver.mkTerm(NOT, isEmpty1);
2020-02-25 11:47:24 -06:00
// (assert (not (= females (as emptyset (Set (Tuple Person))))))
Term femaleSetIsNotEmpty = solver.mkTerm(NOT, isEmpty2);
2020-02-25 11:47:24 -06:00
// (assert (= (intersection males females) (as emptyset (Set (Tuple
// Person)))))
Term malesFemalesIntersection = solver.mkTerm(INTERSECTION, males, females);
Term malesAndFemalesAreDisjoint = solver.mkTerm(EQUAL, malesFemalesIntersection, emptySetTerm);
2020-02-25 11:47:24 -06:00
// (assert (not (= father (as emptyset (Set (Tuple Person Person))))))
// (assert (not (= mother (as emptyset (Set (Tuple Person Person))))))
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);
2020-02-25 11:47:24 -06:00
// fathers are males
// (assert (subset (join father people) males))
Term fathers = solver.mkTerm(JOIN, father, people);
Term fathersAreMales = solver.mkTerm(SUBSET, fathers, males);
2020-02-25 11:47:24 -06:00
// mothers are females
// (assert (subset (join mother people) females))
Term mothers = solver.mkTerm(JOIN, mother, people);
Term mothersAreFemales = solver.mkTerm(SUBSET, mothers, females);
2020-02-25 11:47:24 -06:00
// (assert (= parent (union father mother)))
Term unionFatherMother = solver.mkTerm(UNION, father, mother);
Term parentIsFatherOrMother = solver.mkTerm(EQUAL, parent, unionFatherMother);
2020-02-25 11:47:24 -06:00
// (assert (= parent (union father mother)))
Term transitiveClosure = solver.mkTerm(TCLOSURE, parent);
Term descendantFormula = solver.mkTerm(EQUAL, descendant, transitiveClosure);
2020-02-25 11:47:24 -06:00
// (assert (= parent (union father mother)))
Term transpose = solver.mkTerm(TRANSPOSE, descendant);
Term ancestorFormula = solver.mkTerm(EQUAL, ancestor, transpose);
2020-02-25 11:47:24 -06:00
// (assert (forall ((x Person)) (not (member (mkTuple x x) ancestor))))
Term x = solver.mkVar(personSort, "x");
DatatypeConstructor constructor = tupleArity2.getDatatype().getConstructor(0);
Term xxTuple = solver.mkTerm(APPLY_CONSTRUCTOR, constructor.getConstructorTerm(), x, x);
Term member = solver.mkTerm(MEMBER, xxTuple, ancestor);
Term notMember = solver.mkTerm(NOT, member);
Term quantifiedVariables = solver.mkTerm(BOUND_VAR_LIST, x);
Term noSelfAncestor = solver.mkTerm(FORALL, quantifiedVariables, notMember);
2020-02-25 11:47:24 -06:00
// 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);
2020-02-25 11:47:24 -06:00
// check sat
Result result = solver.checkSat();
2020-02-25 11:47:24 -06:00
// output
System.out.println("Result = " + result);
System.out.println("people = " + solver.getValue(people));
System.out.println("males = " + solver.getValue(males));
System.out.println("females = " + solver.getValue(females));
System.out.println("father = " + solver.getValue(father));
System.out.println("mother = " + solver.getValue(mother));
System.out.println("parent = " + solver.getValue(parent));
System.out.println("descendant = " + solver.getValue(descendant));
System.out.println("ancestor = " + solver.getValue(ancestor));
2020-02-25 11:47:24 -06:00
}
}