001package conexp.fx.core.algorithm.nextclosures.mn;
002
003/*
004 * #%L
005 * Concept Explorer FX
006 * %%
007 * Copyright (C) 2010 - 2019 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.HashSet;
026import java.util.Set;
027
028import com.google.common.collect.Sets;
029
030import conexp.fx.core.context.MatrixContext;
031
032public class NextClosuresMN<G, M> {
033
034  public static final <G, M> ResultMN<G, M> compute(
035      final MatrixContext<G, M> cxt,
036      final Set<M> premises,
037      final Set<M> conclusions) {
038    final MatrixContextMN<G, M> cxtMN = new MatrixContextMN<G, M>(cxt, premises, conclusions);
039    final ResultMN<G, M> result = new ResultMN<G, M>();
040    final Set<Set<M>> candidates = new HashSet<Set<M>>();
041    final Set<Set<M>> candidates2 = new HashSet<Set<M>>();
042    final Set<M> p = new HashSet<M>();
043    candidates.add(p);
044    final Set<M> c = new HashSet<M>(cxtMN.closureMN(p));
045    if (!c.isEmpty()) // i.e. p->c does not follow from the empty set of implications
046      result.implications.put(
047          p,
048          c);
049    for (int i = 1; i < premises.size(); i++) {
050      System.out.println("size " + i);
051      candidates2.clear();
052      for (Set<M> s : candidates) {
053        for (M m : Sets.difference(
054            premises,
055            s)) {
056          Set<M> t = new HashSet<M>(s);
057          t.add(m);
058          candidates2.add(t);
059        }
060      }
061      for (Set<M> s : candidates2) {
062        if (s.size() != i)
063          throw new RuntimeException();
064        final Set<M> closureMN = cxtMN.closureMN(s);
065        final Set<M> closureL = result.closure(s);
066        if (!closureL.containsAll(closureMN)) // i.e. s is M-N-pseudo-closed
067          result.implications.put(
068              s,
069              closureMN);
070      }
071      candidates.clear();
072      candidates.addAll(candidates2);
073    }
074    return result;
075  }
076}