add utils class for relational theory
authorPaulMeng <baolmeng@gmail.com>
Wed, 20 Apr 2016 18:54:32 +0000 (13:54 -0500)
committerPaulMeng <baolmeng@gmail.com>
Wed, 20 Apr 2016 18:54:32 +0000 (13:54 -0500)
src/theory/sets/rels_utils.h [new file with mode: 0644]

diff --git a/src/theory/sets/rels_utils.h b/src/theory/sets/rels_utils.h
new file mode 100644 (file)
index 0000000..3b98203
--- /dev/null
@@ -0,0 +1,95 @@
+/*********************                                                        */
+/*! \file rels_utils.h
+ ** \verbatim
+ ** Original author: Paul Meng
+ ** Major contributors: none
+ ** Minor contributors (to current version): none
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2014  New York University and The University of Iowa
+ ** See the file COPYING in the top-level source directory for licensing
+ ** information.\endverbatim
+ **
+ ** \brief Sets theory implementation.
+ **
+ ** Extension to Sets theory.
+ **/
+
+#ifndef SRC_THEORY_SETS_RELS_UTILS_H_
+#define SRC_THEORY_SETS_RELS_UTILS_H_
+
+namespace CVC4 {
+namespace theory {
+namespace sets {
+
+class RelsUtils {
+
+public:
+
+  // Assumption: the input rel_mem contains all constant pairs
+  static std::set< Node > computeTC( std::set< Node > rel_mem, Node rel ) {
+    std::set< Node >::iterator mem_it = rel_mem.begin();
+    std::map< Node, int > ele_num_map;
+    std::set< Node > tc_rel_mem;
+       
+    while( mem_it != rel_mem.end() ) {
+      Node fst = nthElementOfTuple( *mem_it, 0 );
+      Node snd = nthElementOfTuple( *mem_it, 1 );
+      std::set< Node > traversed;
+      traversed.insert(fst);
+      computeTC(rel, rel_mem, fst, snd, traversed, tc_rel_mem);      
+      mem_it++;             
+    }
+    return tc_rel_mem;
+  }
+  
+  static void computeTC( Node rel, std::set< Node >& rel_mem, Node fst, 
+                         Node snd, std::set< Node >& traversed, std::set< Node >& tc_rel_mem ) {    
+    tc_rel_mem.insert(constructPair(rel, fst, snd));
+    if( traversed.find(snd) == traversed.end() ) {
+      traversed.insert(snd);
+    } else {
+      return;
+    }
+
+    std::set< Node >::iterator mem_it = rel_mem.begin();
+    while( mem_it != rel_mem.end() ) {
+      Node new_fst = nthElementOfTuple( *mem_it, 0 );
+      Node new_snd = nthElementOfTuple( *mem_it, 1 );
+      if( snd == new_fst ) {
+        computeTC(rel, rel_mem, fst, new_snd, traversed, tc_rel_mem);
+      }
+      mem_it++; 
+    }  
+  }
+  static Node nthElementOfTuple( Node tuple, int n_th ) {    
+    if(tuple.isConst() || (!tuple.isVar() && !tuple.isConst()))
+      return tuple[n_th];
+    Datatype dt = tuple.getType().getDatatype();
+    return NodeManager::currentNM()->mkNode(kind::APPLY_SELECTOR_TOTAL, dt[0][n_th].getSelector(), tuple);
+  } 
+  
+  static Node reverseTuple( Node tuple ) {
+    Assert( tuple.getType().isTuple() );
+    std::vector<Node> elements;
+    std::vector<TypeNode> tuple_types = tuple.getType().getTupleTypes();
+    std::reverse( tuple_types.begin(), tuple_types.end() );
+    TypeNode tn = NodeManager::currentNM()->mkTupleType( tuple_types );
+    Datatype dt = tn.getDatatype();
+    elements.push_back( Node::fromExpr(dt[0].getConstructor() ) );
+    for(int i = tuple_types.size() - 1; i >= 0; --i) {
+      elements.push_back( nthElementOfTuple(tuple, i) );
+    }
+    return NodeManager::currentNM()->mkNode( kind::APPLY_CONSTRUCTOR, elements );
+  }
+  static Node constructPair(Node rel, Node a, Node b) {
+    Datatype dt = rel.getType().getSetElementType().getDatatype();
+    return NodeManager::currentNM()->mkNode(kind::APPLY_CONSTRUCTOR, Node::fromExpr(dt[0].getConstructor()), a, b);
+  }     
+    
+};             
+}/* CVC4::theory::sets namespace */
+}/* CVC4::theory namespace */
+}/* CVC4 namespace */
+
+#endif
\ No newline at end of file