1/*
2 * SingleValue.cpp
3 * @brief domain constraint
4 * @date Feb 13, 2012
5 * @author Frank Dellaert
6 */
7
8#include <gtsam/base/Testable.h>
9#include <gtsam/discrete/DecisionTreeFactor.h>
10#include <gtsam_unstable/discrete/Domain.h>
11#include <gtsam_unstable/discrete/SingleValue.h>
12
13
14namespace gtsam {
15
16using namespace std;
17
18/* ************************************************************************* */
19void SingleValue::print(const string& s, const KeyFormatter& formatter) const {
20 cout << s << "SingleValue on "
21 << "j=" << formatter(keys_[0]) << " with value " << value_ << endl;
22}
23
24/* ************************************************************************* */
25double SingleValue::evaluate(const Assignment<Key>& values) const {
26 return (double)(values.at(k: keys_[0]) == value_);
27}
28
29/* ************************************************************************* */
30DecisionTreeFactor SingleValue::toDecisionTreeFactor() const {
31 const DiscreteKeys keys{DiscreteKey(keys_[0], cardinality_)};
32 vector<double> table;
33 for (size_t i1 = 0; i1 < cardinality_; i1++) table.push_back(x: i1 == value_);
34 DecisionTreeFactor converted(keys, table);
35 return converted;
36}
37
38/* ************************************************************************* */
39DecisionTreeFactor SingleValue::operator*(const DecisionTreeFactor& f) const {
40 // TODO: can we do this more efficiently?
41 return toDecisionTreeFactor() * f;
42}
43
44/* ************************************************************************* */
45bool SingleValue::ensureArcConsistency(Key j, Domains* domains) const {
46 if (j != keys_[0])
47 throw invalid_argument("SingleValue check on wrong domain");
48 Domain& D = domains->at(k: j);
49 if (D.isSingleton()) {
50 if (D.firstValue() != value_) throw runtime_error("Unsatisfiable");
51 return false;
52 }
53 D = Domain(discreteKey(), value_);
54 return true;
55}
56
57/* ************************************************************************* */
58Constraint::shared_ptr SingleValue::partiallyApply(const DiscreteValues& values) const {
59 DiscreteValues::const_iterator it = values.find(x: keys_[0]);
60 if (it != values.end() && it->second != value_)
61 throw runtime_error("SingleValue::partiallyApply: unsatisfiable");
62 return std::make_shared<SingleValue>(args: keys_[0], args: cardinality_, args: value_);
63}
64
65/* ************************************************************************* */
66Constraint::shared_ptr SingleValue::partiallyApply(
67 const Domains& domains) const {
68 const Domain& Dk = domains.at(k: keys_[0]);
69 if (Dk.isSingleton() && !Dk.contains(value: value_))
70 throw runtime_error("SingleValue::partiallyApply: unsatisfiable");
71 return std::make_shared<SingleValue>(args: discreteKey(), args: value_);
72}
73
74/* ************************************************************************* */
75} // namespace gtsam
76