{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-31T08:58:14.902557Z",
     "start_time": "2019-08-31T08:58:14.684856Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2. 泳ぐ (およぐ, 泳いでいる)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>value</th>\n",
       "      <th>text</th>\n",
       "      <th>chunk</th>\n",
       "      <th>upos</th>\n",
       "      <th>start</th>\n",
       "      <th>end</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>ガ</td>\n",
       "      <td>少女</td>\n",
       "      <td>少女を</td>\n",
       "      <td>[少女, ]</td>\n",
       "      <td>NOUN</td>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  name value text   chunk  upos  start  end\n",
       "0    ガ    少女  少女を  [少女, ]  NOUN      3    3"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "4. 見る (みる, 見た。)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>value</th>\n",
       "      <th>text</th>\n",
       "      <th>chunk</th>\n",
       "      <th>upos</th>\n",
       "      <th>start</th>\n",
       "      <th>end</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>ヲ</td>\n",
       "      <td>少女</td>\n",
       "      <td>少女を</td>\n",
       "      <td>[少女, ]</td>\n",
       "      <td>NOUN</td>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>デ</td>\n",
       "      <td>鏡</td>\n",
       "      <td>鏡で</td>\n",
       "      <td>[望遠, 鏡, ]</td>\n",
       "      <td>NOUN</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  name value text      chunk  upos  start  end\n",
       "0    ヲ    少女  少女を     [少女, ]  NOUN      3    3\n",
       "1    デ     鏡   鏡で  [望遠, 鏡, ]  NOUN      1    1"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'type': 'predicate', 'lemma': '泳ぐ', 'index': 2, 'rel': 'D', 'governor': 4, 'domains': [('ガ', 3, '少女を', '少女', ['少女'], ['c_noun', 'x_n'])], 'stems': []}\n",
      "{'type': 'predicate', 'lemma': '見る', 'index': 4, 'rel': 'D', 'governor': 0, 'domains': [('ヲ', 3, '少女を', '少女', ['少女'], ['c_noun', 'x_n']), ('デ', 1, '鏡で', '鏡', ['望遠', '鏡'], ['c_noun', 'x_n'])], 'stems': []}\n"
     ]
    }
   ],
   "source": [
    "import sagas.ja.knp_helper as kh\n",
    "import sagas\n",
    "from sagas.nlu.uni_impl_knp import tag_pos, pos_list\n",
    "\n",
    "def trim_chunk(chunk):\n",
    "    return [c for c in chunk if c!='']\n",
    "def get_feats(tag):\n",
    "    return ['c_{}'.format(tag_pos(tag)).lower(), \n",
    "            'x_{}'.format(pos_list(tag)[0]).lower()]\n",
    "def get_governor(tag):\n",
    "    if tag.parent_id == -1:\n",
    "        governor = 0\n",
    "    else:\n",
    "        governor = tag.parent_id + 1\n",
    "    return governor\n",
    "def collect_bnst(result):\n",
    "    rs=[]\n",
    "    for bnst in result.bnst_list():\n",
    "        rs.append(([tag.tag_id for tag in bnst.tag_list()],\n",
    "                   [mrph.repname.split('/')[0] for mrph in bnst.mrph_list()]\n",
    "                  ))\n",
    "    return rs\n",
    "\n",
    "def extract_predicates(result, verbose=True):    \n",
    "    deps={}\n",
    "    predict_keys=[]\n",
    "    predicts=[]\n",
    "    predict_tuples=[]\n",
    "    bnst_set=collect_bnst(result)\n",
    "    words=result.tag_list()\n",
    "    for tag in words:\n",
    "        if tag.pas is not None:  # find predicate\n",
    "            predict_cnt=''.join(mrph.midasi for mrph in tag.mrph_list())\n",
    "            # word_main=tag.mrph_list()[0]            \n",
    "            if verbose:\n",
    "                print(tag.tag_id, '. 述語: %s' % predict_cnt)\n",
    "            # print(tag.features)\n",
    "            # print(tag.normalized_repname)\n",
    "            repname=tag.normalized_repname.split('/')\n",
    "            predict_lemma=repname[0]\n",
    "            predict_phonetic=repname[1]\n",
    "            \n",
    "            predict_keys.append(kh.merge_tag(tag))\n",
    "            p_args=[]\n",
    "            domains=[]\n",
    "            for case, args in tag.pas.arguments.items():  # case: str, args: list of Argument class                \n",
    "                for arg in args:  # arg: Argument class\n",
    "                    arg_tag=words[arg.tid]\n",
    "                    if verbose:\n",
    "                        print('\\t格: %s,  項: %s  (項の基本句ID: %d)' % (case, arg.midasi, arg.tid))\n",
    "                    kh.put_items(deps, {tag.tag_id, arg.tid}, case)\n",
    "                    cnt=''.join(mrph.midasi for mrph in arg_tag.mrph_list())\n",
    "                    chunk=[b[1] for b in bnst_set if arg_tag.tag_id in b[0]][0]\n",
    "                    p_args.append({'name':case, 'value':arg.midasi, 'text':cnt,\n",
    "                                   'chunk':chunk,\n",
    "                                   'upos':tag_pos(arg_tag),\n",
    "                                   'start':arg.tid, 'end':arg.tid})\n",
    "                    # ['rel', 'index', 'text', 'lemma', 'children', 'features']\n",
    "                    feats=get_feats(arg_tag)\n",
    "                    domains.append((case, arg.tid, cnt, arg.midasi, trim_chunk(chunk), feats))\n",
    "            predicts.append({'index':tag.tag_id, 'predicate':predict_lemma, \n",
    "                             'cnt':predict_cnt, 'phonetic':predict_phonetic,\n",
    "                             'args':p_args})\n",
    "            predict_tuples.append({'type':'predicate', 'lemma':predict_lemma, 'index': tag.tag_id,\n",
    "                              'rel': tag.dpndtype, 'governor': get_governor(tag),\n",
    "                              'domains': domains, 'stems':[]})\n",
    "    if verbose:\n",
    "        print(deps, predict_keys)\n",
    "        # print(predicts)\n",
    "    return deps, predict_keys, predicts, predict_tuples\n",
    "\n",
    "sents=\"望遠鏡で泳いでいる少女を見た。\"\n",
    "\n",
    "def parse_and_repr(sents):\n",
    "    result = kh.knp.parse(sents)\n",
    "    dep_sets, predict_keys, predicts, predict_tuples = extract_predicates(result, verbose=False)\n",
    "    for pr in predicts:\n",
    "        print(f\"{pr['index']}. {pr['predicate']} ({pr['phonetic']}, {pr['cnt']})\")\n",
    "        cols=pr['args'][0].keys()\n",
    "        rows=[row.values() for row in pr['args']]\n",
    "        display(sagas.to_df(rows, cols))\n",
    "\n",
    "    for t in predict_tuples:\n",
    "        print(t)\n",
    "parse_and_repr(sents)              "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 45,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-31T08:58:32.086721Z",
     "start_time": "2019-08-31T08:58:31.750138Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "5. 鳴る (なる?成る, なります。)\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>name</th>\n",
       "      <th>value</th>\n",
       "      <th>text</th>\n",
       "      <th>chunk</th>\n",
       "      <th>upos</th>\n",
       "      <th>start</th>\n",
       "      <th>end</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>ガ</td>\n",
       "      <td>あなた</td>\n",
       "      <td>あなたは</td>\n",
       "      <td>[あなた, ]</td>\n",
       "      <td>NOUN</td>\n",
       "      <td>2</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>ニ</td>\n",
       "      <td>勝者</td>\n",
       "      <td>勝者に</td>\n",
       "      <td>[勝者, ]</td>\n",
       "      <td>NOUN</td>\n",
       "      <td>4</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>修飾</td>\n",
       "      <td>常に</td>\n",
       "      <td>常に</td>\n",
       "      <td>[常に]</td>\n",
       "      <td>ADV</td>\n",
       "      <td>3</td>\n",
       "      <td>3</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>ニトル</td>\n",
       "      <td>私</td>\n",
       "      <td>私に</td>\n",
       "      <td>[私, ]</td>\n",
       "      <td>NOUN</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  name value  text    chunk  upos  start  end\n",
       "0    ガ   あなた  あなたは  [あなた, ]  NOUN      2    2\n",
       "1    ニ    勝者   勝者に   [勝者, ]  NOUN      4    4\n",
       "2   修飾    常に    常に     [常に]   ADV      3    3\n",
       "3  ニトル     私    私に    [私, ]  NOUN      0    0"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'type': 'predicate', 'lemma': '鳴る', 'index': 5, 'rel': 'D', 'governor': 0, 'domains': [('ガ', 2, 'あなたは', 'あなた', ['あなた'], ['c_noun', 'x_n']), ('ニ', 4, '勝者に', '勝者', ['勝者'], ['c_noun', 'x_n']), ('修飾', 3, '常に', '常に', ['常に'], ['c_adv', 'x_a']), ('ニトル', 0, '私に', '私', ['私'], ['c_noun', 'x_n'])], 'stems': []}\n"
     ]
    }
   ],
   "source": [
    "parse_and_repr(\"私にとって、あなたは常に勝者になります。\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 38,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-08-30T19:48:03.206320Z",
     "start_time": "2019-08-30T19:48:03.129093Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "望遠/ぼうえん 鏡/きょう  -> 見る/みる \n",
      "\t [0, 1]\n",
      "泳ぐ/およぐ いる/いる -> 少女/しょうじょ \n",
      "\t [2]\n",
      "少女/しょうじょ  -> 見る/みる \n",
      "\t [3]\n",
      "[([0, 1], ['望遠/ぼうえん', '鏡/きょう', '']), ([2], ['泳ぐ/およぐ', 'いる/いる']), ([3], ['少女/しょうじょ', '']), ([4], ['見る/みる', ''])]\n"
     ]
    }
   ],
   "source": [
    "result = kh.knp.parse(sents)\n",
    "\n",
    "for bnst in result.bnst_list():\n",
    "    parent = bnst.parent\n",
    "    if parent is not None:\n",
    "        child_rep = \" \".join(mrph.repname for mrph in bnst.mrph_list())\n",
    "        parent_rep = \" \".join(mrph.repname for mrph in parent.mrph_list())\n",
    "        print(child_rep, \"->\", parent_rep)\n",
    "        print('\\t', [tag.tag_id for tag in bnst.tag_list()])\n",
    "\n",
    "rs=[]\n",
    "for bnst in result.bnst_list():\n",
    "    rs.append(([tag.tag_id for tag in bnst.tag_list()],\n",
    "               [mrph.repname for mrph in bnst.mrph_list()]\n",
    "              ))\n",
    "print(rs)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.7.3"
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
