#define CATCH_CONFIG_MAIN
#include "catch2/catch.hpp"
#include "ir/ir.h"
using namespace std;
using namespace empathy;
using namespace empathy::ir;
SCENARIO( "Match works", "[match]" )
{
WHEN( "Matching various expressions against various patterns stored in a trie" )
{
auto pat0 = ANYTERM( a );
auto pat1 = TVEC(
TVEC( TSTR( "foo" ), TSTR( "bar" ) ),
TVEC(),
TVEC( TSTR( "foo" ), TSTR( "bar" ) ),
TVEC( TSTR( "foo" ), TSTR( "bar" ) )
);
auto expr1 = pat1;
auto pat2 = TVEC(
TVEC( ANYTERM( a ), TSTR( "bar" ) ),
TVEC(),
TVEC( ANYTERM( a ), TSTR( "bar" ) ),
TVEC( ANYTERM( a ), TSTR( "bar" ) )
);
auto expr2 = TVEC(
TVEC( TSTR( "meh" ), TSTR( "bar" ) ),
TVEC(),
TVEC( TSTR( "meh" ), TSTR( "bar" ) ),
TVEC( TSTR( "meh" ), TSTR( "bar" ) )
);
auto pat3 = TVEC(
ANYTERM( x ),
TVEC( ANYTERM( a ), TSTR( "bar" ) ),
ANYTERM( z ),
ANYTERM( z )
);
auto expr3 = TVEC(
TSID( a ),
TVEC( TSTR( "meh" ), TSTR( "bar" ) ),
TSID( b ),
TSID( b )
);
auto pat4 = TVEC(
TVEC( ANYTERM( a ), TSTR( "bar" ) ),
ANYTERM( y ),
ANYTERM( y ),
ANYTERM( y )
);
auto expr4 = TVEC(
TVEC( TSTR( "huh" ), TSTR( "bar" ) ),
TVEC(),
TVEC(),
TVEC()
);
Trie< string > testTrie1;
testTrie1 = Merge( testTrie1, pat0, []( auto&& ){ return "pat0"s; } );
testTrie1 = Merge( testTrie1, pat1, []( auto&& ){ return "pat1"s; } );
testTrie1 = Merge( testTrie1, pat2, []( auto&& ){ return "pat2"s; } );
testTrie1 = Merge( testTrie1, pat3, []( auto&& ){ return "pat3"s; } );
testTrie1 = Merge( testTrie1, pat4, []( auto&& ){ return "pat4"s; } );
THEN( "Matching the terms and the trie work as expected" )
{
vector< pair< MatchSolution, string > > solutions;
for( auto&& [sol, str] : Match( expr1, testTrie1 ) )
solutions.emplace_back( sol, str );
REQUIRE( solutions.size() == 3 );
REQUIRE( solutions[0].second == "pat0"s ); REQUIRE( solutions[0].first.complexity() == 0 ); REQUIRE( solutions[0].first.numVars() == 1 );
REQUIRE( solutions[1].second == "pat1"s ); REQUIRE( solutions[1].first.complexity() == 17 ); REQUIRE( solutions[1].first.numVars() == 0 );
REQUIRE( solutions[2].second == "pat2"s ); REQUIRE( solutions[2].first.complexity() == 11 ); REQUIRE( solutions[2].first.numVars() == 1 );
solutions.clear();
for( auto&& [sol, str] : Match( expr2, testTrie1 ) )
solutions.emplace_back( sol, str );
REQUIRE( solutions.size() == 2 );
REQUIRE( solutions[0].second == "pat0"s ); REQUIRE( solutions[0].first.complexity() == 0 ); REQUIRE( solutions[0].first.numVars() == 1 );
REQUIRE( solutions[1].second == "pat2"s ); REQUIRE( solutions[1].first.complexity() == 11 ); REQUIRE( solutions[1].first.numVars() == 1 );
solutions.clear();
for( auto&& [sol, str] : Match( expr3, testTrie1 ) )
solutions.emplace_back( sol, str );
REQUIRE( solutions.size() == 2 );
REQUIRE( solutions[0].second == "pat0"s ); REQUIRE( solutions[0].first.complexity() == 0 ); REQUIRE( solutions[0].first.numVars() == 1 );
REQUIRE( solutions[1].second == "pat3"s ); REQUIRE( solutions[1].first.complexity() == 4 ); REQUIRE( solutions[1].first.numVars() == 3 );
solutions.clear();
for( auto&& [sol, str] : Match( expr4, testTrie1 ) )
solutions.emplace_back( sol, str );
REQUIRE( solutions.size() == 2 );
REQUIRE( solutions[0].second == "pat0"s ); REQUIRE( solutions[0].first.complexity() == 0 ); REQUIRE( solutions[0].first.numVars() == 1 );
REQUIRE( solutions[1].second == "pat4"s ); REQUIRE( solutions[1].first.complexity() == 4 ); REQUIRE( solutions[1].first.numVars() == 2 );
}
}
}