/*
 * DlpSolverTest.java
 * JUnit based test
 *
 * Copyright (C) 2006 - 2007 Martin Slota
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 2 of the License, or (at your option) any later
 * version.
 *
 * This program 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 General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program; if not, write to the Free Software Foundation, Inc., 51
 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

/*
 * History:
 * v0.1 (2007-02-15): initial version
 * v0.1.5 (2007-02-14):
 * - 1 test added
 * v1.0.0 (2007-05-06):
 * - documentation added
 *
 * PENDING write more tests
 */

package lp.trans;

import java.util.HashSet;
import java.util.Set;
import junit.framework.*;

import lp.parse.LpParser;
import lp.unit.DynamicLogicProgram;
import lp.unit.StableModel;
import lp.unit.TransformedDlp;
import static lp.parse.LpTokenType.*;

/**
 * Contains tests of the {@link DlpSolver} class.
 *
 * @author Martin Slota
 * @version 1.0.0
 * @see DlpSolver
 */
public class DlpSolverTest extends TestCase {
	/**
	 * The parser used in the tests.
	 */
	private final LpParser parser = new LpParser();
	
	/**
	 * The grounder used in the tests.
	 */
	private final DlpGrounder grounder = new DlpGrounder();
	
	/**
	 * The transformer used in the tests.
	 */
	private final DlpTransformer transformer = new DlpTransformer();
	
	/**
	 * The instance of {@link DlpSolver} that is being tested.
	 */
	private final DlpSolver solver = new DlpSolver();
	
	/**
	 * Object for collecting the computed models.
	 */
	private final CollectingModelConsumer processor =
			new CollectingModelConsumer();
	
	/**
	 * A default test case constructor.
	 *
	 * @param testName the name of the test case
	 */
	public DlpSolverTest(String testName) {
		super(testName);
	}
	
	/**
	 *
	 */
	public void testOrdinaryInput() {
		String [] dlpSource = {
			"a <- not b. b <- not a.",
			"c <- a. not c <- a."
		};
		
		Set<String> expModelSources = new HashSet<String>();
		expModelSources.add("b");
		
		doTest(dlpSource, expModelSources);
	}
	
	/**
	 * Performs a single call of
	 *
	 *<pre>
	 *solver.solve(dlp);
	 *</pre>
	 *
	 * where {@code dlp} is the dynamic logic program obtained by parsing
	 * {@code dlpSource}. Then it tests if the expected set of models is
	 * computed.
	 *
	 * @param dlpSource the string with the input dynamic logic program
	 * @param expModelSources string representations of the expected models
	 */
	private void doTest(String [] dlpSource, Set<String> expModelSources) {
		DynamicLogicProgram dlp = new DynamicLogicProgram();
		for (String programSource : dlpSource) {
			parser.setInput(programSource);
			dlp.add(parser.parseAllRules());
			parser.close();
		}
		
		DynamicLogicProgram groundedDlp = grounder.ground(dlp);
		TransformedDlp transformedDlp = transformer.transform(groundedDlp);
		
		Set<StableModel> expModels = new HashSet<StableModel>();
		for (String expModelSource : expModelSources) {
			parser.setInput(expModelSource);
			StableModel expModel = new StableModel();
			while (parser.hasMoreTokens()) {
				expModel.add(parser.parseAtom());
			}
			expModels.add(expModel);
		}
		
		processor.clear();
		solver.solve(transformedDlp, processor);
		
		assertEquals("The stable models are not as expected!",
				expModels, processor);
		
	}
}