Limi
meta_state.h
1 /*
2  * Copyright 2016, IST Austria
3  *
4  * This file is part of Limi.
5  *
6  * Limi is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Limi is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public License
17  * along with Limi. If not, see <http://www.gnu.org/licenses/>.
18  */
19 
20 #ifndef LIMI_INTERNAL_META_STATE_H
21 #define LIMI_INTERNAL_META_STATE_H
22 
23 #include <vector>
24 #include <ostream>
25 #include <memory>
26 #include "helpers.h"
27 
28 namespace Limi {
29  namespace internal {
30 
31 // TODO make this more efficient by removing / adding on copy
38 template <class StateB, class Symbol, class Independence = independence<Symbol>>
39 struct meta_state {
40 private:
41  StateB inner_state_;
42  std::vector<Symbol> early_;
43  std::vector<Symbol> late_;
44  size_t hash_ = 0;
45 public:
46  typedef typename std::vector<Symbol>::const_iterator vector_iterator;
47  meta_state(StateB inner_state) : inner_state_(inner_state), hash_(std::hash<StateB>()(inner_state)) {}
48 
49  size_t hash() const {
50  return hash_;
51  }
52 
53  /*virtual std::string to_string() const override {
54 
55  }*/
56 
57  inline StateB inner_state() const { return inner_state_; }
58 
59  inline void inner_state(StateB new_inner_state) {
60  hash_ = hash_ ^ std::hash<StateB>()(inner_state_);
61  inner_state_ = new_inner_state;
62  hash_ = hash_ ^ std::hash<StateB>()(inner_state_);
63  }
64 
65  inline const std::vector<Symbol>& early() const { return early_; }
66  inline const std::vector<Symbol>& late() const { return late_; }
67 
68  inline void add_early(const Symbol& symbol, const Independence& independence = Independence()) {
69  hash_ = hash_ ^ std::hash<Symbol>()(symbol);
70  // find position to insert
71  int position;
72  for(position = early_.size()-1; position>=0; --position) {
73  if (symbol > early_[position] || !independence(symbol, early_[position]))
74  break;
75  }
76  early_.insert(early_.begin()+(position+1), symbol);
77  }
78 
79  inline void add_late(const Symbol& symbol, const Independence& independence = Independence()) {
80  hash_ = hash_ ^ ~std::hash<Symbol>()(symbol);
81  int position;
82  for(position = late_.size()-1; position>=0; --position) {
83  if (symbol > late_[position] || !independence(symbol, late_[position]))
84  break;
85  }
86  late_.insert(late_.begin()+(position+1), symbol);
87  }
88 
89  inline void erase_early(unsigned position) {
90  hash_ = hash_ ^ std::hash<Symbol>()(early_[position]);
91  early_.erase(early_.begin() + position); // trick because iterator is const
92  }
93 
94  inline void erase_late(unsigned position) {
95  hash_ = hash_ ^ ~std::hash<Symbol>()(late_[position]);
96  late_.erase(late_.begin() + position);
97  }
98 
99  inline unsigned size() {
100  return early_.size();
101  }
102 
103  inline bool operator==(const meta_state<StateB,Symbol,Independence>& other) const {
104  if (&other == this) return true;
105  if (!std::equal_to<StateB>()(inner_state(), other.inner_state()))
106  return false;
107  if (early().size() != other.early().size() || !std::equal(early().begin(), early().end(), other.early().begin(), std::equal_to<Symbol>()))
108  return false;
109  if (late().size() != other.late().size() || !std::equal(late().begin(), late().end(), other.late().begin(), std::equal_to<Symbol>()))
110  return false;
111  return true;
112  }
113 };
114  }
115 
116 template<class InnerStateB, class Symbol, class Independence>
117 struct printer<std::shared_ptr<Limi::internal::meta_state<InnerStateB, Symbol,Independence>>> : printer_base<std::shared_ptr<Limi::internal::meta_state<InnerStateB, Symbol,Independence>>> {
118  printer(const printer_base<InnerStateB>& printerS, const printer_base<Symbol>& printerSy) : printerS(printerS), printerSy(printerSy) {}
119  virtual void print(const std::shared_ptr<Limi::internal::meta_state<InnerStateB, Symbol,Independence>>& state, std::ostream& out) const override {
120  out << "(" << printerS(state->inner_state());
121 
122  out << ", ";
123  internal::print_vector(state->early(), out, printerSy);
124  out << ", ";
125  internal::print_vector(state->late(), out, printerSy);
126  out << ")";
127  }
128 private:
129  const printer_base<InnerStateB>& printerS;
130  const printer_base<Symbol>& printerSy;
131 };
132 
133 template<class InnerStateB, class Symbol, class Independence>
134 std::ostream& operator<<(std::ostream& out, Limi::internal::meta_state<InnerStateB, Symbol,Independence>& state) {
135  out << "(" << state.inner_state();
136  out << ", ";
137  internal::print_vector(state.early(), out);
138  out << ", ";
139  internal::print_vector(state.late(), out);
140  out << ")";
141  return out;
142 }
143 
144 
145 }
146 
147 namespace std {
148  template<class StateB, class Symbol, class Independence> struct hash<Limi::internal::meta_state<StateB,Symbol,Independence>> {
149  inline size_t operator()(const Limi::internal::meta_state<StateB,Symbol, Independence>& val) const {
150  return val.hash();
151  }
152  };
153  template<class StateB, class Symbol, class Independence> struct hash<shared_ptr<Limi::internal::meta_state<StateB,Symbol,Independence>>> {
154  inline size_t operator()(const std::shared_ptr<Limi::internal::meta_state<StateB,Symbol, Independence>>& val) const {
155  return hash<Limi::internal::meta_state<StateB,Symbol,Independence>>()(*val);
156  }
157  };
158 
159  template<class StateB, class Symbol, class Independence> struct equal_to<shared_ptr<Limi::internal::meta_state<StateB,Symbol,Independence>>> {
160  inline bool operator()(const shared_ptr<Limi::internal::meta_state<StateB,Symbol, Independence>>& a, const shared_ptr<Limi::internal::meta_state<StateB,Symbol,Independence>>& b) const {
161  return equal_to<Limi::internal::meta_state<StateB,Symbol,Independence>>()(*a,*b);
162  }
163  };
164 }
165 
166 
167 #endif // LIMI_INTERNAL_META_STATE_H
The printer base is what custom printers need to inherit from.
Definition: generics.h:81
The main namespace of the library.
Definition: antichain_algo.h:40
Definition: generics.h:30
The template for the independence relation.
Definition: generics.h:53
A state in the meta-automaton.
Definition: meta_state.h:39
virtual void print(const Key &item, std::ostream &out) const override
Prints an item to the out stream.
Definition: generics.h:105
The default implementation of Limi::printer_base.
Definition: generics.h:104