Skip to content

Instantly share code, notes, and snippets.

@zitterbewegung
Last active September 18, 2018 22:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zitterbewegung/4152b322eef5ecccdcf3502e8220844b to your computer and use it in GitHub Desktop.
Save zitterbewegung/4152b322eef5ecccdcf3502e8220844b to your computer and use it in GitHub Desktop.
Partial prototype of a knot theory POW.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# A Knot theoretical Proof of Work by random table enumeration"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ways to implement the system\n",
"1. Give you a table of random knots. You give me the knot that has the least crossings.\n",
"2. Give me a table of random knots. You give me a set of knots that have x more crossings but that are ambient isotopic."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Requirement already satisfied: spherogram in /opt/sagemath-8.2/local/lib/python2.7/site-packages\n",
"Requirement already satisfied: networkx>=1.3 in /opt/sagemath-8.2/local/lib/python2.7/site-packages (from spherogram)\n",
"Requirement already satisfied: decorator in /opt/sagemath-8.2/local/lib/python2.7/site-packages (from spherogram)\n",
"Requirement already satisfied: future in /opt/sagemath-8.2/local/lib/python2.7/site-packages (from spherogram)\n",
"Requirement already satisfied: snappy_manifolds>=1.0 in /opt/sagemath-8.2/local/lib/python2.7/site-packages (from spherogram)\n",
"\u001b[33mYou are using pip version 9.0.3, however version 18.0 is available.\n",
"You should consider upgrading via the 'pip install --upgrade pip' command.\u001b[0m\n",
"Requirement already satisfied: snappy in /opt/sagemath-8.2/local/lib/python2.7/site-packages\n",
"Requirement already satisfied: plink>=2.2 in /opt/sagemath-8.2/local/lib/python2.7/site-packages (from snappy)\n",
"Requirement already satisfied: spherogram>=1.8 in /opt/sagemath-8.2/local/lib/python2.7/site-packages (from snappy)\n",
"Requirement already satisfied: FXrays>=1.3 in /opt/sagemath-8.2/local/lib/python2.7/site-packages (from snappy)\n",
"Requirement already satisfied: pypng in /opt/sagemath-8.2/local/lib/python2.7/site-packages (from snappy)\n",
"Requirement already satisfied: decorator in /opt/sagemath-8.2/local/lib/python2.7/site-packages (from snappy)\n",
"Requirement already satisfied: future in /opt/sagemath-8.2/local/lib/python2.7/site-packages (from snappy)\n",
"Requirement already satisfied: snappy_manifolds>=1.0 in /opt/sagemath-8.2/local/lib/python2.7/site-packages (from snappy)\n",
"Requirement already satisfied: networkx>=1.3 in /opt/sagemath-8.2/local/lib/python2.7/site-packages (from spherogram>=1.8->snappy)\n",
"\u001b[33mYou are using pip version 9.0.3, however version 18.0 is available.\n",
"You should consider upgrading via the 'pip install --upgrade pip' command.\u001b[0m\n",
"Requirement already satisfied: PLink in /opt/sagemath-8.2/local/lib/python2.7/site-packages\n",
"Requirement already satisfied: future in /opt/sagemath-8.2/local/lib/python2.7/site-packages (from PLink)\n",
"\u001b[33mYou are using pip version 9.0.3, however version 18.0 is available.\n",
"You should consider upgrading via the 'pip install --upgrade pip' command.\u001b[0m\n"
]
}
],
"source": [
"!pip install spherogram\n",
"!pip install snappy\n",
"!pip install PLink"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Solve Definition\n",
"=====\n",
"This is my starting point in asking you for a mosaic knot table with a set of restrictions. What I want to ask you is to give me a table with the following properties\n",
"\n",
"1. It must have at least one element with a crossing number C\n",
"1. It must have at least element with dimension of N by M\n",
"1. It must be ambient isotopic to the knot K that we send\n",
"~~1. It must have a set of operations O of cardinality On that show that it is ambient isotopic to the knot K ~~\n",
"~~~1. All operations must be unique~~\n",
"1. You must give me two tables. One table is the set of knots where you have computed the kovanov homology and the resultant knot \n",
"1. You must give me the coordinates CR of the operation on the knot itself.\n",
"1. It must follow the result specification\n",
"\n",
"\n",
"This would give us the trivial task which would be the trivial table would have only the prime knot 31. The source and target knots in the above structure would be the same. The crossing number would be three. The dimension would be four by four.\n",
"\n",
"So, now that we have established what the output should be. Now how do we tackle the generation of the problem?\n",
"\n",
" So we know that under ambient isotopy that you can get to another knot diagram given another knot diagram in a finite set of reidmeister moves. So lets generate two random links. The task then we define is given a arbitrary large table of random knots compute Kovanov Homology on each element of the table. You then send me the knots in the table that are equivalent to the unknot and the set of knots not equivalent. To allow for adjustment of the table size\n",
"\n",
"\n",
"There are three pieces to every proof of Work. We would need to know. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"TODO:\n",
" Implement set of problems we only have one challenge "
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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czoFQVFUJC1aVByEpk2TfvzRwnL58vaz79zZ9inq3Flq25ZdrQEEEwEJUQmFpKVL9w1M8+bZ7zEs50+hkG3KOG1acSCaOVPavt1+v2XL4iDUubP9XNPS3NYMAIlCQEKpbdkiTZlSHJimTbNOQ6VKdsp6y5Z23fvrBg1srgoSp7DQdqpetszO9FuyRJo1ywJRuCvYsGFxEOrcWerUiaFUAMmNgISYCQ/LTZ0qLVwoLV5swzUrVtjQjWRzmlq0IDzFUigkbdpk4WfZsj/eVqyweURh9epJxx23byBq0MBZ+QDgSQQkxN2ePfZGvWhRcWiKJjyFr82aSbVrS9WrJ+9cp99+23/4CXeFdu4s/rM1a9r3LHxr2nTfrxkmA4BDIyDBqWjDk2SThGvWtKGfWrUsNIW/PtTNZbgKhWyV4Pbt0rZtdj3Q1wf6/R07iu+vSpU/Bp+9bzVruvl7AkCQEJDgWeHwtGKFtHWrzXnauvXgt99+2/99hcNVOFTVqGETyVNTbRVWauqBb+np9tgFBTafp6DgwF/n5+8/DO0d9PZXV40axdfIr2vUkOrXLw5AdesmbycNABKFgIRAKSiwQHKwELVli/2Z/PzigHOwW0aGlJNjYSYcmg72dfXq+w86+/s6LY2wAwBeREACAACIwJohAACACAQkAACACAQkAACACAQkAACACAQkAACACAQkAACACAQkAACACAQkAACACAQkAACACAQkAACACAQkAACACAQkAACACAQkAACACAQkAACACAQkAACACAQkAACACAQkAACACAQkAACACAQkAACACP8f0UuaG0jDoJkAAAAASUVORK5CYII=\n",
"text/plain": [
"Graphics object consisting of 14 graphics primitives"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import collections, profile\n",
"import spherogram\n",
"from snappy import *\n",
" \n",
"def plot(knot):\n",
" \"\"\"Helper function to plot a knot\"\"\"\n",
" return knot.sage_link().plot()\n",
"def reid_move_one(knot):\n",
" \"\"\"Perform the first reidmeister move on a knot\"\"\"\n",
" return knot.backtrack(steps=1, prob_type_1=1,prob_type_2=0)\n",
"def reid_move_two(knot):\n",
" \"\"\"Perform the first reidmeister move on a knot\"\"\"\n",
" return knot.backtrack(steps=1, prob_type_1=0,prob_type_2=1)\n",
"K = Link('3_1')\n",
"K.sage_link().plot()"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [],
"source": [
"\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<Link L14a7689: 2 comp; 16 cross>"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": []
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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DElbtth4L/6+gbLZssW28fniC8KRH/gmIEmlIalGDenuu236/9tvswQAKmbnTun6623F2UcflW6/ncDttXBIqlHDthWaOdMGw7MEALB/8+dLfftKq1db61GvXq4rgtNp/vszapQthtWggfTJJywmifKZN89mf/z0k/Taa7YwKWJrzBjrKkhPt2U8WEwS2LehQ6UrrpBatLBnpW1b1xVBcjzNf3/69LFPn9Wr28y2t9+27hLg/9q7l5Co2jiO47/StKgspYvVWGpjSVe6KEFQLoSIEISwViFtogtBBV22LVq2KKEgkVpEBEEYQWVXiqywTXektEzNyrxiacrYtPgzHD2vyVvvm2cu3w8cHBqFZ5rznPM7z/M/zxnOjx82jbZypT1nraqKcOSV9ettgbvJk21R2NJS+34AmO5uae9eafNmO+c9ekQ4CidhG5AkWyfp4UOpqEjaulXKy7ORAWAotbXSunV2wNm+3aZoGbXwVkaGVFlpdRXbtklr1khPn3rdKsBbwaB06ZK0YIF04oR07JitJzZhgtctw0BhHZAkq2U4c0a6cUP6/NlOePv22cJZgCQ1N1utUXa2VF0tXb9uo0jjxnndMki2uN2pU9KdO/ZYkuXL7UaMjg6vWwaMvJoaacMGqbDQAtLLl9YfqI8MP2EfkELy86Vnz6QjR+xZNPPnW/Lu7va6ZfBKV5d0+LA0d6509qztG69fs2ZIuMrLk548sRsxTp+2PlxSIn375nXLgL+vqUk6cEBauNBqI8vL7W41v9/rluFXwrZIezgNDdKhQ9L581YAumuXbdOmed0yjIR37ywkl5VZSNq925aESEnxumX4t5qarA+fOyclJUk7d9r3OH261y0D/l8vXkhHj9oU2tixVgJw8KDNjiC8RWRACnn71qZSysqs+LO42A60ixczXBltAgFbcv/kSamiwpZ+KC626dbZs71uHf5UXZ3VX5SW2ne8ZYtd7CxdSh9G5AoEpNu37fx09ao0a5a0Z4893ohlayJHRAekkNZWWym5pMTqlLKzrbB70yYbzuRAG5n6+qS7d6XLl21dkMZGKSdH2rHD7vrgCix6tLfbqODx49LHj9K8eU4f5oIHkSAQkO7ds1v2L16UvnyRliyR9u+3/TghwesW4ndFRUAK6e21Yu4LF+wOgc5OJyzl59vJlcLd8NbcLF27ZqGoosKm0NLSpIICWydkxQqvW4i/qa9PunXLTjLl5VbIHQpL+flSbi7BGOGjpUV68MBGt0OhaM4c21+LiuycQ7iPXFEVkAYaKiyNGWN30Kxe7WzUPHinq8vWyamqslvyHz+W3r+393JzLRQVFNhVGAeZ2NPXJ9286fTh9nYpPl5atmxwH54xw+uWIhYEg9KbN7ZsRWirrrb30tPtOY+EougStQFpoP5+6fnzwTt2fb29N3WqlJVldxJkZTmvMzJsgTueI/VngkGprc2mxUJbQ4Pzur7ebncNBqXx421kKCfHtrVrpdRUrz8Bwkl/v90OXVkp3b9vP0NhesqUoftwZiZ9GL8nELBRoNpaC0M1NfYz9PrrVws/ixYNDunp6YSiaBQTAWkojY02NFpdPbgjtLY6vzN6tBXUJScP3iZNsvnk+Hg7wW/cKE2c6N1nGWlXrtj/X3+/jdR9/+787OmRPn2y93t6nL+Ji5NmzpR8Ppsy8/mstiQnx6ZB4+K8+zyITB8+DN2HW1qc3xk1yvprSsrwfbiw0MIUotOrV1YsnZRk+0Rvr41IDtza2iwADZSW5gRvv9+OWatWsa/EipgNSL/S3m4H2rq6f3ag0NbZaVcagYBNE9XVed3qkef320knMdFuXU1MdF6npg4OQj6f/RshCCOho8Ppw21t9GE4/H4LSQkJFnLcF7/JyTYimZlp66tRsxrbCEj/UXe3Mw8dS7KzKZZFdIjVPhyLOG7hdxCQAAAAXChfBAAAcCEgAQAAuBCQAAAAXAhIAAAALgQkAAAAFwISAACACwEJAADAhYAEAADgQkACAABwISABAAC4EJAAAABcCEgAAAAuBCQAAAAXAhIAAIALAQkAAMCFgAQAAOBCQAIAAHAhIAEAALj8BMuRkCi/dtw4AAAAAElFTkSuQmCC\n",
"text/plain": [
"Graphics object consisting of 60 graphics primitives"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"K.sage_link().plot()"
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<Link L14a7689: 2 comp; 17 cross>"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"K"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"ename": "NameError",
"evalue": "name 'K' is not defined",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-2-dafdd4c3eac5>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mcurrent_manifold\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mK\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcopy\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0mworking_copy\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0mmove_list\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0m_\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m5\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mNameError\u001b[0m: name 'K' is not defined"
]
}
],
"source": [
"current_manifold = K.copy()\n",
"working_copy = []\n",
"move_list = []\n",
"for _ in range(5):\n",
" \n",
" working_copy = current_manifold.copy()\n",
" working_copy.backtrack(steps=1)\n",
" #print(working_copy)\n",
" #print(working_copy.backtrack(steps=1))\n",
" #import pdb; pdb.set_trace()\n",
" print(working_copy)\n",
" \n",
" move_list.append(working_copy)\n",
" #working_copy = [working_copy[1], working_copy[1]]\n",
" \n",
" #print(previous_knot)\n",
"move_list"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [],
"source": [
"def compute_solution_table(current_manifold,table_size,moves_away=1):\n",
" \"\"\"Uses backtrack to create a knot table from the current manifold to process\"\"\"\n",
" #current_manifold = current_manifold.copy()\n",
" working_copy = []\n",
" move_list = []\n",
" for _ in range(table_size):\n",
" \n",
" working_copy = current_manifold.copy()\n",
" working_copy.backtrack(steps=moves_away)\n",
" #print(working_copy)\n",
" #print(working_copy.backtrack(steps=1))\n",
" #import pdb; pdb.set_trace()\n",
" print(working_copy)\n",
" \n",
" move_list.append(working_copy)\n",
" #working_copy = [working_copy[1], working_copy[1]]\n",
" #print(previous_knot)\n",
" return move_list"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 4 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n",
"<Link 3_1: 1 comp; 3 cross>\n",
"<Link 3_1: 1 comp; 5 cross>\n"
]
}
],
"source": [
"sol_table = compute_solution_table(Link('3_1'),100) #TODO Make this into unit test"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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1KGD63QAIi1YkBhB8plTTrGdbcOH291QTZvaOqWtW10nA9wKBKQvv7T1e+efL1WrZueLTZ4sde7sOh2AaGGKzcdKlrRdOCtWSP/+tzRypNSwoe12i8SiNMDLAgFp4kSpfXupb1+pcmUbaZ0yxTY3APAXptigChVsh9sff0hXXGHXljRubHe6cSwA4l0gIH31la3R691bKltWmjrVytGpp7pOB8CVihWlxERGkCDp6KOlF16wYwBOPVUaPNh27HzyCUUJ8WffPtum37mz1LOnjahOnixNm2b3GQLwt4SEyF03QkGKUQ0aSB9+aHe51aljO3fq15cef9wWdgOxKhCw9USDB9ui64svlkqVsoXX06dLZ5zBln0AOSJ13QgFKca1aWOfqOfNk848064tOfZYm4abM8d1OqDgVq2yk+UbNbINCpMnS7feKi1fbiNGZ51FMQJwqEhdN0JBihMnnWQLuNeutTeZ77+3S3E7d7YThbkMF17099/25/aUU2xUdNgwmzr+4Qdp5UrpkUesMAHAkTDFhgI56ijpnntsMfdnn9li1oEDpXr17M1m0ybXCeF3WVl2eewll9gU2uDB9uf0/feljRulUaOsJCXy6gSgACpWlHbtCv/X5SUoTpUsKZ13nu30WbBAOucc6amnbPqtRw/b/cZaJUTTokVW3uvWtemyuXOlBx6Q1qzJKUwVKrhOCSDWlCoVmWu5KEg+0LKlXda5dq303HPS/v12N1XNmrYT6OWXpfXrXadEvNm2za7/uOkmqXlzqUULK+bnnSf98osVpnvvlY45xnVSALGsZMnI7OJOCAQCgfB/WXjd5s3SF1/YG9iUKfaHq1MnqV8/e3B/VY65c20x/Jw5UuvWrtN4186dtvts6lRbA/frr7YjrVEjK+I9ethW/TJlXCcFEE8uushumPjuu/B+XQoSlJZml3qOHSt984104IAVgX79pF69bASqRAnXKd2hIB3enj1279n331spmj3bLo099lipWzcrRV272pQaAETKpZdK69bZa1E4UZBwkF27pEmTrCxNmmRvgpUr2+hSSopd59C+vb/WilCQzIED0s8/54wQ/fyz7Y6sUcOKULAUNWzIdnwA0XPFFbYx6ccfw/t1KUg4on37pNRUO5xvxgx77Nxp872tWuUUppQUW88Ur/xWkAIB2+24ZIm0eLE9L1ggzZxp69eS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\n",
"text/plain": [
"Graphics object consisting of 14 graphics primitives"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"plot(sol_table[3])"
]
},
{
"cell_type": "code",
"execution_count": 105,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<Link L14a7689: 2 comp; 18 cross>\n",
"<Link L14a7689: 2 comp; 17 cross>\n",
"<Link L14a7689: 2 comp; 18 cross>\n",
"<Link L14a7689: 2 comp; 18 cross>\n",
"<Link L14a7689: 2 comp; 19 cross>\n",
"<Link L14a7689: 2 comp; 18 cross>\n",
"<Link L14a7689: 2 comp; 19 cross>\n",
"<Link L14a7689: 2 comp; 17 cross>\n",
"<Link L14a7689: 2 comp; 17 cross>\n",
"<Link L14a7689: 2 comp; 17 cross>\n"
]
},
{
"data": {
"text/plain": [
"[<Link L14a7689: 2 comp; 18 cross>,\n",
" <Link L14a7689: 2 comp; 17 cross>,\n",
" <Link L14a7689: 2 comp; 18 cross>,\n",
" <Link L14a7689: 2 comp; 18 cross>,\n",
" <Link L14a7689: 2 comp; 19 cross>,\n",
" <Link L14a7689: 2 comp; 18 cross>,\n",
" <Link L14a7689: 2 comp; 19 cross>,\n",
" <Link L14a7689: 2 comp; 17 cross>,\n",
" <Link L14a7689: 2 comp; 17 cross>,\n",
" <Link L14a7689: 2 comp; 17 cross>]"
]
},
"execution_count": 105,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"compute_solution_table(sol_table[1],10)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"ename": "ValueError",
"evalue": "invalid input: data must be either a list or a braid",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-11-b389db0edf0d>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 8\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mmove_list\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 9\u001b[0;31m \u001b[0mmake_move_list\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mLink\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"3_1\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 10\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/opt/sagemath-8.2/local/lib/python2.7/site-packages/sage/knots/link.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, data)\u001b[0m\n\u001b[1;32m 365\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 366\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 367\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"invalid input: data must be either a list or a braid\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 368\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 369\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0marcs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpresentation\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'pd'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mValueError\u001b[0m: invalid input: data must be either a list or a braid"
]
}
],
"source": [
"#def make_move_list(table_size, problem_manifold):\n",
"# move_list = []\n",
"# current_manifold = problem_manifold.copy()\n",
"# for _ in range(table_size):\n",
"# previous_knot = current_manifold.copy()\n",
"# move_list.append(reid_move_one(current_manifold))\n",
" \n",
"# return move_list\n",
"#make_move_list(10, Link(\"3_1\"))\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Verify Solution"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"ename": "ValueError",
"evalue": "invalid input: data must be either a list or a braid",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-10-bbe6246e3f6b>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mprevious\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mitem\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnxt\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mprevious_and_next\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmake_move_list\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m10\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mLink\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"3_1\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2\u001b[0m \u001b[0;32mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Item is now\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mitem\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"next is\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mnxt\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"previous is\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mprevious\u001b[0m \u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/opt/sagemath-8.2/local/lib/python2.7/site-packages/sage/knots/link.py\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, data)\u001b[0m\n\u001b[1;32m 365\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 366\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 367\u001b[0;31m \u001b[0;32mraise\u001b[0m \u001b[0mValueError\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"invalid input: data must be either a list or a braid\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 368\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 369\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0marcs\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpresentation\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;34m'pd'\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mValueError\u001b[0m: invalid input: data must be either a list or a braid"
]
}
],
"source": [
"for previous, item, nxt in previous_and_next(make_move_list(10, Link(\"3_1\"))):\n",
" print(\"Item is now\", item, \"next is\", nxt, \"previous is\", previous )"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#correct = False\n",
"#for knot in table:\n",
" "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Find Solution"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"def compute_solution_table(current_manifold,table_size):\n",
" \"\"\"Uses backtrack to create a knot table from the current manifold to process\"\"\"\n",
" current_manifold = K.copy()\n",
" working_copy = []\n",
" move_list = []\n",
" for _ in range(table_size):\n",
" \n",
" working_copy = current_manifold.copy()\n",
" working_copy.backtrack(steps=10)\n",
" #print(working_copy)\n",
" #print(working_copy.backtrack(steps=1))\n",
" #import pdb; pdb.set_trace()\n",
" print(working_copy)\n",
" \n",
" move_list.append(working_copy)\n",
" #working_copy = [working_copy[1], working_copy[1]]\n",
" #print(previous_knot)\n",
" return move_list\n",
"\n",
"def solver(step_number,table_size,target_manifold):\n",
" \"\"\"This creates a set of knots that are ambient isotopic to the target_manifold\"\"\"\n",
" solution = collections.namedtuple('Solution',['problems', 'target']) \n",
" \n",
" knot_table = [target_manifold.copy() for x in range(1,table_size)]\n",
" solution_table = []\n",
" for knot in knot_table:\n",
" #for _ in range(step_number):\n",
" # knot.backtrack(1)\n",
" solution_table.append(compute_solution_table(knot, table_size))\n",
" return challenge(problems=knot_table, target=target_manifold)\n",
"\n",
"#def generate_random_knot_challenge(crossing_number,step_number,table_size):\n",
"# return solver(step_number,table_size,spherogram.random_link(crossing_number, num_components=1, initial_map_gives_link=True, alternating=True))\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Create Challenge"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"def generate_random_table(crossing_number, num_components, table_size):\n",
" problem_set = [spherogram.random_link(crossing_number, num_components=num_components, initial_map_gives_link=True, alternating=True) for x in range(1,table_size)]\n",
" return problem_set"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#Lets create a large challenge (a few million knots)\n",
"million_knots = generate_random_table(30,1,2000000)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Verify Output"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"def ambient_isotopy(knot_1 , knot_2,verbose=False):\n",
" \"\"\"\n",
" >>>ambient_isotopy(Link(\"3_1\"),Link(\"3_1\"))\n",
" True\n",
" >>>ambient_isotopy(Link(\"3_1\"),Link(\"4_1\"))\n",
" False\n",
" \"\"\"\n",
" knot_1.simplify(\"global\")\n",
" \n",
" knot_2.simplify(\"global\")\n",
" print(\"Completed Simplification\")\n",
" #if knot_1.exterior().is_isomteric.to(knot_2) == True\n",
" \n",
" print(knot_1.alexander_polynomial())\n",
" print(knot_2.alexander_polynomial())\n",
" if knot_1.alexander_polynomial() == knot_2.alexander_polynomial():\n",
" \n",
" return True\n",
" print(\"Finished alexander polynominal\")\n",
" print(knot_1.jones_polynomial())\n",
" print(knot_2.jones_polynomial())\n",
" \n",
" if knot_1.jones_polynomial() == knot_2.jones_polynomial(): \n",
" print(\"Finished jones polynominal\")\n",
" return True\n",
" \n",
" return False"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<Link 4_1: 1 comp; 13 cross>\n",
"<Link 4_1: 1 comp; 14 cross>\n",
"<Link 4_1: 1 comp; 16 cross>\n",
"<Link 4_1: 1 comp; 10 cross>\n",
"<Link 4_1: 1 comp; 13 cross>\n",
"<Link 4_1: 1 comp; 10 cross>\n",
"<Link 4_1: 1 comp; 12 cross>\n",
"<Link 4_1: 1 comp; 5 cross>\n",
"<Link 4_1: 1 comp; 11 cross>\n",
"<Link 4_1: 1 comp; 16 cross>\n",
"<Link 4_1: 1 comp; 15 cross>\n",
"<Link 4_1: 1 comp; 14 cross>\n",
"<Link 4_1: 1 comp; 13 cross>\n",
"<Link 4_1: 1 comp; 15 cross>\n",
"<Link 4_1: 1 comp; 14 cross>\n",
"<Link 4_1: 1 comp; 13 cross>\n",
"<Link 4_1: 1 comp; 14 cross>\n",
"<Link 4_1: 1 comp; 9 cross>\n",
"<Link 4_1: 1 comp; 13 cross>\n",
"<Link 4_1: 1 comp; 9 cross>\n",
"<Link 4_1: 1 comp; 16 cross>\n",
"<Link 4_1: 1 comp; 13 cross>\n",
"<Link 4_1: 1 comp; 13 cross>\n",
"<Link 4_1: 1 comp; 14 cross>\n",
"<Link 4_1: 1 comp; 10 cross>\n",
"<Link 4_1: 1 comp; 11 cross>\n",
"<Link 4_1: 1 comp; 17 cross>\n",
"<Link 4_1: 1 comp; 13 cross>\n",
"<Link 4_1: 1 comp; 11 cross>\n",
"<Link 4_1: 1 comp; 11 cross>\n",
"<Link 4_1: 1 comp; 16 cross>\n",
"<Link 4_1: 1 comp; 11 cross>\n",
"<Link 4_1: 1 comp; 15 cross>\n",
"<Link 4_1: 1 comp; 8 cross>\n",
"<Link 4_1: 1 comp; 10 cross>\n",
"<Link 4_1: 1 comp; 15 cross>\n",
"<Link 4_1: 1 comp; 14 cross>\n",
"<Link 4_1: 1 comp; 15 cross>\n",
"<Link 4_1: 1 comp; 10 cross>\n",
"<Link 4_1: 1 comp; 14 cross>\n",
"<Link 4_1: 1 comp; 9 cross>\n",
"<Link 4_1: 1 comp; 15 cross>\n",
"<Link 4_1: 1 comp; 19 cross>\n",
"<Link 4_1: 1 comp; 11 cross>\n",
"<Link 4_1: 1 comp; 13 cross>\n",
"<Link 4_1: 1 comp; 8 cross>\n",
"<Link 4_1: 1 comp; 11 cross>\n",
"<Link 4_1: 1 comp; 15 cross>\n",
"<Link 4_1: 1 comp; 15 cross>\n",
"<Link 4_1: 1 comp; 11 cross>\n",
"<Link 4_1: 1 comp; 11 cross>\n",
"<Link 4_1: 1 comp; 10 cross>\n",
"<Link 4_1: 1 comp; 15 cross>\n",
"<Link 4_1: 1 comp; 15 cross>\n",
"<Link 4_1: 1 comp; 15 cross>\n",
"<Link 4_1: 1 comp; 10 cross>\n",
"<Link 4_1: 1 comp; 15 cross>\n",
"<Link 4_1: 1 comp; 9 cross>\n",
"<Link 4_1: 1 comp; 13 cross>\n",
"<Link 4_1: 1 comp; 11 cross>\n",
"<Link 4_1: 1 comp; 12 cross>\n",
"<Link 4_1: 1 comp; 16 cross>\n",
"<Link 4_1: 1 comp; 12 cross>\n",
"<Link 4_1: 1 comp; 13 cross>\n",
"<Link 4_1: 1 comp; 15 cross>\n",
"<Link 4_1: 1 comp; 14 cross>\n",
"<Link 4_1: 1 comp; 17 cross>\n",
"<Link 4_1: 1 comp; 12 cross>\n",
"<Link 4_1: 1 comp; 17 cross>\n",
"<Link 4_1: 1 comp; 16 cross>\n",
"<Link 4_1: 1 comp; 9 cross>\n",
"<Link 4_1: 1 comp; 14 cross>\n",
"<Link 4_1: 1 comp; 14 cross>\n",
"<Link 4_1: 1 comp; 14 cross>\n",
"<Link 4_1: 1 comp; 10 cross>\n",
"<Link 4_1: 1 comp; 13 cross>\n",
"<Link 4_1: 1 comp; 13 cross>\n",
"<Link 4_1: 1 comp; 13 cross>\n",
"<Link 4_1: 1 comp; 17 cross>\n",
"<Link 4_1: 1 comp; 14 cross>\n",
"<Link 4_1: 1 comp; 10 cross>\n",
"<Link 4_1: 1 comp; 18 cross>\n",
"<Link 4_1: 1 comp; 11 cross>\n",
"<Link 4_1: 1 comp; 12 cross>\n",
"<Link 4_1: 1 comp; 12 cross>\n",
"<Link 4_1: 1 comp; 12 cross>\n",
"<Link 4_1: 1 comp; 10 cross>\n",
"<Link 4_1: 1 comp; 13 cross>\n",
"<Link 4_1: 1 comp; 12 cross>\n",
"<Link 4_1: 1 comp; 17 cross>\n",
"<Link 4_1: 1 comp; 7 cross>\n",
"<Link 4_1: 1 comp; 7 cross>\n",
"<Link 4_1: 1 comp; 11 cross>\n",
"<Link 4_1: 1 comp; 10 cross>\n",
"<Link 4_1: 1 comp; 9 cross>\n",
"<Link 4_1: 1 comp; 18 cross>\n",
"<Link 4_1: 1 comp; 11 cross>\n",
"<Link 4_1: 1 comp; 9 cross>\n",
"<Link 4_1: 1 comp; 12 cross>\n",
"<Link 4_1: 1 comp; 15 cross>\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n",
"Completed Simplification\n",
"t^2 - 3*t + 1\n",
"t^2 - 3*t + 1\n"
]
},
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"def verify(solution_table):\n",
" #table = compute_solution_table(knot,100) #TODO Make this into unit test\n",
" #correct = True\n",
" incorrect_list = []\n",
" for knot in solution_table:\n",
" if not ambient_isotopy(knot,Link('4_1')):\n",
" return False\n",
" return True \n",
"verify(1) "
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Challenge(problems=[<Link: 1 comp; 33 cross>, <Link: 1 comp; 37 cross>, <Link: 1 comp; 35 cross>, <Link: 1 comp; 42 cross>, <Link: 1 comp; 32 cross>, <Link: 1 comp; 37 cross>, <Link: 1 comp; 33 cross>, <Link: 1 comp; 34 cross>, <Link: 1 comp; 33 cross>], target=<Link: 1 comp; 25 cross>)"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"generate_mock_challenge(10,10,spherogram.random_link(25, num_components=1, initial_map_gives_link=True, alternating=True))"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [],
"source": [
"random_knot_test = generate_random_table(crossing_number=25,num_components=1,table_size=25)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Completed Simplification\n",
"2*t^16 - 27*t^15 + 173*t^14 - 684*t^13 + 1864*t^12 - 3756*t^11 + 5901*t^10 - 7564*t^9 + 8181*t^8 - 7564*t^7 + 5901*t^6 - 3756*t^5 + 1864*t^4 - 684*t^3 + 173*t^2 - 27*t + 2\n",
"15*t^14 - 176*t^13 + 978*t^12 - 3426*t^11 + 8497*t^10 - 15809*t^9 + 22731*t^8 - 25619*t^7 + 22731*t^6 - 15809*t^5 + 8497*t^4 - 3426*t^3 + 978*t^2 - 176*t + 15\n",
"Finished alexander polynominal\n"
]
}
],
"source": [
"ambient_isotopy(random_knot_test[0],random_knot_test[1])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"problem_set_large = profile.run(generate_random_knot_challenge(5000,50,50))"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 3702593 function calls (3700603 primitive calls) in 45.463 seconds\n",
"\n",
" Ordered by: standard name\n",
"\n",
" ncalls tottime percall cumtime percall filename:lineno(function)\n",
" 239397 1.620 0.000 1.620 0.000 :0(__new__)\n",
" 59700 0.235 0.000 0.235 0.000 :0(add)\n",
" 398 0.126 0.000 0.173 0.000 :0(all)\n",
" 100296 0.375 0.000 0.375 0.000 :0(append)\n",
" 597 0.000 0.000 0.000 0.000 :0(getattr)\n",
" 19900 0.170 0.000 0.170 0.000 :0(index)\n",
" 480386 2.346 0.000 2.346 0.000 :0(isinstance)\n",
" 796 0.048 0.000 0.048 0.000 :0(items)\n",
"446158/444168 2.263 0.000 2.263 0.000 :0(len)\n",
" 99898 0.841 0.000 0.841 0.000 :0(pop)\n",
" 190091 1.187 0.000 1.187 0.000 :0(random)\n",
" 199 1.445 0.007 5.415 0.027 :0(random_map)\n",
" 30448 0.246 0.000 0.246 0.000 :0(range)\n",
" 19900 0.186 0.000 0.186 0.000 :0(remove)\n",
" 1 0.000 0.000 0.000 0.000 :0(setprofile)\n",
" 199 0.015 0.000 0.015 0.000 :0(zip)\n",
" 1 0.016 0.016 45.447 45.447 <ipython-input-6-8e1c0d27c528>:1(generate_random_table)\n",
" 1 0.016 0.016 45.463 45.463 <string>:1(<module>)\n",
" 239397 2.250 0.000 3.870 0.000 <string>:8(__new__)\n",
" 597 0.000 0.000 0.975 0.002 _abcoll.py:188(_from_iterable)\n",
" 597 0.000 0.000 0.975 0.002 _abcoll.py:219(__sub__)\n",
" 597 0.475 0.001 0.959 0.002 _abcoll.py:224(<genexpr>)\n",
" 2189 1.125 0.001 4.113 0.002 _abcoll.py:328(__ior__)\n",
" 597 0.015 0.000 0.031 0.000 _abcoll.py:548(update)\n",
" 1194 0.000 0.000 0.000 0.000 _weakrefset.py:70(__contains__)\n",
" 597 0.000 0.000 0.000 0.000 abc.py:128(__instancecheck__)\n",
" 597 0.015 0.000 0.015 0.000 abc.py:148(__subclasscheck__)\n",
" 597 0.016 0.000 0.062 0.000 collections.py:50(__init__)\n",
" 59700 0.532 0.000 0.532 0.000 collections.py:71(__setitem__)\n",
" 318400 5.035 0.000 8.080 0.000 graphs.py:57(__getitem__)\n",
" 398 0.000 0.000 12.081 0.030 invariants.py:93(__init__)\n",
" 60696 0.203 0.000 0.203 0.000 links_base.py:102(<lambda>)\n",
" 4837 0.047 0.000 0.265 0.000 links_base.py:113(rotate_by_90)\n",
" 10337 0.095 0.000 0.704 0.000 links_base.py:117(rotate_by_180)\n",
" 199 1.538 0.008 13.527 0.068 links_base.py:1173(copy)\n",
" 29850 0.234 0.000 0.938 0.000 links_base.py:121(orient)\n",
" 199 0.159 0.001 26.797 0.135 links_base.py:1259(alternating)\n",
" 39800 0.282 0.000 0.282 0.000 links_base.py:126(__getitem__)\n",
" 30049 0.512 0.000 1.763 0.000 links_base.py:129(entry_points)\n",
" 39800 0.268 0.000 0.268 0.000 links_base.py:136(__setitem__)\n",
" 19900 0.579 0.000 2.578 0.000 links_base.py:149(DT_info)\n",
" 119400 2.816 0.000 8.000 0.000 links_base.py:224(next)\n",
" 59700 0.705 0.000 1.684 0.000 links_base.py:233(other)\n",
" 597 0.686 0.001 5.192 0.009 links_base.py:244(component)\n",
" 59700 0.702 0.000 2.395 0.000 links_base.py:255(component_label)\n",
" 59700 1.000 0.000 4.648 0.000 links_base.py:258(label_crossing)\n",
" 597 0.000 0.000 5.192 0.009 links_base.py:269(add)\n",
" 59700 0.938 0.000 1.673 0.000 links_base.py:275(add)\n",
" 398 0.249 0.001 12.050 0.030 links_base.py:366(__init__)\n",
" 10547 0.047 0.000 0.047 0.000 links_base.py:410(<genexpr>)\n",
" 597 0.016 0.000 0.016 0.000 links_base.py:543(all_crossings_oriented)\n",
" 597 0.047 0.000 32.371 0.054 links_base.py:546(_build)\n",
" 199 0.061 0.000 11.578 0.058 links_base.py:550(_rebuild)\n",
" 597 1.323 0.002 6.527 0.011 links_base.py:561(_orient_crossings)\n",
" 597 0.262 0.000 2.025 0.003 links_base.py:584(crossing_entries)\n",
" 199 0.080 0.000 1.390 0.007 links_base.py:596(_DT_convention_holds)\n",
" 597 2.753 0.005 25.797 0.043 links_base.py:603(_build_components)\n",
" 19900 0.278 0.000 0.638 0.000 links_base.py:75(__init__)\n",
" 29850 0.329 0.000 0.609 0.000 links_base.py:80(_clear)\n",
" 59700 0.531 0.000 0.531 0.000 links_base.py:84(_clear_strand_info)\n",
" 59700 0.453 0.000 0.688 0.000 links_base.py:88(make_tail)\n",
" 15174 0.624 0.000 0.827 0.000 links_base.py:98(rotate)\n",
" 2786 0.016 0.000 0.031 0.000 ordered_set.py:12(__len__)\n",
" 59302 0.173 0.000 0.173 0.000 ordered_set.py:15(__contains__)\n",
" 199000 2.029 0.000 2.029 0.000 ordered_set.py:18(add)\n",
" 80396 1.080 0.000 1.765 0.000 ordered_set.py:24(discard)\n",
" 59899 0.311 0.000 0.311 0.000 ordered_set.py:30(__iter__)\n",
" 796 0.000 0.000 0.047 0.000 ordered_set.py:44(pop)\n",
" 2189 0.032 0.000 4.145 0.002 ordered_set.py:5(__init__)\n",
" 1 0.000 0.000 45.463 45.463 profile:0(generate_random_table(50,1,200))\n",
" 0 0.000 0.000 profile:0(profiler)\n",
" 190091 3.012 0.000 4.199 0.000 random.py:177(randrange)\n",
" 199 0.093 0.000 5.846 0.029 random_links.py:23(random_map)\n",
" 199 0.286 0.001 12.772 0.064 random_links.py:51(map_to_link)\n",
" 199 0.016 0.000 45.431 0.228 random_links.py:89(random_link)\n",
"\n",
"\n"
]
}
],
"source": [
"profile.run('generate_random_table(50,1,200)')"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<Link: 1 comp; 20 cross>\n"
]
},
{
"data": {
"text/plain": [
"[<Link: 1 comp; 40 cross>,\n",
" <Link: 1 comp; 34 cross>,\n",
" <Link: 1 comp; 43 cross>,\n",
" <Link: 1 comp; 41 cross>,\n",
" <Link: 1 comp; 38 cross>,\n",
" <Link: 1 comp; 41 cross>,\n",
" <Link: 1 comp; 35 cross>,\n",
" <Link: 1 comp; 41 cross>,\n",
" <Link: 1 comp; 36 cross>,\n",
" <Link: 1 comp; 37 cross>,\n",
" <Link: 1 comp; 40 cross>,\n",
" <Link: 1 comp; 38 cross>,\n",
" <Link: 1 comp; 34 cross>,\n",
" <Link: 1 comp; 36 cross>,\n",
" <Link: 1 comp; 37 cross>,\n",
" <Link: 1 comp; 40 cross>,\n",
" <Link: 1 comp; 40 cross>,\n",
" <Link: 1 comp; 40 cross>,\n",
" <Link: 1 comp; 33 cross>]"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"problem_set = generate_random_knot_challenge(20,20,20)\n",
"print(problem_set.target)\n",
"problem_set[0]"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Completed Simplification\n",
"t^14 - 12*t^13 + 62*t^12 - 199*t^11 + 460*t^10 - 812*t^9 + 1131*t^8 - 1261*t^7 + 1131*t^6 - 812*t^5 + 460*t^4 - 199*t^3 + 62*t^2 - 12*t + 1\n",
"t^14 - 12*t^13 + 62*t^12 - 199*t^11 + 460*t^10 - 812*t^9 + 1131*t^8 - 1261*t^7 + 1131*t^6 - 812*t^5 + 460*t^4 - 199*t^3 + 62*t^2 - 12*t + 1\n"
]
},
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ambient_isotopy(problem_set.problems[0],problem_set.problems[2])"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2*t^14 - 17*t^13 + 69*t^12 - 177*t^11 + 324*t^10 - 456*t^9 + 533*t^8 - 555*t^7 + 533*t^6 - 456*t^5 + 324*t^4 - 177*t^3 + 69*t^2 - 17*t + 2"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"problem_set.problems[0].alexander_polynomial()"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2*t^14 - 17*t^13 + 69*t^12 - 177*t^11 + 324*t^10 - 456*t^9 + 533*t^8 - 555*t^7 + 533*t^6 - 456*t^5 + 324*t^4 - 177*t^3 + 69*t^2 - 17*t + 2"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"\n",
"problem_set.problems[1].alexander_polynomial()"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ambient_isotopy(problem_set.problems[0], problem_set.problems[1])"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['__call__',\n",
" '__class__',\n",
" '__cmp__',\n",
" '__delattr__',\n",
" '__doc__',\n",
" '__format__',\n",
" '__getattribute__',\n",
" '__hash__',\n",
" '__init__',\n",
" '__name__',\n",
" '__new__',\n",
" '__objclass__',\n",
" '__reduce__',\n",
" '__reduce_ex__',\n",
" '__repr__',\n",
" '__self__',\n",
" '__setattr__',\n",
" '__sizeof__',\n",
" '__str__',\n",
" '__subclasshook__']"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"dir(problem_set.problems[0].alexander_polynomial().__eq__)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"ename": "AssertionError",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-13-b5db8f10819a>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mproblem_set\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mproblems\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0malexander_polynomial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m/opt/sagemath-8.2/local/lib/python2.7/site-packages/spherogram/links/invariants.pyc\u001b[0m in \u001b[0;36malexander_polynomial\u001b[0;34m(self, multivar, v, method, norm, factored)\u001b[0m\n\u001b[1;32m 264\u001b[0m \u001b[0;31m# If single variable, use the super-fast method of Bar-Natan.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 265\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcomp\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mmethod\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'default'\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mnorm\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 266\u001b[0;31m \u001b[0mp\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0malexander\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0malexander\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 267\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# Use a simple method based on the Wirtinger presentation.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 268\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mmethod\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m'default'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'wirtinger'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/opt/sagemath-8.2/local/lib/python2.7/site-packages/spherogram/links/alexander.pyc\u001b[0m in \u001b[0;36malexander\u001b[0;34m(K)\u001b[0m\n\u001b[1;32m 244\u001b[0m \u001b[0mc\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mK\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcrossings\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 245\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mc\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 246\u001b[0;31m \u001b[0mE\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mExhaustion\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mK\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 247\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 248\u001b[0m \u001b[0mE\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgood_exhaustion\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mK\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmax\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m20\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.15\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/opt/sagemath-8.2/local/lib/python2.7/site-packages/spherogram/links/alexander.pyc\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, link, crossing)\u001b[0m\n\u001b[1;32m 183\u001b[0m \u001b[0mfrontier\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 184\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 185\u001b[0;31m \u001b[0;32massert\u001b[0m \u001b[0mfrontier_lengths\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m4\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0moverlap\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfrontier\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 186\u001b[0m \u001b[0mfrontier_lengths\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfrontier\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 187\u001b[0m \u001b[0mgluings\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mC_gluings\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mAssertionError\u001b[0m: "
]
}
],
"source": [
"problem_set.problems[0].alexander_polynomial()"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Completed Simplification\n",
"t^2 - t + 1\n",
"t^2 - t + 1\n"
]
},
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ambient_isotopy(Link(\"3_1\"),Link(\"3_1\"))"
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ambient_isotopy(Link(\"3_1\"),Link(\"4_1\"))"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "generate_random_table() got an unexpected keyword argument 'step_number'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-33-2b0e6123e887>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mrandom_knot_test\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgenerate_random_table\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcrossing_number\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m25\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mstep_number\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mtable_size\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m200\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m: generate_random_table() got an unexpected keyword argument 'step_number'"
]
}
],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4*t^14 - 60*t^13 + 390*t^12 - 1486*t^11 + 3809*t^10 - 7112*t^9 + 10154*t^8 - 11399*t^7 + 10154*t^6 - 7112*t^5 + 3809*t^4 - 1486*t^3 + 390*t^2 - 60*t + 4"
]
},
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"random_knot_test[0].alexander_polynomial()"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"ename": "IndexError",
"evalue": "list index out of range",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mIndexError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-27-4c66a2ead63e>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mrandom_knot_test\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0malexander_polynomial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mIndexError\u001b[0m: list index out of range"
]
}
],
"source": [
"random_knot_test[1].alexander_polynomial()"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Completed Simplification\n",
"Finished alexander polynominal\n"
]
},
{
"ename": "KeyboardInterrupt",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-24-5db5d28d89cd>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mambient_isotopy\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrandom_knot_test\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m0\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mrandom_knot_test\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mInteger\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m<ipython-input-15-ec807676640a>\u001b[0m in \u001b[0;36mambient_isotopy\u001b[0;34m(knot_1, knot_2)\u001b[0m\n\u001b[1;32m 16\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 17\u001b[0m \u001b[0;32mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Finished alexander polynominal\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 18\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0mknot_1\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjones_polynomial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mknot_2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjones_polynomial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 19\u001b[0m \u001b[0;32mprint\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Finished jones polynominal\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/opt/sagemath-8.2/local/lib/python2.7/site-packages/spherogram/links/invariants.pyc\u001b[0m in \u001b[0;36mjones_polynomial\u001b[0;34m(self, variable)\u001b[0m\n\u001b[1;32m 549\u001b[0m \"\"\"\n\u001b[1;32m 550\u001b[0m \u001b[0;32mfrom\u001b[0m \u001b[0;34m.\u001b[0m \u001b[0;32mimport\u001b[0m \u001b[0mjones\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 551\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mjones\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mJones_poly\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mvariable\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 552\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 553\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mseifert_matrix\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/opt/sagemath-8.2/local/lib/python2.7/site-packages/spherogram/links/jones.pyc\u001b[0m in \u001b[0;36mJones_poly\u001b[0;34m(K, variable)\u001b[0m\n\u001b[1;32m 174\u001b[0m \u001b[0mwrithe\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mK\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrithe\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 175\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mT\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mspanning_trees\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mG\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 176\u001b[0;31m \u001b[0manswer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0manswer\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0m_Jones_contrib\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mK\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mG\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mT\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mA\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 177\u001b[0m \u001b[0manswer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0manswer\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0mA\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mwrithe\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 178\u001b[0m \u001b[0;31m#Python doesn't deal well with rational powers, so renormalizing (divide exponents by 4) is a pain. (Sage would do this fine.)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/opt/sagemath-8.2/local/lib/python2.7/site-packages/spherogram/links/jones.pyc\u001b[0m in \u001b[0;36m_Jones_contrib\u001b[0;34m(K, G, T, A)\u001b[0m\n\u001b[1;32m 161\u001b[0m \u001b[0;31m# 2 loops, edges in T and edges not in T\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 162\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0me\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mG\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0medges\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 163\u001b[0;31m \u001b[0manswer\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0manswer\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0m_Jones_contrib_edge\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mK\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mG\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mT\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0me\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mA\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 164\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0manswer\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 165\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/opt/sagemath-8.2/local/lib/python2.7/site-packages/spherogram/links/jones.pyc\u001b[0m in \u001b[0;36m_Jones_contrib_edge\u001b[0;34m(K, G, T, e, A)\u001b[0m\n\u001b[1;32m 149\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_internally_active\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mG\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mT\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0me\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 150\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0;34m-\u001b[0m\u001b[0mA\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m3\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 151\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0me\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mT\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0medges\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0;32mnot\u001b[0m \u001b[0mis_internally_active\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mG\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mT\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0me\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 152\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mA\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0ms\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 153\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mis_externally_active\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mG\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mT\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0me\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/opt/sagemath-8.2/local/lib/python2.7/site-packages/spherogram/links/jones.pyc\u001b[0m in \u001b[0;36mis_internally_active\u001b[0;34m(G, T, e)\u001b[0m\n\u001b[1;32m 41\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mFalse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 42\u001b[0m \u001b[0medges\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mG\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0medges\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 43\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mf\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcut\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mG\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mT\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0me\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 44\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0medges\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mf\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m<\u001b[0m\u001b[0medges\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mindex\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0me\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 45\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mFalse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32msrc/cysignals/signals.pyx\u001b[0m in \u001b[0;36mcysignals.signals.python_check_interrupt\u001b[0;34m()\u001b[0m\n",
"\u001b[0;32msrc/cysignals/signals.pyx\u001b[0m in \u001b[0;36mcysignals.signals.sig_raise_exception\u001b[0;34m()\u001b[0m\n",
"\u001b[0;31mKeyboardInterrupt\u001b[0m: "
]
}
],
"source": [
"ambient_isotopy(random_knot_test[0],random_knot_test[1])"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"ename": "AssertionError",
"evalue": "",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mAssertionError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-20-5a558a1ae902>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"Not equivalent\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 14\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 15\u001b[0;31m \u001b[0msolution\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msolve\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mproblem_set\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m<ipython-input-20-5a558a1ae902>\u001b[0m in \u001b[0;36msolve\u001b[0;34m(problem_set)\u001b[0m\n\u001b[1;32m 3\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mknot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mproblem_set\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mproblems\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 4\u001b[0m \u001b[0mmetadata\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 5\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0mambient_isotopy\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mproblem_set\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtarget\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mknot\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 6\u001b[0m \u001b[0;31m#metadata[\"alexander_polynominal\"] = knot.alexander_polynomial()\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 7\u001b[0m \u001b[0mmetadata\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"simplify_result\"\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mknot\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msimplify\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"global\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m<ipython-input-12-488b1778359a>\u001b[0m in \u001b[0;36mambient_isotopy\u001b[0;34m(knot_1, knot_2)\u001b[0m\n\u001b[1;32m 5\u001b[0m \"\"\"\n\u001b[1;32m 6\u001b[0m \u001b[0;31m#if knot_1.exterior().is_isomteric.to(knot_2) == True\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 7\u001b[0;31m \u001b[0;32mif\u001b[0m \u001b[0mknot_1\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0malexander_polynomial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mknot_2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0malexander_polynomial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 8\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mTrue\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 9\u001b[0m \u001b[0;32melif\u001b[0m \u001b[0mknot_1\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjones_polynomial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mknot_2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjones_polynomial\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/opt/sagemath-8.2/local/lib/python2.7/site-packages/spherogram/links/invariants.pyc\u001b[0m in \u001b[0;36malexander_polynomial\u001b[0;34m(self, multivar, v, method, norm, factored)\u001b[0m\n\u001b[1;32m 264\u001b[0m \u001b[0;31m# If single variable, use the super-fast method of Bar-Natan.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 265\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mcomp\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mmethod\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;34m'default'\u001b[0m \u001b[0;32mand\u001b[0m \u001b[0mnorm\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 266\u001b[0;31m \u001b[0mp\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0malexander\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0malexander\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 267\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;31m# Use a simple method based on the Wirtinger presentation.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 268\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mmethod\u001b[0m \u001b[0;32mnot\u001b[0m \u001b[0;32min\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m'default'\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m'wirtinger'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/opt/sagemath-8.2/local/lib/python2.7/site-packages/spherogram/links/alexander.pyc\u001b[0m in \u001b[0;36malexander\u001b[0;34m(K)\u001b[0m\n\u001b[1;32m 244\u001b[0m \u001b[0mc\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mK\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcrossings\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 245\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mc\u001b[0m \u001b[0;34m<\u001b[0m \u001b[0;36m100\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 246\u001b[0;31m \u001b[0mE\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mExhaustion\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mK\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 247\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 248\u001b[0m \u001b[0mE\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mgood_exhaustion\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mK\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmax\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m20\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;36m0.15\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mc\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/opt/sagemath-8.2/local/lib/python2.7/site-packages/spherogram/links/alexander.pyc\u001b[0m in \u001b[0;36m__init__\u001b[0;34m(self, link, crossing)\u001b[0m\n\u001b[1;32m 183\u001b[0m \u001b[0mfrontier\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0madd\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mcs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 184\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 185\u001b[0;31m \u001b[0;32massert\u001b[0m \u001b[0mfrontier_lengths\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m-\u001b[0m\u001b[0;36m1\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0;36m4\u001b[0m \u001b[0;34m-\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0moverlap\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfrontier\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 186\u001b[0m \u001b[0mfrontier_lengths\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfrontier\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 187\u001b[0m \u001b[0mgluings\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mC_gluings\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mAssertionError\u001b[0m: "
]
}
],
"source": [
"def solve(problem_set):\n",
" result = []\n",
" for knot in problem_set.problems:\n",
" metadata = {}\n",
" if ambient_isotopy(problem_set.target,knot): \n",
" #metadata[\"alexander_polynominal\"] = knot.alexander_polynomial()\n",
" metadata[\"simplify_result\"] = knot.simplify(\"global\")\n",
" metadata[\"simplified_alexander_polynomial\"] = knot.alexander_polynomial()\n",
" print(knot.alexander_polynomial())\n",
" metadata[\"PD_code\"] = knot.PD_code()\n",
" result.append(metadata)\n",
" else:\n",
" result.append(\"Not equivalent\")\n",
" return result\n",
"solution = solve(problem_set)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"solution"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"solve(problem_set_large)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"for knot_solution in problem_set[0]:\n",
" problem_set[1].is_isometric_to(.exterior())\n",
" \n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"Link([(19, 9, 20, 8), (14, 5, 15, 6), (38, 23, 39, 24), (26, 29, 27, 30), (12, 15, 13, 16), (4, 13, 5, 14), (11, 44, 12, 45), (1, 30, 2, 31), (22, 35, 23, 36), (24, 37, 25, 38), (7, 21, 8, 20), (36, 25, 37, 26), (34, 39, 35, 40), (28, 33, 29, 34), (31, 2, 32, 3), (43, 10, 44, 11), (32, 27, 33, 28), (45, 42, 0, 43), (9, 6, 10, 7), (18, 4, 19, 3), (16, 41, 17, 42), (40, 17, 41, 18), (21, 0, 22, 1)]).view()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"E = problem_set[0][1].exterior()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "raw",
"metadata": {},
"source": [
"E.volume()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"problem_set[1].sage_link().plot()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"problem_set[0][1].exterior()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"E_target = problem_set[1].exterior()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"problem_set[1].view()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"problem_set[1].DT_code()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"problem_set[1].view()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
" problem_set[0][0].DT_code()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
" problem_set[0][0].DT_code()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"E_target.is_isometric_to(E)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def verify(solution):\n",
" for link in solution.problems:\n",
" E_target = solution.target.exterior()\n",
" to_compare = link.exterior()\n",
" to_compare.is_isometric_to(E_target)\n",
" print(to_compare.DT_code())\n",
" print(to_compare.is_isometric_to(E_target)) # Note is_isometric_to only matters if it is True. False is not rigourous and an exception is thrown if it doesn't work."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"verify(problem_set_large)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def generate_random_table(crossing_number, num_components, problem_size):\n",
" problem_set = [spherogram.random_link(crossing_number, num_components=num_components, initial_map_gives_link=True, alternating=True) for x in range(1,problem_size)]\n",
" return problem_set"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"random_table = generate_random_table(50,1,50)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"profile.run(\"generate_random_table(50,1,1000)\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"l = [spherogram.random_link(50, num_components=1) for x in range(1,200)]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"spherogram.random_link(20, num_components=1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def solve(table):\n",
" \n",
" result = [link.simplify(\"global\") for link in table]\n",
" for link in table:\n",
" try:\n",
" link.exterior().is_isometric_to(Link(\"3_1\").exterior())\n",
" link.exterior().is_isometric_to(Link(\"4_1\").exterior())\n",
" \n",
" except:\n",
" print(\"Could not find an isometry \")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"solve(random_table)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"try:\n",
" random_table[0].exterior().is_isometric_to(Link(\"3_1\").exterior())\n",
"except:\n",
" print(\"not isometric\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"random_table[0].PD_code()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"simplified = [link.simplify(\"global\") for link in random_table]\n",
"random_table"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"def print_table_pdcode(table):\n",
" for x in l:\n",
" print(x.PD_code())\n",
"profile.run(\"print_table_pdcode(simplified)\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
" "
]
}
],
"metadata": {
"kernelspec": {
"display_name": "SageMath 8.2",
"language": "",
"name": "sagemath"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
#! /usr/bin/env racket
#lang typed/racket #:with-refinements
;(require graph)
;raco pkg install graph
(require typed/racket/date)
(require racket/sequence)
(require typed/racket/date)
(require math/array)
(require math/matrix)
(require typed/racket/unit)
(require pfds/queue/hood-melville)
(define trefoil (array #[#[00 02 01 00]
#[02 10 09 01]
#[03 09 04 06]
#[00 03 05 04]] : Integer))
(define simple-unknot (array #[#[02 01 ]
#[03 04]] : Integer))
;TODO It must have a dimention of N by M
;TODO It must be ambiend isotopic to the knot $K$ that we send
;TODO It must have a set of operations $O$ of cardinality $O_n$
;DONE It must have a crossing number $C$
;TODO use a queue (set? ) and a set of mosaic moves to implement the checking of validity of a set of moves.
;source is optional
; Knot table
;KNOTS are specified as a $N * M$ matrix corresponding to $0-18$ that maps to the set of mosaic tiles $T_0$ to $T_n$
;(define culprit (matrix-graph [[0 3 8 #f -4]
; [#f 0 #f 1 7]
; [#f 4 0 #f #f]
; [2 #f -5 0 #f]
; [#f #f #f 6 0]]))
; https://docs.racket-lang.org/math/matrix_types.html#%28form._%28%28lib._math%2Fmatrix..rkt%29._.Matrix%29%29
(struct braidcoin ([source_knot : (Matrix Integer)]
[target_knot : (Matrix Integer)]
[crossing_number : (Refine [n : Integer] (> n 0))]
[dimention : (Refine [n : Integer] (> n 0))]
[timestamp : date])
#:prefab)
(define unknot-trefoil (braidcoin trefoil simple-unknot 3 4 (current-date)))
(define unknot-unknot (braidcoin simple-unknot simple-unknot 3 4 (current-date)))
;* Header X-braidcoin: 0:SOURCE_KNOT:DESTINATION_KNOT:CROSSING_NUMBER:DIMENTION:OPERATION_COUNTER:DATE
;KNOTS are specified as a $N * M$ matrix corresponding to $0-18$ that maps to the set of mosaic tiles $T_0$ to $T_n$
(struct knot-operations ([queue : braidcoin]))
(: crossing-number (-> (Array Integer) Integer))
(define (crossing-number array)
;09 and 10 correspond to over and under crossing
(array-count (λ: ([x : Integer]) (or (equal? x 10) (equal? x 09))) array))
(: crossing-number-test (-> braidcoin Boolean))
(define (crossing-number-test bc)
;DONE It must have a crossing number $C$
(if (equal? (crossing-number (braidcoin-source_knot bc))
(crossing-number (braidcoin-target_knot bc)))
#t
#f))
;(struct knot-operations braidcoin)
;(define (expansion move braidcoin)
; #t)
;(define (reidmeister-1 braidcoin)
; #t)
(define-type Tree (U leaf node))
(struct leaf ([source_knot : (Matrix Integer)]
[target_knot : (Matrix Integer)]
[crossing_number : (Refine [n : Integer] (> n 0))]
[dimention : (Refine [n : Integer] (> n 0))]
[timestamp : date])
#:prefab)
(struct node ([left : Tree] [right : Tree]))
(: tree-height (-> Tree Integer))
(define (tree-height t)
(cond [(leaf? t) 1]
[else (max (+ 1 (tree-height (node-left t)))
(+ 1 (tree-height (node-right t))))]))
(define unknot-trefoil-leaf (leaf trefoil simple-unknot 3 4 (current-date)))
(define unknot-unknot-leaf (leaf simple-unknot simple-unknot 3 4 (current-date)))
(tree-height (node unknot-unknot-leaf unknot-trefoil-leaf))
(node unknot-unknot-leaf unknot-trefoil-leaf)
(tree-height (node unknot-unknot-leaf unknot-trefoil-leaf))
;(: test-fail (-> Tree Boolean))
;(define (tree-height t)
; (cond [eqv? (crossing-number (node-left t)) (node-right t) #f]
; [else (max (+ 1 (tree-height (node-left t)))
; (+ 1 (tree-height (node-right t))))]))
;(struct queue)
;(struct chain)
;(struct current_transactions)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment