| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | /*
 | 
					
						
							|  |  |  |  * Domain.cpp | 
					
						
							|  |  |  |  * @brief Domain restriction constraint | 
					
						
							|  |  |  |  * @date Feb 13, 2012 | 
					
						
							|  |  |  |  * @author Frank Dellaert | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-18 23:17:49 +08:00
										 |  |  | #include <gtsam/base/Testable.h>
 | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  | #include <gtsam/discrete/DecisionTreeFactor.h>
 | 
					
						
							|  |  |  | #include <gtsam_unstable/discrete/Domain.h>
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-21 04:52:12 +08:00
										 |  |  | #include <sstream>
 | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | namespace gtsam { | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  | using namespace std; | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | void Domain::print(const string& s, const KeyFormatter& formatter) const { | 
					
						
							| 
									
										
										
										
											2021-11-21 04:52:12 +08:00
										 |  |  |   cout << s << ": Domain on " << formatter(key()) << " (j=" << formatter(key()) | 
					
						
							|  |  |  |        << ") with values"; | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  |   for (size_t v : values_) cout << " " << v; | 
					
						
							|  |  |  |   cout << endl; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-21 04:52:12 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | string Domain::base1Str() const { | 
					
						
							|  |  |  |   stringstream ss; | 
					
						
							|  |  |  |   for (size_t v : values_) ss << v + 1; | 
					
						
							|  |  |  |   return ss.str(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2024-12-10 10:09:00 +08:00
										 |  |  | double Domain::evaluate(const Assignment<Key>& values) const { | 
					
						
							| 
									
										
										
										
											2021-11-21 04:52:12 +08:00
										 |  |  |   return contains(values.at(key())); | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | DecisionTreeFactor Domain::toDecisionTreeFactor() const { | 
					
						
							| 
									
										
										
										
											2023-01-08 02:19:52 +08:00
										 |  |  |   const DiscreteKeys keys{DiscreteKey(key(), cardinality_)}; | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  |   vector<double> table; | 
					
						
							|  |  |  |   for (size_t i1 = 0; i1 < cardinality_; ++i1) table.push_back(contains(i1)); | 
					
						
							|  |  |  |   DecisionTreeFactor converted(keys, table); | 
					
						
							|  |  |  |   return converted; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							|  |  |  | DecisionTreeFactor Domain::operator*(const DecisionTreeFactor& f) const { | 
					
						
							|  |  |  |   // TODO: can we do this more efficiently?
 | 
					
						
							|  |  |  |   return toDecisionTreeFactor() * f; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2021-11-21 04:52:12 +08:00
										 |  |  | bool Domain::ensureArcConsistency(Key j, Domains* domains) const { | 
					
						
							|  |  |  |   if (j != key()) throw invalid_argument("Domain check on wrong domain"); | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  |   Domain& D = domains->at(j); | 
					
						
							|  |  |  |   for (size_t value : values_) | 
					
						
							|  |  |  |     if (!D.contains(value)) throw runtime_error("Unsatisfiable"); | 
					
						
							|  |  |  |   D = *this; | 
					
						
							|  |  |  |   return true; | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2023-01-13 05:43:29 +08:00
										 |  |  | std::optional<Domain> Domain::checkAllDiff(const KeyVector keys, | 
					
						
							| 
									
										
										
										
											2021-11-21 04:52:12 +08:00
										 |  |  |                                              const Domains& domains) const { | 
					
						
							|  |  |  |   Key j = key(); | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  |   // for all values in this domain
 | 
					
						
							|  |  |  |   for (const size_t value : values_) { | 
					
						
							|  |  |  |     // for all connected domains
 | 
					
						
							|  |  |  |     for (const Key k : keys) | 
					
						
							|  |  |  |       // if any domain contains the value we cannot make this domain singleton
 | 
					
						
							| 
									
										
										
										
											2021-11-21 04:52:12 +08:00
										 |  |  |       if (k != j && domains.at(k).contains(value)) goto found; | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  |     // Otherwise: return a singleton:
 | 
					
						
							|  |  |  |     return Domain(this->discreteKey(), value); | 
					
						
							|  |  |  |   found:; | 
					
						
							| 
									
										
										
										
											2012-10-02 22:40:07 +08:00
										 |  |  |   } | 
					
						
							| 
									
										
										
										
											2023-01-13 05:43:29 +08:00
										 |  |  |   return {};  // we did not change it
 | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2021-12-14 02:46:53 +08:00
										 |  |  | Constraint::shared_ptr Domain::partiallyApply(const DiscreteValues& values) const { | 
					
						
							|  |  |  |   DiscreteValues::const_iterator it = values.find(key()); | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  |   if (it != values.end() && !contains(it->second)) | 
					
						
							|  |  |  |     throw runtime_error("Domain::partiallyApply: unsatisfiable"); | 
					
						
							| 
									
										
										
										
											2023-01-18 06:05:12 +08:00
										 |  |  |   return std::make_shared<Domain>(*this); | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2021-11-21 04:52:12 +08:00
										 |  |  | Constraint::shared_ptr Domain::partiallyApply(const Domains& domains) const { | 
					
						
							|  |  |  |   const Domain& Dk = domains.at(key()); | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  |   if (Dk.isSingleton() && !contains(*Dk.begin())) | 
					
						
							|  |  |  |     throw runtime_error("Domain::partiallyApply: unsatisfiable"); | 
					
						
							| 
									
										
										
										
											2023-01-18 06:05:12 +08:00
										 |  |  |   return std::make_shared<Domain>(Dk); | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2012-04-16 06:35:28 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* ************************************************************************* */ | 
					
						
							| 
									
										
										
										
											2021-11-19 04:08:01 +08:00
										 |  |  | }  // namespace gtsam
 |