Package com.anjlab.sat3

Source Code of com.anjlab.sat3.SimpleFormula

/*
* Copyright (c) 2010, 2011 AnjLab
*
* This file is part of
* Reference Implementation of Romanov's Polynomial Algorithm for 3-SAT Problem.
*
* Reference Implementation of Romanov's Polynomial Algorithm for 3-SAT Problem
* is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Reference Implementation of Romanov's Polynomial Algorithm for 3-SAT Problem
* 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with
* Reference Implementation of Romanov's Polynomial Algorithm for 3-SAT Problem.
* If not, see <http://www.gnu.org/licenses/>.
*/
package com.anjlab.sat3;

import static com.anjlab.sat3.SimpleTier.createCompleteTier;
import static java.lang.Boolean.parseBoolean;

import java.util.Comparator;
import java.util.Properties;

import cern.colt.list.ObjectArrayList;
import cern.colt.map.OpenIntIntHashMap;
import cern.colt.map.OpenIntObjectHashMap;
import cern.colt.map.OpenLongObjectHashMap;

public final class SimpleFormula implements ICompactTripletsStructure, ICompactTripletsStructureHolder
{
    //  List of ITier
    private final ObjectArrayList tiers;
    //  tiersHash1 and tiersHash2 only needed during CTF creation
    private OpenIntObjectHashMap tiersHash1;
    private OpenLongObjectHashMap tiersHash2;
    private OpenLongObjectHashMap tiersHash3;
    private final IPermutation permutation;
    private OpenIntIntHashMap internalToOriginalMap;

    public SimpleFormula()
    {
        permutation = new SimplePermutation();
        tiers = new ObjectArrayList();
        tiersHash1 = new OpenIntObjectHashMap();
        tiersHash2 = new OpenLongObjectHashMap();
        tiersHash3 = new OpenLongObjectHashMap();
    }
   
    public SimpleFormula(IPermutation permutation)
    {
        this.permutation = permutation;
        tiers = new ObjectArrayList();
        tiersHash3 = new OpenLongObjectHashMap();
    }
   
    /**
     * Creates copy of <code>formula</code>.
     *
     * New formula uses the same instance of <code>permutation</code> and cloned instances of tiers.
     * Be careful about modifying permutation of new formula, because these changes will also affect initial formula.
     *
     * @param formula
     */
    private SimpleFormula(SimpleFormula formula, final boolean fillTiersHash3)
    {
        this.permutation = formula.permutation;
        int tiersCount = formula.tiers.size();
       
        this.tiers = new ObjectArrayList(tiersCount);
        this.tiersHash3 = fillTiersHash3
                        ? new OpenLongObjectHashMap(tiersCount)
                        : null;
                       
        Object[] tiersElements = formula.tiers.elements();
        for (int i = 0; i < tiersCount; i++)
        {
            ITier clone = ((ITier) tiersElements[i]).clone();
            tiers.add(clone);
            if (fillTiersHash3)
            {
                tiersHash3.put(clone.canonicalHashCode(), clone);
            }
        }
    }
   
    /**
     * Creates copy of this formula.
     *
     * New formula uses the same instance of <code>permutation</code> and cloned instances of tiers.
     * Be careful about modifying permutation of new formula, because these changes will also affect initial formula.
     * TiersHashX will not be initialized.
     */
    public SimpleFormula clone()
    {
        return new SimpleFormula(this, false);
    }
   
    public void clear()
    {
        tiers.clear();
       
        if (tiersHash1 != null) tiersHash1.clear();
        if (tiersHash2 != null) tiersHash2.clear();
        if (tiersHash3 != null) tiersHash3.clear();
    }
   
    public int getClausesCount()
    {
        int clausesCount = 0;
        for (int i = 0; i < tiers.size(); i++)
        {
            ITier tier = (ITier) tiers.get(i);
            clausesCount += tier.size();
        }
        return clausesCount;
    }
   
    public int getVarCount()
    {
        return permutation.size();
    }
   
    public ObjectArrayList getTiers()
    {
        return tiers;
    }

    public boolean tiersSorted()
    {
        boolean sorted = true;
        int[] permutationElements = permutation.elements();
        Object[] tiersElements = tiers.elements();
        for (int i = 0; i < tiers.size() - 1; i++)
        {
            ITier tier = (ITier) tiersElements[i];
            if (permutation.indexOf(tier.getAName()) >
                permutation.indexOf(((ITier)tiersElements[i + 1]).getAName()))
            {
                sorted = false;
                break;
            }
            else
            {
                if (!(permutationElements[i] == tier.getAName()
                        && permutationElements[i + 1] == tier.getBName()
                        && permutationElements[i + 2] == tier.getCName()))
                {
                    sorted = false;
                    break;
                }
            }
        }
        return sorted;
    }

    private final Comparator<ITier> tierComparator = new Comparator<ITier>()
    {
        public int compare(ITier t1, ITier t2)
        {
            return permutation.indexOf(t1.getAName()) - permutation.indexOf(t2.getAName());
        }
    };
   
    public void sortTiers()
    {
        tiers.quickSortFromTo(0, tiers.size() - 1, tierComparator);
    }

    public void complete(IPermutation variables) throws EmptyStructureException
    {
        tiersHash1 = null;
        tiersHash2 = null;
       
        int varCount = variables.size();
        int tiersCount = varCount - 2;
       
        int[] variablesElements = ((SimplePermutation)variables).elements();
        for (int i = 0; i < varCount; i++)
        {
            int varName = variablesElements[i];
            if (!permutation.contains(varName))
            {
                permutation.add(varName);
            }
        }
        for (int i = 0; i < tiers.size(); i++)
        {
            ((ITier) tiers.get(i)).inverse();
        }
        int[] permutationElements = ((SimplePermutation)permutation).elements();
        SimpleTripletPermutation buffer = new SimpleTripletPermutation(1, 2, 3);
        for (int i = 0; i < tiersCount; i++)
        {
            int a = permutationElements[i];
            int b = permutationElements[i + 1];
            int c = permutationElements[i + 2];
           
            buffer.setCanonicalAttributes(a, b, c);
           
            if (!tiersHash3.containsKey(buffer.canonicalHashCode()))
            {
                addTier(createCompleteTier(a, b, c));
            }
        }
       
        if (tiers.size() != tiersCount)
        {
            throw new AssertionError("tiers.size() != tiersCount (" + tiers.size() + " != " + tiersCount + ")");
        }
       
        sortTiers();
        if (Helper.EnableAssertions)
        {
            assertTiersSorted();
        }
        cleanup();
        if (isEmpty())
        {
            throw new EmptyStructureException(this);
        }
    }

    public void add(ITriplet triplet)
    {
        ITier targetTier = findOrCreateTargetTierFor(triplet);

        triplet.transposeTo(targetTier);
       
        targetTier.add(triplet);
    }
   
    public ObjectArrayList findTiersFor(int varName)
    {
        return (ObjectArrayList) tiersHash1.get(varName);
    }
   
    public ObjectArrayList findTiersFor(int varName1, int varName2)
    {
        long key = varName1 < varName2 ? (long)varName1 << 21 | varName2 : (long)varName2 << 21 | varName1;
       
        return (ObjectArrayList) tiersHash2.get(key);
    }

    public void unionOrAdd(ITier tier)
    {
        ITier targetTier = findTierFor(tier);
       
        if (targetTier == null)
        {
            ensurePermutationContains(tier);
            addTier(tier);
           
            addTiersHash1(tier, tier.getAName());
            addTiersHash1(tier, tier.getBName());
            addTiersHash1(tier, tier.getCName());
           
            addTiersHash2(tier, tier.getAName(), tier.getBName());
            addTiersHash2(tier, tier.getAName(), tier.getCName());
            addTiersHash2(tier, tier.getBName(), tier.getCName());
        }
        else
        {
            tier.transposeTo(targetTier);
            targetTier.union(tier);
        }
    }

    private void addTiersHash1(ITier tier, int varName)
    {
        int key = varName;
       
        //  List of ITier
        ObjectArrayList tiers = (ObjectArrayList) tiersHash1.get(key);
       
        if (tiers == null)
        {
            tiersHash1.put(key, new ObjectArrayList(new ITier[] {tier}));
        }
        else
        {
            tiers.add(tier);
        }
    }
   
    private void addTiersHash2(ITier tier, int varName1, int varName2)
    {
        long key = varName1 < varName2 ? (long)varName1 << 21 | varName2 : (long)varName2 << 21 | varName1;
       
        ObjectArrayList tiers = (ObjectArrayList) tiersHash2.get(key);
       
        if (tiers == null)
        {
            tiersHash2.put(key, new ObjectArrayList(new ITier[] {tier}));
        }
        else
        {
            tiers.add(tier);
        }
    }
   
    void addTier(ITier tier)
    {
        tiers.add(tier);
        tiersHash3.put(tier.canonicalHashCode(), tier);
    }

    private ITier findOrCreateTargetTierFor(ITripletPermutation triplet) {
        ITier targetTier = findTierFor(triplet);

        if (targetTier == null)
        {
            ITripletPermutation tierPermutation = createTierFor(triplet);
           
            targetTier = new SimpleTier(tierPermutation.getAName(),
                                        tierPermutation.getBName(),
                                        tierPermutation.getCName());
           
            addTier(targetTier);
        }
       
        return targetTier;
    }

    private ITripletPermutation createTierFor(ITripletPermutation variables) {
        ITripletPermutation tierPermutation;
       
        ensurePermutationContains(variables);

        int aIndex = permutation.indexOf(variables.getAName());
        int bIndex = permutation.indexOf(variables.getBName());
        int cIndex = permutation.indexOf(variables.getCName());

        tierPermutation = orderIs(aIndex, bIndex, cIndex) ? new SimpleTripletPermutation(variables.getAName(), variables.getBName(), variables.getCName()) :
                          orderIs(bIndex, aIndex, cIndex) ? new SimpleTripletPermutation(variables.getBName(), variables.getAName(), variables.getCName()) :
                          orderIs(bIndex, cIndex, aIndex) ? new SimpleTripletPermutation(variables.getBName(), variables.getCName(), variables.getAName()) :
                          orderIs(cIndex, bIndex, aIndex) ? new SimpleTripletPermutation(variables.getCName(), variables.getBName(), variables.getAName()) :
                          orderIs(aIndex, cIndex, bIndex) ? new SimpleTripletPermutation(variables.getAName(), variables.getCName(), variables.getBName()) :
                                                            new SimpleTripletPermutation(variables.getCName(), variables.getAName(), variables.getBName());
        return tierPermutation;
    }

    private void ensurePermutationContains(ITripletPermutation variables)
    {
        if (!permutation.contains(variables.getAName())) { permutation.add(variables.getAName()); }
        if (!permutation.contains(variables.getBName())) { permutation.add(variables.getBName()); }
        if (!permutation.contains(variables.getCName())) { permutation.add(variables.getCName()); }
    }

    public ITier findTierFor(ITripletPermutation tripletPermutation) {
        long key = tripletPermutation.canonicalHashCode();
        //    O(1)
        ITier targetTier = (ITier) tiersHash3.get(key);
       
        return targetTier;
    }

    private static boolean orderIs(int aIndex, int bIndex, int cIndex)
    {
        return (aIndex < bIndex && bIndex < cIndex);
    }

    public IPermutation getPermutation()
    {
        return permutation;
    }

    /**
     * {@inheritDoc}
     *
     * <p><b>IMPORTANT!</b> If formula doesn't not meet the above conditions, the
     * result will be incorrect. In this case if {@link Helper#EnableAssertions}
     * set to <code>true</code> an exception will be thrown.</p>
     */
    public CleanupStatus cleanup(int from, int to)
    {
        if (tiers.size() == 1)
        {
            return CleanupStatus.NOTHING_REMOVED;
        }

        if (tiers.size() != getVarCount() - 2)
        {
            clear();
            return CleanupStatus.ALL_REMOVED;
        }

        if ((from > to) || (from < 0) || (to > tiers.size() - 1))
        {
            throw new IllegalArgumentException("(from > to) || (from < 0) || (to > tiers.size() - 1), from: " + from + ", to: " + to);
        }
       
        if (Helper.EnableAssertions)
        {
            assertTiersSorted();
        }
       
        int numberOfClausesRemoved = 0;
       
        int index;

        index = from - 1;
        while (index >= 0)
        {
            ITier tier = (ITier) tiers.get(index);
            ITier bottom = (ITier) tiers.get(index + 1);
            int size = tier.size();
            tier.adjoinRight(bottom);
            int removed = size - tier.size();
            numberOfClausesRemoved += removed;
            if (removed == 0)
            {
                //  Nothing removed
                break;
            }
            else
            {
                if (tier.isEmpty())
                {
                    clear();
                    return CleanupStatus.ALL_REMOVED;
                }
            }
            index--;
        }
       
        int actualFrom = index + 1;
       
        index = to + 1;
        while (index < tiers.size())
        {
            ITier top = (ITier) tiers.get(index - 1);
            ITier tier = (ITier) tiers.get(index);
            int size = tier.size();
            tier.adjoinLeft(top);
            int removed = size - tier.size();
            numberOfClausesRemoved += removed;
            if (removed == 0)
            {
                //  Nothing removed
                break;
            }
            else
            {
                if (tier.isEmpty())
                {
                    clear();
                    return CleanupStatus.ALL_REMOVED;
                }
            }
            index++;
        }
       
        int actualTo = index - 1;
       
        if (Helper.EnableAssertions)
        {
            SimpleFormula clone = this.clone();
            clone.cleanup();
            if (this.getClausesCount() != clone.getClausesCount())
            {
                throw new AssertionError("Error in cleanup(from,to) implementation");
            }
        }
       
        return new CleanupStatus(numberOfClausesRemoved > 0, actualFrom, actualTo, numberOfClausesRemoved);
    }
   
    public boolean cleanup()
    {
        if (tiers.size() == 1)
        {
            return false;
        }

        if (tiers.size() != getVarCount() - 2)
        {
            clear();
            return true;
        }

        if (Helper.EnableAssertions)
        {
            assertTiersSorted();
        }

        return internalCleanup();
    }

    private void assertTiersSorted()
    {
        if (!tiersSorted())
        {
            throw new IllegalStateException("Tiers should be sorted");
        }
    }

    private boolean internalCleanup()
    {       
        boolean someClausesRemoved = false;

        int tiersSize = tiers.size();
        int tiersSizeMinusOne = tiersSize - 1;
       
        Object[] tiersElements = tiers.elements();
       
        for (int i = 0; i < tiersSize; i++)
        {
            ITier tier = (ITier) tiersElements[i];
            int size = tier.size();
            if (i < tiersSizeMinusOne)
            {
                ITier nextTier = (ITier) tiersElements[i + 1];
                tier.adjoinRight(nextTier);
            }
            if (i > 0)
            {
                ITier prevTier = (ITier) tiersElements[i - 1];
                tier.adjoinLeft(prevTier);
            }
            if (tier.isEmpty())
            {
                clear();
                return true;
            }
            if (size != tier.size())
            {
                someClausesRemoved = true;
            }
        }
       
        if (someClausesRemoved)
        {
            internalCleanup();
        }
       
        return someClausesRemoved;
    }

    public void union(ICompactTripletsStructure cts)
    {
        SimpleFormula other = (SimpleFormula) cts;

        if (Helper.EnableAssertions)
        {
            assertSamePermutation(other);
        }
       
        if (other.isEmpty())
        {
            //  Union with empty structure will not change the structure
            return;
        }
       
        if (isEmpty())
        {
            ObjectArrayList otherTiers = cts.getTiers();
            for (int i = 0; i < otherTiers.size(); i++)
            {
                ITier otherTier = (ITier) otherTiers.get(i);
                ITier clone = otherTier.clone();
//                ((SimpleTier) clone).setFormula(this);
                tiers.add(clone);
            }
        }
        else
        {
            //  Both left and right operands are not empty
            for (int i = 0; i < tiers.size(); i++)
            {
                ITier tier = (ITier) tiers.get(i);
               
                ITier otherTier = (ITier) other.tiers.get(i);
               
                tier.union(otherTier);
            }
        }

        //  No need in running clearing procedure
    }

    private void assertSamePermutation(SimpleFormula operand)
    {
        if (!permutation.sameAs(operand.permutation))
        {
            throw new IllegalArgumentException("Operand permutation should be the same as the formula permutation");
        }
    }

    public void intersect(ICompactTripletsStructure cts)
    {
        SimpleFormula other = (SimpleFormula) cts;
       
        if (Helper.EnableAssertions)
        {
            assertSamePermutation(other);
        }
       
        if (cts.isEmpty() || isEmpty())
        {
            //  Intersection with empty structure will result in empty structure
            clear();
            return;
        }
       
        //  XXX Test when implementation with partial cleanups be better
        //  than the full single cleanup. The value 100 in condition was taken
        //  based just on few runs.
       
        if (permutation.size() > 100)
        {
            for (int i = 0; i < tiers.size(); i++)
            {
                SimpleTier tier = (SimpleTier) tiers.get(i);
               
                SimpleTier otherTier = (SimpleTier) other.tiers.get(i);
               
                if (tier.keys_73516240 != otherTier.keys_73516240)
                {
                    tier.intersect(otherTier);
                   
                    //  Partial cleanup each time triplets get removed from tier
                    cleanup(i, i);
                   
                    if (isEmpty())
                    {
                        break;
                    }
                }
            }
        }
        else
        {
            for (int i = 0; i < tiers.size(); i++)
            {
                ITier tier = (SimpleTier) tiers.get(i);
               
                ITier otherTier = (SimpleTier) other.tiers.get(i);
               
                tier.intersect(otherTier);
            }
           
            //  Full single cleanup after all tiers been intersected
            cleanup();
        }
    }

    public CleanupStatus concretize(int varName, Value value)
    {
        return internalConcretize(varName, value);
    }
   
    public boolean concretize(ITripletPermutation tripletPermutation, ITripletValue tripletValue)
    {
        boolean someClausesRemoved = internalConcretize(tripletPermutation.getAName(), tripletValue.isNotA() ? Value.AllNegative : Value.AllPlain).someClausesRemoved
                                   | internalConcretize(tripletPermutation.getBName(), tripletValue.isNotB() ? Value.AllNegative : Value.AllPlain).someClausesRemoved
                                   | internalConcretize(tripletPermutation.getCName(), tripletValue.isNotC() ? Value.AllNegative : Value.AllPlain).someClausesRemoved;
       
        return someClausesRemoved;
    }
   
    private CleanupStatus internalConcretize(int varName, Value value)
    {
        if (isEmpty())
        {
            return CleanupStatus.NOTHING_REMOVED;
        }
       
        int indexOf = permutation.indexOf(varName);

        if (Helper.EnableAssertions)
        {
            if (value != Value.AllPlain && value != Value.AllNegative)
            {
                throw new IllegalArgumentException(
                        "Value should be one of (" + Value.AllPlain + ", " + Value.AllNegative
                        + ") but was " + value);
            }
           
            if (indexOf < 0)
            {
                throw new IllegalArgumentException("Can't concretize on varName="
                        + varName + " because varName is not from the formula's permutation");
            }
        }
       
        //  Find tiers containing varName (there are maximum 3 of them),
        //  and concretize only them

        boolean someClausesRemoved = false;
       
        int from = indexOf;
        int to = indexOf;
       
        for (int i = 0, tierIndex = indexOf; i < 3 && tierIndex >= 0; i++, tierIndex--)
        {
            if (tierIndex < tiers.size())
            {
                from = tierIndex;
               
                ITier tier = (ITier) tiers.get(tierIndex);
                if (!someClausesRemoved)
                {
                    int size = tier.size();
                    tier.concretize(varName, value);
                    if (size != tier.size())
                    {
                        someClausesRemoved = true;
                    }
                }
                else
                {
                    tier.concretize(varName, value);
                }
                if (tier.isEmpty())
                {
                    clear();
                    return CleanupStatus.ALL_REMOVED;
                }
            }
        }
       
        if (someClausesRemoved)
        {
            if (to > tiers.size() - 1)
            {
                to = tiers.size() - 1;
            }
            return cleanup(from, to);
        }
       
        return CleanupStatus.NOTHING_REMOVED;
    }

    public boolean isEmpty()
    {
        return tiers.size() == 0;
    }
   
    public String toString()
    {
        return Helper.buildPrettyOutput(this).insert(0, '\n').toString();
    }

    public Value valueOf(int varName)
    {
       
        int indexOf = permutation.indexOf(varName);
       
        if (Helper.EnableAssertions)
        {
            if (indexOf < 0)
            {
                throw new IllegalArgumentException("Can't get value of varName="
                        + varName + " because varName is not from the formula's permutation");
            }
        }
       
        Value value = Value.Mixed;
       
        for (int i = 0, tierIndex = indexOf; i < 3 && tierIndex >= 0; i++, tierIndex--)
        {
            if (tierIndex < tiers.size())
            {
                if (i == 0)
                {
                    value = ((ITier) tiers.get(tierIndex)).valueOfA();
                    if (value == Value.Mixed)
                    {
                        break;
                    }
                }
                else if (i == 1)
                {
                    Value value2 = ((ITier) tiers.get(tierIndex)).valueOfB();
                    if (value2 != value)
                    {
                        value = Value.Mixed;
                        break;
                    }
                }
                else
                {
                    Value value3 = ((ITier) tiers.get(tierIndex)).valueOfC();
                    if (value3 != value)
                    {
                        value = Value.Mixed;
                        break;
                    }
                }
            }
        }
       
        return value;
    }
   
    public ICompactTripletsStructure getCTS()
    {
        return this;
    }
   
    public ITier getTier(int tierIndex)
    {
        return (ITier) tiers.get(tierIndex);
    }
   
    public boolean evaluate(Properties properties)
    {
        boolean result = true;
        for (int j = 0; j < getTiers().size(); j++)
        {
            for (ITripletValue tiplet : getTier(j))
            {
                ITripletPermutation permutation = getTier(j);
               
                boolean aValue = parseBoolean(String.valueOf(properties.get("_" + permutation.getAName())));
                boolean bValue = parseBoolean(String.valueOf(properties.get("_" + permutation.getBName())));
                boolean cValue = parseBoolean(String.valueOf(properties.get("_" + permutation.getCName())));

                if (tiplet.isNotA()) aValue = !aValue;
                if (tiplet.isNotB()) bValue = !bValue;
                if (tiplet.isNotC()) cValue = !cValue;

                result = result && (aValue || bValue || cValue);
               
                if (!result)
                {
                    return result;
                }
            }
        }
        return result;
    }
   
    public boolean evaluate(ObjectArrayList route)
    {
        boolean result = true;
        for (int j = 0; j < getTiers().size(); j++)
        {
            for (ITripletValue tiplet : getTier(j))
            {
                ITripletPermutation permutation = getTier(j);
               
                boolean aValue = getValueFromRoute(route, permutation.getAName());
                boolean bValue = getValueFromRoute(route, permutation.getBName());
                boolean cValue = getValueFromRoute(route, permutation.getCName());

                if (tiplet.isNotA()) aValue = !aValue;
                if (tiplet.isNotB()) bValue = !bValue;
                if (tiplet.isNotC()) cValue = !cValue;

                result = result && (aValue || bValue || cValue);
               
                if (!result)
                {
                    return result;
                }
            }
        }
        return result;
    }

    private boolean getValueFromRoute(ObjectArrayList route, int varName)
    {
        for (int i = 0; i < route.size(); i++)
        {
            IVertex vertex = (IVertex) route.get(i);
            if (vertex.getPermutation().hasVariable(varName))
            {
                if (varName == vertex.getPermutation().getAName())
                {
                    return vertex.getTripletValue().isNotA();
                }
                if (varName == vertex.getPermutation().getBName())
                {
                    return vertex.getTripletValue().isNotB();
                }
                if (varName == vertex.getPermutation().getCName())
                {
                    return vertex.getTripletValue().isNotC();
                }
            }
        }
        throw new IllegalArgumentException("Variable " + varName + " was not found in route");
    }
   
    public boolean equals(Object obj)
    {
        if (!(obj instanceof SimpleFormula))
        {
            return false;
        }
        SimpleFormula other = (SimpleFormula) obj;
        if (!this.permutation.sameAs(other.permutation))
        {
            //  Permutations differs
            return false;
        }
        for (int j = 0; j < tiers.size(); j++)
        {
            ITier tier = (ITier) tiers.get(j);
            ITier otherTier = (ITier) other.tiers.get(j);
            if (!tier.equals(otherTier))
            {
                //  Tiers differs
                return false;
            }
        }
        return true;
    }
   
    public boolean containsAllValuesOf(ITier anotherTier)
    {
        for (int i = 0; i < getTiers().size(); i++)
        {
            ITier tier = getTier(i);
            if (tier.hasSameVariablesAs(anotherTier))
            {
                int[] abc = new int[3];
                System.arraycopy(tier.getABC(), 0, abc, 0, 3);
                try
                {
                    tier.transposeTo(anotherTier);
                    if (tier.equals(anotherTier))
                    {
                        return true;
                    }
                }
                finally
                {
                    tier.transposeTo(abc);
                }
            }
        }
        return false;
    }
   
    public boolean isElementary()
    {
        if (Helper.EnableAssertions)
        {
            assertTiersSorted();
        }
        if (tiers.size() != permutation.size() - 2)
        {
            //  Not all tiers present in CTS
            return false;
        }
        for (int j = 0; j < tiers.size(); j++)
        {
            ITier tier = (ITier) tiers.get(j);
            if (tier.size() != 1)
            {
                return false;
            }
        }
        return true;
    }

    public void clearTierHash3()
    {
        if (tiersHash3 != null) tiersHash3.clear();
    }

    public void setVarMappings(OpenIntIntHashMap internalToOriginalMap)
    {
        this.internalToOriginalMap = internalToOriginalMap;
    }
   
    public int getOriginalVarName(int varName)
    {
        int originalVarName = internalToOriginalMap.get(varName);
        if (originalVarName == 0)
        {
            throw new IllegalArgumentException("Original variable not found for varName=" + varName);
        }
        return originalVarName;
    }
}
TOP

Related Classes of com.anjlab.sat3.SimpleFormula

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.