001package conexp.fx.core.math;
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.Arrays;
026import java.util.Iterator;
027import java.util.function.Function;
028
029//import conexp.fx.core.dl.ELConceptDescription;
030//import conexp.fx.core.dl.ELInterpretation2;
031//import conexp.fx.core.dl.ELTBox;
032
033@FunctionalInterface
034public interface DualClosureOperator<T extends LatticeElement<T>> extends Function<T, T> {
035
036  @Override
037  public default T apply(final T element) {
038    return closure(element);
039  }
040
041  public T closure(T element);
042
043  public default boolean close(final T element) {
044    return !element.inf(closure(element));
045  }
046
047  public default boolean isClosed(final T element) {
048    return element.equivalent(closure(element));
049  }
050
051  @SafeVarargs
052  public static <T extends LatticeElement<T>> DualClosureOperator<T>
053      infimum(final DualClosureOperator<T>... closureOperators) {
054    return infimum(Arrays.asList(closureOperators));
055  }
056
057  public static <T extends LatticeElement<T>> DualClosureOperator<T>
058      infimum(final Iterable<DualClosureOperator<T>> closureOperators) {
059    return element -> {
060      final Iterator<DualClosureOperator<T>> it = closureOperators.iterator();
061      if (!it.hasNext())
062        return element.smallest();
063      else {
064        final T closure = it.next().closure(element);
065        while (it.hasNext())
066          closure.sup(it.next().closure(element));
067        return closure;
068      }
069    };
070  }
071
072  @SafeVarargs
073  public static <T extends LatticeElement<T>> DualClosureOperator<T>
074      supremum(final DualClosureOperator<T>... closureOperators) {
075    return supremum(Arrays.asList(closureOperators));
076  }
077
078  public static <T extends LatticeElement<T>> DualClosureOperator<T>
079      supremum(final Iterable<DualClosureOperator<T>> closureOperators) {
080    return element -> {
081      final Iterator<DualClosureOperator<T>> it = closureOperators.iterator();
082      if (!it.hasNext())
083        return element;
084      else {
085        final T closure = closureOperators.iterator().next().closure(element);
086        boolean changed = true;
087        while (changed) {
088          changed = false;
089          for (DualClosureOperator<T> clop : closureOperators)
090            changed |= closure.inf(clop.closure(closure));
091        }
092        return closure;
093      }
094    };
095  }
096
097}