 
 (defn context-semiproduct
   "Computes the context semiproduct of ctx-1 and ctx-2, where for
-  contexts $(G_1,M_1,I_1)$ and $(G_2,M_2,I_2)$ their semidirect
-  product is defined as
-  \\[
-    (G_1\\times G_2, M_1\\cup M_2, \\nabla)
-  \\]
+  contexts (G_1,M_1,I_1) and (G_2,M_2,I_2) their semidirect product is
+  defined as
+
+    (G_1 x G_2, M_1 dunion M_2, nabla)
+
   where
-  \\[
-    (g_1,g_2)\\nabla(j,m) \\iff g_jI_jm \\qquad\\text{for $j\\in\\set{1,2}$}.
-  \\]"
+
+    (g_1,g_2) nabla (j,m) <=> g_jI_jm for j in {1,2}.
+  "
   [ctx-1 ctx-2]
   (let [new-objs (cross-product (objects ctx-1) (objects ctx-2))
         new-atts (disjoint-union (attributes ctx-1) (attributes ctx-2))


(defn context-apposition
  "Returns context apposition of ctx-1 and ctx-2, that is
  \\[
     (G_1,M_1,I_1) | (G_1,M_2,I_2) := (G_1,M_1\\cup M_2,I_1\\cup I_2).
  \\]"
  [ctx-1 ctx-2]
  (if (not= (objects ctx-1) (objects ctx-2))
    (illegal-argument "Cannot do context apposition, since object sets are not equal."))

;;; Common Operations with Contexts

(defn dual-context
  "Dualizes context ctx, that is (G,M,I) gets (M,G,I^{-1})."
  [ctx]
  (make-context-nc (attributes ctx) (objects ctx) (set-of [m g] [[g m] (incidence ctx)])))

(defn invert-context
  "Inverts context ctx, that is (G,M,I) gets (G,M,(G x M) \\ I)."
  [ctx]
  (make-context-nc (objects ctx) (attributes ctx) (set-of [g m] [g (objects ctx)
                                                                 m (attributes ctx)
