001package org.biopax.paxtools.pattern.constraint;
002
003import org.apache.commons.collections15.SetUtils;
004import org.biopax.paxtools.model.BioPAXElement;
005import org.biopax.paxtools.pattern.MappedConst;
006import org.biopax.paxtools.pattern.Match;
007
008import java.util.Collection;
009import java.util.HashSet;
010import java.util.Set;
011
012/**
013 * Used for getting logical XOR of a set of constraints.
014 *
015 * @author Ozgun Babur
016 */
017public class XOR extends OR
018{
019        /**
020         * Constructor with the mapped constraints.
021         * @param con mapped constraints
022         */
023        public XOR(MappedConst... con)
024        {
025                super(con);
026        }
027
028        /**
029         * Checks if constraints satisfy in xor pattern.
030         * @param match match to validate
031         * @param ind mapped indices
032         * @return true if all satisfy
033         */
034        @Override
035        public boolean satisfies(Match match, int... ind)
036        {
037                int x = -1;
038                for (MappedConst mc : con)
039                {
040                        if (mc.satisfies(match, ind)) x *= -1;
041                }
042                return x == 1;
043        }
044
045        /**
046         * Gets xor of the generated elements by the member constraints.
047         * @param match match to process
048         * @param ind mapped indices
049         * @return satisfying elements
050         */
051        @Override
052        public Collection<BioPAXElement> generate(Match match, int... ind)
053        {
054                Collection<BioPAXElement> gen = new HashSet<BioPAXElement> (
055                        con[0].generate(match, ind));
056
057                for (int i = 1; i < con.length; i++)
058                {
059                        if (gen.isEmpty()) break;
060
061                        Collection<BioPAXElement> subset = con[i].generate(match, ind);
062                        Set<BioPAXElement> copy = new HashSet<BioPAXElement>(subset);
063
064                        copy.removeAll(gen);
065                        gen.removeAll(subset);
066                        gen.addAll(copy);
067                }
068                return gen;
069        }
070}