// ---------------------------------------------------------------------------
//
//  This file is part of PermLib.
//
// Copyright (c) 2009-2010 Thomas Rehn <thomas@carmen76.de>
// All rights reserved.
// 
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
// 3. The name of the author may not be used to endorse or promote products
//    derived from this software without specific prior written permission.
// 
// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
// NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
// THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------


#define BOOST_TEST_DYN_LINK 
#define BOOST_TEST_MODULE permutation test
#include <boost/test/unit_test.hpp>

#include <iostream>
#include <fstream>

#include <permlib/permutation.h>
#include <permlib/permutationword.h>
#include <permlib/bsgs.h>

template<class PERM>
void testPermutation() {
	std::string line1("1 2 5,3 6 7 8, 9 4 10");
	std::string line2("1 2, 5 3 6, 7 8 9 4 10");
	const unsigned int n = 10;
	PERM a(n, line1);
	PERM b(n, line2);
	
	BOOST_CHECK(a / 1 == 4);
	BOOST_CHECK(a % 4 == 1);
	BOOST_CHECK((~a) / 4 == 1);

	BOOST_CHECK(b / 1 == 0);
	BOOST_CHECK(b % 0 == 1);
	BOOST_CHECK((~b) / 0 == 1);
	
	for (unsigned int i = 0; i < n; ++i) {
		BOOST_CHECK( a / (~a / i) == i);
		BOOST_CHECK( a % (~a % i) == i);
	}
	
	PERM c = a * b;
	PERM d(a);
	d *= b;
	
	BOOST_CHECK(c == d);
	
	d.invertInplace();
	
	for (unsigned int i = 0; i < n; ++i) {
		BOOST_CHECK( c / (d / i) == i);
		BOOST_CHECK( c % (d % i) == i);
	}
	
	c *= d;
	
	BOOST_CHECK(c.isIdentity());
}

BOOST_AUTO_TEST_CASE( test_permutation )
{
    testPermutation<permlib::Permutation>();
}

BOOST_AUTO_TEST_CASE( test_permutationword )
{
    testPermutation<permlib::PermutationWord>();
}
