This file is indexed.

/usr/include/cvc3/theory_quant.h is in libcvc3-dev 2.4.1-5.1ubuntu1.

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
/*****************************************************************************/
/*!
 * \file theory_quant.h
 * 
 * Author: Sergey Berezin, Yeting Ge
 * 
 * Created: Jun 24 21:13:59 GMT 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>
 * 
 * ! Author: Daniel Wichs
 * ! Created: Wednesday July 2, 2003
 *
 * 
 */
/*****************************************************************************/
#ifndef _cvc3__include__theory_quant_h_
#define _cvc3__include__theory_quant_h_

#include "theory.h"
#include "cdmap.h"
#include "statistics.h"
#include<queue>

namespace CVC3 {

class QuantProofRules;

/*****************************************************************************/
/*!
 *\class TheoryQuant
 *\ingroup Theories
 *\brief This theory handles quantifiers.
 *
 * Author: Daniel Wichs
 *
 * Created: Wednesday July 2,  2003
 */
/*****************************************************************************/

 typedef enum{ Ukn, Pos, Neg, PosNeg} Polarity;

 class Trigger {
 public: 
   Expr trig;
   Polarity polarity;
   
   std::vector<Expr> bvs;
   Expr head;
   bool hasRWOp;
   bool hasTrans;
   bool hasT2; //if has trans of 2,
   bool isSimple; //if of the form g(x,a);
   bool isSuperSimple; //if of the form g(x,y);
   bool isMulti;
   size_t multiIndex; 
   size_t multiId;

   Trigger(TheoryCore* core, Expr e, Polarity pol, std::set<Expr>);
   bool  isPos();
   bool  isNeg();
   Expr  getEx();
   std::vector<Expr> getBVs(); 
   void  setHead(Expr h);
   Expr  getHead();
   void  setRWOp(bool b);
   bool  hasRW(); 
   void  setTrans(bool b);
   bool  hasTr(); 
   void  setTrans2(bool b);
   bool  hasTr2(); 
   void  setSimp();
   bool  isSimp(); 
   void  setSuperSimp();
   bool  isSuperSimp(); 
   void  setMultiTrig();
   bool  isMultiTrig(); 

   
 };

 typedef struct dynTrig{
   Trigger trig;
   size_t univ_id;
   ExprMap<Expr> binds;
   dynTrig(Trigger t, ExprMap<Expr> b, size_t id);
 } dynTrig;
 

 class CompleteInstPreProcessor {
 
   TheoryCore* d_theoryCore; //needed by plusOne and minusOne;
   QuantProofRules* d_quant_rules;

   std::set<Expr> d_allIndex; //a set contains all index

   ExprMap<Polarity> d_expr_pol ;//map a expr to its polarity

   ExprMap<Expr> d_quant_equiv_map ; //map a quant to its equivalent form

   std::vector<Expr> d_gnd_cache; //cache of all ground formulas, before index can be collected, all such ground terms must be put into d_expr_pol.
   
   ExprMap<bool> d_is_macro_def;//if a quant is a macro quant

   ExprMap<Expr> d_macro_quant;//map a macro to its macro quant.

   ExprMap<Expr> d_macro_def;//map a macro head to its def.

   ExprMap<Expr> d_macro_lhs;//map a macro to its lhs.
   
   //! if all formulas checked so far are good
   bool d_all_good ;

   //! if e satisfies the shiled property, that is all bound vars are parameters of uninterpreted functions/predicates and array reads/writes
   bool isShield(const Expr& e);

   bool hasShieldVar(const Expr& e);

   //! insert an index
   void addIndex(const Expr& e);
   
   void collect_shield_index(const Expr& e);

   void collect_forall_index(const Expr& forall_quant);

   //! if e is a quant in the array property fragmenet
   bool isGoodQuant(const Expr& e);

   //! return e+1
   Expr plusOne(const Expr& e);

   //! return e-1
   Expr minusOne(const Expr& e);

   void collectHeads(const Expr& assert, std::set<Expr>& heads);
   
   //! if assert is a macro definition
   bool isMacro(const Expr& assert);

   Expr recInstMacros(const Expr& assert);

   Expr substMacro(const Expr&);

   Expr recRewriteNot(const Expr&, ExprMap<Polarity>&);

   //! rewrite neg polarity forall / exists to pos polarity
   Expr rewriteNot(const Expr &);
   
   Expr recSkolemize(const Expr &, ExprMap<Polarity>&);

   Expr pullVarOut(const Expr&);

 public :

   CompleteInstPreProcessor(TheoryCore * , QuantProofRules*);

   //! if e is a formula in the array property fragment 
   bool isGood(const Expr& e);

   //! collect index for instantiation
   void collectIndex(const Expr & e);

   //! inst forall quant using index from collectIndex
   Expr inst(const Expr & e);

   //! if there are macros
   bool hasMacros(const std::vector<Expr>& asserts);

   //! substitute a macro in assert
   Expr instMacros(const Expr& , const Expr );

   //! simplify a=a to True
   Expr simplifyEq(const Expr &);
   
   //! put all quants in postive form and then skolemize all exists 
   Expr simplifyQuant(const Expr &);
 };
 
 class TheoryQuant :public Theory {
   
   Theorem rewrite(const Expr& e);

   Theorem theoryPreprocess(const Expr& e);

   class  TypeComp { //!< needed for typeMap
   public:
     bool operator() (const Type t1, const Type t2) const
     {return (t1.getExpr() < t2.getExpr()); }
   };

  //! used to facilitate instantiation of universal quantifiers
  typedef std::map<Type, std::vector<size_t>, TypeComp > typeMap; 

  //! database of universally quantified theorems
  CDList<Theorem> d_univs; 

  CDList<Theorem> d_rawUnivs; 

  CDList<dynTrig> d_arrayTrigs; 
  CDO<size_t> d_lastArrayPos;

  //! universally quantified formulas to be instantiated, the var bindings is in d_bingQueue and the ground term matched with the trigger is in d_gtermQueue 
  std::queue<Theorem> d_univsQueue;

  std::queue<Theorem> d_simplifiedThmQueue;

  std::queue<Theorem> d_gUnivQueue;
  
  std::queue<Expr> d_gBindQueue;


  ExprMap<std::set<std::vector<Expr> > >  d_tempBinds;

  //!tracks the possition of preds 
  CDO<size_t> d_lastPredsPos;
  //!tracks the possition of terms 
  CDO<size_t> d_lastTermsPos;

  //!tracks the positions of preds for partial instantiation
  CDO<size_t> d_lastPartPredsPos;
  //!tracks the possition of terms for partial instantiation
  CDO<size_t> d_lastPartTermsPos;
  //!tracks a possition in the database of universals for partial instantiation
  CDO<size_t> d_univsPartSavedPos;
  
  //! the last decision level on which partial instantion is called
  CDO<size_t> d_lastPartLevel;

  CDO<bool> d_partCalled;
  
  //! the max instantiation level reached
  CDO<bool> d_maxILReached;


  
  //!useful gterms for matching
  CDList<Expr> d_usefulGterms; 

  //!tracks the position in d_usefulGterms
  CDO<size_t> d_lastUsefulGtermsPos;
  
  //!tracks a possition in the savedTerms map
  CDO<size_t> d_savedTermsPos;
  //!tracks a possition in the database of universals
  CDO<size_t> d_univsSavedPos;
  CDO<size_t> d_rawUnivsSavedPos;
  //!tracks a possition in the database of universals
  CDO<size_t> d_univsPosFull;
  //!tracks a possition in the database of universals if fulleffort mode, the d_univsSavedPos now uesed when fulleffort=0 only.

  CDO<size_t> d_univsContextPos;
  
  
  CDO<int> d_instCount; //!< number of instantiations made in given context

  //! set if the fullEffort = 1
  int d_inEnd; 

  int d_allout; 

  //! a map of types to posisitions in the d_contextTerms list
  std::map<Type, CDList<size_t>* ,TypeComp> d_contextMap;
  //! a list of all the terms appearing in the current context
  CDList<Expr> d_contextTerms;
  //!< chache of expressions
  CDMap<Expr, bool> d_contextCache;
  
  //! a map of types to positions in the d_savedTerms vector
  typeMap d_savedMap;
  ExprMap<bool> d_savedCache; //!< cache of expressions
  //! a vector of all of the terms that have produced conflicts.
  std::vector<Expr> d_savedTerms; 

  //! a map of instantiated universals to a vector of their instantiations
  ExprMap<std::vector<Expr> >  d_insts;

  //! quantifier theorem production rules
  QuantProofRules* d_rules;
  
  const int* d_maxQuantInst; //!< Command line option

  /*! \brief categorizes all the terms contained in an expressions by
   *type.
   *
   * Updates d_contextTerms, d_contextMap, d_contextCache accordingly.
   * returns true if the expression does not contain bound variables, false
   * otherwise.
   */
  bool recursiveMap(const Expr& term);

  /*! \brief categorizes all the terms contained in a vector of  expressions by
   * type.
   *
   * Updates d_contextTerms, d_contextMap, d_contextCache accordingly.
   */
  void mapTermsByType(const CDList<Expr>& terms);
  
  /*! \brief Queues up all possible instantiations of bound
   * variables.
   *
   * The savedMap boolean indicates whether to use savedMap or
   * d_contextMap the all boolean indicates weather to use all
   * instantiation or only new ones and newIndex is the index where
   * new instantiations begin.
   */
  void instantiate(Theorem univ, bool all, bool savedMap, 
		   size_t newIndex);
  //! does most of the work of the instantiate function.
  void recInstantiate(Theorem& univ , bool all, bool savedMap,size_t newIndex, 
				   std::vector<Expr>& varReplacements);

  /*! \brief A recursive function used to find instantiated universals
   * in the hierarchy of assumptions.
   */
  void findInstAssumptions(const Theorem& thm);

  //  CDO<bool> usedup;
  const bool* d_useNew;//!use new way of instantiation
  const bool* d_useLazyInst;//!use lazy instantiation
  const bool* d_useSemMatch;//!use semantic matching
  const bool* d_useCompleteInst; //! Try complete instantiation 
  const bool* d_translate;//!translate only

  const bool* d_usePart;//!use partial instantiaion
  const bool* d_useMult;//use 
  //  const bool* d_useInstEnd;
  const bool* d_useInstLCache;
  const bool* d_useInstGCache;
  const bool* d_useInstThmCache;
  const bool* d_useInstTrue;
  const bool* d_usePullVar;
  const bool* d_useExprScore;
  const int* d_useTrigLoop;
  const int* d_maxInst;
  //  const int* d_maxUserScore;
  const int*  d_maxIL;
  const bool* d_useTrans;
  const bool* d_useTrans2;
  const bool* d_useManTrig;
  const bool* d_useGFact;
  const int* d_gfactLimit;
  const bool* d_useInstAll;
  const bool* d_usePolarity;
  const bool* d_useEqu;
  const bool* d_useNewEqu;
  const int* d_maxNaiveCall;
  const bool* d_useNaiveInst;


  CDO<int> d_curMaxExprScore;

  bool d_useFullTrig;
  bool d_usePartTrig;
  bool d_useMultTrig;

  //ExprMap<std::vector<Expr> > d_arrayIndic; //map array name to a list of indics
  CDMap<Expr, std::vector<Expr> > d_arrayIndic; //map array name to a list of indics
  void arrayIndexName(const Expr& e);

  std::vector<Expr> d_allInsts; //! all instantiations

  int d_initMaxScore;
  int d_offset_multi_trig ;
  
  int d_instThisRound;
  int d_callThisRound;

  int partial_called;

  //  ExprMap<std::vector<Expr> > d_fullTriggers;
  //for multi-triggers, now we only have one set of multi-triggers.


  ExprMap<std::vector<Expr> > d_multTriggers;
  ExprMap<std::vector<Expr> > d_partTriggers;

  ExprMap<std::vector<Trigger> > d_fullTrigs;
  //for multi-triggers, now we only have one set of multi-triggers.
  ExprMap<std::vector<Trigger> > d_multTrigs;
  ExprMap<std::vector<Trigger> > d_partTrigs;

 
  CDO<size_t> d_exprLastUpdatedPos ;//the position of the last expr updated in d_exprUpdate 

  std::map<ExprIndex, int> d_indexScore;

  std::map<ExprIndex, Expr> d_indexExpr;

  int getExprScore(const Expr& e);

  //!the score for a full trigger
  
  ExprMap<bool> d_hasTriggers;
  ExprMap<bool> d_hasMoreBVs;

  int d_trans_num;
  int d_trans2_num;

  typedef struct{
    std::vector<std::vector<size_t> > common_pos;
    std::vector<std::vector<size_t> > var_pos; 
    
    std::vector<CDMap<Expr, bool>* > var_binds_found;

    std::vector<ExprMap<CDList<Expr>* >* > uncomm_list; //
    Theorem univThm; // for test only
    size_t univ_id; // for test only
  } multTrigsInfo ;
  
  ExprMap<multTrigsInfo> d_multitrigs_maps;
  std::vector<multTrigsInfo> d_all_multTrigsInfo;
  
  ExprMap<CDList<Expr>* > d_trans_back;
  ExprMap<CDList<Expr>* > d_trans_forw;
  CDMap<Expr,bool > d_trans_found;
  CDMap<Expr,bool > d_trans2_found;


  inline  bool transFound(const Expr& comb);
  
  inline   void setTransFound(const Expr& comb);

  inline  bool trans2Found(const Expr& comb);

  inline  void setTrans2Found(const Expr& comb);

 
  inline  CDList<Expr> & backList(const Expr& ex);
  
  inline  CDList<Expr> & forwList(const Expr& ex);

  void inline iterFWList(const Expr& sr, const Expr& dt, size_t univ_id, const Expr& gterm);
  void inline iterBKList(const Expr& sr, const Expr& dt, size_t univ_id, const Expr& gterm);

  Expr defaultWriteExpr;
  Expr defaultReadExpr;
  Expr defaultPlusExpr;
  Expr  defaultMinusExpr ;
  Expr  defaultMultExpr ;
  Expr  defaultDivideExpr;
  Expr  defaultPowExpr ;

  Expr getHead(const Expr& e) ;
  Expr getHeadExpr(const Expr& e) ;



  CDList<Expr> null_cdlist;

  Theorem d_transThm;

  inline  void  pushBackList(const Expr& node, Expr ex);
  inline  void  pushForwList(const Expr& node, Expr ex);
  
  
  ExprMap<CDList<std::vector<Expr> >* > d_mtrigs_inst; //map expr to bindings
  
  ExprMap<CDList<Expr>* > d_same_head_expr; //map an expr to a list of expres shard the same head
  ExprMap<CDList<Expr>* > d_eq_list; //the equalities list

  CDList<Theorem> d_eqsUpdate; //the equalities list collected from update()
  CDO<size_t> d_lastEqsUpdatePos;

  CDList<Expr > d_eqs; //the equalities list
  CDO<size_t > d_eqs_pos; //the equalities list

  ExprMap<CDO<size_t>* > d_eq_pos;

  ExprMap<CDList<Expr>* > d_parent_list; 
  void  collectChangedTerms(CDList<Expr>& changed_terms);
  ExprMap<std::vector<Expr> > d_mtrigs_bvorder;

  int loc_gterm(const std::vector<Expr>& border,
		const Expr& gterm, 
		int pos);

  void  recSearchCover(const std::vector<Expr>& border,
		       const std::vector<Expr>& mtrigs, 
		       int cur_depth, 
		       std::vector<std::vector<Expr> >& instSet,
		       std::vector<Expr>& cur_inst
		       );

  void  searchCover(const Expr& thm, 
		    const std::vector<Expr>& border,
		    std::vector<std::vector<Expr> >& instSet
		    );


  std::map<Type, std::vector<Expr>,TypeComp > d_typeExprMap;
  std::set<std::string> cacheHead;

  StatCounter d_allInstCount ; //the number instantiations asserted in SAT
  StatCounter d_allInstCount2 ; 
  StatCounter d_totalInstCount ;// the total number of instantiations.
  StatCounter d_trueInstCount;//the number of instantiation simplified to be true.
  StatCounter d_abInstCount;

  //  size_t d_totalInstCount;
  //  size_t d_trueInstCount;
  //  size_t d_abInstCount;
  


  std::vector<Theorem> d_cacheTheorem;
  size_t d_cacheThmPos;

  void addNotify(const Expr& e);

  int sendInstNew();

  CDMap<Expr, std::set<std::vector<Expr> > > d_instHistory;//the history of instantiations
  //map univ to the trig, gterm and result

  ExprMap<int> d_thmCount; 
  ExprMap<size_t> d_totalThmCount; 

  ExprMap<CDMap<Expr, bool>* > d_bindHistory; //the history of instantiations
  ExprMap<std::hash_map<Expr, bool>* > d_bindGlobalHistory; //the history of instantiations

  ExprMap<std::hash_map<Expr, Theorem>* > d_bindGlobalThmHistory; //the history of instantiations

  ExprMap<std::set<std::vector<Expr> > > d_instHistoryGlobal;//the history of instantiations

  
  ExprMap<std::vector<Expr> > d_subTermsMap;
  //std::map<Expr, std::vector<Expr> > d_subTermsMap;
  const std::vector<Expr>& getSubTerms(const Expr& e);


  void simplifyExprMap(ExprMap<Expr>& orgExprMap);
  void simplifyVectorExprMap(std::vector<ExprMap<Expr> >& orgVectorExprMap);
  std::string exprMap2string(const ExprMap<Expr>& vec);
  std::string exprMap2stringSimplify(const ExprMap<Expr>& vec);
  std::string exprMap2stringSig(const ExprMap<Expr>& vec);

  //ExprMap<int > d_thmTimes; 
  void enqueueInst(const Theorem, const Theorem); 
  void enqueueInst(const Theorem& univ, const std::vector<Expr>& bind, const Expr& gterm);
  void enqueueInst(size_t univ_id , const std::vector<Expr>& bind, const Expr& gterm);
  void enqueueInst(const Theorem& univ, 
		   Trigger& trig,
		   const std::vector<Expr>& binds,  
		   const Expr& gterm
		   );
    
  void synCheckSat(ExprMap<ExprMap<std::vector<dynTrig>* >* >& , bool);
  void synCheckSat(bool);
  void semCheckSat(bool);
  void naiveCheckSat(bool);

  bool insted(const Theorem & univ, const std::vector<Expr>& binds);
  void synInst(const Theorem & univ,  const CDList<Expr>& allterms, size_t tBegin);

  void synFullInst(const Theorem & univ,  const CDList<Expr>& allterms,	size_t tBegin);

  void arrayHeuristic(const Trigger& trig, size_t univid);
  
  Expr simpRAWList(const Expr& org);

  void synNewInst(size_t univ_id, const std::vector<Expr>& binds, const Expr& gterm, const Trigger& trig );
  void synMultInst(const Theorem & univ,  const CDList<Expr>& allterms,	 size_t tBegin);

  void synPartInst(const Theorem & univ,  const CDList<Expr>& allterms,	 size_t tBegin);

  void semInst(const Theorem & univ, size_t tBegin);


  void goodSynMatch(const Expr& e,
		    const std::vector<Expr> & boundVars,
		    std::vector<std::vector<Expr> >& instBindsTerm,
		    std::vector<Expr>& instGterm,
		    const CDList<Expr>& allterms,		       
		    size_t tBegin);
  void goodSynMatchNewTrig(const Trigger& trig,
			   const std::vector<Expr> & boundVars,
			   std::vector<std::vector<Expr> >& instBinds,
			   std::vector<Expr>& instGterms,
			   const CDList<Expr>& allterms,		       
			   size_t tBegin);

  bool goodSynMatchNewTrig(const Trigger& trig,
			   const std::vector<Expr> & boundVars,
			   std::vector<std::vector<Expr> >& instBinds,
			   std::vector<Expr>& instGterms,
			   const Expr& gterm);

  void matchListOld(const CDList<Expr>& list, size_t gbegin, size_t gend);
    //  void matchListOld(const Expr& gterm);
  void matchListNew(ExprMap<ExprMap<std::vector<dynTrig>*>*>& new_trigs,
		    const CDList<Expr>& list,
		    size_t gbegin,
		    size_t gend);
  
  void delNewTrigs(ExprMap<ExprMap<std::vector<dynTrig>*>*>& new_trigs);
  void combineOldNewTrigs(ExprMap<ExprMap<std::vector<dynTrig>*>*>& new_trigs);

  inline void add_parent(const Expr& parent);

  void newTopMatch(const Expr& gterm, 
		   const Expr& vterm, 
		   std::vector<ExprMap<Expr> >& binds, 
		   const Trigger& trig);

  void newTopMatchSig(const Expr& gterm, 
		      const Expr& vterm, 
		      std::vector<ExprMap<Expr> >& binds, 
		      const Trigger& trig);
  
  void newTopMatchNoSig(const Expr& gterm, 
			const Expr& vterm, 
			std::vector<ExprMap<Expr> >& binds, 
			const Trigger& trig);



  void newTopMatchBackupOnly(const Expr& gterm, 
			     const Expr& vterm, 
			     std::vector<ExprMap<Expr> >& binds, 
			     const Trigger& trig);


  bool synMatchTopPred(const Expr& gterm, const Trigger trig, ExprMap<Expr>& env);

  //  inline bool matchChild(const Expr& gterm, const Expr& vterm, ExprMap<Expr>& env);
  //  inline void matchChild(const Expr& gterm, const Expr& vterm, std::vector<ExprMap<Expr> >& env);
  
  bool recSynMatch(const Expr& gterm, const Expr& vterm, ExprMap<Expr>& env);

  bool recMultMatch(const Expr& gterm,const Expr& vterm, std::vector<ExprMap<Expr> >& binds);
  bool recMultMatchDebug(const Expr& gterm,const Expr& vterm, std::vector<ExprMap<Expr> >& binds);
  bool recMultMatchNewWay(const Expr& gterm,const Expr& vterm, std::vector<ExprMap<Expr> >& binds);
  bool recMultMatchOldWay(const Expr& gterm,const Expr& vterm, std::vector<ExprMap<Expr> >& binds);

  inline bool multMatchChild(const Expr& gterm, const Expr& vterm, std::vector<ExprMap<Expr> >& binds, bool top=false);
  inline bool multMatchTop(const Expr& gterm, const Expr& vterm, std::vector<ExprMap<Expr> >& binds);


  bool recSynMatchBackupOnly(const Expr& gterm, const Expr& vterm, ExprMap<Expr>& env);

  bool hasGoodSynInstNewTrigOld(Trigger& trig, 
				std::vector<Expr> & boundVars, 
				std::vector<std::vector<Expr> >& instBinds, 
				std::vector<Expr>& instGterms, 
				const CDList<Expr>& allterms,		       
				size_t tBegin); 
  
  bool hasGoodSynInstNewTrig(Trigger& trig, 
			     const std::vector<Expr> & boundVars, 
   			     std::vector<std::vector<Expr> >& instBinds, 
 			     std::vector<Expr>& instGterms, 
 			     const CDList<Expr>& allterms,		       
 			     size_t tBegin); 


  bool hasGoodSynMultiInst(const Expr& e,
			   std::vector<Expr>& bVars,
			   std::vector<std::vector<Expr> >& instSet,
			   const CDList<Expr>& allterms,		       
			   size_t tBegin);
  
  void recGoodSemMatch(const Expr& e,
		       const std::vector<Expr>& bVars,
		       std::vector<Expr>& newInst,
		       std::set<std::vector<Expr> >& instSet);
  
  bool hasGoodSemInst(const Expr& e,
		   std::vector<Expr>& bVars,
		   std::set<std::vector<Expr> >& instSet,
		   size_t tBegin);

  bool isTransLike (const std::vector<Expr>& cur_trig);
  bool isTrans2Like (const std::vector<Expr>& all_terms, const Expr& tr2);
  

  static const size_t MAX_TRIG_BVS=15;
  Expr d_mybvs[MAX_TRIG_BVS];
 
  Expr recGeneralTrig(const Expr& trig, ExprMap<Expr>& bvs, size_t& mybvs_count);
  Expr generalTrig(const Expr& trig, ExprMap<Expr>& bvs);

  ExprMap<CDMap<Expr, CDList<dynTrig>* >* > d_allmap_trigs;
  
  CDList<Trigger> d_alltrig_list;

  void registerTrig(ExprMap<ExprMap<std::vector<dynTrig>* >* >& cur_trig_map,
		   Trigger trig, 
		   const std::vector<Expr> thmBVs, 
		   size_t univ_id);
    
  void registerTrigReal(Trigger trig, const std::vector<Expr>, size_t univ_id);

  bool canMatch(const Expr& t1, const Expr& t2, ExprMap<Expr>& env);
  void setGround(const Expr& gterm, const Expr& trig, const Theorem& univ, const std::vector<Expr>& subTerms) ;    

  //  std::string getHead(const Expr& e) ;
  void setupTriggers(ExprMap<ExprMap<std::vector<dynTrig>* >*>& trig_maps,
		     const Theorem& thm, 
		     size_t univs_id);

  void saveContext();


  /*! \brief categorizes all the terms contained in an expressions by
   *type.
   *
   * Updates d_contextTerms, d_contextMap, d_contextCache accordingly.
   * returns true if the expression does not contain bound variables, false
   * otherwise.
   */

  
 public:
  TheoryQuant(TheoryCore* core); //!< Constructor
  ~TheoryQuant(); //! Destructor

  QuantProofRules* createProofRules();
  

 
  void addSharedTerm(const Expr& e) {} //!< Theory interface
  
  /*! \brief Theory interface function to assert quantified formulas
   *
   * pushes in negations and converts to either universally or existentially 
   * quantified theorems. Universals are stored in a database while 
   * existentials are enqueued to be handled by the search engine.
   */
  void assertFact(const Theorem& e); 
  

  /* \brief Checks the satisfiability of the universal theorems stored in a 
   * databse by instantiating them.
   *
   * There are two algorithms that the checkSat function uses to find 
   * instnatiations. The first algortihm looks for instanitations in a saved 
   * database of previous instantiations that worked in proving an earlier
   * theorem unsatifiable. All of the class variables with the word saved in
   * them  are for the use of this algorithm. The other algorithm uses terms 
   * found in the assertions that exist in the particular context when 
   * checkSat is called. All of the class variables with the word context in
   * them are used for the second algorithm.
   */
  void checkSat(bool fullEffort);
  void setup(const Expr& e); 
  
  int help(int i);
  
  void update(const Theorem& e, const Expr& d);
  /*!\brief Used to notify the quantifier algorithm of possible 
   * instantiations that were used in proving a context inconsistent.
   */
  void debug(int i);
  void notifyInconsistent(const Theorem& thm); 
  //! computes the type of a quantified term. Always a  boolean.
  void computeType(const Expr& e); 
  Expr computeTCC(const Expr& e);
  
  virtual Expr parseExprOp(const Expr& e);

  ExprStream& print(ExprStream& os, const Expr& e);
 };
 
}

#endif