/** * * Copyright (c) 2005-2021 by Pierre-Henri WUILLEMIN(_at_LIP6) & Christophe GONZALES(_at_AMU) * info_at_agrum_dot_org * * This library is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this library. If not, see . * */ /** @file * @brief the structural constraint imposing a partial order over nodes * * In DBNs, it is forbidden to add arcs from nodes at time slice t to nodes at * time slice s, where s < t. This class allows for taking this kind of *constraint * into account by imposing a partial order over the nodes: arcs (X,Y) can then * only be added if X <= Y in the partial order. * @warning: there may exist free variables, that is variables whose order * w.r.t. the other variables is unspecified. In this case, arcs adjacent * to them can be constructed. The partial order is specified by assigning * numbers to nodes (through a NodeProperty). Nodes without number (i.e., that * do not belong to the property) are free. * * @author Christophe GONZALES(_at_AMU) and Pierre-Henri WUILLEMIN(_at_LIP6) */ #ifndef DOXYGEN_SHOULD_SKIP_THIS namespace gum { namespace learning { /// sets a new graph from which we will perform checkings INLINE void StructuralConstraintSliceOrder::setGraphAlone(const DiGraph& graph) {} /// checks whether the constraints enable to add arc (x,y) INLINE bool StructuralConstraintSliceOrder::checkArcAdditionAlone(NodeId x, NodeId y) const { try { return _SliceOrder_order_[x] <= _SliceOrder_order_[y]; } catch (const Exception&) { return true; } } /// checks whether the constraints enable to remove arc (x,y) INLINE bool StructuralConstraintSliceOrder::checkArcDeletionAlone(NodeId x, NodeId y) const { return true; } /// checks whether the constraints enable to reverse arc (x,y) INLINE bool StructuralConstraintSliceOrder::checkArcReversalAlone(NodeId x, NodeId y) const { try { return _SliceOrder_order_[x] == _SliceOrder_order_[y]; } catch (const Exception&) { return true; } } /// notify the constraint of a modification of the graph INLINE void StructuralConstraintSliceOrder::modifyGraphAlone(const ArcAddition& change) {} /// notify the constraint of a modification of the graph INLINE void StructuralConstraintSliceOrder::modifyGraphAlone(const ArcDeletion& change) {} /// notify the constraint of a modification of the graph INLINE void StructuralConstraintSliceOrder::modifyGraphAlone(const ArcReversal& change) {} /// notify the constraint of a modification of the graph INLINE void StructuralConstraintSliceOrder::modifyGraphAlone(const GraphChange& change) {} /// indicates whether a change will always violate the constraint INLINE bool StructuralConstraintSliceOrder::isAlwaysInvalidAlone(const GraphChange& change) const { switch (change.type()) { case GraphChangeType::ARC_ADDITION: try { return (_SliceOrder_order_[change.node1()] > _SliceOrder_order_[change.node2()]); } catch (const Exception&) { return false; } case GraphChangeType::ARC_DELETION: return false; case GraphChangeType::ARC_REVERSAL: try { return (_SliceOrder_order_[change.node1()] != _SliceOrder_order_[change.node2()]); } catch (const Exception&) { return false; } default: GUM_ERROR(OperationNotAllowed, "edge modifications are not " "supported by SliceOrder constraints"); } } /// checks whether the constraints enable to add an arc INLINE bool StructuralConstraintSliceOrder::checkModificationAlone(const ArcAddition& change) const { return checkArcAdditionAlone(change.node1(), change.node2()); } /// checks whether the constraints enable to remove an arc INLINE bool StructuralConstraintSliceOrder::checkModificationAlone(const ArcDeletion& change) const { return checkArcDeletionAlone(change.node1(), change.node2()); } /// checks whether the constraints enable to reverse an arc INLINE bool StructuralConstraintSliceOrder::checkModificationAlone(const ArcReversal& change) const { return checkArcReversalAlone(change.node1(), change.node2()); } /// checks whether the constraints enable to perform a graph change INLINE bool StructuralConstraintSliceOrder::checkModificationAlone(const GraphChange& change) const { switch (change.type()) { case GraphChangeType::ARC_ADDITION: return checkArcAdditionAlone(change.node1(), change.node2()); case GraphChangeType::ARC_DELETION: return checkArcDeletionAlone(change.node1(), change.node2()); case GraphChangeType::ARC_REVERSAL: return checkArcReversalAlone(change.node1(), change.node2()); default: GUM_ERROR(OperationNotAllowed, "edge modifications are not " "supported by StructuralConstraintSliceOrder"); } } /// sets the time slices of all the nodes in the property INLINE void StructuralConstraintSliceOrder::setSliceOrder(const NodeProperty< NodeId >& order) { _SliceOrder_order_ = order; } /// sets the default time slice INLINE void StructuralConstraintSliceOrder::setDefaultSlice(NodeId slice) { for (auto& node: _SliceOrder_order_) { node.second = slice; } } /// adds a new node in the slice order INLINE void StructuralConstraintSliceOrder::addNode(NodeId node, NodeId slice) { _SliceOrder_order_.set(node, slice); } /// returns the current slice order INLINE const NodeProperty< NodeId >& StructuralConstraintSliceOrder::sliceOrder() const { return _SliceOrder_order_; } // include all the methods applicable to the whole class hierarchy # define GUM_CONSTRAINT_CLASS_NAME StructuralConstraintSliceOrder # include # undef GUM_CONSTRAINT_CLASS_NAME } /* namespace learning */ } /* namespace gum */ #endif /* DOXYGEN_SHOULD_SKIP_THIS */