001package org.biopax.paxtools.pattern.constraint;
002
003import org.biopax.paxtools.pattern.MappedConst;
004import org.biopax.paxtools.pattern.Match;
005import org.biopax.paxtools.model.BioPAXElement;
006
007import java.util.Collection;
008import java.util.HashSet;
009
010/**
011 * Logical OR of several constraints. Each constraint should have the same variable size and should
012 * be able to process same variables at the same order. Constraints should be all generative or all
013 * non-generative, and they cannot mix.
014 *
015 * @author Ozgun Babur
016 */
017public class OR extends ConstraintAdapter
018{
019        /**
020         * Wrapped constraints.
021         */
022        MappedConst[] con;
023
024        /**
025         * Constructor with the array of mapped constraints.
026         * @param con wrapped constraints
027         */
028        public OR(MappedConst... con)
029        {
030                this.con = con;
031        }
032
033        /**
034         * Checks if any of the wrapped constraints satisfy.
035         * @param match current pattern match
036         * @param ind mapped indices
037         * @return true if any of the wrapped constraints satisfy
038         */
039        @Override
040        public boolean satisfies(Match match, int... ind)
041        {
042                for (MappedConst mc : con)
043                {
044                        if (mc.satisfies(match, ind)) return true;
045                }
046                return false;
047        }
048
049        /**
050         * Can generate only if all of the wrapped constraints are generative.
051         * @return true if none of the wrapped constraints are non-generative
052         */
053        @Override
054        public boolean canGenerate()
055        {
056                for (MappedConst mc : con)
057                {
058                        if (!mc.canGenerate()) return false;
059                }
060                return true;
061        }
062
063        /**
064         * Checks the inner mapping of the wrapped constraints and figures the size.
065         * @return the size
066         */
067        @Override
068        public int getVariableSize()
069        {
070                int size = 0;
071                for (MappedConst mc : con)
072                {
073                        int m = max(mc.getInds());
074                        if (m > size) size = m;
075                }
076                return size + 1;
077        }
078
079        /**
080         * Gets the max value.
081         * @param v array to check
082         * @return max value
083         */
084        protected int max(int[] v)
085        {
086                int x = 0;
087                for (int i : v)
088                {
089                        if (i > x) x = i;
090                }
091                return x;
092        }
093
094        /**
095         * Gets the intersection of the generated values of wrapped constraints.
096         * @param match current pattern match
097         * @param ind mapped indices
098         * @return intersection of the generated values of wrapped constraints
099         */
100        @Override
101        public Collection<BioPAXElement> generate(Match match, int... ind)
102        {
103                Collection<BioPAXElement> gen = new HashSet<BioPAXElement>();
104
105                for (MappedConst mc : con)
106                {
107                        gen.addAll(mc.generate(match, ind));
108                }
109                return gen;
110        }
111}