mirror of
				https://github.com/Z3Prover/z3
				synced 2025-11-03 21:09:11 +00:00 
			
		
		
		
	getting rid of DOS line endings
This commit is contained in:
		
							parent
							
								
									9a2fe83697
								
							
						
					
					
						commit
						fc62be37b6
					
				
					 8 changed files with 4023 additions and 4023 deletions
				
			
		| 
						 | 
				
			
			@ -1,195 +1,195 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2011 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    iz3base.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
   Base class for interpolators. Includes an AST manager and a scoping
 | 
			
		||||
   object as bases.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Ken McMillan (kenmcmil)
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
#ifndef IZ3BASE_H
 | 
			
		||||
#define IZ3BASE_H
 | 
			
		||||
 | 
			
		||||
#include "iz3mgr.h"
 | 
			
		||||
#include "iz3scopes.h"
 | 
			
		||||
 | 
			
		||||
namespace hash_space {
 | 
			
		||||
  template <>
 | 
			
		||||
    class hash<func_decl *> {
 | 
			
		||||
  public:
 | 
			
		||||
    size_t operator()(func_decl * const &s) const {
 | 
			
		||||
      return (size_t) s;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Base class for interpolators. Includes an AST manager and a scoping
 | 
			
		||||
   object as bases. */
 | 
			
		||||
 
 | 
			
		||||
class iz3base : public iz3mgr, public scopes {
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
 | 
			
		||||
  /** Get the range in which an expression occurs. This is the
 | 
			
		||||
      smallest subtree containing all occurrences of the
 | 
			
		||||
      expression. */
 | 
			
		||||
  range &ast_range(ast);
 | 
			
		||||
 | 
			
		||||
  /** Get the scope of an expression. This is the set of tree nodes in
 | 
			
		||||
      which all of the expression's symbols are in scope. */
 | 
			
		||||
  range &ast_scope(ast);
 | 
			
		||||
 | 
			
		||||
  /** Get the range of a symbol. This is the smallest subtree containing
 | 
			
		||||
      all occurrences of the symbol. */ 
 | 
			
		||||
  range &sym_range(symb);
 | 
			
		||||
 | 
			
		||||
  /** Is an expression local (in scope in some frame)? */
 | 
			
		||||
 | 
			
		||||
  bool is_local(ast node){
 | 
			
		||||
    return !range_is_empty(ast_scope(node));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** Simplify an expression */
 | 
			
		||||
 | 
			
		||||
  ast simplify(ast);
 | 
			
		||||
 | 
			
		||||
  /** Constructor */
 | 
			
		||||
 | 
			
		||||
  iz3base(ast_manager &_m_manager,
 | 
			
		||||
	 const std::vector<ast> &_cnsts,
 | 
			
		||||
	 const std::vector<int> &_parents,
 | 
			
		||||
	 const std::vector<ast> &_theory)
 | 
			
		||||
    : iz3mgr(_m_manager), scopes(_parents)  {
 | 
			
		||||
    initialize(_cnsts,_parents,_theory);
 | 
			
		||||
    weak = false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  iz3base(const iz3mgr& other,
 | 
			
		||||
	 const std::vector<ast> &_cnsts,
 | 
			
		||||
	 const std::vector<int> &_parents,
 | 
			
		||||
	 const std::vector<ast> &_theory)
 | 
			
		||||
   : iz3mgr(other), scopes(_parents)  {
 | 
			
		||||
    initialize(_cnsts,_parents,_theory);
 | 
			
		||||
    weak = false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  iz3base(const iz3mgr& other,
 | 
			
		||||
	  const std::vector<std::vector<ast> > &_cnsts,
 | 
			
		||||
	 const std::vector<int> &_parents,
 | 
			
		||||
	 const std::vector<ast> &_theory)
 | 
			
		||||
   : iz3mgr(other), scopes(_parents)  {
 | 
			
		||||
    initialize(_cnsts,_parents,_theory);
 | 
			
		||||
    weak = false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  iz3base(const iz3mgr& other)
 | 
			
		||||
   : iz3mgr(other), scopes()  {
 | 
			
		||||
    weak = false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Set our options */
 | 
			
		||||
  void set_option(const std::string &name, const std::string &value){
 | 
			
		||||
    if(name == "weak" && value == "1") weak = true;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /* Are we doing weak interpolants? */
 | 
			
		||||
  bool weak_mode(){return weak;}
 | 
			
		||||
 | 
			
		||||
  /** Print interpolation problem to an SMTLIB format file */
 | 
			
		||||
  void print(const std::string &filename);
 | 
			
		||||
 | 
			
		||||
  /** Check correctness of a solutino to this problem. */
 | 
			
		||||
  void check_interp(const std::vector<ast> &itps, std::vector<ast> &theory);
 | 
			
		||||
 | 
			
		||||
  /** For convenience -- is this formula SAT? */
 | 
			
		||||
  bool is_sat(const std::vector<ast> &consts, ast &_proof);
 | 
			
		||||
 | 
			
		||||
  /** Interpolator for clauses, to be implemented */
 | 
			
		||||
  virtual void interpolate_clause(std::vector<ast> &lits, std::vector<ast> &itps){
 | 
			
		||||
    throw "no interpolator";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ast get_proof_check_assump(range &rng){
 | 
			
		||||
    std::vector<ast> cs(theory);
 | 
			
		||||
    cs.push_back(cnsts[rng.hi]);
 | 
			
		||||
    return make(And,cs);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  int frame_of_assertion(const ast &ass){
 | 
			
		||||
    stl_ext::hash_map<ast,int>::iterator it = frame_map.find(ass);
 | 
			
		||||
    if(it == frame_map.end())
 | 
			
		||||
      throw "unknown assertion";
 | 
			
		||||
    return it->second;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  void to_parents_vec_representation(const std::vector<ast> &_cnsts,
 | 
			
		||||
				     const ast &tree,
 | 
			
		||||
				     std::vector<ast> &cnsts,
 | 
			
		||||
				     std::vector<int> &parents,
 | 
			
		||||
				     std::vector<ast> &theory,
 | 
			
		||||
				     std::vector<int> &pos_map,
 | 
			
		||||
				     bool merge = false
 | 
			
		||||
				   );
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
  std::vector<ast> cnsts;
 | 
			
		||||
  std::vector<ast> theory;
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
 | 
			
		||||
  struct ranges {
 | 
			
		||||
    range rng;
 | 
			
		||||
    range scp;
 | 
			
		||||
    bool scope_computed;
 | 
			
		||||
    ranges(){scope_computed = false;}
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  stl_ext::hash_map<symb,range> sym_range_hash;
 | 
			
		||||
  stl_ext::hash_map<ast,ranges> ast_ranges_hash;
 | 
			
		||||
  stl_ext::hash_map<ast,ast> simplify_memo;
 | 
			
		||||
  stl_ext::hash_map<ast,int> frame_map;                      // map assertions to frames
 | 
			
		||||
 | 
			
		||||
  int frames;                               // number of frames
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
  void add_frame_range(int frame, ast t);
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  void initialize(const std::vector<ast> &_parts, const std::vector<int> &_parents, const std::vector<ast> &_theory);
 | 
			
		||||
 | 
			
		||||
  void initialize(const std::vector<std::vector<ast> > &_parts, const std::vector<int> &_parents, const std::vector<ast> &_theory);
 | 
			
		||||
 | 
			
		||||
  bool is_literal(ast n);
 | 
			
		||||
  void gather_conjuncts_rec(ast n, std::vector<ast> &conjuncts, stl_ext::hash_set<ast> &memo);
 | 
			
		||||
  void gather_conjuncts(ast n, std::vector<ast> &conjuncts);
 | 
			
		||||
  ast simplify_and(std::vector<ast> &conjuncts);
 | 
			
		||||
  ast simplify_with_lit_rec(ast n, ast lit, stl_ext::hash_map<ast,ast> &memo, int depth);
 | 
			
		||||
  ast simplify_with_lit(ast n, ast lit);  
 | 
			
		||||
  void find_children(const stl_ext::hash_set<ast> &cnsts_set,
 | 
			
		||||
		     const ast &tree,
 | 
			
		||||
		     std::vector<ast> &cnsts,
 | 
			
		||||
		     std::vector<int> &parents,
 | 
			
		||||
		     std::vector<ast> &conjuncts,
 | 
			
		||||
		     std::vector<int> &children,
 | 
			
		||||
		     std::vector<int> &pos_map,
 | 
			
		||||
		     bool merge
 | 
			
		||||
		     );
 | 
			
		||||
  bool weak;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
/*++
 | 
			
		||||
Copyright (c) 2011 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    iz3base.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
   Base class for interpolators. Includes an AST manager and a scoping
 | 
			
		||||
   object as bases.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Ken McMillan (kenmcmil)
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
#ifndef IZ3BASE_H
 | 
			
		||||
#define IZ3BASE_H
 | 
			
		||||
 | 
			
		||||
#include "iz3mgr.h"
 | 
			
		||||
#include "iz3scopes.h"
 | 
			
		||||
 | 
			
		||||
namespace hash_space {
 | 
			
		||||
  template <>
 | 
			
		||||
    class hash<func_decl *> {
 | 
			
		||||
  public:
 | 
			
		||||
    size_t operator()(func_decl * const &s) const {
 | 
			
		||||
      return (size_t) s;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Base class for interpolators. Includes an AST manager and a scoping
 | 
			
		||||
   object as bases. */
 | 
			
		||||
 
 | 
			
		||||
class iz3base : public iz3mgr, public scopes {
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
 | 
			
		||||
  /** Get the range in which an expression occurs. This is the
 | 
			
		||||
      smallest subtree containing all occurrences of the
 | 
			
		||||
      expression. */
 | 
			
		||||
  range &ast_range(ast);
 | 
			
		||||
 | 
			
		||||
  /** Get the scope of an expression. This is the set of tree nodes in
 | 
			
		||||
      which all of the expression's symbols are in scope. */
 | 
			
		||||
  range &ast_scope(ast);
 | 
			
		||||
 | 
			
		||||
  /** Get the range of a symbol. This is the smallest subtree containing
 | 
			
		||||
      all occurrences of the symbol. */ 
 | 
			
		||||
  range &sym_range(symb);
 | 
			
		||||
 | 
			
		||||
  /** Is an expression local (in scope in some frame)? */
 | 
			
		||||
 | 
			
		||||
  bool is_local(ast node){
 | 
			
		||||
    return !range_is_empty(ast_scope(node));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** Simplify an expression */
 | 
			
		||||
 | 
			
		||||
  ast simplify(ast);
 | 
			
		||||
 | 
			
		||||
  /** Constructor */
 | 
			
		||||
 | 
			
		||||
  iz3base(ast_manager &_m_manager,
 | 
			
		||||
	 const std::vector<ast> &_cnsts,
 | 
			
		||||
	 const std::vector<int> &_parents,
 | 
			
		||||
	 const std::vector<ast> &_theory)
 | 
			
		||||
    : iz3mgr(_m_manager), scopes(_parents)  {
 | 
			
		||||
    initialize(_cnsts,_parents,_theory);
 | 
			
		||||
    weak = false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  iz3base(const iz3mgr& other,
 | 
			
		||||
	 const std::vector<ast> &_cnsts,
 | 
			
		||||
	 const std::vector<int> &_parents,
 | 
			
		||||
	 const std::vector<ast> &_theory)
 | 
			
		||||
   : iz3mgr(other), scopes(_parents)  {
 | 
			
		||||
    initialize(_cnsts,_parents,_theory);
 | 
			
		||||
    weak = false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  iz3base(const iz3mgr& other,
 | 
			
		||||
	  const std::vector<std::vector<ast> > &_cnsts,
 | 
			
		||||
	 const std::vector<int> &_parents,
 | 
			
		||||
	 const std::vector<ast> &_theory)
 | 
			
		||||
   : iz3mgr(other), scopes(_parents)  {
 | 
			
		||||
    initialize(_cnsts,_parents,_theory);
 | 
			
		||||
    weak = false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  iz3base(const iz3mgr& other)
 | 
			
		||||
   : iz3mgr(other), scopes()  {
 | 
			
		||||
    weak = false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /* Set our options */
 | 
			
		||||
  void set_option(const std::string &name, const std::string &value){
 | 
			
		||||
    if(name == "weak" && value == "1") weak = true;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  /* Are we doing weak interpolants? */
 | 
			
		||||
  bool weak_mode(){return weak;}
 | 
			
		||||
 | 
			
		||||
  /** Print interpolation problem to an SMTLIB format file */
 | 
			
		||||
  void print(const std::string &filename);
 | 
			
		||||
 | 
			
		||||
  /** Check correctness of a solutino to this problem. */
 | 
			
		||||
  void check_interp(const std::vector<ast> &itps, std::vector<ast> &theory);
 | 
			
		||||
 | 
			
		||||
  /** For convenience -- is this formula SAT? */
 | 
			
		||||
  bool is_sat(const std::vector<ast> &consts, ast &_proof);
 | 
			
		||||
 | 
			
		||||
  /** Interpolator for clauses, to be implemented */
 | 
			
		||||
  virtual void interpolate_clause(std::vector<ast> &lits, std::vector<ast> &itps){
 | 
			
		||||
    throw "no interpolator";
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  ast get_proof_check_assump(range &rng){
 | 
			
		||||
    std::vector<ast> cs(theory);
 | 
			
		||||
    cs.push_back(cnsts[rng.hi]);
 | 
			
		||||
    return make(And,cs);
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  int frame_of_assertion(const ast &ass){
 | 
			
		||||
    stl_ext::hash_map<ast,int>::iterator it = frame_map.find(ass);
 | 
			
		||||
    if(it == frame_map.end())
 | 
			
		||||
      throw "unknown assertion";
 | 
			
		||||
    return it->second;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  void to_parents_vec_representation(const std::vector<ast> &_cnsts,
 | 
			
		||||
				     const ast &tree,
 | 
			
		||||
				     std::vector<ast> &cnsts,
 | 
			
		||||
				     std::vector<int> &parents,
 | 
			
		||||
				     std::vector<ast> &theory,
 | 
			
		||||
				     std::vector<int> &pos_map,
 | 
			
		||||
				     bool merge = false
 | 
			
		||||
				   );
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
  std::vector<ast> cnsts;
 | 
			
		||||
  std::vector<ast> theory;
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
 | 
			
		||||
  struct ranges {
 | 
			
		||||
    range rng;
 | 
			
		||||
    range scp;
 | 
			
		||||
    bool scope_computed;
 | 
			
		||||
    ranges(){scope_computed = false;}
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  stl_ext::hash_map<symb,range> sym_range_hash;
 | 
			
		||||
  stl_ext::hash_map<ast,ranges> ast_ranges_hash;
 | 
			
		||||
  stl_ext::hash_map<ast,ast> simplify_memo;
 | 
			
		||||
  stl_ext::hash_map<ast,int> frame_map;                      // map assertions to frames
 | 
			
		||||
 | 
			
		||||
  int frames;                               // number of frames
 | 
			
		||||
 | 
			
		||||
 protected:
 | 
			
		||||
  void add_frame_range(int frame, ast t);
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  void initialize(const std::vector<ast> &_parts, const std::vector<int> &_parents, const std::vector<ast> &_theory);
 | 
			
		||||
 | 
			
		||||
  void initialize(const std::vector<std::vector<ast> > &_parts, const std::vector<int> &_parents, const std::vector<ast> &_theory);
 | 
			
		||||
 | 
			
		||||
  bool is_literal(ast n);
 | 
			
		||||
  void gather_conjuncts_rec(ast n, std::vector<ast> &conjuncts, stl_ext::hash_set<ast> &memo);
 | 
			
		||||
  void gather_conjuncts(ast n, std::vector<ast> &conjuncts);
 | 
			
		||||
  ast simplify_and(std::vector<ast> &conjuncts);
 | 
			
		||||
  ast simplify_with_lit_rec(ast n, ast lit, stl_ext::hash_map<ast,ast> &memo, int depth);
 | 
			
		||||
  ast simplify_with_lit(ast n, ast lit);  
 | 
			
		||||
  void find_children(const stl_ext::hash_set<ast> &cnsts_set,
 | 
			
		||||
		     const ast &tree,
 | 
			
		||||
		     std::vector<ast> &cnsts,
 | 
			
		||||
		     std::vector<int> &parents,
 | 
			
		||||
		     std::vector<ast> &conjuncts,
 | 
			
		||||
		     std::vector<int> &children,
 | 
			
		||||
		     std::vector<int> &pos_map,
 | 
			
		||||
		     bool merge
 | 
			
		||||
		     );
 | 
			
		||||
  bool weak;
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,321 +1,321 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2011 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    iz3scopes.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
   Calculations with scopes, for both sequence and tree interpolation.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Ken McMillan (kenmcmil)
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
#include "iz3scopes.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** computes the least common ancestor of two nodes in the tree, or SHRT_MAX if none */
 | 
			
		||||
int scopes::tree_lca(int n1, int n2){
 | 
			
		||||
  if(!tree_mode())
 | 
			
		||||
    return std::max(n1,n2);
 | 
			
		||||
  if(n1 == SHRT_MIN) return n2;
 | 
			
		||||
  if(n2 == SHRT_MIN) return n1;
 | 
			
		||||
  if(n1 == SHRT_MAX || n2 == SHRT_MAX) return SHRT_MAX;
 | 
			
		||||
  while(n1 != n2){
 | 
			
		||||
    if(n1 == SHRT_MAX || n2 == SHRT_MAX) return SHRT_MAX;
 | 
			
		||||
    assert(n1 >= 0 && n2 >= 0 && n1 < (int)parents.size() && n2 < (int)parents.size());
 | 
			
		||||
    if(n1 < n2) n1 = parents[n1];
 | 
			
		||||
    else n2 = parents[n2];
 | 
			
		||||
  }
 | 
			
		||||
  return n1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** computes the greatest common descendant two nodes in the tree, or SHRT_MIN if none */
 | 
			
		||||
int scopes::tree_gcd(int n1, int n2){
 | 
			
		||||
  if(!tree_mode())
 | 
			
		||||
    return std::min(n1,n2);
 | 
			
		||||
  int foo = tree_lca(n1,n2);
 | 
			
		||||
  if(foo == n1) return n2;
 | 
			
		||||
  if(foo == n2) return n1;
 | 
			
		||||
  return SHRT_MIN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef FULL_TREE
 | 
			
		||||
 | 
			
		||||
/** test whether a tree node is contained in a range */
 | 
			
		||||
bool scopes::in_range(int n, const range &rng){
 | 
			
		||||
  return tree_lca(rng.lo,n) == n && tree_gcd(rng.hi,n) == n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** test whether two ranges of tree nodes intersect */
 | 
			
		||||
bool scopes::ranges_intersect(const range &rng1, const range &rng2){
 | 
			
		||||
  return tree_lca(rng1.lo,rng2.hi) == rng2.hi && tree_lca(rng1.hi,rng2.lo) == rng1.hi;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool scopes::range_contained(const range &rng1, const range &rng2){
 | 
			
		||||
  return tree_lca(rng2.lo,rng1.lo) == rng1.lo
 | 
			
		||||
  && tree_lca(rng1.hi,rng2.hi) == rng2.hi;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
scopes::range scopes::range_lub(const range &rng1, const range &rng2){
 | 
			
		||||
	range res;
 | 
			
		||||
	res.lo = tree_gcd(rng1.lo,rng2.lo);
 | 
			
		||||
	res.hi = tree_lca(rng1.hi,rng2.hi);
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
  
 | 
			
		||||
scopes::range scopes::range_glb(const range &rng1, const range &rng2){
 | 
			
		||||
	range res;
 | 
			
		||||
	res.lo = tree_lca(rng1.lo,rng2.lo);
 | 
			
		||||
	res.hi = tree_gcd(rng1.hi,rng2.hi);
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  namespace std {
 | 
			
		||||
    template <>
 | 
			
		||||
      class hash<scopes::range_lo > {
 | 
			
		||||
       public:
 | 
			
		||||
          size_t operator()(const scopes::range_lo &p) const {
 | 
			
		||||
            return p.lo + (size_t)p.next;
 | 
			
		||||
          }
 | 
			
		||||
      };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <> inline
 | 
			
		||||
  size_t stdext::hash_value<scopes::range_lo >(const scopes::range_lo& p)
 | 
			
		||||
  {	
 | 
			
		||||
	std::hash<scopes::range_lo> h;
 | 
			
		||||
	return h(p);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  namespace std {
 | 
			
		||||
    template <>
 | 
			
		||||
	   class less<scopes::range_lo > {
 | 
			
		||||
	   public:
 | 
			
		||||
		   bool operator()(const scopes::range_lo &x, const scopes::range_lo &y) const {
 | 
			
		||||
		      return x.lo < y.lo || x.lo == y.lo && (size_t)x.next < (size_t)y.next;
 | 
			
		||||
		   }
 | 
			
		||||
	   };
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
  struct range_op {
 | 
			
		||||
	scopes::range_lo *x, *y;
 | 
			
		||||
	int hi;
 | 
			
		||||
	range_op(scopes::range_lo *_x, scopes::range_lo *_y, int _hi){
 | 
			
		||||
		x = _x; y = _y; hi = _hi;
 | 
			
		||||
	}
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
   namespace std {
 | 
			
		||||
    template <>
 | 
			
		||||
      class hash<range_op > {
 | 
			
		||||
       public:
 | 
			
		||||
          size_t operator()(const range_op &p) const {
 | 
			
		||||
            return (size_t) p.x + (size_t)p.y + p.hi;
 | 
			
		||||
          }
 | 
			
		||||
      };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <> inline
 | 
			
		||||
  size_t stdext::hash_value<range_op >(const range_op& p)
 | 
			
		||||
  {	
 | 
			
		||||
	std::hash<range_op> h;
 | 
			
		||||
	return h(p);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  namespace std {
 | 
			
		||||
    template <>
 | 
			
		||||
	   class less<range_op > {
 | 
			
		||||
	   public:
 | 
			
		||||
		   bool operator()(const range_op &x, const range_op &y) const {
 | 
			
		||||
		      return (size_t)x.x < (size_t)y.x || x.x == y.x &&
 | 
			
		||||
				        ((size_t)x.y < (size_t)y.y || x.y == y.y && x.hi < y.hi);
 | 
			
		||||
		   }
 | 
			
		||||
	   };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  struct range_tables {
 | 
			
		||||
	  hash_map<scopes::range_lo, scopes::range_lo *> unique;
 | 
			
		||||
	  hash_map<range_op,scopes::range_lo *> lub;
 | 
			
		||||
	  hash_map<range_op,scopes::range_lo *> glb;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  scopes::range_lo *scopes::find_range_lo(int lo, range_lo *next){
 | 
			
		||||
	  range_lo foo(lo,next);
 | 
			
		||||
	  std::pair<range_lo,range_lo *> baz(foo,(range_lo *)0);
 | 
			
		||||
	  std::pair<hash_map<range_lo,scopes::range_lo *>::iterator,bool> bar = rt->unique.insert(baz);
 | 
			
		||||
	  if(bar.second)
 | 
			
		||||
		  bar.first->second = new range_lo(lo,next);
 | 
			
		||||
	  return bar.first->second;
 | 
			
		||||
	  //std::pair<hash_set<scopes::range_lo>::iterator,bool> bar = rt->unique.insert(foo);
 | 
			
		||||
	  // const range_lo *baz = &*(bar.first); 
 | 
			
		||||
	  // return (range_lo *)baz; // exit const hell
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  scopes::range_lo *scopes::range_lub_lo(range_lo *rng1, range_lo *rng2){
 | 
			
		||||
    if(!rng1) return rng2;
 | 
			
		||||
    if(!rng2) return rng1;
 | 
			
		||||
    if(rng1->lo > rng2->lo)
 | 
			
		||||
      std::swap(rng1,rng2);
 | 
			
		||||
	std::pair<range_op,range_lo *> foo(range_op(rng1,rng2,0),(range_lo *)0);
 | 
			
		||||
	std::pair<hash_map<range_op,scopes::range_lo *>::iterator,bool> bar = rt->lub.insert(foo);
 | 
			
		||||
	range_lo *&res = bar.first->second;
 | 
			
		||||
	if(!bar.second) return res;
 | 
			
		||||
    if(!(rng1->next && rng1->next->lo <= rng2->lo)){
 | 
			
		||||
      for(int lo = rng1->lo; lo <= rng2->lo; lo = parents[lo])
 | 
			
		||||
		  if(lo == rng2->lo)
 | 
			
		||||
		    {rng2 = rng2->next; break;}
 | 
			
		||||
    }
 | 
			
		||||
    range_lo *baz = range_lub_lo(rng1->next,rng2);
 | 
			
		||||
    res = find_range_lo(rng1->lo,baz);
 | 
			
		||||
	return res;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  scopes::range_lo *scopes::range_glb_lo(range_lo *rng1, range_lo *rng2, int hi){
 | 
			
		||||
	  if(!rng1) return rng1;
 | 
			
		||||
	  if(!rng2) return rng2;
 | 
			
		||||
	  if(rng1->lo > rng2->lo)
 | 
			
		||||
		  std::swap(rng1,rng2);
 | 
			
		||||
	  std::pair<range_op,range_lo *> cand(range_op(rng1,rng2,hi),(range_lo *)0);
 | 
			
		||||
	  std::pair<hash_map<range_op,scopes::range_lo *>::iterator,bool> bar = rt->glb.insert(cand);
 | 
			
		||||
	  range_lo *&res = bar.first->second;
 | 
			
		||||
	  if(!bar.second) return res;
 | 
			
		||||
	  range_lo *foo;
 | 
			
		||||
	  if(!(rng1->next && rng1->next->lo <= rng2->lo)){
 | 
			
		||||
		  int lim = hi;
 | 
			
		||||
		  if(rng1->next) lim = std::min(lim,rng1->next->lo);
 | 
			
		||||
		  int a = rng1->lo, b = rng2->lo;
 | 
			
		||||
		  while(a != b && b <= lim){
 | 
			
		||||
			  a = parents[a];
 | 
			
		||||
			  if(a > b)std::swap(a,b);
 | 
			
		||||
		  }
 | 
			
		||||
		  if(a == b && b <= lim){
 | 
			
		||||
			  foo = range_glb_lo(rng1->next,rng2->next,hi);
 | 
			
		||||
			  foo = find_range_lo(b,foo);
 | 
			
		||||
		  }
 | 
			
		||||
		  else
 | 
			
		||||
			  foo = range_glb_lo(rng2,rng1->next,hi);
 | 
			
		||||
	  }
 | 
			
		||||
	  else foo = range_glb_lo(rng1->next,rng2,hi);
 | 
			
		||||
	  res = foo;
 | 
			
		||||
	  return res;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** computes the lub (smallest containing subtree) of two ranges */
 | 
			
		||||
  scopes::range scopes::range_lub(const range &rng1, const range &rng2){
 | 
			
		||||
    int hi = tree_lca(rng1.hi,rng2.hi);
 | 
			
		||||
	if(hi == SHRT_MAX) return range_full();
 | 
			
		||||
    range_lo *lo = range_lub_lo(rng1.lo,rng2.lo);
 | 
			
		||||
    return range(hi,lo);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** computes the glb (intersection) of two ranges */
 | 
			
		||||
  scopes::range scopes::range_glb(const range &rng1, const range &rng2){
 | 
			
		||||
	if(rng1.hi == SHRT_MAX) return rng2;
 | 
			
		||||
	if(rng2.hi == SHRT_MAX) return rng1;
 | 
			
		||||
    int hi = tree_gcd(rng1.hi,rng2.hi);
 | 
			
		||||
    range_lo *lo = hi == SHRT_MIN ? 0 : range_glb_lo(rng1.lo,rng2.lo,hi);
 | 
			
		||||
	if(!lo) hi = SHRT_MIN;
 | 
			
		||||
    return range(hi,lo);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** is this range empty? */
 | 
			
		||||
  bool scopes::range_is_empty(const range &rng){
 | 
			
		||||
    return rng.hi == SHRT_MIN;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** return an empty range */
 | 
			
		||||
  scopes::range scopes::range_empty(){
 | 
			
		||||
    return range(SHRT_MIN,0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** return a full range */
 | 
			
		||||
  scopes::range scopes::range_full(){
 | 
			
		||||
    return range(SHRT_MAX,0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** return the maximal element of a range */
 | 
			
		||||
  int scopes::range_max(const range &rng){
 | 
			
		||||
    return rng.hi;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** return a minimal (not necessarily unique) element of a range */
 | 
			
		||||
  int scopes::range_min(const range &rng){
 | 
			
		||||
	if(rng.hi == SHRT_MAX) return SHRT_MIN;
 | 
			
		||||
    return rng.lo ? rng.lo->lo : SHRT_MAX;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /** return range consisting of downward closure of a point */
 | 
			
		||||
  scopes::range scopes::range_downward(int _hi){
 | 
			
		||||
    std::vector<bool> descendants(parents.size());
 | 
			
		||||
    for(int i = descendants.size() - 1; i >= 0 ; i--)
 | 
			
		||||
      descendants[i] = i == _hi || parents[i] < parents.size() && descendants[parents[i]];
 | 
			
		||||
    for(unsigned i = 0; i < descendants.size() - 1; i++)
 | 
			
		||||
      if(parents[i] < parents.size())
 | 
			
		||||
	descendants[parents[i]] = false;
 | 
			
		||||
    range_lo *foo = 0;
 | 
			
		||||
    for(int i = descendants.size() - 1; i >= 0; --i)
 | 
			
		||||
      if(descendants[i]) foo = find_range_lo(i,foo);
 | 
			
		||||
    return range(_hi,foo);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** add an element to a range */
 | 
			
		||||
  void scopes::range_add(int i, range &n){
 | 
			
		||||
    range foo = range(i, find_range_lo(i,0));
 | 
			
		||||
    n = range_lub(foo,n);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** Choose an element of rng1 that is near to rng2 */
 | 
			
		||||
  int scopes::range_near(const range &rng1, const range &rng2){
 | 
			
		||||
 | 
			
		||||
    int frame;
 | 
			
		||||
    int thing = tree_lca(rng1.hi,rng2.hi);
 | 
			
		||||
	if(thing != rng1.hi) return rng1.hi;
 | 
			
		||||
	range line = range(rng1.hi,find_range_lo(rng2.hi,(range_lo *)0));
 | 
			
		||||
	line = range_glb(line,rng1);
 | 
			
		||||
	return range_min(line);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /** test whether a tree node is contained in a range */
 | 
			
		||||
  bool scopes::in_range(int n, const range &rng){
 | 
			
		||||
	  range r = range_empty();
 | 
			
		||||
	  range_add(n,r);
 | 
			
		||||
	  r = range_glb(rng,r);
 | 
			
		||||
	  return !range_is_empty(r);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** test whether two ranges of tree nodes intersect */
 | 
			
		||||
  bool scopes::ranges_intersect(const range &rng1, const range &rng2){
 | 
			
		||||
	  range r = range_glb(rng1,rng2);
 | 
			
		||||
	  return !range_is_empty(r);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  bool scopes::range_contained(const range &rng1, const range &rng2){
 | 
			
		||||
	  range r = range_glb(rng1,rng2);
 | 
			
		||||
	  return r.hi == rng1.hi && r.lo == rng1.lo;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/*++
 | 
			
		||||
Copyright (c) 2011 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    iz3scopes.cpp
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
   Calculations with scopes, for both sequence and tree interpolation.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Ken McMillan (kenmcmil)
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
#include <assert.h>
 | 
			
		||||
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
 | 
			
		||||
#include "iz3scopes.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/** computes the least common ancestor of two nodes in the tree, or SHRT_MAX if none */
 | 
			
		||||
int scopes::tree_lca(int n1, int n2){
 | 
			
		||||
  if(!tree_mode())
 | 
			
		||||
    return std::max(n1,n2);
 | 
			
		||||
  if(n1 == SHRT_MIN) return n2;
 | 
			
		||||
  if(n2 == SHRT_MIN) return n1;
 | 
			
		||||
  if(n1 == SHRT_MAX || n2 == SHRT_MAX) return SHRT_MAX;
 | 
			
		||||
  while(n1 != n2){
 | 
			
		||||
    if(n1 == SHRT_MAX || n2 == SHRT_MAX) return SHRT_MAX;
 | 
			
		||||
    assert(n1 >= 0 && n2 >= 0 && n1 < (int)parents.size() && n2 < (int)parents.size());
 | 
			
		||||
    if(n1 < n2) n1 = parents[n1];
 | 
			
		||||
    else n2 = parents[n2];
 | 
			
		||||
  }
 | 
			
		||||
  return n1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** computes the greatest common descendant two nodes in the tree, or SHRT_MIN if none */
 | 
			
		||||
int scopes::tree_gcd(int n1, int n2){
 | 
			
		||||
  if(!tree_mode())
 | 
			
		||||
    return std::min(n1,n2);
 | 
			
		||||
  int foo = tree_lca(n1,n2);
 | 
			
		||||
  if(foo == n1) return n2;
 | 
			
		||||
  if(foo == n2) return n1;
 | 
			
		||||
  return SHRT_MIN;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifndef FULL_TREE
 | 
			
		||||
 | 
			
		||||
/** test whether a tree node is contained in a range */
 | 
			
		||||
bool scopes::in_range(int n, const range &rng){
 | 
			
		||||
  return tree_lca(rng.lo,n) == n && tree_gcd(rng.hi,n) == n;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** test whether two ranges of tree nodes intersect */
 | 
			
		||||
bool scopes::ranges_intersect(const range &rng1, const range &rng2){
 | 
			
		||||
  return tree_lca(rng1.lo,rng2.hi) == rng2.hi && tree_lca(rng1.hi,rng2.lo) == rng1.hi;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
bool scopes::range_contained(const range &rng1, const range &rng2){
 | 
			
		||||
  return tree_lca(rng2.lo,rng1.lo) == rng1.lo
 | 
			
		||||
  && tree_lca(rng1.hi,rng2.hi) == rng2.hi;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
scopes::range scopes::range_lub(const range &rng1, const range &rng2){
 | 
			
		||||
	range res;
 | 
			
		||||
	res.lo = tree_gcd(rng1.lo,rng2.lo);
 | 
			
		||||
	res.hi = tree_lca(rng1.hi,rng2.hi);
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
  
 | 
			
		||||
scopes::range scopes::range_glb(const range &rng1, const range &rng2){
 | 
			
		||||
	range res;
 | 
			
		||||
	res.lo = tree_lca(rng1.lo,rng2.lo);
 | 
			
		||||
	res.hi = tree_gcd(rng1.hi,rng2.hi);
 | 
			
		||||
	return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#else
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  namespace std {
 | 
			
		||||
    template <>
 | 
			
		||||
      class hash<scopes::range_lo > {
 | 
			
		||||
       public:
 | 
			
		||||
          size_t operator()(const scopes::range_lo &p) const {
 | 
			
		||||
            return p.lo + (size_t)p.next;
 | 
			
		||||
          }
 | 
			
		||||
      };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <> inline
 | 
			
		||||
  size_t stdext::hash_value<scopes::range_lo >(const scopes::range_lo& p)
 | 
			
		||||
  {	
 | 
			
		||||
	std::hash<scopes::range_lo> h;
 | 
			
		||||
	return h(p);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  namespace std {
 | 
			
		||||
    template <>
 | 
			
		||||
	   class less<scopes::range_lo > {
 | 
			
		||||
	   public:
 | 
			
		||||
		   bool operator()(const scopes::range_lo &x, const scopes::range_lo &y) const {
 | 
			
		||||
		      return x.lo < y.lo || x.lo == y.lo && (size_t)x.next < (size_t)y.next;
 | 
			
		||||
		   }
 | 
			
		||||
	   };
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
 | 
			
		||||
  struct range_op {
 | 
			
		||||
	scopes::range_lo *x, *y;
 | 
			
		||||
	int hi;
 | 
			
		||||
	range_op(scopes::range_lo *_x, scopes::range_lo *_y, int _hi){
 | 
			
		||||
		x = _x; y = _y; hi = _hi;
 | 
			
		||||
	}
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
   namespace std {
 | 
			
		||||
    template <>
 | 
			
		||||
      class hash<range_op > {
 | 
			
		||||
       public:
 | 
			
		||||
          size_t operator()(const range_op &p) const {
 | 
			
		||||
            return (size_t) p.x + (size_t)p.y + p.hi;
 | 
			
		||||
          }
 | 
			
		||||
      };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  template <> inline
 | 
			
		||||
  size_t stdext::hash_value<range_op >(const range_op& p)
 | 
			
		||||
  {	
 | 
			
		||||
	std::hash<range_op> h;
 | 
			
		||||
	return h(p);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  namespace std {
 | 
			
		||||
    template <>
 | 
			
		||||
	   class less<range_op > {
 | 
			
		||||
	   public:
 | 
			
		||||
		   bool operator()(const range_op &x, const range_op &y) const {
 | 
			
		||||
		      return (size_t)x.x < (size_t)y.x || x.x == y.x &&
 | 
			
		||||
				        ((size_t)x.y < (size_t)y.y || x.y == y.y && x.hi < y.hi);
 | 
			
		||||
		   }
 | 
			
		||||
	   };
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  struct range_tables {
 | 
			
		||||
	  hash_map<scopes::range_lo, scopes::range_lo *> unique;
 | 
			
		||||
	  hash_map<range_op,scopes::range_lo *> lub;
 | 
			
		||||
	  hash_map<range_op,scopes::range_lo *> glb;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  scopes::range_lo *scopes::find_range_lo(int lo, range_lo *next){
 | 
			
		||||
	  range_lo foo(lo,next);
 | 
			
		||||
	  std::pair<range_lo,range_lo *> baz(foo,(range_lo *)0);
 | 
			
		||||
	  std::pair<hash_map<range_lo,scopes::range_lo *>::iterator,bool> bar = rt->unique.insert(baz);
 | 
			
		||||
	  if(bar.second)
 | 
			
		||||
		  bar.first->second = new range_lo(lo,next);
 | 
			
		||||
	  return bar.first->second;
 | 
			
		||||
	  //std::pair<hash_set<scopes::range_lo>::iterator,bool> bar = rt->unique.insert(foo);
 | 
			
		||||
	  // const range_lo *baz = &*(bar.first); 
 | 
			
		||||
	  // return (range_lo *)baz; // exit const hell
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  scopes::range_lo *scopes::range_lub_lo(range_lo *rng1, range_lo *rng2){
 | 
			
		||||
    if(!rng1) return rng2;
 | 
			
		||||
    if(!rng2) return rng1;
 | 
			
		||||
    if(rng1->lo > rng2->lo)
 | 
			
		||||
      std::swap(rng1,rng2);
 | 
			
		||||
	std::pair<range_op,range_lo *> foo(range_op(rng1,rng2,0),(range_lo *)0);
 | 
			
		||||
	std::pair<hash_map<range_op,scopes::range_lo *>::iterator,bool> bar = rt->lub.insert(foo);
 | 
			
		||||
	range_lo *&res = bar.first->second;
 | 
			
		||||
	if(!bar.second) return res;
 | 
			
		||||
    if(!(rng1->next && rng1->next->lo <= rng2->lo)){
 | 
			
		||||
      for(int lo = rng1->lo; lo <= rng2->lo; lo = parents[lo])
 | 
			
		||||
		  if(lo == rng2->lo)
 | 
			
		||||
		    {rng2 = rng2->next; break;}
 | 
			
		||||
    }
 | 
			
		||||
    range_lo *baz = range_lub_lo(rng1->next,rng2);
 | 
			
		||||
    res = find_range_lo(rng1->lo,baz);
 | 
			
		||||
	return res;
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
 | 
			
		||||
  scopes::range_lo *scopes::range_glb_lo(range_lo *rng1, range_lo *rng2, int hi){
 | 
			
		||||
	  if(!rng1) return rng1;
 | 
			
		||||
	  if(!rng2) return rng2;
 | 
			
		||||
	  if(rng1->lo > rng2->lo)
 | 
			
		||||
		  std::swap(rng1,rng2);
 | 
			
		||||
	  std::pair<range_op,range_lo *> cand(range_op(rng1,rng2,hi),(range_lo *)0);
 | 
			
		||||
	  std::pair<hash_map<range_op,scopes::range_lo *>::iterator,bool> bar = rt->glb.insert(cand);
 | 
			
		||||
	  range_lo *&res = bar.first->second;
 | 
			
		||||
	  if(!bar.second) return res;
 | 
			
		||||
	  range_lo *foo;
 | 
			
		||||
	  if(!(rng1->next && rng1->next->lo <= rng2->lo)){
 | 
			
		||||
		  int lim = hi;
 | 
			
		||||
		  if(rng1->next) lim = std::min(lim,rng1->next->lo);
 | 
			
		||||
		  int a = rng1->lo, b = rng2->lo;
 | 
			
		||||
		  while(a != b && b <= lim){
 | 
			
		||||
			  a = parents[a];
 | 
			
		||||
			  if(a > b)std::swap(a,b);
 | 
			
		||||
		  }
 | 
			
		||||
		  if(a == b && b <= lim){
 | 
			
		||||
			  foo = range_glb_lo(rng1->next,rng2->next,hi);
 | 
			
		||||
			  foo = find_range_lo(b,foo);
 | 
			
		||||
		  }
 | 
			
		||||
		  else
 | 
			
		||||
			  foo = range_glb_lo(rng2,rng1->next,hi);
 | 
			
		||||
	  }
 | 
			
		||||
	  else foo = range_glb_lo(rng1->next,rng2,hi);
 | 
			
		||||
	  res = foo;
 | 
			
		||||
	  return res;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** computes the lub (smallest containing subtree) of two ranges */
 | 
			
		||||
  scopes::range scopes::range_lub(const range &rng1, const range &rng2){
 | 
			
		||||
    int hi = tree_lca(rng1.hi,rng2.hi);
 | 
			
		||||
	if(hi == SHRT_MAX) return range_full();
 | 
			
		||||
    range_lo *lo = range_lub_lo(rng1.lo,rng2.lo);
 | 
			
		||||
    return range(hi,lo);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** computes the glb (intersection) of two ranges */
 | 
			
		||||
  scopes::range scopes::range_glb(const range &rng1, const range &rng2){
 | 
			
		||||
	if(rng1.hi == SHRT_MAX) return rng2;
 | 
			
		||||
	if(rng2.hi == SHRT_MAX) return rng1;
 | 
			
		||||
    int hi = tree_gcd(rng1.hi,rng2.hi);
 | 
			
		||||
    range_lo *lo = hi == SHRT_MIN ? 0 : range_glb_lo(rng1.lo,rng2.lo,hi);
 | 
			
		||||
	if(!lo) hi = SHRT_MIN;
 | 
			
		||||
    return range(hi,lo);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** is this range empty? */
 | 
			
		||||
  bool scopes::range_is_empty(const range &rng){
 | 
			
		||||
    return rng.hi == SHRT_MIN;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** return an empty range */
 | 
			
		||||
  scopes::range scopes::range_empty(){
 | 
			
		||||
    return range(SHRT_MIN,0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** return a full range */
 | 
			
		||||
  scopes::range scopes::range_full(){
 | 
			
		||||
    return range(SHRT_MAX,0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** return the maximal element of a range */
 | 
			
		||||
  int scopes::range_max(const range &rng){
 | 
			
		||||
    return rng.hi;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** return a minimal (not necessarily unique) element of a range */
 | 
			
		||||
  int scopes::range_min(const range &rng){
 | 
			
		||||
	if(rng.hi == SHRT_MAX) return SHRT_MIN;
 | 
			
		||||
    return rng.lo ? rng.lo->lo : SHRT_MAX;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /** return range consisting of downward closure of a point */
 | 
			
		||||
  scopes::range scopes::range_downward(int _hi){
 | 
			
		||||
    std::vector<bool> descendants(parents.size());
 | 
			
		||||
    for(int i = descendants.size() - 1; i >= 0 ; i--)
 | 
			
		||||
      descendants[i] = i == _hi || parents[i] < parents.size() && descendants[parents[i]];
 | 
			
		||||
    for(unsigned i = 0; i < descendants.size() - 1; i++)
 | 
			
		||||
      if(parents[i] < parents.size())
 | 
			
		||||
	descendants[parents[i]] = false;
 | 
			
		||||
    range_lo *foo = 0;
 | 
			
		||||
    for(int i = descendants.size() - 1; i >= 0; --i)
 | 
			
		||||
      if(descendants[i]) foo = find_range_lo(i,foo);
 | 
			
		||||
    return range(_hi,foo);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** add an element to a range */
 | 
			
		||||
  void scopes::range_add(int i, range &n){
 | 
			
		||||
    range foo = range(i, find_range_lo(i,0));
 | 
			
		||||
    n = range_lub(foo,n);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** Choose an element of rng1 that is near to rng2 */
 | 
			
		||||
  int scopes::range_near(const range &rng1, const range &rng2){
 | 
			
		||||
 | 
			
		||||
    int frame;
 | 
			
		||||
    int thing = tree_lca(rng1.hi,rng2.hi);
 | 
			
		||||
	if(thing != rng1.hi) return rng1.hi;
 | 
			
		||||
	range line = range(rng1.hi,find_range_lo(rng2.hi,(range_lo *)0));
 | 
			
		||||
	line = range_glb(line,rng1);
 | 
			
		||||
	return range_min(line);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  /** test whether a tree node is contained in a range */
 | 
			
		||||
  bool scopes::in_range(int n, const range &rng){
 | 
			
		||||
	  range r = range_empty();
 | 
			
		||||
	  range_add(n,r);
 | 
			
		||||
	  r = range_glb(rng,r);
 | 
			
		||||
	  return !range_is_empty(r);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** test whether two ranges of tree nodes intersect */
 | 
			
		||||
  bool scopes::ranges_intersect(const range &rng1, const range &rng2){
 | 
			
		||||
	  range r = range_glb(rng1,rng2);
 | 
			
		||||
	  return !range_is_empty(r);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  bool scopes::range_contained(const range &rng1, const range &rng2){
 | 
			
		||||
	  range r = range_glb(rng1,rng2);
 | 
			
		||||
	  return r.hi == rng1.hi && r.lo == rng1.lo;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,197 +1,197 @@
 | 
			
		|||
/*++
 | 
			
		||||
Copyright (c) 2011 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    iz3scopes.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
   Calculations with scopes, for both sequence and tree interpolation.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Ken McMillan (kenmcmil)
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef IZ3SOPES_H
 | 
			
		||||
#define IZ3SOPES_H
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
 | 
			
		||||
class scopes {
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  /** Construct from parents vector. */
 | 
			
		||||
  scopes(const std::vector<int> &_parents){
 | 
			
		||||
    parents = _parents;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  scopes(){
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  void initialize(const std::vector<int> &_parents){
 | 
			
		||||
    parents = _parents;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** The parents vector defining the tree structure */
 | 
			
		||||
  std::vector<int> parents;
 | 
			
		||||
 | 
			
		||||
  // #define FULL_TREE
 | 
			
		||||
#ifndef FULL_TREE
 | 
			
		||||
  struct range {
 | 
			
		||||
    range(){
 | 
			
		||||
      lo = SHRT_MAX;
 | 
			
		||||
      hi = SHRT_MIN;
 | 
			
		||||
    }
 | 
			
		||||
    short lo, hi;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /** computes the lub (smallest containing subtree) of two ranges */
 | 
			
		||||
  range range_lub(const range &rng1, const range &rng2);
 | 
			
		||||
  
 | 
			
		||||
  /** computes the glb (intersection) of two ranges */
 | 
			
		||||
  range range_glb(const range &rng1, const range &rng2);
 | 
			
		||||
 | 
			
		||||
  /** is this range empty? */
 | 
			
		||||
  bool range_is_empty(const range &rng){
 | 
			
		||||
	  return rng.hi < rng.lo;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** return an empty range */
 | 
			
		||||
  range range_empty(){
 | 
			
		||||
     range res;
 | 
			
		||||
	 res.lo = SHRT_MAX;
 | 
			
		||||
	 res.hi = SHRT_MIN;
 | 
			
		||||
	 return res;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** return an empty range */
 | 
			
		||||
  range range_full(){
 | 
			
		||||
     range res;
 | 
			
		||||
	 res.lo = SHRT_MIN;
 | 
			
		||||
	 res.hi = SHRT_MAX;
 | 
			
		||||
	 return res;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** return the maximal element of a range */
 | 
			
		||||
  int range_max(const range &rng){
 | 
			
		||||
	  return rng.hi;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** return a minimal (not necessarily unique) element of a range */
 | 
			
		||||
  int range_min(const range &rng){
 | 
			
		||||
	  return rng.lo;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** return range consisting of downward closure of a point */
 | 
			
		||||
  range range_downward(int _hi){
 | 
			
		||||
    range foo;
 | 
			
		||||
    foo.lo = SHRT_MIN;
 | 
			
		||||
    foo.hi = _hi;
 | 
			
		||||
    return foo;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void range_add(int i, range &n){
 | 
			
		||||
#if 0
 | 
			
		||||
	if(i < n.lo) n.lo = i;
 | 
			
		||||
    if(i > n.hi) n.hi = i;
 | 
			
		||||
#else
 | 
			
		||||
    range rng; rng.lo = i; rng.hi = i;
 | 
			
		||||
    n = range_lub(rng,n);
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** Choose an element of rng1 that is near to rng2 */
 | 
			
		||||
  int range_near(const range &rng1, const range &rng2){
 | 
			
		||||
    int frame;
 | 
			
		||||
    int thing = tree_lca(rng1.lo,rng2.hi);
 | 
			
		||||
    if(thing == rng1.lo) frame = rng1.lo;
 | 
			
		||||
    else frame = tree_gcd(thing,rng1.hi);
 | 
			
		||||
	return frame;
 | 
			
		||||
  }
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
  struct range_lo {
 | 
			
		||||
    int lo;
 | 
			
		||||
    range_lo *next;
 | 
			
		||||
    range_lo(int _lo, range_lo *_next){
 | 
			
		||||
      lo = _lo;
 | 
			
		||||
      next = _next;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  struct range {
 | 
			
		||||
    int hi;
 | 
			
		||||
    range_lo *lo;
 | 
			
		||||
    range(int _hi, range_lo *_lo){
 | 
			
		||||
      hi = _hi;
 | 
			
		||||
      lo = _lo;
 | 
			
		||||
    }
 | 
			
		||||
    range(){
 | 
			
		||||
      hi = SHRT_MIN;
 | 
			
		||||
      lo = 0;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  range_tables *rt;
 | 
			
		||||
 | 
			
		||||
  /** computes the lub (smallest containing subtree) of two ranges */
 | 
			
		||||
  range range_lub(const range &rng1, const range &rng2);
 | 
			
		||||
  
 | 
			
		||||
  /** computes the glb (intersection) of two ranges */
 | 
			
		||||
  range range_glb(const range &rng1, const range &rng2);
 | 
			
		||||
 | 
			
		||||
  /** is this range empty? */
 | 
			
		||||
  bool range_is_empty(const range &rng);
 | 
			
		||||
 | 
			
		||||
  /** return an empty range */
 | 
			
		||||
  range range_empty();
 | 
			
		||||
 | 
			
		||||
  /** return a full range */
 | 
			
		||||
  range range_full();
 | 
			
		||||
 | 
			
		||||
  /** return the maximal element of a range */
 | 
			
		||||
  int range_max(const range &rng);
 | 
			
		||||
 | 
			
		||||
  /** return a minimal (not necessarily unique) element of a range */
 | 
			
		||||
  int range_min(const range &rng);
 | 
			
		||||
 | 
			
		||||
  /** return range consisting of downward closure of a point */
 | 
			
		||||
  range range_downward(int _hi);
 | 
			
		||||
 | 
			
		||||
  /** add an element to a range */
 | 
			
		||||
  void range_add(int i, range &n);
 | 
			
		||||
 | 
			
		||||
  /** Choose an element of rng1 that is near to rng2 */
 | 
			
		||||
  int range_near(const range &rng1, const range &rng2);
 | 
			
		||||
 | 
			
		||||
  range_lo *find_range_lo(int lo, range_lo *next);
 | 
			
		||||
  range_lo *range_lub_lo(range_lo *rng1, range_lo *rng2);
 | 
			
		||||
  range_lo *range_glb_lo(range_lo *rng1, range_lo *rng2, int lim);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
  
 | 
			
		||||
  /** test whether a tree node is contained in a range */
 | 
			
		||||
  bool in_range(int n, const range &rng);
 | 
			
		||||
  
 | 
			
		||||
  /** test whether two ranges of tree nodes intersect */
 | 
			
		||||
  bool ranges_intersect(const range &rng1, const range &rng2);
 | 
			
		||||
 | 
			
		||||
  /** test whether range rng1 contained in range rng2 */
 | 
			
		||||
  bool range_contained(const range &rng1, const range &rng2);
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  int tree_lca(int n1, int n2);
 | 
			
		||||
  int tree_gcd(int n1, int n2);
 | 
			
		||||
  bool tree_mode(){return parents.size() != 0;}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
/*++
 | 
			
		||||
Copyright (c) 2011 Microsoft Corporation
 | 
			
		||||
 | 
			
		||||
Module Name:
 | 
			
		||||
 | 
			
		||||
    iz3scopes.h
 | 
			
		||||
 | 
			
		||||
Abstract:
 | 
			
		||||
 | 
			
		||||
   Calculations with scopes, for both sequence and tree interpolation.
 | 
			
		||||
 | 
			
		||||
Author:
 | 
			
		||||
 | 
			
		||||
    Ken McMillan (kenmcmil)
 | 
			
		||||
 | 
			
		||||
Revision History:
 | 
			
		||||
 | 
			
		||||
--*/
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef IZ3SOPES_H
 | 
			
		||||
#define IZ3SOPES_H
 | 
			
		||||
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <limits.h>
 | 
			
		||||
 | 
			
		||||
class scopes {
 | 
			
		||||
 | 
			
		||||
 public:
 | 
			
		||||
  /** Construct from parents vector. */
 | 
			
		||||
  scopes(const std::vector<int> &_parents){
 | 
			
		||||
    parents = _parents;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  scopes(){
 | 
			
		||||
  }
 | 
			
		||||
  
 | 
			
		||||
  void initialize(const std::vector<int> &_parents){
 | 
			
		||||
    parents = _parents;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** The parents vector defining the tree structure */
 | 
			
		||||
  std::vector<int> parents;
 | 
			
		||||
 | 
			
		||||
  // #define FULL_TREE
 | 
			
		||||
#ifndef FULL_TREE
 | 
			
		||||
  struct range {
 | 
			
		||||
    range(){
 | 
			
		||||
      lo = SHRT_MAX;
 | 
			
		||||
      hi = SHRT_MIN;
 | 
			
		||||
    }
 | 
			
		||||
    short lo, hi;
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /** computes the lub (smallest containing subtree) of two ranges */
 | 
			
		||||
  range range_lub(const range &rng1, const range &rng2);
 | 
			
		||||
  
 | 
			
		||||
  /** computes the glb (intersection) of two ranges */
 | 
			
		||||
  range range_glb(const range &rng1, const range &rng2);
 | 
			
		||||
 | 
			
		||||
  /** is this range empty? */
 | 
			
		||||
  bool range_is_empty(const range &rng){
 | 
			
		||||
	  return rng.hi < rng.lo;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** return an empty range */
 | 
			
		||||
  range range_empty(){
 | 
			
		||||
     range res;
 | 
			
		||||
	 res.lo = SHRT_MAX;
 | 
			
		||||
	 res.hi = SHRT_MIN;
 | 
			
		||||
	 return res;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** return an empty range */
 | 
			
		||||
  range range_full(){
 | 
			
		||||
     range res;
 | 
			
		||||
	 res.lo = SHRT_MIN;
 | 
			
		||||
	 res.hi = SHRT_MAX;
 | 
			
		||||
	 return res;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** return the maximal element of a range */
 | 
			
		||||
  int range_max(const range &rng){
 | 
			
		||||
	  return rng.hi;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** return a minimal (not necessarily unique) element of a range */
 | 
			
		||||
  int range_min(const range &rng){
 | 
			
		||||
	  return rng.lo;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** return range consisting of downward closure of a point */
 | 
			
		||||
  range range_downward(int _hi){
 | 
			
		||||
    range foo;
 | 
			
		||||
    foo.lo = SHRT_MIN;
 | 
			
		||||
    foo.hi = _hi;
 | 
			
		||||
    return foo;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void range_add(int i, range &n){
 | 
			
		||||
#if 0
 | 
			
		||||
	if(i < n.lo) n.lo = i;
 | 
			
		||||
    if(i > n.hi) n.hi = i;
 | 
			
		||||
#else
 | 
			
		||||
    range rng; rng.lo = i; rng.hi = i;
 | 
			
		||||
    n = range_lub(rng,n);
 | 
			
		||||
#endif
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /** Choose an element of rng1 that is near to rng2 */
 | 
			
		||||
  int range_near(const range &rng1, const range &rng2){
 | 
			
		||||
    int frame;
 | 
			
		||||
    int thing = tree_lca(rng1.lo,rng2.hi);
 | 
			
		||||
    if(thing == rng1.lo) frame = rng1.lo;
 | 
			
		||||
    else frame = tree_gcd(thing,rng1.hi);
 | 
			
		||||
	return frame;
 | 
			
		||||
  }
 | 
			
		||||
#else
 | 
			
		||||
 | 
			
		||||
  struct range_lo {
 | 
			
		||||
    int lo;
 | 
			
		||||
    range_lo *next;
 | 
			
		||||
    range_lo(int _lo, range_lo *_next){
 | 
			
		||||
      lo = _lo;
 | 
			
		||||
      next = _next;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  struct range {
 | 
			
		||||
    int hi;
 | 
			
		||||
    range_lo *lo;
 | 
			
		||||
    range(int _hi, range_lo *_lo){
 | 
			
		||||
      hi = _hi;
 | 
			
		||||
      lo = _lo;
 | 
			
		||||
    }
 | 
			
		||||
    range(){
 | 
			
		||||
      hi = SHRT_MIN;
 | 
			
		||||
      lo = 0;
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  range_tables *rt;
 | 
			
		||||
 | 
			
		||||
  /** computes the lub (smallest containing subtree) of two ranges */
 | 
			
		||||
  range range_lub(const range &rng1, const range &rng2);
 | 
			
		||||
  
 | 
			
		||||
  /** computes the glb (intersection) of two ranges */
 | 
			
		||||
  range range_glb(const range &rng1, const range &rng2);
 | 
			
		||||
 | 
			
		||||
  /** is this range empty? */
 | 
			
		||||
  bool range_is_empty(const range &rng);
 | 
			
		||||
 | 
			
		||||
  /** return an empty range */
 | 
			
		||||
  range range_empty();
 | 
			
		||||
 | 
			
		||||
  /** return a full range */
 | 
			
		||||
  range range_full();
 | 
			
		||||
 | 
			
		||||
  /** return the maximal element of a range */
 | 
			
		||||
  int range_max(const range &rng);
 | 
			
		||||
 | 
			
		||||
  /** return a minimal (not necessarily unique) element of a range */
 | 
			
		||||
  int range_min(const range &rng);
 | 
			
		||||
 | 
			
		||||
  /** return range consisting of downward closure of a point */
 | 
			
		||||
  range range_downward(int _hi);
 | 
			
		||||
 | 
			
		||||
  /** add an element to a range */
 | 
			
		||||
  void range_add(int i, range &n);
 | 
			
		||||
 | 
			
		||||
  /** Choose an element of rng1 that is near to rng2 */
 | 
			
		||||
  int range_near(const range &rng1, const range &rng2);
 | 
			
		||||
 | 
			
		||||
  range_lo *find_range_lo(int lo, range_lo *next);
 | 
			
		||||
  range_lo *range_lub_lo(range_lo *rng1, range_lo *rng2);
 | 
			
		||||
  range_lo *range_glb_lo(range_lo *rng1, range_lo *rng2, int lim);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
  
 | 
			
		||||
  /** test whether a tree node is contained in a range */
 | 
			
		||||
  bool in_range(int n, const range &rng);
 | 
			
		||||
  
 | 
			
		||||
  /** test whether two ranges of tree nodes intersect */
 | 
			
		||||
  bool ranges_intersect(const range &rng1, const range &rng2);
 | 
			
		||||
 | 
			
		||||
  /** test whether range rng1 contained in range rng2 */
 | 
			
		||||
  bool range_contained(const range &rng1, const range &rng2);
 | 
			
		||||
 | 
			
		||||
 private:
 | 
			
		||||
  int tree_lca(int n1, int n2);
 | 
			
		||||
  int tree_gcd(int n1, int n2);
 | 
			
		||||
  bool tree_mode(){return parents.size() != 0;}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -464,7 +464,7 @@ public:
 | 
			
		|||
	  for(int i = 0; i < 2; i++){ // try the second equality both ways
 | 
			
		||||
	    if(match_op(eq_ops_r[0],Select,sel_ops,2))
 | 
			
		||||
	      if(match_op(sel_ops[0],Store,sto_ops,3))
 | 
			
		||||
		if(match_op(eq_ops_r[1],Select,sel_ops2,2))
 | 
			
		||||
		if(match_op(eq_ops_r[1],Select,sel_ops2,2))
 | 
			
		||||
                  for(int j = 0; j < 2; j++){ // try the first equality both ways
 | 
			
		||||
                    if(eq_ops_l[0] == sto_ops[1]
 | 
			
		||||
                    && eq_ops_l[1] == sel_ops[1]
 | 
			
		||||
| 
						 | 
				
			
			@ -482,8 +482,8 @@ public:
 | 
			
		|||
                        // int frame = range_min(ast_scope(res)); TODO
 | 
			
		||||
                        // antes.push_back(std::pair<ast,int>(res,frame));
 | 
			
		||||
                        return;
 | 
			
		||||
                      }
 | 
			
		||||
                      std::swap(eq_ops_l[0],eq_ops_l[1]);
 | 
			
		||||
                      }
 | 
			
		||||
                      std::swap(eq_ops_l[0],eq_ops_l[1]);
 | 
			
		||||
                  }
 | 
			
		||||
	    std::swap(eq_ops_r[0],eq_ops_r[1]);
 | 
			
		||||
	  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -484,7 +484,7 @@ public:
 | 
			
		|||
	  for(int i = 0; i < 2; i++){ // try the second equality both ways
 | 
			
		||||
	    if(match_op(eq_ops_r[0],Select,sel_ops,2))
 | 
			
		||||
	      if(match_op(sel_ops[0],Store,sto_ops,3))
 | 
			
		||||
		if(match_op(eq_ops_r[1],Select,sel_ops2,2))
 | 
			
		||||
		if(match_op(eq_ops_r[1],Select,sel_ops2,2))
 | 
			
		||||
                  for(int j = 0; j < 2; j++){ // try the first equality both ways
 | 
			
		||||
                    if(eq_ops_l[0] == sto_ops[1]
 | 
			
		||||
                    && eq_ops_l[1] == sel_ops[1]
 | 
			
		||||
| 
						 | 
				
			
			@ -502,8 +502,8 @@ public:
 | 
			
		|||
                        int frame = range_min(ast_scope(res));
 | 
			
		||||
                        antes.push_back(std::pair<ast,int>(res,frame));
 | 
			
		||||
                        return;
 | 
			
		||||
                      }
 | 
			
		||||
                      std::swap(eq_ops_l[0],eq_ops_l[1]);
 | 
			
		||||
                      }
 | 
			
		||||
                      std::swap(eq_ops_l[0],eq_ops_l[1]);
 | 
			
		||||
                  }
 | 
			
		||||
	    std::swap(eq_ops_r[0],eq_ops_r[1]);
 | 
			
		||||
	  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue