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}