{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "To load \"kenzo\":\n", " Load 1 ASDF system:\n", " kenzo\n", "; Loading \"kenzo\"\n", "\n" ] }, { "data": { "text/plain": [ "#" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(ql:quickload \"kenzo\")\n", "(in-package :cat)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Chain Complexes\n", "\n", "## Introduction\n", "\n", "In the Kenzo program, a *chain complex* $(C_p, d_p)$ is a collection of free $\\mathbb{Z}$-modules $(C_p)$, one for each\n", "$p \\in \\mathbb{Z}$, together with a homomorphism $d_p : C_p \\rightarrow C_{p-1}$, such\n", "that, for all $p$, $d_{p-1} \\circ d_p = 0$. (See, for example, __P.J. Giblin__ in *Graph, Surface and Homology*, Chapman and Hall Math. series, 1981.)\n", "\n", "In the Kenzo program, a *morphism* $f=(f_p)$, of degree $k$, from a chain complex $(C_p, d_p)$ to another $(C'_p, d'_p)$ is a collection of homomorphisms\n", "\n", "$$f_p : C_p \\rightarrow C'_{p+k}.$$\n", "\n", "This is expressed by the following diagram, generally not assumend commutative .\n", "\n", "$$\n", "\\begin{aligned}\n", "\\cdots & \\leftarrow & C_{p-1} & \\quad\\xleftarrow{d_p} & C_p & \\quad\\xleftarrow{d_{p+1}} & C_{p+1} & \\quad\\leftarrow & \\cdots \\\\\n", " & & f_{p-1} \\Bigg\\downarrow & & f_p \\Bigg\\downarrow & & f_{p+1} \\Bigg\\downarrow \\\\\n", "\\cdots & \\leftarrow & C'_{p+k-1} & \\quad\\xleftarrow{d'_{p+k}} & C'_{p+k} & \\quad\\xleftarrow{d'_{p+k+1}} & C'_{p+k+1} & \\quad\\leftarrow & \\cdots \\end{aligned}\n", "$$\n", "\n", "Three types of morphisms are most generally considered.\n", "\n", "1. $k=0$. If the commutativity relation $d'_p\\circ f_p=f_{p-1}\\circ d_p$ holds for every $p$, then the morphism $f$ is an ordinary chain complex morphism or *chain map*.\n", "2. $k=-1$. If $(C_p,d_p)=(C'_p,d'_p)$ and $f_p=d_p$, then $f$ is the *differential* of the chain complex $(C_p,d_p)$ and, in fact, this differential is implemented in the ${\\tt Kenzo}$ program as a morphism of degree $-1$. Also, if $d_p \\neq f_p$ and $(d_{p-1}+f_{p-1})(d_p+f_p) = 0$ for every $p$, then $f_\\ast$ is a perturbation of the differential $d_\\ast$.\n", "3. $k=+1$. In this case, $f$ is usually a *homotopy operator*, that is, some relation $$d'_{p+1}\\circ f_p+f_{p-1}\\circ d_p=g_p-g'_p$$ is satisfied for two (ordinary) chain complex morphisms $g_\\ast$ and $g'_\\ast$, and $f_\\ast$ is a homotopy between $g_\\ast$ and $g'_\\ast$.\n", "\n", "For technical reasons, these three types of morphisms have been implemented in the `Kenzo` program\n", "in a unique type.\n", "\n", "\n", "## Generators, terms, and combinations\n", "\n", "To become familiar with the Lisp functions implementing the chain complexes, the best is to begin with an example. *Simplicial complexes* are good candidates for this purpose, and we shall take as a typical example the following simplicial complex." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "scrolled": false }, "outputs": [ { "data": { "image/png": "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bqhGv99/+fLl4i3v379f+R/ul19+WRTF5uD0888/R1EUhluue8zr16+/++47Aez+wjLXuqA1Go3CWdk6aZp2Op1Op7Mhg2VZ1u/3BTCWyWAHYTKZhLWs0WhUFMV8Pi+KIlwSurx4XQmXig4GgxCuoij6j//4j3X/zsPLxK5+ADg2VV/ru+++sw7GaajWwZIksQ5Wg5B23r179/bt2+U/7eVbNhcCv/zyy3V3vXnzpiiK//W//teGiYhv374tiuLDhw/v37//7LPPvvnmGzn8o8IpU5iIuHyOtPmsaTqd5nl+fX294WKw8PZ3WC4Loz42nNRxbmSwg7DYCQ5vdN2/JdxsNkN3eTeHBqemmhfXbDZdD8aJ+R//43+E9xdevHjherBd+/zzz0O15OrqamXo/fd///f7PM9vv/325Zdf/vWvf11574cPH16+fPnRqYavX79uNBrv3r179+5do9EIcyYuLy9F8Q2qRNTr9Vb+d7BubEaIVR+dahjmWlcVpOFw2Ol0BoOB/3do2B8MOCvVFmHVpmH7PiJ4YtW+5K9evfrhhx8euv0U91elpnAV1k8//XTnT/s+4+b/8Y9/fPHFFxt2b3v58uV333330ad6//79ncsWiqJ48eLFL7/88tFjOFvVxfNlWXa73TBxevEBK68EaTQaSZKsG2e9qCzLO//L5Hne7XZDNuPMyWDAuaj2qx0MBotTsODEhLcY/vt//+9FUVxeXm6xpS/38dlnn7148aL69NWrV0mSvHnz5p5f/uHDh7///e+vX7/+888/1w3k+Pnnn9+/f3+f9cwff/zxxx9//Oc//zkej7/77rtnz56F21++fCmGrdNqtRZ3Z03T9OLiIgzq2CBN07Is77Nv2Gw2m81mt7e319fXi1eFhaGLjzlyToAMBpy+8B5nmqZhKKINmjl5zWYzz/PBYFAt0ez7iE7Tt99+e3V1VQWeP/744+rq6ocffgjjOtb5/fff//GPf3z33XdhsuK7d+9evHjx888/33nYn3/++csvvyzGvPv44osv/va3v7169eqbb74Jt2RZZjl0nX6/v7hX5Hw+7/V63W533VT6+XyeZdlicruPKIrG4/HNzU115cjymhvnRgYDTpz+IWdLL7EGX3/99atXrxa3Yy6KYvOC2LNnz7755puXL1++ePGi2ssry7I7K5Z///vf//rXv243WuPTTz/993//9++++67RaLx//z5cLcZKcRzf3NwsbuqT5/m6BbFqGPUW3yhchBxmY5ZlaSnszMlgwCnTP+TM6SXW4NNPP/3+++9fvXpVXSD0/v37q6urdTHss88+++qrr7766qtvv/32//yf/xOSUuNfG44FP/3002efffbtt98+5sD6/X5Yo9u8+Rhh0PTim3RhetOdGDYcDh+/o89oNKrmMT7meTh2MhhwmvQPIdBLrMdnn332448/Lp6gv3z58j5rj3/729/CaliVlN6+ffv69euHthCXffrpp9VS2COf6hy0Wq07/1kkSVI1BvM836KFuKzZbFZLYY98Ko6a2fTACcrzvNfrhZlUi11/OFuj0ajT6fR6vVevXr179+7q6spmvrvw17/+9dmzZ2F35lACXDd0ftG3336bZVkYK99oNF69evX+/ftqfWzZf/tv/y188M9//nPzM/tbfqjBYNBsNsPuzKExGGqKYRTH8+fP133hJ598Ej64vb3d/C38l0TDOhhwevQPYSW9xCe0YfDGt99+W8Wne/bNwgbNH511voXQRayuOqOyYfBGv9+v1jM3bMG8tfC/kv2az5wMBpwO/UPYTC/xqXz55ZfLkwwrVZqqRibeR5WUwpT5ZWF5rdFoVLd89DlDULzPTmXnJoqiNE3X3VtdGFa9ixemzC+rdmqubvnotw7ZbxeRmyMigwEnwvxDuCfzEh/v008/ff369bpZF9X1V/cMP2G5rJom/4SKovj8888fOdvjJDWbzSzL1i1UVhdr7SIp5Xn++NkeHDsZDDgF+ofwIHqJjxTag3//+99XJthwZv/s2bPFa7o+fPjw9u3b5cd/+PDh9evXl5eXX3311XYH8+bNm59++mn5L/HNmzfv3r1zrr9SCFfhyuHle0MFsZqfsYXpdDocDperjNPptCgKNQ1kMOC46R/CdvQSHyNs2/XHH38kSXIn/Pz8889hyvyLFy8WR2KEDcEuLy8X/6j//PPPH3744bvvvvv++++3Ppirq6tXr16Fv8Qq47158ybLshcvXnz99ddbP/MJC5djzefzi4uLO0kpTdMwlX48Hm/9jl6v10vTtNvtLm7HHILZeDyuNmvmbJmLCBwx8w/hkcxL3E7IYGFr5nCZVrjlzz///OOPP6Io6vf7d4qIURT99ttv79+/f/Xq1evXr8O9z5496/f7W6+ABd99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", "text/plain": [ "#" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(cl-jupyter-user:png-from-file \"diabolo.png\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this simplicial complex, called here *diabolo*, there are 3 non-null chain groups.\n", "\n", "* $C_0$, the free $\\mathbb{Z}$-module on the set of vertices $\\{s_0,s_1,s_2,s_3,s_4,s_5\\}$\n", "* $C_1$, the free $\\mathbb{Z}$-module on the set of edges $\\{s_{01},s_{02},s_{12},s_{23},s_{34},s_{35}, s_{45}\\}$\n", "* $C_2$, the free $\\mathbb{Z}$-module on the set of triangles (here a singleton) $\\{s_{345}\\}$\n", "\n", "The elements of either of those groups $C_p$ are linear integer combinations of the corresponding basis $\\beta_p$, i.e. elements of the form:\n", "$$\n", "\\sum_{b \\in \\beta_p} \\lambda_b b.\n", "$$\n", "For example $2 s_{02} - 3 s_{34} \\in C_1$. An element $b$ of the basis $\\beta_p$ of $C_p$ is called a *generator* of $C_p$ and in our specific case this generator will be represented by a Lisp symbol. For instance, $s_{45}$ will be translated into `s45`. However, the user should be aware that in more realistic usage of the software, generators may be of any type. A product such as $\\lambda_i\\sigma_i$ is called a *term* and a sum of terms, a *combination*.\n", "\n", "### Representation of a combination\n", "\n", "A combination is represented internally in the system by a structure having the following general form:\n", "\n", "$$\\#\\texttt{S(CMBN}\\quad\\texttt{DEGREE P}\\quad\\texttt{LIST (}\\texttt{(}\\lambda_1\\cdot\\sigma_1\\texttt{)}\\dots\\texttt{(}\\lambda_k\\cdot\\sigma_k\\texttt{)))}$$\n", "and containing\n", "\n", "1. The degree of the combination corresponding to the index $p\\in\\mathbb{Z}$ of the group $C_p$ to which this combination belongs.\n", "2. The list of the internal representation of the terms, namely the list of pairs $(\\lambda_i\\cdot\\sigma_i)$.\n", "\n", "This choice of representation implies that only homogeneous combinations will be considered. The type `CMBN` and a printing method are provided with this internal representation. The external form of a combination is shown in the examples.\n", "\n", "### Ordering the generators\n", "\n", "In order to speed up the execution of algorithms involving combinations, the list of pairs $(\\lambda_i.\\sigma_i)$ is ordered by an adequate ordering function (ex: the lexicographical ordering on the symbols). For programming convenience, an enumerated type `CMPR` has been defined:\n", "``lisp\n", "(deftype cmpr() '(member :less :equal :greater))\n", "``\n", "A number of macros, functions and methods have been defined on usual sets (symbols, numbers, lists, etc.) taking their value in the set `[:less, :equal, :greater]`. Of course, the user may define its own function for a particular case. There exists functions to compare various couples of usual items:\n", "\n", "`(f-cmpr` *n1 n2*`)` *[Function]* \n", "> Return `:less`, `:equal`, `:greater`, according to the result of the canonical comparison of both integers *n1* and *n2*.\n", "\n", "`(s-cmpr` *symbol1 symbol2*`)` *[Function]* \n", "> Return `:less`, `:equal`, `:greater`, according to the result of the lisp comparison functions on the strings `(symbol-name` *symbol1*`)` and `(symbol-name` *symbol2*`)`\n", "\n", "`(l-cmpr ` *list1 list2*`)` *[Function]* \n", "> Return `:less`, `:equal`, `:greater`, according to the lexicographical ordering of the two lists *list1*\n", "and *list2*, making sense only if *list1* and *list2* are lists made of integers, symbols and/or lists; in the last case, the qualifier *list* is to be understood recursively.\n", "\n", "#### Examples" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ ":LESS" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(f-cmpr 123 789)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ ":GREATER" ] }, "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(s-cmpr 'circulation 'circular)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ ":EQUAL" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(s-cmpr 'qwerty 'qwerty)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ ":GREATER" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(l-cmpr '(1 a b) '(1 a))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1.2.3 Functions handling combinations\n", "\n", "The software provides a set of functions, methods, and macros to create or modify combinations.\n", "\n", "`(term-cmbn` *dgr cf gnr*`)` *[Macro]* \n", "> Construct the combination of degree `dgr` with unique term `cf * gnr`.\n", "\n", "`(cmbn` *dgr cf1 gnr1 cf2 gnr2 ... cfn gnrn*`)` *[Function]* \n", "> Construct a combination of degree `dgr`, sum of the terms $cf_i * gnr_i$. The sequence of pairs $\\lbrace cf_i\\ gnr_i\\rbrace$ has an undefinite length and may be void. In this case, the combination is a null combination of degree `dgr`. It is the responsability of the user to properly order the terms of the combination, otherwise later calculations with this combination could work erroneously. This point can be checked by the `do-control` function. **[I suggest to insert here two appropriate examples.]**\n", "\n", "`(cmbn-p` *object*`)` *[Function]* \n", "> Test is `object` is a legal combination.\n", "\n", "`(cmbn-degr` *cmbn*`)` *[Macro]* \n", "> Get the degree (an integer) of the combination `cmbn`.\n", "\n", "`(cmbn-list` *cmbn*`)` *[Macro]* \n", "> Get the list of the terms of the combination `cmbn`. Beware: a term is not a structure object, it is a simple `cons` `(cffc . gnrt)`, a pair coefficient - generator. Given a term, one may select the coefficient (an integer) or the generator - a `Kenzo` object - respectively by the macros `cffc` and `gnrt`.\n", "\n", "`(zero-cmbn` *dgr*`)` *[Function]* \n", "> Create an instance of a null combination in the degree `dgr`.\n", "\n", "`(cmbn-zero-p` *cmbn*`)` *[Macro]* \n", "> Test if `cmbn` is a null combination in any degree.\n", "\n", "`(cmbn-non-zero-p` *cmbn*`)` *[Macro]* \n", "> Test if `cmbn` is a non-null combination in any degree.\n", "\n", "`(cmbn-opps` *cmbn*`)` *[Function]*\n", "> Create a combination opposite to `cmbn`.\n", "\n", "`(n-cmbn` *n cmbn*`)` *[Function]* \n", "> Create a combination multiple of `cmbn` by the factor `n`.\n", "\n", "`(2cmbn-add cmpr` *cmbn1 cmbn2*`)` *[Function]*\n", "> Create a combination, sum of both combinations `cmbn1` and `cmbn2`. The first argument, `cmpr`, must be the comparison function available in the slot `cmpr` of the underlying chain complex, required to properly merge the terms of both combinations.\n", "\n", "`(ncmbn-add` *cmpr cmbn1 cmbn2 ... cmbnk*`)` *[Function]* \n", "> Create a combination, sum of the indefinite number of combinations $cmbn_i$. As to the first argument, `cmpr`, see the function `2cmbn-add`.\n", "\n", "`(2n-2cmbn` *cmpr n1 cmbn1 n2 cmbn2*`)` *[Function]* \n", "> Build the combination `n1 * cmbn1 + n2 * cmbn2`. Both integers `n1` and `n2` must be\n", "non null. As to the first argument, `cmpr`, see the function `2cmbn-add`.\n", "\n", "`(2cmbn-sbtr` *cmpr cmbn1 cmbn2*`)` *[Function]* \n", "> Create a combination, difference of `cmbn1` and `cmbn2`. As to the first argument, `cmpr`, see the function `2cmbn-add`.\n", "\n", "#### Examples" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 1}\n", "<1 * U>\n", "<2 * V>\n", "<3 * W>\n", "<4 * Z>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def comb1 (cmbn 1 1 'u 2 'v 3 'w 4 'z))" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "T" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(cmbn-non-zero-p comb1)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "((1 . U) (2 . V) (3 . W) (4 . Z))" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(cmbn-list comb1)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "(3 . W)" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def term3 (third *)) ;; a simple cons!" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(cffc term3)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "W" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(gnrt term3)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 1}\n", "<-1 * U>\n", "<-2 * V>\n", "<-3 * W>\n", "<-4 * Z>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def mcomb1 (cmbn-opps comb1))" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 1}\n", "<10 * U>\n", "<20 * V>\n", "<30 * W>\n", "<40 * Z>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 14, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def comb2 (n-cmbn 10 comb1))" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 1}\n", "<11 * U>\n", "<22 * V>\n", "<33 * W>\n", "<44 * Z>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def cmb12 (2cmbn-add #'s-cmpr comb1 comb2))" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 1}\n", "<-10 * U>\n", "<-20 * V>\n", "<-30 * W>\n", "<-40 * Z>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(2cmbn-sbtr #'s-cmpr comb1 cmb12)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 1}\n", "<55 * U>\n", "<110 * V>\n", "<165 * W>\n", "<220 * Z>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 17, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(ncmbn-add #'s-cmpr\n", " comb1 comb2 comb1 comb2 comb1 comb2 comb1 comb2 comb1 comb2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Representation of a chain complex\n", "\n", "A chain complex is implemented as an instance of a `CLOS` class, \n", "the class `CHAIN-COMPLEX`, whose definition is\n", "\n", "```commonlisp\n", "(DEFCLASS CHAIN-COMPLEX ()\n", " ((cmpr :type cmprf :initarg :cmpr :reader cmpr1)\n", " (basis :type basis :initarg :basis :reader basis1)\n", " ;; BaSe GeNerator\n", " (bsgn :type gnrt :initarg :bsgn :reader bsgn)\n", " ;; DiFFeRential\n", " (dffr :type morphism :initarg :dffr :reader dffr1)\n", " ;; GRound MoDule\n", " (grmd :type chain-complex :initarg :grmd :reader grmd)\n", " ;; EFfective HoMology\n", " (efhm :type homotopy-equivalence :initarg :efhm :reader efhm)\n", " ;; IDentification NuMber\n", " (idnm :type fixnum :initform (incf *idnm-counter*) :reader idnm)\n", " ;; ORiGiN\n", " (orgn :type list :initarg :orgn :reader orgn)))\n", "```\n", "\n", "This class has 8 slots:\n", "\n", "1. `cmpr`, a comparison function or method for generators with a range in the set `[:less, :equal, :greater]`. It is very important to note that the generators to be compared are assumed to be of the *same degree*, i.e. they must belong to the same group $C_p$. As an exception with the general policy of the program, this degree is not explicitly precised. The implementor has chosen to avoid additional tests because in real problems the program spends a lot of time comparing generators.\n", "2. `basis`, a lisp function giving the distinguished **ordered** basis of the free $\\mathbb{Z}$-modules ($C_p$). (Recall that in the program, only free chain complexes are considered.) When some components of the chain complex are not finitely generated, we say that the chain complex is *locally effective*. In this case the value of this slot must be the keyword `locally-effective`.\n", "3. `bsgn`, a lisp object of any type representing a distinguished generator in dimension 0, the base generator. \n", "4. `dffr`, the differential morphism, instance of the class `MORPHISM`, defined hereafter. The pure lisp function corresponding to the differential homomorphism for each $p$ ($d_p : C_p \\rightarrow C_{p-1}$) is defined in the instance morphism object and not directly in the instance chain complex object.\n", "5. `idnm`, an integer, number plate for this object. This is generated by the system in a sequential way, each time a new `Kenzo` object is created.\n", "6. `orgn`, a list containing a comment to recall to the user the *origin* of the object. This comment must be chosen with care because, when the user creates a new chain complex instance, the system `Kenzo` uses the comment list information to search in a specific list (here `*chcm-list*`) if the object has not been already built. So, one avoids the duplication of instances of the same object.\n", "\n", "The two slots `grmd` and `efhm` will be explained later. The accessors of the slots are the functions whose name appears after the specifier `:reader` in the class definition. A printing method has been associated to the class `CHAIN-COMPLEX` and the external representation of a chain complex instance is a string like `[Kn Chain-Complex]`, \n", "where `n` is the number plate of this `Kenzo` object.\n", "\n", "\n", "### The function `build-chcm`\n", "\n", "To facilitate the construction of instances of the class `CHAIN-COMPLEX` and to free the user to call\n", "the standard constructor `make-instance`, the software provides the function\n", "\n", "`build-chcm`\n", "> `:cmpr` *cmpr* `:basis` *basis* `:bsgn` *bsgn* `:intr-dffr` *intr-dffr* `:strt` *strt* `:orgn` *orgn*\n", "\n", "defined with keyword parameters. The returned value is an instance of the class `CHAIN-COMPLEX`. In particular, this function frees the user to build himself the instance of the class `MORPHISM` corresponding to the differential homomorphism. The keyword arguments of `build-chcm` are:\n", "\n", "- `cmpr`, the comparison function for generators.\n", "- `basis`, the function defining the distinguished basis of the free $\\mathbb{Z}$-modules $C_p$ or the keyword `:locally-effective`.\n", "- `bsgn`, a generator, the base point of the underlying set.\n", "- `intr-dffr`, a **lisp function** defining the differential homomorphism for each $p$ ($d_p : C_p \\rightarrow C_{p-1}$).\n", "- `strt`, one of the two values: `:gnrt` or `:cmbn`, defining the mapping *strategy* of the differential homomorphism, either by generator or by combination. The default is `:gnrt`. The real connection between the arguments `intr-dffr` and `strt`will be detailed hereafter through typical examples. The general idea is the following: if the strategy is `:gnrt`, the `:intr-dffr` argument function uses two arguments, namely a degree and a generator of this degree and computes the boundary combination of this generator. If the strategy is `:cmbn`, the `:intr-dffr` argument function uses a combination as argument and computes the boundary combination of this argument. We recall that a combination contains its own degree.\n", "- `orgn`, a list containing a relevant and carefully chosen comment about the `origin` of the chain complex. If, during a Lisp session, the user wishes to modify any slot of an existing chain complex, by calling again `build-chcm`, he must change also the comment, otherwise the new version of the object will not be created. This remark is valid for any kind of instantiation of `Kenzo` objects. The function `cat-init` reinitializes the environment, that is, the previous relations `orgn` $\\rightarrow$ Kenzo objects are deleted.\n", "\n", "\n", "After creation of an instance of chain complex, the function `build-chcm` pushes this\n", "object in the list of already created chain complexes `*chcm-list*`.\n", "\n", "#### A first example of a chain complex\n", "\n", "Let us consider our small example *diabolo*. We shall give the same name to the corresponding chain complex instance. Let us define, one by one, the values of the key parameters, though it is possible to put them directly in the `build-chcm` call. First, the function `s-cmpr`, already seen above, is the natural choice to compare generators, which are here, lisp symbols:" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "#" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def diabolo-cmpr #'s-cmpr)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The function for the basis consists in enumerating the distinguished basis as lisp lists according to the degree:" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "#" ] }, "execution_count": 19, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def diabolo-basis #'(lambda (dmn)\n", " (case dmn\n", " (0 '(s0 s1 s2 s3 s4 s5))\n", " (1 '(s01 s02 s12 s23 s34 s35 s45))\n", " (2 '(s345))\n", " (otherwise nil))))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For the base point, we may choose any vertex:" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "S0" ] }, "execution_count": 20, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def diabolo-bspn 's0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The lisp function for the differential homomorphism, also called boundary homomorphism, computes the boundary of each generator, in this case, according to the classical (simplicial) rule:\n", "\n", "$$ {\\bf d}[{s_0s_1\\ldots s_n}] = \\sum_{i=0}^n{(-1)^is_0s_1\\ldots\\widehat{s_i}\\ldots s_n}.$$\n", "\n", "It must be noted that our differential uses a predefined choice for the order of the vertices." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "#" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def diabolo-pure-dffr\n", " #'(lambda (dmn gnr)\n", " (unless (<= 0 dmn 2)\n", " (error \"Incorrect dimension for diabolo-dp.\"))\n", " (case dmn\n", " (0 (cmbn -1)) ; Note the null combination of degree -1\n", " (1 (case gnr\n", " (s01 (cmbn 0 -1 's0 1 's1))\n", " (s02 (cmbn 0 -1 's0 1 's2))\n", " (s12 (cmbn 0 -1 's1 1 's2))\n", " (s23 (cmbn 0 -1 's2 1 's3))\n", " (s34 (cmbn 0 -1 's3 1 's4))\n", " (s35 (cmbn 0 -1 's3 1 's5))\n", " (s45 (cmbn 0 -1 's4 1 's5))))\n", " (2 (case gnr\n", " (s345 (cmbn 1 1 's34 -1 's35 1 's45))))\n", " (otherwise (error \"Bad generator for complex diabolo\")))))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The strategy is by generator and the comment recalls the name of the problem:" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ ":GNRT" ] }, "execution_count": 22, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def diabolo-strt :GNRT)" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "(DIABOLO-FOR-EXAMPLE)" ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def diabolo-orgn '(diabolo-for-example))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The effective call to `build-chcm` is now reduced to:" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[K1 Chain-Complex]" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def diabolo (build-chcm :cmpr diabolo-cmpr :basis diabolo-basis\n", " :bsgn diabolo-bspn :intr-dffr diabolo-pure-dffr\n", " :strt diabolo-strt :orgn diabolo-orgn))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The value of the symbol `diabolo` is the `CHAIN-COMPLEX` instance which is here the first created `Kenzo` object. The string `[K1 Chain-Complex]` is printed by the printing method associated to the class.\n", "\n", "### Simple functions handling chain complexes\n", "\n", "`(cat-init)` *[Function]*\n", "> Clear among others, the list `*chcm-list*`, list of user created chain complexes and reset the global counter to 1. The existing objects and in particular here the chain complexes, are not destroyed but they will not enter any more in account during the search process for duplicated objects. This remark is general for the other types of objects saved in specific lists. \n", "\n", "`(chcm` *n*`)` *[Function]*\n", "> Return from the list `*chcm-list*` the chain complex instance whose the Kenzo identification is `n`; if it does not exist, return `NIL`.\n", "\n", "`(cmpr` *object item1 item2*`)` *[Macro]*\n", "> Apply the comparison function associated to the chain complex `object` to the two generators `item1` and `item2`.\n", "\n", "`(basis` *object n*`)` *[Macro]*\n", "> With only one argument (`object`), get the function attached to the slot `basis` of the chain complex object. With two arguments, get the distinguished basis of the group of degree `n` in the chain complex `object`. If the chain complex is locally effective, this function returns an error because, in some degrees, the corresponding set of generators is probably infinite.\n", "\n", "`(dffr` *chcm* `&rest)` *[Macro]* \n", "> Versatile macro to apply the differential morphism of the chain complex `chcm` either to a combination or a generator with a degree, respectively `(dffr chcm cmbn)` or `(dffr chcm degr gnrt)`. The macro `?`, described later, may be used for the same purpose.\n", "\n", "`(z-chcm)` *[Function]* \n", "> Build the unit chain complex (see hereafter).\n", "\n", "#### Examples\n", "\n", "Let us apply some accessors functions and the simple functions above to the chain complex `diabolo`. First, we see that the list `*chcm-list*` contains only one element, namely the chain complex just created." ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "([K1 Chain-Complex])" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "*chcm-list*" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[K1 Chain-Complex]" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(chcm 1)" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "(DIABOLO-FOR-EXAMPLE)" ] }, "execution_count": 27, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(orgn diabolo)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 28, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(idnm diabolo)" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "(S0 S1 S2 S3 S4 S5)" ] }, "execution_count": 29, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(basis diabolo 0)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "(S01 S02 S12 S23 S34 S35 S45)" ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(basis diabolo 1)" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "(S345)" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(basis diabolo 2)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "NIL" ] }, "execution_count": 32, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(basis diabolo 10)" ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 1}\n", "<1 * S34>\n", "<-1 * S35>\n", "<1 * S45>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 33, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(dffr diabolo 2 's345)" ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 0}\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 34, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(dffr diabolo *)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### An important trivial case: the unit chain complex, $\\mathbb{Z}$\n", "\n", "The unit chain complex, has a unique non null component, namely a $\\mathbb{Z}$-module of degree 0 generated by a unique generator, called here `:Z-gnrt`. It is defined by the following call to `build-chcm`:" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[K3 Chain-Complex]" ] }, "execution_count": 35, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def ZCC\n", " (the chain-complex\n", " (build-chcm\n", " :cmpr #'(lambda (gnrt1 gnrt2)\n", " (declare (ignore gnrt1 gnrt2))\n", " (the cmpr :equal))\n", " :basis #'(lambda (n)\n", " (the list\n", " (if (zerop n) '(:Z-gnrt) +empty-list+)))\n", " :bsgn :Z-gnrt\n", " :intr-dffr #'(lambda (cmbn)\n", " (the cmbn (zero-cmbn (1- (cmbn-degr cmbn)))))\n", " :strt :cmbn\n", " :orgn '(zcc-constant))))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this definition,\n", "\n", "1. The `:cmpr` keyword argument is a function returning `:equal` on any pair on generators (because there is a unique generator!).\n", "2. The `:basis` keyword argument is a lisp function returning the null basis (the constant `+empty-list+ = ()`) for $p \\not= 0$ and the list `(:Z-gnrt)`, for $p=0$.\n", "3. The base generator is of course `Z-gnrt`.\n", "4. The `:intr-dffr` keyword argument is a lisp function defining the differential which, to any combination of degre $p$ of the chain complex, returns a *null combination* of degree $p-1$. This simple lisp function is also provided in `Kenzo` and is called `#'zero-intr-dffr`.\n", "5. The `:strt` keyword argument is the combination strategy (`:cmbn`).\n", "6. The `:orgn` keyword argument is the comment list `(zcc-constant)`.\n", "\n", "In the program `Kenzo`, the chain complex instance `ZCC` may be built, when needed, by the lisp statement: `(z-chcm)`. This statement may be used freely each time one needs this chain complex, since the system recognizes if it has already been created.\n", "\n", "#### The chain complex `circle`\n", "\n", "On the model of the previous chain complex, one may define a function `circle` for building the chain complex associated to the standard model of the circle as a simplicial set." ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "MY-CIRCLE" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(defun MY-CIRCLE ()\n", " (the chain-complex\n", " (build-chcm\n", " :cmpr #'(lambda (gnrt1 gnrt2)\n", " (declare (ignore gnrt1 gnrt2))\n", " (the cmpr :equal))\n", " :basis #'(lambda (dmns)\n", " (the list\n", " (case dmns (0 '(*)) (1 '(s1))\n", " (otherwise +empty-list+))))\n", " :bsgn '*\n", " :intr-dffr #'zero-intr-dffr\n", " :strt :cmbn\n", " :orgn '(circle))))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Morphisms\n", "\n", "Algebraic Topology uses morphisms between chain complexes and the differential homomorphism may be considered as a particular case of morphism. A morphism is implemented in the system as an instance of the class `MORPHISM`, whose definition is:\n", "\n", "```commonlisp\n", "(DEFCLASS MORPHISM ()\n", " ;; SOuRCe\n", " ((sorc :type chain-complex :initarg :sorc :reader sorc)\n", " ;; TaRGeT\n", " (trgt :type chain-complex :initarg :trgt :reader trgt)\n", " ;; DEGRee\n", " (degr :type fixnum :initarg :degr :reader degr)\n", " ;; INTeRnal\n", " (intr :type intr-mrph :initarg :intr :reader intr)\n", " ;; STRaTegy\n", " (strt :type strt :initarg :strt :reader strt)\n", " ;; CaLl NuMber\n", " (???-clnm :type fixnum :initform 0 :accessor ???-clnm)\n", " (?-clnm :type fixnum :initform 0 :accessor ?-clnm)\n", " ;; ReSuLTS\n", " (rslts :type simple-vector :reader rslts)\n", " ;; IDentification NuMber\n", " (idnm :type fixnum :initform (incf *idnm-counter*) :reader idnm)\n", " ;; ORiGiN\n", " (orgn :type list :initarg :orgn :reader orgn)))\n", "```\n", "\n", "This class has 10 slots:\n", "\n", "1. `sorc`, an object of the class `CHAIN-COMPLEX`, namely the *source* chain complex of this morphism.\n", "2. `trgt`, an object of the class `CHAIN-COMPLEX`, namely the *target* chain complex of this morphism.\n", "3. `degr`, an integer, the degree of the morphism. A morphism is supposed to associate to any element of degree $k$ of the source chain complex, an element of degree $k + degr$ of the target chain complex. For instance, a differential homomorphism is of degree -1.\n", "4. `intr`, a **pure lisp function** implementing the mathematical algorithm of the morphism and taking in account the strategy (`strt`).\n", "5. `strt`, one of the two symbols `:gnrt`, `:cmbn`. What has already been said about the strategy of the differential morphism is generalized to any morphism: according to the value of the argument, `:gnrt` or `:cmbn`, the lisp function attached to the keyword just above, works respectively with 2 arguments (a degree and a generator) or only one (a combination) and must return a combination, image of the generator or the combination argument. \n", "6. `???-clnm`, an integer updated by the system for statistics (number of times the morphism has been called on combinations - Internal use)\n", "7. `?-clnm`, analogous to the previous field, but for generators.\n", "8. `rslts`, an array of dimension `*maxdim*` reserved by the system to save computed results in order to avoid re-computing, for instance, the differential of the same generator. - Internal use.\n", "9. `idnm`, an integer, number plate for this object. This is generated by the system.\n", "10. `orgn`, a relevant comment list.\n", "\n", "The accessors of the slots are the functions whose name appears after the specifier `:reader` or after the specifier `:accessor` in the class definition. A printing method has been associated to the class `MORPHISM` and the external representation of an instance is a string like `[Kn Morphism (degree d): Kp -> Kq]` or `[Kn Cohomology-Class (degree d)]` when the chain complex target is the unit $\\mathbb{Z}$. In this string, `n` is the number plate of the `Kenzo` object, `d` is the degree of the morphism, `Kp` is the `Kenzo` object source of the morphism and `Kq` the target. In all the examples of this manual, the last part of the string will not be necessarily printed." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### The function `build-mprh`\n", "\n", "To facilitate the construction of instances of the class `MORPHISM` and to free the user to call the standard constructor `make-instance`, the software provides the function `build-mrph`\n", "\n", "`build-mrph`\n", "> `:sorc` *sorc* `:trgt` *trgt* `:degr` *degr* `:intr` *intr* `:strt` *strt* `:orgn` *orgn*\n", "\n", "\n", "defined with keyword parameters. The returned value is an instance of the class `MORPHISM`. The keyword arguments of `build-mrph` are:\n", "\n", "- *sorc*, the source object, a `CHAIN-COMPLEX` type object.\n", "- *trgt*, the target object, a `CHAIN-COMPLEX` type object.\n", "- *degr*, the degree of the morphism, an integer.\n", "- *intr*, the pure lisp function defining the effective mapping.\n", "- *strt*, the strategy, i.e. `:gnrt` or `:cmbn`.\n", "- *orgn*, a relevant comment list.\n", "\n", "After a call to `build-mrph`, the morphism instance is added to a list of previously constructed ones (`*mrph-list*`).\n", "\n", "#### The differential homomorphism in a chain complex instance\n", "\n", "In a chain complex instance, the differential homomorphism is defined as a morphism with identical source and target, and degree -1. The user must know that the function `build-chcm` calls internally the function `build-mrph` and passes it the keyword argument `intr-dffr`. The function `build-mrph` builds the morphism instance which will be then inserted into the slot `:dffr` of the chain complex instance to be constructed.\n", "\n", "##### Example\n", "\n", "Let us define respectively a *zero--morphism* of degree -1 and an *identity-morphism* (degree 0) between the *unit chain complex* `ZCC` and itself." ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "---done---" ] }, { "data": { "text/plain": [ "NIL" ] }, "execution_count": 37, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(cat-init)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[K1 Chain-Complex]" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def ZCC (z-chcm))" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[K3 Cohomology-Class on K1 of degree 1]" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def zero-morphism (build-mrph :sorc ZCC\n", " :trgt ZCC\n", " :degr -1\n", " :intr #'(lambda (comb)\n", " (cmbn (1- (degr comb))))\n", " :strt :cmbn\n", " :orgn '(zero morphism on ZCC)))" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[K4 Cohomology-Class on K1 of degree 0]" ] }, "execution_count": 40, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def id-morphism (build-mrph :sorc ZCC\n", " :trgt ZCC\n", " :degr 0\n", " :intr #'identity\n", " :strt :cmbn\n", " :orgn '(identity morphism on ZCC)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "On the first morphism, we see that the `:intr` keyword argument is a lisp function taking any combination of degree `p` of the unit chain complex and generating a null combination of degree `p-1` of the same chain complex. The second morphism uses the lisp function `identity`.\n", "\n", "### Applying morphisms\n", "\n", "To apply an already constructed morphism on a generator, one uses the function `gnrt-?`, the usage of which is described hereafter. On a similar way, to apply a morphism on a combination, one uses the function `cmbn-?`. It is very important to note that these functions can be used with the underlying morphism, **whatever strategy had been decided\n", "at creation time by the user for the morphism mapping**. In other words, a morphism defined with the strategy `:gnrt` (resp. `:cmbn`) may be applied to a combination (resp. generator). These functions are mainly used inside the software. For a practical usage, one may use the versatile macro `?`.\n", "\n", "`(gnrt-? mrph degr gnrt)` *[Function]*\n", "> Apply the morphism `mrph` on the generator `gnrt` of degree `degr`.\n", "\n", "`(cmbn-? mrph cmbn)` *[Function]*\n", "> Apply the morphism `mrph` on the combination `cmbn`.\n", "\n", "`(? &rest args)` *[Macro]*\n", "> Versatile macro for applying a morphism in both cases above, i.e. indifferently as `(? mrph degr gnrt)` or `(? mrph cmbn)`. If the first argument is a chain complex object, as in `(? chcm degr gnrt)` or in `(? chcm cmbn)`, then the differential morphism of the chain complex `chcm` is applied to the arguments.\n", "\n", "### Functions defining morphisms\n", "\n", "The following functions are useful to work on morphisms, particularly to define new morphisms from already defined ones.\n", "\n", "`(cat-init)` *[Function]*\n", "> Clear in particular `*mrph-list*`, the list of user created morphisms and reset the global counter to 1.\n", "\n", "`(mrph` *n*`)` *[Function]*\n", "> Retrieve in the list `*mrph-list*` the morphism instance whose identification is `n`. If it does not exist, return `NIL`. \n", "\n", "`(zero-mrph` *chcm1* `&optional (`*chcm2 chcm1*`) (`*degr* `0))` *[Function]*\n", "> Construct the null morphism between the chain complexes `chcm1` and `chcm2` of degree `degr`. The parameters `chcm2` and `degr` are optional and if omitted the default values (respectively `chcm1` and 0) are taken.\n", "\n", "`(idnt-mrph` *chcm*`)` *[Function]*\n", "> Construct the identity morphism (degree 0) between the chain complex `chcm` and itself.\n", "\n", "`(opps` *mrph*`)` *[Function]*\n", "> Construct the opposite morphism of `mrph`, i.e. $-1 \\times mrph$; such a function, as well as the following ones, installs the right source and target.\n", "\n", "`(cmps` *mrph1 mrph2* `&optional` *strt*`)` *[Method]*\n", "> Construct the composite of the morphisms, i.e. $mrph_1 \\circ\\, mrph_2$. Of course, the target of $mrph_2$ must be the same as the source of $mrph_1$, otherwise the system signals an error. The new instance inherits its source slot from $mrph_2$ and its target slot from $mrph_1$. This function optimizes the compositions in which appear zero morphisms or identity morphisms. Unless the user gives explicitly the strategy (`strt`), the resulting strategy is determined by the respective strategy of the two morphisms.\n", "\n", "`(cmps` *chcm1 chcm2* `&optional` *strt*`)` *[Method]*\n", "Construct the composite of the differential of the chain complexes `chcm1` and `chcm2`, i.e. $d_1 \\circ d_2$.\n", "\n", "`(cmps` *chcm1 mrph2* `&optional` *strt*`)` *[Method]*\n", "> Construct the composite of the differential of the chain complex `chcm1` and the morphism `mrph2`, i.e. $d_1 \\circ mrph_2$.\n", "\n", "`(cmps` *mrph1 chcm2* `&optional` *strt*`)` *[Method]*\n", "> Construct the composite of the morphism `mrph1` and the differential of the chain complex `chcm2`, i.e. $mrph_1 \\circ d_2$.\n", "\n", "`(i-cmps` *mrph1 mrph2 ... mrphk*`)` *[Macro]*\n", "> Construct the composite of the morphisms, i.e. $mrph_1 \\circ\\, mrph2 \\circ\\, \\cdots\\, \\circ\\, mrph_k$. Of course, the target of $mrph_i$ must be the same as the source of $mrph_{i-1}$, otherwise the system signals an error. The new instance inherits its source slot from $mrph_k$ and its target slot from $mrph_1$. This function optimizes the compositions in which appear zero morphisms or identity morphisms.\n", "\n", "`(add` *mrph1 mrph2* `&optional` *strt*`)` *[Method]*\n", "> Construct a morphism, sum of the morphisms $mrph_1$ and $mrph_2$. The result of the mapping of the morphism sum is the sum of the results of the mappings of the morphisms. The respective definitions of the morphisms $mrph_1$ and $mrph_2$ must be coherent, in particular they must have the same source, target and degree. The user may impose its strategy, otherwise it is defined in the program according to the respective strategy of the arguments.\n", "\n", "`(i-add` *mrph1 mrph2 ... mrphk*`)` *[Macro]*\n", "> Construct a morphism, sum of the morphism $mrph_1$, $mrph_2$, $\\ldots$, $mrph_k$. The result of the mapping of the morphism sum is the sum of the results of the mappings of the $mrph_i$. The respective definitions of $mrph_i$ must be coherent, in particular they must have the same source, target and degree. The macro `i-add` has an undefinite number of arguments. With one argument, the macro returns that argument.\n", "\n", "`(sbtr` *mrph1 mrph2* `&optional` *strt*`)` *[Method]*\n", "> Construct a morphism, difference of the morphisms $mrph_1$ and $mrph_2$. The conditions of validity are similar to those of the method `add`.\n", "\n", "`(i-sbtr` *mrph1 mrph2 ... mrphk*`)` *[Macro]*\n", "> Construct a morphism, difference of the morphisms $mrph_1$, $mrph_2$, $\\ldots$, $mrph_k$, in the sense $mrph_1 - mrph_2 - \\cdots - mrph_k$. The conditions of validity are similar to those of the method `add` for the morphisms. The macro `i-sbtr` must have at least 2 arguments.\n", "\n", "`(change-sorc-trgt` *mrph* `&key` *sorc trgt*`)` *[Function]*\n", "> Build from the morphism `mrph` a new morphism inheriting from `mrph` the slots `:degr` (degree), `:intr` (mapping) and `:strt` (strategy). The source and target slots of this new morphism are given by the key parameters `sorc` and `trgt`. If any key parameter is omitted, the corresponding slot is inherited from `mrph` (default value). This function is most often used when the old and new sources and/or targets are chain complexes with the same underlying graded modules, but with different differentials. Important to have this tool when handling perturbations of differentials.\n", "\n", "`(dstr-change-sorc-trgt` *mrph* `&key` *sorc trgt*`)` *[Function]*\n", "> Modify **destructively** the morphism `mrph`. The source and target slots of the first argument are replaced respectively by the key parameters `sorc` and `trgt`.\n", "\n", "`(add` *chcm perturbation* `&optional` *strt*`)` *[Method]*\n", "> Create from the chain complex `chcm` a new chain complex inheriting from `chcm` the slots `cmpr` and `basis`. The boundary morphism attached to this new chain complex is the sum of the boundary morphism $d$ of `chcm` (slot `dffr`) and a perturbation morphism $\\delta$ represented by the `MORPHISM` instance `perturbation`. Of course, the new boundary operator must satisfy $(d+\\delta)\\circ (d+\\delta)=0$.\n", "\n", "#### Examples\n", "\n", "In the following examples, we first construct a chain complex instance `ccn` where the groups $C_p$ are freely generated by numerical basis taken formally. These basis are sets of 10 numbers or *decades* produced by the fonction `" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def ccn-boundary #'(lambda (dgr gnr)\n", " (if (evenp (+ dgr gnr))\n", " (cmbn (1- dgr) 1 (- gnr 10))\n", " (cmbn (1- dgr)))))" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[K5 Chain-Complex]" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def ccn (build-chcm :cmpr #'f-cmpr\n", " :basis #'(lambda (n) ( K5]" ] }, "execution_count": 43, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def upper-shift (build-mrph\n", " :sorc ccn :trgt ccn :strt :gnrt :degr +1\n", " :intr #'(lambda (d gn) (cmbn (1+ d) 1 (+ gn 10)))\n", " :orgn '(ccn shift +10)))" ] }, { "cell_type": "code", "execution_count": 44, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[K8 Morphism (degree -1): K5 -> K5]" ] }, "execution_count": 44, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def lower-shift (build-mrph\n", " :sorc ccn :trgt ccn :strt :gnrt :degr -1\n", " :intr #'(lambda (d gn) (cmbn (1- d) 1 (- gn 10)))\n", " :orgn '(ccn shift -10)))" ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 1}\n", "<1 * 12>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(? ccn 2 22)" ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 0}\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(? ccn *) ;(* means the result of the previous command)" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 5}\n", "<1 * 50>\n", "<5 * 55>\n", "<9 * 59>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def combn (cmbn 5 1 50 5 55 9 59))" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 4}\n", "<5 * 45>\n", "<9 * 49>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(? ccn combn)" ] }, { "cell_type": "code", "execution_count": 49, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 3}\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(? ccn *)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then, let us test the morphisms on generators and combinations." ] }, { "cell_type": "code", "execution_count": 50, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 1}\n", "<1 * 16>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(? upper-shift 0 6)" ] }, { "cell_type": "code", "execution_count": 51, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 4}\n", "<1 * 41>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(? lower-shift 5 51)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We may iterate the mapping upon the previous result (symbol \\*). Note that now, though `lower-shift` has been constructed with \n", "the strategy `:gnrt`, its works also on a combination." ] }, { "cell_type": "code", "execution_count": 52, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 3}\n", "<1 * 31>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(? lower-shift *)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us construct new morphisms from `upper-shift` and `lower-shift`. The tests are made upon the degree 1 combination $1*10 + 2*11 + 3*12 +4*13$." ] }, { "cell_type": "code", "execution_count": 53, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 1}\n", "<1 * 10>\n", "<2 * 11>\n", "<3 * 12>\n", "<4 * 13>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 53, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def comb1 (cmbn 1 1 10 2 11 3 12 4 13))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The composition of the two morphisms must be an identity operation. The degree of `identity?` is in the `degr` slot of the morphism object instance and may be read by the function `degr`:" ] }, { "cell_type": "code", "execution_count": 54, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[K9 Morphism (degree 0): K5 -> K5]" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def identity? (cmps upper-shift lower-shift))" ] }, { "cell_type": "code", "execution_count": 55, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "0" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(degr identity?)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We see now that `identity?` applied on `comb1` returns a combination mathematically equal to `comb1`. No simple lisp comparison can prove this, nevertheless, their mathematical difference is the null combination, as shown by a call to the function `2cmbn-sbtr` applied to two combinations. Note that the function `2cmbn-sbtr` needs the comparison function of the chain complex `ccn`." ] }, { "cell_type": "code", "execution_count": 56, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 1}\n", "<1 * 10>\n", "<2 * 11>\n", "<3 * 12>\n", "<4 * 13>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(? identity? comb1)" ] }, { "cell_type": "code", "execution_count": 57, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 1}\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(2cmbn-sbtr (cmpr ccn) comb1 *)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We may compose `upper-shift` with itself:" ] }, { "cell_type": "code", "execution_count": 58, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[K10 Morphism (degree 2): K5 -> K5]" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def upper-shift2 (cmps upper-shift upper-shift))" ] }, { "cell_type": "code", "execution_count": 59, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(degr upper-shift2)" ] }, { "cell_type": "code", "execution_count": 60, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 3}\n", "<1 * 30>\n", "<2 * 31>\n", "<3 * 32>\n", "<4 * 33>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(? upper-shift2 comb1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Adding `upper-shift` with itself gives a very different result:" ] }, { "cell_type": "code", "execution_count": 61, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[K11 Morphism (degree 1): K5 -> K5]" ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def twice-up-shift (add upper-shift upper-shift))" ] }, { "cell_type": "code", "execution_count": 62, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "1" ] }, "execution_count": 62, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(degr twice-up-shift)" ] }, { "cell_type": "code", "execution_count": 63, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 2}\n", "<2 * 20>\n", "<4 * 21>\n", "<6 * 22>\n", "<8 * 23>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 63, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(? twice-up-shift comb1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let us compose `upper-shift` and the differential in both ways. Recall that the differential is a morphism structure, and may be obtained from the `dffr` slot of the chain complex `ccn` by the reader accessor function `dffr1`. This morphism has been built by `build-chcm` from the lisp function `ccn-boundary`. One can see that the operators do not commute; in other words, `upper-shift` is not a chain complex morphism." ] }, { "cell_type": "code", "execution_count": 64, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[K12 Morphism (degree 0): K5 -> K5]" ] }, "execution_count": 64, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def up-d (cmps upper-shift (dffr1 ccn)))" ] }, { "cell_type": "code", "execution_count": 65, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[K13 Morphism (degree 0): K5 -> K5]" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def d-up (cmps (dffr1 ccn) upper-shift))" ] }, { "cell_type": "code", "execution_count": 66, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 1}\n", "<1 * 11>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(? up-d 1 11)" ] }, { "cell_type": "code", "execution_count": 67, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 1}\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 67, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(? d-up 1 11)" ] }, { "cell_type": "code", "execution_count": 68, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 1}\n", "<1 * 10>\n", "<2 * 11>\n", "<3 * 12>\n", "<4 * 13>\n", "<5 * 14>\n", "<6 * 15>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 68, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(def comb3 (cmbn 1 1 10 2 11 3 12 4 13 5 14 6 15))" ] }, { "cell_type": "code", "execution_count": 69, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 1}\n", "<2 * 11>\n", "<4 * 13>\n", "<6 * 15>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 69, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(? up-d comb3)" ] }, { "cell_type": "code", "execution_count": 70, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "\n", "----------------------------------------------------------------------{CMBN 1}\n", "<1 * 10>\n", "<3 * 12>\n", "<5 * 14>\n", "------------------------------------------------------------------------------\n" ] }, "execution_count": 70, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(? d-up comb3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Accessing `Kenzo` objects\n", "\n", "Up to now, we have seen two kinds of `Kenzo` objects stored in specific lists and retrievable by a number, namely the chain complexes and the morphisms. The retrieval functions are specific to the object: `chcm` for a chain complex, `mrph` for a morphism. The same scheme will be applied for others kinds of objects: reductions, homotopy equivalences, \n", "coalgebras, algebras, simplicial morphisms, etc., each having its specific list. But, in fact the numbering is independent\n", "of the type of the object and is incremented each time an object is created. Three general functions are at the disposal of the user to get information about the `n`-th `Kenzo` object: `K`, `KD`, and `KD2`. They may be useful for debugging purpose.\n", "\n", "`(k` *n*`)` *[Function]*\n", "> Get the `n`-th `Kenzo` object.\n", "\n", "`(kd` *n*`)` *[Function]*\n", "> Give the type of the `Kenzo` objet number `n` and print the comment list (slot `:orgn`) of the object.\n", "\n", "`(kd2` *n*`)` *[Function]*\n", "> Give the type of the `Kenzo` objet number `n`, print the comment list (slot `:orgn`) of the object and recursively, give the same kind of informations about all the `Kenzo` objects of the same type in relation with this `n`-th object. Return the list of numbers of all those objects. See in the following example, the case of composition of morphisms.\n", "\n", "#### Examples" ] }, { "cell_type": "code", "execution_count": 71, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[K1 Chain-Complex]" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(k 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Function `KD`" ] }, { "cell_type": "code", "execution_count": 72, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Object: [K1 Chain-Complex]\n", " Origin: (Z-CHCM)\n", "\n" ] }, { "data": { "text/plain": [ "NIL" ] }, "execution_count": 72, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(kd 1)" ] }, { "cell_type": "code", "execution_count": 73, "metadata": { "scrolled": false }, "outputs": [ { "data": { "text/plain": [ "[K3 Cohomology-Class on K1 of degree 1]" ] }, "execution_count": 73, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(k 3)" ] }, { "cell_type": "code", "execution_count": 74, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Object: [K3 Cohomology-Class on K1 of degree 1]\n", " Origin: (ZERO MORPHISM ON ZCC)\n", "\n" ] }, { "data": { "text/plain": [ "NIL" ] }, "execution_count": 74, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(kd 3)" ] }, { "cell_type": "code", "execution_count": 75, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Object: [K8 Morphism (degree -1): K5 -> K5]\n", " Origin: (CCN SHIFT -10)\n", "\n" ] }, { "data": { "text/plain": [ "NIL" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(kd 8)" ] }, { "cell_type": "code", "execution_count": 76, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Object: [K5 Chain-Complex]\n", " Origin: (CCN)\n", "\n" ] }, { "data": { "text/plain": [ "NIL" ] }, "execution_count": 76, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(kd 5)" ] }, { "cell_type": "code", "execution_count": 77, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Object: [K9 Morphism (degree 0): K5 -> K5]\n", " Origin: (2MRPH-CMPS [K7 Morphism (degree 1): K5 -> K5] [K8 Morphism (degree -1): K5 -> K5] GNRT)\n", "\n" ] }, { "data": { "text/plain": [ "NIL" ] }, "execution_count": 77, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(kd 9)" ] }, { "cell_type": "code", "execution_count": 78, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Object: [K9 Morphism (degree 0): K5 -> K5]\n", " Origin: (2MRPH-CMPS [K7 Morphism (degree 1): K5 -> K5] [K8 Morphism (degree -1): K5 -> K5] GNRT)\n", "\n", "\n", "Object: [K8 Morphism (degree -1): K5 -> K5]\n", " Origin: (CCN SHIFT -10)\n", "\n", "\n", "Object: [K7 Morphism (degree 1): K5 -> K5]\n", " Origin: (CCN SHIFT 10)\n", "\n" ] }, { "data": { "text/plain": [ "(9 8 7)" ] }, "execution_count": 78, "metadata": {}, "output_type": "execute_result" } ], "source": [ "(kd2 9)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Lisp files concerned in this chapter\n", "\n", "`combinations.lisp`, `chain-complexes.lisp`, `chcm-elementary-op.lisp`.\n", "\n", "[`classes.lisp`, `macros.lisp`, `various.lisp`]." ] } ], "metadata": { "kernelspec": { "display_name": "SBCL Lisp", "language": "lisp", "name": "lisp" }, "language_info": { "codemirror_mode": "text/x-common-lisp", "mimetype": "text/x-common-lisp", "name": "common-lisp", "pygments_lexer": "common-lisp", "version": "X3J13" } }, "nbformat": 4, "nbformat_minor": 1 }