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.HashMap;
026import java.util.HashSet;
027import java.util.Map;
028import java.util.Set;
029
030import com.google.common.collect.Sets;
031
032import conexp.fx.core.context.MatrixContext;
033
034public class NextClosuresMN2<G, M> {
035
036  public static final <G, M> ResultMN<G, M> compute(
037      final MatrixContext<G, M> cxt,
038      final Set<M> premises,
039      final Set<M> conclusions) {
040    final MatrixContextMN<G, M> cxtMN = new MatrixContextMN<G, M>(cxt, premises, conclusions);
041    final ResultMN<G, M> result = new ResultMN<G, M>();
042    final Map<Integer, Set<Set<M>>> candidates = new HashMap<Integer, Set<Set<M>>>();
043    for (int i = 0; i <= premises.size(); i++)
044      candidates.put(
045          i,
046          new HashSet<Set<M>>());
047    final Set<M> p = new HashSet<M>();
048    candidates.get(
049        0).add(
050        p);
051    final Set<M> c = new HashSet<M>(cxtMN.closureMN(p));
052    if (!c.isEmpty()) // i.e. p->c does not follow from the empty set of implications
053      result.implications.put(
054          p,
055          c);
056    final Set<M> pmm = cxtMN.intentM(p);
057    for (M m : Sets.difference(
058        premises,
059        pmm)) {
060      Set<M> nextCandidate = new HashSet<M>(pmm);
061      nextCandidate.add(m);
062      candidates.get(
063          pmm.size() + 1).add(
064          nextCandidate);
065    }
066    for (int i = 1; i < premises.size(); i++) {
067//      System.out.println("size " + i);
068      for (Set<M> s : candidates.get(i)) {
069//        System.out.println(s);
070        if (s.size() != i)
071          throw new RuntimeException();
072        final Set<M> closureMN = cxtMN.closureMN(s);
073        final Set<M> closureL = result.closure(s);
074        if (!closureL.containsAll(closureMN)) { // i.e. s is M-N-pseudo-closed
075          result.implications.put(
076              s,
077              closureMN);
078        } else {
079//          for (M m : Sets.difference(premises, s)) {
080//            Set<M> nextCandidate = new HashSet<M>(s);
081//            nextCandidate.add(m);
082//            candidates.get(s.size() + 1).add(nextCandidate);
083//          }
084        }
085        final Set<M> smm = cxtMN.intentM(s);
086        for (M m : Sets.difference(
087            premises,
088            smm)) {
089          Set<M> nextCandidate = new HashSet<M>(smm);
090          nextCandidate.add(m);
091          candidates.get(
092              smm.size() + 1).add(
093              nextCandidate);
094        }
095      }
096    }
097    return result;
098  }
099}