001package conexp.fx.core.context;
002
003/*
004 * #%L
005 * Concept Explorer FX
006 * %%
007 * Copyright (C) 2010 - 2023 Francesco Kriegel
008 * %%
009 * This program is free software: you can redistribute it and/or modify
010 * it under the terms of the GNU General Public License as
011 * published by the Free Software Foundation, either version 3 of the
012 * License, or (at your option) any later version.
013 * 
014 * This program is distributed in the hope that it will be useful,
015 * but WITHOUT ANY WARRANTY; without even the implied warranty of
016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
017 * GNU General Public License for more details.
018 * 
019 * You should have received a copy of the GNU General Public
020 * License along with this program.  If not, see
021 * <http://www.gnu.org/licenses/gpl-3.0.html>.
022 * #L%
023 */
024
025import java.util.Collection;
026import java.util.Set;
027import java.util.function.BiPredicate;
028
029import conexp.fx.core.collections.relation.AbstractRelation;
030import conexp.fx.core.collections.relation.Relation;
031import conexp.fx.core.collections.setlist.SetList;
032
033public abstract class AbstractContext<G, M> extends AbstractRelation<G, M> implements Context<G, M> {
034
035  public static <G, M> AbstractContext<G, M>
036      fromPredicate(final SetList<G> objects, final SetList<M> attributes, final BiPredicate<G, M> predicate) {
037    return new AbstractContext<G, M>(objects, attributes, false) {
038
039      @Override
040      public final boolean contains(final Object o1, final Object o2) {
041        try {
042          return predicate.test((G) o1, (M) o2);
043        } catch (ClassCastException e) {
044          return false;
045        }
046      }
047
048    };
049  }
050
051  public static <G> AbstractContext<G, G> fromPredicate(final SetList<G> objects, final BiPredicate<G, G> predicate) {
052    return new AbstractContext<G, G>(objects, objects, true) {
053
054      @Override
055      public final boolean contains(final Object o1, final Object o2) {
056        try {
057          return predicate.test((G) o1, (G) o2);
058        } catch (ClassCastException e) {
059          return false;
060        }
061      }
062
063    };
064  }
065
066  protected AbstractContext(final SetList<G> objects, final SetList<M> attributes, final boolean homogen) {
067    super(objects, attributes, homogen);
068  }
069
070  public Set<G> extent(final Collection<?> objects) {
071    return colAnd(rowAnd(objects));
072  }
073
074  public Set<M> intent(final Collection<?> attributes) {
075    return rowAnd(colAnd(attributes));
076  }
077
078  public Set<G> extent(final Object... objects) {
079    if (objects.length == 1)
080      return colAnd(row(objects[0]));
081    return colAnd(rowAnd(objects));
082  }
083
084  public Set<M> intent(final Object... attributes) {
085    if (attributes.length == 1)
086      return rowAnd(col(attributes[0]));
087    return rowAnd(colAnd(attributes));
088  }
089
090  public final Relation<G, G> objectQuasiOrder() {
091    return new AbstractRelation<G, G>(rowHeads(), rowHeads(), true) {
092
093      public final boolean contains(Object object1, Object object2) {
094        return AbstractContext.this.row(object1).containsAll(AbstractContext.this.row(object2));
095      }
096    };
097  }
098
099  public final Relation<M, M> attributeQuasiOrder() {
100    return new AbstractRelation<M, M>(colHeads(), colHeads(), true) {
101
102      public final boolean contains(Object attribute1, Object attribute2) {
103        return AbstractContext.this.col(attribute1).containsAll(AbstractContext.this.col(attribute2));
104      }
105    };
106  }
107
108  public MatrixContext<G, M> clone() {
109    final MatrixContext<G, M> clone = new MatrixContext<G, M>(rowHeads().clone(), colHeads().clone(), false);
110    clone.rowHeads().parallelStream().forEach(object -> clone.row(object).addAll(row(object)));
111//    for (G object : clone.rowHeads())
112//      for (M attribute : clone.colHeads())
113//        if (contains(object, attribute))
114//          clone.addFast(object, attribute);
115    return clone;
116  }
117
118  @Override
119  public final AbstractContext<G, M> getSelection() {
120    return this;
121  }
122
123}