/*
 * Copyright (C) 2013 Matthew Dawson <matthew@mjdsystems.ca>
 *
 * 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 3 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, see <http://www.gnu.org/licenses/>.
 */
package ca.mcmaster.cas.smtlibchecker;

import ca.mcmaster.cas.matlab2smt.VariableParser;
import ca.mcmaster.cas.tablularexpression.HierarchcialGridCheckerWalkerGenerator;
import ca.mcmaster.cas.tablularexpression.HierarchicalCell;
import ca.mcmaster.cas.tablularexpression.HierarchicalGrid;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.util.List;

import static org.junit.Assert.assertEquals;

/**
 *
 * @author Matthew Dawson <matthew@mjdsystems.ca>
 */
@RunWith(JUnit4.class)
public class HierarchicalGridSMTLIBGeneratorTest {

    // Exercise the smtlib generator using a table designed in matlab.
    @Test
    public void exerciseSMTLIBGenerator() {
        HierarchicalGrid grid = new HierarchicalGrid();
        List<HierarchicalCell> topCells = grid.getSubHiearchy();

        topCells.add(new HierarchicalCell("x > 0"));
        topCells.add(new HierarchicalCell("x == 0"));
        topCells.add(new HierarchicalCell("0 > x"));

        List<HierarchicalCell> nextGrid = topCells.get(1).getSubHiearchy();
        nextGrid.add(new HierarchicalCell("z > 0"));
        nextGrid.add(new HierarchicalCell("z == 0"));
        nextGrid.add(new HierarchicalCell("0 > z"));

        nextGrid.get(1).getSubHiearchy().add(new HierarchicalCell("z == 0"));

        String out = HierarchcialGridCheckerWalkerGenerator.GenerateCheckerFromGrid(grid, new HierarchicalGridSMTLIBGenerator(new VariableParser("x,z")));

        String expected = "(push 1)\n" +
                "(assert (and true (or (and (> x 0.0) (= x 0.0))\n" +
                "(and (> x 0.0) (> 0.0 x))\n" +
                "(and (= x 0.0) (> 0.0 x)))))\n" +
                "(check-sat)\n" +
                "(pop 1)\n" +
                "(push 1)\n" +
                "(assert (and true (not (or (> x 0.0) (= x 0.0) (> 0.0 x)))))\n" +
                "(check-sat)\n" +
                "(pop 1)\n" +
                "(push 1)\n" +
                "(assert (and (= x 0.0) (or (and (> z 0.0) (= z 0.0))\n" +
                "(and (> z 0.0) (> 0.0 z))\n" +
                "(and (= z 0.0) (> 0.0 z)))))\n" +
                "(check-sat)\n" +
                "(pop 1)\n" +
                "(push 1)\n" +
                "(assert (and (= x 0.0) (not (or (> z 0.0) (= z 0.0) (> 0.0 z)))))\n" +
                "(check-sat)\n" +
                "(pop 1)\n" +
                "(push 1)\n" +
                "(assert (and (= z 0.0) (= x 0.0) false))\n" +
                "(check-sat)\n" +
                "(pop 1)\n" +
                "(push 1)\n" +
                "(assert (and (= z 0.0) (= x 0.0) (not (= z 0.0))))\n" +
                "(check-sat)\n" +
                "(pop 1)\n";

        assertEquals(expected, out);
    }

    // Test the smtlib generator using an empty table
    @Test
    public void testEmptyTable() {
        HierarchicalGrid grid = new HierarchicalGrid();

        String out = HierarchcialGridCheckerWalkerGenerator.GenerateCheckerFromGrid(grid, new HierarchicalGridSMTLIBGenerator(new VariableParser("x,z")));

        String expected = "(push 1)\n" +
                "(assert (and true false))\n" +
                "(check-sat)\n" +
                "(pop 1)\n" +
                "(push 1)\n" +
                "(assert (and true (not true)))\n" +
                "(check-sat)\n" +
                "(pop 1)\n";

        assertEquals(expected, out);
    }
}
