001package conexp.fx.core.builder;
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.io.File;
026import java.util.Arrays;
027import java.util.Collections;
028import java.util.List;
029
030import org.openrdf.repository.Repository;
031import org.ujmp.core.booleanmatrix.BooleanMatrix;
032
033import conexp.fx.core.collections.Pair;
034import conexp.fx.core.collections.setlist.SetList;
035import conexp.fx.core.collections.setlist.SetLists;
036import conexp.fx.core.context.MatrixContext;
037import conexp.fx.core.importer.CEXImporter;
038import conexp.fx.core.importer.CFXImporter;
039import conexp.fx.core.importer.CSVImporter;
040import conexp.fx.core.importer.CXTImporter;
041import conexp.fx.core.importer.RDFImporter;
042import conexp.fx.core.math.BooleanMatrices;
043
044public final class Requests {
045
046  public static enum Metatype {
047    NEW("New Context", ""),
048    IMPORT("Import Context", ""),
049    SCALE("Scale Context", ""),
050    CONSTRUCT("Construction Context", "");//,
051//    DL_CONTEXT("DL Context", "");
052
053//    OTHER("Other Context", "");
054    public final String title;
055    public final String description;
056
057    private Metatype(final String title, final String description) {
058      this.title = title;
059      this.description = description;
060    }
061  }
062
063  public static enum Type {
064//    INDUCED_CONTEXT(
065//        "Induced Context",
066//        "An induced context from a DL interpretation.",
067//        Metatype.DL_CONTEXT,
068//        false,
069//        Source.NULL),
070    NEW_CONTEXT(
071        "New Context",
072        "Creates a new empty Formal Context of desired size.",
073        Metatype.NEW,
074        false,
075        Source.INT_INT),
076    NEW_ORDER(
077        "New Order (experimental)",
078        "Creates a new empty Order Context of desired size.",
079        Metatype.NEW,
080        true,
081        Source.INT),
082    IMPORT_CXT_CONTEXT(
083        "Local File (Burmeister Format, *.cxt)",
084        "Imports a Formal Context from a *.cxt File.",
085        Metatype.IMPORT,
086        false,
087        Source.FILE),
088    IMPORT_CEX_CONTEXT(
089        "Local File (Concept Explorer Format, *.cex)",
090        "Imports a Formal Context from a *.cex File.",
091        Metatype.IMPORT,
092        false,
093        Source.FILE),
094    IMPORT_CFX_CONTEXT(
095        "Local File (Concept Explorer FX Format, *.cfx)",
096        "Imports a Formal Context from a *.cfx File.",
097        Metatype.IMPORT,
098        false,
099        Source.FILE),
100    IMPORT_CSV_CONTEXT(
101        "Local File (Comma Separated Values, *.csv)",
102        "Imports a Formal Context from a *.csv File.",
103        Metatype.IMPORT,
104        false,
105        Source.FILE),
106    IMPORT_SPARQL_CONTEXT(
107        "SPARQL Result from an Ontology",
108        "Imports a Formal Context from an Ontology.",
109        Metatype.IMPORT,
110        false,
111        Source.SPARQL_AND_XMLURL,
112        Source.SPARQL_AND_ONTOLOGYFILE,
113        Source.SPARQL_AND_ONTOLOGYURL,
114        Source.SPARQL_AND_ONTOLOGYREPOSITORY),
115    DICHTOMIC(
116        "Dichtomic Scale",
117        "Creates a new formal context that is the nominal scale of the two boolean values true and false",
118        Metatype.SCALE,
119        true,
120        Source.NULL),
121    BOOLEAN("Boolean Scale", "", Metatype.SCALE, true, Source.INT_LIST, Source.STRINGS),
122    NOMINAL("Nominal Scale", "", Metatype.SCALE, true, Source.INT_LIST, Source.STRINGS),
123    CONTRA_NOMINAL("Contra-Nominal Scale", "", Metatype.SCALE, true, Source.INT_LIST, Source.STRINGS),
124    ORDINAL("Ordinal Scale", "", Metatype.SCALE, true, Source.INT_LIST, Source.STRINGS),
125    CONTRA_ORDINAL("Contra-Ordinal Scale", "", Metatype.SCALE, true, Source.INT_LIST, Source.STRINGS, Source.ORDER),
126    INTER_ORDINAL("Inter-Ordinal Scale", "", Metatype.SCALE, false, Source.INT_LIST, Source.STRINGS, Source.ORDER),
127    CONVEX_ORDINAL("Convex-Ordinal Scale", "", Metatype.SCALE, false, Source.INT_LIST, Source.STRINGS, Source.ORDER),
128    BI_ORDINAL("Bi-Ordinal Scale", "", Metatype.SCALE, false, Source.ORDER_ORDER),
129    GRID("Grid Scale", "", Metatype.SCALE, false, Source.ORDER_ORDER),
130    COMPLEMENT("Complement Context", "", Metatype.CONSTRUCT, false, Source.CONTEXT),
131    DUAL("Dual Context", "", Metatype.CONSTRUCT, false, Source.CONTEXT),
132    CONTRARY("Contrary Context", "", Metatype.CONSTRUCT, false, Source.CONTEXT),
133    APPOSITION("Apposition Context", "", Metatype.CONSTRUCT, false, Source.CONTEXT_CONTEXT),
134    SUBPOSITION("Subposition Context", "", Metatype.CONSTRUCT, false, Source.CONTEXT_CONTEXT),
135    QUADPOSITION("Juxtaposition Context", "", Metatype.CONSTRUCT, false, Source.CONTEXT_CONTEXT_CONTEXT_CONTEXT),
136    HORIZONTAL_SUM("Horizontal Sum Context", "", Metatype.CONSTRUCT, false, Source.CONTEXT_CONTEXT),
137    VERTICAL_SUM("Vertical Sum Context", "", Metatype.CONSTRUCT, false, Source.CONTEXT_CONTEXT),
138    DIRECT_SUM("Direct Sum Context", "", Metatype.CONSTRUCT, false, Source.CONTEXT_CONTEXT),
139    DIRECT_PRODUCT("Direct Product Context", "", Metatype.CONSTRUCT, false, Source.CONTEXT_CONTEXT),
140    BI_PRODUCT("Bi-Product Context", "", Metatype.CONSTRUCT, false, Source.CONTEXT_CONTEXT),
141    SEMI_PRODUCT("Semi-Product Context", "", Metatype.CONSTRUCT, false, Source.CONTEXT_CONTEXT),
142    SUBSTITUTION_SUM("Substitution Sum Context", "", Metatype.CONSTRUCT, false, Source.CONTEXT_CONTEXT_OBJECT_OBJECT);
143
144//    APPROXIMATION_CONTEXT_BY_ATTRIBUTES(
145//        "Dau's Approximation Context by Attributes",
146//        "",
147//        Metatype.OTHER,
148//        false,
149//        Source.CONTEXT_DOUBLE),
150//    APPROXIMATION_CONTEXT("Meschke's Approximation Context", "", Metatype.OTHER, false, Source.CONTEXT_SET_SET),
151//    BINARY_RELATIONS_CONTEXT("Binary Relations Context", "", Metatype.OTHER, false, Source.INT_LIST);
152    public final String title;
153    public final String description;
154    public final Metatype type;
155    public final boolean homogen;
156    public final List<Source> sources;
157
158    private Type(
159        final String title,
160        final String description,
161        final Metatype type,
162        final boolean homogen,
163        final Source... sources) {
164      this.title = title;
165      this.description = description;
166      this.type = type;
167      this.homogen = homogen;
168      this.sources = Arrays.asList(sources);
169    }
170  }
171
172  public static enum Source {
173    NULL("No source needed"),
174    INT_INT("Custom Size"),
175    INT("Custom Size"),
176    INT_LIST("Create from natural numbers {0, ..., n}"),
177    STRINGS("Create from custom set list"),
178    ORDER("Create from existing order context"),
179    ORDER_ORDER("Create from two existing order contexts"),
180    CONTEXT("Create from existing formal context"),
181    CONTEXT_CONTEXT("Create from two existing formal contexts"),
182    CONTEXT_CONTEXT_CONTEXT_CONTEXT("Create from four existing formal contexts"),
183    CONTEXT_SET_SET("TODO"),
184    CONTEXT_DOUBLE("Create from existing formal context"),
185    CONTEXT_CONTEXT_OBJECT_OBJECT("Create from two existing formal contexts"),
186    FILE("Concept Explorer File Import"),
187    SPARQL_AND_XMLURL("SPARQL Import from XML Endpoint"),
188    SPARQL_AND_ONTOLOGYFILE("SPARQL Import from Ontology File"),
189    SPARQL_AND_ONTOLOGYURL("SPARQL Import from Ontology URL"),
190    SPARQL_AND_ONTOLOGYREPOSITORY("SPARQL Import from Sesame Repository");
191
192    public final String title;
193
194    private Source(final String title) {
195      this.title = title;
196    }
197  }
198
199  public final static class New {
200
201    public static final class NewContext extends StringRequest {
202
203      private final int objects;
204      private final int attributes;
205
206      public NewContext(final int objects, final int attributes) {
207        super(Type.NEW_CONTEXT, Source.INT_INT);
208        this.objects = objects;
209        this.attributes = attributes;
210      }
211
212      public final void setContent() {
213        for (int row = 0; row < objects; row++)
214          context.rowHeads().add("Object " + row);
215        for (int column = 0; column < attributes; column++)
216          context.colHeads().add("Attribute " + column);
217        context.pushAllChangedEvent();
218      }
219    }
220
221    public static final class NewOrder extends StringRequest {
222
223      private final int elements;
224
225      public NewOrder(final int elements) {
226        super(Type.NEW_ORDER, Source.INT);
227        this.elements = elements;
228      }
229
230      public final void setContent() {
231        for (int row = 0; row < elements; row++)
232          context.rowHeads().add("Element " + row);
233        context.pushAllChangedEvent();
234      }
235    }
236  }
237
238  public static final class Import {
239
240    public static final class ImportCFX extends FileRequest {
241
242      public ImportCFX(final File file) {
243        super(Type.IMPORT_CFX_CONTEXT, file);
244      }
245
246      public final void setContent() {
247        CFXImporter.importt(context, null, file);
248      }
249    }
250
251    public static final class ImportCXT extends FileRequest {
252
253      public ImportCXT(final File file) {
254        super(Type.IMPORT_CXT_CONTEXT, file);
255      }
256
257      public final void setContent() throws Exception {
258        CXTImporter.read(context, file);
259      }
260    }
261
262    public static final class ImportCSVB extends FileRequest {
263
264      public ImportCSVB(final File file) {
265        super(Type.IMPORT_CSV_CONTEXT, file);
266      }
267
268      @Override
269      public void setContent() {
270        try {
271          CSVImporter.importContext(file, context, ";");
272        } catch (Exception e) {
273          e.printStackTrace();
274        }
275      }
276    }
277
278    public static final class ImportCEX extends StringRequest {
279
280      private final File file;
281
282      public ImportCEX(final File file) {
283        super(Type.IMPORT_CEX_CONTEXT, Source.FILE);
284        this.file = file;
285      }
286
287      public final void setContent() {
288        CEXImporter.importt(context, null, file);
289      }
290    }
291
292    public static final class ImportSPARQLFromEndpoint extends StringRequest {
293
294      private final String url;
295      private final String query;
296
297      public ImportSPARQLFromEndpoint(final String url, final String query) {
298        super(Type.IMPORT_SPARQL_CONTEXT, Source.SPARQL_AND_XMLURL);
299        this.url = url;
300        this.query = query;
301      }
302
303      public final void setContent() {
304        RDFImporter.importXML(context, url, query);
305      }
306    }
307
308    public static final class ImportSPARQLFromURL extends StringRequest {
309
310      private final String url;
311      private final String query;
312
313      public ImportSPARQLFromURL(final String url, final String query) {
314        super(Type.IMPORT_SPARQL_CONTEXT, Source.SPARQL_AND_ONTOLOGYURL);
315        this.url = url;
316        this.query = query;
317      }
318
319      public final void setContent() {
320        RDFImporter.importURL(context, url, query);
321      }
322    }
323
324    public static final class ImportSPARQLFromFile extends StringRequest {
325
326      private final File   file;
327      private final String query;
328
329      public ImportSPARQLFromFile(final File file, final String query) {
330        super(Type.IMPORT_SPARQL_CONTEXT, Source.SPARQL_AND_ONTOLOGYFILE);
331        this.file = file;
332        this.query = query;
333      }
334
335      public final void setContent() {
336        RDFImporter.importFile(context, file, query);
337      }
338    }
339
340    public static final class ImportSPARQLFromRepository extends StringRequest {
341
342      private final Repository repo;
343      private final String     query;
344
345      public ImportSPARQLFromRepository(final Repository repo, final String query) {
346        super(Type.IMPORT_SPARQL_CONTEXT, Source.SPARQL_AND_ONTOLOGYREPOSITORY);
347        this.repo = repo;
348        this.query = query;
349      }
350
351      public final void setContent() {
352        RDFImporter.importRepository(context, repo, query);
353      }
354    }
355  }
356
357  public final static class Scale {
358
359    public static final class DichtomicScale extends Request<Boolean, Boolean> {
360
361      public DichtomicScale() {
362        super(Type.DICHTOMIC, Source.NULL);
363      }
364
365      public final void setContent() {
366        context.setContent(SetLists.create(true, false), null, BooleanMatrices.identity(2));
367      }
368    }
369
370    public static final class BooleanScaleFromInt extends Request<SetList<Integer>, SetList<Integer>> {
371
372      private final int n;
373
374      public BooleanScaleFromInt(final int n) {
375        super(Type.BOOLEAN, Source.INT_LIST);
376        this.n = n;
377      }
378
379      public final void setContent() {
380        context.setContent(SetLists.powerSet(SetLists.integers(n)), null, BooleanMatrices.booleann(n));
381      }
382    }
383
384    public static final class BooleanScaleFromSetList<E> extends Request<SetList<E>, SetList<E>> {
385
386      private final SetList<E> s;
387
388      public BooleanScaleFromSetList(final SetList<E> s) {
389        super(Type.BOOLEAN, Source.STRINGS);
390        this.s = s;
391      }
392
393      public final void setContent() {
394        context.setContent(SetLists.powerSet(s), null, BooleanMatrices.booleann(s.size()));
395      }
396    }
397
398    public static final class NominalScaleFromInt extends Request<Integer, Integer> {
399
400      private final int n;
401
402      public NominalScaleFromInt(final int n) {
403        super(Type.NOMINAL, Source.INT_LIST);
404        this.n = n;
405      }
406
407      public final void setContent() {
408        context.setContent(SetLists.integers(n), null, BooleanMatrices.identity(n));
409      }
410    }
411
412    public static final class NominalScaleFromSetList<E> extends Request<E, E> {
413
414      private final SetList<E> s;
415
416      public NominalScaleFromSetList(final SetList<E> s) {
417        super(Type.NOMINAL, Source.STRINGS);
418        this.s = s;
419      }
420
421      public final void setContent() {
422        context.setContent(s, null, BooleanMatrices.identity(s.size()));
423      }
424    }
425
426    public static final class ContraNominalScaleFromInt extends Request<Integer, Integer> {
427
428      private final int n;
429
430      public ContraNominalScaleFromInt(final int n) {
431        super(Type.CONTRA_NOMINAL, Source.INT_LIST);
432        this.n = n;
433      }
434
435      public final void setContent() {
436        context.setContent(SetLists.integers(n), null, BooleanMatrices.negativeIdentity(n));
437      }
438    }
439
440    public static final class ContraNominalScaleFromSetList<E> extends Request<E, E> {
441
442      private final SetList<E> s;
443
444      public ContraNominalScaleFromSetList(final SetList<E> s) {
445        super(Type.CONTRA_NOMINAL, Source.STRINGS);
446        this.s = s;
447      }
448
449      public final void setContent() {
450        context.setContent(s, null, BooleanMatrices.negativeIdentity(s.size()));
451      }
452    }
453
454    public static final class OrdinalScaleFromInt extends Request<Integer, Integer> {
455
456      private final int n;
457
458      public OrdinalScaleFromInt(final int n) {
459        super(Type.ORDINAL, Source.INT_LIST);
460        this.n = n;
461      }
462
463      public final void setContent() {
464        context.setContent(SetLists.integers(n), null, BooleanMatrices.upperDiagonal(n));
465      }
466    }
467
468    public static final class OrdinalScaleFromSetList<E> extends Request<E, E> {
469
470      private final SetList<E> s;
471
472      public OrdinalScaleFromSetList(final SetList<E> s) {
473        super(Type.ORDINAL, Source.STRINGS);
474        this.s = s;
475      }
476
477      public final void setContent() {
478        context.setContent(s, null, BooleanMatrices.upperDiagonal(s.size()));
479      }
480    }
481
482    public static final class ContraOrdinalScaleFromInt extends Request<Integer, Integer> {
483
484      private final int n;
485
486      public ContraOrdinalScaleFromInt(final int n) {
487        super(Type.CONTRA_ORDINAL, Source.INT_LIST);
488        this.n = n;
489      }
490
491      public final void setContent() {
492        context.setContent(
493            SetLists.integers(n),
494            null,
495            BooleanMatrices.complement(BooleanMatrices.dual(BooleanMatrices.upperDiagonal(n))));
496      }
497    }
498
499    public static final class ContraOrdinalScaleFromSetList<E> extends Request<E, E> {
500
501      private final SetList<E> s;
502
503      public ContraOrdinalScaleFromSetList(final SetList<E> s) {
504        super(Type.CONTRA_ORDINAL, Source.STRINGS);
505        this.s = s;
506      }
507
508      public final void setContent() {
509        context.setContent(
510            s,
511            null,
512            BooleanMatrices.complement(BooleanMatrices.dual(BooleanMatrices.upperDiagonal(s.size()))));
513      }
514    }
515
516    public static final class ContraOrdinalScaleFromOrder<E> extends Request<E, E> {
517
518      private final MatrixContext<E, E> c;
519
520      public ContraOrdinalScaleFromOrder(final MatrixContext<E, E> c) {
521        super(Type.CONTRA_ORDINAL, Source.ORDER);
522        this.c = c;
523      }
524
525      public final void setContent() {
526        context.setContent(c.rowHeads(), null, BooleanMatrices.complement(BooleanMatrices.dual(c.matrix())));
527      }
528    }
529
530    public static final class InterOrdinalScaleFromInt extends Request<Integer, Pair<Integer, Integer>> {
531
532      private final int n;
533
534      public InterOrdinalScaleFromInt(final int n) {
535        super(Type.INTER_ORDINAL, Source.INT_LIST);
536        this.n = n;
537      }
538
539      public final void setContent() {
540        context.setContent(
541            SetLists.integers(n),
542            SetLists.disjointUnion(SetLists.integers(n), SetLists.integers(n)),
543            BooleanMatrices
544                .apposition(BooleanMatrices.upperDiagonal(n), BooleanMatrices.dual(BooleanMatrices.upperDiagonal(n))));
545      }
546    }
547
548    public static final class InterOrdinalScaleFromSetList<E> extends Request<E, Pair<E, E>> {
549
550      private final SetList<E> s;
551
552      public InterOrdinalScaleFromSetList(final SetList<E> s) {
553        super(Type.INTER_ORDINAL, Source.STRINGS);
554        this.s = s;
555      }
556
557      public final void setContent() {
558        context.setContent(
559            s,
560            SetLists.disjointUnion(s, s),
561            BooleanMatrices.apposition(
562                BooleanMatrices.upperDiagonal(s.size()),
563                BooleanMatrices.dual(BooleanMatrices.upperDiagonal(s.size()))));
564      }
565    }
566
567    public static final class InterOrdinalScaleFromOrder<E> extends Request<E, Pair<E, E>> {
568
569      private final MatrixContext<E, E> c;
570
571      public InterOrdinalScaleFromOrder(final MatrixContext<E, E> c) {
572        super(Type.INTER_ORDINAL, Source.ORDER);
573        this.c = c;
574      }
575
576      public final void setContent() {
577        context.setContent(
578            c.rowHeads(),
579            SetLists.disjointUnion(c.colHeads(), c.colHeads()),
580            BooleanMatrices.apposition(c.matrix(), BooleanMatrices.dual(c.matrix())));
581      }
582    }
583
584    public static final class ConvexOrdinalScaleFromInt extends Request<Integer, Pair<Integer, Integer>> {
585
586      private final int n;
587
588      public ConvexOrdinalScaleFromInt(final int n) {
589        super(Type.CONVEX_ORDINAL, Source.INT_LIST);
590        this.n = n;
591      }
592
593      public final void setContent() {
594        context.setContent(
595            SetLists.integers(n),
596            SetLists.disjointUnion(SetLists.integers(n), SetLists.integers(n)),
597            BooleanMatrices.apposition(
598                BooleanMatrices.complement(BooleanMatrices.dual(BooleanMatrices.upperDiagonal(n))),
599                BooleanMatrices.complement(BooleanMatrices.upperDiagonal(n))));
600      }
601    }
602
603    public static final class ConvexOrdinalScaleFromSetList<E> extends Request<E, Pair<E, E>> {
604
605      private final SetList<E> s;
606
607      public ConvexOrdinalScaleFromSetList(final SetList<E> s) {
608        super(Type.CONVEX_ORDINAL, Source.STRINGS);
609        this.s = s;
610      }
611
612      public final void setContent() {
613        context.setContent(
614            s,
615            SetLists.disjointUnion(s, s),
616            BooleanMatrices.apposition(
617                BooleanMatrices.complement(BooleanMatrices.dual(BooleanMatrices.upperDiagonal(s.size()))),
618                BooleanMatrices.complement(BooleanMatrices.upperDiagonal(s.size()))));
619      }
620    }
621
622    public static final class ConvexOrdinalScaleFromOrder<E> extends Request<E, Pair<E, E>> {
623
624      private final MatrixContext<E, E> c;
625
626      public ConvexOrdinalScaleFromOrder(final MatrixContext<E, E> c) {
627        super(Type.CONVEX_ORDINAL, Source.ORDER);
628        this.c = c;
629      }
630
631      public final void setContent() {
632        context.setContent(
633            c.rowHeads(),
634            SetLists.disjointUnion(c.colHeads(), c.colHeads()),
635            BooleanMatrices.apposition(
636                BooleanMatrices.complement(BooleanMatrices.dual(c.matrix())),
637                BooleanMatrices.complement(c.matrix())));
638      }
639    }
640
641    public static final class BiOrdinalScale<E, T> extends Request<Pair<E, T>, Pair<E, T>> {
642
643      private final MatrixContext<E, E> order1;
644      private final MatrixContext<T, T> order2;
645
646      public BiOrdinalScale(final MatrixContext<E, E> order1, final MatrixContext<T, T> order2) {
647        super(Type.BI_ORDINAL, Source.ORDER_ORDER);
648        this.order1 = order1;
649        this.order2 = order2;
650      }
651
652      public final void setContent() {
653        context.setContent(
654            SetLists.disjointUnion(order1.rowHeads(), order2.rowHeads()),
655            SetLists.disjointUnion(order1.colHeads(), order2.colHeads()),
656            BooleanMatrices.horizontalSum(order1.matrix(), order2.matrix()));
657      }
658    }
659
660    public static final class GridScale<E, T> extends Request<Pair<E, T>, Pair<E, T>> {
661
662      private final MatrixContext<E, E> order1;
663      private final MatrixContext<T, T> order2;
664
665      public GridScale(final MatrixContext<E, E> order1, final MatrixContext<T, T> order2) {
666        super(Type.GRID, Source.ORDER_ORDER);
667        this.order1 = order1;
668        this.order2 = order2;
669      }
670
671      public final void setContent() {
672        context.setContent(
673            SetLists.cartesianProduct(order1.rowHeads(), order2.rowHeads()),
674            SetLists.disjointUnion(order1.colHeads(), order2.colHeads()),
675            BooleanMatrices.semiProduct(order1.matrix(), order2.matrix()));
676      }
677    }
678  }
679
680  public static final class Construct {
681
682    public static final class Complement<G, M> extends Request<G, M> {
683
684      private final MatrixContext<G, M> c;
685
686      public Complement(final MatrixContext<G, M> c) {
687        super(Type.COMPLEMENT, Source.CONTEXT);
688        this.c = c;
689      }
690
691      public final void setContent() {
692        context.setContent(c.rowHeads(), c.colHeads(), BooleanMatrices.complement(c.matrix()));
693      }
694    }
695
696    public static final class Dual<G, M> extends Request<M, G> {
697
698      private final MatrixContext<G, M> c;
699
700      public Dual(final MatrixContext<G, M> c) {
701        super(Type.DUAL, Source.CONTEXT);
702        this.c = c;
703      }
704
705      public final void setContent() {
706        context.setContent(c.colHeads(), c.rowHeads(), BooleanMatrices.dual(c.matrix()));
707      }
708    }
709
710    public static final class Contrary<G, M> extends Request<M, G> {
711
712      private final MatrixContext<G, M> c;
713
714      public Contrary(final MatrixContext<G, M> c) {
715        super(Type.CONTRARY, Source.CONTEXT);
716        this.c = c;
717      }
718
719      public final void setContent() {
720        context.setContent(c.colHeads(), c.rowHeads(), BooleanMatrices.complement(BooleanMatrices.dual(c.matrix())));
721      }
722    }
723
724    public static final class Apposition<G, M, N> extends Request<G, Pair<M, N>> {
725
726      private final MatrixContext<G, M> context1;
727      private final MatrixContext<G, N> context2;
728
729      public Apposition(final MatrixContext<G, M> context1, final MatrixContext<G, N> context2) {
730        super(Type.APPOSITION, Source.CONTEXT_CONTEXT);
731        this.context1 = context1;
732        this.context2 = context2;
733      }
734
735      public final void setContent() {
736        context.setContent(
737            SetLists.intersection(context1.rowHeads(), context2.rowHeads()),
738            SetLists.disjointUnion(context1.colHeads(), context2.colHeads()),
739            BooleanMatrices.apposition(context1.matrix(), context2.matrix()));
740      }
741    }
742
743    public static final class Subposition<G, H, M> extends Request<Pair<G, H>, M> {
744
745      private final MatrixContext<G, M> context1;
746      private final MatrixContext<H, M> context2;
747
748      public Subposition(final MatrixContext<G, M> context1, final MatrixContext<H, M> context2) {
749        super(Type.APPOSITION, Source.CONTEXT_CONTEXT);
750        this.context1 = context1;
751        this.context2 = context2;
752      }
753
754      public final void setContent() {
755        context.setContent(
756            SetLists.disjointUnion(context1.rowHeads(), context2.rowHeads()),
757            SetLists.intersection(context1.colHeads(), context2.colHeads()),
758            BooleanMatrices.subposition(context1.matrix(), context2.matrix()));
759      }
760    }
761
762    public static final class Quadposition<G, H, M, N> extends Request<Pair<G, H>, Pair<M, N>> {
763
764      private final MatrixContext<G, M> upperLeft;
765      private final MatrixContext<G, N> upperRight;
766      private final MatrixContext<H, M> lowerLeft;
767      private final MatrixContext<H, N> lowerRight;
768
769      public Quadposition(
770          final MatrixContext<G, M> upperLeft,
771          final MatrixContext<G, N> upperRight,
772          final MatrixContext<H, M> lowerLeft,
773          final MatrixContext<H, N> lowerRight) {
774        super(Type.QUADPOSITION, Source.CONTEXT_CONTEXT_CONTEXT_CONTEXT);
775        this.upperLeft = upperLeft;
776        this.upperRight = upperRight;
777        this.lowerLeft = lowerLeft;
778        this.lowerRight = lowerRight;
779      }
780
781      public final void setContent() {
782        context.setContent(
783            SetLists.disjointUnion(
784                SetLists.intersection(upperLeft.rowHeads(), upperRight.rowHeads()),
785                SetLists.intersection(lowerLeft.rowHeads(), lowerRight.rowHeads())),
786            SetLists.intersection(
787                SetLists.disjointUnion(upperLeft.colHeads(), upperRight.colHeads()),
788                SetLists.disjointUnion(lowerLeft.colHeads(), lowerRight.colHeads())),
789            BooleanMatrices.subposition(
790                BooleanMatrices.apposition(upperLeft.matrix(), upperRight.matrix()),
791                BooleanMatrices.apposition(lowerLeft.matrix(), lowerRight.matrix())));
792      }
793    }
794
795    public static final class HorizontalSum<G, H, M, N> extends Request<Pair<G, H>, Pair<M, N>> {
796
797      private final MatrixContext<G, M> context1;
798      private final MatrixContext<H, N> context2;
799
800      public HorizontalSum(final MatrixContext<G, M> context1, final MatrixContext<H, N> context2) {
801        super(Type.HORIZONTAL_SUM, Source.CONTEXT_CONTEXT);
802        this.context1 = context1;
803        this.context2 = context2;
804      }
805
806      public final void setContent() {
807        context.setContent(
808            SetLists.disjointUnion(context1.rowHeads(), context2.rowHeads()),
809            SetLists.disjointUnion(context1.colHeads(), context2.colHeads()),
810            BooleanMatrices.horizontalSum(context1.matrix(), context2.matrix()));
811      }
812    }
813
814    public static final class VerticalSum<G, H, M, N> extends Request<Pair<G, H>, Pair<M, N>> {
815
816      private final MatrixContext<G, M> context1;
817      private final MatrixContext<H, N> context2;
818
819      public VerticalSum(final MatrixContext<G, M> context1, final MatrixContext<H, N> context2) {
820        super(Type.VERTICAL_SUM, Source.CONTEXT_CONTEXT);
821        this.context1 = context1;
822        this.context2 = context2;
823      }
824
825      public final void setContent() {
826        context.setContent(
827            SetLists.disjointUnion(context1.rowHeads(), context2.rowHeads()),
828            SetLists.disjointUnion(context1.colHeads(), context2.colHeads()),
829            BooleanMatrices.verticalSum(context1.matrix(), context2.matrix()));
830      }
831    }
832
833    public static final class DirectSum<G, H, M, N> extends Request<Pair<G, H>, Pair<M, N>> {
834
835      private final MatrixContext<G, M> context1;
836      private final MatrixContext<H, N> context2;
837
838      public DirectSum(final MatrixContext<G, M> context1, final MatrixContext<H, N> context2) {
839        super(Type.DIRECT_SUM, Source.CONTEXT_CONTEXT);
840        this.context1 = context1;
841        this.context2 = context2;
842      }
843
844      public final void setContent() {
845        context.setContent(
846            SetLists.disjointUnion(context1.rowHeads(), context2.rowHeads()),
847            SetLists.disjointUnion(context1.colHeads(), context2.colHeads()),
848            BooleanMatrices.directSum(context1.matrix(), context2.matrix()));
849      }
850    }
851
852    public static final class DirectProduct<G, H, M, N> extends Request<Pair<G, H>, Pair<M, N>> {
853
854      private final MatrixContext<G, M> context1;
855      private final MatrixContext<H, N> context2;
856
857      public DirectProduct(final MatrixContext<G, M> context1, final MatrixContext<H, N> context2) {
858        super(Type.DIRECT_PRODUCT, Source.CONTEXT_CONTEXT);
859        this.context1 = context1;
860        this.context2 = context2;
861      }
862
863      public final void setContent() {
864        context.setContent(
865            SetLists.cartesianProduct(context1.rowHeads(), context2.rowHeads()),
866            SetLists.cartesianProduct(context1.colHeads(), context2.colHeads()),
867            BooleanMatrices.directProduct(context1.matrix(), context2.matrix()));
868      }
869    }
870
871    public static final class BiProduct<G, H, M, N> extends Request<Pair<G, H>, Pair<M, N>> {
872
873      private final MatrixContext<G, M> context1;
874      private final MatrixContext<H, N> context2;
875
876      public BiProduct(final MatrixContext<G, M> context1, final MatrixContext<H, N> context2) {
877        super(Type.BI_PRODUCT, Source.CONTEXT_CONTEXT);
878        this.context1 = context1;
879        this.context2 = context2;
880      }
881
882      public final void setContent() {
883        context.setContent(
884            SetLists.cartesianProduct(context1.rowHeads(), context2.rowHeads()),
885            SetLists.cartesianProduct(context1.colHeads(), context2.colHeads()),
886            BooleanMatrices.biProduct(context1.matrix(), context2.matrix()));
887      }
888    }
889
890    public static final class SemiProduct<G, H, M, N> extends Request<Pair<G, H>, Pair<M, N>> {
891
892      private final MatrixContext<G, M> context1;
893      private final MatrixContext<H, N> context2;
894
895      public SemiProduct(final MatrixContext<G, M> context1, final MatrixContext<H, N> context2) {
896        super(Type.SEMI_PRODUCT, Source.CONTEXT_CONTEXT);
897        this.context1 = context1;
898        this.context2 = context2;
899      }
900
901      public final void setContent() {
902        context.setContent(
903            SetLists.cartesianProduct(context1.rowHeads(), context2.rowHeads()),
904            SetLists.disjointUnion(context1.colHeads(), context2.colHeads()),
905            BooleanMatrices.semiProduct(context1.matrix(), context2.matrix()));
906      }
907    }
908
909    public static final class SubstitutionSum<G, H, M, N> extends Request<Pair<G, H>, Pair<M, N>> {
910
911      private final MatrixContext<G, M> context1;
912      private final MatrixContext<H, N> context2;
913      private final G                   object;
914      private final M                   attribute;
915
916      public SubstitutionSum(
917          final MatrixContext<G, M> context1,
918          final MatrixContext<H, N> context2,
919          final G object,
920          final M attribute) {
921        super(Type.SUBSTITUTION_SUM, Source.CONTEXT_CONTEXT_OBJECT_OBJECT);
922        this.context1 = context1;
923        this.context2 = context2;
924        this.object = object;
925        this.attribute = attribute;
926      }
927
928      public final void setContent() {
929        System.out.println("substitution sum");
930        final int i = context1.rowHeads().indexOf(object);
931        final int j = context1.colHeads().indexOf(attribute);
932        System.out.println(i + ":" + j);
933        final BooleanMatrix matrix = BooleanMatrices
934            .substitutionSum(context1.matrix(), context2.matrix(), i, j, context1._row(i), context1._col(j));
935        System.out.println(matrix);
936        context.setContent(
937            SetLists.disjointUnion(
938                SetLists.difference(context1.rowHeads(), Collections.singleton(object)),
939                context2.rowHeads()),
940            SetLists.disjointUnion(
941                SetLists.difference(context1.colHeads(), Collections.singleton(attribute)),
942                context2.colHeads()),
943            matrix);
944        System.out.println(context);
945      }
946    }
947  }
948//
949//  public static final class Other
950//  {
951//    public static final class AttributeApproximation<G, M>
952//      extends Request<G, M>
953//    {
954//      private final MatrixContext<G, M> c;
955//      private final double              tolerance;
956//
957//      public AttributeApproximation(final MatrixContext<G, M> c, final double tolerance)
958//      {
959//        super(Type.APPROXIMATION_CONTEXT_BY_ATTRIBUTES, Source.CONTEXT_DOUBLE);
960//        this.c = c;
961//        this.tolerance = tolerance;
962//      }
963//
964//      public final void setContent()
965//      {
966//        final MatrixContext<G, M> approx = new AbstractContext<G, M>(c.rowHeads(), c.colHeads(), false)
967//          {
968//            public final boolean contains(final Object object, final Object attribute)
969//            {
970//              if (c.contains(object, attribute))
971//                return true;
972//              final Collection<Integer> attributeIntent = c._intent(c.colHeads().indexOf(attribute));
973//              final Collection<Integer> objectIntent = c._row(c.rowHeads().indexOf(object));
974//              final double tau =
975//                  ((double) Collections3.intersection(attributeIntent, objectIntent).size())
976//                      / ((double) attributeIntent.size());
977//              return tau >= tolerance;
978//            }
979//          }.clone();
980//        final BooleanMatrix matrix = approx.matrix();
981//        System.out.println(matrix);
982//        context.setContent(approx.rowHeads(), approx.colHeads(), matrix);
983//      }
984//    }
985//
986//    public static final class Approximation<G, M>
987//      extends Request<Pair<G, G>, Pair<M, M>>
988//    {
989//      private final MatrixContext<G, M> c;
990//      private final Set<G>              objects;
991//      private final Set<M>              attributes;
992//
993//      public Approximation(final MatrixContext<G, M> c, final Set<G> objects, final Set<M> attributes)
994//      {
995//        super(Type.APPROXIMATION_CONTEXT, Source.CONTEXT_SET_SET);
996//        this.c = c;
997//        this.objects = objects;
998//        this.attributes = attributes;
999//      }
1000//
1001//      public final void setContent()
1002//      {
1003//        final MatrixContext<Pair<G, G>, Pair<M, M>> approx = ApproximationBuilder.build(c, objects, attributes);
1004//        context.setContent(approx.rowHeads(), approx.colHeads(), approx.matrix());
1005//      }
1006//    }
1007//
1008//    private static final class ApproximationBuilder<G, M>
1009//    {
1010//      private static final <G, M> MatrixContext<Pair<G, G>, Pair<M, M>> build(
1011//          final MatrixContext<G, M> context,
1012//          final Set<G> H,
1013//          final Set<M> N)
1014//      {
1015//        final MatrixContext<G, M> HM = context.subRelation(H, context.colHeads()).clone();
1016//        final MatrixContext<G, M> HN = context.subRelation(H, N).clone();
1017//        final MatrixContext<G, M> GN = context.subRelation(context.rowHeads(), N).clone();
1018//        final MatrixContext<G, M> GM = bondClosure(context, GN, HM);
1019//        final Quadposition<G, G, M, M> quadposition = new Quadposition<G, G, M, M>(HM, HN, GM, GN);
1020//        final MatrixContext<Pair<G, G>, Pair<M, M>> approx = quadposition.createContext();
1021//        quadposition.setContent();
1022//        return approx;
1023//      }
1024//
1025//      private static final <G, M> MatrixContext<G, M> bondClosure(
1026//          final MatrixContext<G, M> context,
1027//          final MatrixContext<G, M> leftContext,
1028//          final MatrixContext<G, M> upperContext)
1029//      {
1030//        final MatrixContext<G, M> bond = context.clone();
1031//        while (!isBond(bond, leftContext, upperContext)) {
1032//          for (G g : bond.rowHeads()) {
1033//            final Set<M> gBond = context.rowAnd(g);
1034//            final Set<M> intent = upperContext.intent(gBond);
1035//            for (M m : intent)
1036//              bond.addFast(g, m);
1037//          }
1038//          for (M m : bond.colHeads()) {
1039//            final Set<G> mBond = context.colAnd(m);
1040//            final Set<G> extent = leftContext.extent(mBond);
1041//            for (G g : extent)
1042//              bond.addFast(g, m);
1043//          }
1044//        }
1045//        return bond;
1046//      }
1047//
1048//      private static final <G, M> boolean isBond(
1049//          final MatrixContext<G, M> context,
1050//          final MatrixContext<G, M> leftContext,
1051//          final MatrixContext<G, M> upperContext)
1052//      {
1053//        for (G g : context.rowHeads()) {
1054//          final Set<M> gBond = context.rowAnd(g);
1055//          if (!upperContext.intent(gBond).equals(gBond))
1056//            return false;
1057//        }
1058//        for (M m : context.colHeads()) {
1059//          final Set<G> mBond = context.colAnd(m);
1060//          if (!leftContext.extent(mBond).equals(mBond))
1061//            return false;
1062//        }
1063//        return true;
1064//      }
1065//    }
1066//
1067//    public static final class BinaryRelationsFromInt
1068//      extends Request<MatrixRelation<Integer, Integer>, String>
1069//    {
1070//      private final int n;
1071//
1072//      public BinaryRelationsFromInt(final int n)
1073//      {
1074//        super(Type.BINARY_RELATIONS_CONTEXT, Source.INT_LIST);
1075//        this.n = n;
1076//      }
1077//
1078//      public final void setContent()
1079//      {
1080//        BinaryRelationsBuilder.build(context, n);
1081//      }
1082//    }
1083//
1084//    private static final class BinaryRelationsBuilder
1085//    {
1086//      private static final MatrixContext<MatrixRelation<Integer, Integer>, String> build(
1087//          final MatrixContext<MatrixRelation<Integer, Integer>, String> context,
1088//          final int maxSize)
1089//      {
1090//        generateAllBinaryRelations(context, maxSize);
1091//        context.colHeads().add("reflexive");
1092//        context.colHeads().add("irreflexive");
1093//        context.colHeads().add("symmetric");
1094//        context.colHeads().add("asymmetric");
1095//        context.colHeads().add("connex");
1096//        context.colHeads().add("antisymmetric");
1097//        context.colHeads().add("quasiconnex");
1098//        context.colHeads().add("alternative");
1099//        context.colHeads().add("transitive");
1100//        context.colHeads().add("negative transitive");
1101//        context.colHeads().add("atransitive");
1102//        context.colHeads().add("negative atransitive");
1103//        // context.getCodomain().add("0-cyclic");
1104//        // context.getCodomain().add("1-cyclic");
1105//        // context.getCodomain().add("2-cyclic");
1106//        // context.getCodomain().add("3-cyclic");
1107//        // context.getCodomain().add("4-cyclic");
1108//        context.colHeads().add("cyclic");
1109//        // context.getCodomain().add("0-acyclic");
1110//        // context.getCodomain().add("1-acyclic");
1111//        // context.getCodomain().add("2-acyclic");
1112//        // context.getCodomain().add("3-acyclic");
1113//        // context.getCodomain().add("4-acyclic");
1114//        context.colHeads().add("acyclic");
1115//        // context.getCodomain().add("0-transitive");
1116//        // context.getCodomain().add("1-transitive");
1117//        // context.getCodomain().add("2-transitive");
1118//        // context.getCodomain().add("3-transitive");
1119//        // context.getCodomain().add("4-transitive");
1120//        // context.getCodomain().add("0-atransitive");
1121//        // context.getCodomain().add("1-atransitive");
1122//        // context.getCodomain().add("2-atransitive");
1123//        // context.getCodomain().add("3-atransitive");
1124//        // context.getCodomain().add("4-atransitive");
1125//        // context.getCodomain().add("left comparative");
1126//        // context.getCodomain().add("right comparative");
1127//        for (MatrixRelation<Integer, Integer> binaryRelation : context.rowHeads()) {
1128//          if (binaryRelation.isReflexive())
1129//            context.addFast(binaryRelation, "reflexive");
1130//          if (binaryRelation.isIrreflexive())
1131//            context.addFast(binaryRelation, "irreflexive");
1132//          if (binaryRelation.isSymmetric())
1133//            context.addFast(binaryRelation, "symmetric");
1134//          if (binaryRelation.isAsymmetric())
1135//            context.addFast(binaryRelation, "asymmetric");
1136//          if (binaryRelation.isConnex())
1137//            context.addFast(binaryRelation, "connex");
1138//          if (binaryRelation.isAntisymmetric())
1139//            context.addFast(binaryRelation, "antisymmetric");
1140//          if (binaryRelation.isQuasiconnex())
1141//            context.addFast(binaryRelation, "quasiconnex");
1142//          if (binaryRelation.isAlternative())
1143//            context.addFast(binaryRelation, "alternative");
1144//          if (binaryRelation.isTransitive())
1145//            context.addFast(binaryRelation, "transitive");
1146//          if (binaryRelation.isNegativeTransitive())
1147//            context.addFast(binaryRelation, "negative transitive");
1148//          if (binaryRelation.isAtransitive())
1149//            context.addFast(binaryRelation, "atransitive");
1150//          if (binaryRelation.isNegativAtransitive())
1151//            context.addFast(binaryRelation, "negative atransitive");
1152//          // if(rel.isNCyclic(0)) context.set(binaryRelation, "");
1153//          // if(rel.isNCyclic(1)) context.set(binaryRelation, "");
1154//          // if(rel.isNCyclic(2)) context.set(binaryRelation, "");
1155//          // if(rel.isNCyclic(3)) context.set(binaryRelation, "");
1156//          // if(rel.isNCyclic(4)) context.set(binaryRelation, "");
1157//          if (binaryRelation.isCyclic())
1158//            context.addFast(binaryRelation, "cyclic");
1159//          // if(rel.isNAcyclic(0)) context.set(binaryRelation, "");
1160//          // if(rel.isNAcyclic(1)) context.set(binaryRelation, "");
1161//          // if(rel.isNAcyclic(2)) context.set(binaryRelation, "");
1162//          // if(rel.isNAcyclic(3)) context.set(binaryRelation, "");
1163//          // if(rel.isNAcyclic(4)) context.set(binaryRelation, "");
1164//          if (binaryRelation.isAcyclic())
1165//            context.addFast(binaryRelation, "acyclic");
1166//          // if(rel.isNTransitive(0)) context.set(binaryRelation, "");
1167//          // if(rel.isNTransitive(1)) context.set(binaryRelation, "");
1168//          // if(rel.isNTransitive(2)) context.set(binaryRelation, "");
1169//          // if(rel.isNTransitive(3)) context.set(binaryRelation, "");
1170//          // if(rel.isNTransitive(4)) context.set(binaryRelation, "");
1171//          // if(rel.isNAtransitive(0)) context.set(binaryRelation, "");
1172//          // if(rel.isNAtransitive(1)) context.set(binaryRelation, "");
1173//          // if(rel.isNAtransitive(2)) context.set(binaryRelation, "");
1174//          // if(rel.isNAtransitive(3)) context.set(binaryRelation, "");
1175//          // if(rel.isNAtransitive(4)) context.set(binaryRelation, "");
1176//          // if(rel.isLeftComparative()) context.set(binaryRelation, "");
1177//          // if(rel.isRightComparative()) context.set(binaryRelation, "");
1178//        }
1179//        return context;
1180//      }
1181//
1182//      private static final void generateAllBinaryRelations(
1183//          final MatrixContext<MatrixRelation<Integer, Integer>, String> context,
1184//          final int maxSize)
1185//      {
1186//        for (int size = 0; size < maxSize; size++) {
1187//          final SetList<Integer> domain = SetLists.integers(size);
1188//          MatrixRelation<Integer, Integer> binaryRelation;
1189//          for (List<Boolean> list : generateAllArrays(size * size)) {
1190//            binaryRelation = new MatrixRelation<Integer, Integer>(true)
1191//              {
1192//                public String toString()
1193//                {
1194//                  return Iterators.toString(iterator());
1195//                }
1196//              };
1197//            binaryRelation.rowHeads().addAll(domain);
1198//            populateMatrix(binaryRelation, list);
1199//            context.rowHeads().add(binaryRelation);
1200//          }
1201//        }
1202//      }
1203//
1204//      private static final Set<List<Boolean>> generateAllArrays(final int size)
1205//      {
1206//        final Set<List<Boolean>> arrays = new LinkedHashSet<List<Boolean>>();
1207//        if (size < 0)
1208//          return arrays;
1209//        if (size == 0)
1210//          arrays.add(new ArrayList<Boolean>());
1211//        else {
1212//          for (List<Boolean> array : generateAllArrays(size - 1)) {
1213//            final List<Boolean> newArray0 = new ArrayList<Boolean>(array);
1214//            newArray0.add(false);
1215//            arrays.add(newArray0);
1216//            final List<Boolean> newArray1 = new ArrayList<Boolean>(array);
1217//            newArray1.add(true);
1218//            arrays.add(newArray1);
1219//          }
1220//        }
1221//        return arrays;
1222//      }
1223//
1224//      private static final void
1225//          populateMatrix(final MatrixRelation<Integer, Integer> context, final List<Boolean> list)
1226//      {
1227//        int size = (int) Math.sqrt(list.size());
1228//        int row = 0;
1229//        int col = 0;
1230//        final Iterator<Boolean> iterator = list.iterator();
1231//        while (iterator.hasNext()) {
1232//          if (iterator.next())
1233//            context.addFast(row, col);
1234//          if (col < size - 1) {
1235//            col++;
1236//          } else {
1237//            col = 0;
1238//            row++;
1239//          }
1240//        }
1241//      }
1242//    }
1243//  }
1244}