madarasip@1141: /* -*- mode: C++; indent-tabs-mode: nil; -*- madarasip@1141: * madarasip@1141: * This file is a part of LEMON, a generic C++ optimization library. madarasip@1141: * madarasip@1141: * Copyright (C) 2015 madarasip@1141: * EMAXA Kutato-fejleszto Kft. (EMAXA Research Ltd.) madarasip@1141: * madarasip@1141: * Permission to use, modify and distribute this software is granted madarasip@1141: * provided that this copyright notice appears in all copies. For madarasip@1141: * precise terms see the accompanying LICENSE file. madarasip@1141: * madarasip@1141: * This software is provided "AS IS" with no warranty of any kind, madarasip@1141: * express or implied, and with no claim as to its suitability for any madarasip@1141: * purpose. madarasip@1141: * madarasip@1141: */ madarasip@1141: madarasip@1141: #include madarasip@1141: #include madarasip@1141: #include madarasip@1141: #include madarasip@1141: #include madarasip@1141: madarasip@1141: #include madarasip@1141: #include madarasip@1141: madarasip@1141: using namespace lemon; madarasip@1141: madarasip@1141: char petersen_lgf[] = madarasip@1141: "@nodes\n" madarasip@1141: "label col1 col2\n" madarasip@1141: "0 1 1\n" madarasip@1141: "1 1 2\n" madarasip@1141: "2 1 3\n" madarasip@1141: "3 1 4\n" madarasip@1141: "4 2 5\n" madarasip@1141: "5 2 1\n" madarasip@1141: "6 2 2\n" madarasip@1141: "7 2 3\n" madarasip@1141: "8 2 4\n" madarasip@1141: "9 2 5\n" madarasip@1141: "@arcs\n" madarasip@1141: " -\n" madarasip@1141: "0 1\n" madarasip@1141: "1 2\n" madarasip@1141: "2 3\n" madarasip@1141: "3 4\n" madarasip@1141: "4 0\n" madarasip@1141: "0 5\n" madarasip@1141: "1 6\n" madarasip@1141: "2 7\n" madarasip@1141: "3 8\n" madarasip@1141: "4 9\n" madarasip@1141: "5 8\n" madarasip@1141: "5 7\n" madarasip@1141: "9 6\n" madarasip@1141: "9 7\n" madarasip@1141: "6 8\n"; madarasip@1141: madarasip@1141: char c5_lgf[] = madarasip@1141: "@nodes\n" madarasip@1141: "label col\n" madarasip@1141: "0 1\n" madarasip@1141: "1 2\n" madarasip@1141: "2 3\n" madarasip@1141: "3 4\n" madarasip@1141: "4 5\n" madarasip@1141: "@arcs\n" madarasip@1141: " -\n" madarasip@1141: "0 1\n" madarasip@1141: "1 2\n" madarasip@1141: "2 3\n" madarasip@1141: "3 4\n" madarasip@1141: "4 0\n"; madarasip@1141: madarasip@1141: char c7_lgf[] = madarasip@1141: "@nodes\n" madarasip@1141: "label\n" madarasip@1141: "0\n" madarasip@1141: "1\n" madarasip@1141: "2\n" madarasip@1141: "3\n" madarasip@1141: "4\n" madarasip@1141: "5\n" madarasip@1141: "6\n" madarasip@1141: "@arcs\n" madarasip@1141: " -\n" madarasip@1141: "0 1\n" madarasip@1141: "1 2\n" madarasip@1141: "2 3\n" madarasip@1141: "3 4\n" madarasip@1141: "4 5\n" madarasip@1141: "5 6\n" madarasip@1141: "6 0\n"; madarasip@1141: madarasip@1141: char c10_lgf[] = madarasip@1141: "@nodes\n" madarasip@1141: "label\n" madarasip@1141: "0\n" madarasip@1141: "1\n" madarasip@1141: "2\n" madarasip@1141: "3\n" madarasip@1141: "4\n" madarasip@1141: "5\n" madarasip@1141: "6\n" madarasip@1141: "7\n" madarasip@1141: "8\n" madarasip@1141: "9\n" madarasip@1141: "@arcs\n" madarasip@1141: " -\n" madarasip@1141: "0 1\n" madarasip@1141: "1 2\n" madarasip@1141: "2 3\n" madarasip@1141: "3 4\n" madarasip@1141: "4 5\n" madarasip@1141: "5 6\n" madarasip@1141: "6 7\n" madarasip@1141: "7 8\n" madarasip@1141: "8 9\n" madarasip@1141: "9 0\n"; madarasip@1141: madarasip@1141: char p10_lgf[] = madarasip@1141: "@nodes\n" madarasip@1141: "label\n" madarasip@1141: "0\n" madarasip@1141: "1\n" madarasip@1141: "2\n" madarasip@1141: "3\n" madarasip@1141: "4\n" madarasip@1141: "5\n" madarasip@1141: "6\n" madarasip@1141: "7\n" madarasip@1141: "8\n" madarasip@1141: "9\n" madarasip@1141: "@arcs\n" madarasip@1141: " -\n" madarasip@1141: "0 1\n" madarasip@1141: "1 2\n" madarasip@1141: "2 3\n" madarasip@1141: "3 4\n" madarasip@1141: "4 5\n" madarasip@1141: "5 6\n" madarasip@1141: "6 7\n" madarasip@1141: "7 8\n" madarasip@1141: "8 9\n"; madarasip@1141: madarasip@1141: SmartGraph petersen, c5, c7, c10, p10; madarasip@1141: SmartGraph::NodeMap petersen_col1(petersen); madarasip@1141: SmartGraph::NodeMap petersen_col2(petersen); madarasip@1141: SmartGraph::NodeMap c5_col(c5); madarasip@1141: madarasip@1141: void make_graphs() { madarasip@1141: std::stringstream ss(petersen_lgf); madarasip@1141: graphReader(petersen, ss) madarasip@1141: .nodeMap("col1",petersen_col1) madarasip@1141: .nodeMap("col2",petersen_col2) madarasip@1141: .run(); madarasip@1141: madarasip@1141: ss.clear(); madarasip@1141: ss.str(""); madarasip@1141: ss< madarasip@1141: class EqClass { madarasip@1141: public: madarasip@1141: bool operator()(A, B) { return false; } madarasip@1141: }; madarasip@1141: madarasip@1141: template madarasip@1141: void checkVf2Compile() madarasip@1141: { madarasip@1141: G1 g; madarasip@1141: G2 h; madarasip@1141: concepts::ReadWriteMap r; madarasip@1141: bool succ; madarasip@1141: ::lemon::ignore_unused_variable_warning(succ); madarasip@1141: madarasip@1141: succ = vf2(g,h).run(); madarasip@1141: succ = vf2(g,h).induced().run(); madarasip@1141: succ = vf2(g,h).iso().run(); madarasip@1141: succ = vf2(g,h).mapping(r).run(); madarasip@1141: succ = vf2(g,h).induced().mapping(r).run(); madarasip@1141: succ = vf2(g,h).iso().mapping(r).run(); madarasip@1141: concepts::ReadMap l1; madarasip@1141: concepts::ReadMap l2; madarasip@1141: succ = vf2(g,h).nodeLabels(l1,l2).mapping(r).run(); madarasip@1141: succ = vf2(g,h).nodeEq(EqClass()) madarasip@1141: .mapping(r).run(); madarasip@1141: } madarasip@1141: madarasip@1141: void justCompile() madarasip@1141: { madarasip@1141: checkVf2Compile(); madarasip@1141: checkVf2Compile(); madarasip@1141: checkVf2Compile(); madarasip@1141: } madarasip@1141: madarasip@1141: template madarasip@1141: void checkSub(const G1 &g1, const G2 &g2, const I &i) madarasip@1141: { madarasip@1141: { madarasip@1141: std::set image; madarasip@1141: for(typename G1::NodeIt n(g1);n!=INVALID;++n) madarasip@1141: { madarasip@1141: check(i[n]!=INVALID, "Wrong isomorphism: incomplete mapping."); madarasip@1141: check(image.count(i[n])==0,"Wrong isomorphism: not injective."); madarasip@1141: image.insert(i[n]); madarasip@1141: } madarasip@1141: } madarasip@1141: for(typename G1::EdgeIt e(g1);e!=INVALID;++e) madarasip@1141: check(findEdge(g2,i[g1.u(e)],i[g1.v(e)])!=INVALID, madarasip@1141: "Wrong isomorphism: missing edge(checkSub)."); madarasip@1141: } madarasip@1141: madarasip@1141: template madarasip@1141: void checkInd(const G1 &g1, const G2 &g2, const I &i) madarasip@1141: { madarasip@1141: std::set image; madarasip@1141: for(typename G1::NodeIt n(g1);n!=INVALID;++n) madarasip@1141: { madarasip@1141: check(i[n]!=INVALID, "Wrong isomorphism: incomplete mapping."); madarasip@1141: check(image.count(i[n])==0,"Wrong isomorphism: not injective."); madarasip@1141: image.insert(i[n]); madarasip@1141: } madarasip@1141: for(typename G1::NodeIt n(g1); n!=INVALID; ++n) madarasip@1141: for(typename G1::NodeIt m(g1); m!=INVALID; ++m) madarasip@1141: if((findEdge(g1,n,m)==INVALID) != (findEdge(g2,i[n],i[m])==INVALID)) madarasip@1141: { madarasip@1141: std::cout << "Wrong isomorphism: edge mismatch"; madarasip@1141: exit(1); madarasip@1141: } madarasip@1141: } madarasip@1141: madarasip@1141: template madarasip@1141: int checkSub(const G1 &g1, const G2 &g2) madarasip@1141: { madarasip@1141: typename G1:: template NodeMap iso(g1,INVALID); madarasip@1141: if(vf2(g1,g2).mapping(iso).run()) madarasip@1141: { madarasip@1141: checkSub(g1,g2,iso); madarasip@1141: return true; madarasip@1141: } madarasip@1141: else return false; madarasip@1141: } madarasip@1141: madarasip@1141: template madarasip@1141: int checkInd(const G1 &g1, const G2 &g2) madarasip@1141: { madarasip@1141: typename G1:: template NodeMap iso(g1,INVALID); madarasip@1141: if(vf2(g1,g2).induced().mapping(iso).run()) madarasip@1141: { madarasip@1141: checkInd(g1,g2,iso); madarasip@1141: return true; madarasip@1141: } madarasip@1141: else return false; madarasip@1141: } madarasip@1141: madarasip@1141: template madarasip@1141: int checkIso(const G1 &g1, const G2 &g2) madarasip@1141: { madarasip@1141: typename G1:: template NodeMap iso(g1,INVALID); madarasip@1141: if(vf2(g1,g2).iso().mapping(iso).run()) madarasip@1141: { madarasip@1141: check(countNodes(g1)==countNodes(g2), madarasip@1141: "Wrong iso alg.: they are not isomophic."); madarasip@1141: checkInd(g1,g2,iso); madarasip@1141: return true; madarasip@1141: } madarasip@1141: else return false; madarasip@1141: } madarasip@1141: madarasip@1141: template madarasip@1141: void checkLabel(const G1 &g1, const G2 &, madarasip@1141: const L1 &l1, const L2 &l2,const I &i) madarasip@1141: { madarasip@1141: for(typename G1::NodeIt n(g1);n!=INVALID;++n) madarasip@1141: { madarasip@1141: check(l1[n]==l2[i[n]],"Wrong isomorphism: label mismatch."); madarasip@1141: } madarasip@1141: } madarasip@1141: madarasip@1141: template madarasip@1141: int checkSub(const G1 &g1, const G2 &g2, const L1 &l1, const L2 &l2) madarasip@1141: { madarasip@1141: typename G1:: template NodeMap iso(g1,INVALID); madarasip@1141: if(vf2(g1,g2).nodeLabels(l1,l2).mapping(iso).run()) madarasip@1141: { madarasip@1141: checkSub(g1,g2,iso); madarasip@1141: checkLabel(g1,g2,l1,l2,iso); madarasip@1141: return true; madarasip@1141: } madarasip@1141: else return false; madarasip@1141: } madarasip@1141: madarasip@1141: int main() { madarasip@1141: make_graphs(); madarasip@1141: check(checkSub(c5,petersen), "There should exist a C5->Petersen mapping."); madarasip@1141: check(!checkSub(c7,petersen), madarasip@1141: "There should not exist a C7->Petersen mapping."); madarasip@1141: check(checkSub(p10,petersen), "There should exist a P10->Petersen mapping."); madarasip@1141: check(!checkSub(c10,petersen), madarasip@1141: "There should not exist a C10->Petersen mapping."); madarasip@1141: check(checkSub(petersen,petersen), madarasip@1141: "There should exist a Petersen->Petersen mapping."); madarasip@1141: madarasip@1141: check(checkInd(c5,petersen), madarasip@1141: "There should exist a C5->Petersen spanned mapping."); madarasip@1141: check(!checkInd(c7,petersen), madarasip@1141: "There should exist a C7->Petersen spanned mapping."); madarasip@1141: check(!checkInd(p10,petersen), madarasip@1141: "There should not exist a P10->Petersen spanned mapping."); madarasip@1141: check(!checkInd(c10,petersen), madarasip@1141: "There should not exist a C10->Petersen spanned mapping."); madarasip@1141: check(checkInd(petersen,petersen), madarasip@1141: "There should exist a Petersen->Petersen spanned mapping."); madarasip@1141: madarasip@1141: check(!checkSub(petersen,c10), madarasip@1141: "There should not exist a Petersen->C10 mapping."); madarasip@1141: check(checkSub(p10,c10), madarasip@1141: "There should exist a P10->C10 mapping."); madarasip@1141: check(!checkInd(p10,c10), madarasip@1141: "There should not exist a P10->C10 spanned mapping."); madarasip@1141: check(!checkSub(c10,p10), madarasip@1141: "There should not exist a C10->P10 mapping."); madarasip@1141: madarasip@1141: check(!checkIso(p10,c10), madarasip@1141: "P10 and C10 are not isomorphic."); madarasip@1141: check(checkIso(c10,c10), madarasip@1141: "C10 and C10 are not isomorphic."); madarasip@1141: madarasip@1141: check(!checkSub(c5,petersen,c5_col,petersen_col1), madarasip@1141: "There should exist a C5->Petersen mapping."); madarasip@1141: check(checkSub(c5,petersen,c5_col,petersen_col2), madarasip@1141: "There should exist a C5->Petersen mapping."); madarasip@1141: }