{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "id": "fa65e521-713f-4c6b-8e27-17d2b489b0cf",
   "metadata": {},
   "source": [
    "## Lecture 6 - Normalization continued\n",
    "\n",
    "### Announcements\n",
    "\n",
    "1. Lecture Exercise 7 is out later today, due on monday at 2pm.\n",
    "2. Homework \\#2 out on later today, due next week thursday.\n",
    "3. If you have accommodations, please reserve an exam slot with the test center for Exam #1 on October 1st. See: https://provost.rpi.edu/faculty-resources/testing-center \n",
    "   - Note the exam will be 110 minutes. \n",
    "   - For 50% extra time, reserve a 3 hour block\n",
    "   - For 100% extra time, reserve a 4 hour block\n",
    "   - Ideally your block should start at 2pm, but if you cannot do this, please notify me.\n",
    "\n",
    "### Today's topics\n",
    "\n",
    "- Boyce-Codd Normal Form and Third Normal Form revisited\n",
    "- Meaning of a set of functional dependencies (closure)\n",
    "- Minimal Functional Dependencies and how to find them\n",
    "- Decompositions \n",
    "   - What is a decomposition\n",
    "   - How can you find the functional dependencies that hold for a decomposition\n",
    "   - When is a decomposition functional dependency preserving\n",
    "   - When is a decomposition lossless\n",
    "   - How can we check a decomposition is lossless with the Chase Algorithm\n",
    "- How to compute the 3NF decomposition\n",
    "- How to compute BCNF decomposition\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b2b783a9-fbbf-42d7-b259-9d4edffe38e9",
   "metadata": {},
   "source": [
    "**Functional Dependency (fd):** Given a relation R and a set of attributes X and Y of R, a fd is an expression of the form **X -> Y** which means if two tuples in R have the same values for X, then they must have the same values for Y.\n",
    "                                                                                                          "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "b91d7a9c-84ad-4b20-91c4-ba0d44a387c0",
   "metadata": {},
   "source": [
    "**Boyce-Codd Normal Form (BCNF):** Given a relation R and a set of functional dependencies F, the relation R is said to be in Boyce-Codd Normal Form (BCNF) iff for all functional dependencies X->Y in R, one of the following is true:\n",
    "    1. X-> Y is trivial, or\n",
    "    2. X is a superkey of R\n",
    "\n",
    "In other words, if there is a single violation of BCNF, where X->Y in F, and X->Y is not trivial and X is not a superkey, then R is not in BCNF.\n",
    "\n",
    "\n",
    "\n",
    "**Third Normal Form (3NF):** Given a relation R and a set of functional dependencies F, the relation R is said to be in Third Normal Form (3NF) iff for all functional dependencies X->Y in R, one of the following is true:\n",
    "    1. X-> Y is trivial, or\n",
    "    2. X is a superkey of R, or\n",
    "    3. Y is contains only prime attributes.\n",
    "\n",
    "        \n",
    "Everything in BCNF is also in 3NF, but 3NF allows additional relations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "30074f2b-5430-4cc3-95f7-50b0fc012251",
   "metadata": {
    "jupyter": {
     "source_hidden": true
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAASIAAAEiCAYAAABdvt+2AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjAsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvlHJYcgAAAAlwSFlzAAAPYQAAD2EBqD+naQAANftJREFUeJzt3XlcVOX+B/DPMKwKuJSyqRlquaTiRcFUFpdEBCHMtXKBlHJpUbN+aXotvXlvmd6bC6Z23QNLrzooiEuBW5DiguHVUFMU0DQRBsQZZub7+8M7JzA0leU5c+b7fr14ZTDiZ5bzmec5c85zVEREYIwxgWxEB2CMMS4ixphwXESMMeG4iBhjwnERMcaE4yJijAnHRcQYE46LiDEmHBcRY0w4LiLGmHBcRIwx4biIGGPCcRExxoTjImKMCcdFxBgTjouIMSYcFxFjTDguIsaYcFxEjDHhuIgYY8JxETHGhOMiYowJx0XEGBOOi4gxJhwXEWNMOC4ixphwXESMMeG4iBhjwnERMcaE4yJijAnHRcQYE46LiDEmHBcRY0w4LiLGmHC2ogMwy0REMBgMMBgMAABbW1vY2tpCpVIJTsYsERcRAxFBq9WioKAA+fn5lf5b8c9Xr17FnTt3YDAYYDKZqvxdNjY2sLW1haOjI9zd3eHh4QFPT094eHhU+rP5vy4uLlxeDCoiItEhWN0pKyvDyZMnkZmZKX2dP38epaWlQvLUr18frVq1gq+vL3x9fdG1a1d06tQJTk5OQvIwMbiIFKyq0snOzobRaKzy9q6urg8cwbi7u6NevXrSNMz8BUCappm/bt++jatXrz5whFVcXFxlDrVajQ4dOkjl5Ovri86dO3M5KRgXkYKYTCb8+OOP0Gg0SE5OxqlTp6osnaZNm1YagbRv3x6enp6oX79+neYtLS1Ffn4+srOzK5Xlr7/++ofbqtVqdOzYEaGhoYiIiICfnx9sbPizFqXgIrJwpaWl2Lt3LzQaDXbs2PGHjfje0vH19YWXl5ds98sQEfLy8nD06NEHlpObmxvCw8MRERGBfv36oV69eoISs5rARWSBCgoKsGPHDmg0Guzduxd37tyRfubq6orQ0FAMGjQIQUFBsi6dh2Uup7S0NCQmJiI5ObnStM7R0RH9+vVDREQEwsPD4eHhITAtexxcRBaipKQEGzduxL///W/8+OOPlX7WsmVLREREICIiAgEBAbC3txeUsm7o9Xrs378fGo0GGo0Gly5dqvRzPz8/xMTE4JVXXoGzs7OglOxRcBHJ3OnTpxEXF4e1a9dCq9VK3/fz85PK57nnnrP4Uc/jIiL89NNPUilVLGkXFxeMGTMGEyZMQPv27QWmZH+Gi0iGysvLsW3bNixbtgypqanS99u0aYMJEyZgxIgRPP24j4KCAiQkJCAuLg45OTnS94ODgzFp0iRERkbCzs5OYEJWFS4iGcnLy8OKFSuwcuVKFBQUALh7gGBkZCQmTpyIPn368CdFD8lkMmHfvn1YtmwZNBqNdACmh4cHYmNjMX78eHh5eQlOySTEhMvOzqahQ4eSWq0mAASA3NzcaNasWZSbmys6nsXLzc2lWbNmkZubm/T4qtVqGjp0KGVnZ4uOx4iIi0igS5cu0dixY8nGxkbaQIKCgmjTpk2k0+lEx1McnU5HCQkJFBgYKD3eNjY2FB0dTZcuXRIdz6pxEQlw/fp1mjJlCtnb20sbxODBgykrK0t0NKuRlZVFgwcPlh5/BwcHmjp1Kt24cUN0NKvERVSHtFotzZ07l1xdXaUNoHfv3pSRkSE6mtVKT0+n4OBg6flwdXWluXPnUklJiehoVoWLqA7odDpasmRJpX0UXbp0oZSUFDKZTKLjWT2TyUS7du0iHx+fSvvoli5dylPkOsJFVMuSkpLI29tbeoG3atWK4uPjyWg0io7G7mE0Gunrr7+u9Hx5e3tTUlKS6GiKx0VUSwoLC2ns2LH8DmuBdDodLV26tNIINjo6mgoLC0VHUywuolqwc+dO8vLyIgCkUqnonXfeIa1WKzoWe0RarZbeeecdUqlUBIC8vLx4dFRLuIhq0L2joNatW9OBAwdq/d/95Zdf6Mknn6SgoCDy9/eno0eP3ve2Y8aMoVOnTlX5s8LCQtq0aZP0/7GxsY+dKTk5mf7zn/881G0DAgIoKCiInn/+eSnbmDFjaMCAAdJt/P39iYjo+++/p2bNmlFQUBAFBQXRmTNnHjvjw9q/fz+1bt2aR0e1iIuohlQ1CiotLa2Tf/uXX36hl156iYiIDh06REOGDLnvbR9URBV/T13S6/VERJSamkoxMTFEdDfnc889RydOnCCiykU0bdq0Os9YWlrKo6NaxOcLVNOtW7cQHR2NsLAw5OXloXXr1ti/fz8WLVokZI2cW7dugf531s6uXbsQEBCAHj16ID4+vtLtrl27hr59+yIwMBBDhgyB0WhEXFwc0tLSEBwcjLNnz6Jr164AgMuXL6NPnz4ICAjAhAkTAABr1qzB4MGDERYWhm7duiE/P7/S71+zZg2WLFkCAGjXrh1eeeUVdOnSBevXr/9DZvO5X8XFxejYsaP0/enTp+PTTz+toUemeurVq4dFixYhLS0NrVu3Rl5eHgYOHIiYmBjcunVLdDzLJ7oJLdnhw4eFjYIqMk/N/Pz86IknnqCTJ0+S0Wik559/nnQ6HRmNRgoMDCSDwSCNiHQ6HZWXlxMR0ZQpU2j37t1/GBH5+voSEdHEiRMpOTmZiIhiYmIoNTWVVq9eTdHR0UREtGLFCvrXv/5VKdPq1atp8eLFRETUsGFDKioqIq1WS927d/9D/l9//ZV69OhBzZo1o8zMTCL6feQWEhJCFy5cqHJqVnHqVpeqGh0dPnxYSBal4BHRY1qzZg2Cg4NlMQoCgKCgIGRkZGDWrFlIT0/HjRs3kJOTg/79+6NPnz64ceMGrl+/Lt3+5s2bGDJkCIKCgrBjx44/jGgqOn/+PLp16wYA6NatG86dOwcA6NKlCwCgefPmKCwsvO/f9/b2hqurK5ydnaXRWkVNmjTBoUOHsGXLFsyYMaPSz6ZNm4YFCxZU+t7w4cORmpqK5OTkP3lUakdVo6Pg4GCsXbtWSB4l4CJ6RAaDAVOnTkV0dDT0ej2ioqJw/Phx9OrVS3Q0AMDEiROxfPlyNGjQAO3atcOePXuQmpqKEydOwN3dXbrdxo0b0b9/f6SlpSE8PBxEBDs7uyrXuG7dujWOHDkCADhy5AjatGkDAJXWQKqqYMwetFZSxUsTNWjQ4A/rZr/wwgs4efIkbty48RD3vm4FBATg2LFjePHFF6HX6zF27FhMmzZNutYbe3hcRI+gsLAQYWFhWLRoEQBg9uzZ2Lx5s6xWAbSzs0NISAi2bt2KmTNnol+/fujduzdeeeWVSrfr27cv4uLiEBkZKS054uHhgbKyMgwZMgQXLlyQbvv+++/j008/lVZ/DAwMrLG8165dQ+/evdG7d29MnDgRf/vb3/5wmzfffBPnz5+vsX+zJrm4uGDLli2YNWsWAGDhwoUICwt74AiR/RGvR/SQ/vvf/yIyMhI5OTmoV68e1q5diyFDhoiOxWTk22+/xZgxY1BWVoY2bdpAo9Ggbdu2omNZBC6ih5CUlISRI0eiuLgYLVq0wPbt2+Hj4yM6FpOh48ePIzIyEpcvX4arqysSEhIQGhoqOpbs8dTsAYgIn332GcLDw1FcXIxevXrhyJEjXELsvrp06YKjR4+iZ8+eKC4uRlhYGBYsWPDAfWgM/PH9/RiNRnrjjTeko2nHjx/P54mxh6bT6WjcuHHS6+eNN97gE50fgIuoCgaDQTpVQ6VS0eLFi3m5DvbITCYTffHFF9LxRmPHjiWDwSA6lizxPqJ7lJeXY/To0UhISIBarca6devw8ssvi47FLNjGjRsxZswYGI1GjBw5EmvXruUridyDi6gCvV6PESNGYOvWrbCzs0N8fDxeeukl0bGYAmzZsgUjRoyAwWBAVFQUEhISFH8hzEfBRfQ/5eXlGD58OLZu3Qp7e3ts2bIF4eHhomMxBUlMTMSQIUOg1+sxePBgbNq0Cba2tqJjyQJ/agbAaDRi9OjR2Lp1KxwcHJCYmMglxGrcoEGDoNFoYG9vj//85z8YPXp0lUeyWyOrLyKTyYTXXnsNCQkJsLW1xebNm9G/f3/RsZhChYSEYPPmzbC1tUV8fDzGjRsnneJizay6iIgIkyZNwtq1a6FWq5GQkMAjIVbrBg0aJH0YsmbNGkyaNMnqjzOy6iJasGABli9fDpVKhXXr1vGOaVZnXnrpJaxbtw4qlQrLly/H559/LjqSUFa7szopKUk663zx4sWYPHmy6EjMCi1evBhvvfUWVCoVdu7cabWng1hlEZ05cwb+/v4oLi7G+PHj8eWXXz5wqQrGagsRITY2FqtWrYKrqysyMjKs8kRZqyuiwsJC+Pv7IycnB7169cK+ffv4eA4mlF6vR9++fXHw4EE888wzSE9PR6NGjUTHqlNWtY/IYDBg+PDhyMnJQYsWLbBlyxYuISac+bi15s2b4+eff8bIkSOtbnE1qyqi9957D3v27EG9evWwfft2NG3aVHQkxgAATZs2hUajgZOTE1JSUvD++++LjlSnrKaI1qxZI62suGbNGl7Kg8mOj4+PtO71woULrWoNbKsooh9++AGvv/46gLvLuw4dOlRwIsaqNnToUGnZ2djYWKSnpwtOVDcUv7P61q1beO6555CXl4eoqChs3rwZNjZW0b/MQplMJrz00kvYtm0bvLy88NNPP6Fhw4aiY9UqxW+RU6dOlS75s27dOi4hJns2NjZYt26ddKmiadOmiY5U6xQ9IkpKSkJYWBhUKhX2798vm0v+MPYwDhw4gKCgIBARkpKSFH2wo2KHB7du3cL48eMBAG+//TaXELM4AQEBeOuttwAA48ePV/SlrRU7IoqJicHq1avRpk0bnDhxQtgVWBmrjtu3b6Nz5844d+4cYmJi8NVXX4mOVCsUWUQ8JWNKYg1TNMVNzXhKxpTGGqZoihsR8ZSMKZHSp2iKKqLk5GQMHDiQp2RMkZQ8RVPM1Eyv10trCvGUjClRxSna5MmTodfrBSeqOYopopUrV+LChQtwc3PD3LlzRcdhrFbMmzcPbm5uuHDhAlatWiU6To1RRBGVlJRI5TN79mw4OzsLTsRY7XB2dpbORfv4449RWloqOFHNUEQR/fOf/8S1a9fQqlUr6RMzxpRq/Pjx8Pb2xrVr1/DPf/5TdJwaYfE7q2/cuAFvb29otVrEx8djxIgRoiMxVuvi4+Px8ssvw9XVFRcuXMATTzwhOlK1WPyIaP78+dBqtejSpQuGDRsmOg5jdWL48OHw8fFBcXEx5s+fLzpOtVn0iCg3Nxdt2rSBXq/Hrl27EBISIjoSY3Vm165dCA0NhYODA37++We0aNFCdKTHZtEjor/+9a/Q6/Xo3bs3X52VWZ2QkBAEBwdDp9Nhzpw5ouNUi8WOiLKzs9GpUyeYTCZkZGTAz89PdCTG6lxGRga6d+8OGxsbnDp1Cu3btxcd6bFY7Ijoo48+gslkwuDBg7mEmNXy9/dHVFQUTCYTPvroI9FxHptFjojy8vLw1FNPwWg0IisrCx07dhQdiTFhTp06hU6dOkGtViM3Nxeenp6iIz0yixwRrVy5EkajEUFBQVxCzOp17NgRgYGBMBqNWLlypeg4j8Xiiqi8vBwrVqwAAEycOFFwGsbkwbwtfPnllygvLxec5tFZXBFt27YNBQUFcHd3x4svvig6DmOyEBUVBTc3NxQUFGD79u2i4zwyW9EBHtWyZcsA3D3MnS8XXTfu3LmDq1evIj8/HwUFBcjPz8dvv/2G8vJy6dLItra2sLOzwxNPPAFPT094eHjA09MT7u7ucHR0FHwPlM/e3h7jx4/HvHnzsGzZMgwZMkR0pEdiUTurT58+jQ4dOkCtVuPixYto1qyZ6EiKc+3aNWRmZuLo0aPIzMxEZmYm8vLyqvU7vby84OvrC19fX3Tt2hW+vr5wc3OrocTM7PLly2jZsiVMJhNOnz6Ndu3aiY700CxqRBQXFwcAiIiI4BKqITqdDmlpadBoNNi5cycuXrxY5e0cHBykUY6HhweaNGkCe3t72NrefQkZDAbo9Xpcv35dGjkVFBRAp9MhLy8PeXl50Gg00u9r2bIlwsLCEBERgaCgIDg4ONTF3VW05s2bIyIiAtu2bUNcXBy++OIL0ZEemsWMiEpKSuDp6QmtVos9e/agX79+oiNZrLKyMmzduhVbt25FSkoKtFqt9DOVSoW2bdtKIxhfX1+0b98ejRs3hkqleqR/h4hw8+ZNnD59WhpdZWZm4syZM6j4snNxccGAAQPw4osvIioqCk5OTjV2X63Nnj170L9/f7i6uiIvL89ylsQhC7F8+XICQM888wwZjUbRcSzSuXPn6N1336XGjRsTAOnL3d2dxo8fT4mJiVRcXFzrOYqLiykxMZHGjx9P7u7ulbI0btyYpk+fTufOnav1HEpkNBqpTZs2BIC+/PJL0XEemsUUkZ+fHwGghQsXio5iUUwmEyUlJdGAAQMqbfAtWrSgmTNn0o8//ii02I1GI2VkZNDMmTOpRYsWUj6VSkWhoaGUlJREJpNJWD5LtHDhQgJA/v7+oqM8NIsoovz8fOkFmp+fLzqOxThw4AD17NmzUgENGDCANBoNGQwG0fH+wGAwkEaj+UNp9uzZkw4cOCA6nsWouL0UFBSIjvNQLKKIVqxYQQDIz89PdBSLkJWVRWFhYdKL0cnJiaZMmWJR052cnByaMmUKOTk5SfcjPDycsrKyREezCN26dSMAtHLlStFRHopFFFF4eDgBoHnz5omOImtFRUUUGxtLKpWKAJBarabXX3+d8vLyREd7bHl5efT666+TWq2WpmyxsbFUVFQkOpqszZ07lwDQoEGDREd5KLIvopKSEnJ0dCQA/G74ACkpKdS8eXNp9DBs2DD6+eefRceqMWfPnqVhw4ZJ96958+aUkpIiOpZsnTx5kgCQo6MjlZaWio7zp2RfRNu2bSMA1LJlS95pWYWioiIaN26ctIF6e3tTWlqa6Fi1Ji0tjby9vaX7O378eB4dVcFkMtFTTz1FAGj79u2i4/wp2Z9rlpiYCODuQYyPehyL0mVmZqJjx47S9a3efPNNZGVlITAwUHCy2hMYGIisrCy8+eabAO6uxNCxY0ccO3ZMcDJ5UalUiIiIAPD7NiRropvwQYxGIzVt2pQA0J49e0THkZX4+Hhpyurt7U2pqamiI9W51NRUaXTk5ORECQkJoiPJyu7duwkAubm5yf7YO1kX0Q8//EAAyNXVlXQ6neg4smA0GmnGjBnS1CQ0NJRu3bolOpYwhYWFlT7unzlzpuw3urqi0+nIxcWFAFB6erroOA8k66mZ+dyk0NBQPtMeQGlpKaKiovDJJ58AAN577z0kJiaiQYMGgpOJ07BhQ+zYsQPTp08HAPztb39DVFSUYq6AWh329vYIDQ0FgErn+cmS6CZ8EB8fHwJAGzZsEB1FuKKiIgoICCAA5ODgQOvXrxcdSXbWrVtHDg4OBIACAgLq5HQVuduwYQMBIB8fH9FRHki2J72WlZXBxcUFRqMRly9ftuqz7YuKihASEoKMjAy4uroiOTkZPXr0EB1Llg4fPozQ0FAUFxfD398fKSkpVj1ivHz5Mlq0aAG1Wg2tVivbE4plOzU7efIkjEYjmjZtCi8vL9FxhCkpKcHAgQORkZGBRo0a4bvvvuMSeoAePXpg3759aNSoETIyMjBw4ECUlJSIjiVMs2bN0KRJE+lCE3Il2yLKzMwEAPj6+lrtx/Y6nQ4RERE4fPgwGjZsiH379sHX11d0LNnr2rUr9u3bh4YNG+Lw4cOIiIiATqcTHUsIlUolvWbM25QcWUQRWSMiwqRJk/D999/DxcUFKSkp6NKli+hYFqNLly5ISUmBi4sLvv/+e0yePBky3QtR67iIqsH8oHXt2lVwEjGWLFmCr776CjY2Nvjmm2/4IpKPwc/PD5s2bYJKpcKqVauwdOlS0ZGEMG9Dci4iWX5qdvv2bekkx8uXL4uOU+f27Nkj3f8FCxaIjmPxPvvsM+kk4L1794qOU+dyc3MJANna2tLt27dFx6mSLIvIfCBj06ZNre78svPnz1OjRo0IAI0ePdrq7n9tMJlMNGrUKAJAjRo1ovPnz4uOVKdMJhM1adJE1gc2ynJqZq07qk0mE8aMGYPCwkL4+/vjyy+/tKr7X1tUKhVWrFgBPz8/FBYWYsyYMTCZTKJj1RlL2GEt+yKyJl988QUOHjwIZ2dnbNq0ia8HVoMcHR2xadMmODs74+DBg1i8eLHoSHWKi+gxWOOO6pycHMyYMQMAsGDBAjz11FOCEylPy5Yt8dlnnwEAPvjgA+Tk5AhOVHfkvsNadkVERDh//jwAoH379oLT1A2TyYSYmBiUlZWhb9++iI2NFR1JsWJjY9GnTx+UlZUhJibGaqZoHTp0AABp25Ib2RWRVquVTlj09PQUnKZurFq1SpqSffXVV7xfqBbZ2Njgq6++kqZoX331lehIdcLDwwPA3SP1K17HTi5kV0QFBQUAAFdXV9SvX19wmtp3+/ZtzJkzBwAwd+5cnpLVgZYtW2Lu3LkAgDlz5uD27duCE9U+Z2dnuLi4APh9G5MT2RVRfn4+gN8bXOm++OILFBQUoGXLlpgwYYLoOFZjwoQJaNmyJfLz861mx7V5mzJvY3IiuyIyt7U1TMtu3ryJv//97wDujob4+u91x8HBAR9//DEA4O9//zsKCwsFJ6p95m2KR0QPwZpGRP/4xz9QVFSEjh07YuTIkaLjWJ2XX34Zzz33HG7duiW9ISgZj4gegbmtlV5ExcXF0rlPn3zyCdRqteBE1ketVmP+/PkAgGXLlqG4uFhwotpl3qZ4RPQQrGVqtn79epSWlqJdu3YICwsTHcdqhYWFoW3btigpKcGGDRtEx6lVPDV7BNYwNSMiLFu2DAAwceJE/rheIJVKhYkTJwK4OyoiBS8VwlOzR2ANI6K0tDScPn0a9evXx6hRo0THsXqjR49GvXr1kJ2djf3794uOU2t4RPQIrl69CgBwd3cXnKT2mEdDr776qlWvpywXDRo0wKuvvgrg9+dGiczblHkbkxPZLZ7v4OAAvV6P3NxcNG/eXHScGldSUoInnngCer0ex44d41UXZeL48eP4y1/+AgcHB/z222+KPJg2NzcXTz31FBwcHHDnzh3RcSqR3YjIYDAAAGxtbQUnqR179uyBXq9Hq1at4OPjIzoO+x8fHx94e3tDp9Nhz549ouPUCvM2Zd7G5ERWRWQymaSTEJVaROYL3Q0aNIh3UsuISqXCoEGDAFjAxQgfk3mbMhqNstspL6siMhqN0p+VWERGoxE7duwAAERERAhOw+5lfk527NhR6bWoFBW3KbndP1kVUcUhoxKLKD09HTdu3EDDhg3Rq1cv0XHYPQICAtCgQQNcv34dGRkZouPUuIrbVHl5ucAkfySrIlK67777DgAQEhICOzs7wWnYvezs7BASEgIA2Ldvn+A01kVWRVSxseW4Q626jh49CgDo3r274CTsfszPjVxXMqyOituU3N4IZVVEFc+3UmIRWeta3JZE7ms7V0fFbUpu5zbKqohsbGxgY3M3ktKK6Nq1a8jLy4NKpeJjh2SsS5cuUKlUuHLlCn799VfRcWqUeZtSq9Wy+8RWVkUEyPtYh+owv8O2bdsWzs7OgtOw+3FxccGzzz4LQHmjIjkfoye7IjJfQkdpy3eePHkSAHg0ZAH+8pe/APj9OVMK8zYlx8tUya6I5Hw+THXk5eUBuLteMpM387rh5udMKeR8HqfsikjOSxVUh7Us+KYEcl5ArDrkvMSO7IpIzksVVIc1LG+iFPwarHuyKyKljohq6t3o4sWLaNKkCYKDg9G9e/cH7lAdO3Ysfvrppyp/duvWLXzzzTfS/7/++uvVynWvh/19c+bMQceOHREcHIygoCDpcbpy5QoGDx4s3c/NmzcDuHtO2KZNmwAAZ86cwdixYwHcva/dunVDcHAwoqOjq5WdX4N1T7ZFpKR3IyKS5uc18SIICgpCamoqFi5c+NiLvt9bRF9++WW1c1X0KL9v/vz5SE1Nxbhx47B69WoAd4vlr3/9K1JTU3HgwAE0bdoUAPD0009jyZIlVf6e1atXIzU1Vfodj0uJr0FA3rsHZFdEShwWm0wm6HQ6AJAuclcTbt26JZ1FvWvXLgQEBKBHjx6Ij4+vdLtr166hb9++CAwMxJAhQ2A0GhEXF4e0tDQEBwfj7Nmz0rXRL1++jD59+iAgIEC6ztqaNWswePBghIWFoVu3bsjPz8fNmzcRHByM4ODgKk/gNf++sWPHYvz48ejXrx8iIyMfeNa3VquFi4sLcnNz0aBBA3Tu3BnA3aOAAwMDAQCNGzeGj48Pdu/eXc1H7/7Mz5FOp1PUJal5avYIlDgsrumTedPS0uDv74/Ro0dj9uzZMJlM+Pjjj7Fv3z4cPHgQy5cvr3R2daNGjZCSkoL9+/ejRYsW+O677zBhwgRpZGU+bga4e42v9957DwcOHIBer0daWhoAoGHDhti5cydiY2OxefNmHD9+HF27dkVqaiq2bdv2wLwBAQHYu3cvnJ2dcerUqT/8/IMPPkCPHj3wySefYOjQoSgoKHjgxjJt2jR8/vnnf/h+dHQ0goOD8a9//evPHsIHUuqpRjw1ewRKHBFVLIWaOLQ+KCgIGRkZmDVrlnRGf05ODvr3748+ffrgxo0buH79unT7mzdvYsiQIQgKCsKOHTseWPLnz59Ht27dAADdunXDuXPnAPx+/FPz5s1RWFiIoKAgNGjQAGPGjMHChQsfmPfev3uv+fPn4/Dhw1i+fDk+/PBDeHp6PvCj85YtW+LJJ5/EkSNHKn3fPDV7++23H5jnzyj1VCMeET0Cc1sXFxejtLRUcJqaUfGFXZPrwEycOBHLly9HgwYN0K5dO+zZswepqak4ceJEpWNFNm7ciP79+yMtLQ3h4eEgItjZ2VWZpXXr1tIGfuTIEbRp0wYAKp0SQEQoLy/HrFmzsHbtWuzevRu5ubn3zXnv372fhg0b4ubNm2jevDm0Wq10QKHBYMCBAwcq3fa9997Dp59++qCH57EpcV2skpISaLVaADwieiguLi7SesFKmZ7V1lDfvGzF1q1bMXPmTPTr1w+9e/fGK6+8Uul2ffv2RVxcHCIjIyvtsCwrK8OQIUNw4cIF6bbvv/8+Pv30UwQEBMDe3l7aN3OvI0eOICAgAM8//zyefPJJNGvW7LHvxwcffIDg4GC8++67mDFjBoC7o5s5c+YgODgYgYGBlUZ4ANC5c+dq/ZsPosR1sczPu7Ozc43up6wpsls8H7j7IsvKysK2bdsQGRkpOk61ERGcnJyg0+nwyy+/8NHVMvfLL7/A29tblovMP65t27YhKioKnTt3xokTJ0TH+QPZjYiA35diMK/fY+lUKpU0VVLSvi+lkvPH3I/LvC3JdQkaWReRks5+VuJOeKWS807dxyX3tbBkX0QynDk+FiUelqBUcv6Y+3EQERfR4+jcuTPUajV+/fVXxZwBrdSjdZVIaVOzK1eu4Pr167C1tUWnTp1Ex6mSLIvIyckJHTp0AKCc6ZmXlxeAu+eKMXm7dOkSgN+fM0tn3oY6dOgAJycnwWmqJssiApS3w9p8usLx48cFJ2F/5tixYwB+f84sndx3VAMWUERKGRGZ78+ZM2dQUlIiOA27H61Wi7NnzwKQ94b7KOS+fwiwkCJSwg5rNzc3eHl5gYh4VCRjx48fBxGhWbNm0hn/lswSdlQDMi4iJe6wVtooT4ksYaN9FOYd1Wq1WrY7qgEZF5GTkxM6duwIANIZ4JbOvDRGenq64CTsfszPjVKKaP/+/QCAjh07ynZHNSDjIgKA0NBQAEBiYqLgJDWjT58+AICUlBTZXXuc3b0efEpKCoC75+cpgUajAQAMHDhQcJIHk3URmRfcSk5Ohl6vF5ym+rp3744nn3wSt27dwsGDB0XHYfc4cOAAioqK0KRJE/j7+4uOU216vR7JyckAUOXidXIi6yLy8/ND06ZNUVxcLA0xLZlarUZ4eDiA39+pmHyYn5Pw8HDZXZL5caSlpUGr1cLNzU1aY0quZF1ENjY2GDRoEADlTM/M70yJiYmK+DRQKYhIKiK5jx4elnmbGTRokHQpd7mSdzpAKiKNRqOIDfeFF16Avb09zp8/L8vlGKzViRMn8Msvv8DBwQEvvPCC6DjVVrFYzduQnMm+iPr16wdHR0dcvHjxvpfGsSTOzs7SGks1feUM9viWL18OAIiMjJQW5rNkp06dwqVLl+Do6Ih+/fqJjvOnZF9E9evXlx5IpexXmThxIgBgw4YNKCoqEpyGFRUVYcOGDQB+f24snXlbeeGFF1CvXj3Baf6c7IsI+H3OrpQiCgoKQvv27VFaWor169eLjmP11q1bh9u3b6NDhw73XRrX0lja/i6LKCLzJ00//vijIpbRUKlU0jvvsmXLFLHvy1IREZYtWwbg7mio4kL/lio/P1+6AIJ525E7iygiDw8P+Pn5AQASEhIEp6kZo0aNQv369fHf//4XO3fuFB3Hau3cuRNnzpyBs7MzXn31VdFxaoT5ktz+/v6VruYiZxZRRAAQExMDAIiLi1PE1TddXV0xadIkAMCMGTNq9DJD7OEYjUZ88MEHAO6OhlxdXQUnqj6TyYS4uDgAv28zFoEshFarJRcXFwJAe/bsER2nRvz222/UsGFDAkDr168XHcfqrFu3jgBQw4YN6ebNm6Lj1Ijdu3cTAHJ1dSWtVis6zkOzmBGRs7MzxowZAwDSnN7SNW7cGO+//z4AYNasWdDpdIITWQ+dTodZs2YBAP7v//4PjRo1EpyoZpi3jTFjxsDZ2VlwmkcgugkfRXZ2NgEgGxsbunz5sug4NaK0tJQ8PDwIAC1atEh0HKuxaNEiAkCenp5UWloqOk6NyM3NJRsbGwJAp0+fFh3nkVjMiAgA2rdvj+DgYJhMJqxYsUJ0nBpRr149zJkzB8DdURGvaV37Ll68KI2G5syZYxHH2TyMFStWwGQyoXfv3mjXrp3oOI9GdBM+qm+++YYAkLu7O+l0OtFxaoTRaKRevXoRAOrbty+ZTCbRkRTLaDRSnz59CAAFBASQ0WgUHalG6HQ6cnNzIwD07bffio7zyCyuiPR6vTSV2bRpk+g4Nebnn38mJycnAkDLly8XHUex4uLiCAA5OTlRTk6O6Dg1JiEhQZpq6vV60XEemUVNzQDAzs4OsbGxAJSz0xoA2rRpg08++QQA8O677/IUrRZcvHgR06dPBwDMnz8frVu3Fpyo5pi3hdjYWNjZ2QlO8xhEN+HjuHLlCqnVagJAWVlZouPUmIpTND8/PyorKxMdSTHKysrIz89PcVMyIqKsrCwCQGq1mvLy8kTHeSwWWUREREOHDiUANHjwYNFRatT58+epUaNGBIBGjRrF+4tqgMlkolGjRhEAatSoEZ0/f150pBoVFRVFAGjYsGGiozw2iy2in376SfqoMiMjQ3ScGrV3715pxLdgwQLRcSzeZ599Jo0Y9u7dKzpOjUpPT5cOacnOzhYd57FZbBEREY0dO5YAUO/evRU3cvjiiy+kF1hycrLoOBYrKSmJVCoVAaDFixeLjlOjTCYTBQcHEwCKjo4WHadaLLqILl26RA4ODgSAdu3aJTpOjTKZTPTaa68RAHJxcVHcqK8upKenS6cFjRs3TnFvVsnJyQSAHBwcKDc3V3ScarHoIiIimjp1KgEgHx8fRe2AJCK6c+cO9e7dWzof6tixY6IjWYxjx45J5/H17t1bMcecmRmNRurcuTMBoGnTpomOU20WX0TXr18nV1dXAkDx8fGi49Q4rVZLPXr0kHa0HjlyRHQk2Tty5Ii0w79nz54WdfLnw/r666+lk1tv3LghOk61WXwRERHNnTuXAFCrVq0U985HRHTr1i3y9/eXXniHDh0SHUm2Dh48KL0x+fv7061bt0RHqnE6nY68vb0JAM2bN090nBqhiCLSarXS4e1Lly4VHadWFBcXU0BAgLRPYN26daIjyc7atWulfYaBgYFUXFwsOlKtWLJkCQEgNzc3KikpER2nRiiiiIgqPzlKHIoTEZWUlFBERAQBIAA0ffp0MhgMomMJZzAY6N1335Uel4iICMVsoPdS6puuYoqo4nD1nXfeER2n1hiNRpo5c6a00YWGhlJhYaHoWMIUFhbSgAEDpMfjww8/VNyHFhW9/fbb0m4ISzyn7H4UU0REd48ZAUAqlYoOHDggOk6tSkhIkE6Sffrppyk1NVV0pDr3/fff09NPPy2dxJqQkCA6Uq3av3+/dExUUlKS6Dg1SlFFREQUHR1NAKh169aKWfDqfjIzM6lFixbSaGDy5MmKnZJUVFJSQpMnT5bud4sWLSgzM1N0rFpVWlpKrVu3JgAUExMjOk6NU1wRFRYWkpeXl+KnaGZFRUU0fvx4aaP09vZW9OgoNTVVmoIDoNjYWCoqKhIdq9aZp2ReXl6KnIorroiIrGuKZpaSkkLNmzeXNtChQ4fS2bNnRceqMWfPnpVOdAZAzZs3p927d4uOVSeUPCUzU2QREVnXFM2sqKiIYmNjpRetWq2m2NhYi10agujuki+xsbHSScAqlcpqRkFEyp+SmSm2iKxtilZRVlYWhYeHS6MHJycnmjJlikWtSJiTk0NTpkwhR0dH6X4MGjRIUetPPQylT8nMFFtERNY5RavowIED1LNnT2lDBkAhISG0fft2WR5/ZDAYaPv27RQSElIpc8+ePa3y+bOGKZmZoouIqPIUTalH2j6IyWSipKQkCg0NlV7U5k+aZsyYQRkZGUKPuzEajZSenk4zZsyo9AmgSqWigQMHUlJSkuLOmn8YxcXFVjElM1N8EVWcor344ouKPtjtz5w7d46mT59OjRs3rjTicHd3p3HjxpFGo6mTsi4uLiaNRkPjxo2TjhI2fz3xxBP03nvvKW4VxUdhNBopMjLSKqZkZioiogetaa0EP/zwA4KDg6HX6zF79mx89NFHoiMJVVZWhq1bt2Lbtm3YtWsXtFqt9DOVSoVnn30Wvr6+0leHDh3QuHFjqFSqR/p3iAg3b95EdnY2MjMzpa+zZ8+i4svOxcUFoaGhiIyMxODBg+Ho6Fhj99USzZ49G3PnzoW9vT3S0tLQvXt30ZFqnVUUEQCsWbMG0dHRAIBvvvkGQ4cOFZxIHvR6PdLS0qDRaLBjx477Xj3EwcEB7u7u8PT0hIeHB5o0aQJ7e3vY2toCAAwGA/R6Pa5fv478/HwUFBSgoKAAer2+yt/XsmVLhIeHIyIiAkFBQbC3t6+tu2hRvvnmGwwfPhzA3des+TLrSmc1RQQAU6dOxaJFi1CvXj0cOnQIPj4+oiPJzrVr1yqNXjIzM3HlypVq/c5mzZpJo6uuXbvC19cXTZs2raHEynH8+HH07NkTZWVlmDp1Kj7//HPRkeqMVRWRwWBAWFgYdu/ejRYtWuDIkSO8QTwEnU6Hq1evSiOd/Px83LhxAwaDAeXl5QDuXm/O1tYWTz75pDRq8vT0hLu7OxwcHATfA/m7du0aunXrhsuXLyMkJAQ7duyQRpvWwKqKCAAKCwvh7++PnJwc9OrVC/v27eNpARNKr9ejT58+OHToEJ555hlkZGSgYcOGomPVKYu70mt1NWrUCBqNBq6urjh48CAmT54MK+tiJiNEhEmTJuHQoUNo0KABNBqN1ZUQYIVFBABt27ZFfHw8VCoVVq5ciaVLl4qOxKzUkiVLsGrVKqhUKsTHx+PZZ58VHUkIqywiABg4cCD+8Y9/AADeeustfP3114ITMWuzceNGvP322wCATz/9FKGhoYITCSTi4CW5MJlM9MYbb0gniG7evFl0JGYlvv32W+lE3jfeeMMqjx6vyOp2Vt/LZDLhtddew5o1a2Bra4utW7ciPDxcdCymYImJiRg8eDAMBgOio6OxatUq2NhY7eQEgBV+alYVo9GIV199FQkJCbC3t4dGo0FISIjoWEyBUlJSEBERAb1ej5EjR2L9+vVQq9WiYwln3TX8P2q1GuvWrUNUVBT0ej0iIiKwY8cO0bGYwiQmJkolNHjwYKxbt45L6H+4iP7Hzs4OCQkJUhlFRUVhy5YtomMxhdi8eTMGDx4slVB8fLxVHbD4Z7iIKrC3t8emTZswYsQIGAwGDB8+nD9NY9W2ceNGDB8+HAaDASNHjsSmTZv4INp7cBHdw87ODhs2bMDYsWOlfUeLFy/mgx7ZIyMiLF68GKNGjYLJZEJ0dDTWr1/PI6GqiPzITs6MRqP00T4AGjduHOl0OtGxmIXQ6XQ0btw46fXzxhtvWPVaWH+Gi+gBTCYTffbZZ9LKhr169aJr166JjsVk7tq1a9ISvTY2NrRgwQKrP07oz/DH9w8hKSkJI0eORHFxMVq0aIHt27fzEiKsSsePH0dkZCQuX74MV1dXJCQkWPcR0w+J9xE9hIEDByIjIwNt2rRBbm4uevbsiW+//VZ0LCYz3377LXr27InLly9LZ9FzCT0cLqKH1LZtW2RkZKB///64ffs2hg0bhtmzZ8NkMomOxgQzmUyYNWsWhg0bhrKyMoSEhCA9PR1t27YVHc1yiJ4bWpry8nKaOnWqtBPyxRdfJK1WKzoWE6S4uFha6B4ATZs2jcrLy0XHsjhcRI9p9erVZG9vL12qyBqvu2Xt9u/fL13yx97entasWSM6ksXiIqqGw4cPS5cqUqlU9M4771jN5a2tWWlpKb399tvSp6leXl70ww8/iI5l0biIqqmwsFC6iCOPjpRv//791KpVK+n5jomJsYrrjtU2LqIasnPnTh4dKVhVoyClXwa6LnER1SAeHSkTj4JqHxdRLahqdMSfrFkerVbLo6A6wkVUS+4dHbm5udGSJUv4fDULoNPpaMmSJeTm5sajoDrCRVTLkpKSyNvbW3pBe3t709dff80nQMqQ0WikjRs3/uH54lFQ7eMiqgM6nY6WLl1a6R22S5cutGvXLj4ZUgZMJhMlJyeTj49PpRHssmXLeARbR7iI6pBWq6V58+aRq6ur9IIPDg6m9PR00dGs1g8//EDBwcHS8+Hq6krz5s2jkpIS0dGsCheRANevX6epU6eSg4ODtAFERUVRVlaW6GhWIysri6KioqTH38HBgaZNm0Y3btwQHc0qcREJdOnSJYqOjiYbGxtpgwgMDKSEhASeEtQCnU5H8fHxFBAQID3eNjY2FBMTQ5cuXRIdz6pxEclAdnY2DRs2TLrgnnkfxYcffki5ubmi41m83Nxc+vDDDyvto1Or1TRs2DDKzs4WHY8RL4wmK3l5eVi5ciVWrFiBgoICAICNjQ0iIiIwceJE9O3b1+ovxPewTCYT9u7di2XLliExMVFarsXT0xOxsbEYN24cvLy8BKdkZlxEMlReXo7t27dj2bJl+P7776Xvt2nTBhMmTMCIESPg4eEhMKF8FRQUICEhAXFxccjJyZG+37t3b0yaNAkRERGws7MTmJBVhYtI5k6fPo3ly5dj7dq1KC4ulr7frVs3REREICIiAh07doRKpRKYUhwiwqlTp6DRaKDRaHDkyBHpZ66urhgzZgwmTJiAdu3aCUzJ/gwXkYUoKSnB119/jX//+9/IyMio9LOnnnpKKqXAwEDFXzNLr9cjLS0NGo0GiYmJuHTpUqWf+/v7IyYmBi+//DKcnZ0FpWSPgovIAhUUFGDnzp3QaDTYs2cP7ty5I/3M1dUVAwYMkEqpWbNmFj9aIiJcuXIF+/fvh0ajwa5duyqNDh0dHfHCCy8gIiICYWFhPG21QFxEFu727dvYu3cvNBoNduzYgWvXrlX6eZMmTeDr64uuXbvC19cXvr6+si4nc+lkZmbi6NGjyMzMRGZmJq5fv17pdm5ubhg0aBAiIiLQt29f1KtXT1BiVhO4iBTEZDLhyJEj0Gg0SEpKwqlTp2A0Gv9wO3M5mQuqQ4cO8PDwqPNpTElJCQoKCpCdnf3A0gEAtVqNjh07YuDAgYiIiEC3bt34E0QF4SJSsLKyMmRlZUkbeGZmJn766acqywkAXFxc4OHhAU9PT3h4eFT6s6enJ9zd3VGvXj3Y2tpW+gIAg8FQ6ev27du4evUq8vPzUVBQIP234p+1Wm2VOdRqNZ577jmpLH19fdGpUyc4OTnV2mPFxOIisjJVldO5c+dQWloqJE/9+vXRunXrSiO0Tp06wdHRUUgeJgYXEQMAaLXaSqOVqkYwV69exZ07d2AwGO47qlKr1bC1tYWjoyPc3d0fOMLy8PCAi4tLHd9TJkdcROyxEBGMRiPKy8sBAHZ2dlCr1bLdCc7kjYuIMSYcf+zAGBOOi4gxJhwXEWNMOC4ixphwXESMMeG4iBhjwnERMcaE4yJijAnHRcQYE46LiDEmHBcRY0w4LiLGmHBcRIwx4biIGGPCcRExxoTjImKMCcdFxBgTjouIMSYcFxFjTDguIsaYcFxEjDHhuIgYY8JxETHGhOMiYowJx0XEGBOOi4gxJhwXEWNMOC4ixphwXESMMeG4iBhjwnERMcaE4yJijAnHRcQYE46LiDEm3P8D1K8duNAF+K4AAAAASUVORK5CYII=",
      "text/plain": [
       "<Figure size 300x300 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(3, 3))\n",
    "\n",
    "# Circle B (outer) - Relations in 3NF\n",
    "circle_b = plt.Circle((0.5, 0.5), 0.4, fill=False, color='black', linewidth=1.5)\n",
    "ax.add_patch(circle_b)\n",
    "\n",
    "# Circle A (inner) - Relations in BCNF, fully inside B\n",
    "circle_a = plt.Circle((0.5, 0.45), 0.2, fill=False, color='black', linewidth=1.5)\n",
    "ax.add_patch(circle_a)\n",
    "\n",
    "# Label inside A\n",
    "ax.text(0.5, 0.45, \"Relations in BCNF\", ha='center', va='center', fontsize=6)\n",
    "\n",
    "# Label inside B but outside A (near the top of B)\n",
    "ax.text(0.5, 0.82, \"Relation in 3NF\", ha='center', va='center', fontsize=6)\n",
    "\n",
    "ax.set_xlim(0, 1)\n",
    "ax.set_ylim(0, 1)\n",
    "ax.set_aspect('equal')\n",
    "ax.axis('off')\n",
    "\n",
    "plt.tight_layout()\n",
    "plt.savefig('normal_forms.png', dpi=150)\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "a9479747-a040-4d74-a296-29c2a6787361",
   "metadata": {},
   "source": [
    "We are given a relation R and a set F of functional dependencies.\n",
    "\n",
    "The closure F+ of F is the set of all functional dependencies implied by F.  \n",
    "Check if X->Y is in F+, I can find the closure X+ of X, check if Y is in the X+.\n",
    "\n",
    "   R(A,B,C,D,E,F) F={A->BC, AD->F}\n",
    "\n",
    "   Is ABD-> ACEF implied by F?\n",
    "   ABD+ = {A,B,C,D,F}\n",
    "   No, because ACEF is not a subset of ABD+                   \n",
    "\n",
    "   ACD -> BF implied by F?\n",
    "   ACD+ = {A,C,D,B,F} BF is in ACD+, so ACD->BF is implied by F.\n",
    "\n",
    "**Two set of functional dependencies F1 and F2 are equivalent** if they have the same closure. Equivalent set of fds have the same meaning, same implications.\n",
    "\n",
    "$$F1 \\equiv F2 \\mbox{ iff } (F1)+ = (F2)+$$\n",
    "\n",
    "Another way to test if F1 and F2 are equivalent is to test:  \n",
    "1. All fds X->Y in F1 are implied by F2, and\n",
    "2. All fds X->Y in F2 are implied by F1.\n",
    "\n",
    "If all these are true then, these two sets are equivalent.  \n",
    "\n",
    "\n",
    "A set F of functional dependencies is said to be **minimal** if there is no way to simplify F to get F' where F is equivalent to F. Possible simplifications include:  \n",
    "\n",
    "1. removing an fd  \n",
    "2. removing an attribute on the right hand side of an fd  \n",
    "3. removing an attribute on the left hand side of an fd.  \n",
    "\n",
    "A set of fds F is said to be **a basis** if there is only one attribute on the right hand side of all fds. Note that you can easily put an fd in this form using the decomposition rule. \n",
    "\n",
    "Algorithm for finding a minimal basis of an input set F of functional dependencies:\n",
    "\n",
    "1. Put F in basis form\n",
    "2. Remove all trivial fds from F\n",
    "3. For all fds of the form XZ->Y in F, try replacing it with X->Y to get F'.\n",
    "    Check X+ in F and X+ in F', if it is the same, then we can remove Z."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "58bae841-4286-4f7b-8f10-ca02886ba7ef",
   "metadata": {},
   "source": [
    "F1={A->B, B->C}, F2={A->B, A->A, B->C, AB->AB}\n",
    "\n",
    "Is F1 equivalent to F2? Yes!\n",
    "\n",
    "F1={A->B, B->C}, F3={A->B, B->C, AB->C}\n",
    "\n",
    "Is F1 equivalent to F3? Yes, because AB->C is implied by F1.\n",
    "\n",
    "Is AB->C implied by F1?  Given F1, AB+ = {A,B,C}, C is in AB+, AB->C is implied by F1.\n",
    "\n",
    "F1={A->B, B->C}, F4={A->B, B->C, C->A}\n",
    "\n",
    "Is C->A implied by F1? Using F1, C+ = {C}, Using F4, C+={A,B,C}\n",
    "\n",
    "\n",
    "F5={A->BC, C->A}, F4={A->B, B->C, C->A}\n",
    "\n",
    "IS F5 Equivalent to F4?\n",
    "\n",
    "1. Given F5:\n",
    "A->BC implied by F4? Yes\n",
    "C->A implied by F4?   Yes\n",
    "1. Given F4:\n",
    "A->B implied by F5?  Yes\n",
    "B->C implied by F5?   In F5, B+ = {B} **NO!!!**\n",
    "C->A implied by F5?  Yes\n",
    "\n",
    "No, they are not equivalent.\n",
    "\n",
    "\n",
    "How can we simplify F={A->B, A->A, AB->C, AB->AB, A->C} ?\n",
    "\n",
    "\n",
    "1. Remove all trivial fds  F={A->B, AB->C, A->C}\n",
    "2. \n",
    "\n",
    "Can I remove AB->C?  F1={A->B, A->C}, Does F1 imply AB->C?  AB+={A,B,C} Yes\n",
    "Can I remove A->C?   F2={A->B, AB->C} Does F2 imply A->C?   A+={A,B,C} Yes\n",
    "\n",
    "Assume, we take F2, F2={A->B, AB->C} \n",
    "\n",
    "3. Can I remove A from AB->C?  No\n",
    "\n",
    "F2={A->B, AB->C}  B+= {B}\n",
    "F3={A->B, B->C}   B+= {B,C}\n",
    "\n",
    "3. Can I remove B from AB->C? \n",
    "\n",
    "F2={A->B, AB->C}   A+={A,B,C}\n",
    "F3={A->B, A->C}    A+={A,B,C}\n",
    "\n",
    "Yes, final result:  {A->B, A->C}   or {A->BC}\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7ea95651-04f7-439a-b598-dafa31c1dbc4",
   "metadata": {},
   "source": [
    "F={AB->CD, ABD->ACE, AB->E}\n",
    "\n",
    "1. Put it in basis form\n",
    "\n",
    "F={AB->C, AB->D, ABD->A, ABD->C, ABD->E, AB->E}\n",
    "\n",
    "2. Remove trivial fds\n",
    "\n",
    "F={AB->C, AB->D, ABD->C, ABD->E, AB->E}\n",
    "\n",
    "3. Which fds are implied by the rest?\n",
    "\n",
    "F={AB->D, ABD->C, ABD->E}\n",
    "\n",
    "4. Which fds can be simplified on the left hand side?\n",
    "\n",
    "F={AB->D, AB->C, AB->E}\n",
    "\n",
    "5. Use combining rule for all fds. with the same left hand side\n",
    "\n",
    "F={AB->CDE}"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "56f37f2c-05c8-43ed-8cba-d1d9eda7800f",
   "metadata": {},
   "source": [
    "Given a relation R and a set of functional dependencies F, **a decomposition** of R is a set of relations R1, R2, ... Rn such that\n",
    "1. R1, R2, .., Rn all contain attributes of R and \n",
    "2. the set of all attributes in R1, R2, .., Rn is the set of all attributes in R. \n",
    "\n",
    "A decomposition is computed by projecting R into the attributes in each relation:\n",
    "Given a decomposition R1(A,B) and R2(B,C) of R(A,B,C):\n",
    "\n",
    "we compute R1 = PROJECT_(A,B) (R) and R2 = PROJECT_(B,C) (R)\n",
    "\n",
    "A decomposition R1, R2, ... Rn of R with functional dependencies F is said be lossless iff R1 * R2 * .. * Rn = R for all instances of R.\n",
    "\n",
    "---- \n",
    "\n",
    "Chase algorithm for checking whether a decomposition R1,R2,...,Rn is lossless (given a set of functional dependencies)\n",
    "\n",
    "1. First construct a canonical database with a single tuple for each relation in the decomposition, each tuple for relation Ri is going to have attributes in Ri with no subscripts and the attributes not in Ri with a new subscript\n",
    "\n",
    "2. Use the functional dependencies such as X->Y to find two rows with the same X value, and we will make Y values the same (if one of the Y has no subscript, then make the other one also no subscript, known!, otherwise they should have the same subscript)\n",
    "\n",
    "3. Apply until no more changes are possible. \n",
    "   - If there is a row with no subscripts, then this decomposition is lossless.\n",
    "   - If there is No row with no subscripts, then this decomposition lossy and the resulting relation is a counter example of why.\n",
    "\n",
    "Given a decomposition R1, R2, ... Rn of relation R and a set of functional dependencies F, the projection of F into R1, given by F1 is the set of all fds in F+ that only contain the attributes in R1.\n",
    "\n",
    "Given a decomposition R1, R2, ... Rn of relation R and fds F, the decomposition is said to be **dependency preserving** iff\n",
    "\n",
    "1. F1, F2, ... , Fn are the projection of F onto R1, R2, .., Rn respectively\n",
    "2. F1 union F2 union ... union Fn is equivalent to F, i.e. (F1 union F2 union ... union Fn)+ = F+\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "078e0d47-c761-403b-a4ba-8a96cdc9fd95",
   "metadata": {},
   "source": [
    "R(A,B,C) {A->BC}\n",
    "\n",
    "R  \n",
    "a b c  \n",
    "d b e  \n",
    "\n",
    "\n",
    "R1(A,B)    \n",
    "a b  \n",
    "d b  \n",
    "\n",
    "R2(B,C)  \n",
    "b c  \n",
    "b e  \n",
    "\n",
    "\n",
    "R1*R2   \n",
    "a b c  \n",
    "a b e  \n",
    "d b c    \n",
    "d b e    \n",
    "\n",
    "This decomposition is not lossless since I am not guaranteed to get the same result!\n",
    "\n",
    "\n",
    "MusicGroups(Artist, Group, Genre, DOB, DFound, DJoined)\n",
    "\n",
    "Artist-> DOB\n",
    "Group-> Genre DFound\n",
    "Artist Group -> DJoined\n",
    "\n",
    "Key: Artist Group \n",
    "\n",
    "R(A,B,C,D,E,F)\n",
    "\n",
    "A->D  \n",
    "B->CE  \n",
    "AB->F  \n",
    "\n",
    "R1(A,B,D,F)  \n",
    "R2(B,E)  \n",
    "R3(A,C)  \n",
    "\n",
    "R1:  a  b  c1 d  e1 f  \n",
    "R2:  a2 b  c2 d2 e  f2  \n",
    "R3:  a  b3 c  d3 e3 f3  \n",
    "\n",
    "B->CE  \n",
    "\n",
    "R1:  a  b  c1 d  e  f  \n",
    "R2:  a2 b  c1 d2 e  f2  \n",
    "R3:  a  b3 c  d3 e3 f3  \n",
    "\n",
    "A->D  \n",
    "\n",
    "R1:  a  b  c1 d  e  f  \n",
    "R2:  a2 b  c1 d2 e  f2  \n",
    "R3:  a  b3 c  d e3 f3  \n",
    "\n",
    "Not lossless, i.e. lossy because there is no row with no subscripts.\n",
    "\n",
    "R(A,B,C,D,E,F)\n",
    "\n",
    "A->D  \n",
    "B->CE  \n",
    "AB->F  \n",
    "\n",
    "R1(A,D)  \n",
    "R2(B,C,E)  \n",
    "R3(A,B,F)  \n",
    "\n",
    "R1:  a  b1 c1 d  e1 f1  \n",
    "R2:  a2 b  c  d2 e  f2  \n",
    "R3:  a  b  c3 d3 e3 f  \n",
    "\n",
    "A->D  \n",
    "\n",
    "R1:  a  b1 c1 d  e1 f1    \n",
    "R2:  a2 b  c  d2 e  f2  \n",
    "R3:  a  b  c3 d e3 f   \n",
    "\n",
    "B->CE  \n",
    "\n",
    "R1:  a  b1 c1 d  e1 f1  \n",
    "R2:  a2 b  c  d2 e  f2  \n",
    "R3:  a  b  c  d   e f  \n",
    "\n",
    "R3 has no subscript! So it is lossless."
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fb82f66a-e06b-45a9-81a9-c7c738c22c41",
   "metadata": {},
   "source": [
    "R(A,B,C,D,E,F) F= {A->D, B->CE, AB->F}\n",
    "\n",
    "Decomposition:\n",
    "\n",
    "R1(A,B,D,F), Project onto R1 to find F1= {A->D, AB->F}\n",
    "\n",
    "A+  B  D  F  AB AD AF  BD BF DF\n",
    "\n",
    "R2(B,E), Project F onto R2 to find F2 = {B->E}\n",
    "\n",
    "R3(A,C), Project F onto R3 to find F3 = {}\n",
    "\n",
    "\n",
    "F1 union F2 union F3 = Fnew = {A->D, AB->F, B->E} equivalent to F?\n",
    "\n",
    "F= {A->D, B->CE, AB->F}\n",
    "\n",
    "A->D implied by Fnew? Yes\n",
    "AB->F implied by Fnew? Yes\n",
    "\n",
    "B->CE?\n",
    "\n",
    "According to Fnew, B+= {B,E}  since C is not in B+, then B->CE is not implied by Fnew.\n",
    "\n",
    "Then, this decomposition is not dependency preserving because we lost B-> CE."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "2a6e71c6-8345-425a-89ff-dc737e686b0b",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
