This file is indexed.

/usr/include/cvc3/expr_value.h is in libcvc3-dev 2.4.1-5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
/*****************************************************************************/
/*!
 * \file expr_value.h
 * 
 * Author: Sergey Berezin
 * 
 * Created: Fri Feb  7 15:07:18 2003
 *
 * <hr>
 *
 * License to use, copy, modify, sell and/or distribute this software
 * and its documentation for any purpose is hereby granted without
 * royalty, subject to the terms and conditions defined in the \ref
 * LICENSE file provided with this distribution.
 * 
 * <hr>
 * 
 * Class ExprValue: the value holding class of Expr.  No one should
 * use it directly; use Expr API instead.  To enforce that, the
 * constructors are made protected, and only Expr, ExprManager, and
 * subclasses can use them.
 */
/*****************************************************************************/

// *** HACK ATTACK *** (trick from Aaron Stump's code)

// In order to inline the Expr constructors (for efficiency), this
// file (expr_value.h) must be included in expr.h.  However, we also
// need to include expr.h here, hence, circular dependency.  A way to
// break it is to include expr_value.h in the middle of expr.h after
// the definition of class Expr, but before the definition of its
// inlined methods.  So, expr.h included below will also suck in
// expr_value.h recursively, meaning that we then should skip the rest
// of the file (since it's already been included). 

// That's why expr.h is outside of #ifndef.  The same is true for
// type.h and theorem.h.

#ifndef _cvc3__expr_h_
#include "expr.h"
#endif

#ifndef _cvc3__expr_value_h_
#define _cvc3__expr_value_h_

#include "theorem.h"
#include "type.h"

// The prime number used in the hash function for a vector of elements
#define PRIME 131

namespace CVC3 {
  
/*****************************************************************************/
/*!
 *\class ExprValue
 *\brief The base class for holding the actual data in expressions
 * 
 *
 * Author: Sergey Berezin
 *
 * Created: long time ago
 *
 * \anchor ExprValue The base class just holds the operator.
 * All the additional data resides in subclasses.
 * 
 */
/*****************************************************************************/
class CVC_DLL ExprValue {
  friend class Expr;
  friend class Expr::iterator;
  friend class ExprManager;
  friend class ::CInterface;
  friend class ExprApply;
  friend class Theorem;
  friend class ExprClosure;

  //! Unique expression id
  ExprIndex d_index;

  //! Reference counter for garbage collection
  unsigned d_refcount;
  
  //! Cached hash value (initially 0)
  size_t d_hash; 

  //! The find attribute (may be NULL)
  CDO<Theorem>* d_find;

  //! Equality between this term and next term in ring of all terms in the equivalence class
  CDO<Theorem>* d_eqNext;

  //! The cached type of the expression (may be Null)
  Type d_type;

  //! The cached TCC of the expression (may be Null)
  //  Expr d_tcc;

  //! Subtyping predicate for the expression and all subexpressions
  //  Theorem d_subtypePred;

  //! Notify list may be NULL (== no such attribute)
  NotifyList* d_notifyList;

  //! For caching calls to Simplify
  Theorem d_simpCache;

  //! For checking whether simplify cache is valid
  unsigned d_simpCacheTag;

  //! context-dependent bit-vector for flags that are context-dependent
  CDFlags d_dynamicFlags;

  //! Size of dag rooted at this expression
  Unsigned d_size;

  //! Which child has the largest height
  //  int d_highestKid;

  //! Most distant expression we were simplified *from*
  //  Expr d_simpFrom;

  //! Generic flag for marking expressions (e.g. in DAG traversal)
  unsigned d_flag;

protected:
  /*! @brief The kind of the expression.  In particular, it determines which
   * subclass of ExprValue is used to store the expression. */
  int d_kind;

  //! Our expr. manager
  ExprManager* d_em;

  // End of data members

private:

  //! Set the ExprIndex
  void setIndex(ExprIndex idx) { d_index = idx; }

  //! Increment reference counter
  void incRefcount() { ++d_refcount; }

  //! Decrement reference counter
  void decRefcount() {
    // Cannot be DebugAssert, since we are called in a destructor
    // and should not throw an exception
    IF_DEBUG(FatalAssert(d_refcount > 0, "Mis-handled the ref. counting");)
    if((--d_refcount) == 0) d_em->gc(this);
  }

  //! Caching hash function
  /*! Do NOT implement it in subclasses! Implement computeHash() instead.
   */
  size_t hash() const {
    if (d_hash == 0)
      const_cast<ExprValue*>(this)->d_hash = computeHash();
    return d_hash;
  }

  //! Return DAG-size of Expr
  Unsigned getSize() const {
    if (d_flag == d_em->getFlag()) return 0;
    const_cast<ExprValue*>(this)->d_flag = d_em->getFlag();
    return computeSize();
  }

  //! Return child with greatest height
  //  int getHighestKid() const { return d_highestKid; }

  //! Get Expr simplified to obtain this expr
  //  const Expr& getSimpFrom() const { return d_simpFrom; }

  //! Set Expr simplified to obtain this expr
  //  void setSimpFrom(const Expr& simpFrom) { d_simpFrom = simpFrom; }

protected:

  // Static hash functions.  They don't depend on the context
  // (ExprManager and such), so it is still thread-safe to have them
  // static.
  static std::hash<char*> s_charHash;
  static std::hash<long int> s_intHash;

  static size_t pointerHash(void* p) { return s_intHash((long int)p); }
  // Hash function for subclasses with children
  static size_t hash(const int kind, const std::vector<Expr>& kids);
  // Hash function for kinds
  static size_t hash(const int n) { return s_intHash((long int)n); }

  // Size function for subclasses with children
  static Unsigned sizeWithChildren(const std::vector<Expr>& kids);

  //! Return the memory manager (for the benefit of subclasses)
  MemoryManager* getMM(size_t MMIndex) {
    DebugAssert(d_em!=NULL, "ExprValue::getMM()");
    return d_em->getMM(MMIndex);
  }

  //! Make a clean copy of itself using the given ExprManager
  ExprValue* rebuild(ExprManager* em) const
    { return copy(em, 0); }

  //! Make a clean copy of the expr using the given ExprManager
  Expr rebuild(Expr e, ExprManager* em) const
    { return em->rebuildRec(e); }

  // Protected API

  //! Non-caching hash function which actually computes the hash.
  /*! This is the method that all subclasses should implement */
  virtual size_t computeHash() const { return hash(d_kind); }

  //! Non-caching size function which actually computes the size.
  /*! This is the method that all subclasses should implement */
  virtual Unsigned computeSize() const { return 1; }

  //! Make a clean copy of itself using the given ExprManager
  virtual ExprValue* copy(ExprManager* em, ExprIndex idx) const;

public:
  //! Constructor
  ExprValue(ExprManager* em, int kind, ExprIndex idx = 0)
    : d_index(idx), d_refcount(0),
      d_hash(0), d_find(NULL), d_eqNext(NULL), d_notifyList(NULL),
      d_simpCacheTag(0),
      d_dynamicFlags(em->getCurrentContext()),
      d_size(0),
      //      d_height(0), d_highestKid(-1),
      d_flag(0), d_kind(kind), d_em(em)
  {
    DebugAssert(em != NULL, "NULL ExprManager is given to ExprValue()");
    DebugAssert(em->isKindRegistered(kind),
                ("ExprValue(kind = " + int2string(kind)
                 + ")): kind is not registered").c_str());
    DebugAssert(kind != APPLY, "Only ExprApply should have APPLY kind");
// #ifdef _CVC3_DEBUG_MODE //added by yeting, just hold a place to put my breakpoints in gdb
//     if(idx != 0){
//       TRACE("expr", "expr created ", idx, "");//the line added by yeting
//       //      char * a;
//       //      a="a";
//       //      a[999999]=255;
//     }
// #endif
  }
  //! Destructor
  virtual ~ExprValue();

  //! Get the kind of the expression
  int getKind() const { return d_kind; }

  //! Overload operator new
  void* operator new(size_t size, MemoryManager* mm)
    { return mm->newData(size); }
  void operator delete(void* pMem, MemoryManager* mm) {
    mm->deleteData(pMem);
  }

  //! Overload operator delete
  void operator delete(void*) { }

  //! Get unique memory manager ID
  virtual size_t getMMIndex() const { return EXPR_VALUE; }

  //! Equality between any two ExprValue objects (including subclasses)
  virtual bool operator==(const ExprValue& ev2) const;

  // Testers

  //! Test whether the expression is a generic subclass
  /*!
   * \return 0 for the core classes, and getMMIndex() value for
   * generic subclasses (those defined in DPs)
   */
  virtual const ExprValue* getExprValue() const
    { throw Exception("Illegal call to getExprValue()"); }
  //! String expression tester
  virtual bool isString() const { return false; }
  //! Rational number expression tester
  virtual bool isRational() const { return false; }
  //! Uninterpreted constants
  virtual bool isVar() const { return false; }
  //! Application of another expression
  virtual bool isApply() const { return false; }
  //! Special named symbol
  virtual bool isSymbol() const { return false; }
  //! A LAMBDA-expression or a quantifier
  virtual bool isClosure() const { return false; }
  //! Special Expr holding a theorem
  virtual bool isTheorem() const { return false; }

  //! Get kids: by default, returns a ref to an empty vector
  virtual const std::vector<Expr>& getKids() const
    { return d_em->getEmptyVector(); }

  // Methods to access leaf data in subclasses

  //! Default arity = 0
  virtual unsigned arity() const { return 0; }

  //! Special attributes for uninterpreted functions
  virtual CDO<Theorem>* getSig() const {
    DebugAssert(false, "getSig() is called on ExprValue");
    return NULL;
  }

  virtual CDO<Theorem>* getRep() const {
    DebugAssert(false, "getRep() is called on ExprValue");
    return NULL;
  }

  virtual void setSig(CDO<Theorem>* sig) {
    DebugAssert(false, "setSig() is called on ExprValue");
  }

  virtual void setRep(CDO<Theorem>* rep) {
    DebugAssert(false, "setRep() is called on ExprValue");
  }

  virtual const std::string& getUid() const { 
    static std::string null;
    DebugAssert(false, "ExprValue::getUid() called in base class");
    return null;
  }

  virtual const std::string& getString() const {
    DebugAssert(false, "getString() is called on ExprValue");
    static std::string s("");
    return s;
  }

  virtual const Rational& getRational() const {
    DebugAssert(false, "getRational() is called on ExprValue");
    static Rational r(0);
    return r;
  }

  //! Returns the string name of UCONST and BOUND_VAR expr's.
  virtual const std::string& getName() const {
    static std::string ret = "";
    DebugAssert(false, "getName() is called on ExprValue");
    return ret;
  }

  //! Returns the original Boolean variable (for BoolVarExprValue)
  virtual const Expr& getVar() const {
    DebugAssert(false, "getVar() is called on ExprValue");
    static Expr null;
    return null;
  }

  //! Get the Op from an Apply Expr
  virtual Op getOp() const {
    DebugAssert(false, "getOp() is called on ExprValue");
    return Op(NULL_KIND);
  }

  virtual const std::vector<Expr>& getVars() const  {
    DebugAssert(false, "getVars() is called on ExprValue");
    static std::vector<Expr> null;
    return null;
  }

  virtual const Expr& getBody() const {
    DebugAssert(false, "getBody() is called on ExprValue");
    static Expr null;
    return null;
  }

  virtual void setTriggers(const std::vector<std::vector<Expr> >& triggers) {
    DebugAssert(false, "setTriggers() is called on ExprValue");
  }

  virtual const std::vector<std::vector<Expr> >& getTriggers() const { //by yeting
    DebugAssert(false, "getTrigs() is called on ExprValue");
    static std::vector<std::vector<Expr> > null;
    return null;
  }


  virtual const Expr& getExistential() const {
    DebugAssert(false, "getExistential() is called on ExprValue");
    static Expr null;
    return null;
  }
  virtual int getBoundIndex() const {
    DebugAssert(false, "getIndex() is called on ExprValue");
    return 0;
  }

  virtual const std::vector<std::string>& getFields() const {
    DebugAssert(false, "getFields() is called on ExprValue");
    static std::vector<std::string> null;
    return null;
  }
  virtual const std::string& getField() const {
    DebugAssert(false, "getField() is called on ExprValue");
    static std::string null;
    return null;
  }
  virtual int getTupleIndex() const {
    DebugAssert(false, "getTupleIndex() is called on ExprValue");
    return 0;
  }
  virtual const Theorem& getTheorem() const {
    static Theorem null;
    DebugAssert(false, "getTheorem() is called on ExprValue");
    return null;
  }

}; // end of class ExprValue

// Class ExprNode; it's an expression with children
class CVC_DLL ExprNode: public ExprValue {
  friend class Expr;
  friend class ExprManager;

protected:
  //! Vector of children
  std::vector<Expr> d_children;

  // Special attributes for helping with congruence closure
  CDO<Theorem>* d_sig;
  CDO<Theorem>* d_rep;

private:

  //! Tell ExprManager who we are
  size_t getMMIndex() const { return EXPR_NODE; }

protected:
  //! Return number of children
  unsigned arity() const { return d_children.size(); }

  //! Return reference to children
  std::vector<Expr>& getKids1() { return d_children; }

  //! Return reference to children
  const std::vector<Expr>& getKids() const { return d_children; }

  //! Use our static hash() for the member method
  size_t computeHash() const {
    return ExprValue::hash(d_kind, d_children);
  }

  //! Use our static sizeWithChildren() for the member method
  Unsigned computeSize() const {
    return ExprValue::sizeWithChildren(d_children);
  }

  //! Make a clean copy of itself using the given memory manager
  virtual ExprValue* copy(ExprManager* em, ExprIndex idx = 0) const;

public:
  //! Constructor
  ExprNode(ExprManager* em, int kind, ExprIndex idx = 0)
    : ExprValue(em, kind, idx), d_sig(NULL), d_rep(NULL) { }
  //! Constructor
  ExprNode(ExprManager* em, int kind, const std::vector<Expr>& kids,
           ExprIndex idx = 0)
    : ExprValue(em, kind, idx), d_children(kids), d_sig(NULL), d_rep(NULL) { }
  //! Destructor
  virtual ~ExprNode();
    
  //! Overload operator new
  void* operator new(size_t size, MemoryManager* mm)
    { return mm->newData(size); }
  void operator delete(void* pMem, MemoryManager* mm) {
    mm->deleteData(pMem);
  }

  //! Overload operator delete
  void operator delete(void*) { }

  //! Compare with another ExprValue
  virtual bool operator==(const ExprValue& ev2) const;

  virtual CDO<Theorem>* getSig() const { return d_sig; }
  virtual CDO<Theorem>* getRep() const { return d_rep; }

  virtual void setRep(CDO<Theorem>* rep) { d_rep = rep; }
  virtual void setSig(CDO<Theorem>* sig) { d_sig = sig; }

}; // end of class ExprNode

// Class ExprNodeTmp; special version of ExprNode for Expr constructor
class ExprNodeTmp: public ExprValue {
  friend class Expr;
  friend class ExprManager;

protected:
  //! Vector of children
  const std::vector<Expr>& d_children;

private:

  //! Tell ExprManager who we are
  size_t getMMIndex() const { return EXPR_NODE; }

protected:
  //! Return number of children
  unsigned arity() const { return d_children.size(); }

  //! Return reference to children
  const std::vector<Expr>& getKids() const { return d_children; }

  //! Use our static hash() for the member method
  size_t computeHash() const {
    return ExprValue::hash(d_kind, d_children);
  }

  //! Use our static sizeWithChildren() for the member method
  Unsigned computeSize() const {
    return ExprValue::sizeWithChildren(d_children);
  }

  //! Make a clean copy of itself using the given memory manager
  virtual ExprValue* copy(ExprManager* em, ExprIndex idx = 0) const;

public:
  //! Constructor
  ExprNodeTmp(ExprManager* em, int kind, const std::vector<Expr>& kids)
    : ExprValue(em, kind, 0), d_children(kids) { }

  //! Destructor
  virtual ~ExprNodeTmp() {}
    
  //! Compare with another ExprValue
  virtual bool operator==(const ExprValue& ev2) const;

}; // end of class ExprNodeTmp

// Special version for Expr Constructor
class ExprApplyTmp: public ExprNodeTmp {
  friend class Expr;
  friend class ExprManager;
private:
  Expr d_opExpr;
protected:
  size_t getMMIndex() const { return EXPR_APPLY; }
  size_t computeHash() const {
    return PRIME*ExprNodeTmp::computeHash() + d_opExpr.hash();
  }
  Op getOp() const { return Op(d_opExpr); }
  bool isApply() const { return true; }
  // Make a clean copy of itself using the given memory manager
  ExprValue* copy(ExprManager* em, ExprIndex idx = 0) const;
public:
  // Constructor
  ExprApplyTmp(ExprManager* em, const Op& op,
               const std::vector<Expr>& kids)
    : ExprNodeTmp(em, NULL_KIND, kids), d_opExpr(op.getExpr())
  { DebugAssert(!op.getExpr().isNull(), "Expected non-null Op");
    d_kind = APPLY; }
  virtual ~ExprApplyTmp() { }

  bool operator==(const ExprValue& ev2) const;
}; // end of class ExprApply

class CVC_DLL ExprApply: public ExprNode {
  friend class Expr;
  friend class ExprManager;
private:
  Expr d_opExpr;
protected:
  size_t getMMIndex() const { return EXPR_APPLY; }
  size_t computeHash() const {
    return PRIME*ExprNode::computeHash() + d_opExpr.hash();
  }
  Op getOp() const { return Op(d_opExpr); }
  bool isApply() const { return true; }
  // Make a clean copy of itself using the given memory manager
  ExprValue* copy(ExprManager* em, ExprIndex idx = 0) const;
public:
  // Constructor
  ExprApply(ExprManager* em, const Op& op, ExprIndex idx = 0)
    : ExprNode(em, NULL_KIND, idx), d_opExpr(op.getExpr())
  { DebugAssert(!op.getExpr().isNull(), "Expected non-null Op");
    d_kind = APPLY; }
  ExprApply(ExprManager* em, const Op& op,
            const std::vector<Expr>& kids, ExprIndex idx = 0)
    : ExprNode(em, NULL_KIND, kids, idx), d_opExpr(op.getExpr())
  { DebugAssert(!op.getExpr().isNull(), "Expected non-null Op");
    d_kind = APPLY; }
  virtual ~ExprApply() { }

  bool operator==(const ExprValue& ev2) const;
  // Memory management
  void* operator new(size_t size, MemoryManager* mm) {
    return mm->newData(size);
  }
  void operator delete(void* pMem, MemoryManager* mm) {
    mm->deleteData(pMem);
  }
  void operator delete(void*) { }
}; // end of class ExprApply

/*****************************************************************************/
/*!
 *\class NamedExprValue
 *\brief NamedExprValue
 *
 * Author: Clark Barrett
 *
 * Created: Thu Dec  2 23:18:17 2004
 *
 * Subclass of ExprValue for kinds that have a name associated with them.
 */
/*****************************************************************************/

// class NamedExprValue : public ExprNode {
//   friend class Expr;
//   friend class ExprManager;

// private:
//   std::string d_name;

// protected:

//   ExprValue* copy(ExprManager* em, ExprIndex idx = 0) const {
//     return new(em->getMM(getMMIndex()))
//       NamedExprValue(d_em, d_kind, d_name, d_children, idx);
//   }

//   ExprValue* copy(ExprManager* em, const std::vector<Expr>& kids,
//       	    ExprIndex idx = 0) const {
//     return new(em->getMM(getMMIndex()))
//       NamedExprValue(d_em, d_kind, d_name, kids, idx);
//   }

//   size_t computeHash() const {
//     return s_charHash(d_name.c_str())*PRIME + ExprNode::computeHash();
//   }

//   size_t getMMIndex() const { return EXPR_NAMED; }

// public:
//   // Constructor
//   NamedExprValue(ExprManager *em, int kind, const std::string& name,
//                  const std::vector<Expr>& kids, ExprIndex idx = 0)
//     : ExprNode(em, kind, kids, idx), d_name(name) { }
//   // virtual ~NamedExprValue();
//   bool operator==(const ExprValue& ev2) const {
//     if(getMMIndex() != ev2.getMMIndex()) return false;
//     return (getName() == ev2.getName())
//       && ExprNode::operator==(ev2);
//   }

//   const std::string& getName() const { return d_name; }

//   // Memory management
//   void* operator new(size_t size, MemoryManager* mm) {
//     return mm->newData(size);
//   }
//   void operator delete(void*) { }
// }; // end of class NamedExprValue

// Leaf expressions
class ExprString: public ExprValue {
  friend class Expr;
  friend class ExprManager;
private:
  std::string d_str;

  // Hash function for this subclass
  static size_t hash(const std::string& str) {
    return s_charHash(str.c_str());
  }

  // Tell ExprManager who we are
  virtual size_t getMMIndex() const { return EXPR_STRING; }

protected:
  // Use our static hash() for the member method
  virtual size_t computeHash() const { return hash(d_str); }

  virtual bool isString() const { return true; }
  virtual const std::string& getString() const { return d_str; }

  //! Make a clean copy of itself using the given memory manager
  virtual ExprValue* copy(ExprManager* em, ExprIndex idx = 0) const;
public:
  // Constructor
  ExprString(ExprManager* em, const std::string& s, ExprIndex idx = 0)
    : ExprValue(em, STRING_EXPR, idx), d_str(s) { }
  // Destructor
  virtual ~ExprString() { }

  virtual bool operator==(const ExprValue& ev2) const;
  // Memory management
  void* operator new(size_t size, MemoryManager* mm) {
    return mm->newData(size);
  }
  void operator delete(void* pMem, MemoryManager* mm) {
    mm->deleteData(pMem);
  }
  void operator delete(void*) { }
}; // end of class ExprString

class ExprSkolem: public ExprValue {
  friend class Expr;
  friend class ExprManager;
private:
  Expr d_quant; //!< The quantified expression to skolemize
  int d_idx; //!< Variable index in the quantified expression
  const Expr& getExistential() const {return d_quant;}
  int getBoundIndex() const {return d_idx;}

  // Tell ExprManager who we are
  size_t getMMIndex() const { return EXPR_SKOLEM;}

protected:
  size_t computeHash() const {
    size_t res = getExistential().getBody().hash();
    res = PRIME*res + getBoundIndex();
    return res;
  }

  bool operator==(const ExprValue& ev2) const;

  //! Make a clean copy of itself using the given memory manager
  ExprValue* copy(ExprManager* em, ExprIndex idx = 0) const;
  bool isVar() const { return true; }
   
public:
  // Constructor
  ExprSkolem(ExprManager* em, int index, const Expr& exist, ExprIndex idx = 0)
    : ExprValue(em, SKOLEM_VAR, idx), d_quant(exist), d_idx(index) { }
  // Destructor
  virtual ~ExprSkolem() { }
  // Memory management
  void* operator new(size_t size, MemoryManager* mm) {
    return mm->newData(size);
  }
  void operator delete(void* pMem, MemoryManager* mm) {
    mm->deleteData(pMem);
  }
  void operator delete(void*) { }
}; // end of class ExprSkolem

class ExprRational: public ExprValue {
  friend class Expr;
  friend class ExprManager;
private:
  Rational d_r;

  virtual const Rational& getRational() const { return d_r; }

  // Hash function for this subclass
  static size_t hash(const Rational& r) {
    return s_charHash(r.toString().c_str());
  }

  // Tell ExprManager who we are
  virtual size_t getMMIndex() const { return EXPR_RATIONAL; }

protected:

  virtual size_t computeHash() const { return hash(d_r); }
  virtual bool operator==(const ExprValue& ev2) const;
  //! Make a clean copy of itself using the given memory manager
  virtual ExprValue* copy(ExprManager* em, ExprIndex idx = 0) const;
  virtual bool isRational() const { return true; }

public:
  // Constructor
  ExprRational(ExprManager* em, const Rational& r, ExprIndex idx = 0)
    : ExprValue(em, RATIONAL_EXPR, idx), d_r(r) { }
  // Destructor
  virtual ~ExprRational() { }
  // Memory management
  void* operator new(size_t size, MemoryManager* mm) {
    return mm->newData(size);
  }
  void operator delete(void* pMem, MemoryManager* mm) {
    mm->deleteData(pMem);
  }
  void operator delete(void*) { }
}; // end of class ExprRational

// Uninterpreted constants (variables)
class ExprVar: public ExprValue {
  friend class Expr;
  friend class ExprManager;
private:
  std::string d_name;

  virtual const std::string& getName() const { return d_name; }

  // Tell ExprManager who we are
  virtual size_t getMMIndex() const { return EXPR_UCONST; }
protected:

  virtual size_t computeHash() const {
    return s_charHash(d_name.c_str());
  }
  virtual bool isVar() const { return true; }

  //! Make a clean copy of itself using the given memory manager
  virtual ExprValue* copy(ExprManager* em, ExprIndex idx = 0) const;

public:
  // Constructor
  ExprVar(ExprManager *em, const std::string& name, ExprIndex idx = 0)
    : ExprValue(em, UCONST, idx), d_name(name) { }
  // Destructor
  virtual ~ExprVar() { }

  virtual bool operator==(const ExprValue& ev2) const;
  // Memory management
  void* operator new(size_t size, MemoryManager* mm) {
    return mm->newData(size);
  }
  void operator delete(void* pMem, MemoryManager* mm) {
    mm->deleteData(pMem);
  }
  void operator delete(void*) { }
}; // end of class ExprVar

// Interpreted symbols: similar to UCONST, but returns false for isVar().
class ExprSymbol: public ExprValue {
  friend class Expr;
  friend class ExprManager;
private:
  std::string d_name;

  virtual const std::string& getName() const { return d_name; }

  // Tell ExprManager who we are
  virtual size_t getMMIndex() const { return EXPR_SYMBOL; }
protected:

  virtual size_t computeHash() const {
    return s_charHash(d_name.c_str())*PRIME + s_intHash(d_kind);
  }
  //! Make a clean copy of itself using the given memory manager
  virtual ExprValue* copy(ExprManager* em, ExprIndex idx = 0) const;
  bool isSymbol() const { return true; }

public:
  // Constructor
  ExprSymbol(ExprManager *em, int kind, const std::string& name,
             ExprIndex idx = 0)
    : ExprValue(em, kind, idx), d_name(name) { }
  // Destructor
  virtual ~ExprSymbol() { }

  virtual bool operator==(const ExprValue& ev2) const;
  // Memory management
  void* operator new(size_t size, MemoryManager* mm) {
    return mm->newData(size);
  }
  void operator delete(void* pMem, MemoryManager* mm) {
    mm->deleteData(pMem);
  }
  void operator delete(void*) { }
}; // end of class ExprSymbol

class ExprBoundVar: public ExprValue {
  friend class Expr;
  friend class ExprManager;
private:
  std::string d_name;
  std::string d_uid;

  virtual const std::string& getName() const { return d_name; }
  virtual const std::string& getUid() const { return d_uid; }

  // Tell ExprManager who we are
  virtual size_t getMMIndex() const { return EXPR_BOUND_VAR; }
protected:

  virtual size_t computeHash() const {
    return s_charHash(d_name.c_str())*PRIME + s_charHash(d_uid.c_str());
  }
  virtual bool isVar() const { return true; }
  //! Make a clean copy of itself using the given memory manager
  virtual ExprValue* copy(ExprManager* em, ExprIndex idx = 0) const;

public:
  // Constructor
  ExprBoundVar(ExprManager *em, const std::string& name,
               const std::string& uid, ExprIndex idx = 0)
    : ExprValue(em, BOUND_VAR, idx), d_name(name), d_uid(uid) { }
  // Destructor
  virtual ~ExprBoundVar() { }

  virtual bool operator==(const ExprValue& ev2) const;
  // Memory management
  void* operator new(size_t size, MemoryManager* mm) {
    return mm->newData(size);
  }
  void operator delete(void* pMem, MemoryManager* mm) {
    mm->deleteData(pMem);
  }
  void operator delete(void*) { }
}; // end of class ExprBoundVar

/*! @brief A "closure" expression which binds variables used in the
  "body".  Used by LAMBDA and quantifiers. */
class ExprClosure: public ExprValue {
  friend class Expr;
  friend class ExprManager;
private:
  //! Bound variables
  std::vector<Expr> d_vars;
  //! The body of the quantifier/lambda
  Expr d_body;
  //! Manual triggers. // added by yeting
  // Note that due to expr caching, only the most recent triggers specified for a given formula will be used.
  std::vector<std::vector<Expr> > d_manual_triggers;
  //! Tell ExprManager who we are
  virtual size_t getMMIndex() const { return EXPR_CLOSURE; }

  virtual const std::vector<Expr>& getVars() const { return d_vars; }
  virtual const Expr& getBody() const { return d_body; }
  virtual void setTriggers(const std::vector<std::vector<Expr> >& triggers) { d_manual_triggers = triggers; }
  virtual const std::vector<std::vector<Expr> >&  getTriggers() const { return d_manual_triggers; }

protected:

  size_t computeHash() const;
  Unsigned computeSize() const { return d_body.d_expr->getSize() + 1; }
  //! Make a clean copy of itself using the given memory manager
  ExprValue* copy(ExprManager* em, ExprIndex idx = 0) const;

public:
  // Constructor
  ExprClosure(ExprManager *em, int kind, const Expr& var,
              const Expr& body, ExprIndex idx = 0)
    : ExprValue(em, kind, idx), d_body(body) { d_vars.push_back(var); }

  ExprClosure(ExprManager *em, int kind, const std::vector<Expr>& vars,
              const Expr& body, ExprIndex idx = 0)
    : ExprValue(em, kind, idx), d_vars(vars), d_body(body) { }

  ExprClosure(ExprManager *em, int kind, const std::vector<Expr>& vars, 
              const Expr& body, const std::vector<std::vector<Expr> >&  trigs, ExprIndex idx = 0)
    : ExprValue(em, kind, idx), d_vars(vars), d_body(body),  d_manual_triggers(trigs) { }

  // Destructor
  virtual ~ExprClosure() { }

  bool operator==(const ExprValue& ev2) const;
  // Memory management
  void* operator new(size_t size, MemoryManager* mm) {
    return mm->newData(size);
  }
  void operator delete(void* pMem, MemoryManager* mm) {
    mm->deleteData(pMem);
  }
  void operator delete(void*) { }
  virtual bool isClosure() const { return true; }
}; // end of class ExprClosure


} // end of namespace CVC3

#endif