TuringSim
C++ framework to simulate abstract computing models
mConfiguration.h
1 #pragma once
2 
3 #include <utils/printer.h>
4 #include <state/statePattern.h>
5 #include <utils/messageException.h>
6 
7 #include <numeric>
8 
20  template <typename NodeType>
22  public StatePattern<
23  std::shared_ptr<const MConfiguration<NodeType>>,
24  std::map<NodeType, std::shared_ptr<const MConfiguration<NodeType>>>
25  > {
26  public:
30  typedef std::map<NodeType, std::shared_ptr<const MConfiguration<NodeType>>> Unification;
31  private:
32  typedef std::shared_ptr<const MConfiguration<NodeType>> StateType_;
34  public:
35  using typename StatePattern_::StateType;
36  using typename StatePattern_::MatcherType;
37 
41  typedef std::map<NodeType, NodeType> AlphaRewriting;
42 
46  typedef std::pair<AlphaRewriting, AlphaRewriting> AlphaRelation;
47 
48  static_assert(std::is_same_v<StateType, StateType_>);
49  static_assert(std::is_same_v<StateType, std::shared_ptr<const MConfiguration<NodeType>>>);
50  static_assert(std::is_same_v<MatcherType, std::map<NodeType, std::shared_ptr<const MConfiguration<NodeType>>>>);
51  static_assert(std::is_same_v<MatcherType, Unification>);
52 
58  constexpr MConfiguration(const NodeType& leaf);
65  constexpr MConfiguration(const NodeType& leaf, bool isVar);
72  constexpr MConfiguration(const NodeType& node, const std::vector<MConfiguration<NodeType>>& subTrees);
79  constexpr MConfiguration(const NodeType& node, std::vector<MConfiguration<NodeType>>&& subTrees);
86  constexpr MConfiguration(const NodeType& node, const std::vector<std::shared_ptr<const MConfiguration<NodeType>>>& subTrees);
93  constexpr MConfiguration(const NodeType& node, std::vector<std::shared_ptr<const MConfiguration<NodeType>>>&& subTrees);
98  constexpr MConfiguration(const MConfiguration<NodeType>& other);
123  virtual ~MConfiguration() override = default;
132  constexpr std::shared_ptr<const MConfiguration<NodeType>> getArg(size_t) const;
138  constexpr const NodeType& getNode() const;
144  constexpr size_t getArity() const;
150  constexpr bool isLeaf() const;
158  constexpr bool isVariable() const;
166  constexpr bool isPattern() const;
172  constexpr bool isMFunction() const;
182  static std::shared_ptr<const MConfiguration<NodeType>> applySubstitution(std::shared_ptr<const MConfiguration<NodeType>> pattern, const Unification& subs);
193  static std::shared_ptr<const MConfiguration<NodeType>> applySubstitution(std::shared_ptr<const MConfiguration<NodeType>> pattern, const Unification& subs, const std::shared_ptr<const MConfiguration<NodeType>>& def);
200  static void unify_state(const std::shared_ptr<const MConfiguration<NodeType>>& state, const MConfiguration<NodeType>& pattern, std::map<NodeType, std::shared_ptr<const MConfiguration<NodeType>>>& unification);
207  static std::map<NodeType, std::shared_ptr<const MConfiguration<NodeType>>> unify_state(const std::shared_ptr<const MConfiguration<NodeType>>& state, const MConfiguration<NodeType>& pattern);
217  constexpr Unification unifyWithMConf(const std::shared_ptr<const MConfiguration<NodeType>>& state) const;
228  Unification unify(const std::shared_ptr<const MConfiguration<NodeType>>& state) const;
237  std::optional<Unification> unifyWithMConf_opt(const std::shared_ptr<const MConfiguration<NodeType>>& state) const noexcept;
246  std::optional<MatcherType> match(const StateType& state) const noexcept override final;
259  std::optional<Unification> unify_opt(const std::shared_ptr<const MConfiguration<NodeType>>& state) const;
270  template<typename CharT = char, typename Traits = std::char_traits<CharT>, typename Alloc = std::allocator<CharT>>
271  std::basic_string<CharT, Traits, Alloc> toString() const;
278  constexpr int compare(const MConfiguration<NodeType>& other) const;
285  constexpr bool operator!=(const MConfiguration<NodeType>& other) const;
292  constexpr bool operator==(const MConfiguration<NodeType>& other) const;
299  bool operator<(const MConfiguration<NodeType>& other) const;
306  std::optional<AlphaRelation> isAlphaEquivalent(const std::shared_ptr<const MConfiguration<NodeType>>& other) const;
315  void isAlphaEquivalent(const std::shared_ptr<const MConfiguration<NodeType>>& other, AlphaRewriting& direct, AlphaRewriting& back) const;
321  template <typename CharT = char, typename Traits = std::char_traits<CharT>>
322  std::function<std::basic_ostream<CharT, Traits>&(std::basic_ostream<CharT, Traits>&)> debug() const;
323 
330  template <typename CharT = char, typename Traits = std::char_traits<CharT>>
331  static std::function<std::basic_ostream<CharT, Traits>&(std::basic_ostream<CharT, Traits>&)> debug(const Unification& unification);
332 
339  template <typename CharT = char, typename Traits = std::char_traits<CharT>>
340  static std::function<std::basic_ostream<CharT, Traits>&(std::basic_ostream<CharT, Traits>&)> debug(const AlphaRewriting& rewriting);
341 
348  template <typename CharT = char, typename Traits = std::char_traits<CharT>>
349  static std::function<std::basic_ostream<CharT, Traits>&(std::basic_ostream<CharT, Traits>&)> debug(const AlphaRelation& relation);
350 
361  template <typename U, typename CharT, typename Traits> constexpr friend std::basic_ostream<CharT, Traits>& operator<<(std::basic_ostream<CharT, Traits>& os, const MConfiguration<U>& m_conf) {
362  if(m_conf.args.empty()) {
363  os << (m_conf.isVar ? "_" : "") << m_conf.node;
364  return os;
365  }
366 
367  os << m_conf.node << "(";
368  bool first = true;
369  for(size_t i = 0; i < m_conf.args.size(); ++i) {
370  if(first) {
371  first = false;
372  }
373  else {
374  os << ", ";
375  }
376  os << *m_conf.args[i];
377  }
378  os << ")";
379  return os;
380  }
381 
382  protected:
386  NodeType node;
391  bool isVar;
395  std::vector<std::shared_ptr<const MConfiguration<NodeType>>> args;
400  };
401 
406  template <typename NodeType>
408  public:
413 
421  std::string message,
425  MessageException(message),
426  pattern(pattern),
427  state(state),
429  {}
430 
431  protected:
432  virtual std::string makeFullMessage() const override {
433  using Utils::Debug::operator<<;
434  std::ostringstream ss;
435  ss << this->msg << std::endl;
436  ss << " pattern: " << pattern.debug() << std::endl;
437  ss << " state: " << state.debug() << std::endl;
438  ss << " unification: " << Utils::Debug::debug(unification) << std::endl;
439  return ss.str();
440  }
441 
445 
449 
453  };
454 
459  template <typename NodeType>
461  public:
466 
475  std::string message,
480  MessageException(message),
481  lhs(lhs),
482  rhs(rhs),
483  direct(direct),
484  back(back)
485  {}
486 
487  protected:
488  virtual std::string makeFullMessage() const override {
489  using Utils::Debug::operator<<;
490  std::ostringstream ss;
491  ss << this->msg << std::endl;
492  ss << " lhs: " << lhs.debug() << std::endl;
493  ss << " rhs: " << rhs.debug() << std::endl;
494  ss << " direct: " << Utils::Debug::debug(direct) << std::endl;
495  ss << " back: " << Utils::Debug::debug(back) << std::endl;
496  return ss.str();
497  }
498 
502 
506 
510 
514  };
515 
518  template <typename NodeType> MConfiguration(const NodeType&) -> MConfiguration<NodeType>;
519 
520  template <typename NodeType>
521  constexpr MConfiguration<NodeType>::MConfiguration(const NodeType& leaf) :
522  StatePattern_(),
523  node(leaf),
524  isVar(false),
525  args(std::vector<std::shared_ptr<const MConfiguration<NodeType>>>()),
526  is_pattern(false)
527  {}
528 
529  template <typename NodeType>
530  constexpr MConfiguration<NodeType>::MConfiguration(const NodeType& leaf, bool isVariable) :
531  StatePattern_(),
532  node(leaf),
533  isVar(isVariable),
534  args(std::vector<std::shared_ptr<const MConfiguration<NodeType>>>()),
535  is_pattern(isVariable)
536  {}
537 
538  template <typename NodeType>
539  constexpr MConfiguration<NodeType>::MConfiguration(const NodeType& nodeContent, const std::vector<MConfiguration<NodeType>>& subTrees) :
540  StatePattern_(),
541  node(nodeContent),
542  isVar(false),
543  args(),
544  is_pattern(std::accumulate(subTrees.begin(), subTrees.end(), false, [](bool acc, const MConfiguration<NodeType>& b) -> bool { return acc || b.is_pattern; }))
545  {
546  for(const MConfiguration<NodeType>& subTree: subTrees) {
547  args.push_back(std::make_shared<MConfiguration<NodeType>>(subTree));
548  }
549  }
550 
551  template <typename NodeType>
552  constexpr MConfiguration<NodeType>::MConfiguration(const NodeType& nodeContent, std::vector<MConfiguration<NodeType>>&& subTrees) :
553  StatePattern_(),
554  node(nodeContent),
555  isVar(false),
556  args(),
557  is_pattern(std::accumulate(subTrees.begin(), subTrees.end(), false, [](bool acc, const MConfiguration<NodeType>& b) -> bool { return acc || b.is_pattern; }))
558  {
559  for(const MConfiguration<NodeType>& subTree: subTrees) {
560  args.push_back(std::make_shared<MConfiguration<NodeType>>(std::move(subTree)));
561  }
562  }
563 
564  template <typename NodeType>
565  constexpr MConfiguration<NodeType>::MConfiguration(const NodeType& nodeContent, const std::vector<std::shared_ptr<const MConfiguration<NodeType>>>& subTrees) :
566  StatePattern_(),
567  node(nodeContent),
568  isVar(false),
569  args(subTrees),
570  is_pattern(std::accumulate(subTrees.begin(), subTrees.end(), false, [](bool acc, const std::shared_ptr<const MConfiguration<NodeType>>& b) -> bool { return acc || b->is_pattern; }))
571  {}
572 
573  template <typename NodeType>
574  constexpr MConfiguration<NodeType>::MConfiguration(const NodeType& nodeContent, std::vector<std::shared_ptr<const MConfiguration<NodeType>>>&& subTrees) :
575  StatePattern_(),
576  node(nodeContent),
577  isVar(false),
578  args(std::move(subTrees)),
579  is_pattern(std::accumulate(subTrees.begin(), subTrees.end(), false, [](bool acc, const std::shared_ptr<const MConfiguration<NodeType>>& b) -> bool { return acc || b->is_pattern; }))
580  {}
581 
582  template <typename NodeType>
584  StatePattern_(other),
585  node(other.node),
586  isVar(other.isVar),
587  args(other.args),
588  is_pattern(other.is_pattern)
589  {}
590 
591  template <typename NodeType>
593  StatePattern_(std::move(other)),
594  node(std::move(other.node)),
595  isVar(other.isVar),
596  args(std::move(other.args)),
597  is_pattern(other.is_pattern)
598  {}
599 
600  template <typename NodeType>
602  if(this != &other) {
603  StatePattern_::operator=(other);
604  node = other.node;
605  isVar = other.isVar;
606  args = other.args;
607  is_pattern = other.is_pattern;
608  }
609  return *this;
610  }
611 
612  template <typename NodeType>
614  if(this != &other) {
615  StatePattern_::operator=(std::move(other));
616  node = std::move(other.node);
617  isVar = other.isVar;
618  args = std::move(other.args);
619  is_pattern = other.is_pattern;
620  }
621  return *this;
622  }
623 
624  template <typename NodeType>
625  constexpr std::shared_ptr<const MConfiguration<NodeType>> MConfiguration<NodeType>::getArg(size_t i) const {
626  return args.at(i);
627  }
628 
629  template <typename NodeType>
630  constexpr const NodeType& MConfiguration<NodeType>::getNode() const {
631  return node;
632  }
633 
634  template <typename NodeType>
635  constexpr size_t MConfiguration<NodeType>::getArity() const {
636  return args.size();
637  }
638 
639  template <typename NodeType>
640  constexpr bool MConfiguration<NodeType>::isLeaf() const {
641  return args.empty();
642  }
643 
644  template <typename NodeType>
645  constexpr bool MConfiguration<NodeType>::isVariable() const {
646  return isVar;
647  }
648 
649  template <typename NodeType>
650  constexpr bool MConfiguration<NodeType>::isPattern() const {
651  return is_pattern;
652  }
653 
654  template <typename NodeType>
655  constexpr bool MConfiguration<NodeType>::isMFunction() const {
656  return !is_pattern;
657  }
658 
659  template <typename NodeType>
660  std::shared_ptr<const MConfiguration<NodeType>> MConfiguration<NodeType>::applySubstitution(std::shared_ptr<const MConfiguration<NodeType>> pattern, const Unification& subs) {
661  if(pattern->isLeaf() && pattern->isVariable()) {
662  if(subs.count(pattern->node))
663  return subs.at(pattern->node);
664  else
665  return pattern;
666  }
667 
668  std::vector<std::shared_ptr<const MConfiguration<NodeType>>> outputArgs;
669 
670  for(std::shared_ptr<const MConfiguration<NodeType>> arg : pattern->args) {
671  if(arg->is_pattern) {
672  outputArgs.push_back(applySubstitution(arg, subs));
673  }
674  else {
675  outputArgs.push_back(arg);
676  }
677  }
678 
679  return std::make_shared<const MConfiguration<NodeType>>(pattern->node, std::move(outputArgs));
680  }
681 
682  template <typename NodeType>
683  std::shared_ptr<const MConfiguration<NodeType>> MConfiguration<NodeType>::applySubstitution(std::shared_ptr<const MConfiguration<NodeType>> pattern, const Unification& subs, const std::shared_ptr<const MConfiguration<NodeType>>& def) {
684  if(pattern->isLeaf() && pattern->isVariable()) {
685  if(subs.count(pattern->node))
686  return subs.at(pattern->node);
687  else
688  return def;
689  }
690 
691  std::vector<std::shared_ptr<const MConfiguration<NodeType>>> outputArgs;
692 
693  for(std::shared_ptr<const MConfiguration<NodeType>> arg : pattern->args) {
694  if(arg->is_pattern) {
695  outputArgs.push_back(applySubstitution(arg, subs, def));
696  }
697  else {
698  outputArgs.push_back(arg);
699  }
700  }
701 
702  return std::make_shared<const MConfiguration<NodeType>>(pattern->node, std::move(outputArgs));
703  }
704 
705  template <typename NodeType>
706  void MConfiguration<NodeType>::unify_state(const std::shared_ptr<const MConfiguration<NodeType>>& state, const MConfiguration<NodeType>& pattern, std::map<NodeType, std::shared_ptr<const MConfiguration<NodeType>>>& unification) {
707  std::function<NoUnificationException<NodeType>(const std::string&)> make_exception =
708  [&state, &pattern, &unification = std::as_const(unification)](const std::string& message) {
709  return NoUnificationException(message, pattern, *state, unification);
710  };
711 
712  if(pattern.isLeaf()) {
713  if(pattern.isVariable()) {
714  NodeType node = pattern.getNode();
715  typename std::map<NodeType, std::shared_ptr<const MConfiguration<NodeType>>>::const_iterator it = unification.find(node);
716  if(it == unification.end()) {
717  unification.insert({node, state});
718  }
719  else if(*it->second != *state) {
720  std::ostringstream ss;
721  ss << "Unable to unify: incompatible variables. At node " << node << "." << std::endl
722  << " Known unification: " << it->second;
723  throw make_exception(ss.str());
724  }
725  else {
726  return;
727  }
728  }
729  else if(pattern.getNode() == state->getNode())
730  return;
731  else {
732  std::ostringstream ss;
733  ss << "Unable to unify: incompatible leaves: " << state->getNode() << "(state) vs " << pattern.getNode() << "(pattern)";
734  throw make_exception(ss.str());
735  }
736  } else {
737  if(state->getArity() != pattern.getArity()) {
738  std::ostringstream ss;
739  ss << "Unable to unify: arities does not match: "
740  << state->getArity() << "(state) vs "
741  << pattern.getArity() << "(pattern)";
742  throw make_exception(ss.str());
743  }
744  if(state->getNode() != pattern.getNode()) {
745  std::ostringstream ss;
746  ss << "Unable to unify: m-function name does not match: " << state->getNode() << "(state) vs "
747  << pattern.getNode() << "(pattern)";
748  throw make_exception(ss.str());
749  }
750  size_t args_size = state->getArity();
751  for(size_t i=0; i < args_size; ++i) {
752  unify_state(state->args[i], *pattern.args[i], unification);
753  }
754  }
755  }
756 
757  template <typename NodeType>
758  std::map<NodeType, std::shared_ptr<const MConfiguration<NodeType>>> MConfiguration<NodeType>::unify_state(const std::shared_ptr<const MConfiguration<NodeType>>& state, const MConfiguration<NodeType>& pattern) {
759  std::function<NoUnificationException<NodeType>(const std::string&)> make_exception =
760  [&state, &pattern](const std::string& message) {
761  using Utils::Debug::operator<<;
762  std::ostringstream ss;
763  ss << message << std::endl;
764  ss << " state: " << state->debug() << std::endl;
765  ss << " pattern: " << pattern.debug() << std::endl;
766  return NoUnificationException<NodeType>(message, pattern, *state, {});
767  };
768 
769  if(state->isPattern()) {
770  throw make_exception("first argument of unify_state must not be a pattern.");
771  }
772  std::map<NodeType, std::shared_ptr<const MConfiguration<NodeType>>> unification;
773  unify_state(state, pattern, unification);
774  return unification;
775  }
776 
777  template <typename NodeType>
779  return unify_state(state, *this);
780  }
781 
782  template <typename NodeType>
784  std::function<NoUnificationException<NodeType>(const std::string&)> make_exception =
785  [this, &other](const std::string& message) {
786  return NoUnificationException(message, *this, *other, {});
787  };
788 
789  if(isPattern()) {
790  if(other->isMFunction()) {
791  return unifyWithMConf(other);
792  }
793  throw make_exception("Two patterns in MConfiguration<T>::unify");
794  }
795  else {
796  throw make_exception("'this' should be a pattern for MConfiguration<T>::unify");
797  }
798  }
799 
800  template <typename NodeType>
801  std::optional<typename MConfiguration<NodeType>::Unification> MConfiguration<NodeType>::unifyWithMConf_opt(const std::shared_ptr<const MConfiguration<NodeType>>& m_conf) const noexcept {
802  try {
803  return std::make_optional(unify_state(m_conf, *this));
804  }
806  return std::nullopt;
807  }
808  }
809 
810  template <typename NodeType>
811  std::optional<typename MConfiguration<NodeType>::MatcherType> MConfiguration<NodeType>::match(const StateType& state) const noexcept {
812  return unifyWithMConf_opt(state);
813  }
814 
815  template <typename NodeType>
816  std::optional<typename MConfiguration<NodeType>::Unification> MConfiguration<NodeType>::unify_opt(const std::shared_ptr<const MConfiguration<NodeType>>& state) const {
817  std::function<NoUnificationException<NodeType>(const std::string&)> make_exception =
818  [this, &state](const std::string& message) {
819  return NoUnificationException(message, *this, *state, {});
820  };
821 
822  if(isPattern()) {
823  if(state->isMFunction()) {
824  return unifyWithMConf_opt(state);
825  }
826  throw make_exception("Two patterns in MConfiguration<T>::unify");
827  }
828  else {
829  throw make_exception("'this' should be a pattern for MConfiguration<T>::unify_opt");
830  }
831  }
832 
833  template <typename NodeType>
834  template <typename CharT, typename Traits, typename Alloc>
835  std::basic_string<CharT, Traits, Alloc> MConfiguration<NodeType>::toString() const {
836  std::basic_ostringstream<CharT, Traits, Alloc> ss;
837  ss << *this;
838  return ss.str();
839  }
840 
841  template <typename NodeType>
843  if(node != other.node) {
844  // return node <=> other.node;
845  if(node < other.node) {
846  return -1;
847  }
848  return 1;
849  }
850 
851  if(isVar != other.isVar) {
852  // return isVar <=> other.isVar;
853  if(isVar < other.isVar) {
854  return -1;
855  }
856  return 1;
857  }
858 
859  if(args.size() != other.args.size()) {
860  // return args.size() <=> other.args.size();
861  if(args.size() < other.args.size()) {
862  return -1;
863  }
864  return 1;
865  }
866 
867  const size_t args_size = args.size();
868 
869  for(size_t i = 0; i < args_size; ++i) {
870  // int cmp = args[i] <=> other.args[i];
871  // if(cmp) return cmp;
872  int cmp = args[i]->compare(*other.args[i]);
873  if (cmp) {
874  return cmp;
875  }
876  }
877 
878  return 0;
879  }
880 
881  template <typename NodeType>
883  return compare(other) != 0;
884  }
885 
886  template <typename NodeType>
888  return compare(other) == 0;
889  }
890 
891  template<typename NodeType>
893  return compare(other) < 0;
894  }
895 
896  template <typename NodeType>
897  std::optional<typename MConfiguration<NodeType>::AlphaRelation> MConfiguration<NodeType>::isAlphaEquivalent(const std::shared_ptr<const MConfiguration<NodeType>>& other) const {
898  AlphaRewriting direct, back;
899  try {
900  isAlphaEquivalent(other, direct, back);
901  }
903  return std::nullopt;
904  }
905  return {{direct, back}};
906  }
907 
908  template <typename NodeType>
909  void MConfiguration<NodeType>::isAlphaEquivalent(const std::shared_ptr<const MConfiguration<NodeType>>& other, AlphaRewriting& direct, AlphaRewriting& back) const {
910  std::function<NoAlphaEquivalenceException<NodeType>(const std::string&)> make_exception =
911  [this, &other, &direct = std::as_const(direct), &back = std::as_const(back)](const std::string& message) {
912  return NoAlphaEquivalenceException<NodeType>(message, *this, *other, direct, back);
913  };
914  if(isVar != other->isVar) {
915  throw make_exception("One variable and one constant node");
916  }
917  if(!isVar) {
918  if(node != other->node) {
919  throw make_exception("Two unequal nodes");
920  }
921  if(args.size() != other->args.size()) {
922  throw make_exception("Two nodes with unequal arity");
923  }
924 
925  const size_t args_size = args.size();
926  for(size_t i = 0; i < args_size; ++i) {
927  args[i]->isAlphaEquivalent(other->args[i], direct, back);
928  }
929  }
930  else {
931  if(direct.count(node) > 0 && back.count(other->node) == 0) {
932  throw make_exception("Left node does not point to right node");
933  }
934  else if(direct.count(node) == 0 && back.count(other->node) > 0) {
935  throw make_exception("Right node does not point to left node");
936  }
937  else if(direct.count(node) == 0 && back.count(other->node) == 0) {
938  direct[node] = other->node;
939  back[other->node] = node;
940  }
941  else if(direct[node] != other->node || back[other->node] != node) {
942  throw make_exception("Incompatible relation");
943  }
944  else {
945  return;
946  }
947 
948  }
949  }
950 
951  template <typename NodeType>
952  template <typename CharT, typename Traits>
953  std::function<std::basic_ostream<CharT, Traits>&(std::basic_ostream<CharT, Traits>&)> MConfiguration<NodeType>::debug() const {
954  return [this](std::basic_ostream<CharT, Traits>& out) -> std::basic_ostream<CharT, Traits>& {
955  if (args.empty()) {
956  out << std::string(isVar ? "_" : "") << node;
957  return out;
958  }
959 
960  out << "{" << node << "}(";
961  for (size_t i = 0; i < args.size() - 1; ++i)
962  out << "{" << *args[i] << "}, ";
963  out << "{" << *args.back() << "})";
964  return out;
965  };
966  }
967 
968  template<typename NodeType>
969  template <typename CharT, typename Traits>
970  std::function<std::basic_ostream<CharT, Traits>&(std::basic_ostream<CharT, Traits>&)> MConfiguration<NodeType>::debug(const MConfiguration::Unification& u) {
971  return Utils::Debug::debug(u);
972  }
973 
974  template<typename NodeType>
975  template <typename CharT, typename Traits>
976  std::function<std::basic_ostream<CharT, Traits>&(std::basic_ostream<CharT, Traits>&)> MConfiguration<NodeType>::debug(const MConfiguration::AlphaRewriting& rew) {
977  return Utils::Debug::debug(rew);
978  }
979 
980  template<typename NodeType>
981  template <typename CharT, typename Traits>
982  std::function<std::basic_ostream<CharT, Traits>&(std::basic_ostream<CharT, Traits>&)> MConfiguration<NodeType>::debug(const MConfiguration::AlphaRelation& rel) {
983  return Utils::Debug::debug(rel);
984  }
985 }
TuringSim::Utils::MessageException::MessageException
MessageException()=delete
a message exception must have an explicative message.
TuringSim::State::MConfiguration::MConfiguration::getArg
constexpr std::shared_ptr< const MConfiguration< NodeType > > getArg(size_t) const
Returns a child.
Definition: mConfiguration.h:625
TuringSim::State::MConfiguration::MConfiguration::AlphaRewriting
std::map< NodeType, NodeType > AlphaRewriting
The type of rewriting in an alpha-equivalence, in one direction only.
Definition: mConfiguration.h:41
TuringSim::State::MConfiguration::NoUnificationException::unification
MConfiguration< NodeType >::Unification unification
The unification when fail happened.
Definition: mConfiguration.h:452
TuringSim::State::MConfiguration::NoUnificationException::NoUnificationException
NoUnificationException()=delete
Deleted default constructor: a NoUnificationException must contain interesting information.
TuringSim::State::MConfiguration::MConfiguration::isLeaf
constexpr bool isLeaf() const
Returns whether the node is a leaf.
Definition: mConfiguration.h:640
TuringSim::Utils::MessageException::msg
std::string msg
The error message.
Definition: messageException.h:78
TuringSim::State::MConfiguration::MConfiguration
The base class for m-configurations.
Definition: mConfiguration.h:25
TuringSim::State::MConfiguration::MConfiguration::MConfiguration
constexpr MConfiguration(MConfiguration< NodeType > &&)
Move constructor.
Definition: mConfiguration.h:592
TuringSim::State::MConfiguration::MConfiguration::operator=
constexpr MConfiguration & operator=(const MConfiguration< NodeType > &)
Copy assignment operator.
Definition: mConfiguration.h:601
TuringSim::Utils::MessageException
The Base class for all custom exceptions.
Definition: messageException.h:12
TuringSim::State::MConfiguration::MConfiguration::match
std::optional< MatcherType > match(const StateType &state) const noexcept override final
Unify the MConfiguration with another.
Definition: mConfiguration.h:811
TuringSim::State::MConfiguration::MConfiguration::compare
constexpr int compare(const MConfiguration< NodeType > &other) const
Compare two MConfiguration. OCaml style, waiting for <=>. Strong ordering.
Definition: mConfiguration.h:842
TuringSim::State::MConfiguration::MConfiguration::args
std::vector< std::shared_ptr< const MConfiguration< NodeType > > > args
The ordered list of children.
Definition: mConfiguration.h:395
TuringSim::State::MConfiguration::NoAlphaEquivalenceException::lhs
MConfiguration< NodeType > lhs
the lhs operand.
Definition: mConfiguration.h:501
TuringSim::State::MConfiguration::MConfiguration::MConfiguration
constexpr MConfiguration(const NodeType &node, std::vector< std::shared_ptr< const MConfiguration< NodeType >>> &&subTrees)
Create an interior node.
Definition: mConfiguration.h:574
TuringSim::State::MConfiguration::MConfiguration::unify
Unification unify(const std::shared_ptr< const MConfiguration< NodeType >> &state) const
Unify the MConfiguration with another.
Definition: mConfiguration.h:783
TuringSim::State::MConfiguration::NoAlphaEquivalenceException::makeFullMessage
virtual std::string makeFullMessage() const override
Build the full error message. It should be overridden by derived class that adds data to the exceptio...
Definition: mConfiguration.h:488
TuringSim::State::MConfiguration::MConfiguration::MConfiguration
constexpr MConfiguration(const NodeType &leaf)
Create a constant leaf.
Definition: mConfiguration.h:521
TuringSim::State::MConfiguration::NoAlphaEquivalenceException::back
MConfiguration< NodeType >::AlphaRewriting back
The current right to left rewriting when fail happened.
Definition: mConfiguration.h:513
TuringSim::State::MConfiguration::MConfiguration::debug
static std::function< std::basic_ostream< CharT, Traits > &(std::basic_ostream< CharT, Traits > &)> debug(const AlphaRewriting &rewriting)
Return a debug printer for rewriting.
Definition: mConfiguration.h:976
TuringSim::State::MConfiguration::MConfiguration::MConfiguration
constexpr MConfiguration(const NodeType &node, std::vector< MConfiguration< NodeType >> &&subTrees)
Create an interior node and consume the subTrees.
Definition: mConfiguration.h:552
TuringSim::State::MConfiguration::MConfiguration::AlphaRelation
std::pair< AlphaRewriting, AlphaRewriting > AlphaRelation
The type of bi-directional alpha-equivalence.
Definition: mConfiguration.h:46
TuringSim::State::StatePattern::MatcherType
MatcherType_ MatcherType
The type returned when a state matches the pattern.
Definition: statePattern.h:25
TuringSim::State::MConfiguration::NoAlphaEquivalenceException::NoAlphaEquivalenceException
NoAlphaEquivalenceException()=delete
Deleted default constructor: a NoAlphaEquivalence must contain interesting information.
TuringSim::State::MConfiguration::MConfiguration::debug
static std::function< std::basic_ostream< CharT, Traits > &(std::basic_ostream< CharT, Traits > &)> debug(const AlphaRelation &relation)
Return a debug printer for relation.
Definition: mConfiguration.h:982
TuringSim::State::MConfiguration::MConfiguration::applySubstitution
static std::shared_ptr< const MConfiguration< NodeType > > applySubstitution(std::shared_ptr< const MConfiguration< NodeType >> pattern, const Unification &subs, const std::shared_ptr< const MConfiguration< NodeType >> &def)
Apply a substitution to the tree.
Definition: mConfiguration.h:683
TuringSim::State::MConfiguration::MConfiguration::debug
std::function< std::basic_ostream< CharT, Traits > &(std::basic_ostream< CharT, Traits > &)> debug() const
Return a debug printer for *this.
Definition: mConfiguration.h:953
TuringSim::State::MConfiguration::NoUnificationException::pattern
MConfiguration< NodeType > pattern
The pattern against which the state was matched.
Definition: mConfiguration.h:444
TuringSim::State::MConfiguration::MConfiguration::is_pattern
bool is_pattern
Whether the MConfiguration is a pattern.
Definition: mConfiguration.h:399
TuringSim::State::MConfiguration::MConfiguration::operator!=
constexpr bool operator!=(const MConfiguration< NodeType > &other) const
Test whether two MConfiguration are different.
Definition: mConfiguration.h:882
TuringSim::State::MConfiguration::MConfiguration::node
NodeType node
The content of the node.
Definition: mConfiguration.h:386
TuringSim::State::MConfiguration::MConfiguration::~MConfiguration
virtual ~MConfiguration() override=default
Destructor.
TuringSim::State::MConfiguration::MConfiguration
MConfiguration(const NodeType &) -> MConfiguration< NodeType >
TuringSim::State::MConfiguration::MConfiguration::operator<
bool operator<(const MConfiguration< NodeType > &other) const
Compare two MConfiguration.
Definition: mConfiguration.h:892
TuringSim::State::MConfiguration::MConfiguration::operator=
constexpr MConfiguration & operator=(MConfiguration< NodeType > &&)
Move assignment operator.
Definition: mConfiguration.h:613
TuringSim::State::MConfiguration::NoUnificationException::makeFullMessage
virtual std::string makeFullMessage() const override
Build the full error message. It should be overridden by derived class that adds data to the exceptio...
Definition: mConfiguration.h:432
TuringSim::State::MConfiguration::MConfiguration::unifyWithMConf_opt
std::optional< Unification > unifyWithMConf_opt(const std::shared_ptr< const MConfiguration< NodeType >> &state) const noexcept
Unify the MConfiguration with another.
Definition: mConfiguration.h:801
TuringSim::State::MConfiguration::NoUnificationException
Exception launched when we try to unify two incompatibles MConfiguration.
Definition: mConfiguration.h:407
TuringSim::State::MConfiguration::MConfiguration::operator==
constexpr bool operator==(const MConfiguration< NodeType > &other) const
Test whether two MConfiguration are the same.
Definition: mConfiguration.h:887
TuringSim::State::StatePattern
The base class of all state patterns.
Definition: statePattern.h:15
TuringSim::State::MConfiguration::MConfiguration::unify_state
static std::map< NodeType, std::shared_ptr< const MConfiguration< NodeType > > > unify_state(const std::shared_ptr< const MConfiguration< NodeType >> &state, const MConfiguration< NodeType > &pattern)
unify a state with a pattern.
Definition: mConfiguration.h:758
TuringSim::State::MConfiguration::MConfiguration::unify_state
static void unify_state(const std::shared_ptr< const MConfiguration< NodeType >> &state, const MConfiguration< NodeType > &pattern, std::map< NodeType, std::shared_ptr< const MConfiguration< NodeType >>> &unification)
unify a state with a pattern, while filling a unification.
Definition: mConfiguration.h:706
TuringSim::State::MConfiguration::MConfiguration::MConfiguration
constexpr MConfiguration(const NodeType &node, const std::vector< std::shared_ptr< const MConfiguration< NodeType >>> &subTrees)
Create an interior node.
Definition: mConfiguration.h:565
TuringSim::State::MConfiguration::MConfiguration::unify_opt
std::optional< Unification > unify_opt(const std::shared_ptr< const MConfiguration< NodeType >> &state) const
Unify the MConfiguration with another.
Definition: mConfiguration.h:816
TuringSim::State::MConfiguration::NoAlphaEquivalenceException::rhs
MConfiguration< NodeType > rhs
the rhs operand.
Definition: mConfiguration.h:505
TuringSim::State::MConfiguration::NoUnificationException::state
MConfiguration< NodeType > state
The state we try to unify.
Definition: mConfiguration.h:448
TuringSim::State::MConfiguration::NoAlphaEquivalenceException
Exception launched when we try to unify two incompatibles MConfiguration.
Definition: mConfiguration.h:460
TuringSim::State::MConfiguration::MConfiguration< T >::MatcherType
MatcherType_ MatcherType
The type returned when a state matches the pattern.
Definition: statePattern.h:25
TuringSim::State::MConfiguration::MConfiguration::getNode
constexpr const NodeType & getNode() const
Returns the content of the node.
Definition: mConfiguration.h:630
TuringSim::State::MConfiguration::MConfiguration::debug
static std::function< std::basic_ostream< CharT, Traits > &(std::basic_ostream< CharT, Traits > &)> debug(const Unification &unification)
Return a debug printer for unification.
Definition: mConfiguration.h:970
TuringSim::State::MConfiguration::MConfiguration::Unification
std::map< NodeType, std::shared_ptr< const MConfiguration< NodeType > > > Unification
The unification type between a pattern and a m-configuration.
Definition: mConfiguration.h:30
TuringSim::State::MConfiguration::NoAlphaEquivalenceException::NoAlphaEquivalenceException
NoAlphaEquivalenceException(std::string message, const MConfiguration< NodeType > &lhs, const MConfiguration< NodeType > &rhs, const typename MConfiguration< NodeType >::AlphaRewriting &direct, const typename MConfiguration< NodeType >::AlphaRewriting &back)
Builds a NoAlphaEquivalence.
Definition: mConfiguration.h:474
TuringSim::State::MConfiguration::NoAlphaEquivalenceException::direct
MConfiguration< NodeType >::AlphaRewriting direct
The current left to right rewriting when fail happened.
Definition: mConfiguration.h:509
TuringSim::State::MConfiguration::MConfiguration::MConfiguration
constexpr MConfiguration(const NodeType &leaf, bool isVar)
Create a leaf.
Definition: mConfiguration.h:530
TuringSim::Utils::Debug::debug
std::function< std::basic_ostream< CharT, Traits > &(std::basic_ostream< CharT, Traits > &)> debug(const T &s)
Generic debug printing function.
Definition: printer.h:34
TuringSim::State::MConfiguration::MConfiguration::unifyWithMConf
constexpr Unification unifyWithMConf(const std::shared_ptr< const MConfiguration< NodeType >> &state) const
Unify the MConfiguration with another.
Definition: mConfiguration.h:778
TuringSim::State::MConfiguration::MConfiguration::MConfiguration
constexpr MConfiguration(const MConfiguration< NodeType > &other)
Copy constructor.
Definition: mConfiguration.h:583
TuringSim::State::MConfiguration::MConfiguration::isAlphaEquivalent
void isAlphaEquivalent(const std::shared_ptr< const MConfiguration< NodeType >> &other, AlphaRewriting &direct, AlphaRewriting &back) const
Test whether two MConfiguration are alpha-equivalent.
Definition: mConfiguration.h:909
TuringSim::State::MConfiguration::NoUnificationException::NoUnificationException
NoUnificationException(std::string message, const MConfiguration< NodeType > &pattern, const MConfiguration< NodeType > &state, const typename MConfiguration< NodeType >::Unification &unification)
Builds a NoUnification.
Definition: mConfiguration.h:420
TuringSim::State::MConfiguration::MConfiguration::MConfiguration
constexpr MConfiguration(const NodeType &node, const std::vector< MConfiguration< NodeType >> &subTrees)
Create an interior node.
Definition: mConfiguration.h:539
TuringSim::State::MConfiguration::MConfiguration::operator<<
constexpr friend std::basic_ostream< CharT, Traits > & operator<<(std::basic_ostream< CharT, Traits > &os, const MConfiguration< U > &m_conf)
Print a MConfiguration.
Definition: mConfiguration.h:361
TuringSim::State::MConfiguration::MConfiguration< T >::StateType
StateType_ StateType
The type of states matched.
Definition: statePattern.h:20
TuringSim::State::MConfiguration::MConfiguration::isPattern
constexpr bool isPattern() const
Returns whether the MConfiguration is a pattern.
Definition: mConfiguration.h:650
TuringSim::State::MConfiguration::MConfiguration::isVar
bool isVar
Whether the node is a variable.
Definition: mConfiguration.h:391
TuringSim::State::MConfiguration::MConfiguration::isVariable
constexpr bool isVariable() const
Returns whether the node is a variable.
Definition: mConfiguration.h:645
TuringSim::State::MConfiguration::MConfiguration::toString
std::basic_string< CharT, Traits, Alloc > toString() const
Convert the MConfiguration in a string.
Definition: mConfiguration.h:835
TuringSim::State::MConfiguration::MConfiguration::getArity
constexpr size_t getArity() const
Returns the arity of the node.
Definition: mConfiguration.h:635
TuringSim::State::StatePattern::StateType
StateType_ StateType
The type of states matched.
Definition: statePattern.h:20
TuringSim::State::MConfiguration
The namespace of everything about m-configurations.
TuringSim::State::MConfiguration::MConfiguration::isAlphaEquivalent
std::optional< AlphaRelation > isAlphaEquivalent(const std::shared_ptr< const MConfiguration< NodeType >> &other) const
Test whether two MConfiguration are alpha-equivalent.
Definition: mConfiguration.h:897
TuringSim::State::MConfiguration::MConfiguration::isMFunction
constexpr bool isMFunction() const
Returns whether the MConfiguration is a m-function (ie. not a pattern).
Definition: mConfiguration.h:655
TuringSim::State::MConfiguration::MConfiguration::applySubstitution
static std::shared_ptr< const MConfiguration< NodeType > > applySubstitution(std::shared_ptr< const MConfiguration< NodeType >> pattern, const Unification &subs)
Apply a substitution to the tree.
Definition: mConfiguration.h:660