{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 189,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "from sage.categories.category_with_axiom import CategoryWithAxiom\n"
     ]
    }
   ],
   "source": [
    "import_statements(\"CategoryWithAxiom\")\n",
    "from sage.structure.element import Element\n",
    "from sage.categories.category_with_axiom import CategoryWithAxiom\n",
    "from sage.categories.morphism import SetMorphism"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 190,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "class Stroumphs(Category):\n",
    "    def super_categories(self):\n",
    "        return [Sets()]\n",
    "    class ParentMethods:\n",
    "        def party(self):\n",
    "            print \"party time!\"\n",
    "    class ElementMethods:\n",
    "        def sing(self):\n",
    "            print \"I sing!\"\n",
    "    class Finite(CategoryWithAxiom):\n",
    "        class ParentMethods:\n",
    "            def party(self):\n",
    "                print \"party time\"\n",
    "                for stroumph in self:\n",
    "                    stroumph.sing()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 191,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<unbound method Stroumphs.element_class.sing>"
      ]
     },
     "execution_count": 191,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Stroumphs().element_class.sing"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 192,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 192,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "F2(11)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 193,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "class Trivial(UniqueRepresentation, Parent):\n",
    "    def __init__(self):\n",
    "        Parent.__init__(self, category=Stroumphs() & Groups() & EnumeratedSets().Finite())\n",
    "\n",
    "    def semigroup_generators(self):\n",
    "        return Family([self.an_element()])\n",
    "    gens = semigroup_generators\n",
    "        \n",
    "    def an_element(self):\n",
    "        return self(\"the unique element of Trivial\")\n",
    "    \n",
    "    def one(self):\n",
    "        return self.an_element()\n",
    "    \n",
    "    def __iter__(self):\n",
    "        yield self.an_element()\n",
    "    \n",
    "    class Element(ElementWrapper):\n",
    "        def _mul_(self, other):\n",
    "            return self\n",
    "        \n",
    "        def __invert__(self):\n",
    "            return self"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 194,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "T = Trivial()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 195,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "phi = SetMorphism(Hom(T, GF(2)), lambda x: GF(2).one())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 201,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 201,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "phi(T.an_element())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 202,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "phi.register_as_coercion()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 204,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 204,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "T.an_element() * GF(2).one()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 185,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "party time\n",
      "I sing!\n"
     ]
    }
   ],
   "source": [
    "T.party()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 167,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "I sing!\n"
     ]
    }
   ],
   "source": [
    "stroumph = T.an_element()\n",
    "stroumph.__class__\n",
    "stroumph.sing()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 160,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<class '__main__.Trivial_with_category.element_class'>,\n",
       " <class '__main__.Trivial.Element'>,\n",
       " <type 'sage.structure.element_wrapper.ElementWrapper'>,\n",
       " <type 'sage.structure.element.Element'>,\n",
       " <type 'sage.structure.sage_object.SageObject'>,\n",
       " <class 'sage.categories.category.JoinCategory.element_class'>,\n",
       " <class 'sage.categories.finite_groups.FiniteGroups.element_class'>,\n",
       " <class 'sage.categories.finite_monoids.FiniteMonoids.element_class'>,\n",
       " <class 'sage.categories.groups.Groups.element_class'>,\n",
       " <class 'sage.categories.monoids.Monoids.element_class'>,\n",
       " <class 'sage.categories.finite_semigroups.FiniteSemigroups.element_class'>,\n",
       " <class 'sage.categories.semigroups.Semigroups.element_class'>,\n",
       " <class 'sage.categories.magmas.Magmas.Unital.Inverse.element_class'>,\n",
       " <class 'sage.categories.magmas.Magmas.Unital.element_class'>,\n",
       " <class 'sage.categories.magmas.Magmas.element_class'>,\n",
       " <class 'sage.categories.finite_enumerated_sets.FiniteEnumeratedSets.element_class'>,\n",
       " <class 'sage.categories.enumerated_sets.EnumeratedSets.element_class'>,\n",
       " <class 'sage.categories.finite_sets.FiniteSets.element_class'>,\n",
       " <class '__main__.Stroumphs.element_class'>,\n",
       " <class 'sage.categories.sets_cat.Sets.element_class'>,\n",
       " <class 'sage.categories.sets_with_partial_maps.SetsWithPartialMaps.element_class'>,\n",
       " <class 'sage.categories.objects.Objects.element_class'>,\n",
       " <type 'object'>]"
      ]
     },
     "execution_count": 160,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "stroumph.__class__.mro()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 87,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'the unique element of Trivial'"
      ]
     },
     "execution_count": 87,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x = T.an_element(); x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 88,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'the unique element of Trivial'"
      ]
     },
     "execution_count": 88,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x * x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 89,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'the unique element of Trivial'"
      ]
     },
     "execution_count": 89,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x^4"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 66,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x.parent() is T"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'the unique element of Trivial'"
      ]
     },
     "execution_count": 69,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "T.random_element()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 68,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 68,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "T.cardinality()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['the unique element of Trivial']"
      ]
     },
     "execution_count": 67,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "list(T)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 151,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "running ._test_an_element() . . . pass\n",
      "running ._test_associativity() . . . pass\n",
      "running ._test_category() . . . pass\n",
      "running ._test_elements() . . .\n",
      "  Running the test suite of self.an_element()\n",
      "  running ._test_category() . . . pass\n",
      "  running ._test_eq() . . . pass\n",
      "  running ._test_not_implemented_methods() . . . pass\n",
      "  running ._test_pickling() . . . fail\n",
      "  Traceback (most recent call last):\n",
      "    File \"/opt/sage-git2/local/lib/python2.7/site-packages/sage/misc/sage_unittest.py\", line 282, in run\n",
      "      test_method(tester = tester)\n",
      "    File \"sage/structure/sage_object.pyx\", line 550, in sage.structure.sage_object.SageObject._test_pickling (build/cythonized/sage/structure/sage_object.c:4495)\n",
      "      tester.assertEqual(loads(dumps(self)), self)\n",
      "    File \"sage/structure/sage_object.pyx\", line 1015, in sage.structure.sage_object.dumps (build/cythonized/sage/structure/sage_object.c:11613)\n",
      "      return obj.dumps(compress)\n",
      "    File \"sage/structure/sage_object.pyx\", line 371, in sage.structure.sage_object.SageObject.dumps (build/cythonized/sage/structure/sage_object.c:3183)\n",
      "      s = cPickle.dumps(self, protocol=2)\n",
      "  PicklingError: Can't pickle <class '__main__.Stroumphs'>: it's not the same object as __main__.Stroumphs\n",
      "  ------------------------------------------------------------\n",
      "  The following tests failed: _test_pickling\n",
      "running ._test_elements_eq_reflexive() . . . pass\n",
      "running ._test_elements_eq_symmetric() . . . pass\n",
      "running ._test_elements_eq_transitive() . . . pass\n",
      "running ._test_elements_neq() . . . pass\n",
      "running ._test_enumerated_set_contains() . . . pass\n",
      "running ._test_enumerated_set_iter_cardinality() . . . pass\n",
      "running ._test_enumerated_set_iter_list() . . . pass\n",
      "running ._test_eq() . . . pass\n",
      "running ._test_inverse() . . . pass\n",
      "running ._test_not_implemented_methods() . . . pass\n",
      "running ._test_one() . . . pass\n",
      "running ._test_pickling() . . . pass\n",
      "running ._test_prod() . . . pass\n",
      "running ._test_some_elements() . . . pass\n",
      "The following tests failed: _test_elements\n"
     ]
    }
   ],
   "source": [
    "TestSuite(T).run(verbose=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "T2 = Trivial()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ZZ.an_element()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "T == T2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "True"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "T is T2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 106,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[Category of monoids, Category of inverse unital magmas]"
      ]
     },
     "execution_count": 106,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Groups().super_categories()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 107,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "frozenset({Category of unital magmas,\n",
       "           Category of magmas,\n",
       "           Category of sets with partial maps,\n",
       "           Category of sets})"
      ]
     },
     "execution_count": 107,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Groups().structure()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 108,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "frozenset({'Associative', 'Inverse', 'Unital'})"
      ]
     },
     "execution_count": 108,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "Groups().axioms()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 113,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "G = Fields().category_graph()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 114,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "G.set_latex_options(format=\"dot2tex\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 117,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "view(G, tightpage=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 118,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "C = Magmas()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 129,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "D = (C.Associative().Unital() & AdditiveMagmas().AdditiveCommutative().AdditiveAssociative().AdditiveUnital().AdditiveInverse()).Distributive()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 132,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Category of finite fields"
      ]
     },
     "execution_count": 132,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "D.Division() & Sets().Finite()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Sage 6.6.beta5",
   "language": "",
   "name": "sage_6_6_beta5"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
