From d625d56188ce561a9ea5c3b69d45262cfdee1dbf Mon Sep 17 00:00:00 2001
From: BLADIER Tatiana <tatiana.bladier@lis-lab.fr>
Date: Thu, 15 May 2025 14:46:30 +0200
Subject: [PATCH] add tree depth calculation

---
 .../tania-some-other-metrics-checkpoint.ipynb | 178 +++-
 .../transform-checkpoint.py                   | 459 ++++++++++
 .../__pycache__/transform.cpython-311.pyc     | Bin 0 -> 24881 bytes
 .../.ipynb_checkpoints/__init__-checkpoint.py | 106 +++
 .../.ipynb_checkpoints/parser-checkpoint.py   | 620 ++++++++++++++
 tania_scripts/supar/__init__.py               | 106 +++
 .../__pycache__/__init__.cpython-310.pyc      | Bin 0 -> 3404 bytes
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 5116 bytes
 .../supar/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 3349 bytes
 .../supar/__pycache__/model.cpython-310.pyc   | Bin 0 -> 6512 bytes
 .../supar/__pycache__/model.cpython-311.pyc   | Bin 0 -> 14276 bytes
 .../supar/__pycache__/parser.cpython-310.pyc  | Bin 0 -> 20095 bytes
 .../supar/__pycache__/parser.cpython-311.pyc  | Bin 0 -> 38217 bytes
 .../vector_quantize.cpython-310.pyc           | Bin 0 -> 3635 bytes
 tania_scripts/supar/cmds/__init__.py          |   0
 .../cmds/__pycache__/__init__.cpython-310.pyc | Bin 0 -> 144 bytes
 .../cmds/__pycache__/run.cpython-310.pyc      | Bin 0 -> 2736 bytes
 tania_scripts/supar/cmds/const/aj.py          |  38 +
 tania_scripts/supar/cmds/const/crf.py         |  39 +
 tania_scripts/supar/cmds/const/sl.py          |  44 +
 tania_scripts/supar/cmds/const/tt.py          |  41 +
 tania_scripts/supar/cmds/const/vi.py          |  42 +
 .../dep/__pycache__/biaffine.cpython-310.pyc  | Bin 0 -> 2259 bytes
 .../dep/__pycache__/eager.cpython-310.pyc     | Bin 0 -> 2194 bytes
 .../cmds/dep/__pycache__/sl.cpython-310.pyc   | Bin 0 -> 2281 bytes
 tania_scripts/supar/cmds/dep/biaffine.py      |  45 +
 tania_scripts/supar/cmds/dep/crf.py           |  46 +
 tania_scripts/supar/cmds/dep/crf2o.py         |  46 +
 tania_scripts/supar/cmds/dep/eager.py         |  44 +
 tania_scripts/supar/cmds/dep/sl.py            |  46 +
 tania_scripts/supar/cmds/dep/vi.py            |  46 +
 tania_scripts/supar/cmds/run.py               |  65 ++
 tania_scripts/supar/cmds/sdp/biaffine.py      |  41 +
 tania_scripts/supar/cmds/sdp/vi.py            |  42 +
 tania_scripts/supar/codelin/__init__.py       |  34 +
 .../__pycache__/__init__.cpython-310.pyc      | Bin 0 -> 1419 bytes
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 2143 bytes
 .../abstract_encoding.cpython-310.pyc         | Bin 0 -> 1801 bytes
 .../abstract_encoding.cpython-311.pyc         | Bin 0 -> 2197 bytes
 .../supar/codelin/encs/abstract_encoding.py   |  37 +
 .../supar/codelin/encs/constituent.py         | 115 +++
 .../supar/codelin/encs/dependency.py          | 129 +++
 .../supar/codelin/encs/enc_const/__init__.py  |   4 +
 .../__pycache__/__init__.cpython-310.pyc      | Bin 0 -> 423 bytes
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 515 bytes
 .../naive_absolute.cpython-310.pyc            | Bin 0 -> 3375 bytes
 .../naive_absolute.cpython-311.pyc            | Bin 0 -> 6958 bytes
 .../__pycache__/naive_dynamic.cpython-310.pyc | Bin 0 -> 3661 bytes
 .../__pycache__/naive_dynamic.cpython-311.pyc | Bin 0 -> 7604 bytes
 .../naive_incremental.cpython-310.pyc         | Bin 0 -> 3908 bytes
 .../naive_incremental.cpython-311.pyc         | Bin 0 -> 7608 bytes
 .../naive_relative.cpython-310.pyc            | Bin 0 -> 3289 bytes
 .../naive_relative.cpython-311.pyc            | Bin 0 -> 6884 bytes
 .../codelin/encs/enc_const/naive_absolute.py  | 144 ++++
 .../codelin/encs/enc_const/naive_dynamic.py   | 166 ++++
 .../encs/enc_const/naive_incremental.py       | 160 ++++
 .../codelin/encs/enc_const/naive_relative.py  | 152 ++++
 .../supar/codelin/encs/enc_deps/__init__.py   |   6 +
 .../__pycache__/__init__.cpython-310.pyc      | Bin 0 -> 454 bytes
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 562 bytes
 .../__pycache__/brk2p_based.cpython-310.pyc   | Bin 0 -> 4874 bytes
 .../__pycache__/brk2p_based.cpython-311.pyc   | Bin 0 -> 9802 bytes
 .../__pycache__/brk_based.cpython-310.pyc     | Bin 0 -> 2420 bytes
 .../__pycache__/brk_based.cpython-311.pyc     | Bin 0 -> 4630 bytes
 .../naive_absolute.cpython-310.pyc            | Bin 0 -> 1873 bytes
 .../naive_absolute.cpython-311.pyc            | Bin 0 -> 3173 bytes
 .../naive_relative.cpython-310.pyc            | Bin 0 -> 1960 bytes
 .../naive_relative.cpython-311.pyc            | Bin 0 -> 3406 bytes
 .../__pycache__/pos_based.cpython-310.pyc     | Bin 0 -> 2476 bytes
 .../__pycache__/pos_based.cpython-311.pyc     | Bin 0 -> 4493 bytes
 .../codelin/encs/enc_deps/brk2p_based.py      | 215 +++++
 .../supar/codelin/encs/enc_deps/brk_based.py  |  87 ++
 .../codelin/encs/enc_deps/naive_absolute.py   |  42 +
 .../codelin/encs/enc_deps/naive_relative.py   |  48 ++
 .../supar/codelin/encs/enc_deps/pos_based.py  |  89 ++
 .../supar/codelin/models/__init__.py          |   0
 .../__pycache__/__init__.cpython-310.pyc      | Bin 0 -> 163 bytes
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 193 bytes
 .../__pycache__/const_label.cpython-310.pyc   | Bin 0 -> 1556 bytes
 .../__pycache__/const_label.cpython-311.pyc   | Bin 0 -> 2538 bytes
 .../__pycache__/const_tree.cpython-310.pyc    | Bin 0 -> 12187 bytes
 .../__pycache__/const_tree.cpython-311.pyc    | Bin 0 -> 21102 bytes
 .../__pycache__/deps_label.cpython-310.pyc    | Bin 0 -> 973 bytes
 .../__pycache__/deps_label.cpython-311.pyc    | Bin 0 -> 1396 bytes
 .../__pycache__/deps_tree.cpython-310.pyc     | Bin 0 -> 13060 bytes
 .../__pycache__/deps_tree.cpython-311.pyc     | Bin 0 -> 21064 bytes
 .../linearized_tree.cpython-310.pyc           | Bin 0 -> 5132 bytes
 .../linearized_tree.cpython-311.pyc           | Bin 0 -> 9798 bytes
 .../supar/codelin/models/const_label.py       |  38 +
 .../supar/codelin/models/const_tree.py        | 414 +++++++++
 .../supar/codelin/models/deps_label.py        |  18 +
 .../supar/codelin/models/deps_tree.py         | 371 +++++++++
 .../supar/codelin/models/linearized_tree.py   | 179 ++++
 tania_scripts/supar/codelin/utils/__init__.py |   0
 .../__pycache__/__init__.cpython-310.pyc      | Bin 0 -> 162 bytes
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 192 bytes
 .../__pycache__/constants.cpython-310.pyc     | Bin 0 -> 1112 bytes
 .../__pycache__/constants.cpython-311.pyc     | Bin 0 -> 1260 bytes
 .../supar/codelin/utils/constants.py          |  54 ++
 .../supar/codelin/utils/extract_feats.py      |  41 +
 tania_scripts/supar/model.py                  | 249 ++++++
 .../.ipynb_checkpoints/__init__-checkpoint.py |  22 +
 tania_scripts/supar/models/__init__.py        |  22 +
 .../__pycache__/__init__.cpython-310.pyc      | Bin 0 -> 742 bytes
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 1043 bytes
 .../__pycache__/__init__.cpython-39.pyc       | Bin 0 -> 731 bytes
 tania_scripts/supar/models/const/__init__.py  |  14 +
 .../__pycache__/__init__.cpython-310.pyc      | Bin 0 -> 758 bytes
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 966 bytes
 .../const/__pycache__/__init__.cpython-39.pyc | Bin 0 -> 653 bytes
 .../.ipynb_checkpoints/__init__-checkpoint.py |   6 +
 .../aj/.ipynb_checkpoints/model-checkpoint.py | 786 ++++++++++++++++++
 .../.ipynb_checkpoints/parser-checkpoint.py   | 534 ++++++++++++
 .../transform-checkpoint.py                   | 459 ++++++++++
 .../supar/models/const/aj/__init__.py         |   6 +
 .../aj/__pycache__/__init__.cpython-310.pyc   | Bin 0 -> 415 bytes
 .../aj/__pycache__/__init__.cpython-311.pyc   | Bin 0 -> 515 bytes
 .../aj/__pycache__/__init__.cpython-39.pyc    | Bin 0 -> 308 bytes
 .../aj/__pycache__/model.cpython-310.pyc      | Bin 0 -> 22080 bytes
 .../aj/__pycache__/model.cpython-311.pyc      | Bin 0 -> 47523 bytes
 .../const/aj/__pycache__/model.cpython-39.pyc | Bin 0 -> 13878 bytes
 .../aj/__pycache__/parser.cpython-310.pyc     | Bin 0 -> 14431 bytes
 .../aj/__pycache__/parser.cpython-311.pyc     | Bin 0 -> 32140 bytes
 .../aj/__pycache__/transform.cpython-310.pyc  | Bin 0 -> 17396 bytes
 .../aj/__pycache__/transform.cpython-311.pyc  | Bin 0 -> 24903 bytes
 tania_scripts/supar/models/const/aj/model.py  | 786 ++++++++++++++++++
 tania_scripts/supar/models/const/aj/parser.py | 534 ++++++++++++
 .../supar/models/const/aj/transform.py        | 459 ++++++++++
 .../supar/models/const/crf/__init__.py        |   6 +
 .../crf/__pycache__/__init__.cpython-310.pyc  | Bin 0 -> 287 bytes
 .../crf/__pycache__/__init__.cpython-311.pyc  | Bin 0 -> 365 bytes
 .../crf/__pycache__/model.cpython-310.pyc     | Bin 0 -> 9776 bytes
 .../crf/__pycache__/model.cpython-311.pyc     | Bin 0 -> 12210 bytes
 .../crf/__pycache__/parser.cpython-310.pyc    | Bin 0 -> 8295 bytes
 .../crf/__pycache__/parser.cpython-311.pyc    | Bin 0 -> 15580 bytes
 .../crf/__pycache__/transform.cpython-310.pyc | Bin 0 -> 19620 bytes
 .../crf/__pycache__/transform.cpython-311.pyc | Bin 0 -> 26740 bytes
 tania_scripts/supar/models/const/crf/model.py | 221 +++++
 .../supar/models/const/crf/parser.py          | 205 +++++
 .../supar/models/const/crf/transform.py       | 494 +++++++++++
 .../supar/models/const/sl/__init__.py         |   4 +
 .../sl/__pycache__/__init__.cpython-310.pyc   | Bin 0 -> 282 bytes
 .../sl/__pycache__/__init__.cpython-311.pyc   | Bin 0 -> 358 bytes
 .../sl/__pycache__/model.cpython-310.pyc      | Bin 0 -> 3360 bytes
 .../sl/__pycache__/model.cpython-311.pyc      | Bin 0 -> 5671 bytes
 .../sl/__pycache__/parser.cpython-310.pyc     | Bin 0 -> 8808 bytes
 .../sl/__pycache__/parser.cpython-311.pyc     | Bin 0 -> 18487 bytes
 .../sl/__pycache__/transform.cpython-310.pyc  | Bin 0 -> 3612 bytes
 .../sl/__pycache__/transform.cpython-311.pyc  | Bin 0 -> 6748 bytes
 tania_scripts/supar/models/const/sl/model.py  | 102 +++
 tania_scripts/supar/models/const/sl/parser.py | 219 +++++
 .../supar/models/const/sl/transform.py        |  94 +++
 .../supar/models/const/tt/__init__.py         |   6 +
 .../tt/__pycache__/__init__.cpython-310.pyc   | Bin 0 -> 304 bytes
 .../tt/__pycache__/__init__.cpython-311.pyc   | Bin 0 -> 382 bytes
 .../tt/__pycache__/model.cpython-310.pyc      | Bin 0 -> 10462 bytes
 .../tt/__pycache__/model.cpython-311.pyc      | Bin 0 -> 15368 bytes
 .../tt/__pycache__/parser.cpython-310.pyc     | Bin 0 -> 8248 bytes
 .../tt/__pycache__/parser.cpython-311.pyc     | Bin 0 -> 15371 bytes
 .../tt/__pycache__/transform.cpython-310.pyc  | Bin 0 -> 11481 bytes
 .../tt/__pycache__/transform.cpython-311.pyc  | Bin 0 -> 17156 bytes
 tania_scripts/supar/models/const/tt/model.py  | 265 ++++++
 tania_scripts/supar/models/const/tt/parser.py | 205 +++++
 .../supar/models/const/tt/transform.py        | 301 +++++++
 .../supar/models/const/vi/__init__.py         |   6 +
 .../vi/__pycache__/__init__.cpython-310.pyc   | Bin 0 -> 284 bytes
 .../vi/__pycache__/__init__.cpython-311.pyc   | Bin 0 -> 362 bytes
 .../vi/__pycache__/model.cpython-310.pyc      | Bin 0 -> 10359 bytes
 .../vi/__pycache__/model.cpython-311.pyc      | Bin 0 -> 13244 bytes
 .../vi/__pycache__/parser.cpython-310.pyc     | Bin 0 -> 4769 bytes
 .../vi/__pycache__/parser.cpython-311.pyc     | Bin 0 -> 8761 bytes
 tania_scripts/supar/models/const/vi/model.py  | 237 ++++++
 tania_scripts/supar/models/const/vi/parser.py | 108 +++
 tania_scripts/supar/models/dep/__init__.py    |  15 +
 .../dep/__pycache__/__init__.cpython-310.pyc  | Bin 0 -> 723 bytes
 .../dep/__pycache__/__init__.cpython-311.pyc  | Bin 0 -> 902 bytes
 .../supar/models/dep/biaffine/__init__.py     |   6 +
 .../__pycache__/__init__.cpython-310.pyc      | Bin 0 -> 305 bytes
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 374 bytes
 .../__pycache__/model.cpython-310.pyc         | Bin 0 -> 10021 bytes
 .../__pycache__/model.cpython-311.pyc         | Bin 0 -> 12885 bytes
 .../__pycache__/parser.cpython-310.pyc        | Bin 0 -> 8024 bytes
 .../__pycache__/parser.cpython-311.pyc        | Bin 0 -> 14692 bytes
 .../__pycache__/transform.cpython-310.pyc     | Bin 0 -> 16984 bytes
 .../__pycache__/transform.cpython-311.pyc     | Bin 0 -> 24798 bytes
 .../supar/models/dep/biaffine/model.py        | 234 ++++++
 .../supar/models/dep/biaffine/parser.py       | 213 +++++
 .../supar/models/dep/biaffine/transform.py    | 379 +++++++++
 .../supar/models/dep/crf/__init__.py          |   6 +
 .../crf/__pycache__/__init__.cpython-310.pyc  | Bin 0 -> 290 bytes
 .../crf/__pycache__/__init__.cpython-311.pyc  | Bin 0 -> 359 bytes
 .../dep/crf/__pycache__/model.cpython-310.pyc | Bin 0 -> 6656 bytes
 .../dep/crf/__pycache__/model.cpython-311.pyc | Bin 0 -> 7412 bytes
 .../crf/__pycache__/parser.cpython-310.pyc    | Bin 0 -> 4987 bytes
 .../crf/__pycache__/parser.cpython-311.pyc    | Bin 0 -> 8854 bytes
 tania_scripts/supar/models/dep/crf/model.py   | 134 +++
 tania_scripts/supar/models/dep/crf/parser.py  | 131 +++
 .../supar/models/dep/crf2o/__init__.py        |   6 +
 .../__pycache__/__init__.cpython-310.pyc      | Bin 0 -> 296 bytes
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 365 bytes
 .../crf2o/__pycache__/model.cpython-310.pyc   | Bin 0 -> 11378 bytes
 .../crf2o/__pycache__/model.cpython-311.pyc   | Bin 0 -> 15100 bytes
 .../crf2o/__pycache__/parser.cpython-310.pyc  | Bin 0 -> 8249 bytes
 .../crf2o/__pycache__/parser.cpython-311.pyc  | Bin 0 -> 15194 bytes
 tania_scripts/supar/models/dep/crf2o/model.py | 263 ++++++
 .../supar/models/dep/crf2o/parser.py          | 216 +++++
 .../supar/models/dep/eager/__init__.py        |   2 +
 .../__pycache__/__init__.cpython-310.pyc      | Bin 0 -> 273 bytes
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 333 bytes
 .../eager/__pycache__/model.cpython-310.pyc   | Bin 0 -> 6877 bytes
 .../eager/__pycache__/model.cpython-311.pyc   | Bin 0 -> 11595 bytes
 .../eager/__pycache__/parser.cpython-310.pyc  | Bin 0 -> 14058 bytes
 .../eager/__pycache__/parser.cpython-311.pyc  | Bin 0 -> 29283 bytes
 .../__pycache__/transform.cpython-310.pyc     | Bin 0 -> 7792 bytes
 .../__pycache__/transform.cpython-311.pyc     | Bin 0 -> 13871 bytes
 tania_scripts/supar/models/dep/eager/model.py | 198 +++++
 .../supar/models/dep/eager/oracle/__init__.py |   0
 .../__pycache__/__init__.cpython-310.pyc      | Bin 0 -> 172 bytes
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 202 bytes
 .../__pycache__/arceager.cpython-310.pyc      | Bin 0 -> 7330 bytes
 .../__pycache__/arceager.cpython-311.pyc      | Bin 0 -> 15872 bytes
 .../oracle/__pycache__/buffer.cpython-310.pyc | Bin 0 -> 1286 bytes
 .../oracle/__pycache__/buffer.cpython-311.pyc | Bin 0 -> 1846 bytes
 .../__pycache__/dependency.cpython-310.pyc    | Bin 0 -> 1544 bytes
 .../__pycache__/dependency.cpython-311.pyc    | Bin 0 -> 2377 bytes
 .../oracle/__pycache__/node.cpython-310.pyc   | Bin 0 -> 2800 bytes
 .../oracle/__pycache__/node.cpython-311.pyc   | Bin 0 -> 5581 bytes
 .../oracle/__pycache__/stack.cpython-310.pyc  | Bin 0 -> 1180 bytes
 .../oracle/__pycache__/stack.cpython-311.pyc  | Bin 0 -> 1703 bytes
 .../supar/models/dep/eager/oracle/arceager.py | 219 +++++
 .../supar/models/dep/eager/oracle/buffer.py   |  24 +
 .../models/dep/eager/oracle/dependency.py     |  30 +
 .../supar/models/dep/eager/oracle/node.py     |  74 ++
 .../supar/models/dep/eager/oracle/stack.py    |  24 +
 .../supar/models/dep/eager/parser.py          | 380 +++++++++
 .../supar/models/dep/eager/transform.py       | 176 ++++
 tania_scripts/supar/models/dep/sl/__init__.py |   2 +
 .../sl/__pycache__/__init__.cpython-310.pyc   | Bin 0 -> 258 bytes
 .../sl/__pycache__/__init__.cpython-311.pyc   | Bin 0 -> 318 bytes
 .../dep/sl/__pycache__/model.cpython-310.pyc  | Bin 0 -> 5672 bytes
 .../dep/sl/__pycache__/model.cpython-311.pyc  | Bin 0 -> 9943 bytes
 .../dep/sl/__pycache__/parser.cpython-310.pyc | Bin 0 -> 12083 bytes
 .../dep/sl/__pycache__/parser.cpython-311.pyc | Bin 0 -> 25291 bytes
 .../sl/__pycache__/transform.cpython-310.pyc  | Bin 0 -> 3766 bytes
 .../sl/__pycache__/transform.cpython-311.pyc  | Bin 0 -> 7098 bytes
 tania_scripts/supar/models/dep/sl/model.py    | 154 ++++
 tania_scripts/supar/models/dep/sl/parser.py   | 323 +++++++
 .../supar/models/dep/sl/transform.py          | 102 +++
 tania_scripts/supar/models/dep/vi/__init__.py |   6 +
 .../vi/__pycache__/__init__.cpython-310.pyc   | Bin 0 -> 287 bytes
 .../vi/__pycache__/__init__.cpython-311.pyc   | Bin 0 -> 356 bytes
 .../dep/vi/__pycache__/model.cpython-310.pyc  | Bin 0 -> 10828 bytes
 .../dep/vi/__pycache__/model.cpython-311.pyc  | Bin 0 -> 14278 bytes
 .../dep/vi/__pycache__/parser.cpython-310.pyc | Bin 0 -> 4732 bytes
 .../dep/vi/__pycache__/parser.cpython-311.pyc | Bin 0 -> 8333 bytes
 tania_scripts/supar/models/dep/vi/model.py    | 253 ++++++
 tania_scripts/supar/models/dep/vi/parser.py   | 124 +++
 tania_scripts/supar/models/sdp/__init__.py    |   7 +
 .../sdp/__pycache__/__init__.cpython-310.pyc  | Bin 0 -> 396 bytes
 .../sdp/__pycache__/__init__.cpython-311.pyc  | Bin 0 -> 487 bytes
 .../supar/models/sdp/biaffine/__init__.py     |   6 +
 .../__pycache__/__init__.cpython-310.pyc      | Bin 0 -> 321 bytes
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 390 bytes
 .../__pycache__/model.cpython-310.pyc         | Bin 0 -> 9519 bytes
 .../__pycache__/model.cpython-311.pyc         | Bin 0 -> 11764 bytes
 .../__pycache__/parser.cpython-310.pyc        | Bin 0 -> 8024 bytes
 .../__pycache__/parser.cpython-311.pyc        | Bin 0 -> 14949 bytes
 .../supar/models/sdp/biaffine/model.py        | 222 +++++
 .../supar/models/sdp/biaffine/parser.py       | 202 +++++
 tania_scripts/supar/models/sdp/vi/__init__.py |   6 +
 .../vi/__pycache__/__init__.cpython-310.pyc   | Bin 0 -> 303 bytes
 .../vi/__pycache__/__init__.cpython-311.pyc   | Bin 0 -> 372 bytes
 .../sdp/vi/__pycache__/model.cpython-310.pyc  | Bin 0 -> 19591 bytes
 .../sdp/vi/__pycache__/model.cpython-311.pyc  | Bin 0 -> 24854 bytes
 .../sdp/vi/__pycache__/parser.cpython-310.pyc | Bin 0 -> 4845 bytes
 .../sdp/vi/__pycache__/parser.cpython-311.pyc | Bin 0 -> 8540 bytes
 tania_scripts/supar/models/sdp/vi/model.py    | 471 +++++++++++
 tania_scripts/supar/models/sdp/vi/parser.py   | 114 +++
 tania_scripts/supar/modules/__init__.py       |  20 +
 .../__pycache__/__init__.cpython-310.pyc      | Bin 0 -> 795 bytes
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 1028 bytes
 .../__pycache__/affine.cpython-310.pyc        | Bin 0 -> 8011 bytes
 .../__pycache__/affine.cpython-311.pyc        | Bin 0 -> 12963 bytes
 .../__pycache__/decoder.cpython-310.pyc       | Bin 0 -> 1746 bytes
 .../__pycache__/decoder.cpython-311.pyc       | Bin 0 -> 2997 bytes
 .../__pycache__/dropout.cpython-310.pyc       | Bin 0 -> 6173 bytes
 .../__pycache__/dropout.cpython-311.pyc       | Bin 0 -> 8710 bytes
 .../modules/__pycache__/gnn.cpython-310.pyc   | Bin 0 -> 5471 bytes
 .../modules/__pycache__/gnn.cpython-311.pyc   | Bin 0 -> 7820 bytes
 .../modules/__pycache__/lstm.cpython-310.pyc  | Bin 0 -> 10155 bytes
 .../modules/__pycache__/lstm.cpython-311.pyc  | Bin 0 -> 16394 bytes
 .../modules/__pycache__/mlp.cpython-310.pyc   | Bin 0 -> 2397 bytes
 .../modules/__pycache__/mlp.cpython-311.pyc   | Bin 0 -> 3517 bytes
 .../__pycache__/pretrained.cpython-310.pyc    | Bin 0 -> 10694 bytes
 .../__pycache__/pretrained.cpython-311.pyc    | Bin 0 -> 16517 bytes
 .../__pycache__/transformer.cpython-310.pyc   | Bin 0 -> 17309 bytes
 .../__pycache__/transformer.cpython-311.pyc   | Bin 0 -> 36701 bytes
 tania_scripts/supar/modules/affine.py         | 260 ++++++
 tania_scripts/supar/modules/decoder.py        |  38 +
 tania_scripts/supar/modules/dropout.py        | 155 ++++
 tania_scripts/supar/modules/gnn.py            | 135 +++
 tania_scripts/supar/modules/lstm.py           | 271 ++++++
 tania_scripts/supar/modules/mlp.py            |  62 ++
 tania_scripts/supar/modules/pretrained.py     | 256 ++++++
 tania_scripts/supar/modules/transformer.py    | 585 +++++++++++++
 tania_scripts/supar/parser.py                 | 620 ++++++++++++++
 tania_scripts/supar/structs/__init__.py       |  23 +
 .../__pycache__/__init__.cpython-310.pyc      | Bin 0 -> 703 bytes
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 946 bytes
 .../structs/__pycache__/chain.cpython-310.pyc | Bin 0 -> 9988 bytes
 .../structs/__pycache__/chain.cpython-311.pyc | Bin 0 -> 17390 bytes
 .../structs/__pycache__/dist.cpython-310.pyc  | Bin 0 -> 5710 bytes
 .../structs/__pycache__/dist.cpython-311.pyc  | Bin 0 -> 7995 bytes
 .../structs/__pycache__/fn.cpython-310.pyc    | Bin 0 -> 11869 bytes
 .../structs/__pycache__/fn.cpython-311.pyc    | Bin 0 -> 21496 bytes
 .../__pycache__/semiring.cpython-310.pyc      | Bin 0 -> 17503 bytes
 .../__pycache__/semiring.cpython-311.pyc      | Bin 0 -> 33629 bytes
 .../structs/__pycache__/tree.cpython-310.pyc  | Bin 0 -> 26754 bytes
 .../structs/__pycache__/tree.cpython-311.pyc  | Bin 0 -> 52834 bytes
 .../structs/__pycache__/vi.cpython-310.pyc    | Bin 0 -> 13833 bytes
 .../structs/__pycache__/vi.cpython-311.pyc    | Bin 0 -> 28892 bytes
 tania_scripts/supar/structs/chain.py          | 208 +++++
 tania_scripts/supar/structs/dist.py           | 138 +++
 tania_scripts/supar/structs/fn.py             | 379 +++++++++
 tania_scripts/supar/structs/semiring.py       | 406 +++++++++
 tania_scripts/supar/structs/tree.py           | 635 ++++++++++++++
 tania_scripts/supar/structs/vi.py             | 499 +++++++++++
 tania_scripts/supar/utils/__init__.py         |  17 +
 .../__pycache__/__init__.cpython-310.pyc      | Bin 0 -> 590 bytes
 .../__pycache__/__init__.cpython-311.pyc      | Bin 0 -> 781 bytes
 .../utils/__pycache__/common.cpython-310.pyc  | Bin 0 -> 358 bytes
 .../utils/__pycache__/common.cpython-311.pyc  | Bin 0 -> 496 bytes
 .../utils/__pycache__/config.cpython-310.pyc  | Bin 0 -> 4218 bytes
 .../utils/__pycache__/config.cpython-311.pyc  | Bin 0 -> 7268 bytes
 .../utils/__pycache__/data.cpython-310.pyc    | Bin 0 -> 15054 bytes
 .../utils/__pycache__/data.cpython-311.pyc    | Bin 0 -> 25699 bytes
 .../utils/__pycache__/embed.cpython-310.pyc   | Bin 0 -> 13204 bytes
 .../utils/__pycache__/embed.cpython-311.pyc   | Bin 0 -> 19798 bytes
 .../utils/__pycache__/field.cpython-310.pyc   | Bin 0 -> 16475 bytes
 .../utils/__pycache__/field.cpython-311.pyc   | Bin 0 -> 24575 bytes
 .../utils/__pycache__/fn.cpython-310.pyc      | Bin 0 -> 13456 bytes
 .../utils/__pycache__/fn.cpython-311.pyc      | Bin 0 -> 26506 bytes
 .../utils/__pycache__/logging.cpython-310.pyc | Bin 0 -> 3238 bytes
 .../utils/__pycache__/logging.cpython-311.pyc | Bin 0 -> 5351 bytes
 .../utils/__pycache__/metric.cpython-310.pyc  | Bin 0 -> 10873 bytes
 .../utils/__pycache__/metric.cpython-311.pyc  | Bin 0 -> 20588 bytes
 .../utils/__pycache__/optim.cpython-310.pyc   | Bin 0 -> 2798 bytes
 .../utils/__pycache__/optim.cpython-311.pyc   | Bin 0 -> 4195 bytes
 .../__pycache__/parallel.cpython-310.pyc      | Bin 0 -> 2976 bytes
 .../__pycache__/parallel.cpython-311.pyc      | Bin 0 -> 5035 bytes
 .../__pycache__/tokenizer.cpython-310.pyc     | Bin 0 -> 9291 bytes
 .../__pycache__/tokenizer.cpython-311.pyc     | Bin 0 -> 15768 bytes
 .../__pycache__/transform.cpython-310.pyc     | Bin 0 -> 9574 bytes
 .../__pycache__/transform.cpython-311.pyc     | Bin 0 -> 15399 bytes
 .../utils/__pycache__/vocab.cpython-310.pyc   | Bin 0 -> 4122 bytes
 .../utils/__pycache__/vocab.cpython-311.pyc   | Bin 0 -> 6223 bytes
 tania_scripts/supar/utils/common.py           |  14 +
 tania_scripts/supar/utils/config.py           |  85 ++
 tania_scripts/supar/utils/data.py             | 344 ++++++++
 tania_scripts/supar/utils/embed.py            | 334 ++++++++
 tania_scripts/supar/utils/field.py            | 415 +++++++++
 tania_scripts/supar/utils/fn.py               | 383 +++++++++
 tania_scripts/supar/utils/logging.py          | 100 +++
 tania_scripts/supar/utils/metric.py           | 346 ++++++++
 tania_scripts/supar/utils/optim.py            |  55 ++
 tania_scripts/supar/utils/parallel.py         |  80 ++
 tania_scripts/supar/utils/tokenizer.py        | 220 +++++
 tania_scripts/supar/utils/transform.py        | 219 +++++
 tania_scripts/supar/utils/vocab.py            |  77 ++
 tania_scripts/supar/vector_quantize.py        | 130 +++
 tania_scripts/tania-some-other-metrics.ipynb  | 178 +++-
 tania_scripts/transform.py                    | 459 ++++++++++
 372 files changed, 23775 insertions(+), 80 deletions(-)
 create mode 100644 tania_scripts/.ipynb_checkpoints/transform-checkpoint.py
 create mode 100644 tania_scripts/__pycache__/transform.cpython-311.pyc
 create mode 100644 tania_scripts/supar/.ipynb_checkpoints/__init__-checkpoint.py
 create mode 100644 tania_scripts/supar/.ipynb_checkpoints/parser-checkpoint.py
 create mode 100644 tania_scripts/supar/__init__.py
 create mode 100644 tania_scripts/supar/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/__pycache__/__init__.cpython-39.pyc
 create mode 100644 tania_scripts/supar/__pycache__/model.cpython-310.pyc
 create mode 100644 tania_scripts/supar/__pycache__/model.cpython-311.pyc
 create mode 100644 tania_scripts/supar/__pycache__/parser.cpython-310.pyc
 create mode 100644 tania_scripts/supar/__pycache__/parser.cpython-311.pyc
 create mode 100644 tania_scripts/supar/__pycache__/vector_quantize.cpython-310.pyc
 create mode 100644 tania_scripts/supar/cmds/__init__.py
 create mode 100644 tania_scripts/supar/cmds/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/cmds/__pycache__/run.cpython-310.pyc
 create mode 100644 tania_scripts/supar/cmds/const/aj.py
 create mode 100644 tania_scripts/supar/cmds/const/crf.py
 create mode 100644 tania_scripts/supar/cmds/const/sl.py
 create mode 100644 tania_scripts/supar/cmds/const/tt.py
 create mode 100644 tania_scripts/supar/cmds/const/vi.py
 create mode 100644 tania_scripts/supar/cmds/dep/__pycache__/biaffine.cpython-310.pyc
 create mode 100644 tania_scripts/supar/cmds/dep/__pycache__/eager.cpython-310.pyc
 create mode 100644 tania_scripts/supar/cmds/dep/__pycache__/sl.cpython-310.pyc
 create mode 100644 tania_scripts/supar/cmds/dep/biaffine.py
 create mode 100644 tania_scripts/supar/cmds/dep/crf.py
 create mode 100644 tania_scripts/supar/cmds/dep/crf2o.py
 create mode 100644 tania_scripts/supar/cmds/dep/eager.py
 create mode 100644 tania_scripts/supar/cmds/dep/sl.py
 create mode 100644 tania_scripts/supar/cmds/dep/vi.py
 create mode 100644 tania_scripts/supar/cmds/run.py
 create mode 100644 tania_scripts/supar/cmds/sdp/biaffine.py
 create mode 100644 tania_scripts/supar/cmds/sdp/vi.py
 create mode 100644 tania_scripts/supar/codelin/__init__.py
 create mode 100644 tania_scripts/supar/codelin/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/__pycache__/abstract_encoding.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/__pycache__/abstract_encoding.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/abstract_encoding.py
 create mode 100644 tania_scripts/supar/codelin/encs/constituent.py
 create mode 100644 tania_scripts/supar/codelin/encs/dependency.py
 create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__init__.py
 create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_absolute.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_absolute.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_dynamic.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_dynamic.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_incremental.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_incremental.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_relative.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_relative.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_const/naive_absolute.py
 create mode 100644 tania_scripts/supar/codelin/encs/enc_const/naive_dynamic.py
 create mode 100644 tania_scripts/supar/codelin/encs/enc_const/naive_incremental.py
 create mode 100644 tania_scripts/supar/codelin/encs/enc_const/naive_relative.py
 create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__init__.py
 create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk2p_based.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk2p_based.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk_based.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk_based.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_absolute.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_absolute.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_relative.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_relative.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/pos_based.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/__pycache__/pos_based.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/brk2p_based.py
 create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/brk_based.py
 create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/naive_absolute.py
 create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/naive_relative.py
 create mode 100644 tania_scripts/supar/codelin/encs/enc_deps/pos_based.py
 create mode 100644 tania_scripts/supar/codelin/models/__init__.py
 create mode 100644 tania_scripts/supar/codelin/models/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/models/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/models/__pycache__/const_label.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/models/__pycache__/const_label.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/models/__pycache__/const_tree.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/models/__pycache__/const_tree.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/models/__pycache__/deps_label.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/models/__pycache__/deps_label.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/models/__pycache__/deps_tree.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/models/__pycache__/deps_tree.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/models/__pycache__/linearized_tree.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/models/__pycache__/linearized_tree.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/models/const_label.py
 create mode 100644 tania_scripts/supar/codelin/models/const_tree.py
 create mode 100644 tania_scripts/supar/codelin/models/deps_label.py
 create mode 100644 tania_scripts/supar/codelin/models/deps_tree.py
 create mode 100644 tania_scripts/supar/codelin/models/linearized_tree.py
 create mode 100644 tania_scripts/supar/codelin/utils/__init__.py
 create mode 100644 tania_scripts/supar/codelin/utils/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/utils/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/utils/__pycache__/constants.cpython-310.pyc
 create mode 100644 tania_scripts/supar/codelin/utils/__pycache__/constants.cpython-311.pyc
 create mode 100644 tania_scripts/supar/codelin/utils/constants.py
 create mode 100644 tania_scripts/supar/codelin/utils/extract_feats.py
 create mode 100644 tania_scripts/supar/model.py
 create mode 100644 tania_scripts/supar/models/.ipynb_checkpoints/__init__-checkpoint.py
 create mode 100644 tania_scripts/supar/models/__init__.py
 create mode 100644 tania_scripts/supar/models/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/__pycache__/__init__.cpython-39.pyc
 create mode 100644 tania_scripts/supar/models/const/__init__.py
 create mode 100644 tania_scripts/supar/models/const/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/__pycache__/__init__.cpython-39.pyc
 create mode 100644 tania_scripts/supar/models/const/aj/.ipynb_checkpoints/__init__-checkpoint.py
 create mode 100644 tania_scripts/supar/models/const/aj/.ipynb_checkpoints/model-checkpoint.py
 create mode 100644 tania_scripts/supar/models/const/aj/.ipynb_checkpoints/parser-checkpoint.py
 create mode 100644 tania_scripts/supar/models/const/aj/.ipynb_checkpoints/transform-checkpoint.py
 create mode 100644 tania_scripts/supar/models/const/aj/__init__.py
 create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/__init__.cpython-39.pyc
 create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/model.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/model.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/model.cpython-39.pyc
 create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/parser.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/parser.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/transform.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/aj/__pycache__/transform.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/aj/model.py
 create mode 100644 tania_scripts/supar/models/const/aj/parser.py
 create mode 100644 tania_scripts/supar/models/const/aj/transform.py
 create mode 100644 tania_scripts/supar/models/const/crf/__init__.py
 create mode 100644 tania_scripts/supar/models/const/crf/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/crf/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/crf/__pycache__/model.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/crf/__pycache__/model.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/crf/__pycache__/parser.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/crf/__pycache__/parser.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/crf/__pycache__/transform.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/crf/__pycache__/transform.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/crf/model.py
 create mode 100644 tania_scripts/supar/models/const/crf/parser.py
 create mode 100644 tania_scripts/supar/models/const/crf/transform.py
 create mode 100644 tania_scripts/supar/models/const/sl/__init__.py
 create mode 100644 tania_scripts/supar/models/const/sl/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/sl/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/sl/__pycache__/model.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/sl/__pycache__/model.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/sl/__pycache__/parser.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/sl/__pycache__/parser.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/sl/__pycache__/transform.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/sl/__pycache__/transform.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/sl/model.py
 create mode 100644 tania_scripts/supar/models/const/sl/parser.py
 create mode 100644 tania_scripts/supar/models/const/sl/transform.py
 create mode 100644 tania_scripts/supar/models/const/tt/__init__.py
 create mode 100644 tania_scripts/supar/models/const/tt/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/tt/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/tt/__pycache__/model.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/tt/__pycache__/model.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/tt/__pycache__/parser.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/tt/__pycache__/parser.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/tt/__pycache__/transform.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/tt/__pycache__/transform.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/tt/model.py
 create mode 100644 tania_scripts/supar/models/const/tt/parser.py
 create mode 100644 tania_scripts/supar/models/const/tt/transform.py
 create mode 100644 tania_scripts/supar/models/const/vi/__init__.py
 create mode 100644 tania_scripts/supar/models/const/vi/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/vi/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/vi/__pycache__/model.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/vi/__pycache__/model.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/vi/__pycache__/parser.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/const/vi/__pycache__/parser.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/const/vi/model.py
 create mode 100644 tania_scripts/supar/models/const/vi/parser.py
 create mode 100644 tania_scripts/supar/models/dep/__init__.py
 create mode 100644 tania_scripts/supar/models/dep/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/biaffine/__init__.py
 create mode 100644 tania_scripts/supar/models/dep/biaffine/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/biaffine/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/biaffine/__pycache__/model.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/biaffine/__pycache__/model.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/biaffine/__pycache__/parser.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/biaffine/__pycache__/parser.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/biaffine/__pycache__/transform.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/biaffine/__pycache__/transform.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/biaffine/model.py
 create mode 100644 tania_scripts/supar/models/dep/biaffine/parser.py
 create mode 100644 tania_scripts/supar/models/dep/biaffine/transform.py
 create mode 100644 tania_scripts/supar/models/dep/crf/__init__.py
 create mode 100644 tania_scripts/supar/models/dep/crf/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/crf/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/crf/__pycache__/model.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/crf/__pycache__/model.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/crf/__pycache__/parser.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/crf/__pycache__/parser.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/crf/model.py
 create mode 100644 tania_scripts/supar/models/dep/crf/parser.py
 create mode 100644 tania_scripts/supar/models/dep/crf2o/__init__.py
 create mode 100644 tania_scripts/supar/models/dep/crf2o/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/crf2o/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/crf2o/__pycache__/model.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/crf2o/__pycache__/model.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/crf2o/__pycache__/parser.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/crf2o/__pycache__/parser.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/crf2o/model.py
 create mode 100644 tania_scripts/supar/models/dep/crf2o/parser.py
 create mode 100644 tania_scripts/supar/models/dep/eager/__init__.py
 create mode 100644 tania_scripts/supar/models/dep/eager/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/__pycache__/model.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/__pycache__/model.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/__pycache__/parser.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/__pycache__/parser.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/__pycache__/transform.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/__pycache__/transform.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/model.py
 create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__init__.py
 create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/arceager.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/arceager.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/buffer.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/buffer.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/dependency.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/dependency.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/node.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/node.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/stack.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/oracle/__pycache__/stack.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/eager/oracle/arceager.py
 create mode 100644 tania_scripts/supar/models/dep/eager/oracle/buffer.py
 create mode 100644 tania_scripts/supar/models/dep/eager/oracle/dependency.py
 create mode 100644 tania_scripts/supar/models/dep/eager/oracle/node.py
 create mode 100644 tania_scripts/supar/models/dep/eager/oracle/stack.py
 create mode 100644 tania_scripts/supar/models/dep/eager/parser.py
 create mode 100644 tania_scripts/supar/models/dep/eager/transform.py
 create mode 100644 tania_scripts/supar/models/dep/sl/__init__.py
 create mode 100644 tania_scripts/supar/models/dep/sl/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/sl/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/sl/__pycache__/model.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/sl/__pycache__/model.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/sl/__pycache__/parser.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/sl/__pycache__/parser.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/sl/__pycache__/transform.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/sl/__pycache__/transform.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/sl/model.py
 create mode 100644 tania_scripts/supar/models/dep/sl/parser.py
 create mode 100644 tania_scripts/supar/models/dep/sl/transform.py
 create mode 100644 tania_scripts/supar/models/dep/vi/__init__.py
 create mode 100644 tania_scripts/supar/models/dep/vi/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/vi/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/vi/__pycache__/model.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/vi/__pycache__/model.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/vi/__pycache__/parser.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/dep/vi/__pycache__/parser.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/dep/vi/model.py
 create mode 100644 tania_scripts/supar/models/dep/vi/parser.py
 create mode 100644 tania_scripts/supar/models/sdp/__init__.py
 create mode 100644 tania_scripts/supar/models/sdp/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/sdp/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/sdp/biaffine/__init__.py
 create mode 100644 tania_scripts/supar/models/sdp/biaffine/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/sdp/biaffine/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/sdp/biaffine/__pycache__/model.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/sdp/biaffine/__pycache__/model.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/sdp/biaffine/__pycache__/parser.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/sdp/biaffine/__pycache__/parser.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/sdp/biaffine/model.py
 create mode 100644 tania_scripts/supar/models/sdp/biaffine/parser.py
 create mode 100644 tania_scripts/supar/models/sdp/vi/__init__.py
 create mode 100644 tania_scripts/supar/models/sdp/vi/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/sdp/vi/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/sdp/vi/__pycache__/model.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/sdp/vi/__pycache__/model.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/sdp/vi/__pycache__/parser.cpython-310.pyc
 create mode 100644 tania_scripts/supar/models/sdp/vi/__pycache__/parser.cpython-311.pyc
 create mode 100644 tania_scripts/supar/models/sdp/vi/model.py
 create mode 100644 tania_scripts/supar/models/sdp/vi/parser.py
 create mode 100644 tania_scripts/supar/modules/__init__.py
 create mode 100644 tania_scripts/supar/modules/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/modules/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/modules/__pycache__/affine.cpython-310.pyc
 create mode 100644 tania_scripts/supar/modules/__pycache__/affine.cpython-311.pyc
 create mode 100644 tania_scripts/supar/modules/__pycache__/decoder.cpython-310.pyc
 create mode 100644 tania_scripts/supar/modules/__pycache__/decoder.cpython-311.pyc
 create mode 100644 tania_scripts/supar/modules/__pycache__/dropout.cpython-310.pyc
 create mode 100644 tania_scripts/supar/modules/__pycache__/dropout.cpython-311.pyc
 create mode 100644 tania_scripts/supar/modules/__pycache__/gnn.cpython-310.pyc
 create mode 100644 tania_scripts/supar/modules/__pycache__/gnn.cpython-311.pyc
 create mode 100644 tania_scripts/supar/modules/__pycache__/lstm.cpython-310.pyc
 create mode 100644 tania_scripts/supar/modules/__pycache__/lstm.cpython-311.pyc
 create mode 100644 tania_scripts/supar/modules/__pycache__/mlp.cpython-310.pyc
 create mode 100644 tania_scripts/supar/modules/__pycache__/mlp.cpython-311.pyc
 create mode 100644 tania_scripts/supar/modules/__pycache__/pretrained.cpython-310.pyc
 create mode 100644 tania_scripts/supar/modules/__pycache__/pretrained.cpython-311.pyc
 create mode 100644 tania_scripts/supar/modules/__pycache__/transformer.cpython-310.pyc
 create mode 100644 tania_scripts/supar/modules/__pycache__/transformer.cpython-311.pyc
 create mode 100644 tania_scripts/supar/modules/affine.py
 create mode 100644 tania_scripts/supar/modules/decoder.py
 create mode 100644 tania_scripts/supar/modules/dropout.py
 create mode 100644 tania_scripts/supar/modules/gnn.py
 create mode 100644 tania_scripts/supar/modules/lstm.py
 create mode 100644 tania_scripts/supar/modules/mlp.py
 create mode 100644 tania_scripts/supar/modules/pretrained.py
 create mode 100644 tania_scripts/supar/modules/transformer.py
 create mode 100644 tania_scripts/supar/parser.py
 create mode 100644 tania_scripts/supar/structs/__init__.py
 create mode 100644 tania_scripts/supar/structs/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/structs/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/structs/__pycache__/chain.cpython-310.pyc
 create mode 100644 tania_scripts/supar/structs/__pycache__/chain.cpython-311.pyc
 create mode 100644 tania_scripts/supar/structs/__pycache__/dist.cpython-310.pyc
 create mode 100644 tania_scripts/supar/structs/__pycache__/dist.cpython-311.pyc
 create mode 100644 tania_scripts/supar/structs/__pycache__/fn.cpython-310.pyc
 create mode 100644 tania_scripts/supar/structs/__pycache__/fn.cpython-311.pyc
 create mode 100644 tania_scripts/supar/structs/__pycache__/semiring.cpython-310.pyc
 create mode 100644 tania_scripts/supar/structs/__pycache__/semiring.cpython-311.pyc
 create mode 100644 tania_scripts/supar/structs/__pycache__/tree.cpython-310.pyc
 create mode 100644 tania_scripts/supar/structs/__pycache__/tree.cpython-311.pyc
 create mode 100644 tania_scripts/supar/structs/__pycache__/vi.cpython-310.pyc
 create mode 100644 tania_scripts/supar/structs/__pycache__/vi.cpython-311.pyc
 create mode 100644 tania_scripts/supar/structs/chain.py
 create mode 100644 tania_scripts/supar/structs/dist.py
 create mode 100644 tania_scripts/supar/structs/fn.py
 create mode 100644 tania_scripts/supar/structs/semiring.py
 create mode 100644 tania_scripts/supar/structs/tree.py
 create mode 100644 tania_scripts/supar/structs/vi.py
 create mode 100644 tania_scripts/supar/utils/__init__.py
 create mode 100644 tania_scripts/supar/utils/__pycache__/__init__.cpython-310.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/__init__.cpython-311.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/common.cpython-310.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/common.cpython-311.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/config.cpython-310.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/config.cpython-311.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/data.cpython-310.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/data.cpython-311.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/embed.cpython-310.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/embed.cpython-311.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/field.cpython-310.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/field.cpython-311.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/fn.cpython-310.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/fn.cpython-311.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/logging.cpython-310.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/logging.cpython-311.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/metric.cpython-310.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/metric.cpython-311.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/optim.cpython-310.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/optim.cpython-311.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/parallel.cpython-310.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/parallel.cpython-311.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/tokenizer.cpython-310.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/tokenizer.cpython-311.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/transform.cpython-310.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/transform.cpython-311.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/vocab.cpython-310.pyc
 create mode 100644 tania_scripts/supar/utils/__pycache__/vocab.cpython-311.pyc
 create mode 100644 tania_scripts/supar/utils/common.py
 create mode 100644 tania_scripts/supar/utils/config.py
 create mode 100644 tania_scripts/supar/utils/data.py
 create mode 100644 tania_scripts/supar/utils/embed.py
 create mode 100644 tania_scripts/supar/utils/field.py
 create mode 100644 tania_scripts/supar/utils/fn.py
 create mode 100644 tania_scripts/supar/utils/logging.py
 create mode 100644 tania_scripts/supar/utils/metric.py
 create mode 100644 tania_scripts/supar/utils/optim.py
 create mode 100644 tania_scripts/supar/utils/parallel.py
 create mode 100644 tania_scripts/supar/utils/tokenizer.py
 create mode 100644 tania_scripts/supar/utils/transform.py
 create mode 100644 tania_scripts/supar/utils/vocab.py
 create mode 100644 tania_scripts/supar/vector_quantize.py
 create mode 100644 tania_scripts/transform.py

diff --git a/tania_scripts/.ipynb_checkpoints/tania-some-other-metrics-checkpoint.ipynb b/tania_scripts/.ipynb_checkpoints/tania-some-other-metrics-checkpoint.ipynb
index e23180b..ceb6052 100644
--- a/tania_scripts/.ipynb_checkpoints/tania-some-other-metrics-checkpoint.ipynb
+++ b/tania_scripts/.ipynb_checkpoints/tania-some-other-metrics-checkpoint.ipynb
@@ -88,7 +88,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": 4,
    "id": "2a882cc9-8f9d-4457-becb-d2e26ab3f14f",
    "metadata": {},
    "outputs": [
@@ -107,7 +107,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 5,
    "id": "8897dcc3-4218-4ee5-9984-17b9a6d8dce2",
    "metadata": {},
    "outputs": [],
@@ -163,7 +163,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 6,
    "id": "1363f307-fa4b-43ba-93d5-2d1c11ceb9e4",
    "metadata": {},
    "outputs": [
@@ -184,7 +184,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
+   "execution_count": 7,
    "id": "1362e192-514a-4a77-a8cb-5c012026e2bb",
    "metadata": {},
    "outputs": [],
@@ -238,7 +238,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": 8,
    "id": "544ff6aa-4104-4580-a01f-97429ffcc228",
    "metadata": {},
    "outputs": [
@@ -328,7 +328,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 10,
+   "execution_count": 9,
    "id": "b9052dc2-ce45-4af4-a0a0-46c60a13da12",
    "metadata": {},
    "outputs": [],
@@ -388,7 +388,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 11,
+   "execution_count": 10,
    "id": "1e9dd0fb-db6a-47d1-8bfb-1015845f6d3e",
    "metadata": {},
    "outputs": [
@@ -398,7 +398,7 @@
        "{'Flesch-Douma': 88.68, 'LIX': 11.55, 'Kandel-Moles': 5.86}"
       ]
      },
-     "execution_count": 11,
+     "execution_count": 10,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -421,7 +421,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 12,
+   "execution_count": 11,
    "id": "24bc84a5-b2df-4194-838a-8f24302599bd",
    "metadata": {},
    "outputs": [],
@@ -467,7 +467,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 13,
+   "execution_count": 12,
    "id": "0cdb972f-31b6-4e7e-82a8-371eda344f2c",
    "metadata": {},
    "outputs": [
@@ -477,7 +477,7 @@
        "{'Average Word Length': 3.79, 'Average Sentence Length': 7.0}"
       ]
      },
-     "execution_count": 13,
+     "execution_count": 12,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -521,7 +521,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 14,
+   "execution_count": 13,
    "id": "56af520c-d56b-404a-aebf-ad7c2a9ca503",
    "metadata": {},
    "outputs": [],
@@ -567,7 +567,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 15,
+   "execution_count": 14,
    "id": "f7c8b125-4651-4b21-bcc4-93ef78a4239b",
    "metadata": {},
    "outputs": [
@@ -603,7 +603,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 23,
+   "execution_count": 15,
    "id": "daa17c33-adca-4695-90eb-741579382939",
    "metadata": {},
    "outputs": [],
@@ -622,7 +622,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 25,
+   "execution_count": 16,
    "id": "80d8fa08-6b7d-4ab7-85cd-987823639277",
    "metadata": {},
    "outputs": [
@@ -665,7 +665,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 22,
+   "execution_count": 18,
    "id": "3f9c7dc7-6820-4013-a85c-2af4f846d4f5",
    "metadata": {},
    "outputs": [
@@ -693,7 +693,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 18,
+   "execution_count": 19,
    "id": "65e1a630-c46e-4b18-9831-b97864de53ee",
    "metadata": {},
    "outputs": [],
@@ -713,7 +713,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 21,
+   "execution_count": 20,
    "id": "1612e911-12a8-47c9-b811-b2d6885c3647",
    "metadata": {},
    "outputs": [
@@ -742,7 +742,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 19,
+   "execution_count": 21,
    "id": "925a3a75-aaaa-4851-b77b-b42cb1e21e11",
    "metadata": {},
    "outputs": [],
@@ -757,7 +757,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 20,
+   "execution_count": 22,
    "id": "6fa60897-ad26-43b4-b8de-861290ca6bd3",
    "metadata": {},
    "outputs": [
@@ -783,25 +783,10 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": 23,
    "id": "f3678462-e572-4ce5-8d3d-a5389b2356c8",
    "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Defaulting to user installation because normal site-packages is not writeable\n",
-      "Collecting scipy\n",
-      "  Downloading scipy-1.15.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (61 kB)\n",
-      "Requirement already satisfied: numpy<2.5,>=1.23.5 in /public/conda/Miniconda/envs/pytorch-2.6/lib/python3.11/site-packages (from scipy) (2.2.4)\n",
-      "Downloading scipy-1.15.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (37.7 MB)\n",
-      "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m37.7/37.7 MB\u001b[0m \u001b[31m75.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0ma \u001b[36m0:00:01\u001b[0m\n",
-      "\u001b[?25hInstalling collected packages: scipy\n",
-      "Successfully installed scipy-1.15.3\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "#!pip3 install seaborn\n",
     "#!pip3 install scipy"
@@ -809,7 +794,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": 24,
    "id": "b621b2a8-488f-44db-b085-fe156f453943",
    "metadata": {},
    "outputs": [
@@ -830,7 +815,7 @@
     "import matplotlib.pyplot as plt\n",
     "from scipy.stats import spearmanr\n",
     "\n",
-    "# Sample data (replace with your real values)\n",
+    "# Sample data (to be replaces with real values)\n",
     "data = {\n",
     "    \"perplexity\": [32.5, 45.2, 28.1, 39.0, 50.3],\n",
     "    \"avg_word_length\": [4.1, 4.3, 4.0, 4.2, 4.5],\n",
@@ -853,10 +838,123 @@
     "plt.show()"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "id": "45ee04fc-acab-4bba-ba06-e4cf4bca9fe5",
+   "metadata": {},
+   "source": [
+    "## Tree depth"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "id": "79f99787-c220-4f1d-93a9-59230363ec3f",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def parse_sentence_block(text):\n",
+    "    lines = text.strip().split('\\n')\n",
+    "    result = []\n",
+    "    tokenlist = []\n",
+    "    for line in lines:\n",
+    "        # Split the line by tab and strip whitespace\n",
+    "        parts = tuple(line.strip().split('\\t'))\n",
+    "        # Only include lines that have exactly 4 parts\n",
+    "        if len(parts) == 4:\n",
+    "            parentidx =  int(parts[3])\n",
+    "            if '@@' in parts[2]:\n",
+    "                nonterm1 = parts[2].split('@@')[0]\n",
+    "                nonterm2 = parts[2].split('@@')[1]\n",
+    "            else:\n",
+    "                nonterm1 = parts[2]\n",
+    "                nonterm2 = '<nul>'\n",
+    "            postag = parts[1]\n",
+    "            token = parts[0]\n",
+    "            result.append((parentidx, nonterm1, nonterm2, postag))\n",
+    "            tokenlist.append(token)\n",
+    "    return result, tokenlist\n",
+    "    "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "id": "f567efb0-8b0b-4782-9345-052cf1785776",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "example_sentence = \"\"\"\n",
+    "<s>\t<s>\t<s>\t1\n",
+    "--\tponct\t<nul>@@<nul>\t1\n",
+    "Eh\tnpp\t<nul>@@<nul>\t1\n",
+    "bien?\tadv\tAP@@<nul>\t1\n",
+    "fit\tv\tVN@@<nul>\t2\n",
+    "-il\tcls-suj\tVN@@VPinf-OBJ\t3\n",
+    ".\tponct\t<nul>@@<nul>\t4\n",
+    "</s>\t</s>\t</s>\t4\n",
+    "\"\"\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "id": "8d4ecba9-89b8-4000-a061-aa16aa68a404",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from transform import *\n",
+    "\n",
+    "def visualize_const_prediction(example_sent):\n",
+    "    parsed, tokenlist = parse_sentence_block(example_sent)\n",
+    "    tree = AttachJuxtaposeTree.totree(tokenlist, 'SENT')\n",
+    "    AttachJuxtaposeTree.action2tree(tree, parsed).pretty_print()\n",
+    "    nltk_tree = AttachJuxtaposeTree.action2tree(tree, parsed)\n",
+    "    #print(\"NLTK TREE\", nltk_tree)\n",
+    "    depth = nltk_tree.height() - 1  # NLTK includes the leaf level as height 1, so subtract 1 for tree depth \n",
+    "    print(\"Tree depth:\", depth)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "id": "bfd3abf3-b83a-4817-85ad-654daf72be88",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "               SENT                                 \n",
+      "                |                                    \n",
+      "               <s>                                  \n",
+      "                |                                    \n",
+      "               <s>                                  \n",
+      "  ______________|__________                          \n",
+      " |    |    |               AP                       \n",
+      " |    |    |     __________|________                 \n",
+      " |    |    |    |               VPinf-OBJ           \n",
+      " |    |    |    |     ______________|_______         \n",
+      " |    |    |    |    |                      VN      \n",
+      " |    |    |    |    |      ________________|____    \n",
+      " |    |    |    |    VN    |                |   </s>\n",
+      " |    |    |    |    |     |                |    |   \n",
+      " |  ponct npp  adv   v  cls-suj           ponct </s>\n",
+      " |    |    |    |    |     |                |    |   \n",
+      "<s>   --   Eh bien? fit   -il               .   </s>\n",
+      "\n",
+      "Tree depth: 8\n"
+     ]
+    }
+   ],
+   "source": [
+    "visualize_const_prediction(example_sentence)"
+   ]
+  },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "3a6e3b53-7104-45ef-a4b5-e831bdd6ca6f",
+   "id": "bc51ab44-6885-45cc-bad2-6a43a7791fdb",
    "metadata": {},
    "outputs": [],
    "source": []
diff --git a/tania_scripts/.ipynb_checkpoints/transform-checkpoint.py b/tania_scripts/.ipynb_checkpoints/transform-checkpoint.py
new file mode 100644
index 0000000..56e0f51
--- /dev/null
+++ b/tania_scripts/.ipynb_checkpoints/transform-checkpoint.py
@@ -0,0 +1,459 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+import os
+from typing import TYPE_CHECKING, Iterable, List, Optional, Tuple, Union
+
+import nltk
+import torch
+
+from supar.models.const.crf.transform import Tree
+from supar.utils.common import NUL
+from supar.utils.logging import get_logger
+from supar.utils.tokenizer import Tokenizer
+from supar.utils.transform import Sentence
+
+if TYPE_CHECKING:
+    from supar.utils import Field
+
+logger = get_logger(__name__)
+
+
+class AttachJuxtaposeTree(Tree):
+    r"""
+    :class:`AttachJuxtaposeTree` is derived from the :class:`Tree` class,
+    supporting back-and-forth transformations between trees and AttachJuxtapose actions :cite:`yang-deng-2020-aj`.
+
+    Attributes:
+        WORD:
+            Words in the sentence.
+        POS:
+            Part-of-speech tags, or underscores if not available.
+        TREE:
+            The raw constituency tree in :class:`nltk.tree.Tree` format.
+        NODE:
+            The target node on each rightmost chain.
+        PARENT:
+            The label of the parent node of each terminal.
+        NEW:
+            The label of each newly inserted non-terminal with a target node and a terminal as juxtaposed children.
+            ``NUL`` represents the `Attach` action.
+    """
+
+    fields = ['WORD', 'POS', 'TREE', 'NODE', 'PARENT', 'NEW']
+
+    def __init__(
+        self,
+        WORD: Optional[Union[Field, Iterable[Field]]] = None,
+        POS: Optional[Union[Field, Iterable[Field]]] = None,
+        TREE: Optional[Union[Field, Iterable[Field]]] = None,
+        NODE: Optional[Union[Field, Iterable[Field]]] = None,
+        PARENT: Optional[Union[Field, Iterable[Field]]] = None,
+        NEW: Optional[Union[Field, Iterable[Field]]] = None
+    ) -> Tree:
+        super().__init__()
+
+        self.WORD = WORD
+        self.POS = POS
+        self.TREE = TREE
+        self.NODE = NODE
+        self.PARENT = PARENT
+        self.NEW = NEW
+
+    @property
+    def src(self):
+        return self.WORD, self.POS, self.TREE
+
+    @property
+    def tgt(self):
+        return self.NODE, self.PARENT, self.NEW
+
+    @classmethod
+    def tree2action(cls, tree: nltk.Tree):
+        r"""
+        Converts a constituency tree into AttachJuxtapose actions.
+
+        Args:
+            tree (nltk.tree.Tree):
+                A constituency tree in :class:`nltk.tree.Tree` format.
+
+        Returns:
+            A sequence of AttachJuxtapose actions.
+
+        Examples:
+            >>> from supar.models.const.aj.transform import AttachJuxtaposeTree
+            >>> tree = nltk.Tree.fromstring('''
+                                            (TOP
+                                              (S
+                                                (NP (_ Arthur))
+                                                (VP
+                                                  (_ is)
+                                                  (NP (NP (_ King)) (PP (_ of) (NP (_ the) (_ Britons)))))
+                                                (_ .)))
+                                            ''')
+            >>> tree.pretty_print()
+                            TOP
+                             |
+                             S
+               ______________|_______________________
+              |              VP                      |
+              |      ________|___                    |
+              |     |            NP                  |
+              |     |    ________|___                |
+              |     |   |            PP              |
+              |     |   |     _______|___            |
+              NP    |   NP   |           NP          |
+              |     |   |    |        ___|_____      |
+              _     _   _    _       _         _     _
+              |     |   |    |       |         |     |
+            Arthur  is King  of     the     Britons  .
+            >>> AttachJuxtaposeTree.tree2action(tree)
+            [(0, 'NP', '<nul>'), (0, 'VP', 'S'), (1, 'NP', '<nul>'),
+             (2, 'PP', 'NP'), (3, 'NP', '<nul>'), (4, '<nul>', '<nul>'),
+             (0, '<nul>', '<nul>')]
+        """
+
+        def isroot(node):
+            return node == tree[0]
+
+        def isterminal(node):
+            return len(node) == 1 and not isinstance(node[0], nltk.Tree)
+
+        def last_leaf(node):
+            pos = ()
+            while True:
+                pos += (len(node) - 1,)
+                node = node[-1]
+                if isterminal(node):
+                    return node, pos
+
+        def parent(position):
+            return tree[position[:-1]]
+
+        def grand(position):
+            return tree[position[:-2]]
+
+        def detach(tree):
+            last, last_pos = last_leaf(tree)
+            siblings = parent(last_pos)[:-1]
+
+            if len(siblings) > 0:
+                last_subtree = last
+                last_subtree_siblings = siblings
+                parent_label = NUL
+            else:
+                last_subtree, last_pos = parent(last_pos), last_pos[:-1]
+                last_subtree_siblings = [] if isroot(last_subtree) else parent(last_pos)[:-1]
+                parent_label = last_subtree.label()
+
+            target_pos, new_label, last_tree = 0, NUL, tree
+            if isroot(last_subtree):
+                last_tree = None
+            
+            elif len(last_subtree_siblings) == 1 and not isterminal(last_subtree_siblings[0]):
+                new_label = parent(last_pos).label()
+                new_label = new_label
+                target = last_subtree_siblings[0]
+                last_grand = grand(last_pos)
+                if last_grand is None:
+                    last_tree = targetistermina
+                else:
+                    last_grand[-1] = target
+                target_pos = len(last_pos) - 2
+            else:
+                target = parent(last_pos)
+                target.pop()
+                target_pos = len(last_pos) - 2
+            action = target_pos, parent_label, new_label
+            return action, last_tree
+        if tree is None:
+            return []
+        action, last_tree = detach(tree)
+        return cls.tree2action(last_tree) + [action]
+
+    @classmethod
+    def action2tree(
+        cls,
+        tree: nltk.Tree,
+        actions: List[Tuple[int, str, str]],
+        join: str = '::',
+    ) -> nltk.Tree:
+        r"""
+        Recovers a constituency tree from a sequence of AttachJuxtapose actions.
+
+        Args:
+            tree (nltk.tree.Tree):
+                An empty tree that provides a base for building a result tree.
+            actions (List[Tuple[int, str, str]]):
+                A sequence of AttachJuxtapose actions.
+            join (str):
+                A string used to connect collapsed node labels. Non-terminals containing this will be expanded to unary chains.
+                Default: ``'::'``.
+
+        Returns:
+            A result constituency tree.
+
+        Examples:
+            >>> from supar.models.const.aj.transform import AttachJuxtaposeTree
+            >>> tree = AttachJuxtaposeTree.totree(['Arthur', 'is', 'King', 'of', 'the', 'Britons', '.'], 'TOP')
+            >>> AttachJuxtaposeTree.action2tree(tree,
+                                                [(0, 'NP', '<nul>'), (0, 'VP', 'S'), (1, 'NP', '<nul>'),
+                                                 (2, 'PP', 'NP'), (3, 'NP', '<nul>'), (4, '<nul>', '<nul>'),
+                                                 (0, '<nul>', '<nul>')]).pretty_print()
+                            TOP
+                             |
+                             S
+               ______________|_______________________
+              |              VP                      |
+              |      ________|___                    |
+              |     |            NP                  |
+              |     |    ________|___                |
+              |     |   |            PP              |
+              |     |   |     _______|___            |
+              NP    |   NP   |           NP          |
+              |     |   |    |        ___|_____      |
+              _     _   _    _       _         _     _
+              |     |   |    |       |         |     |
+            Arthur  is King  of     the     Britons  .
+        """
+
+        def target(node, depth):
+            node_pos = ()
+            for _ in range(depth):
+                node_pos += (len(node) - 1,)
+                node = node[-1]
+            return node, node_pos
+
+        def parent(tree, position):
+            return tree[position[:-1]]
+
+        def execute(tree: nltk.Tree, terminal: Tuple(str, str), action: Tuple[int, str, str]) -> nltk.Tree:
+            target_pos, parent_label, new_label, post = action
+            #print(target_pos, parent_label, new_label)
+            new_leaf = nltk.Tree(post, [terminal[0]])
+
+            # create the subtree to be inserted
+            new_subtree = new_leaf if parent_label == NUL else nltk.Tree(parent_label, [new_leaf])
+            # find the target position at which to insert the new subtree
+            target_node = tree
+            if target_node is not None:
+                target_node, target_pos = target(target_node, target_pos)
+
+            # Attach
+            if new_label == NUL:
+                # attach the first token
+                if target_node is None:
+                    return new_subtree
+                target_node.append(new_subtree)
+            # Juxtapose
+            else:
+                new_subtree = nltk.Tree(new_label, [target_node, new_subtree])
+                if len(target_pos) > 0:
+                    parent_node = parent(tree, target_pos)
+                    parent_node[-1] = new_subtree
+                else:
+                    tree = new_subtree
+            return tree
+
+        tree, root, terminals = None, tree.label(), tree.pos()
+        for terminal, action in zip(terminals, actions):
+            tree = execute(tree, terminal, action)
+        # recover unary chains
+        nodes = [tree]
+        while nodes:
+            node = nodes.pop()
+            if isinstance(node, nltk.Tree):
+                nodes.extend(node)
+                if join in node.label():
+                    labels = node.label().split(join)
+                    node.set_label(labels[0])
+                    subtree = nltk.Tree(labels[-1], node)
+                    for label in reversed(labels[1:-1]):
+                        subtree = nltk.Tree(label, [subtree])
+                    node[:] = [subtree]
+        return nltk.Tree(root, [tree])
+
+    @classmethod
+    def action2span(
+        cls,
+        action: torch.Tensor,
+        spans: torch.Tensor = None,
+        nul_index: int = -1,
+        mask: torch.BoolTensor = None
+    ) -> torch.Tensor:
+        r"""
+        Converts a batch of the tensorized action at a given step into spans.
+
+        Args:
+            action (~torch.Tensor): ``[3, batch_size]``.
+                A batch of the tensorized action at a given step, containing indices of target nodes, parent and new labels.
+            spans (~torch.Tensor):
+                Spans generated at previous steps, ``None`` at the first step. Default: ``None``.
+            nul_index (int):
+                The index for the obj:`NUL` token, representing the Attach action. Default: -1.
+            mask (~torch.BoolTensor): ``[batch_size]``.
+                The mask for covering the unpadded tokens.
+
+        Returns:
+            A tensor representing a batch of spans for the given step.
+
+        Examples:
+            >>> from collections import Counter
+            >>> from supar.models.const.aj.transform import AttachJuxtaposeTree, Vocab
+            >>> from supar.utils.common import NUL
+            >>> nodes, parents, news = zip(*[(0, 'NP', NUL), (0, 'VP', 'S'), (1, 'NP', NUL),
+                                             (2, 'PP', 'NP'), (3, 'NP', NUL), (4, NUL, NUL),
+                                             (0, NUL, NUL)])
+            >>> vocab = Vocab(Counter(sorted(set([*parents, *news]))))
+            >>> actions = torch.tensor([nodes, vocab[parents], vocab[news]]).unsqueeze(1)
+            >>> spans = None
+            >>> for action in actions.unbind(-1):
+            ...     spans = AttachJuxtaposeTree.action2span(action, spans, vocab[NUL])
+            ...
+            >>> spans
+            tensor([[[-1,  1, -1, -1, -1, -1, -1,  3],
+                     [-1, -1, -1, -1, -1, -1,  4, -1],
+                     [-1, -1, -1,  1, -1, -1,  1, -1],
+                     [-1, -1, -1, -1, -1, -1,  2, -1],
+                     [-1, -1, -1, -1, -1, -1,  1, -1],
+                     [-1, -1, -1, -1, -1, -1, -1, -1],
+                     [-1, -1, -1, -1, -1, -1, -1, -1],
+                     [-1, -1, -1, -1, -1, -1, -1, -1]]])
+            >>> sequence = torch.where(spans.ge(0))
+            >>> sequence = list(zip(sequence[1].tolist(), sequence[2].tolist(), vocab[spans[sequence]]))
+            >>> sequence
+            [(0, 1, 'NP'), (0, 7, 'S'), (1, 6, 'VP'), (2, 3, 'NP'), (2, 6, 'NP'), (3, 6, 'PP'), (4, 6, 'NP')]
+            >>> tree = AttachJuxtaposeTree.totree(['Arthur', 'is', 'King', 'of', 'the', 'Britons', '.'], 'TOP')
+            >>> AttachJuxtaposeTree.build(tree, sequence).pretty_print()
+                            TOP
+                             |
+                             S
+               ______________|_______________________
+              |              VP                      |
+              |      ________|___                    |
+              |     |            NP                  |
+              |     |    ________|___                |
+              |     |   |            PP              |
+              |     |   |     _______|___            |
+              NP    |   NP   |           NP          |
+              |     |   |    |        ___|_____      |
+              _     _   _    _       _         _     _
+              |     |   |    |       |         |     |
+            Arthur  is King  of     the     Britons  .
+
+        """
+
+        # [batch_size]
+        target, parent, new = action
+        if spans is None:
+            spans = action.new_full((action.shape[1], 2, 2), -1)
+            spans[:, 0, 1] = parent
+            return spans
+        if mask is None:
+            mask = torch.ones_like(target, dtype=bool)
+        juxtapose_mask = new.ne(nul_index) & mask
+        # ancestor nodes are those on the rightmost chain and higher than the target node
+        # [batch_size, seq_len]
+        rightmost_mask = spans[..., -1].ge(0)
+        ancestors = rightmost_mask.cumsum(-1).masked_fill_(~rightmost_mask, -1) - 1
+        # should not include the target node for the Juxtapose action
+        ancestor_mask = mask.unsqueeze(-1) & ancestors.ge(0) & ancestors.le((target - juxtapose_mask.long()).unsqueeze(-1))
+        target_pos = torch.where(ancestors.eq(target.unsqueeze(-1))[juxtapose_mask])[-1]
+        # the right boundaries of ancestor nodes should be aligned with the new generated terminals
+        spans = torch.cat((spans, torch.where(ancestor_mask, spans[..., -1], -1).unsqueeze(-1)), -1)
+        spans[..., -2].masked_fill_(ancestor_mask, -1)
+        spans[juxtapose_mask, target_pos, -1] = new.masked_fill(new.eq(nul_index), -1)[juxtapose_mask]
+        spans[mask, -1, -1] = parent.masked_fill(parent.eq(nul_index), -1)[mask]
+        # [batch_size, seq_len+1, seq_len+1]
+        spans = torch.cat((spans, torch.full_like(spans[:, :1], -1)), 1)
+        return spans
+
+    def load(
+        self,
+        data: Union[str, Iterable],
+        lang: Optional[str] = None,
+        **kwargs
+    ) -> List[AttachJuxtaposeTreeSentence]:
+        r"""
+        Args:
+            data (Union[str, Iterable]):
+                A filename or a list of instances.
+            lang (str):
+                Language code (e.g., ``en``) or language name (e.g., ``English``) for the text to tokenize.
+                ``None`` if tokenization is not required.
+                Default: ``None``.
+
+        Returns:
+            A list of :class:`AttachJuxtaposeTreeSentence` instances.
+        """
+
+        if lang is not None:
+            tokenizer = Tokenizer(lang)
+        if isinstance(data, str) and os.path.exists(data):
+            if data.endswith('.txt'):
+                data = (s.split() if lang is None else tokenizer(s) for s in open(data) if len(s) > 1)
+            else:
+                data = open(data)
+        else:
+            if lang is not None:
+                data = [tokenizer(i) for i in ([data] if isinstance(data, str) else data)]
+            else:
+                data = [data] if isinstance(data[0], str) else data
+
+        index = 0
+        for s in data:
+
+            try:
+                tree = nltk.Tree.fromstring(s) if isinstance(s, str) else self.totree(s, self.root)
+                sentence = AttachJuxtaposeTreeSentence(self, tree, index)
+            except ValueError:
+                logger.warning(f"Error found while converting Sentence {index} to a tree:\n{s}\nDiscarding it!")
+                continue
+            except IndexError:
+                tree = nltk.Tree.fromstring('(S ' + s + ')')
+                sentence = AttachJuxtaposeTreeSentence(self, tree, index)
+            else:
+                yield sentence
+                index += 1
+        self.root = tree.label()
+
+
+class AttachJuxtaposeTreeSentence(Sentence):
+    r"""
+    Args:
+        transform (AttachJuxtaposeTree):
+            A :class:`AttachJuxtaposeTree` object.
+        tree (nltk.tree.Tree):
+            A :class:`nltk.tree.Tree` object.
+        index (Optional[int]):
+            Index of the sentence in the corpus. Default: ``None``.
+    """
+
+    def __init__(
+        self,
+        transform: AttachJuxtaposeTree,
+        tree: nltk.Tree,
+        index: Optional[int] = None
+    ) -> AttachJuxtaposeTreeSentence:
+        super().__init__(transform, index)
+
+        words, tags = zip(*tree.pos())
+        nodes, parents, news = None, None, None
+        if transform.training:
+            oracle_tree = tree.copy(True)
+            # the root node must have a unary chain
+            if len(oracle_tree) > 1:
+                oracle_tree[:] = [nltk.Tree('*', oracle_tree)]
+            oracle_tree.collapse_unary(joinChar='::')
+            if len(oracle_tree) == 1 and not isinstance(oracle_tree[0][0], nltk.Tree):
+                oracle_tree[0] = nltk.Tree('*', [oracle_tree[0]])
+            nodes, parents, news = zip(*transform.tree2action(oracle_tree))
+        tags = [x.split("##")[0] for x in tags]
+        self.values = [words, tags, tree, nodes, parents, news]
+
+    def __repr__(self):
+        return self.values[-4].pformat(1000000)
+
+    def pretty_print(self):
+        self.values[-4].pretty_print()
diff --git a/tania_scripts/__pycache__/transform.cpython-311.pyc b/tania_scripts/__pycache__/transform.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0fa71196328a1158b12ae2fffe91d227ae067efc
GIT binary patch
literal 24881
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/.ipynb_checkpoints/__init__-checkpoint.py b/tania_scripts/supar/.ipynb_checkpoints/__init__-checkpoint.py
new file mode 100644
index 0000000..146f3df
--- /dev/null
+++ b/tania_scripts/supar/.ipynb_checkpoints/__init__-checkpoint.py
@@ -0,0 +1,106 @@
+# -*- coding: utf-8 -*-
+
+from .models import (AttachJuxtaposeConstituencyParser, AttachJuxtaposeConstituencyParserPos,
+                     BiaffineDependencyParser,
+                     BiaffineSemanticDependencyParser, CRF2oDependencyParser,
+                     CRFConstituencyParser, CRFDependencyParser, SLDependencyParser, ArcEagerDependencyParser,
+                     TetraTaggingConstituencyParser, VIConstituencyParser, SLConstituentParser,
+                     VIDependencyParser, VISemanticDependencyParser)
+from .parser import Parser
+from .structs import (BiLexicalizedConstituencyCRF, ConstituencyCRF,
+                      ConstituencyLBP, ConstituencyMFVI, Dependency2oCRF,
+                      DependencyCRF, DependencyLBP, DependencyMFVI,
+                      LinearChainCRF, MatrixTree, SemanticDependencyLBP,
+                      SemanticDependencyMFVI, SemiMarkovCRF)
+
+
+
+__all__ = ['Parser',
+
+           # Dependency Parsing
+           'BiaffineDependencyParser',
+           'CRFDependencyParser',
+           'CRF2oDependencyParser',
+           'VIDependencyParser',
+           'SLDependencyParser',
+           'ArcEagerDependencyParser',
+
+           # Constituent Parsing
+           'AttachJuxtaposeConstituencyParser',
+           'CRFConstituencyParser',
+           'TetraTaggingConstituencyParser',
+           'VIConstituencyParser',
+           'SLConstituentParser',
+
+           # Semantic Parsing
+           'BiaffineSemanticDependencyParser',
+           'VISemanticDependencyParser',
+           'LinearChainCRF',
+           'SemiMarkovCRF',
+
+           # transforms
+           'MatrixTree',
+           'DependencyCRF',
+           'Dependency2oCRF',
+           'ConstituencyCRF',
+           'BiLexicalizedConstituencyCRF',
+           'DependencyLBP',
+           'DependencyMFVI',
+           'ConstituencyLBP',
+           'ConstituencyMFVI',
+           'SemanticDependencyLBP',
+           'SemanticDependencyMFVI']
+
+__version__ = '1.1.4'
+
+PARSER = {parser.NAME: parser for parser in [BiaffineDependencyParser,
+                                             CRFDependencyParser,
+                                             CRF2oDependencyParser,
+                                             VIDependencyParser,
+                                             SLDependencyParser,
+                                             ArcEagerDependencyParser,
+                                             AttachJuxtaposeConstituencyParser,
+                                             CRFConstituencyParser,
+                                             TetraTaggingConstituencyParser,
+                                             VIConstituencyParser,
+                                             SLConstituentParser,
+                                             BiaffineSemanticDependencyParser,
+                                             VISemanticDependencyParser]}
+
+SRC = {'github': 'https://github.com/yzhangcs/parser/releases/download',
+       'hlt': 'http://hlt.suda.edu.cn/~yzhang/supar'}
+NAME = {
+    'biaffine-dep-en': 'ptb.biaffine.dep.lstm.char',
+    'biaffine-dep-zh': 'ctb7.biaffine.dep.lstm.char',
+    'crf2o-dep-en': 'ptb.crf2o.dep.lstm.char',
+    'crf2o-dep-zh': 'ctb7.crf2o.dep.lstm.char',
+    'biaffine-dep-roberta-en': 'ptb.biaffine.dep.roberta',
+    'biaffine-dep-electra-zh': 'ctb7.biaffine.dep.electra',
+    'biaffine-dep-xlmr': 'ud.biaffine.dep.xlmr',
+    'crf-con-en': 'ptb.crf.con.lstm.char',
+    'crf-con-zh': 'ctb7.crf.con.lstm.char',
+    'crf-con-roberta-en': 'ptb.crf.con.roberta',
+    'crf-con-electra-zh': 'ctb7.crf.con.electra',
+    'crf-con-xlmr': 'spmrl.crf.con.xlmr',
+    'biaffine-sdp-en': 'dm.biaffine.sdp.lstm.tag-char-lemma',
+    'biaffine-sdp-zh': 'semeval16.biaffine.sdp.lstm.tag-char-lemma',
+    'vi-sdp-en': 'dm.vi.sdp.lstm.tag-char-lemma',
+    'vi-sdp-zh': 'semeval16.vi.sdp.lstm.tag-char-lemma',
+    'vi-sdp-roberta-en': 'dm.vi.sdp.roberta',
+    'vi-sdp-electra-zh': 'semeval16.vi.sdp.electra'
+}
+MODEL = {src: {n: f"{link}/v1.1.0/{m}.zip" for n, m in NAME.items()} for src, link in SRC.items()}
+CONFIG = {src: {n: f"{link}/v1.1.0/{m}.ini" for n, m in NAME.items()} for src, link in SRC.items()}
+
+
+def compatible():
+    import sys
+    supar = sys.modules[__name__]
+    if supar.__version__ < '1.2':
+        sys.modules['supar.utils.transform'].CoNLL = supar.models.dep.biaffine.transform.CoNLL
+        sys.modules['supar.utils.transform'].Tree = supar.models.const.crf.transform.Tree
+        sys.modules['supar.parsers'] = supar.models
+        sys.modules['supar.parsers.con'] = supar.models.const
+
+
+compatible()
diff --git a/tania_scripts/supar/.ipynb_checkpoints/parser-checkpoint.py b/tania_scripts/supar/.ipynb_checkpoints/parser-checkpoint.py
new file mode 100644
index 0000000..f1c372e
--- /dev/null
+++ b/tania_scripts/supar/.ipynb_checkpoints/parser-checkpoint.py
@@ -0,0 +1,620 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+import contextlib
+import os
+import shutil
+import sys
+import tempfile
+import pickle
+from contextlib import contextmanager
+from datetime import datetime, timedelta
+from typing import Any, Iterable, Union
+
+import dill
+import torch
+import torch.distributed as dist
+import torch.nn as nn
+from torch.cuda.amp import GradScaler
+from torch.optim import Adam, Optimizer
+from torch.optim.lr_scheduler import ExponentialLR, _LRScheduler
+
+import supar
+from supar.utils import Config, Dataset
+from supar.utils.field import Field
+from supar.utils.fn import download, get_rng_state, set_rng_state
+from supar.utils.logging import get_logger, init_logger, progress_bar
+from supar.utils.metric import Metric
+from supar.utils.optim import InverseSquareRootLR, LinearLR
+from supar.utils.parallel import DistributedDataParallel as DDP
+from supar.utils.parallel import gather, is_dist, is_master, reduce
+from supar.utils.transform import Batch
+
+logger = get_logger(__name__)
+
+
+class Parser(object):
+
+    NAME = None
+    MODEL = None
+
+    def __init__(self, args, model, transform):
+        self.args = args
+        self.model = model
+        self.transform = transform
+
+    @property
+    def device(self):
+        return 'cuda' if torch.cuda.is_available() else 'cpu'
+
+    @property
+    def sync_grad(self):
+        return self.step % self.args.update_steps == 0 or self.step % self.n_batches == 0
+
+    @contextmanager
+    def sync(self):
+        context = getattr(contextlib, 'suppress' if sys.version < '3.7' else 'nullcontext')
+        if is_dist() and not self.sync_grad:
+            context = self.model.no_sync
+        with context():
+            yield
+
+    @contextmanager
+    def join(self):
+        context = getattr(contextlib, 'suppress' if sys.version < '3.7' else 'nullcontext')
+        if not is_dist():
+            with context():
+                yield
+        elif self.model.training:
+            with self.model.join():
+                yield
+        else:
+            try:
+                dist_model = self.model
+                # https://github.com/pytorch/pytorch/issues/54059
+                if hasattr(self.model, 'module'):
+                    self.model = self.model.module
+                yield
+            finally:
+                self.model = dist_model
+
+    def train(
+        self,
+        train: Union[str, Iterable],
+        dev: Union[str, Iterable],
+        test: Union[str, Iterable],
+        epochs: int,
+        patience: int,
+        batch_size: int = 5000,
+        update_steps: int = 1,
+        buckets: int = 32,
+        workers: int = 0,
+        clip: float = 5.0,
+        amp: bool = False,
+        cache: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ) -> None:
+        r"""
+        Args:
+            train/dev/test (Union[str, Iterable]):
+                Filenames of the train/dev/test datasets.
+            epochs (int):
+                The number of training iterations.
+            patience (int):
+                The number of consecutive iterations after which the training process would be early stopped if no improvement.
+            batch_size (int):
+                The number of tokens in each batch. Default: 5000.
+            update_steps (int):
+                Gradient accumulation steps. Default: 1.
+            buckets (int):
+                The number of buckets that sentences are assigned to. Default: 32.
+            workers (int):
+                The number of subprocesses used for data loading. 0 means only the main process. Default: 0.
+            clip (float):
+                Clips gradient of an iterable of parameters at specified value. Default: 5.0.
+            amp (bool):
+                Specifies whether to use automatic mixed precision. Default: ``False``.
+            cache (bool):
+                If ``True``, caches the data first, suggested for huge files (e.g., > 1M sentences). Default: ``False``.
+            verbose (bool):
+                If ``True``, increases the output verbosity. Default: ``True``.
+        """
+
+        args = self.args.update(locals())
+        init_logger(logger, verbose=args.verbose)
+
+        self.transform.train()
+        batch_size = batch_size // update_steps
+        eval_batch_size = args.get('eval_batch_size', batch_size)
+        if is_dist():
+            batch_size = batch_size // dist.get_world_size()
+            eval_batch_size = eval_batch_size // dist.get_world_size()
+        logger.info("Loading the data")
+        if args.cache:
+            args.bin = os.path.join(os.path.dirname(args.path), 'bin')
+        args.even = args.get('even', is_dist())
+        
+        train = Dataset(self.transform, args.train, **args).build(batch_size=batch_size,
+                                                                  n_buckets=buckets,
+                                                                  shuffle=True,
+                                                                  distributed=is_dist(),
+                                                                  even=args.even,
+                                                                  n_workers=workers)
+        dev = Dataset(self.transform, args.dev, **args).build(batch_size=eval_batch_size,
+                                                              n_buckets=buckets,
+                                                              shuffle=False,
+                                                              distributed=is_dist(),
+                                                              even=False,
+                                                              n_workers=workers)
+        logger.info(f"{'train:':6} {train}")
+        if not args.test:
+            logger.info(f"{'dev:':6} {dev}\n")
+        else:
+            test = Dataset(self.transform, args.test, **args).build(batch_size=eval_batch_size,
+                                                                    n_buckets=buckets,
+                                                                    shuffle=False,
+                                                                    distributed=is_dist(),
+                                                                    even=False,
+                                                                    n_workers=workers)
+            logger.info(f"{'dev:':6} {dev}")
+            logger.info(f"{'test:':6} {test}\n")
+        loader, sampler = train.loader, train.loader.batch_sampler
+        args.steps = len(loader) * epochs // args.update_steps
+        args.save(f"{args.path}.yaml")
+
+        self.optimizer = self.init_optimizer()
+        self.scheduler = self.init_scheduler()
+        self.scaler = GradScaler(enabled=args.amp)
+
+        if dist.is_initialized():
+            self.model = DDP(module=self.model,
+                             device_ids=[args.local_rank],
+                             find_unused_parameters=args.get('find_unused_parameters', True),
+                             static_graph=args.get('static_graph', False))
+            if args.amp:
+                from torch.distributed.algorithms.ddp_comm_hooks.default_hooks import fp16_compress_hook
+                self.model.register_comm_hook(dist.group.WORLD, fp16_compress_hook)
+        if args.wandb and is_master():
+            import wandb
+            # start a new wandb run to track this script
+            wandb.init(config=args.primitive_config,
+                       project=args.get('project', self.NAME),
+                       name=args.get('name', args.path),
+                       resume=self.args.checkpoint)
+        self.step, self.epoch, self.best_e, self.patience = 1, 1, 1, patience
+        # uneven batches are excluded
+        self.n_batches = min(gather(len(loader))) if is_dist() else len(loader)
+        self.best_metric, self.elapsed = Metric(), timedelta()
+        if args.checkpoint:
+            try:
+                self.optimizer.load_state_dict(self.checkpoint_state_dict.pop('optimizer_state_dict'))
+                self.scheduler.load_state_dict(self.checkpoint_state_dict.pop('scheduler_state_dict'))
+                self.scaler.load_state_dict(self.checkpoint_state_dict.pop('scaler_state_dict'))
+                set_rng_state(self.checkpoint_state_dict.pop('rng_state'))
+                for k, v in self.checkpoint_state_dict.items():
+                    setattr(self, k, v)
+                sampler.set_epoch(self.epoch)
+            except AttributeError:
+                logger.warning("No checkpoint found. Try re-launching the training procedure instead")
+
+        for epoch in range(self.epoch, args.epochs + 1):
+            start = datetime.now()
+            bar, metric = progress_bar(loader), Metric()
+
+            logger.info(f"Epoch {epoch} / {args.epochs}:")
+            self.model.train()
+            with self.join():
+                # we should reset `step` as the number of batches in different processes is not necessarily equal
+                self.step = 1
+                for batch in bar:
+                    with self.sync():
+                        with torch.autocast(self.device, enabled=args.amp):
+                            loss = self.train_step(batch)
+                        self.backward(loss)
+                    if self.sync_grad:
+                        self.clip_grad_norm_(self.model.parameters(), args.clip)
+                        self.scaler.step(self.optimizer)
+                        self.scaler.update()
+                        self.scheduler.step()
+                        self.optimizer.zero_grad(True)
+
+                    bar.set_postfix_str(f"lr: {self.scheduler.get_last_lr()[0]:.4e} - loss: {loss:.4f}")
+                    # log metrics to wandb
+                    if args.wandb and is_master():
+                        wandb.log({'lr': self.scheduler.get_last_lr()[0], 'loss': loss})
+                    self.step += 1
+                logger.info(f"{bar.postfix}")
+            self.model.eval()
+            with self.join(), torch.autocast(self.device, enabled=args.amp):
+                metric = self.reduce(sum([self.eval_step(i) for i in progress_bar(dev.loader)], Metric()))
+                logger.info(f"{'dev:':5} {metric}")
+                if args.wandb and is_master():
+                    wandb.log({'dev': metric.values, 'epochs': epoch})
+                if args.test:
+                    test_metric = sum([self.eval_step(i) for i in progress_bar(test.loader)], Metric())
+                    logger.info(f"{'test:':5} {self.reduce(test_metric)}")
+                    if args.wandb and is_master():
+                        wandb.log({'test': test_metric.values, 'epochs': epoch})
+
+            t = datetime.now() - start
+            self.epoch += 1
+            self.patience -= 1
+            self.elapsed += t
+
+            if metric > self.best_metric:
+                self.best_e, self.patience, self.best_metric = epoch, patience, metric
+                if is_master():
+                    self.save_checkpoint(args.path)
+                logger.info(f"{t}s elapsed (saved)\n")
+            else:
+                logger.info(f"{t}s elapsed\n")
+            if self.patience < 1:
+                break
+        if is_dist():
+            dist.barrier()
+
+        best = self.load(**args)
+        # only allow the master device to save models
+        if is_master():
+            best.save(args.path)
+
+        logger.info(f"Epoch {self.best_e} saved")
+        logger.info(f"{'dev:':5} {self.best_metric}")
+        if args.test:
+            best.model.eval()
+            with best.join():
+                test_metric = sum([best.eval_step(i) for i in progress_bar(test.loader)], Metric())
+                logger.info(f"{'test:':5} {best.reduce(test_metric)}")
+        logger.info(f"{self.elapsed}s elapsed, {self.elapsed / epoch}s/epoch")
+        if args.wandb and is_master():
+            wandb.finish()
+
+        self.evaluate(data=args.test, batch_size=batch_size)
+        self.predict(args.test, batch_size=batch_size, buckets=buckets, workers=workers)
+
+        with open(f'{self.args.folder}/status', 'w') as file:
+            file.write('finished')
+
+
+
+    def evaluate(
+        self,
+        data: Union[str, Iterable],
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        r"""
+        Args:
+            data (Union[str, Iterable]):
+                The data for evaluation. Both a filename and a list of instances are allowed.
+            batch_size (int):
+                The number of tokens in each batch. Default: 5000.
+            buckets (int):
+                The number of buckets that sentences are assigned to. Default: 8.
+            workers (int):
+                The number of subprocesses used for data loading. 0 means only the main process. Default: 0.
+            amp (bool):
+                Specifies whether to use automatic mixed precision. Default: ``False``.
+            cache (bool):
+                If ``True``, caches the data first, suggested for huge files (e.g., > 1M sentences). Default: ``False``.
+            verbose (bool):
+                If ``True``, increases the output verbosity. Default: ``True``.
+
+        Returns:
+            The evaluation results.
+        """
+
+        args = self.args.update(locals())
+        init_logger(logger, verbose=args.verbose)
+
+        self.transform.train()
+        logger.info("Loading the data")
+        if args.cache:
+            args.bin = os.path.join(os.path.dirname(args.path), 'bin')
+        if is_dist():
+            batch_size = batch_size // dist.get_world_size()
+        data = Dataset(self.transform, **args)
+        data.build(batch_size=batch_size,
+                   n_buckets=buckets,
+                   shuffle=False,
+                   distributed=is_dist(),
+                   even=False,
+                   n_workers=workers)
+        logger.info(f"\n{data}")
+
+        logger.info("Evaluating the data")
+        start = datetime.now()
+        self.model.eval()
+        with self.join():
+            bar, metric = progress_bar(data.loader), Metric()
+            for batch in bar:
+                metric += self.eval_step(batch)
+                bar.set_postfix_str(metric)
+            metric = self.reduce(metric)
+        elapsed = datetime.now() - start
+        logger.info(f"{metric}")
+        logger.info(f"{elapsed}s elapsed, "
+                    f"{sum(data.sizes)/elapsed.total_seconds():.2f} Tokens/s, "
+                    f"{len(data)/elapsed.total_seconds():.2f} Sents/s")
+        os.makedirs(os.path.dirname(self.args.folder + '/metrics.pickle'), exist_ok=True)
+        with open(f'{self.args.folder}/metrics.pickle', 'wb') as file:
+            pickle.dump(obj=metric, file=file)
+
+        return metric
+
+    def predict(
+        self,
+        data: Union[str, Iterable],
+        pred: str = None,
+        lang: str = None,
+        prob: bool = False,
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        cache: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        r"""
+        Args:
+            data (Union[str, Iterable]):
+                The data for prediction.
+                - a filename. If ends with `.txt`, the parser will seek to make predictions line by line from plain texts.
+                - a list of instances.
+            pred (str):
+                If specified, the predicted results will be saved to the file. Default: ``None``.
+            lang (str):
+                Language code (e.g., ``en``) or language name (e.g., ``English``) for the text to tokenize.
+                ``None`` if tokenization is not required.
+                Default: ``None``.
+            prob (bool):
+                If ``True``, outputs the probabilities. Default: ``False``.
+            batch_size (int):
+                The number of tokens in each batch. Default: 5000.
+            buckets (int):
+                The number of buckets that sentences are assigned to. Default: 8.
+            workers (int):
+                The number of subprocesses used for data loading. 0 means only the main process. Default: 0.
+            amp (bool):
+                Specifies whether to use automatic mixed precision. Default: ``False``.
+            cache (bool):
+                If ``True``, caches the data first, suggested for huge files (e.g., > 1M sentences). Default: ``False``.
+            verbose (bool):
+                If ``True``, increases the output verbosity. Default: ``True``.
+
+        Returns:
+            A :class:`~supar.utils.Dataset` object containing all predictions if ``cache=False``, otherwise ``None``.
+        """
+
+        args = self.args.update(locals())
+        init_logger(logger, verbose=args.verbose)
+
+        if self.args.use_vq:
+            self.model.passes_remaining = 0
+            self.model.vq.observe_steps_remaining = 0
+
+        self.transform.eval()
+        if args.prob:
+            self.transform.append(Field('probs'))
+
+        #logger.info("Loading the data")
+        if args.cache:
+            args.bin = os.path.join(os.path.dirname(args.path), 'bin')
+        if is_dist():
+            batch_size = batch_size // dist.get_world_size()
+        data = Dataset(self.transform, **args)
+        data.build(batch_size=batch_size,
+                   n_buckets=buckets,
+                   shuffle=False,
+                   distributed=is_dist(),
+                   even=False,
+                   n_workers=workers)
+
+        #logger.info(f"\n{data}")
+
+        #logger.info("Making predictions on the data")
+        start = datetime.now()
+        self.model.eval()
+        #with tempfile.TemporaryDirectory() as t:
+            # we have clustered the sentences by length here to speed up prediction,
+            # so the order of the yielded sentences can't be guaranteed
+        for batch in progress_bar(data.loader):
+            #batch, head_preds, deprel_preds, stack_list, buffer_list, actions_list, act_dict_list, deprel_preds_decoded, pos_preds_decoded, sent_text, act_dict = self.pred_step(batch)
+            *predicted_values, = self.pred_step(batch)
+            #print('429 supar/parser.py ', batch.sentences)
+            #print(head_preds, deprel_preds, stack_list, act_dict_list, deprel_preds_decoded, pos_preds_decoded, sent_text)
+            #logger.info(f"Saving predicted results to {pred}")
+           # with open(pred, 'w') as f:
+                    
+
+            elapsed = datetime.now() - start
+
+            #if is_dist():
+            #    dist.barrier()
+            #tdirs = gather(t) if is_dist() else (t,)
+            #if pred is not None and is_master():
+                #logger.info(f"Saving predicted results to {pred}")
+            """with open(pred, 'w') as f:
+                    # merge all predictions into one single file
+                    if is_dist() or args.cache:
+                        sentences = (os.path.join(i, s) for i in tdirs for s in os.listdir(i))
+                        for i in progress_bar(sorted(sentences, key=lambda x: int(os.path.basename(x)))):
+                            with open(i) as s:
+                                shutil.copyfileobj(s, f)
+                    else:
+                        for s in progress_bar(data):
+                            f.write(str(s) + '\n')"""
+            # exit util all files have been merged
+            if is_dist():
+                dist.barrier()
+        #logger.info(f"{elapsed}s elapsed, "
+        #            f"{sum(data.sizes)/elapsed.total_seconds():.2f} Tokens/s, "
+        #            f"{len(data)/elapsed.total_seconds():.2f} Sents/s")
+
+        if not cache:
+            #return data, head_preds, deprel_preds, stack_list, buffer_list, actions_list, act_dict_list, deprel_preds_decoded, pos_preds_decoded, sent_text, act_dict
+            return *predicted_values,
+
+    def backward(self, loss: torch.Tensor, **kwargs):
+        loss /= self.args.update_steps
+        if hasattr(self, 'scaler'):
+            self.scaler.scale(loss).backward(**kwargs)
+        else:
+            loss.backward(**kwargs)
+
+    def clip_grad_norm_(
+        self,
+        params: Union[Iterable[torch.Tensor], torch.Tensor],
+        max_norm: float,
+        norm_type: float = 2
+    ) -> torch.Tensor:
+        self.scaler.unscale_(self.optimizer)
+        return nn.utils.clip_grad_norm_(params, max_norm, norm_type)
+
+    def clip_grad_value_(
+        self,
+        params: Union[Iterable[torch.Tensor], torch.Tensor],
+        clip_value: float
+    ) -> None:
+        self.scaler.unscale_(self.optimizer)
+        return nn.utils.clip_grad_value_(params, clip_value)
+
+    def reduce(self, obj: Any) -> Any:
+        if not is_dist():
+            return obj
+        return reduce(obj)
+
+    def train_step(self, batch: Batch) -> torch.Tensor:
+        ...
+
+    @torch.no_grad()
+    def eval_step(self, batch: Batch) -> Metric:
+        ...
+
+    @torch.no_grad()
+    def pred_step(self, batch: Batch) -> Batch:
+        ...
+
+    def init_optimizer(self) -> Optimizer:
+        if self.args.encoder in ('lstm', 'transformer'):
+            optimizer = Adam(params=self.model.parameters(),
+                             lr=self.args.lr,
+                             betas=(self.args.get('mu', 0.9), self.args.get('nu', 0.999)),
+                             eps=self.args.get('eps', 1e-8),
+                             weight_decay=self.args.get('weight_decay', 0))
+        else:
+            # we found that Huggingface's AdamW is more robust and empirically better than the native implementation
+            from transformers import AdamW
+            optimizer = AdamW(params=[{'params': p, 'lr': self.args.lr * (1 if n.startswith('encoder') else self.args.lr_rate)}
+                                      for n, p in self.model.named_parameters()],
+                              lr=self.args.lr,
+                              betas=(self.args.get('mu', 0.9), self.args.get('nu', 0.999)),
+                              eps=self.args.get('eps', 1e-8),
+                              weight_decay=self.args.get('weight_decay', 0))
+        return optimizer
+
+    def init_scheduler(self) -> _LRScheduler:
+        if self.args.encoder == 'lstm':
+            scheduler = ExponentialLR(optimizer=self.optimizer,
+                                      gamma=self.args.decay**(1/self.args.decay_steps))
+        elif self.args.encoder == 'transformer':
+            scheduler = InverseSquareRootLR(optimizer=self.optimizer,
+                                            warmup_steps=self.args.warmup_steps)
+        else:
+            scheduler = LinearLR(optimizer=self.optimizer,
+                                 warmup_steps=self.args.get('warmup_steps', int(self.args.steps*self.args.get('warmup', 0))),
+                                 steps=self.args.steps)
+        return scheduler
+
+    @classmethod
+    def build(cls, path, **kwargs):
+        ...
+
+    @classmethod
+    def load(
+        cls,
+        path: str,
+        reload: bool = True,
+        src: str = 'github',
+        checkpoint: bool = False,
+        **kwargs
+    ) -> Parser:
+        r"""
+        Loads a parser with data fields and pretrained model parameters.
+
+        Args:
+            path (str):
+                - a string with the shortcut name of a pretrained model defined in ``supar.MODEL``
+                  to load from cache or download, e.g., ``'biaffine-dep-en'``.
+                - a local path to a pretrained model, e.g., ``./<path>/model``.
+            reload (bool):
+                Whether to discard the existing cache and force a fresh download. Default: ``False``.
+            src (str):
+                Specifies where to download the model.
+                ``'github'``: github release page.
+                ``'hlt'``: hlt homepage, only accessible from 9:00 to 18:00 (UTC+8).
+                Default: ``'github'``.
+            checkpoint (bool):
+                If ``True``, loads all checkpoint states to restore the training process. Default: ``False``.
+
+        Examples:
+            >>> from supar import Parser
+            >>> parser = Parser.load('biaffine-dep-en')
+            >>> parser = Parser.load('./ptb.biaffine.dep.lstm.char')
+        """
+
+        args = Config(**locals())
+        if not os.path.exists(path):
+            path = download(supar.MODEL[src].get(path, path), reload=reload)
+        state = torch.load(path, map_location='cpu', weights_only=False)
+        #torch.load(path, map_location='cpu')
+        cls = supar.PARSER[state['name']] if cls.NAME is None else cls
+        args = state['args'].update(args)
+        #print('ARGS', args)
+        model = cls.MODEL(**args)
+        model.load_pretrained(state['pretrained'])
+        model.load_state_dict(state['state_dict'], True)
+        transform = state['transform']
+        parser = cls(args, model, transform)
+        parser.checkpoint_state_dict = state.get('checkpoint_state_dict', None) if checkpoint else None
+        parser.model.to(parser.device)
+        return parser
+
+    def save(self, path: str) -> None:
+        model = self.model
+        if hasattr(model, 'module'):
+            model = self.model.module
+        state_dict = {k: v.cpu() for k, v in model.state_dict().items()}
+        pretrained = state_dict.pop('pretrained.weight', None)
+        state = {'name': self.NAME,
+                 'args': model.args,
+                 'state_dict': state_dict,
+                 'pretrained': pretrained,
+                 'transform': self.transform}
+        torch.save(state, path, pickle_module=dill)
+
+    def save_checkpoint(self, path: str) -> None:
+        model = self.model
+        if hasattr(model, 'module'):
+            model = self.model.module
+        checkpoint_state_dict = {k: getattr(self, k) for k in ['epoch', 'best_e', 'patience', 'best_metric', 'elapsed']}
+        checkpoint_state_dict.update({'optimizer_state_dict': self.optimizer.state_dict(),
+                                      'scheduler_state_dict': self.scheduler.state_dict(),
+                                      'scaler_state_dict': self.scaler.state_dict(),
+                                      'rng_state': get_rng_state()})
+        state_dict = {k: v.cpu() for k, v in model.state_dict().items()}
+        pretrained = state_dict.pop('pretrained.weight', None)
+        state = {'name': self.NAME,
+                 'args': model.args,
+                 'state_dict': state_dict,
+                 'pretrained': pretrained,
+                 'checkpoint_state_dict': checkpoint_state_dict,
+                 'transform': self.transform}
+        torch.save(state, path, pickle_module=dill)
diff --git a/tania_scripts/supar/__init__.py b/tania_scripts/supar/__init__.py
new file mode 100644
index 0000000..146f3df
--- /dev/null
+++ b/tania_scripts/supar/__init__.py
@@ -0,0 +1,106 @@
+# -*- coding: utf-8 -*-
+
+from .models import (AttachJuxtaposeConstituencyParser, AttachJuxtaposeConstituencyParserPos,
+                     BiaffineDependencyParser,
+                     BiaffineSemanticDependencyParser, CRF2oDependencyParser,
+                     CRFConstituencyParser, CRFDependencyParser, SLDependencyParser, ArcEagerDependencyParser,
+                     TetraTaggingConstituencyParser, VIConstituencyParser, SLConstituentParser,
+                     VIDependencyParser, VISemanticDependencyParser)
+from .parser import Parser
+from .structs import (BiLexicalizedConstituencyCRF, ConstituencyCRF,
+                      ConstituencyLBP, ConstituencyMFVI, Dependency2oCRF,
+                      DependencyCRF, DependencyLBP, DependencyMFVI,
+                      LinearChainCRF, MatrixTree, SemanticDependencyLBP,
+                      SemanticDependencyMFVI, SemiMarkovCRF)
+
+
+
+__all__ = ['Parser',
+
+           # Dependency Parsing
+           'BiaffineDependencyParser',
+           'CRFDependencyParser',
+           'CRF2oDependencyParser',
+           'VIDependencyParser',
+           'SLDependencyParser',
+           'ArcEagerDependencyParser',
+
+           # Constituent Parsing
+           'AttachJuxtaposeConstituencyParser',
+           'CRFConstituencyParser',
+           'TetraTaggingConstituencyParser',
+           'VIConstituencyParser',
+           'SLConstituentParser',
+
+           # Semantic Parsing
+           'BiaffineSemanticDependencyParser',
+           'VISemanticDependencyParser',
+           'LinearChainCRF',
+           'SemiMarkovCRF',
+
+           # transforms
+           'MatrixTree',
+           'DependencyCRF',
+           'Dependency2oCRF',
+           'ConstituencyCRF',
+           'BiLexicalizedConstituencyCRF',
+           'DependencyLBP',
+           'DependencyMFVI',
+           'ConstituencyLBP',
+           'ConstituencyMFVI',
+           'SemanticDependencyLBP',
+           'SemanticDependencyMFVI']
+
+__version__ = '1.1.4'
+
+PARSER = {parser.NAME: parser for parser in [BiaffineDependencyParser,
+                                             CRFDependencyParser,
+                                             CRF2oDependencyParser,
+                                             VIDependencyParser,
+                                             SLDependencyParser,
+                                             ArcEagerDependencyParser,
+                                             AttachJuxtaposeConstituencyParser,
+                                             CRFConstituencyParser,
+                                             TetraTaggingConstituencyParser,
+                                             VIConstituencyParser,
+                                             SLConstituentParser,
+                                             BiaffineSemanticDependencyParser,
+                                             VISemanticDependencyParser]}
+
+SRC = {'github': 'https://github.com/yzhangcs/parser/releases/download',
+       'hlt': 'http://hlt.suda.edu.cn/~yzhang/supar'}
+NAME = {
+    'biaffine-dep-en': 'ptb.biaffine.dep.lstm.char',
+    'biaffine-dep-zh': 'ctb7.biaffine.dep.lstm.char',
+    'crf2o-dep-en': 'ptb.crf2o.dep.lstm.char',
+    'crf2o-dep-zh': 'ctb7.crf2o.dep.lstm.char',
+    'biaffine-dep-roberta-en': 'ptb.biaffine.dep.roberta',
+    'biaffine-dep-electra-zh': 'ctb7.biaffine.dep.electra',
+    'biaffine-dep-xlmr': 'ud.biaffine.dep.xlmr',
+    'crf-con-en': 'ptb.crf.con.lstm.char',
+    'crf-con-zh': 'ctb7.crf.con.lstm.char',
+    'crf-con-roberta-en': 'ptb.crf.con.roberta',
+    'crf-con-electra-zh': 'ctb7.crf.con.electra',
+    'crf-con-xlmr': 'spmrl.crf.con.xlmr',
+    'biaffine-sdp-en': 'dm.biaffine.sdp.lstm.tag-char-lemma',
+    'biaffine-sdp-zh': 'semeval16.biaffine.sdp.lstm.tag-char-lemma',
+    'vi-sdp-en': 'dm.vi.sdp.lstm.tag-char-lemma',
+    'vi-sdp-zh': 'semeval16.vi.sdp.lstm.tag-char-lemma',
+    'vi-sdp-roberta-en': 'dm.vi.sdp.roberta',
+    'vi-sdp-electra-zh': 'semeval16.vi.sdp.electra'
+}
+MODEL = {src: {n: f"{link}/v1.1.0/{m}.zip" for n, m in NAME.items()} for src, link in SRC.items()}
+CONFIG = {src: {n: f"{link}/v1.1.0/{m}.ini" for n, m in NAME.items()} for src, link in SRC.items()}
+
+
+def compatible():
+    import sys
+    supar = sys.modules[__name__]
+    if supar.__version__ < '1.2':
+        sys.modules['supar.utils.transform'].CoNLL = supar.models.dep.biaffine.transform.CoNLL
+        sys.modules['supar.utils.transform'].Tree = supar.models.const.crf.transform.Tree
+        sys.modules['supar.parsers'] = supar.models
+        sys.modules['supar.parsers.con'] = supar.models.const
+
+
+compatible()
diff --git a/tania_scripts/supar/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d5c3cf986e39a18d48492fcd3a44278864d4b01b
GIT binary patch
literal 3404
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..56a7800cb9807c641e2b80be758fb03c3bf53e19
GIT binary patch
literal 5116
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/__pycache__/__init__.cpython-39.pyc b/tania_scripts/supar/__pycache__/__init__.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6cfcfd5b0e97b495425c09456acbce3e34f9f610
GIT binary patch
literal 3349
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/__pycache__/model.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1f9c7f70c814a90cca12c500a2fd2a58d1bca963
GIT binary patch
literal 6512
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/__pycache__/model.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..bda67fe0c4d0c1e433a13cbc03f01e01e490e0d9
GIT binary patch
literal 14276
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/__pycache__/parser.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..854f1c47cee59890cdb61da54ee728faf5093ffb
GIT binary patch
literal 20095
zcmd1j<>g{vU|{HuS)ZPr&cN^(#6iX^3=9ko3=E9LC5#LVDGVu$ISjdsQH+crHd78$
z6jKUA3R4bq6f>A+iDCiMtWm6Bnk|YAOtVL^r!b^2=P>1RL~(%ivgB~)az=6Haz$~0
z`K&qIxja!kxx7)lxqMN4U@@i~{wRL1et{?fFfEuX6eSFm6Uh~g5(Tr_a>R1Qqr|~%
z_8f^^$tcNOsVFHhpCd;)S0+j(S2ju(%xB7xi;_!WNa4(p&sB(0$W@F|1dDU!DCH_g
zDTCSEIV!oTQL4FWQEIvBQR-kZo*a!_%_z-WtthQr?I>-q7;lbFu5Oern9Y}?m#ZJ8
zpKB0h0Os@O80H#98H3pZIfl6=Q6{;jQKq?OQD(X3QRZNA!5oWR%P31mhE&Z|t7gV1
zYj=hep%md3h7{pcn`Y)H+Z3i?22GKdp!m>ayv3cEmzQ6XSdy8aSL~<Bc#AJNKd&UU
zq9ivlFEKr}NR#OnM@nKzYDs2p>Mc$XnUb1QlBmgii`g-+@)n0@NorAIQcmhE*3i7n
z{5(y@TU_o%i7CO!i8)}+ERHFOxwkm|3raF`GpoQtysi}m`FW{%C7FpiK0&v5;(daG
zlQU9NN+CMfob&V2GShFdyCjw*7N?eIGTvf!%S_El(PX~Gk&<7Ymy@5Ea*H=TwIseM
zFFn4vB(Ws*7H=^!SCjb`7f3!QKRrFQ=oWWoUS>%=l*3a{l%HOdT3j5Tlvt$6c#F+9
zwWKIBS(E9OuxDObYEf}&aA9d;QEE_reu+=eEe@Z|ywt=ZpCC=fTjDO6#U(|VNu?#J
zDImuMBo-y+<fP_kvfN@zPb|quExN^?Ssb5|SzL09GqX58H?g=RwdfXGQEEzQaw^Cl
zPKhPS8OflKN5-tM+~B~-z>vxi#hAhn#gxJr#hk(z#gf95!ra0T#hS{N!ji(;!qChZ
z#h%KR!j{4gW^<%+rf{Tig4tZDoGDx>++a30Cl4ntCm$z2rvRrQry!?LN<vCvidu?#
z3u_b)Cl99vCqGm?DJ3~YD@D77HHw#$k&}^A5H2f}l9G~|Vvu6k!WzYwl9pnUV%owI
z#m{M$lAe;0Vx3~s!Wt!zl9^(cV&B3NC76<x;*{dt!V)EvlAYp~;@-j%C7dd<Ky)EP
zN=}MridPFuGh>t(R3taWJH-bqBA$|$;+Nvz!V)EslAjWo64b&HC7CLf5}XnO_K9?=
z6sHhpD5qdbK}umtR7!LUYcpe%OiEEoOiFAEOO$L%QA%7&d<#pITnb|_gJ$t9wt&Q<
z;?yF)WKb~!3uq9ViGhK^8C2|uF)%RHFxD`{Gt@BEFvK&~FxN1|Go>&DGpuCv(`3HI
zl30{pe2X<VKP5Hi7H3IOVqS4teo?L_%Pp4T)SR>;B?bnDB4rSv!oa|=lA%bAfq~(d
zseVR&ZmK>gGbQFF>LukQrevlT=_lvs7Ub)u7nJCN&C@R~El4cVF95qyub}c4M|?au
zfyQewFfbIeF)%Q&F|sjoF;?+I{GkVvPiBO9hJk?r#D@Dvh=GBjgdvM@0n<W;B6d(P
zfHOI>-z}Ep(v-wo%*h3%n#{LYOY)17Gm11B7#MExWERIKmL+E9fO79j#v)aaZ$RDv
z`=v-7q=qdewJb9^RUhOokX=GdRlHC)L1b{d2oyp!3|R~{3|Wj>OkxZvjM+>D0#FfV
z2tSxXlgY0L<Pl9!z?P&IfCKgxPiX<D$cZm5Ni8V8#hDkM1j;t4#YMVU+{js6nU@@&
zUX++(40EOuQ<VVJnQ%!ImxBDl!N9<f3`z?L3=9m73?&RDj3rE2%qfi73`JZiOnHnc
z%*{--j3q413`OEK3|XwjAd)SMy_T_tv6-Qt2UOUGF)%WOGo&!EFt9K*GlN8e84MYU
zHOm<p89*?S0V1Z!;`fW$SkL?xM{#LE0jTu3#hq80lLIYlH92mvr>B-AmXs9T;)06h
zWG3BWF0L%T#SSWzGV}9_WI(<*0ui8;cZ)qQKOW>gO(t;M-C~Dogv1{>Cc%-&0#alS
z3L8EK1_q`E2__y!4lq>uU&W0SPAEad%)r0^526zUgQ!@OV4x_W2MQ=qv)GC}K=cCk
zh4_Qi5nXo`C^}ecnMyc7`cqh%nTo<etSrtNhIrN#21wL^vo|X!V?$Ww44SNdMWB>Y
zWC99FQ*biR%?DLJnp{O@ATdx_6<L5-mLLKg?BEdRC@D(J%*)J6zr~W3pP6@yJtMIg
z6lX=Y3=9mK%;0D!vSwglh~fg(0rBAMjust7_6!URAY7~fjSV(vTyTKnMd?2iGaDlh
z6Bi=~qYx83en9rU>=0&PcnQibFF|_28Rt2qL=bUs3%SJ#cHS=$a77$lTvDW?0IQv2
zZ!xE&mfd10Ni8n9#g<x-pPW&Ai#ao|<Q7LkVo7FdUUKR!E^sc3F9y}p2B2VJPby8$
zPAw_E#a^CYl$}~se2XPHC$r!dYg$fzV#zJ$#N2{gEJ^wKIk#Ao6O%Ji!6`K<zc>|C
z<CT;a<=tZO%g;+q1|>U)GZ`2_4(DNDVBiMjyciA!h7QIoh6RizOw9}n8Eg4Vm`hk{
z__J737<-u*L2_)Mgu%#A!&bvC#Zb#u!@qzdg{g*ZAychD31>4ykxmU;3D*Mdg$!U>
z0XSQrgk=Fw3iConMur;xEZ!o=622_{1p;7Fu!cX2e<5QE%R;6a{&*p<nXDkwz<l8n
zkq*Wzwi^B{_B5tUh8q4QjD3t*qBU$a94TxdRW<xs!Zn;J?7eKYjBvGLC~5_2I8r!3
zYEw9%Dw)9U;Y{J0&62`h!#JB^F3fG>#r<G89;h7CY=#uxxhx=;=jp)B7bjpoGrAcN
z^TDEgP?MPvCf6`#Nq}&cBokAuV69MzRE=OWV-1T4D72)d7;5<AWoq~r$bv#@HbV;k
zTqclvIv5woEoA6mjF<0VT%Z7EDV8YJ@MkHf2=p>`FvhEta4k?>$S{GiNVr6;gE33J
zhCfRqoe><uf+=jE@Lj->B9y|hkSRsDm!*R-9;8AUq&`I?MKnh<SF2VS9PjE2v`e_M
zbh317gcmY_<4|t`W07fzely5)(-e^uu^hcxks6UKgBt!UL$D3v9gJB<P&*_*E?>w5
zN?lpTDU!V`j0`DKAXvki#u5Xv*`$Lp-n4@;-mHT$-W(KH6Bvv9ODsw(Az{(X*vy#6
z3}JUL##@zGH#3yjG&3+Ubuh-;b}+`<)$nH-Phc$CP-Wl2m?ggeL^>>ROp#v52nnk!
zMYxy@TucQnCJPZOaq3{q0_l@m$k@yX_PfIZ=Y<R|46)oXOtqr5VkIsej5VS)VxanE
z0%KusjnD$u4#q4~kS*a1dHgI4C2kWKE7ybS8%Bl_mIdx9@*ufLhCIe{h7u2u+8X{W
z&lD+fhGr%gh6#+Z+iS&3ycT#bWT=%W@d3p=$ahRkwUV_`;1r`!BR-oUMG>THHbaWi
zTvm{Ip!kI3#ty~>0t*@Xmw>{wgE8KuM$&~Lw!c=ogK>fHLWX`FMurl<EdLJ1tN>`*
zVCv@u`D{U8jr2msTA6T$6fszhna63!FoCI<6}fotU|bMXBLlJ%i%Ka}m07_Pn2KCF
z7#D<q-50tLl!C)RX{LiQOJ#uxC~iO|fq9Gz89?sHQe0pHWyvoHPhkVe*GMjiNKx)!
z%u-wsxsV}6M3NyzWj0HSYK=^a+H4j`eyrio(wo3klnqXWOhwr>A`7CBb=1hDsLz4s
z6c&aolN2d)1}27hlL?H4Pe9>XBbgOFn*n4S7Js#&`AdC448)D#ux`N;rdc4rEQl?M
zYiCSjOwmZuY~d*JsbR{JXl8U_Xl4Y(X*1J8MrfS!q-cT59x0@<2jrV`P~V&b`KCrH
zE51fNMH}La8vZQt3Cu-|P#bihHZY^wP%8`aTM8e<{0_ziu{E*_kxMu|uo<A7%Ur|=
zwnY|fi!Q_#jIdxX=0Oe%Eb=nQ@{p8VBO$?1E7!ru!jNSO4R=#8&pbuS0u&48V4hu#
z95_zwYNR?Cvuv|jCNLKz)QH!x)<`ikGcm);15h3ZhYNF2cn9Nx1aN7>2+mzRHFC2V
zQuH7tVjc&`?_d#qh)4%xmU)U)Hp2wwq5?*SJf;bZg*(Be3v*Fb3D<%|NStORrC7r1
zmQDt!O+6h9kP;V^LO|xGD0DDpnayTMF+eKKq45ZEJyJ}9;^|%oLl!L6Fo08y8Y4qV
zTsuP=V~QbBamRofcUVIHCQ8V&Ea2&2%(9!!kYWU)Ys94)W;3K1Bjpz6qMuOT{j3pL
zkPP*G3MggOu%(zlYxz_NzXnuWnu5yek~DD1oj#i(#cVE9ig`0rKVPkUjr@X)6bn%3
zAiFF@4AkbHz*4M^>^6|7rd1*fD+2?U0u(qFr59Vlc_2Y>i%CBvwM-w>GE&gM)^yTD
z)dJGymYI{9mzbMctdO6kP?C|VfM!k#WaOe)55+P_vr9oEGp_`TnIRde3VEfuNvTC(
zL!m8Ag-p=+3V3h^)i7AIjX2|y^Ye;RlS@l7%Tkd{R7gxKNi9++&&W*9KzJiFFI}Oa
zC_g#1xLBb)zceRBAt_ZMHL)nCQlYpczn~yBMIkdyAunGcGq<29zbrL3HLnEKZHR^>
zajq-L&rZ!NR>;g#NKH)6PylP!Q*cR5ODxSPu~INKFfc&10J(pN%L>paRAy>ki9%v>
za%pa94tRu10o<iTGTRW<U}%dMmzk(>1XEm+kyxTooSIhxYDO0;Bo?JABo-HErst)m
zD3s(QS!Qg6Y8$j!O`L7TrAg3ONi9|=Ely2QNXsu$0Hrhq(12KGUb>!wfkJL-VqURA
zeqK%`I6`w1GxK1PiR2Kp-~_em6*R!DdMpXkIVZEASOL_*1_x(;nnGe8BoQU$q=M3F
zL1Iy2ZfZ$tQLzFjAPQ2GGt)9tQxwV)b4pW@Y&F$Gvo|rfKtUrZKR*YHt-(-ZiWSN;
zQb9v&3MKg<Z!090mgMIqmSiR?<Yrc+rYIB?r6y+<XXfW2*_4prmY7qVnvj4R-r!ye
zP8&Vb6cQ3bib_)x5_A;6N{hi^2oB=3%%b8F9fji3^z_u?5@_IOl%}UDq-Ex$7At6^
z>ZR-HDA*|&`XZ8oCSfO)r51sDOvE`VGcUO)HL*Aq;;#JCl7i9_1&9fmC6y?aLHvR6
z{z}H85Ky0vKea3|Cmx)`z&*WR0zUbPDWEJ5D#k!wy~UiAnRkmNwJbF+WF=dX4@ehi
z2nN;{EY2uROUp^U#SQA>LI*>OqM@pwDcY@y4O}8x-C{KR#i&rll9F0xb&HX!iWOAM
zT2-;?RVL=<XfobnPt5}jKc(CfOUukli7(9qCG2=ag1W^68s5zWkM9&@XtIEN+PAnM
zgHQ39DaA#ppe}kEhyZnrH5qRSr4<;O#e>G&K*KEY8Tt9yez({Qit@8klS^)~fQoI<
zcx^Ixkhv%mq%#ZTdbXm};?msIA}0_>Bp)_j4H;jKPsvO!xg}Bz8>U7U6)Xmibt4OL
z!Uv|ST>SDCk~311vkUSw^GX!b@=Nnl^b|shDiw-Sb#oF+^O7@Qp$`r+5C@#kQ%Z|c
z6*BXROHvb4s@PmXU3P^kW(9qPUyN2&EICD13RTQ{CaG1N3c3n8`NhQ$ewrrJEvB5J
zTPz?UlmQ*km=|cES(t%=@iS=rGo7J^A(p+Cv4dd&Lk;6X#)(XYOu>+m%$1C{IKc@8
zR9voPy2YetaEmb$Y4{C1u*7APlUZB>3TZpgFvMq&4Pp#c3eX`Xuy^!qa`KZCbBgWs
z5Q=Xxnrbo?xr0L96Ep}1ia6N#0LToOD~n1%O27kIr65*0h(HVhg4|G4#lXPu1|(h$
z8iHXe@&K_xrdA0RE2QQm7Jv#$jpD?z)D%swDlWJfR~4HASQKX%VY6M6@fJ%`YH<l<
zOb6}&9!3U+B9H@qal<XpQK(`s)(2PlnoPG?KsgJXmo%BdRFN;pp?(Yu3{~v<pfp}u
ze2cOC7DrlUUS@GdY6{o}%}mI6C>x}{yTt|x%OX)w5@pK)Pi}y-brEP3y2uqI%$%ND
z0v;*6#RAHpxA;KwAm#Z*IVs@$ev2hDFD<_)7^IXbzxWnQL1IY;cueXRdrD>zD0dV^
zft&`)(M9|qWvof1nK>zt_yPql$Qg+#sYSPVp~XmIZb43J(Jkhj)Vw0_z!57b*%aSm
z0R`|aKJeH!JU`vyL@*&z@Jw}!6V5E+1i2v)WIY=sd)?y8ECvsgXC~%kR;8xgVs>!}
z01v_6;sOUtd{JUvc9bP}gj)~fb!ge7mza~DUzAyrkz1^nl2QOF8FIm;La|;7q=f<D
z6=i^I6Dmqg&jiidAk^JrO)ttXEx5%R?jPjia*MS*F)t;lNEW1;1?0C|0tH2xxtXB0
zRXn6rxy9n==<9lm3z6@OKtt%aSi#BR78@uD#itf|gN$I#&CDy32Km+yM2Le3PzJcg
z4OW#4o}9YH4o%9p_(64jJSf4WLdqmjgeAzr%mw)cMZzEpSTjpfbBk}W7emLFIYBdJ
z5Qp$NmO!VoT#JhGi*B)(Cl-N+H(84k^U_m`K>4T$G;eZ?IWNDw2vlek*?=6V4KkPm
zR1+sB7MB$1fw)}Y{0<(ozr~T1n4DdnSd>x(8m_*@4{Bh5hv?(;@{4lgZ*d_?_#%Ih
zX3nbAqI|H5Tl^sR733F}q-9pb7nc;>;s&MQoW$ai_#99o%TK?>4wVMgQi(Z5av&3!
zi%WBFv4NW$#kcrDDK8!oGPl^15{rs5Q^Dn8V#+NxNH)900V?E5LGy>~1x2agGM**B
zAT{q6TUve&D2cO{7iE^DYAO_|g1imNU`60^3zQEa!2^m!NR9?2eMGhf`>P0)g29;$
zoK0`BfdVDH7@Vt%B0xs=g51tt49P;^Bv>>TB*d6~i?OU|5s1lJT#{H+a*H`BvFH{X
zG(E6_vtCg#XsnqVRHw#6B^XO?v4C16kn)46s1{@i*zw@f3gm+z&{Tj9BLf4UHXkDw
z69*#?BO4<RBM&1NBO9X>qX44>6B8p7BMT!7BNHRrZwWRC4@9#47GndcfvJFrNiYg9
ziZBW>axrl+g3N@>UvV*V{N-TbVH9E%01a_7f$U&oWcw?_qQoS`$ic|OC<2B8U=;$4
ze2jdIO#daAIT!^PrI@%t?qT9!<YE+I<YAQi&%-45mxDzFWIiJoBM+krlK_(xSf|_@
zE>Sr~HAXQ;kVzbj3XC#f7E^=Vccun81|DvZ$$X4FOk#{6-wH7bF!6x=_n(7_gHeD9
zH1ICMB*6%>i;Gc#QI1jWpByvD%>qm!jABeYj4J=Dc#vzgmmHvAtp`<JAQr6h5@29p
z02N%`puz2Hj0~X3FT~(BCwOq16E?VA!;l3X+%91O4QhkBwKbesoJATXTv^-;c)%oY
z4QCejLdF#4g-kV^@q8ux%?w3`HB2P}3k1PK-b^JzAal|fGZ|_)K?BvG$*C;i8m1cN
z6c&)`6qXv66xLog@X!TE3LALn89YP<wv`=ZYYBLcww9}gAxmt5IH-$W!?1v7Aw$19
zBSQ&jm{_uzu|x_q^jXVY%TvSc!Vt?>%Ui=!!>~ZQhIb*OIRi*^flLh#$h5+o8qhEX
z&qBspo^XZ~4){PHhap387jhRJVs8zX1Vb$!$Tc-Qkiju9n{PHl3TKI24P%ykGh+=O
zXt-IL0Wy$XqFBR-CdM-tJcw7qm8Ap?H-;>REaenlafXGADSRpXpn--G70~o!mNIx4
zoGC@1nW<l(mcK+bORa{dhCf9Rqz2i=H9Vk!h2kg3ZU%{I3MI~D#yhM4s_ls$OaOH%
z!5TpQIcR|d?#?*nmt-g;DuA*xs9sh`%u7*7Q~<TPK)o(d(=ahFIThOB%*n|wPfbBI
z_(8)I;6egi?Gx9<B)K0B>j4urqybY*ba&YT)i=<-1#w=XVQ+b~*9z@(rqZm}3LiEL
zN(Id$q7B-CG7KW0D1iEHIVDJAZAIar(m4`DfSR&yMKK^IXw^-Xuq&vAkXQohWx+bU
zenoYl#T(3eMrpse6+*ycQToL?3colMf>ZNKiuH@D`1K*xYq4HIW^#5;YKSJ|EsoTR
z%;J*x{Onsy<w=@Mx0v&jvWhN%dLinN`n?HcYcq%dwbzSUKrB!nya?V{FX{k^f!g9l
zogh{hhycwE7j=VJAjgB7@<nYRZaatowaANlKrB$ZtY`y>1)7^K+6`iXTWFvrMG?3i
zSq2i@4kAEJq@q2L)<kAiYVj@JlKhgyocQ9@<ovvp;-Y?#6i04ic4|syQE|~xke(wT
zF*b;YZ?UA5<`!rQK-xi|iVxD}f%jt2S~^9?K_-CKfE1kuvCe>qvmoLeh*$<9Kw$-L
zra%aA`{WP<1A`PJ14A*Wk;10{YD+*`C7>3H5F;BSsKo(lmw;L(0&Jkx3#gp{YEAHg
z+b}Y}dDuWL86ifN{{l>0|KylKtpcw9EX)FbS(xD~YM{v{^%e`L-FJ%_)XrqdNd(R8
z7Zl|uC4*NlLaTL21_lPulr^|kpMYMgbAxMjZlqeBA&ad@I)$l*A&Wg8G+E7%#h%3(
z52{_cLA5F)Lk)KpZ;^HlLl*Y}z7qZv=4SAOVF}9uffVqxZw+^rV39+KP?qol5iluQ
z!<{9(kTHdIAyW-^yjY2NGeePQ4Qq+S0!eTyfVD&lWE!{?zzuH&NY}8|u%)npRHv}j
zu!AP7!L0y+6b_VDfItc-sNOD-Ss=R*RFgAgu|wPmt9@M<Vijt6YZw+NfNJ{~?poej
zzFPiTfm*>@p<3Zu5zr)MtvEz~4UYsvtpq0n$kw8nB@zo1LG6jcN|5hrBxW<DaFr<4
zFlH$?GuB8fP+7<z&5*)9n<a&(L={}8Ba87u>hv0p;$t<8HGDPvH3Bt)H9|GQH6ozt
z&>HbH?qG%#zF-DT{zM5j8r8?3<dK;S8h=Nvj6l_^E>h*Jr{I~UkeZiLtWcg=lA(~G
zS5i@upaUL1ge>$@D9_BvQ7BGL%?1r*f^r&Y<Py~704=;!$jQu0RY<CY&}l{axe5h2
zps`!fN=&4p4P-3{gRI7A2%x$U<Z=a#;*ugPgR7ot3dPXz)fA{BA>E(U6j*Tzac@#8
zWRwKtW>9$vYKx$ZGlCX)pbxWx@)0hZeG>E1OB2&m6_WE)QemT}2??or2??4C`9%sK
zy<mB8iw8QYnvmd{m!6YZoB>h<Y9)c30ty+hvp@xQW>qSx??Hi-kN|NVXu1O2w8^Z3
zOaf#UE9B*uC={g@mSz^AH<~~?;ZqMVBTx+o6%oYMeULF)$apPCS7K6TPG(7FYB5S6
zVjZj=ZM>xxgNC|6Bf`|1>KJXj4RGVlQNb!XC$YHLDxnU%4py(UBr~U2544=RIJG1}
zAwLN;POku3%LrL(r;wPFgHlvxg63(!^E0;4jH9EF51Jt=&n!+=z|66b<{)U0`4%fE
z4;B|;Z5qn?CT4@0g`jd1QsRT=(ZD4*sCNc#Bo<u)HC!%(h${>X41Stw_?vpS*h-62
z<I4&m<CFpgiJ%l6Uz7@(mIEy#WGX9+63<U6PAw`+1&^E+BP1csL~yh20k|cWSWu9f
zmr?{8WS~;R5#C(9#R>8?*ab!VLB0bu6^m|wST{igsClR<iPZSJ3lhB#B0z3KZwrE3
zwBV*LS~C#T_`AiGk(!ti53;cM7EelQK~ZWBl*d(El9-$w531O1aVM3grKJ`@I6R5q
zD!3TJ<4sI10S|scxFX1A#HXZ!YL=8+f(7}-5M$v&oS-?{cu>7@ivwmv5x6M|o?`$L
z;8y5i1_p)%P%AWmfq{WfhmR37PQ=B?#l*%a04AltBW4)wQFcgsl#fM$k%yg$osFA=
zk*R@;5!M!EVUc2F`Cr8c9Z3R(KxT3Yco6Rw4`kdrBsH%%zbF|r3j%F@GJqE1g4+7v
z=BFEU-Fg;77NaafEn^8&4MPfJGgFad4MP_50v6CbP8MqlXx$<cs38bheO$wcDW=Kn
zS2PV2fgo>dvO&@@cnH%0Bnpzc#R?gE-wf*1Kv%bdMjRoHdyqb)mODt%c~F>v2E;%u
za2ZAsCU|=rHXi&E<g;6B;NjomU)qr67O+LC(a2#CtD}Izy~UB6SOFeBzQqY1L@uc;
zNX1y-4;ncKFYpI-ctE2)3m9t{vLNGK%vmf8SZf$TV`B@MgBgkxLEd5m2f{6m(mb$V
z<BKMP@)}cK-Yr&e!Bn&bq>2TS^uK^Y<{OCk4kFM(0HhK$=vNGiEj~5@#wsyrOk)gx
zg9XY!)8omY=tYleun$1Xj&b>5A!wow$^At?K<)uKz33;1^$X+)0kAEgdHZ;<Rq?PD
z%3yE&2B|~y!5;<&hWns61p9!MkFiP|!v_$fimrpSgSIN5q*YMtf-u+vkUa^_48^Q9
zjKK^gpjGpXuwZ9`^lL$}1YN!kF%iu{Ao=GY2Z3y2V`O3EV1#c#fNZKM0u?Dm@}QAe
zkj1c&1hGLSKFA@TLB0X400+l7ILWSrESZOBMzeDhXhsoaC&&yI#wtN*5Fn;Ez@2Lh
zf5WUR`U?sgP~?EED*6ZFqS*oJn7?OaU;s~<vLJRVfV!pNQkWvspD{2nd<IQP{s&Dj
z!gfM{iW{)mMckm!0y!5JTA(xt8n<R<U|=lX$H2hQ0UAAJOkpfzDAFlm>Hrrl3n8Mc
zAh`u>pj}A|K{5;r!26OGGNr+IY$@z;8IBarg-j`2y{w>d>0pKw&J^w(_FRry(2`yz
z@WM2n6y6pNunnA`MX$|_AoH^*vPF~64>aYPQ(TgJiyOXoC$;DnQ*LSc*)t&U#{L#l
zUTL~^yV%Wh-{0HcVooh6PPghYc+^+vYIlpLJT)^tqXblOBvyi#*=w>Efpbj}C}XiE
zrIsWX7qNhXn3a)%0kp9Tw973VWiA;MsO$_3450b;V$fa#@O-;i3{x#*EmI9Ru(B9y
z7#A?5Ff3#&5=>#tV+MPjS%e{lX$}))HeQn%v_t|_qZNS{CTKDt+@Z+=DYU_E0#%(w
zCB>l5XB2x*QG8KiNvbAuQ3c4ojCr>h3(zL-!4v0<OtAe%3~Y=V|En~iNgXt+84sVP
z#Wsbn$px{S0~7|J!4hx_r)VoEt%KZC)C#hg2PyE2i`W?%7;XuG`gJKtD?DI@61eaJ
zDS_k~@H9WTGM>c1!0;WEA3?)rpo#@F0R^5)`oqG<^Aog}h2=jRlN5OPhwV2DTa_qQ
zZxr#OCwou^2jvA&AyEt(iUSq5S&X2aN=4$Jnl+0VEW(lk8q8tHVwGkPW=LV~Wr8GT
zupDCwOEy!HMhP3J{soJ$r?A3QfVZZA%~-&h!d3zr0%FMG2B})WnZgcQ1uw$T%(xI@
zI(G_ZFEhksO)kG8(Ecu1l!L<N7HfK9Zf;@`BPhW!L8>X9^2DOt(gJX<E-vB+g)bXK
z2$E=-!OFlAMH4{v7!Ojcfrhle^0!!1Qj-%aqqxBo)G!H9OoB`-0u6tGqqE2hBnCDI
zT6|6g37{2iQ$TZIpmZe%8a88OV-#X!`_ID3^Aj{D$o8LwjqR@zBO4>zKNe=xh=R}k
zqm+H1Tm&krK&>CNk`=TCH94oa2s~;EZfK%81vE@5#>Bu-1TF_*6L{d&47b?QGfOf`
zlfarm+f_i*>bIDSi;{~Lf|3cS9RVvHK}iI}2RWe_)Fv)rNa4w3C}C`705!2{*+ARI
zAWg4g=@Qlwwk-A<W=Vzx95swJpvYxPVFV?J63#5H8b(mL*~?VR4jQjZVJT%O(ko%h
z;;CUzVU=W%WXNNzVW?%OVNYR`WLUsk!?uvI7L>5qLH5<Kfo<cc;aI>28qJdgFC?$w
zSioPyp28u?04ix2L3+6)8EQFeKwD-wYB-yjYq@GziV|wr7jUF-gSNcnF{ZH8aK#JM
zaAgTD5USw<jVv-U)NlneX!0i7vmlM5fmVhUD<mqw2e3*qAnOg&K)Z2^!ShiCMXBJ5
zF*QX2yxR$+7`hlxj|)DGkGb#`wCqFy$LJJja0|50HZL7Am<Af{DbC0*DoHLaQ2>=6
zpy{tfP@fRh>Xg*9OwgLk%shpJ1W4!7*Wbm}Cm{ju5YXTb1efH4mrW{w$J)TXNzm{U
zY<sbe0%Sd3LV|iyW?~x1T-}t^0^QU+b@b6LkZ~XvgBPJFfc;gH4+=H3kU<!!r*8vN
zW~UDhF?92aQbB1E=kQWEVl`w+W^r<2Q3|+=3Z9GrbzdP~0ZkRA<rgKVf`%xIQj0Sb
zU_K)}@Kjusj4NhP7G)Ntf`;E<=7L=T_7Lh=87O!X64W8tO+6vON&&)DC`!!%tz}dw
zNKD5%cBh_^Qvz0>kyE0Ok)N9iQm6x2+M1XQTAiE;T7L?TKT9hE1CV13EkF#7&=6;B
z3r$RSAPwsw9E7S2v1SBk44|wN1;te{c!&Z?CwO^IF~~thsl_Gvpn!s{5eG#PczItj
zjv+vJQgy8WFA71M`?9mMgCtpS`UWk*&Mzu~uDFA11%)|CAvELKLgn>9j@7_O(3(W*
z)6*{~Nz#L52fdWk0zFU@OD{Piu}B?Zh$dr^2&h#6+RUuUc#9`Du^=9lH$Y?Penp_A
zmf%Y078j!ExCLsxlt30Vg+RtVR=}zjO_3td{=p*fL|P|E6ja{dVgo1m;vzv%JA)M*
z7`Ir#xgAnhfmSFL9RMj`08+sg;20F_8dL<DlY_3ILReq49Hb6xBWNn^7E?(+cuA8c
zcaadtCm;(Uei8+7K@|j~3k;gyx&>OEQ<4g4|A3k(;NER<Y7wLz1Fn+PLFR)TBL%7$
zK^;2*MIJ^eMm|OvCO$?15C$(y5o6?IWMPEw`2<B5N@WP{1;Mtkr+|h67_t~@nMxRI
zn81SoJfNmU7E>(~sFrDAs9{>bypUl53#46L%Ur{}fHj3Bg<&C6EemMXNDULHrm6w4
zIZ{~Xu-3AI>nPS5#uDxnwq9n);DIK)A9&R*M&lM#CkBHSlS(l#Fl2%jlX5~Ew~RGR
z3m6tMOlCq_P+9~^4=W)p(xQ`~067IBz~KWXK!J3N%LX(f0$x%Yzy$3dNikH(LtAv9
zWnD<kQMlS)f{57EgEZbXSrKWiNCFgZ;vfPPLn|3?@j|9G<8vV!e|aF$2OjwV?d64N
zSOs$6N)Q1`L*P^kNu1!sH4&7qSW+@`ax~c>!vo-S0!l#;?O^-lL6(C32PQzCECT8D
z0i^^`BMY?ApMz115xgJ?I=#vEM}!rg3P65FNd=%z1qg$CYao|_x(&#w0K^BSf_Bix
zAJFL$94RcI4PoFE0P1A0EMNuq=GdS#JBTjfXl6)ZodceMOko3^IZ?v|5?=uAm({Y=
zuq@z8VF#xlQ2&g(hAE4uhNXtJ24p603dbC_S~k!I+ZwhS#u5Qga~7I{xUi%kP~#hv
zp26KCP(XlF5JxRz4PyyI2SW{GGZRw!(PRW~&DLZB_h=yL2i!$KgsKW714Aq*R6!<7
zFjQ$Fr5U89fY_3cCM$TQUD0AtT!R<%Ed{YaLxY+uMY$k$9*D>X5e1<3A*e|TYafD|
zsIa_HqzI31B@jy)M1b80Ccx1Ta%d8$S*i+_1hwbcu%=aTi3CcpMd~0$g6N49RG5KV
z@R0NdZjFP+?TSDnFGYk?Z;>X*Sa$Tp3$_-KV-P7A9N=ItfW`<SL17K@6(j`<F@kzx
z9H23pzhW$i)C^ik$o5-=4L%qKO3z5~p~+F?2ntrvvil-u5DOHxMJ@~s3~p{Anlj*3
z%|)PbPsqwkFbll=63hZGQ3ZEQ!0`rVfwn9_IxFDuOt2Vup#qo%T5}DN1+6?S0uAv(
z7B7I796;7;f?444YcMMm<f<@G|A`Ia){7tkkTXFp<SPO%hXA_<VKX-Sz>7h_CV~gZ
z!7R8fnjC(9Zs^8`XbK^j4jy#B2eKPH@(yN!hu^^_;kO%`jZEO7=c11wpD`AF22mW4
z;f1dtOTYu2;NSs|c7j>ppa5%NLsAJIOGL<ngNg+*pa;t0MPOYZmL>~i$PF}J2N4CE
zg&_)By@IJ0q)U?tq7T$5gRwy!drjt$B4I`b1~*MEaG$OS96I2J2sm`WH8)rcTz!MZ
zz|I04NTA7rqz5bt_JTa<WEN0=BR>8XS3I<?h>yR;6CYn#nwSHTDFT(iMbe<Gtiiy*
zaEqg$D8C@JsH76ygaEI9E&`PhkcHFW#XX=!xJ96qE=8b;h9c0&Ie3`42sHi*Ud>zt
z8iXtYRWsmIK0sr*MW8XmBGAxY5okoD2-MHM#SNZH%S|oG$WMW+3Ieq<z!gjpD32nw
zK|nbbe5gwi$j6`+!NnjGIT%=&SQt5&m{_?OnV6xNor{r46136=fq6bL)HC@Y@qaLR
zB6uJc&o{1oCT^ZTT%24ST&!%&Jd7aB#mptd#0xT)i3OyJ?>CnrA1~Mqns%U2O)D)a
zElQ1#F9H?YMc|`1K&`x6Y{eO%0eJ8^9Je@1QgaK^GILUkZi7-LI6Oh4x<#OJ_ZC}8
zWkF_MdJ!mv6@hBTBG4QJxO9Vrp&(=?0cle}Q9Q^T(6Xvq91zL8Jn+zY6d!~OIyFZx
zF}DD`5h02jA_yK5D*_L9fzn@;1d^~`PEkC32%`u*xB^O-MWEG8x46L#RLE2(q&W*(
z$8}2(NmviusV)M|?%m=;5zhlRav_B}ctyW3vNUKH2*~pyAP<2Tnt^8ZZV4f)fh=AF
z4_il}*a`6vsP+X9^V||a)&-iR0iAAD1Zv+E%>bDX-lqU+zk;_vfRpMiQDi;v0YC7N
ze32F?TYwh6-C~2x>w+U5TdKUpVFPK4*@4Q{Vk^+#5ff<I4RTTqXxTPsi8)9FH1@~C
aC;(bi&LqId171Q7;`1;{fa)M75oQ3-{<lK_

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/__pycache__/parser.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7dcf19a63a0a627a255230554792697d13dc2fb5
GIT binary patch
literal 38217
zcmZ3^%ge>Uz`&q*Up3=NIs?OF5C?`?Aq>XP6Brp7rZc24q%h_%<T6GvGJ@DlIZRPZ
zDGVu0Im}VaV45Y01x&L>v4Ux~C^j(79>t!*kiwk9l*<vt0oKcs!<ow&#hJ?$#RcZG
z=5XioMDgVEM)BtIMe%{fm~!}|_`&)Gq6EOSV6IS<FjP(?S2Ri#%x23G%N36j2ea98
zByuIABy**rq`-WR9O+z{D4AT@C|NL{DMv0!E`=e5Ge<sGAxa@vF-j3E&XuE-s~n{a
zW^?DL<f=xg=Bh=h<*G-igT;7qG;%egG;_70v~snhw83J$IXbzzQMzC@Uyfd`ew2Q$
zL6iZQ&!1zMYZPS+W((vP=9)yA<eEmA=9)#B<(fyCgT)1NEOITQEEyS?7*aJ;t(Gw|
zFsx>Tgg663lr<BBJ41?43qy)<s?9QH28Pwla5>u)reFq5k(VF=O~zZ?iFtYXC5a`O
z`FX{DnvA#jlJoOQQY%Vw6Y~<&Q;Rg2ZgHd}mZX+s=BD1_1d%DJIVFjj%(s{w^D1v~
zc$TCVB_`#h-eL{S%goQyWW2@YUX+*;oSc{g*39CVl9+po)4!l3GdHseEX3<tQIMaP
znpcvUnBx<4iznVEC^$JIHKi1ygUvZVFD*0u7Q0JgNn&woi6-MMR=3R5oD@ywTO29*
z<#{>zi7B^u(^E_0i}KRri%SwqQg87VBXc#GZ*hU-bMn*EQ;TkKXXa&=#6vke1x5Mk
zMXANb@kxnAnvA#Dd{aw`GLto#ZV7wlm8BLHrv?|6CKjaz<>#091l{8B$;?YlEb<A`
zWV|Krl383*l$lgol9~c?TtH$`VopwKjwZ`3w)Di3jMSoA?3u;!DVfD3w>UG4<8u>>
zOHzw&u@$AJlqRQw{Na>XlAMtY3V9f2fiM_9F9GM0RE8+V6ox3K6vim#6vil)6s8u2
zDArWA6y_F&Wef}qt0Br67#O11Q`u5jFhn_0Ia63MM7dHqQ`j&>xj7k7VTyN(Pl{p-
zYZMQ%c#3a|Uy4c#YZNcCD2ScnpAwLw*}@vdmlBww)4~$P&&iMyloFg`)WRAikP?z&
z(!vrYm=c;|-og?kloFO=)xr`b%*2o?k|hfB2&%7A!c%NoSWv~H#PI5fNU_DxA)XSM
zV&B3NC6N-9;@H9xC7CLf;)LOU=~O9@FE|-eqElj0JX%=M?3GE0P4R4DiIPo;P4Q}B
ziIPiU3}(=byTuleSX7)^<d+PMJg`@o7#J9s85kHp8!&*1yBfwChIp_9h^S$zVTgxk
z&l=_$hIo*AkQ74-LomZiMn6sFTP%r1>BYBLbMsSDb8c~#6eZ>rr{x#rYO>s7DNfBv
zD^g`(U?@@p5$X&K48<VZ6%-T{emU!B<maa9gEDbqUZP%7PGU-CYLR|&er`d&E+{YS
zrj{k<=$9nsWhTZKCl_TFloab1mlh-z=@)=~qE}FPiz7ZBoK51Z_#xiYg9&JXER$wn
zU}#{tAtKSi(!+T}RH}oehwFx<QU^;9Uk6_Y-)E3llHopNU|<0G4;&tD;P5B`DS+ZE
zxVi-(RZvj`g&GY-Oeu_cjNn3x+3yxha%oE9E#~BcQcdPttR?wH$r(ku3=9mncruIQ
z6U!1ab3mohO2#4$kgGu!DHLgf<k?bE%QBNwt9YTlgK+ghs^r0bdnze6N9wwy!6iw9
zi;_lHB#kcc+jf+7l<i=>z+qdY&A`Bb-G32a|J5*L!97sJfbd}!+=o?c3=AoZ*<gNw
z5Sn^;@r<l0m_d`tuLz_;6O;r>QVYOI;1*A50jNlhFD^+fD89v+7oP+wR#J<L3_-p@
z@-t^~WnOZ8dQoCZl>pS+a1mpWT2RO}Fg)NF?x~z%GRN|YwBbd5!wrF#_{}cxNA6JB
zqj@0ZNZv)OkP8u!m#iW$a71E;0~-SagEA=HzhGcs@Md6Sn9fiFaso6oN<hwsu|X*o
z%FcrOIE67AELOyn!j#9D!n}-$fnhaVS1n@+Cs-Oxprs7q8ip)rGlPMln5Tvz3*;KG
z$}Dy;#lXN&%gDq~!-%TWlmS$UhA~WsG)5Rw7*K5m$p$khGZ-=yvy?McFh??!Gcqzn
zGBASm1v6-}`2Auw)-%7wQCwP30IE%Hap#rh<Us3AO^#da>8T}&B_&0-xS(P=nMt>p
ziz|z7v4bj^%>29}Sx`<k2N9q=eTzLWKOPi2noQuddy5^au^1E<3eZ%{0#Z@MjTD(6
z1B&-DFfhDec)`%X@Ki{0uGUuPE#3!IFPXSsFmYdywIJ(6>_wsID?-s7?030^IxTxF
zKQJ(IYR(9m69;D85R;mcbwy00!~F)YNJn^QWKSeWTnJ3u;1TR_1;G!@jGPc5u=qy?
zMoytGAOg(APyG1t1HXb|AqED9gQBdC>dXh#Ssb<559%>GYO|x{I8fYzQ`!widZ)Bv
zP3os1<g|-Ow?!7n;tSxZ7?zqrG<DN5Cj+vLwM->~AUhx!Stf-AHIEbtBFkpMb7>7j
zJUmaPFhKGcxc);D1?4SNv2q4TF4JW7E3yRT2`dm`4KBHJ^FeJxO|BvvkeDrqumchH
zAOf6=z!`|6q$n{nFEcOw7E4xsX5KCKjKpG47A$gMU|`T>2Is0GN05nJpe9;8xSlNr
zl|u^9>{SG+tKhi{WC+NL;!Z|la~Ho@XJt?22L?V)jT?dz6T~M<PLce;z{o2GCT<9b
zPGAMW56mzju=q!iiZ37n%*9VYvJ%upY)T*S3id=@;Z^v+zzuSR=oG2x@{{B*3MyR@
zR6?kyk6S*lvGZ!&kX4)$HG%7?u+$8bIaUiQE(#l55jOb1z$j>ZLs4~!)D=ae2`*E-
z;4XR~t3H8c3fBa#30yyBM1hzW1k~ZE7}UNx$i(U>!hBGK#ZiL&pfsbS1p6U2RwoJO
zLlP`bGVF)s89}6)p|b+RVFgZSP3D&!!VC;ALDkYr1yG^^6{*i5NnFIiE#wv}IO+Tn
z0rz2|i%W`h6kr{j*jvmgsb#lVN>YnUZn32n<R@no-(t?pE4jr{kXVwLnwOk<iwj%<
z#}|V-IHsTk#-3D~oSj-ye2cw2zbHGksQ4C3a!zK!E!MQ0{KS%5%!#=Lw^)+$^K)*o
zCMPCmq=GAjr2OJkP-mf}v?%Wui(h_TYBC?hjbM_Sfq{V=T+vD~FtjtYD@<qTL~3*_
z0QnBA5Sb`}XF3M7{sU@{v6jCCsi-O8K$ua(kEmkTFrpR#j35_)ie<2JVhSrph8ngS
z_9`X@hFZ27{sl<(fQ<kXDNHqNsP@zfln8^RzyxaXSEN(JRs!!$Ffe3+!U>BysGR~t
zs}(>Fg#|odBhiQyX4Ft*WT@fK;)N+HaxamAu^AY$_+jh?0x%XbjYBO`VT@2+!;dfx
z)dlE<bPazzsAdIg#TnkLxI-5;9%}gG;qg!cYE^^HWk5*<HT;OCR~l0$Lk<5D#y-Xc
zNHGM}#J~Vb3mhqIxNWcD&w|@m!?}ii85;w`YIu69WyIqKF_<j`-5^lIk-~x74JjO0
zY-S=NZE&V=&1OmAu3?<bFc(`o5r?_3ScwSJc%Y^+&1Oj9oy&q6>x>L}b$G%8ZWB$y
zf|)eeV}=D0`uU)~XU6XP8pbRMSZE@%vm{}nwL-OmC7_}iDo`Vc8iF+}Rjdr4+zaaG
zg4KY^iyHoTcn+@NUjS-qfaQ=0<h(eWA%%Y~6ROFeGID_&vJMy<wH)hYhzIpU!IGT}
z3lzW%Gy+41B1}PvD~tv9g))q{MgY|{oec3RFgcWx5Hz*`mO!<msHwykEDR<(8L~hl
z4`6l;e-@~V4Q8h^;w)PPQ_#wCoGOJ<I8aNQHNwkS7#LQ=JB^(T@yNEr{a9p>B9bDS
zqnWE!D+~&4gc}!tdhK8rA`>Md2ws*BjGYDQ3xhc|!l>>5m+E?8DNx%Xrvx#sgI1>&
z#ifX(h~?<jiqwcK0JT$Kn&5N|e-@~d4(8(w3Gq&bEF-WI1_rc_DNa2S$mtN({m89^
zEKs)}Z1fsQ)X-&QNRa};8rC$H7#2{O9&Z9x$N*-;^G+v2ycv=>sQU@#;x0jpG)oG>
zO29-(F_;1q_;Ms_x<%#X@!`|i$q*0fJV0zH2UB1IHD#Anf(5|@s!TFdCqq1_mjRaR
zWQYfKHo)u}enj|9U@S7`1l4@-T)P0&Spcg;COR3i9ANwfpxy_J1E*7@QGJKX1E*+s
zJ}27_8B|kId0;!><pSAu$fBBx%41|GX@z?k6mEn<MGjRzDi7>pgbB_FlMyV`Sao5D
z6^jA2J4I{7N;(m$IvHw2Ys66JNEjJ<#A}2WAeE`e>a*Z^0o_e`TFMM1JqWcb3`Mex
z3@G)RJ3<!0N|8r5DUu<N1=b}lnTSx?$$+rEhCj;_CX*sng;7?xFic>L)vgsUnF>?I
zz>wt)W21&ntwhO8m<$60dhJ+(GZ)oL)k>oH4|_XVp+<Z*Ly97@i)S;WD9vR>_cwA4
zLtKBNlL32s8r6T`0Y9lu21J=wBk960fid=Et#l{D0;D<)5ek?ll*~oQX8FU|oeWt4
zFm?@p7Q9|sBY;{CgWS-`upkho7MZR=D+6j}Qp7+I)dWU{JZ|iRlAR0-f{@LFv1`!s
zJtG6i)D$t|&CLpinN>8mlVL#!jE794#9An_42+E$mNooYVQ?9g;a+gQMwCSG8VIHu
zM0YY|!OL7M=?9@3YmXS!C1Cpyr7KqZu;_r>zaSjsB6OU>hVHH!$pxT!0(6B8DaxG;
zSqS?hF%*DuHOjnSiU_<>%aEcnn<YiHMkYmVHVbB-poTvS(Q0wV(`qrT5m^w0&1Op6
zRwI+5J_k!%xPmbY9?B_FRlE!g$xMh`If1d~G~x23MlvfJ=HA&1=wVHA3Wv8U7sS9!
zMW!+1pV$(ID&<8ivRh#663~c0l+(eG#+ahf!huqPGa-6JsNv&+)@H?BwxgC2sHW6P
z5ssx4o)k@R4_FFE4;Ya;weh4*SzM{JMk)*560Z?Y(ZWn^HT+rdzHiZdj4;zi3o~YF
zhgq#G5uwBf38hYk1z2Oc2CY>^qp*}k2}>Q!up}*4k*1oM7D|mo6&C|Ttz0KV1tX#j
z1TR70Z8EStyjPMURV5BCVc;TQc|?m|4q5^sM5H<yvf!=%Y;f<hD5gfdhP6g2nHg8_
z2f4?9CoM~LGAu}dW?K{rrT2!imItl<h_!uHBR88NMHh4AA&-dk2iB{Hskf6M3m#@E
zQm`pnMut4539LQ3czS!nDB}u=FmIxlqD-JZKoU$g#R4``*rk9s{1ga}!l0H^#Drgp
zLMKBOyjMG$Aw{38Q7UM8hn#+J<W@wfw5d}8X}p5C`bUB2`Ukm|P)K7;F&I=Oo&xzL
z9*N}((mVt9k^D}EEO-epn<2#znO`Gb#m&Gln<2%BKpRU5Ps#<22qnW(J2H))FFF|(
zq#(<~*vNHR4ci)H)Y=);j$M!nQ;STa>Z<{bW}Bdo{FIzU=s+1QN{5NhW=Jue%ame<
zYO5(jt$dCAf()1{WIDwhJs)C^vlKDVWH8o+7Gl8+nwE(ytPBiXpmk0l>{yguYz60m
zM8Gq5`YEYp`k)y)1r2Odc$%nMK-%0gb5ipXb5n~I^3xPbGEx=L%t?VPJ}lNlu?#Z(
zr=XFUSAxaNkc?D?ywcpH)FQB<(Aj8(OwbZZ@cK$r!(h{g#2J^IpI4lkTw0P@mWpJe
zLSkA;YLP;DMrLvb!W)@+=?Vo!`N^rp#R}#5r8y}INvR5{iA6b;3dJS)1qG=o3YlpN
zdHD*Nxdlb}WvRKTc_pZBLriEA=em;o?9{wsh0HvK)WqZr1+aEK1((#c#L}D+D+N;n
z0|QhGke4vwvI4Y_G&41?L?JObxiq&l2fRpC0lex7$!tSZgP}98xXeV2BbefnjKmU!
z;?%qn&~$FGLSj*>LSk`oW_n&~ib6>~l4Zt5sJ20;cZsvDxHJhGE2+f_rNyZ!3TgR8
z3ZRsx09w<UnU}7oV4#qjnwVFtke`=R369X*#LPTcWFk2PEjU55%L*Fc*<~yV(>W)z
zpjZL44h$Te`DqG?d5}bul#>cds|ATgiMgpIsYS&KpnxbyP0mcqOifWJOUx-vMY7dY
z56#}h+yVs+&_p&CTZ5s-6f2Zxq=Ht*DwO1dyseN}T9TieSdy8nkegYNnxarpl$xAb
zoSC18WK%+dTVhUeYC-~Pc!OulaoXsarjU>jQdF9nkf5UgR$2@WLvRqMWfm2e=qMDI
zrl+SCmp}tQqclBLAuTf}wOBzTRWDsnN5M|P&=-*uGzmMYEVT$Ub5ES3GV_v)QWJ|)
zA@0gAEh#81QGl3`SyG8&8N?q5@2_Mm0yPhA@q-p~LYDl2R~-Bj@X1e10cCkmF$VJL
zE#{=myjv`(WvO`~E7^)bLpI=5g0M9S#Tlh(X*sF4xIxQcpzE27K$Q+i6*NV=Rk49f
zM5|kjX15p>s#sD|%dBoOa#gW{idm~FR=vu^+#F5DTkNTMpcR)Xx5Uyi^HSnV^FRqZ
z9+9AK@qkunXM&d@7G!9$fLG((;({!{jL%FdF3JPVs^o(R(6S6o##=&Z1%_tvpyjKe
zm38qM`T5y?x7Z7c^0QKtOK!1%ifz!6>tygc@uDJ-PSB(RXzfICX>Mwf7ibBFNIq=I
zIb?}=d`f0=$t{s$*h+I`QNd#Ha&=@OPWamLDi^<eh2)IX<m`g{%)AnXwEWV%6g`EI
zqDqCLRNb7!(!AshSm=X;48#HF^OVw}RE5mE;*!+Flqxn?(9#iwDrN<Jg<p(TRV+D0
zRti<jdM2q=oC>-MIr+uK5Pq5_(=Dc)qFXE=A(RDhptT&rpcNpX>5Zw3(;3nkY8Yb0
zYZ*J479dx>aCQwNY8^b0sYfE1VI{*###@}=R0JwZS2EvX(lfZlm<e7WRSa1V)c{^J
z`-{saC$qQ&6cct;3eZJ|U_a{F<m4wO<`moMAyj}C)D(l}5q~r=T+obzpaYC6RMzXQ
z(%T_;QOo*@mNi85f@U0eCFw0jQ%$BK&`4?#XjqgMzAdT)rH^_L(Fj`ditN9l76t|e
z!XA4A(g*XHTFeD7+7Y;*WO?19x($gJ)h({5TR=oFsKtOirpZ(U8WRTls!FI>AvGtl
z094>>6epIYrf70ialys7s@N33qO|qBCUa2}C=i-KnS&)MwYUT&s)-B=9!3TRcpNK5
zTmYjTf(uNR+by!&pm<T)<chKhMD&7E1UM*ual^f;qfo_OtPgHPX)@hn0hLwY(n*sU
zOcjBKj*CDe!&U71pi-l>_!eXNEsnIzyv*W^)D&=3YGxLJqT&`Cqy=${4U!OxKnp%V
z9MFyra6wrF8rCZUjqKlIPERcXFSotL0xI%u@qspnl;;=aq<~A%TP&G*Y57H<A;nuv
z`Ng+b3KB~)z-s|-v8QAffy$dAP}?0`Mizlq@7!WdD$UGEfuvkeM1yQjOi3-e#S3ow
z#1|*#7UZNB-D1v3%_{<pP26Gy<+b8lETE{q#Rpz$4=<r^aUz%yDR?n;ixbW)0`0Xb
z0u2%0VuKV|xA-!P!K?N&6LT`FQd4d*ySM~^cL?0#0tZWcQDR>9Elcn+c|DNVp{2cE
zVorK~QD#X-Zn0iUN&%>>%>|dU#d;}_HXDRj1e&<LB~+A}o(bB@f>3vhHN7amwBQzN
zxPOq3%PrRO#JrTGBG57iP+(@3+!81#%FN9KwN~RH<@7BUKSy8JTU>~ev<Nf~e2W#F
z9B#3JQe=E;5oosI7ISW9UJ+>JMG>e|UIbd(Q3P7{bBi0SDi^$C=N3COQ{CbRwVsd*
zZ&8FL$imD8`2|Iw$^TodnI);Y#kbgtp^LORLEDEQ4&iewf$s5fEh@?{y2W0eSOi{F
z%373|m!1mF(M6z=_!e_set8k7Ctu_Q%2=SS1h+UqZJXr8;*uiJ1pX~9aA65vsDFzi
zDKR;_Jh3RH2sEy8iyzcv1Fy}G&&w~$jlac(s56T|vkJF3t5S>d!76U?gWOk;UtE%w
zSrK1cQgn+Ol!9{-i%a5jK#43r{T4e^8dUEm<`jWuC~h$qm*(DL12^J|Z}EdtUOXaX
zZm}mN78PZtf@_+@lv`|&Y<7zSR5O%<HdV0~6s3Y|O_uzE)Vy14Y56&zB+go1lv$Fh
zsR*twz!?mY4<Nw<ibP0`1|@w&wg&qPoPxob4V+DHv4H|5y%?OUi$KFgMKeG}6gxBv
zfs<g-N{|p^_ASP;qIDo9YjH_pQOPalq{O0IY|!+;3eI{(H6VFzP%9-KD#2KCiv`ri
zE9w9h<e=G>1W*?c4|V`oe_+2=@gUcGph>pkB0dI&A3quxK7=tc2#EAlUgwv;#4o>;
zZ6U`Jj*I-7SNJtMSnhHNPjy@1vc%^Chv7vI!z&zy7dQ+baPai-UFVRw#36H$L+%QP
z+yxG~8=~?HY%YrGcW~X1lAEtFOXGsF$%d?pQjS-o96R{o>-Cv9-5GC4DlaX$qHc9j
z-R6qA%|%I@4zC+>x?4rA7`j|Ebh~2cc2Ul)!~ZS^Uq5#j_XQEPiyZ1#IMgq2sNdk`
z@38_cz;|c7D=s;ue0t5Knx#%l+?V?=^55XH#q*+y-4zwP1FRRt-L8ncb-46++z^qN
z?lH+@M%dEug^^1lFN)}25zz;2{dp=NK7(Zr-wKvBTo(kaF9=v~NP*DT1spF4IG%{Q
z;S+qr%kQpV=*i48nK#_Mk5u093I4#%An3&Sk%3h(l<^Cg>|p)M!@w^#A!SP5f|Mm0
z7x>IC@R@H=fza3aY%lTIo{+!c;eW%;`>t2uNzF5wH=I3gc=&(dX5hE`$iT`U2r`I2
zkg<dLD-Q!FKgi1yDlUj<L(l?O2z`-5=L(0;1rD7Xpgk@h7`QkM@A3%sdv|%yFuNe3
z3qcE#A@l_a-HSYWS9tU;fDvTDvfT=kHI^5IZ7&Gh?qGq?*M*%g2|J&tzu^~p!zb`=
zK={Rg$SVPnH$44r_=SGpW)N`!c~vAF<U)~f#txUSJPf?TFiW*BNPrN?QV@NSN9PKU
z&IKMFn7hm`Na#b*f)WUQK|=o`kHHllg9|(cH>Bj}=&WE}!*fN$X##r(+g(wK8DbNo
zr$jF>yC|x;BIJs$-9=G5@a`-Qo_@|Q&Iut?A}<K3LeNDHwJRKI7dX@&NXlN9)VU<7
zb5T<7iliQB8`lj?p}S%VD@4{vTo5z5C}wm;%&3E<hx;iv{}pbzi`)uVxD`Gyuyckm
z-j$SD;IhQ)hNkWs`3oABH%u(Hdu;N!U>kZNJo=(Z%oUTE8(MnnHCAbCusdLSQOom+
zmgfg{W+`vRj|?F43z+P1>GAr&0m@Dl9~hW;Ll|!eWL!W+Hv~kca9tPBy(FN!Hf2rL
z6+OEP4nY?Mg0Bb!Ul0g}rg1h-lewBRwdZJmU|{1kxxpjR;RAvXcm(^sy1ZtjT#+-r
zA+J2YVphcp&J8A8EHBF2UXi!GA)_$gW0uE)uoWR|A}`9AUy(7tA*VDa^NO6&2X+Qt
z@sAA5ye3~j#0N0J!C-5*qws*@frtw>z85(xK{;cB$rP&@C3C7*xUBJgYHG7Fa!cd|
zN&mURbHkQ8uV7o~y~O*XticsogNu@eS0oKDNE#k>KEZa-`-nFv@b7BsuasCLvDI>;
z^%m<39BLgbS2!eQsLas;dCUGI0~cpH;|C^A-gHJ#DDYhu(7Pm{x1!{VzUOs)-%I+w
z7yME#>Ze}OPrWFRc10lVf<PK6>bS29XkQZ0Ug2^@$L+d~*CidV3*K=Tb>gq+#9tIh
zxFV2nK_KC-fGjBVEUwGhT#~cd5q(k4^NO73MFFoX0$vvcyl%)ST#+%mE@N{^#^$1o
z-4z)-&;oxAFfq|(g5!k3yCTvvTox!U2)rnwenmw60vO#85Wg;<cu7EUfyxrCivqe=
z1avQe(T}^rilE&J>5RzaT>-J_e3SSt$RqrD0qk4Qj*4`~A3uJ4Wn&PN2JbT{SyH_r
zaAEyLQS&RJ<{ubLIK@7Khz{4gA~I8aCi+eB>u|j*rM95#qLkhhDZQ<18#%UcOc3jE
zehMidE=X7|5WOH_c|pQ*g~=Lg2<w7`<wYK=D?C;gc&u*l2=sVe=aIR@BXf~Q?h23G
z1s=H@f}+zUCrM6}o+AB$L4;QiOgxa0oxn1M^M<U#2L=H_<&Pj@g6j=Q+4+*QBxg#`
zk^aEIEUE)0?#e37iCf{a#`}QC5s3@3UKeG(uE=_QU|^KA0uwis)tB2Zvfp5OQQ7i}
zvgHhy56mzru>41m$}b=S%*9DSc9B30MW}ipAv2$M7Vm<TixS#bz{S)Dc9_$^?)wOG
z=@$?I=Hev4=A-C@DCJ;~keO2Vfq_-j{Dy?gbqSqI5;`kF)<j*`b-JYMbWzvkimuCn
zlp~oJB?7KU1YD2^xFI1khx@vO#w7`j6(VcoE=pKjk+8TRVF4A_x+I}>Q9|d6gw6#C
z9grB`bqVcD651CfbgzJmcc_@bB?*HKA{Qmhu1J_&kT827B7R*&{gR0K1&#C-C2Q)g
z>w8|(_q?d@eMR5<gyR)`zY7}aP!yX8WoV>d6v?<El5s&K<AJ#Jl&TL5jG~c@OEVW{
zFUf|mZ%D|_=bXg}a_4nT=S!N-7d2h4Xu2LqyrSuGAt>yEQuqa>@QV@=S0o}XNJQKa
zk(l5)#dCq+L_ZKc(G!%oxhHYYD4tV&K}H9j89r#j(h)c@eFP<|FCYTU#Yuo;07WN6
zsTKpTV2@Y7f0zG79@#5AvKM${Q4%dDZy@6b1`s(nbxz)jkTuZ<RE}s|kn_GM=Y2)a
z8zKcEK`B^zmh{qKc&Gk?X57)33qhe*f?_VZ#$Iuay`UL)Q8Vs}X57_;w2KKDR}wNV
zs%BnM&Acd?bwx630vpWFWfx?OAZUdeguW<Xd_}<cf`IW2Veu)T#4qU1xKwkY_7ZJS
znc~iPLqu}A=OoVsX-jf<lwOc?y&&g$QN-<vh}#7bH;@*~4-71VfsA*RRN+1I3u-Y(
zbxxF=slMnGeZ?vIf?CW)wU{evF<0YKF2<!@iA%evlzv4ieS-I05vl3kle`z0Ur_Lb
zpcN(St5;R;u)e78ensCMB6d;4>xzii1re_su;dVklpF#XVadVzini?u(F;oc7nJ<r
z>H32(D2O592q8a$1N{q_goxlL!4ZsZ2reyDH2kX=gP`OTo{4-@_!fv>6j1AMyul;T
z;nm|cL$T8zM1#1#J-#ynFY?HB`1bgM_&z;8GaN7S$aeVj_&nejoxyTNLgNy@#sz+j
z8}=>-GA;y!T@bLDz%qq<M#!94P(5UGS6F7E^%QGRWSiU&k+?3RaY+PJ1V~;KF}@;V
zd_lw*mUap+$e2RVMFF!b0%jM$=&69%bWm<8yda|sK^Fz|t_bK|5YPj)1#4#%UgB4{
zz^?$_cJ`5(K|t{-VsEVUT^@lRpH9CXzYf0#{1P1{J(U;0s%Mx$=nj^r+#;RUJs|gS
zD&F7`==bdMoRBgl^CFMJ6&{5PJPJ=?&2WPmA#<WHh!{W+ye|N4rcWrlAYuYR3skNs
z89|sAIZUr`m|oy81y%o`lniS9gQ^?c`Id>-oe|V>a%a3NrwAW`xu6uWH|K=O8S9I7
z;aBX!FDOM^REoHw6mc~w;bK(Mm8hhPa>-ZZk|%J(0<-*rj4K4KFj;TC%6dcfMQ!IR
z+RhNMivn&}1l%qNxP4$n*axxoBLhg}3z&q6;3vV!7o-JK*;h7LgT7=+%>@zP3nIQ7
zShn!&D7|Rl0^wc|@x935cZI|60*4<ch(P57r!=hL$H*ytgGaF6rwbN?96bHJUA&+j
z?i-{!crS9;T;Z^}z+rQPgQuUTiwD#~USYMP{6au@2hT;0h$|cs7dRrG@(O|^u868$
z5YmI74a^sLO|I~ofO=BOJ6J%m?$zZrq3R-!(iI-13p`4oEz-(hSug?GBCQPCB8?;l
zmcT}U!-J6%x6<NM3=9mHSzOq|c^IzqsDv9cUpHb5H)g&ishA|iddo^NMw9clv{<w)
z_iaNS5Zjg|hLQgcBXf)<=N%SC5Svv3#Fphrl48B1$r7W>dq<ZU#5Q0Au?<~ilcZQ5
zNwFl!aXwOHOp@b#ETotz!}{3Rl`WH%{e>k@rVQ&#R+dao?w6d*AT|#ph|LRT%dliB
zaK2P#%v9j~Ampf5#KZiFhowk>{gW_bkpTNw7O_%w=CA53rP}OY^%zUF*<W&i22Hv^
z$0~qWurX`UHe&ED#|}2|F&fm{;mC<|ha)Gx9gfI{3J|v<8D-5Evfp5SWJtkS7g@uJ
z*g#$6j<Q1qzMpXc*0n!4)WUZm!Yu{ux8p?G9f`8aC<X1<g&NLy_}<eJ&{z`Gm}Mwy
zQH#WCm`Xt7DNxxg_-;j1b)daewM-?Taa*WL<WNmx%w(wH1nm;6WvpRb0N?QkRSKqR
zm};0)Sa7=}g{6jN4J+#YK(v)V*kghXygv^kK8T1zcGS5QMh4^^c(~5DspYC+$N~*j
zgMGCCG<pbTArq)!$H-8_fIa3>)qz%*m%#THF)-9HB6h!_x)gcu45}HmJhj|4+%62U
z`n9|@JT(jp;Je|F-B-hlY943>T`f-y_X5y}EwVx|yM_l<H6ufhK@9_rRa|IlYk5*Q
zKoE7+3GP+!#Kb@iR~2X-As^uwuHnI4TTFy5zS#^ZoF(uTgy5Kf=OEOusNo}KpI;R>
z0|R9LV+qne7xcM363yb7i?K!>W!;_<IPw@67)UB#kV<RBK8O@v@ZJ>E@`i5>KYFZ|
zz<0ASfR3bqIe-CS5_tC~Q;GnpPE&?j{u21U76yha&}k50-8DQl{A&bJRWmYxQWW}L
zL)>Yqh9{UoQz&sJGu~B5ps6gP*B*h^pnx@imVZD;+cQC{ADr?_G87UOKx5UQNhgKG
zycC5*1<({MXpshJCOI)LITgA-B_}7pJT(QeJ^(bF4ITjp&uJ02B8B8-JFo>aM6G~=
zDJFV#jRmT2${}Yb5a$&dF0L6}<N{ryl1j5hF7Q=$L8+kQFVNQbfiestpC}Zi7MJFf
zAT7-+0<Ebo0xc#6&(pdUrGna)IiSgXVOP-fS7HfhQ3h;%j9(FG|6dieo>5vAw?YVb
z>6(7AjzSfOLU3vx=xnqqetpQ?QL$b@W^#5;YKSJ|EsoTR%;J*x{Onsy<w=@Mx0v&j
zvWo74&X!S!OkVYZZ0!RPpc=lYAH)JJ*+I-i7fl9<fhL-Zrhr(Woq6Di=AvmJZZe1f
z?J_R{ZTTyj1mc3Gn~SD{SfEMAqCFrMsDLXv4q|~C5a9VT$Rue4NbE3(0M$4}CqPqS
zte|5_if{3j<d-Do#22R~=jWvq7tI1mapWdur>0~U6&GCu>A3(BV}p437E4NLZh@u%
zWRefmOovS9!Kdiartyj{gG>Om@QSX3ST{h#O%QPlL~H^Pps*?i`3F=~A!EpF+c{8t
z!498;Mt7<dXu&}`GwATS4-QnAZi9BaDVrUG&&n}!+G3fMyUQ;&p=3(k1%AB?{CX=y
zAan-{sJqG4#Wf@AhOEjBX@$G;YBMY6RNjz~y&<deft!I-_#*==r`i_~@c~32=C!<M
zh)nRF;C+!p;R=Vs1rEg6g62gItt%W_7dW);3P?c4WI9-HaPahS_49Y}U*wRy!XbHq
zL-Gc%V1Hy+WM_0wG{|I4Faa9-E?H82QOfv=l=0TEjS*WSCWv)7-;k66^~iO=#01tG
z0%9{%=IhPUTOoQ;O8<(K{zU=(32Zk6gs%%IUlLGW;C4|!`-*_}1u(iHDmguRQuG3`
zi=rA=L^V3xK5(;gLTm$D3G$#O$b(2?U<ot=+!sdC30Clxhe23+iq1s6DS8V`FA8aN
zutQ^WLK#xvz{JWwFffUN$3#Ry)1KhNhbGofsb5fjUESuAy3Iv(yDRE;7sc%^i1>eC
zMkswME;YksV&#;|1>)Bg%`PdLT~xHVqG)kZ+~R@=XxsyCCdB-Y3{0FJj9<Xy2QUd5
zzTocRp6WEkeY*c7{{=2fJg=yjTrl^zsN!)^#Pf=X=Y^1n3mlObIU=ucfDYBWi!{_=
zc0mY)cCcLJwY|b?3mPfVKOl0KN2tephT95}3p{%8DN4|2gFaXRm;jA7=z~TZki@_e
zXaqQL896aju`vjUb?|~0_Z$;<)bikEKEcc4A;^A0gwaEg{fvmXk2&)ha~2<K_A_>j
zKGy8FSU}4IZZU(FBe3Kof{xuPD9TSt2CY&7x4sw{7(jh4aBuz{GnISu+&Fvl+yr{_
zFt;Hc7FZ;k!c@b6IJYJq<ZiG!RB=QfJs$4M8l)44i0P*>GSqM*oe`vtq95Mp23rm#
zkbAx8Ck~<ZC%|Td3RtktBKHz_E1rQN3w{m|_8vA4wIX1n(1;ptglVWQz&L-1J05=W
zPYL{l4fM09io|MIOF-*qp!Oi`!$TQw0FNWEmcY-j0QVE%<0Ig41a9~^f)vy+6sm@`
zhAo8^w@Xr3YuMMYVT>byR_s8{$%6NC(fiKGDTug~Py#yN4r*=<V-{%n6qtt^rY;Pz
z0kym}3=2SYI#?c=K<|ymG1T&v5aHe$9&kUHpOXQ1XcP&f#0vaO8dRS%GV}!2a1^tq
zGt}@cVhmykW=LTVX3*qFlwhM#p9xg(WF~{QRG@YkKy3<Lqz;sxf@hjSYF<jQLV0FM
zhC+f~NkvJ54tPm8<ltL{^30qZh2qrIY|z?tP-_UZ7#+0c33ME`LQZC0szOpFgib5U
z&s8YM0WHS|ovDk|`~+DG!XT?LI%}vd1i4&6qqw99%X)dwG=*a5lKB*<BO&XrQd3|}
zUWj{>QXvaQL2d@MX+ix(l%?aKv*XZL&Vx#5TsHe8=B1Y=rl%?-=clB?7Q!baq~;|g
zXe#6vDS-5X<-xsD=tB8~1lPRuoXp}3kRnh|7UUFA$bg*%YE)-drK0*C6i5jP5Z8fr
zpn$udnN^T|9ht=ndHE#@MX80QnMLRwTaZrpZW5RgsD^_oAL9BakY)FfCHNp+iAk9`
znI)O2#VCP@b^pO=2RpSGw0ofxw3rzb>ELk;(E3YCcCU<fum`w<?WkatoRe5wY?V+4
zJ{MfCv?Md9SPyi_eQ|0@f<k^0XzPUn=tN@35vvM`IXNgrWhQ9rO)}^#OIv8h(NV|;
zZTczCEKXIx%(0LzJ7~klEmlw-EJo_N`)MlT?@-@jD=kiqFDryBbrvW{1f|LNqEygc
zDbV?^Ol5_)#PgGiQ;W({!HaK;5t5M3IJoot8r<JaEGS6LODO_PT|ic)QqnVr_s4H>
zf{J>u<wd7KV+6=OY0y#GMXx|zVvrNiJJ#Ug0r0p1TAv!!lLjrU1~1A@O^Gi9?anGL
z0`;x&bgR#Uy48HpMXVr4WhR#-fO^$u8Nt2k2vU31-26S3SGc7?ogK3qTH2tMdsleW
zZ<v^ZSUtX1cwp;Xr7v+vU*wRz!XbNsLl!hmYYFO#7=hMJ`CaExyu_opRCNXWLcJw=
z7kLb?@EBg;G5o;Bz#~B7T2(sr#zo-E9<X(>zj82$DJ@W0qJ2?R?~1722L>5Vc`(u8
z`an^2x!fYT4XhUx&8{e#UEq<sz$^Qek3n31O3uW*DR~P@FN*1OxPRc|<Td*$#vmXL
zIYXF{SN^Vm2&7X#f$zr$E(QTnP?)Pd5LUe)qH;l46@++HKd>@!s(~fI+bzKBpMUW{
zmi&jL<`w4`C4;gVtj!1-MFMxp)<Dj!XGA`U9&v7cl?3SIbmZe>YZy|{j(;suX95k>
zgLc$_O<w>$ECI|!BG4x)5Z$vBrc8z!CQySNa^5=VjBVVqn#_Jh3qg6N4wRkPASDEN
zeL3h%EwI!rR>;1H{U8<41D`?5!NG%5#UOXWPkII^f!}lhTbX|mlr0Ltw*lPX-~p}K
zyCR@=5wsffF1OGGlNk~hxs|SPD}7*K=2W@CqtoHi<9(e+_7acmjFgK!%2z;0=K_z}
z1s<~%We^%pKH!n;aOv^Az@vPDM|p-Dgocygn0pC|rdw>_Z2-l;v>_XrVaE_hBS&bg
zjsgnz7DsMk1$Z05El%)ef|AODRFvB(K(P+KjRCX=XgVm?;4y^#;NTht#LWe$-4RBH
z63|`@sQxT?oG$>`0To41HH@ICTh!y#f*FcHhcs!jK_ZQ#G!GnY@kR4M1u|1!-Yr&e
z{Zn)R6pt*BA;_PgsQ(Qj{(x5TgRBKL3L!&>Aca+8&@v8fV+H86_+rpLk_LtkJPe$?
zJ=~BL_@LwO;mgDC@(cD<T<2H6#IL@BZ3D*+&5QglSNL5naJYb@<`x&&P;h~p3`$2Z
z4}zQl4p-2~E4{-Nbz%!OREz$Bf(jI%MgKu821W*kTLNHTfc61H>W+BWsp#OqWdx;u
zkmul;gqe|np-LPhSi!*%{}7}cw1uaE;R6?ea0RXPS|PSU>LS0*6@Hrw95&!kEqVlU
z8R*<;loAT$1aO#w&i6yTO#-#!S<F<!7|c)tQV)#}^s)vPCQRVnU*JtK(CZbzb|YV{
z0G6zR-3|h|vIlfxcrmEg-N0}ccC<Sqr}zzFu@0}h{Gt<*JF9!DFK|dfd;_YUi$Hy3
z6yJajAp`pclxaZMU_spk-psZVa@Ru<NGpnC_JJyGL1@S$HW9r8g*hm|8W?VHaCb06
zEC%h5BHqp-Hjp8pvIchQJt*zMF9-n*yn~x99~l`KK11w!0Jn=0Ye09zz^wr_M8MX3
zWn^F|;s6n#!&-|#Yg|w^LUJ)c@6}ny1UmK{_0V%feU-vk#!xf|xxVUTK-@8cy=Fp9
zO(+Lnz{@gZ(FLF=gr+nEmBNI+c!mf)EGew0xi^i82wiL`?5Mhk(8H0!iK=G}*D_WH
zhShK%)-vX;OyNx7&SB5xsAU3OC|1J+K2nUQg##rFIT3zFuu#Jg{ctg4_aSO_WYOUo
zrl68Zlh+Tl%{8aEB=;6K{5q%9qFYS4rRitSfWRC3TTFSS>DujLH_v^4Z-0w9wV*iN
zs>k3_U!|+vEuQk!%=C<s_>|P-#7f9TK&(aJvbq{nQ?e$dmLwJz@q;pt03!o~CgUwu
z&~<C!C>aQpg~7YVK`kNpu5k<SS*VP)Of^iM%!sRt5E-h55&Pv#DQM^Ifv;!cMll0k
zAcM}-PGOqEG?A&tGMGV=`4)R>9%zWE2)spKlL_G$O%_Od4(u;3@aDc^(3ssV_MD>l
zqQsI^O&0L><y(w-w-^h+Edtp6SCFmhkp0V=&=M1Mdo8xj>dZ_G48@?`hM;|X42)`^
zMehjmrk36c#T9`cm>G<WLDwMd(K%6gzUEZTg_zWf{%KeI(=K?`o=`lYcp<0YN>1sO
zoZ5?4br;m?FR0ajz%UD3Mr(3G{3im6E6|8Fxa(SU5L5wz{9H5v6rnswiKMtl2wY`@
zhTKw+&QpL@+2E=jqy*fqO@Ni<pc6`~M6m|LPf)oZ$;iO)qk#e38@s|Sb3wuU0yhZV
zl>l$zx~^h*NyYM_iuDy0>l+FxOE{PC+)&Y2;<?;+k?#hT9n2S1Y_6!->`2*@xj%PT
z?g^I*LE#teBCgm)Tu_b#UFIRVTy~M{iqZ`!7Zt6qC|cjp(p#gsUU!x54!#qN7qz^u
zXnB3$WRdh?{Kx<zzktaO&koNId<?wW7kIRg(G3aN8LXJ$2@$zrWVS`?x{>cCBj1Zg
z{#T6rKQM!$?;|+)zktaHimFQ_m&n{u)m##}Ja$p+29q7a7gcSqsM_u**;Bc{c316*
zkPE>P7wsdj*hgMaiMpYrwnTHe?jqd{tQ$%$D%o67vbmwHzs7RC?JC<Hawh~YYI|SN
z_Wr=lD(MT_-zVt{+TSPX%h=)hfrmjr@&bnhII2OrLs72^1FgjbHvx`-@A$*s;euTa
zR%D1=iPa!gVkr7R4Nq_>oC2D;0<%B_qL2lx8mr=9U|55;va^;kZyt(Cpau#^D?<tk
z<Z`ki#S)N<!D8SU7I=O}(FZD5z-rc@Rb{n|dAVqp2w^p00oDp71?4sm6dOVL25cj;
zC=OHD(N}nZ$|BT`3~IHAY$jrr>>5tgt_x^|YA}N)mtPS#C?|tX8qs8e^jlcd6LWJD
zi$EtNz=U|p6N_?73&8E1V$f0047b=ILXg6o8LSg5Q8XLW*Wp1bB|vcimcPXcF8^<F
zgDI$CphI9G8bR}1;NqhQv^g1K4zyVbIu!(^SveontVAgt;HL|4g9^k4kiIWBc!Wo0
z0ox^RwF}&8cO_Ieux#PGp<}SdbB+Iw!~-lxIIlQ_UbG9ns1pX-fEK|B+IJSg2-<iS
z!3fIFpi77%ukgw((7nW~e}Py3u7vi6lr4ETEN%BlUa<saR>?rHCeSusM#(_1rmt)a
zl8P%#*4W+9Gg_0mK6h2_4!^U`7Xm`A1Vmm5h`*4KawQ@2dP44{gxm{xWfv+cFD6u7
zNvOIQP<7F#`if8WMZKCUdNnuHwU<;bssF&rBx&)Hfl1Qh3yA3O{J@5kNio{7;2{w<
z@Q?`TLPl^072HGz-E^9qQ(OdIsskF31DCh(E)r;EP8Dp6IQUQq2`1zQ?Jc(S%#w`K
zB(Q$a2{oXx@>|TsMae~LL2KXP%`gTA29Wh&cWhz;&6XoyqnE;)iPF(QZFYf%P-@vq
z;AH{>QmKKx>5JY`DmE>F=Pm|@5>P7~oYNSPX2olmL5U6`jQ!@G8pay5A)*>4^gDxU
z8IjM9%mOv<!A90Ff*R6mSkUqtJM#Q^g9M7p;I6D;Phms24Z+G|tYN5Ss9{fGM~E!|
z<twm_$V3g=YS>yfCeR=Wyo>{de+?TroH=SZ7GRyHuVGK&K-hy?)-W>Ea4dk|0EA*Q
zdkQB)R|*$usl*6!JvTzWmJ{Tz8aB{5erO@ZRl`ywR>O`xW>R?2I~;k8DXcYI@$l6G
zHC%|*`wQS}1yEedg}99e!*^W444Qn2_AE#<zMx~NiWL$S;8U$78IZ%y(m=QQ7K2x}
z78Ip|d$*}63gGM5K#CI~Cz0uK!50N$p85wmp#|4$CTJQKbWd+yI%L`xG%s14kzZ7j
zTw0<4YEFR`(<XvuFHo&cNlnYl109W*r;v~UnFjIocX9PeNPs&8G~xuoCHdep+Z4dF
z!r*xi&_pThdSV>~$YEj$3F=9iiD@8nbyHFcbW`)x(dT7B#(`W6KCeXq?5~o1P^h7W
z48lk~eH)N6JAH77p_^Bf3Myf6PK1Udj$%v6EKW`=N&!!YgO@gf)<{CU0$O;SmS2>d
z3YttWN-fS%fccE@6lrl$GOn0GIT5ZX6*N%{GZ*X%u!m4*bwR<Ckf07JMAZ`#tP~(j
zg`(6P&_QYn1&QfcXPMPAa!SDJGjd84GV*g%K?-#s=jtUUgN{bbOv*`x#Gj>=fdR-d
zh87@(Mreq$wuL69JCG)z5e`CChB#gYXAGbmQU{8wV(?@dl1|XkN1zkp@<G%7CHbI$
zf*nu^iX!mYV#PQntKmu2wE}zu5!y;xJ3Bjwm%-^9bpB(0Q3>>9FSu4vn1d8TGp;RE
zUJvA04U7b>Nu)kK{eqGtJy>?oOGz!z1NDsck~0#E)DebgG8U<TnpU90!QC{OZt>(M
z7Q}-x2WYtmtVdiN4>}*wuLyMP8@S1IiwjYb+yeC<OH#oHzJ)-h`?i4kS>SmCks?qj
zTm)XF3!mt_#Rg9Q#YLcU?-naKY;LiFGe4wd1zMX_bOvMyXx8KwTYzIwuxn5eXu&V^
z^dW@xMVmqDz&3)`>E2>0$p;?>q{&^R1o9ZTAp!QHDu@ee1%T%#ApQUyY*Ug7=^d(r
z`h=kQfa27mVo>!AiWn${jC+He1i!Bm6g@JaR-6}jV(+UHBZGk01%AZ~{EBngW^&Bo
zfUrAQK!e@o{dHY+Gg2<{D_`MP22IQPGTs%Ip6fctdj<0q8J+7g2A5<EHi&E}xhP|E
zMaJep*acyqi^4uvgnc?(?h1%b;hJHxBK3gk1p$wX0v=ZcJUUn(=o+kvxS(s>o7$5z
z!*qez9NQ~=niu#q4;Xha-{2RS5Y|(BonQG9zw!bX*daL&1SBUgPvN{Epm;$*afS<o
z2F<SVUgwa##34H)b%D<nIm3$_MprnDE^rv#;6RnwU~-Ye;tGew1rCcFB9b$-uZXC1
zaNZCUnIJqNWQOSi&5MFMR|IuB*lq;JUQkb8P`bQwQRM|gj}s~v)%~xi`(IG^zmS~X
z!FGj1<pu{|4-aU~><qR!yzo;}Zt#nC@Pa#aDD6d1I}O~Qv%~1m)iR+BM>AnenSm}T
zhF7YHDVAC$&`s|(Obg&WCAcDt8z8W^=ulgP=mT-J%r(r|CumZb(Jw!)WkKGZSHpx@
z7g@tx1Cm3mj%1m`T8nafAX0mdwT7_-v<@EXku|KS?G?zBpC+3h_&`XM5i3xe7(8MH
zI+A%hLni2yLn-)p6=MyK(+*KXU@}vWbT9+B3BQuD2vnM^gr0zR6_h`(fhLhafemZP
z|KhR%t^0zUbtn%VKmi?@g*18uR}jR+!0;KAyBioTh<ZTK!jJ`lD;Osv&Jdh0I!kn>
z_#APF_yti9a1#0@h$tiUAOm}vtcVh<NDEXNXo3h(zF*0Bix;vIKRy?7{VflqPykPM
zx`4a@*02r4+6p2-B@?&|ffRY*B5Mw)1Yt?Z%*oMY0}q;kyCD#Rz}ms~8G;6eK#3Ys
zwm^y&kXCrn0tyE|P|>mk(m@2B#M8kFniMsip>dI0`3g6<3{krwA~D75iim25>kV+Q
ztO&iXYkNu8_M)!+6<z!5x~`XWT`%goU(t2HAnI{Z)Z>b%M+espQTgd{lj1I@nC}p|
zC~9{_)UJc;hNSEq$s3>>*>A{ef{>ijoV*X5EP{HVV;%H5Sif>HaPswVO)#CIvNq)c
zhw()Y<0~A-7hnh+;wYIG)RYHjS`#eu2!yjO@|ZPpw(S62zQNSOk;05M%YjlDGy@>0
zP6k4=rl?7|6KSb3_DqbS9^_lFg~X^w9;`t%DTQSY##NIktSt;ROvIRreP{;N28>W+
zsbN{b1$H_bk-~;iP_cF*ExxW{%0hGqS!!5om^&E|3$0Vw=djhXm4G(aK+Q#5p<2UM
z!&m~ExP!{9;lNr{abhW|K;aB7s*D&I7(j#T;KE9{ma&Erx%=M9gx)cp%+w<SEuJ(P
z!53S@4(J3IPoS$6p#u#Kko;&4nv2y!DwmLs^21g{#e=ddXg?0<G**R*3t+TEaDm`b
z_Z2Q16fdfnfHoz7MK35+fb)wcEBJ7|qV=HS1bl|yMi2|MzDSd$s0_pgT?AHC0b*5x
zMlaxFhYSo1)GoD)OhIL#8K`Um<sw))T|{a?q=3d_EI?*~Cm1b36D4d|%Uy7r4OI9R
zS%DM@Ldr=*feUKxfk)&ZWi@DY4ZMP(2()Frh;T_<WCJpm9lan1TZ>j2gVGiBkU~iG
zgARXyuW$er$4Jp14T@?t=)gV^MKdhYL21IS{DMNoMTLqh3KgJ5S{$<1IaDrjsO(7D
zlXu-N{E}VxMZ3r=c9A#ioX`ZU?e|z;w+_5y9eB|?_=<J#U1Nuh_FL>fursT<Fn(YF
zksleDIb9jQfXNRKl7m6alktM62lXljEql;OZFwKKSwVFJt01Uu;2~T$XmS*Rwi|;d
zqKZJ9hruJVMLrA+3~p{AnleS8gJX;QKq(!3JTaIBI_VW620E=6GTsW#C*YA+&^g->
zG4QG+uo!r|9GC?<))pcQI^44ebQ>6C3mxd@Ey%({Fbll!56l8x2UHXX8Wv`Qxb+^$
zHK2)mkPG>Wz?<^G?n2m%&Av#GHn54{m4#py+!jp^KR-8g<3luskW2@!R(uIE1iWMs
z%mS}l1e=84ZfrI(ftRQieFgc9vFHbg;(*Kq{sLJ7UgHA}9?(J`NI-#u0<3`zNhN5(
z3X(iHs93-YJBmR0rwFVI#L{E|udo0w&VY!5&B71`Eu_Fy3#u73nIQT=H4Kam8U)m2
z4k=P*WMFX9<bpJ<z@Y=~-GM^~+{FWnf%|!2F|e~hJ99Kyko15>!CsKR#StG58mEen
zzr_^~ZT`i_-{OgnFDy;Wfyfkrn|r#TVoi&If#DWMK~a7|YEelgxUUI5Vzvl09t=5~
z)(sS};1mtoWLX4S5?TaW0S8`TRRmh*177}81X^}d1Zp|nV$XvdJzE4?98v^Yx={q0
zS}X$1Al%{xFBZ;CEy>7Ff$U8MbwrCmO~xWnK?QDggR2xs;RW(+5r_cQN5!Cd<pu^A
ze8A1$;BtdUpuzP63p1<o2L?F7#lXh*fr*h7bdn&e-A85yHole!hyWW@DhhNuAZrvO
zl4KO)2Q~&akq=C)tU@0cSXqTYaw08p5CJ~0lmM&72L=IF4Y(9Yz=%Ow{)UX~4ROgE
z;u1H+ByWgF-Vl?%AtCcY)&=Y)9Ap?9NTav}NEcj-pbI0b*arq2WDpaBsN@Y1i5sF)
zH>Bi18bLOK?GnvrWL5jXfP+k8W@S|Y`3jj3V~~;kz{$?)%J_i+2PwqHYWsl!l@MTN
z1syzyLU1v%@_b-GCD<6)gd0LzVjJUI;z6O0qyQ9tqA*dS)d{dlf<hmeP~irNp%PLI
zY=Q{;KvoI1L_-AFKvJNi1aAmS-;h@Lz^xAoY!m{n9weH?$jxf<fdQ3}5(J6iARvhs
zlw>vSK$$SDw4}5sH9o!w)D$TK9qs|%z<rCYI0Lj)u?W;ty~R<Inp=>TnUh-d43yu%
z*$>nzf}CB=R#I7znU@YJnm}FXBGCLNxJ>}ba)OXGok+)Y7iECV0qq69#Q~Ab%L6ax
zyTu3LCYPop>LunDfR6^h#SIb62VHzn1R5^_uco>sfh4S#Qxp%M@+$&Og@C84i*!J1
z4Y<JrUy!x`kYO^=?7%HSBw;=9*gbf${4G8d@jUS08Kfx$+BA4e7+E?eKRq4fdC+FS
zBG9M+_~7hYLda?$JMO_7*-`C;cnCBJQUsdpyd{FH3$$D|Cnq(h2y|9W(PB`5fp+LY
z7W~P9xS$1mw?vWkz?WG-Y6J&RDGJ)He~S&W(E(gmp%r4kIBXytal4`jMh4JwN`_(w
zCI*HN%#4hnB8O4=0)rAVdcYuf0fufca5jM94F=u@FucLQ)c}S!82B5&5J^h)0s{)V
z!Ju&g8@j=uegQXnz`)%AhBp{^8o=-dgTe(=bb~?k0xG(JYV`#MRa~~*U~ssA4Lv|u
zhuwKM7?dxdq8kj37jUB+46YY&BWw<~zQBM5-C(f4fQoJ~IA0)yFunhPQ@BHFg2zQp
h*(;o~4QwCS+&LLdJ}_V>JHkGKWxjw(OjY2L1^_RGny>%>

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/__pycache__/vector_quantize.cpython-310.pyc b/tania_scripts/supar/__pycache__/vector_quantize.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..821f6b3037a8f6dcf6144badeb248d0ba76a3cf0
GIT binary patch
literal 3635
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
BjdK71

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/cmds/__init__.py b/tania_scripts/supar/cmds/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tania_scripts/supar/cmds/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/cmds/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d1abebfc6e576b314b0012bd5702c707a2e1f663
GIT binary patch
literal 144
zcmd1j<>g{vU|`_PGe`%~k3j@7W@KPsaA06yC}v?`U`SyIX3%8xTggxa5=IcejP*0}
zb5r$85=$}@^Ah!vauQQAQ;YO7^O6e^i}Z_2L1c1nO0j-?d}dx|NqoFsLFFwDo80`A
R(wtN~kYUA43=9k`3;^29A2R>|

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/cmds/__pycache__/run.cpython-310.pyc b/tania_scripts/supar/cmds/__pycache__/run.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2391df2e6f812f40aa83be07b9bc14104795013a
GIT binary patch
literal 2736
zcmd1j<>g{vU|{(A$}s&ZHv_|C5C<7EF)%PVFfcF_7cej|q%fo~<}gG-XvQc;FrO)k
z2~0ERvP7{mLgd(T*`qkXY^EH}T&^fCFq=7tJC`SlCzm&h7tCkL;mhTZ;?EU`5@2LV
zVNGFcVTck;VNc;`VTck+VGL%_<a`Noi=QUrEjH);ytK@8O{QDinR%Hd@j3bF>8VAx
z*dVkf(=CDY)ROp=)UwRv)cEB5(!7#eydaUZqSVy*g8ZVAWJZutP|VE0z`)MHz~Bt>
z*%U?wh8l(}h7`sWrWEEBmR@E?2%j~D4dj{>&R!O%2v-Vs3Qr0zk_cZ4e~Lf}V~Svk
zP%kS~m2iqkif9RAiWriZc#1@dWC>%66q1;9icE@ZiX7ZN`4pKH1th*=icE?U5??t*
zB}FxzDMckkEkzyfCXE!C6it|_1xyPWVwh?fYnf^o7BJN?)i5q(g78b2vshA$G8sx(
zYZ#jumoTPi)i7l;E@A9rtYu8mUcgqvn8m(;BSm{5C{}e^nIst&GS)E0bCz&ru`l4R
zVa(!O$XGn9glhp0gw4oM!<fZe!j;9BqHDuY!r#o0B9P5ev?oOmET(V6P$JOG0A?H5
zFq8;p36%)fFs3nrRT_f)oWc;yP$FC+k|nx8Y#~F@krc^1#uS|z#%3l^>Ii1gH1?}v
z)733VEXk;1(k-YG0<jcI@)dIPQ&Mvj(lT>WH5qTQWTfU4fYc@D=cQFK=_cP|s1k;$
z1c_y)LzFVzVoym;ODxSPDFQ`(6^E`aB)L>E>89LbG^i5rbWzApQ*aLm1zA#BoC-3v
zI5jn;ib=QlB`En+DS@~OY57G8>8W|CMTsSudFcv8iFqmcxe9ruxk;%-#hT1ToD2*M
zw^&Ll3sNCAaq8-pWE7<)rW98(>6W|{U|?XV;>#<|1=$9Z;MCPE&o9bOEdr@2F9O@9
z231o~l%JehT%200P+FXt0=7OSu_RF;CqFSIGcUc0T~{|bF*zgk7FTgeeo<<CNl|HP
zl{{ETp(G<!0jwD0=(NP*5|}Pcrdw=@$t9Wjc@Rf(>FOqB<|P(oR;5;n!&pe#GmDB#
zs#tY(6LSlyG)s$96%tEJ@^ceQGLsc@Gb>V46bgz`lQWAm^Yg$CEJ!RW2Dyz*S2rcI
zxa1adN=m^kmbBuOf+{JHKv8B=X-R5|LP=3#W*#UMLBUn5$$X1FIU_$aIkgxZiV&x<
z>*|&#=A|T6$$=@b`6We($=M)%sTBpOMVYy&c_qcS*h}-W^YY8{elhC5{Qv*||63x?
zp)QW`VV=RBPCl;jF0Nso&aS~#{3Xc+R{Hum`N@en8TrK}x43;BgF{?{;vHRFg5aD0
z|DX^}rduqDMd`)2*z!P;P`r{sQ~VZBVoFMUVo`c2$kJQPnRz9*1VG+RjR#u}k}56&
zm7BL%KrwWSr7W?i_!di6erDb+7EsE(#adjDlUZ_$EiFGMCAH`lQ-1L+w$zHu;*#Q9
z9Jz_vsVSL7#kbfXsq+?lYF=4pQGQ+#D+2>V5gRCNG36G3%t$QHyTuB&`4($Qeo=D9
zEtcfcl*C&+nZ@ymWr>+NiAg!Bn#{M@z-o$$BtZrUg9vFD@k>uXBR@A)za+6FGchkw
zFDWN6B{Q{1KQk}6AhAflxD-St=cW|v7nSDe6;$400hPWypkh;xfq_AQQHW89Q3MPH
z7(q~sQGk($QGii~QHF_+k%y6oiHnhok%v)&QHH6=h=GA285A<mVwi!2fq?<!BXBt!
z2P%gd7citSE@Z4_Dq&o}RKu9XypWNRp@eY(OATWdE11pJ%#gyA%~GUY!k)#E!d$|c
z#g)P$$uOHCg%!+Z1F`2am#{T6)G(y5gUZPg#w_jyJT(kp{k$c7HH=yOvl&u2Y8bNw
zW;3L4&Sj}#Tp*ajwUDvMIfXlqF@>j@nUSG{Z-Gz>FR0XNW)uhOtzoEPj2Ee4n9ab#
z0Je+I214`OfJ#Gw6oG7}qWT)fEYYIe8m26<6yZ#U8gLn#$6mvfC63_NGS@I?Ng();
z5)b5_6v1q!qG_nQ!Kx*(sus#-Dq4$0wG_H)P-&|v;&+QJAhD=8wWx?2l#p2Rl9O|a
z#2FYEelc1VNiZ-lXtLa5PfASAPR&b!*0i~)B^miCx46pli*i!pi!-ZIZ?P05=4Ibv
z)T?6A%gIl_#g&|qnw(vb56TIQiMJTbZ!vP+VhM8e^S;I9<L~U~6Axyyg7f+<j?}Wm
zoYKUS)LZNYMX4#7$t6Xg<ftiqi@6}bphy?wF8<=wlK8yR+<0j5c#9pz;Lc6VD^1La
zFHTKOxy1q^!TI7A3#d@JB?L;H@t~}lT3j5TUX)*2P^1b<>zW_}lwxmjfsBS^ts+n}
zpa_%(i<CgNvVba<Tg>UHC7@)UmVb-6xTNS77r2~=2YI>38f1(-NG)qpX=YAJkt0aJ
z2}FRBuqI1U0Ei9FXvQFx0f+#35A4SxLl9R76wII;1d;^h4IV}=Mm9zXMixdUMz+5^
zELu!LjBHF|j9iRrj3SI&i~?|y<zEq4w=mdOx7dm^N=q_xAYmp5E&}vG;Q%dMZ*e1W
ziabHi7KJFvEzK#(ga%V)UivM5G=U;5kYa9d_SXYh0WHvkkwidIpPreQjtIqDBFNGO
ziA9MyIjK3|_yLz&;QSBv03<X}!{ru-O>TZlX-=vgsPZco0u?Vz9H1fuT%ZUraxnAA
F0svv=_vQcq

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/cmds/const/aj.py b/tania_scripts/supar/cmds/const/aj.py
new file mode 100644
index 0000000..7952168
--- /dev/null
+++ b/tania_scripts/supar/cmds/const/aj.py
@@ -0,0 +1,38 @@
+# -*- coding: utf-8 -*-
+
+import argparse
+
+from supar import AttachJuxtaposeConstituencyParser
+from supar.cmds.run import init
+
+def main():
+    parser = argparse.ArgumentParser(description='Create AttachJuxtapose Constituency Parser.')
+    parser.set_defaults(Parser=AttachJuxtaposeConstituencyParser)
+    subparsers = parser.add_subparsers(title='Commands', dest='mode')
+    # train
+    subparser = subparsers.add_parser('train', help='Train a parser.')
+    subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first')
+    subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training')
+    subparser.add_argument('--max-len', type=int, help='max length of the sentences')
+    subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use')
+    subparser.add_argument('--train', default='data/ptb/train.pid', help='path to train file')
+    subparser.add_argument('--dev', default='data/ptb/dev.pid', help='path to dev file')
+    subparser.add_argument('--test', default='data/ptb/test.pid', help='path to test file')
+    subparser.add_argument('--embed', default=None, help='file or embeddings available at `supar.utils.Embedding`')
+    subparser.add_argument('--use_vq', action='store_true', default=False, help='whether to use vector quantization')
+    subparser.add_argument('--delay', type=int, default=0)
+    # evaluate
+    subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset')
+    # predict
+    subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset')
+    subparser.add_argument('--pred', default='pred.pid', help='path to predicted result')
+    subparser.add_argument('--prob', action='store_true', help='whether to output probs')
+    init(parser)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/tania_scripts/supar/cmds/const/crf.py b/tania_scripts/supar/cmds/const/crf.py
new file mode 100644
index 0000000..d380931
--- /dev/null
+++ b/tania_scripts/supar/cmds/const/crf.py
@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+
+import argparse
+
+from supar import CRFConstituencyParser
+from supar.cmds.run import init
+
+
+def main():
+    parser = argparse.ArgumentParser(description='Create CRF Constituency Parser.')
+    parser.set_defaults(Parser=CRFConstituencyParser)
+    parser.add_argument('--mbr', action='store_true', help='whether to use MBR decoding')
+    subparsers = parser.add_subparsers(title='Commands', dest='mode')
+    # train
+    subparser = subparsers.add_parser('train', help='Train a parser.')
+    subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first')
+    subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training')
+    subparser.add_argument('--implicit', action='store_true', help='whether to conduct implicit binarization')
+    subparser.add_argument('--max-len', type=int, help='max length of the sentences')
+    subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use')
+    subparser.add_argument('--train', default='data/ptb/train.pid', help='path to train file')
+    subparser.add_argument('--dev', default='data/ptb/dev.pid', help='path to dev file')
+    subparser.add_argument('--test', default='data/ptb/test.pid', help='path to test file')
+    subparser.add_argument('--embed', default=None, help='file or embeddings available at `supar.utils.Embedding`')
+    # evaluate
+    subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset')
+    # predict
+    subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset')
+    subparser.add_argument('--pred', default='pred.pid', help='path to predicted result')
+    subparser.add_argument('--prob', action='store_true', help='whether to output probs')
+    init(parser)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/tania_scripts/supar/cmds/const/sl.py b/tania_scripts/supar/cmds/const/sl.py
new file mode 100644
index 0000000..97c9d47
--- /dev/null
+++ b/tania_scripts/supar/cmds/const/sl.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+import argparse
+
+from supar import SLConstituentParser
+from supar.cmds.run import init
+
+
+def main():
+    parser = argparse.ArgumentParser(description='Create SL Constituency Parser.')
+    parser.set_defaults(Parser=SLConstituentParser)
+    parser.add_argument('--mbr', action='store_true', help='whether to use MBR decoding')
+    subparsers = parser.add_subparsers(title='Commands', dest='mode')
+    # train
+    subparser = subparsers.add_parser('train', help='Train a parser.')
+    subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first')
+    subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training')
+    subparser.add_argument('--implicit', action='store_true', help='whether to conduct implicit binarization')
+    subparser.add_argument('--max_len', type=int, help='max length of the sentences')
+    subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use')
+    subparser.add_argument('--train', default='data/ptb/train.pid', help='path to train file')
+    subparser.add_argument('--dev', default='data/ptb/dev.pid', help='path to dev file')
+    subparser.add_argument('--test', default='data/ptb/test.pid', help='path to test file')
+    subparser.add_argument('--embed', default=None, help='file or embeddings available at `supar.utils.Embedding`')
+    subparser.add_argument('--use_vq', action='store_true', default=False, help='whether to use vector quantization')
+    subparser.add_argument('--decoder', choices=['mlp', 'lstm'], default='mlp', help='incremental decoder to use')
+    subparser.add_argument('--codes', choices=['abs', 'rel'], default=None, help='sequential encoding used')
+    subparser.add_argument('--delay', type=int, default=0)
+    subparser.add_argument('--root_node', type=str, default='S')
+    # evaluate
+    subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset')
+    # predict
+    subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset')
+    subparser.add_argument('--pred', default='pred.pid', help='path to predicted result')
+    subparser.add_argument('--prob', action='store_true', help='whether to output probs')
+    init(parser)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/tania_scripts/supar/cmds/const/tt.py b/tania_scripts/supar/cmds/const/tt.py
new file mode 100644
index 0000000..286c402
--- /dev/null
+++ b/tania_scripts/supar/cmds/const/tt.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+
+import argparse
+
+from supar import TetraTaggingConstituencyParser
+from supar.cmds.run import init
+
+
+def main():
+    parser = argparse.ArgumentParser(description='Create Tetra-tagging Constituency Parser.')
+    parser.set_defaults(Parser=TetraTaggingConstituencyParser)
+    parser.add_argument('--depth', default=8, type=int, help='stack depth')
+    subparsers = parser.add_subparsers(title='Commands', dest='mode')
+    # train
+    subparser = subparsers.add_parser('train', help='Train a parser.')
+    subparser.add_argument('--feat', '-f', choices=['tag', 'char', 'elmo', 'bert'], nargs='*', help='features to use')
+    subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first')
+    subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training')
+    subparser.add_argument('--encoder', choices=['lstm', 'transformer', 'bert'], default='lstm', help='encoder to use')
+    subparser.add_argument('--max-len', type=int, help='max length of the sentences')
+    subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use')
+    subparser.add_argument('--train', default='data/ptb/train.pid', help='path to train file')
+    subparser.add_argument('--dev', default='data/ptb/dev.pid', help='path to dev file')
+    subparser.add_argument('--test', default='data/ptb/test.pid', help='path to test file')
+    subparser.add_argument('--embed', default='glove-6b-100', help='file or embeddings available at `supar.utils.Embedding`')
+    subparser.add_argument('--bert', default='bert-base-cased', help='which BERT model to use')
+    # evaluate
+    subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset')
+    # predict
+    subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset')
+    subparser.add_argument('--pred', default='pred.pid', help='path to predicted result')
+    subparser.add_argument('--prob', action='store_true', help='whether to output probs')
+    init(parser)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/tania_scripts/supar/cmds/const/vi.py b/tania_scripts/supar/cmds/const/vi.py
new file mode 100644
index 0000000..0b63a3b
--- /dev/null
+++ b/tania_scripts/supar/cmds/const/vi.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+
+import argparse
+
+from supar import VIConstituencyParser
+from supar.cmds.run import init
+
+
+def main():
+    parser = argparse.ArgumentParser(description='Create Constituency Parser using Variational Inference.')
+    parser.set_defaults(Parser=VIConstituencyParser)
+    subparsers = parser.add_subparsers(title='Commands', dest='mode')
+    # train
+    subparser = subparsers.add_parser('train', help='Train a parser.')
+    subparser.add_argument('--feat', '-f', choices=['tag', 'char', 'elmo', 'bert'], nargs='*', help='features to use')
+    subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first')
+    subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training')
+    subparser.add_argument('--implicit', action='store_true', help='whether to conduct implicit binarization')
+    subparser.add_argument('--encoder', choices=['lstm', 'transformer', 'bert'], default='lstm', help='encoder to use')
+    subparser.add_argument('--max-len', type=int, help='max length of the sentences')
+    subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use')
+    subparser.add_argument('--train', default='data/ptb/train.pid', help='path to train file')
+    subparser.add_argument('--dev', default='data/ptb/dev.pid', help='path to dev file')
+    subparser.add_argument('--test', default='data/ptb/test.pid', help='path to test file')
+    subparser.add_argument('--embed', default='glove-6b-100', help='file or embeddings available at `supar.utils.Embedding`')
+    subparser.add_argument('--bert', default='bert-base-cased', help='which BERT model to use')
+    subparser.add_argument('--inference', default='mfvi', choices=['mfvi', 'lbp'], help='approximate inference methods')
+    # evaluate
+    subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset')
+    # predict
+    subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset')
+    subparser.add_argument('--pred', default='pred.pid', help='path to predicted result')
+    subparser.add_argument('--prob', action='store_true', help='whether to output probs')
+    init(parser)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/tania_scripts/supar/cmds/dep/__pycache__/biaffine.cpython-310.pyc b/tania_scripts/supar/cmds/dep/__pycache__/biaffine.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9d1e880285e3ad83ee46efd54d2f67696d3632f8
GIT binary patch
literal 2259
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
M9LyZbT#PLL0VCd?y#N3J

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/cmds/dep/__pycache__/eager.cpython-310.pyc b/tania_scripts/supar/cmds/dep/__pycache__/eager.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ad57c97660122f9abeadd858036cba5f3669e9cd
GIT binary patch
literal 2194
zcmd1j<>g{vU|`_PGe|e%W?*;>;vi!t1_lNP1_p*=I|c@Z6owSW9EK<m&6LBK%M``L
z2x2qmFz2#Fu`n{Eu%xiIFhsGYvZb(PGZo3EvNkg?GNdpDgRv(2OOVNanvAz39E*}&
z6Vp?RTv7{C^HNgtk}Crei;7c=G#PKPWaed-B!g7KFf#)K0~-SagEPn-XBZh6N*J;j
zQy5d2dKqgOY8bMZQkX$Dr?B-hGeY?6DJ&@*NPNx|mJ}{HpSgr3g}av#td=!}CxthK
zua~Kov4$~=ErmZtAVsj3sg|jRDT^sZC`CAhB}F8Kt(S$70W2b#!jd8eH3_6bJcT7i
z0*NnK!k!|PA`Ny4NM0sIwuC)JE=3-0f<lU7ic*R)T!l)CYKj^XUp+-5MH7jymBNss
zjl|bUVM)<V(M!>Xn`n??m|~R9lwz1-oMHkOH7#LJF-tKA+XM2MMT#Yo&(Pg1lVXMD
zPU{qn6dS0$ApN!}c1Zg1s|WeqKE)x$5vm`=cS>PNafXCc2}cb>Gb1SN1T$#5_*JPm
z7o{eaq$-3ICFT`pmSpDVDIgMt0wiVVX)@m8PDw3JF3Kzbsi<Pp)h#JXO})icT#{du
z8edXWnp&k;o{?ITky@lslCO}OS6o_@s!*PqlcSrKUzD4gl9yUstjTnXEioBnz%7=H
z)SLp4F$G2WSyc*1T0sJ-$t9U(nN_I@B^jv-DTyVCRh+uI1&Ku^nTa`7YB0r60fof8
zy!?_xkg*Dx#R{2u$vLGdsVSO_x7Z-AkK%C7&&^HDODVp^lAE8Bs>yVVwIs77C-oLf
zN@{V*E!L8v#LT=Z{tytQkf=}q&JB8+j797W3=CE5y1GfFnK>y{Ou9)ZE(ME%od_~D
zM<Fe<sJNtxM^`sFBQ-g@AU`v&q{;y1*phsOoczQTg+v8}EGVRkQo%u}0Cq!WUOLFS
zg3`R?k}5eQtx!)XfMrU-egy?dZeoRQPHJA2bZ%mWLQZO4dP#;tej3<G#i@BEsd>q%
zpg?CSsVqo^c!m??ndI!$lH!*N3=9lak|3RVrMVz&Nu^*3kgH0IQ#F}yv8SY_C6?xt
z6!9`JFhKOPgCZUjTB4w6(Jv@T(g(X-FF8LiC#RxHs35T<17reNR3R-hCsmWFh##(>
zRaZA9wX8}Qt~({Q45n8ArZ*+E46GBBK1x!HOR7ZR%0XP1dO?_akRU_@yRL3(Zc=JW
zl{v^}h5RA~FgGPLFTGeHu`Dq&Cow4}RUxrNA)&amAhAfVv?Md9SkD!t2c#&WibGeo
zv^X`stkA7W2`K_fi&GWKQj<&aixdh=6Z1+ktH6<<$y@{~9FaW83G!faeoAW5E#};u
zf?F&(#U;5_Qki+lMX9-|c_oQC3Mr{zc~B@p!#O!4KQlSC7|9rRkTE%ll|_sU3=En~
zkQe|3<1LQVvc#Oy#FEr1EmtTD65$1@$(d=HsVUI(tB{zN0?s?dsU><ZIY5!krmG7I
z$SQtVz=3$hsU^4A3yM-xGLuWHG((G16%rwd5n)nEzCvzdcB%qYRc3x(u^uRHK>R9h
z5DAMC37E+s!OY~6)D(rH)Z)^d5{UBrq$+WwK+P{LDJU&bC@9KLD%Rw@#gSN)4$gbG
z_#BJUOF^Lp$-uXG5>ry*6QN?ac#2a?;-N{ixCm59-r@r(C@xI`YcDFk#RcL+IJcNH
z^Gb?9)tDypEjEZ)6c<8m6epa$lA%bBfq~(diGD_YZmK@0Oi9d3)Jw`qOvy|w($CCG
zE=VlW2PYi;<lK~E{gl)K{Zvp@s#j2XizPQPGY=Hb#a0Xq3_OeiV93MB$H>Pd1ZE2`
z!e|gnj8TA*j|s#A(J&bv#v)M0yu}e84>B)4UX#5@jDdmS7Ax3Zuy>>Qz-&E`8}y1w
z^T57?Ys*W_O^uHS`vi%Q2bsZPlbfGXnv-e=N>#;t3=9k$Ogv0Hj2uiH%3O>r{{aGQ
BgmwS`

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/cmds/dep/__pycache__/sl.cpython-310.pyc b/tania_scripts/supar/cmds/dep/__pycache__/sl.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ce6e7c7bc3a266002f7b31faf3e1bfbd4c6f6aef
GIT binary patch
literal 2281
zcmd1j<>g{vU|=}2(jdK>n}Ojmh=Yuo7#J8F7#J9e?HCvsQW#Pga~PsPG*b>^E>jc}
zBZ$qM!<@?!#lpyt!ji(;!Vtxp%9g^G%~T|t%G%7p$dJMq491%5FF_{zX)@jt3ifeH
zElABvNzF^H3`i_0PA$@8yv354msyewQUk-x3=9lx3=9m;AQwDhWMC*^$YM-kOkwI}
ztYxTS$YLsCPGRn4WCXEUK(?o_rLgxhL-`yjtSOvGe6AGM6mB@5HH9aIH-)d4sg|*Z
zF^esQKSdx#u$QTpsfH<wB}FJjIE6JuB!#_~g^>X)BAUXQA_mnBQX!tgnj(S3mn>mV
zkxG#U+YXYKNs%pKPmxQJhnt{~qL`wTq6}A|lA@ZThQwD-(MZum;%lWaq-Z1Yby8SU
zbW`+F^x-BNq!^|cr8A`%rWmJ~z(q~d8B)v^F{Uu2m?Mc=l(45*rdYvkw=UsGv4QeI
z{<lrBL-M~&iana^9a1z>9HFiOsdq|oCR#lxJX}&-Q{15XL45ZV))Ws&_?2+hFf=oQ
z(o!&krl(((igQtFVo9n(u#W;FnJ9qLNoHO;m`*Ly(`3BGoswFdT$EW*l9`{U$#{zm
zq$0JbicMFyq$oA@7FTgeeo<<CNl|HPm122DYDq?FkwQtnLTX-dX;G>|d1_9MZd!g(
zZfZ(iYH_h9(=E2dWROv}STa&`3P8pb6y;}CDIjSD38W^MWR_)Cr7DzUq$;E&mLyhj
z>gpCG7L{Zs=2WS{6hj3R67%x%OA<lGDr6QbWacI3l%}MnL~%Ih=jJBnr4-*{$<0qm
z)nvNGT9R3klX{CKCAGNZ7HdgSVrE_ye+Y<DNK_~Q=Mg<k#v%>|28JqjUEQS8%$$@e
zCfy_y_kl&h4g;B*qmY(aR9sTUqpO>ok(!)cke``XQe^;hVoAP2PJUvFLZSjf78E{3
zso;Q90J|YGFTILOS2r`aASW|9v!qG`Nq2I7UP@_li2_VgAt^I2u_&_&>|Ic(<R(_c
z=cMLUN#`b3DCDH(rI%zV<fnn%SDczxlA4#C3JQ0YlFEWqh|f4dK1<F{Eh&Dfz`(#z
zB?;1*SDFjbmQ)Is06DR=I8~GR7JEu+T4HHVNf9pt0|P`qJ1Fi!K_>)?8U2EiBz>?q
z^a?Uls)Py>OEN&(!9ogYnK`MNOhx=~&8)h*DXC>u0&uM<sbye|0x*p!sbyeopu|y<
zT3k{k2v-Z@f)xwG6oW({s@ZjQQ*)D2Q>x5Cb}Hl-DS){tnR)5O3W;TjnK_9`IjIVX
zB?<|}r3HyadZi_qImLReAUz;O2~`}rx~0Xb@nwZ>RZ2)PP+FX-P?nlpl3%1ySelqu
z0u6gj<|1~GuMl421bHnvKP9#37ISV+!7Y}Y;*#7dsm#3OqSV~fypqHmg_KmVJScpi
z!JC|spP8Imj1)rby1F1m#hR?Qm=lwVZ!s68=G<Z~$S=OdWLR*E$*7=;FW5&RIUnR`
zh0@~G6i`x4NzF;DEMjC}V9;cOL>0(gRouF|Mfv$9@p<_vskaz|Z*ioSCFYbSmZVl`
zxk6cxlv0qIoSBxHngY!Q3W<3s;Cxq{TB7$7oFCY9bwTk^#SaU55U)73<Q98DQEEzN
za!HkDXmP4SA|y#8Oe)D&$W6>nRe-9>%+D*<14S)}U&R3;!7(ZUGZrM0nOu^ZqEM7t
zT$)n?QJbGsC5{v)`K2WVr6mdlMfpj^nq0Ry5{uHo+4mNoV^Ml3D6k>r)GeOk)RK5;
z5-u(R)wH*G5>ry*6QRm(@qu{7rAc7zMa8$cKzs=27IS7^$t~vMlA<C|C8^1Liwz<X
z#f8ui#R+GxWGGT)U|{%VsGpIao2m~gkrML~^^$TDQ!-PF^fU943lfX;!HG{lIX9(P
zKP9z5zc@#)pz;<=ZenI0C#VLtVPIh3VdP;H07E`TJ|-bBOMnqZgIHpWVqj5-EQAE<
z;9)FMXJBBs#StG5GBG}0lf6g=B)|%`790Rkd|<X7$O(EyrFme_!L{Wj=BCESgFS*o
msDaGju*uC&Da}c>10}O!J_ZH`4kjKZ9!3sk4izp&mj3|6+@f~?

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/cmds/dep/biaffine.py b/tania_scripts/supar/cmds/dep/biaffine.py
new file mode 100644
index 0000000..315ae6e
--- /dev/null
+++ b/tania_scripts/supar/cmds/dep/biaffine.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+
+import argparse
+
+from supar import BiaffineDependencyParser
+from supar.cmds.run import init
+
+
+def main():
+    parser = argparse.ArgumentParser(description='Create Biaffine Dependency Parser.')
+    parser.add_argument('--tree', action='store_true', help='whether to ensure well-formedness')
+    parser.add_argument('--proj', action='store_true', help='whether to projectivize the data')
+    parser.add_argument('--partial', action='store_true', help='whether partial annotation is included')
+    parser.set_defaults(Parser=BiaffineDependencyParser)
+    subparsers = parser.add_subparsers(title='Commands', dest='mode')
+    # train
+    subparser = subparsers.add_parser('train', help='Train a parser.')
+    subparser.add_argument('--feat', '-f', choices=['tag', 'char', 'elmo', 'bert'], nargs='*', help='features to use')
+    subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first')
+    subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training')
+    subparser.add_argument('--encoder', choices=['lstm', 'transformer', 'bert'], default='lstm', help='encoder to use')
+    subparser.add_argument('--punct', action='store_true', help='whether to include punctuation')
+    subparser.add_argument('--max-len', type=int, help='max length of the sentences')
+    subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use')
+    subparser.add_argument('--train', default='data/ptb/train.conllx', help='path to train file')
+    subparser.add_argument('--dev', default='data/ptb/dev.conllx', help='path to dev file')
+    subparser.add_argument('--test', default='data/ptb/test.conllx', help='path to test file')
+    subparser.add_argument('--embed', default='glove-6b-100', help='file or embeddings available at `supar.utils.Embedding`')
+    subparser.add_argument('--bert', default='bert-base-cased', help='which BERT model to use')
+    # evaluate
+    subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.')
+    subparser.add_argument('--punct', action='store_true', help='whether to include punctuation')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset')
+    # predict
+    subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset')
+    subparser.add_argument('--pred', default='pred.conllx', help='path to predicted result')
+    subparser.add_argument('--prob', action='store_true', help='whether to output probs')
+    init(parser)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/tania_scripts/supar/cmds/dep/crf.py b/tania_scripts/supar/cmds/dep/crf.py
new file mode 100644
index 0000000..1229ae1
--- /dev/null
+++ b/tania_scripts/supar/cmds/dep/crf.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+
+import argparse
+
+from supar import CRFDependencyParser
+from supar.cmds.run import init
+
+
+def main():
+    parser = argparse.ArgumentParser(description='Create first-order CRF Dependency Parser.')
+    parser.set_defaults(Parser=CRFDependencyParser)
+    parser.add_argument('--mbr', action='store_true', help='whether to use MBR decoding')
+    parser.add_argument('--tree', action='store_true', help='whether to ensure well-formedness')
+    parser.add_argument('--proj', action='store_true', help='whether to projectivize the data')
+    parser.add_argument('--partial', action='store_true', help='whether partial annotation is included')
+    subparsers = parser.add_subparsers(title='Commands', dest='mode')
+    # train
+    subparser = subparsers.add_parser('train', help='Train a parser.')
+    subparser.add_argument('--feat', '-f', choices=['tag', 'char', 'elmo', 'bert'], nargs='*', help='features to use')
+    subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first')
+    subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training')
+    subparser.add_argument('--encoder', choices=['lstm', 'transformer', 'bert'], default='lstm', help='encoder to use')
+    subparser.add_argument('--punct', action='store_true', help='whether to include punctuation')
+    subparser.add_argument('--max-len', type=int, help='max length of the sentences')
+    subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use')
+    subparser.add_argument('--train', default='data/ptb/train.conllx', help='path to train file')
+    subparser.add_argument('--dev', default='data/ptb/dev.conllx', help='path to dev file')
+    subparser.add_argument('--test', default='data/ptb/test.conllx', help='path to test file')
+    subparser.add_argument('--embed', default='glove-6b-100', help='file or embeddings available at `supar.utils.Embedding`')
+    subparser.add_argument('--bert', default='bert-base-cased', help='which BERT model to use')
+    # evaluate
+    subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.')
+    subparser.add_argument('--punct', action='store_true', help='whether to include punctuation')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset')
+    # predict
+    subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset')
+    subparser.add_argument('--pred', default='pred.conllx', help='path to predicted result')
+    subparser.add_argument('--prob', action='store_true', help='whether to output probs')
+    init(parser)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/tania_scripts/supar/cmds/dep/crf2o.py b/tania_scripts/supar/cmds/dep/crf2o.py
new file mode 100644
index 0000000..cc066ec
--- /dev/null
+++ b/tania_scripts/supar/cmds/dep/crf2o.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+
+import argparse
+
+from supar import CRF2oDependencyParser
+from supar.cmds.run import init
+
+
+def main():
+    parser = argparse.ArgumentParser(description='Create second-order CRF Dependency Parser.')
+    parser.set_defaults(Parser=CRF2oDependencyParser)
+    parser.add_argument('--mbr', action='store_true', help='whether to use MBR decoding')
+    parser.add_argument('--tree', action='store_true', help='whether to ensure well-formedness')
+    parser.add_argument('--proj', action='store_true', help='whether to projectivize the data')
+    parser.add_argument('--partial', action='store_true', help='whether partial annotation is included')
+    subparsers = parser.add_subparsers(title='Commands', dest='mode')
+    # train
+    subparser = subparsers.add_parser('train', help='Train a parser.')
+    subparser.add_argument('--feat', '-f', choices=['tag', 'char', 'elmo', 'bert'], nargs='*', help='features to use')
+    subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first')
+    subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training')
+    subparser.add_argument('--encoder', choices=['lstm', 'transformer', 'bert'], default='lstm', help='encoder to use')
+    subparser.add_argument('--punct', action='store_true', help='whether to include punctuation')
+    subparser.add_argument('--max-len', type=int, help='max length of the sentences')
+    subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use')
+    subparser.add_argument('--train', default='data/ptb/train.conllx', help='path to train file')
+    subparser.add_argument('--dev', default='data/ptb/dev.conllx', help='path to dev file')
+    subparser.add_argument('--test', default='data/ptb/test.conllx', help='path to test file')
+    subparser.add_argument('--embed', default='glove-6b-100', help='file or embeddings available at `supar.utils.Embedding`')
+    subparser.add_argument('--bert', default='bert-base-cased', help='which BERT model to use')
+    # evaluate
+    subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.')
+    subparser.add_argument('--punct', action='store_true', help='whether to include punctuation')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset')
+    # predict
+    subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset')
+    subparser.add_argument('--pred', default='pred.conllx', help='path to predicted result')
+    subparser.add_argument('--prob', action='store_true', help='whether to output probs')
+    init(parser)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/tania_scripts/supar/cmds/dep/eager.py b/tania_scripts/supar/cmds/dep/eager.py
new file mode 100644
index 0000000..74ae879
--- /dev/null
+++ b/tania_scripts/supar/cmds/dep/eager.py
@@ -0,0 +1,44 @@
+# -*- coding: utf-8 -*-
+
+import argparse
+
+from supar import ArcEagerDependencyParser
+from supar.cmds.run import init
+
+def main():
+    parser = argparse.ArgumentParser(description='Create Transition Dependency Parser.')
+    parser.add_argument('--tree', action='store_true', help='whether to ensure well-formedness')
+    parser.add_argument('--proj', action='store_true', help='whether to projectivize the data')
+    parser.add_argument('--partial', action='store_true', help='whether partial annotation is included')
+    parser.set_defaults(Parser=ArcEagerDependencyParser)
+    subparsers = parser.add_subparsers(title='Commands', dest='mode')
+    # train
+    subparser = subparsers.add_parser('train', help='Train a parser.')
+    subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first')
+    subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training')
+    subparser.add_argument('--punct', action='store_true', help='whether to include punctuation')
+    subparser.add_argument('--max-len', type=int, help='max length of the sentences')
+    subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use')
+    subparser.add_argument('--train', default='data/ptb/train.conllx', help='path to train file')
+    subparser.add_argument('--dev', default='data/ptb/dev.conllx', help='path to dev file')
+    subparser.add_argument('--test', default='data/ptb/test.conllx', help='path to test file')
+    subparser.add_argument('--embed', default=None, help='file or embeddings available at `supar.utils.Embedding`')
+    subparser.add_argument('--use_vq', action='store_true', default=False, help='whether to use vector quantization')
+    subparser.add_argument('--decoder', choices=['mlp', 'lstm'], default='mlp', help='incremental decoder to use')
+    subparser.add_argument('--delay', type=int, default=0)
+    # evaluate
+    subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.')
+    subparser.add_argument('--punct', action='store_true', help='whether to include punctuation')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset')
+    # predict
+    subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset')
+    subparser.add_argument('--pred', default='pred.conllx', help='path to predicted result')
+    subparser.add_argument('--prob', action='store_true', help='whether to output probs')
+    init(parser)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/tania_scripts/supar/cmds/dep/sl.py b/tania_scripts/supar/cmds/dep/sl.py
new file mode 100644
index 0000000..97f852b
--- /dev/null
+++ b/tania_scripts/supar/cmds/dep/sl.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+
+import argparse
+
+from supar import SLDependencyParser
+from supar.cmds.run import init
+
+
+def main():
+    parser = argparse.ArgumentParser(description='Create SL Dependency Parsing Parser.')
+    parser.set_defaults(Parser=SLDependencyParser)
+    parser.add_argument('--tree', action='store_true', help='whether to ensure well-formedness')
+    parser.add_argument('--proj', action='store_true', help='whether to projectivize the data')
+    parser.add_argument('--partial', action='store_true', help='whether partial annotation is included')
+    subparsers = parser.add_subparsers(title='Commands', dest='mode')
+    # train
+    subparser = subparsers.add_parser('train', help='Train a parser.')
+    subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first')
+    subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training')
+    subparser.add_argument('--implicit', action='store_true', help='whether to conduct implicit binarization')
+    subparser.add_argument('--max_len', type=int, help='max length of the sentences')
+    subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use')
+    subparser.add_argument('--train', default='data/ptb/train.pid', help='path to train file')
+    subparser.add_argument('--dev', default='data/ptb/dev.pid', help='path to dev file')
+    subparser.add_argument('--test', default='data/ptb/test.pid', help='path to test file')
+    subparser.add_argument('--embed', default=None, help='file or embeddings available at `supar.utils.Embedding`')
+    subparser.add_argument('--use_vq', action='store_true', default=False, help='whether to use vector quantization')
+    subparser.add_argument('--decoder', choices=['mlp', 'lstm'], default='mlp', help='incremental decoder to use')
+    subparser.add_argument('--codes', choices=['abs', 'rel', 'pos', '1p', '2p'], default=None, help='SL coding used')
+    subparser.add_argument('--delay', type=int, default=0)
+    subparser.add_argument('--root_node', type=str, default='S')
+    # evaluate
+    subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset')
+    # predict
+    subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.pid', help='path to dataset')
+    subparser.add_argument('--pred', default='pred.pid', help='path to predicted result')
+    subparser.add_argument('--prob', action='store_true', help='whether to output probs')
+    init(parser)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/tania_scripts/supar/cmds/dep/vi.py b/tania_scripts/supar/cmds/dep/vi.py
new file mode 100644
index 0000000..1175977
--- /dev/null
+++ b/tania_scripts/supar/cmds/dep/vi.py
@@ -0,0 +1,46 @@
+# -*- coding: utf-8 -*-
+
+import argparse
+
+from supar import VIDependencyParser
+from supar.cmds.run import init
+
+
+def main():
+    parser = argparse.ArgumentParser(description='Create Dependency Parser using Variational Inference.')
+    parser.add_argument('--tree', action='store_true', help='whether to ensure well-formedness')
+    parser.add_argument('--proj', action='store_true', help='whether to projectivise the data')
+    parser.add_argument('--partial', action='store_true', help='whether partial annotation is included')
+    parser.set_defaults(Parser=VIDependencyParser)
+    subparsers = parser.add_subparsers(title='Commands', dest='mode')
+    # train
+    subparser = subparsers.add_parser('train', help='Train a parser.')
+    subparser.add_argument('--feat', '-f', choices=['tag', 'char', 'elmo', 'bert'], nargs='*', help='features to use')
+    subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first')
+    subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training')
+    subparser.add_argument('--encoder', choices=['lstm', 'transformer', 'bert'], default='lstm', help='encoder to use')
+    subparser.add_argument('--punct', action='store_true', help='whether to include punctuation')
+    subparser.add_argument('--max-len', type=int, help='max length of the sentences')
+    subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use')
+    subparser.add_argument('--train', default='data/ptb/train.conllx', help='path to train file')
+    subparser.add_argument('--dev', default='data/ptb/dev.conllx', help='path to dev file')
+    subparser.add_argument('--test', default='data/ptb/test.conllx', help='path to test file')
+    subparser.add_argument('--embed', default='glove-6b-100', help='file or embeddings available at `supar.utils.Embedding`')
+    subparser.add_argument('--bert', default='bert-base-cased', help='which BERT model to use')
+    subparser.add_argument('--inference', default='mfvi', choices=['mfvi', 'lbp'], help='approximate inference methods')
+    # evaluate
+    subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.')
+    subparser.add_argument('--punct', action='store_true', help='whether to include punctuation')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset')
+    # predict
+    subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/ptb/test.conllx', help='path to dataset')
+    subparser.add_argument('--pred', default='pred.conllx', help='path to predicted result')
+    subparser.add_argument('--prob', action='store_true', help='whether to output probs')
+    init(parser)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/tania_scripts/supar/cmds/run.py b/tania_scripts/supar/cmds/run.py
new file mode 100644
index 0000000..df93b72
--- /dev/null
+++ b/tania_scripts/supar/cmds/run.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+
+import os, shutil
+import torch
+import torch.distributed as dist
+import torch.multiprocessing as mp
+from supar.utils import Config
+from supar.utils.logging import init_logger, logger
+from supar.utils.parallel import get_device_count, get_free_port
+
+
+def init(parser):
+    parser.add_argument('--path', '-p', help='path to model file')
+    parser.add_argument('--conf', '-c', default='', help='path to config file')
+    parser.add_argument('--device', '-d', default='0', help='ID of GPU to use')
+    parser.add_argument('--seed', '-s', default=1, type=int, help='seed for generating random numbers')
+    parser.add_argument('--threads', '-t', default=16, type=int, help='num of threads')
+    parser.add_argument('--workers', '-w', default=0, type=int, help='num of processes used for data loading')
+    parser.add_argument('--cache', action='store_true', help='cache the data for fast loading')
+    parser.add_argument('--binarize', action='store_true', help='binarize the data first')
+    parser.add_argument('--amp', action='store_true', help='use automatic mixed precision for parsing')
+    parser.add_argument('--dist', choices=['ddp', 'fsdp'], default='ddp', help='distributed training types')
+    parser.add_argument('--wandb', action='store_true', help='wandb for tracking experiments')
+    args, unknown = parser.parse_known_args()
+    args, unknown = parser.parse_known_args(unknown, args)
+    args = Config.load(**vars(args), unknown=unknown)
+    
+    args.folder = '/'.join(args.path.split('/')[:-1])
+    if not os.path.exists(args.folder):
+        os.makedirs(args.folder)
+
+    os.environ['CUDA_VISIBLE_DEVICES'] = args.device
+    if get_device_count() > 1:
+        os.environ['MASTER_ADDR'] = 'tcp://localhost'
+        os.environ['MASTER_PORT'] = get_free_port()
+        mp.spawn(parse, args=(args,), nprocs=get_device_count())
+    else:
+        parse(0 if torch.cuda.is_available() else -1, args)
+
+
+def parse(local_rank, args):
+    Parser = args.pop('Parser')
+    torch.set_num_threads(args.threads)
+    torch.manual_seed(args.seed)
+    if get_device_count() > 1:
+        dist.init_process_group(backend='nccl',
+                                init_method=f"{os.environ['MASTER_ADDR']}:{os.environ['MASTER_PORT']}",
+                                world_size=get_device_count(),
+                                rank=local_rank)
+    torch.cuda.set_device(local_rank)
+    # init logger after dist has been initialized
+    init_logger(logger, f"{args.path}.{args.mode}.log", 'a' if args.get('checkpoint') else 'w')
+    logger.info('\n' + str(args))
+
+    args.local_rank = local_rank
+    os.environ['RANK'] = os.environ['LOCAL_RANK'] = f'{local_rank}'
+    if args.mode == 'train':
+        parser = Parser.load(**args) if args.checkpoint else Parser.build(**args)
+        parser.train(**args)
+    elif args.mode == 'evaluate':
+        parser = Parser.load(**args)
+        parser.evaluate(**args)
+    elif args.mode == 'predict':
+        parser = Parser.load(**args)
+        parser.predict(**args)
diff --git a/tania_scripts/supar/cmds/sdp/biaffine.py b/tania_scripts/supar/cmds/sdp/biaffine.py
new file mode 100644
index 0000000..a36ab6a
--- /dev/null
+++ b/tania_scripts/supar/cmds/sdp/biaffine.py
@@ -0,0 +1,41 @@
+# -*- coding: utf-8 -*-
+
+import argparse
+
+from supar import BiaffineSemanticDependencyParser
+from supar.cmds.run import init
+
+
+def main():
+    parser = argparse.ArgumentParser(description='Create Biaffine Semantic Dependency Parser.')
+    parser.set_defaults(Parser=BiaffineSemanticDependencyParser)
+    subparsers = parser.add_subparsers(title='Commands', dest='mode')
+    # train
+    subparser = subparsers.add_parser('train', help='Train a parser.')
+    subparser.add_argument('--feat', '-f', choices=['tag', 'char', 'lemma', 'elmo', 'bert'], nargs='*', help='features to use')
+    subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first')
+    subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training')
+    subparser.add_argument('--encoder', choices=['lstm', 'transformer', 'bert'], default='lstm', help='encoder to use')
+    subparser.add_argument('--max-len', type=int, help='max length of the sentences')
+    subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use')
+    subparser.add_argument('--train', default='data/sdp/DM/train.conllu', help='path to train file')
+    subparser.add_argument('--dev', default='data/sdp/DM/dev.conllu', help='path to dev file')
+    subparser.add_argument('--test', default='data/sdp/DM/test.conllu', help='path to test file')
+    subparser.add_argument('--embed', default='glove-6b-100', help='file or embeddings available at `supar.utils.Embedding`')
+    subparser.add_argument('--n-embed-proj', default=125, type=int, help='dimension of projected embeddings')
+    subparser.add_argument('--bert', default='bert-base-cased', help='which BERT model to use')
+    # evaluate
+    subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/sdp/DM/test.conllu', help='path to dataset')
+    # predict
+    subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/sdp/DM/test.conllu', help='path to dataset')
+    subparser.add_argument('--pred', default='pred.conllu', help='path to predicted result')
+    subparser.add_argument('--prob', action='store_true', help='whether to output probs')
+    init(parser)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/tania_scripts/supar/cmds/sdp/vi.py b/tania_scripts/supar/cmds/sdp/vi.py
new file mode 100644
index 0000000..26fee77
--- /dev/null
+++ b/tania_scripts/supar/cmds/sdp/vi.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+
+import argparse
+
+from supar import VISemanticDependencyParser
+from supar.cmds.run import init
+
+
+def main():
+    parser = argparse.ArgumentParser(description='Create Semantic Dependency Parser using Variational Inference.')
+    parser.set_defaults(Parser=VISemanticDependencyParser)
+    subparsers = parser.add_subparsers(title='Commands', dest='mode')
+    # train
+    subparser = subparsers.add_parser('train', help='Train a parser.')
+    subparser.add_argument('--feat', '-f', choices=['tag', 'char', 'lemma', 'elmo', 'bert'], nargs='*', help='features to use')
+    subparser.add_argument('--build', '-b', action='store_true', help='whether to build the model first')
+    subparser.add_argument('--checkpoint', action='store_true', help='whether to load a checkpoint to restore training')
+    subparser.add_argument('--encoder', choices=['lstm', 'transformer', 'bert'], default='lstm', help='encoder to use')
+    subparser.add_argument('--max-len', type=int, help='max length of the sentences')
+    subparser.add_argument('--buckets', default=32, type=int, help='max num of buckets to use')
+    subparser.add_argument('--train', default='data/sdp/DM/train.conllu', help='path to train file')
+    subparser.add_argument('--dev', default='data/sdp/DM/dev.conllu', help='path to dev file')
+    subparser.add_argument('--test', default='data/sdp/DM/test.conllu', help='path to test file')
+    subparser.add_argument('--embed', default='glove-6b-100', help='file or embeddings available at `supar.utils.Embedding`')
+    subparser.add_argument('--n-embed-proj', default=125, type=int, help='dimension of projected embeddings')
+    subparser.add_argument('--bert', default='bert-base-cased', help='which BERT model to use')
+    subparser.add_argument('--inference', default='mfvi', choices=['mfvi', 'lbp'], help='approximate inference methods')
+    # evaluate
+    subparser = subparsers.add_parser('evaluate', help='Evaluate the specified parser and dataset.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/sdp/DM/test.conllu', help='path to dataset')
+    # predict
+    subparser = subparsers.add_parser('predict', help='Use a trained parser to make predictions.')
+    subparser.add_argument('--buckets', default=8, type=int, help='max num of buckets to use')
+    subparser.add_argument('--data', default='data/sdp/DM/test.conllu', help='path to dataset')
+    subparser.add_argument('--pred', default='pred.conllu', help='path to predicted result')
+    subparser.add_argument('--prob', action='store_true', help='whether to output probs')
+    init(parser)
+
+
+if __name__ == "__main__":
+    main()
diff --git a/tania_scripts/supar/codelin/__init__.py b/tania_scripts/supar/codelin/__init__.py
new file mode 100644
index 0000000..847de4f
--- /dev/null
+++ b/tania_scripts/supar/codelin/__init__.py
@@ -0,0 +1,34 @@
+from .encs.enc_deps import D_NaiveAbsoluteEncoding, D_NaiveRelativeEncoding, D_PosBasedEncoding, D_BrkBasedEncoding, D_Brk2PBasedEncoding
+from .encs.enc_const import C_NaiveAbsoluteEncoding, C_NaiveRelativeEncoding
+from .utils.constants import D_2P_GREED, D_2P_PROP
+
+# import structures for encoding/decoding
+from .models.const_label import C_Label
+from .models.const_tree import C_Tree
+from .models.linearized_tree import LinearizedTree
+from .models.deps_label import D_Label
+from .models.deps_tree import D_Tree
+
+LABEL_SEPARATOR = '€'
+UNARY_JOINER = '@'
+
+def get_con_encoder(encoding: str, sep: str = LABEL_SEPARATOR, unary_joiner: str = UNARY_JOINER):
+    if encoding == 'abs':
+        return C_NaiveAbsoluteEncoding(sep, unary_joiner)
+    elif encoding == 'rel':
+        return C_NaiveRelativeEncoding(sep, unary_joiner)
+    return NotImplementedError
+
+def get_dep_encoder(encoding: str, sep: str, displacement: bool = False):
+    if encoding == 'abs':
+        return D_NaiveAbsoluteEncoding(sep)
+    elif encoding == 'rel':
+        return D_NaiveRelativeEncoding(sep, hang_from_root=False)
+    elif encoding == 'pos':
+        return D_PosBasedEncoding(sep)
+    elif encoding == '1p':
+        return D_BrkBasedEncoding(sep, displacement)
+    elif encoding == '2p':
+        return D_Brk2PBasedEncoding(sep, displacement, D_2P_PROP)
+    return NotImplementedError
+
diff --git a/tania_scripts/supar/codelin/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/codelin/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..21b03f9cdf5de941345a04314d4e726119e9dfd2
GIT binary patch
literal 1419
zcmd1j<>g{vU|`^5Uz8rn%E0g##6iaF3=9ko3=9m#I~W)kQW#Pga~N_NqZo6UqL^}-
zqnLA9qF8cSqgWY1a!fgFx$IHwxg1d(U_NsWXD(M1S1xxHH<-_o!;{M!#S3P$=J4h6
zNAZK%Y&inCf>DBCHhYdxu5gqvn9Y$Rk}Db|%E*wy86}p&6(yc3mMWgcl){}Vk;0QI
zk;0oQk;az7m%`t|8YP(`3Kthll}ckv5lRtmVU3bb5ea6{6nn|Yz`&r%dQ03T-Y+q;
zEY&foI6tSfB-J%9IX@*cFC8usl$w)Rl39k35ORqR$S-zEEKW^<D;9EzcPh$86%zrA
z83mw-YBJptcgAHSR07>bO{QC1F7ZYI@$Nyct}eGY!R&w_{{T(KTkOv9K8Z=GIhu^O
z*qq}-ic(WG8E^6VWagzN7G+kYra(p5T@cD#z{*OQ85kHIHLdx@=x~c873OK?;?#m$
zJf(SwMV0Yc`I&jCMadv_u=oeDLD(4-{~8Po3^fcXjM+>@oFxo3j5SQnOu--#rfjAn
zp%O-zNC{IggC?`zE#}0e;#<r`sX3a=MW94f#KFM8a7)-Pzr-`QASX39HLoN!#kHs?
zzetn0NRWYnp-2cs2s1D+tYjz>XJBCXWv`!+pPQ;*l30?Nn3t%Rl#`f}nOdZuoS$2e
zubW;_qMMtalA5DmTw0I_5=}|X$;{J_kI&4@EQycTE2zB1pPpJ0pPZi;5B70t5kJTy
zp!Ckc$i)c4ER02x3=9lzw|G)AiwklRlfmx72m}@e1_p2-#32HK0~83&jHp47!kog=
z3keq1Y^EZq5~dnPs2a9xrXuAMW>_%QFr=_&GZpEUuz*BLSeu!H8A{lK88kWkibOyG
zAqsMrCSw#|Mq*xid|FX{ZhTRGe#tH7g8bqrCc}a#CZhsP_97;bT2LevfgD-H3gWVX
z2#`06#6YPYIe4W&QlP*Ehj5VuC{Dnkl#*Hi3nh@IVi3W>2!cFd5)@h-j694ij72gG
z3=DpnjBc7TQM{>n$;Eo9dCBo9sRhM29TUX|SC^chS6qTf5K;W4C7C(JdSKziyprM~
zPLK;hj*k)oM=w+^J_nTUi?|sW7@`DGBua`>Q;T>&;$l$o9C&_+2TSsTBw?CB4uu-V
z2ND;6Y66Rcm4i~rEq)(ICs&{NVAlZ0Ajc5@pj$klevUzr@m~I(ey%~cn2Sq_z)9y8
zOHzJ*4meC8L5dc*95%W6DWy57cAx^N7!=+z3<8V-j6BRdj1b7e#KI`UB*P8>OzUF;

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/codelin/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..737b648aa6c9eb05010e8759390d493979dff7fc
GIT binary patch
literal 2143
zcmZ3^%ge>Uz`&q*Uo|6=m4V?ghy%myP{!wN3=9m@8B!Qh7;_kM8KW3;nWC6-nWLC<
zS)y2SS)*7PL2^tvY`N@F?719K9AG|k4reY`6jv^H6gQa9lEahB8^sG|v*z&S@<;K5
z*=#uixq?xGU^aV>P_A&4FqqAeBa$l`CCbQ<!Wku&!WAW+DwZmq#+1UHDv`pIDv`pQ
zDv`#P!q>tYC7B`&7ZpgAN@GhAY+;R(P7w-b&=h&e$iTp$$$CrNCEhPFvn<sysW?BU
zv?SFvFF8LYGcO%35tN#fSdv+WkPvc-56CZeN-R!Ifh!hriFYc>MimnQix~x=h-xz3
z5_iUBBUA$2Mop$$TrTlO0rBoZuC6Y(IKk|IApZbO##`*p@ji)3sX3aAx7eKHLyA&U
zH5qU5`DEs$CKhE@rKUhd*j*6HT)@gonHd-u9yP7`#prO0BNgUp=Hk?XTRf$CiA9z1
zS^1fHsYS^kb<hZBU}0cj0P#O(fMdRfA%!uU2_#u0Pyz~15R-v{p@y-BX&Dm(!)mY`
zNHCb8h9QLst`=klNEnCO5|BMm`CtZ3X1`m^iAlw`n2S<#G?|My7#J9eI2jliZVCJ4
zmw4tD<fP`N=9Q$TxE2-V7ilsV34s&{g9s4@28LpgWeN%kzkKyG@^e%5OA<>m6Y~=F
zl5!GLGE<B6lk;;6@^wp6D@t@z%Mx?+OA_-k6XT1Mi!uvJiuH?23lc$UQc`m=^Yr86
zGxIV_;^XxSDsS<pr<TMg=jX+P1246xNQ!}hfgfa{9RmYH1H%n={t2d+*d;EoOWfsG
zTTr~h=OVx56@JSL9F{jY1t)}F;*`3;DTOX|ms{=vi`-|B=iP4cq+}Ks<Rm78{f80}
ztgwjqh8_|8s1dP@k%3_~JZey)L9hfAG9a74(U8Kth6PKcu|gw_zXW6_Ts0PR*`O)~
zN?-*9*j%hhfgP$=tb`M4Bvfq)xY&V+En{Y2SPge$FhdCsL>xp0GiY-76^Vf&S)74^
z!3~t^GZORC<I{@rbK{Hh^Gj|q7vvY;Vlpha#bi{V$zB99s0fs>ia;JIVgqRfIkboy
z#F7A&2FOWA1{9MZJqij6MUtS@29EHQ)B<>fD={!IfLu^K0c(U`<k!B!uYG|-8$G&r
zm|oy_yvXl(h2QZ4ha-xt;sWK1{AySD)h=+Tfh0mMaY|m`l)THYxIlS9%|(8bEBq!G
zI80EalovR!kl9)ZHxQD9iliAB82mID-85xx@uub_7we_wCC8_v78K(QiCcVdb;<d8
z#U)5NjlZ-cGpAS&ES#8EQd|UzCUD5z63Wd_NrlP9=YR^MB2Yx#5=4<GDN0Q(;su4H
z7*sq5UP#4*CHX*-FijwbLJb4usapb2O<-}basiNXeji6CSD*M`*8s;L#}NOZTRfqD
zjzN*}UjCkbu0gk$i%TH+@)k={etu37D8^PYfP)4cr@uICa`RJ4b5iY!3>X*~K>4IN
znvsFw12ZEd;|C@NMlYrh4AdlVF!)@+hHfwzUBHGuurV-dTwqW~MmHE#FQ6h!-8UH2
zE})_t3@R5;(E}mz2L2oTLJd3*^lUE#$A4g8Wt0aKGm^p73T7~MA{b1e6MWnt)!dBo
ZAl2NA@*vgRjPg57J}|&!u(7~_4*<LXBNzYx

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/__pycache__/abstract_encoding.cpython-310.pyc b/tania_scripts/supar/codelin/encs/__pycache__/abstract_encoding.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..163660a55c0e295e147a3eb4645efc78e2a5e088
GIT binary patch
literal 1801
zcmd1j<>g{vU|`^5UzGlynStRkh=Yt-7#J8F7#J9eO&Ay$QW#Pga~N_NqZo6UqL>&N
z+!<1sQkYv9QkYX2o0+4S-5F9?QdnCUQdq%!mK3&N22J*tAoDbtZZSJLIp5+-Oe!uZ
zN=z=vO)bgDPe}&JA!8<}eV;WL7#LC+q8L*cqL@+`qnIH!MX^9^h+<7)OJQ$eh+<3O
z2xidayv60{;+mJ7pOTrEUiF1bK|w*m5o(b_a!z7#u|isYk%CKVL26z~YF=`s0!(o+
zSZ#1>NwGpnMyf(?VrHH~a(-TMNl|HXNq&(6#F+|-c_|7hscD&csZe!b*F!XeEYpP;
zm<l!xBH)smoSy;_2+v5(Q%Fn!IZh!_AuqKYn@bcjOB8ZTi%S$zD@s!HQWQ!uGK(Q@
z2OA1<L1u12PHJvyUWr0UMt*TB)Nv43B!fZ@7Lp(~2s?vf4iv#Pj5Q4L3@Hr33@aJ^
zG#PJk7N-^@7A2PC7iluxVku6|Nh@M!U|?9uP{hf=!0^jgKO;XkRlg*$Br`EDQ7<Vc
zF(os#NIyA0w;*3Py`V%lH$NpcN58nVAQ2>*lA4p5r=OaaT&xd^-uP5#Z0HqK-r|Ul
z&&<m#iI3+2xd-GhF2*WhM2zXd<S{(K$iTn=^2BFQIs`eth>d{(;z&)VA`S)yhFh$8
z`6;QzV0S|ZkbiHnf$dM_XJBCX46=}gu}TohLWpcK$W&OEf!HwXia-uUvWf*_6<bbX
zQff}|E%t)^;*!Ml;#;ic`9&$1cBg=&UJ&F`kONR`hRFG?WCw*xUSe))eEco0`1suX
zl+qj!n<qZLurx6TD#IQhpOT*(A78``GK>#I2!jYtR08DXB31?l24+wIgLoVaEQ}l+
z9LzjSU~!!JtO(?7aQ<<IWr?c)-~@*y|2Ts(MrKJVC<Ve)LsB2f83>k6P|`3Y<A6<u
zWE_Y9-kgNZO_XLOP$<HZ1&9qwK%i7uEWp6P0Le-<Of?MgjPMkx$pp?nw|GkP5{oM1
zv+^_ZQj0X1!N~?J6UAN%5rm{saQuPd2^_JqpjZP%1REnbW5A<=aK=DSsgO(&B>*nN
zAW;=xQk0sCZY?M&DS{FaG=U<lgk}wppJ8DDV&lph5DRbd=Va!kCKhE@rKVuD50q+^
zvDydC5Je&&S#Y=@2yh5VGB7ZJB#S{jXu4+MVJZTN`)RV?Vopp-E&@5R2ozV~<PMfY
d@-o;&koH>~HjtcV2l7ubs4x*=5MUA!1OSyTpk@F7

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/__pycache__/abstract_encoding.cpython-311.pyc b/tania_scripts/supar/codelin/encs/__pycache__/abstract_encoding.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7faea83a2faeba0be37ddc0648b2989d60fcc074
GIT binary patch
literal 2197
zcmZ3^%ge>Uz`&q*Up3=BGXuk85C?`?p^VRd3=9m@8B!Qh7;_kM8KW3;nWC5&8JHN{
z8B&;97*d#18J96LFsx>Vs%MB|2FtOuFr=_z$g!lb1v6-}zXU1PWV*%d=;VBhFEOdO
zq$n}DBsaArBR?e>BnQKcP{wB!uq#p-q8L*cqL@+`qnJUqN3o<Zw=hJprm(ayM6so?
z1~X`~-Qsd|am`E4Psz+nulmBJprD}O2(>^VIVZ8WSRpOHNWmqwAT=)~H7~hR0j9VZ
ztTs5cq*$ROBUK?cF*8pgIX|zsq^LBxB)>=j;yi`KycC6$)U?dJRH!<zt09^}mgzza
zOa+?;5pYRO&QE~|glDAYDI}(V9H)?|ke6DH%_Rz%B?`Hv#U%=<6(y;8DGDVSnZ*#d
zgAE0_ATzfhCp9-UuSB6FBfmHm>Ntoil9`~P2BJW0P~3bL0f%4>V+}(*NF0n)7=jsA
zGWuyU-r_7yEl4a%EXgm@WV*#toSKtX#L2+GPz=(ppzteNKO;XkRlg*$Br`EDQ7<Vc
zF(os#NIyA0w;*4)B(<VMH?=G=N53R7FEcT|IJqdZprly8xU?V<q$VXbCo@k!H7~hX
z9~RZ|sn8hGE2zB15g(tKmst`YUnPu)Iz5;m56Bt33=9kn3^yc|I#_!6I`}&HK7-tk
z;!#ji0eh4U>`{={iZ~b;7*;Z9G8KW+`7PGG{FKyUsF#Yk85kIDv4P!@S|x~NF+_-;
zfq~&OJH%QJo(`5GkQ0(wK-NMrE(?o5S~Xc9cCzIpCZ*;S-(oMwFD^+;FTTZEo?nzw
zTnsV@lsKTyNCBr16lXw$1Q{3@iiAJ}$bP?-?4Z!fOUzA;kH5tgAD^3_Qknx|^Tfv&
zmL}#vW!U56Q}UDJ<BLFnR|Gag9ApN_Wnhnhtt|qD6qo>oTd_CTvkeRo_<@O?mE!{g
zh!9|8RsO&LC)gNSc|lw#!Gg+VfN>%AfUKZGj&_D+(yIU9EPy3PJA<-nW=Sb1Pry_|
z@&n0P8kR~?auq1HNX^^W+(c>S2E`RL1u}qgCy4)937qCpGj|PB4MRLAk%Cpj^MfW6
zIA`DDDa}hPs*KOd&&*3L(qslFSBMOIDMYXsWVC{U0wl43l2VnhBRnSH8B`XOK|#q2
zo<VQOD0i@2;gGxlM&N`%R91!L9B6J80GGXx2#qf(N=-%1xZpHhC5Yr2NUl``rE++7
zA>C5`oXot`#G=fq)D%oRL4HKB6Ou)hQS9_9k^u41a+(}S3`BrRVLUmFiB;tT1DxQ1
z<t0dV!=KYYru%8K-eOKnN-hG$ToI^@0cY<bkQ_L0!EphO&tDuikix^RNS%R!0hCUP
zs~H#=J}@&fGTvZNzJLvVVBu%v{lI`pOc4GE68!=qAo5BAAeEQ|NTmQH?-vG4DX`-J
Dznca)

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/abstract_encoding.py b/tania_scripts/supar/codelin/encs/abstract_encoding.py
new file mode 100644
index 0000000..1e3fa03
--- /dev/null
+++ b/tania_scripts/supar/codelin/encs/abstract_encoding.py
@@ -0,0 +1,37 @@
+from abc import ABC, abstractmethod
+
+class ADEncoding(ABC):
+    '''
+    Abstract class for Dependency Encodings
+    Sets the main constructor method and defines the methods
+        - Encode
+        - Decode
+    When adding a new Dependency Encoding it must extend this class
+    and implement those methods
+    '''
+    def __init__(self, separator):
+        self.separator = separator
+    
+    def encode(self, nodes):
+        pass
+    def decode(self, labels, postags, words):
+        pass
+
+class ACEncoding(ABC):
+    '''
+    Abstract class for Constituent Encodings
+    Sets the main constructor method and defines the abstract methods
+        - Encode
+        - Decode
+    When adding a new Constituent Encoding it must extend this class
+    and implement those methods
+    '''
+    def __init__(self, separator, ujoiner):
+        self.separator = separator
+        self.unary_joiner = ujoiner
+    
+    def encode(self, constituent_tree):
+        pass
+    def decode(self, linearized_tree):
+        pass
+
diff --git a/tania_scripts/supar/codelin/encs/constituent.py b/tania_scripts/supar/codelin/encs/constituent.py
new file mode 100644
index 0000000..0dbe8f0
--- /dev/null
+++ b/tania_scripts/supar/codelin/encs/constituent.py
@@ -0,0 +1,115 @@
+from src.models.linearized_tree import LinearizedTree
+from src.encs.enc_const import *
+from src.utils.extract_feats import extract_features_const
+from src.utils.constants import C_INCREMENTAL_ENCODING, C_ABSOLUTE_ENCODING, C_RELATIVE_ENCODING, C_DYNAMIC_ENCODING
+
+import stanza.pipeline
+from supar.codelin.models.const_tree import C_Tree
+
+
+## Encoding and decoding
+
+def encode_constituent(in_path, out_path, encoding_type, separator, unary_joiner, features):
+    '''
+    Encodes the selected file according to the specified parameters:
+    :param in_path: Path of the file to be encoded
+    :param out_path: Path where to write the encoded labels
+    :param encoding_type: Encoding used
+    :param separator: string used to separate label fields
+    :param unary_joiner: string used to separate nodes from unary chains
+    :param features: features to add as columns to the labels file
+    '''
+
+    if encoding_type == C_ABSOLUTE_ENCODING:
+            encoder = C_NaiveAbsoluteEncoding(separator, unary_joiner)
+    elif encoding_type == C_RELATIVE_ENCODING:
+            encoder = C_NaiveRelativeEncoding(separator, unary_joiner)
+    elif encoding_type == C_DYNAMIC_ENCODING:
+            encoder = C_NaiveDynamicEncoding(separator, unary_joiner)
+    elif encoding_type == C_INCREMENTAL_ENCODING:
+            encoder = C_NaiveIncrementalEncoding(separator, unary_joiner)
+    else:
+        raise Exception("Unknown encoding type")
+
+    # build feature index dictionary
+    f_idx_dict = {}
+    if features:
+        if features == ["ALL"]:
+            features = extract_features_const(in_path)
+        i=0
+        for f in features:
+            f_idx_dict[f]=i
+            i+=1
+
+    file_out = open(out_path, "w")
+    file_in = open(in_path, "r")
+
+    tree_counter = 0
+    labels_counter = 0
+    label_set = set()
+
+    for line in file_in:
+        line = line.rstrip()
+        tree = C_Tree.from_string(line)
+        linearized_tree = encoder.encode(tree)
+        file_out.write(linearized_tree.to_string(f_idx_dict))
+        file_out.write("\n")
+        tree_counter += 1
+        labels_counter += len(linearized_tree)
+        for lbl in linearized_tree.get_labels():
+            label_set.add(str(lbl))   
+    
+    return labels_counter, tree_counter, len(label_set)
+
+def decode_constituent(in_path, out_path, encoding_type, separator, unary_joiner, conflicts, nulls, postags, lang):
+    '''
+    Decodes the selected file according to the specified parameters:
+    :param in_path: Path of the labels file to be decoded
+    :param out_path: Path where to write the decoded tree
+    :param encoding_type: Encoding used
+    :param separator: string used to separate label fields
+    :param unary_joiner: string used to separate nodes from unary chains
+    :param conflicts: conflict resolution heuristics to apply
+    '''
+
+    if encoding_type == C_ABSOLUTE_ENCODING:
+            decoder = C_NaiveAbsoluteEncoding(separator, unary_joiner)
+    elif encoding_type == C_RELATIVE_ENCODING:
+            decoder = C_NaiveRelativeEncoding(separator, unary_joiner)
+    elif encoding_type == C_DYNAMIC_ENCODING:
+            decoder = C_NaiveDynamicEncoding(separator, unary_joiner)
+    elif encoding_type == C_INCREMENTAL_ENCODING:
+            decoder = C_NaiveIncrementalEncoding(separator, unary_joiner)
+    else:
+        raise Exception("Unknown encoding type")
+
+    if postags:
+        stanza.download(lang=lang)
+        nlp = stanza.Pipeline(lang=lang, processors='tokenize, pos')
+
+    f_in = open(in_path)
+    f_out = open(out_path,"w+")
+    
+    tree_string   = ""
+    labels_counter = 0
+    tree_counter = 0
+
+    for line in f_in:
+        if line == "\n":
+            tree_string = tree_string.rstrip()
+            current_tree = LinearizedTree.from_string(tree_string, mode="CONST", separator=separator, unary_joiner=unary_joiner)
+            
+            if postags:
+                c_tags = nlp(current_tree.get_sentence())
+                current_tree.set_postags([word.pos for word in c_tags])
+
+            decoded_tree = decoder.decode(current_tree)
+            decoded_tree = decoded_tree.postprocess_tree(conflicts, nulls)
+
+            f_out.write(str(decoded_tree).replace('\n','')+'\n')
+            tree_string   = ""
+            tree_counter+=1
+        tree_string += line
+        labels_counter += 1
+    
+    return tree_counter, labels_counter
\ No newline at end of file
diff --git a/tania_scripts/supar/codelin/encs/dependency.py b/tania_scripts/supar/codelin/encs/dependency.py
new file mode 100644
index 0000000..b2a49d4
--- /dev/null
+++ b/tania_scripts/supar/codelin/encs/dependency.py
@@ -0,0 +1,129 @@
+import stanza
+from supar.codelin.models.linearized_tree import LinearizedTree
+from supar.codelin.models.deps_label import D_Label
+from supar.codelin.utils.extract_feats import extract_features_deps
+from supar.codelin.encs.enc_deps import *
+from supar.codelin.utils.constants import *
+from supar.codelin.models.deps_tree import D_Tree
+
+# Encoding
+def encode_dependencies(in_path, out_path, encoding_type, separator, displacement, planar_alg, root_enc, features):
+    '''
+    Encodes the selected file according to the specified parameters:
+    :param in_path: Path of the file to be encoded
+    :param out_path: Path where to write the encoded labels
+    :param encoding_type: Encoding used
+    :param separator: string used to separate label fields
+    :param displacement: boolean to indicate if use displacement in bracket based encodings
+    :param planar_alg: string used to choose the plane separation algorithm
+    :param features: features to add as columns to the labels file
+    '''
+
+    # Create the encoder
+    if encoding_type == D_ABSOLUTE_ENCODING:
+            encoder = D_NaiveAbsoluteEncoding(separator)
+    elif encoding_type == D_RELATIVE_ENCODING:
+            encoder = D_NaiveRelativeEncoding(separator, root_enc)
+    elif encoding_type == D_POS_ENCODING:
+            encoder = D_PosBasedEncoding(separator)
+    elif encoding_type == D_BRACKET_ENCODING:
+            encoder = D_BrkBasedEncoding(separator, displacement)
+    elif encoding_type == D_BRACKET_ENCODING_2P:
+            encoder = D_Brk2PBasedEncoding(separator, displacement, planar_alg)
+    else:
+        raise Exception("Unknown encoding type")
+    
+    f_idx_dict = {}
+    if features:
+        if features == ["ALL"]:
+            features = extract_features_deps(in_path)
+        i=0
+        for f in features:
+            f_idx_dict[f]=i
+            i+=1
+
+    file_out = open(out_path,"w+")
+    label_set = set()
+    tree_counter = 0
+    label_counter = 0
+    trees = D_Tree.read_conllu_file(in_path, filter_projective=False)
+    
+    for t in trees:
+        # encode labels
+        linearized_tree = encoder.encode(t)        
+        file_out.write(linearized_tree.to_string(f_idx_dict))
+        file_out.write("\n")
+        
+        tree_counter+=1
+        label_counter+=len(linearized_tree)
+        
+        for lbl in linearized_tree.get_labels():
+            label_set.add(str(lbl))      
+    
+    print('/supar/codelin/encs/dependency.py')
+    return tree_counter, label_counter, len(label_set)
+
+# Decoding
+
+def decode_dependencies(in_path, out_path, encoding_type, separator, displacement, multiroot, root_search, root_enc, postags, lang):
+    '''
+    Decodes the selected file according to the specified parameters:
+    :param in_path: Path of the file to be encoded
+    :param out_path: Path where to write the encoded labels
+    :param encoding_type: Encoding used
+    :param separator: string used to separate label fields
+    :param displacement: boolean to indicate if use displacement in bracket based encodings
+    :param multiroot: boolean to indicate if multiroot conll trees are allowed
+    :param root_search: strategy to select how to search the root if no root found in decoded tree
+    '''
+
+    if encoding_type == D_ABSOLUTE_ENCODING:
+        decoder = D_NaiveAbsoluteEncoding(separator)
+    elif encoding_type == D_RELATIVE_ENCODING:
+        decoder = D_NaiveRelativeEncoding(separator, root_enc)
+    elif encoding_type == D_POS_ENCODING:
+        decoder = D_PosBasedEncoding(separator)
+    elif encoding_type == D_BRACKET_ENCODING:
+        decoder = D_BrkBasedEncoding(separator, displacement)
+    elif encoding_type == D_BRACKET_ENCODING_2P:
+        decoder = D_Brk2PBasedEncoding(separator, displacement, None)
+    else:
+        raise Exception("Unknown encoding type")
+
+    f_in=open(in_path)
+    f_out=open(out_path,"w+")
+
+    tree_counter=0
+    labels_counter=0
+
+    tree_string = ""
+    
+    print('/supar/codelin/encs/dependency.py 101')
+    
+    if postags:
+        stanza.download(lang=lang)
+        nlp = stanza.Pipeline(lang=lang, processors='tokenize,pos')
+        
+
+    for line in f_in:
+        if line == "\n":
+            tree_string = tree_string.rstrip()
+            current_tree = LinearizedTree.from_string(tree_string, mode="DEPS", separator=separator)
+            
+            if postags:
+                c_tags = nlp(current_tree.get_sentence())
+                current_tree.set_postags([word.pos for word in c_tags])
+
+            decoded_tree = decoder.decode(current_tree)
+            decoded_tree.postprocess_tree(root_search, multiroot)
+            f_out.write("# text = "+decoded_tree.get_sentence()+"\n")
+            f_out.write(str(decoded_tree))
+            
+            tree_string = ""
+            tree_counter+=1
+        
+        tree_string += line
+        labels_counter += 1
+
+
+    return tree_counter, labels_counter
diff --git a/tania_scripts/supar/codelin/encs/enc_const/__init__.py b/tania_scripts/supar/codelin/encs/enc_const/__init__.py
new file mode 100644
index 0000000..d803a3b
--- /dev/null
+++ b/tania_scripts/supar/codelin/encs/enc_const/__init__.py
@@ -0,0 +1,4 @@
+from .naive_absolute import C_NaiveAbsoluteEncoding
+from .naive_relative import C_NaiveRelativeEncoding
+from .naive_dynamic import C_NaiveDynamicEncoding
+from .naive_incremental import C_NaiveIncrementalEncoding
\ No newline at end of file
diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..41d16cbfa21181d065d0c1f0e255961bc5fc54b8
GIT binary patch
literal 423
zcmd1j<>g{vU|`^5UzC2Cfq~&Mh=Yuo7#J8F7#J9eO&Ay$QW#Pga~N_NqZk=MY^EHh
zT;?cdFq=7tC6_gd70hPIVasKYVrOJXVGU-`WP8cTz`&r%cuU+l-Y+q;EY&foI6tSf
zB-J%9IX@*cFC9rLC^aXsB(n@zN(`#Yr7|xuH!~SYlN40OGcUO)H8(Y{Bryjj>!-<a
zi!TpkS$rbYwjz*EV1h+Zdy1GD7#N~>Au3ZKHWaad!~`K?nFzCsSQ!`?Rx%WEFfc%f
zUw---`MIh3C5a`OiFt{7NjZrrnW;tk$@#ej`MT)^CAzu!DXBU7#ia#_Akmc6oXkA^
z)V$<k5D}l8pI2O>A0MBYmst`YuUAlci^C>2KczG$)eaP3#UOil7<d?Y7zG#snu>W;

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..12f0189eb2fabe6bb71d622e2452f312b08a7c8c
GIT binary patch
literal 515
zcmZ3^%ge>Uz`&q*Up3=00|Ucj5C?{tpp4IE3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI
zW-yyMhb5OaiWSUe$zjW7k78$JNMQ|T&}4hb$iTp$$#_fLIo>ZZvn<sysW?BUv?SFv
zFF8LYGcO%UDkwE4u_Ut$SxOA5%cU|eF*h?ANs|;*#xpOuC^a`VuOu-CChMokaf>ex
zWLbP7)V3mK1_lP0U=h@wA{LM!FGOVu#D*ePkeDDuEE8dN5gP*o!%BwFpdk4bqo0wV
zo2p-uSdy8Tm#CMNlbDj3TBM(xpIeZxTasE)qMKTln4@2kn3tItUz}W&Sx{1}UtC&{
z2vU=hnv<EQpPH9k3?kx_^Ye;J^yA|*^D;}~<Mj$Ee{tC4=BJeAq}mnnF)%QIg0DE3
kfq~%zGb1D84F=;2s0f>g;ROa1bc4b20yb2{!@$4*0DIS-Qvd(}

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_absolute.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_absolute.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e654e52ff2f574d7c86285d440042167471c068d
GIT binary patch
literal 3375
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_absolute.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_absolute.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..bb3ffaca5b999a39848ef14e042cb37fd4f4ebae
GIT binary patch
literal 6958
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
N!7^XKB&I5`&j7(ZH3$Fz

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_dynamic.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_dynamic.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7d6495f2c7305a9257f7a536493cc1034c193804
GIT binary patch
literal 3661
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_dynamic.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_dynamic.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..30ad5b6badac7cd3836fb4078ae00b30e8c29bd2
GIT binary patch
literal 7604
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
JVyXhiKL8R%%V7Wj

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_incremental.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_incremental.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0df5670f680c988a0e1be47f68f977f4e1915c30
GIT binary patch
literal 3908
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_incremental.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_incremental.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5f6374cacf05ac756434ee357b9b18a208fcc681
GIT binary patch
literal 7608
zcmZ3^%ge>Uz`&q*Uo~TqBm=`^5C?`?p^VRE3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI
z=3JI2mR!~-)?BtIwp{iocCZ|C4o5C$6epO?lEanD9mNf1v*z&R@<#E3*=#v{QG84c
z?hGmHEet6fsf^2*85mYGL+xaU;!j}<X3*q(2@=p`yv60{?3$OHpOTrEuE}~!*g4+O
zDcIj9G{iOD)z8`A#naFI7LRj$kiUOOypN-ktIsVF=Xhs-KQ|vw=aBed*8s;L#}NM@
zkQzUKKUb(4Zs&NHP+#B3cvn9cO~za7&hb8pNvS!SjJNoFGV@Xsi!!THQ$mVTQ#BcH
zu{p<sSboVM2f;8Cl=0aH97L%MQH&`JQA{a}Eeui2DNHR4Q7kFUEeuhtDcmV+EsRlY
zDLg6cEsRm@DI6^fQ5-3pEeuhdDO|w}n!LB9oa6lxGs{vv^OB2Fb5rw55_4caPKE~y
z0|NudP7wdI64=ff#u|ors52NCYM5#m;u&Gw6oz01O-4UWrdyoFsRfBei6!|(w|GkP
z5{oM1v+^_ZQj0X1Z?P1o=A;$zGcYg|2{14)6obrGP*C`ls-Kaco2p-uSdy8Tm#CMN
zlbDj3TBM(xpIeZxTasE)qMKTln4@2kn3tItUz}W&Sx{1}UtC&{2vU=hnv<EQpPH9k
z3?kx_^Ye;J^z%U8i_b*(Pp_cz7Ds%1W?p7Ve0-HM?f}q(DFUU|VsQorh6aWkl1d#c
zJ$yH0G&)$Wa7bPNqt76(C&L4Pfq?<U26^c-8#uU97=sx!nf$8MoIy^?EGbRRD^UQ4
zy8=?cE5Jg2C4(koksv5oK;|eE2{AA*++vT9FD@yHkFQd~>te7PK9F7xh=cjfFYuce
zi7+rQB!eOm<Wvv_ISlMVH%3T4t7WQTTmX{6z%>k6Aa{VpmoYLhtcLSynM+{#m4Shw
zh8a~hg)y52q^T%BouQVchB<{Hg{hTE5+nr1E)1~-wX8KP3qbAwiy#v<tk_+Xf^G{7
z!bDX285w#Ek=?!k>>6Y{K<pY8R9&@9H3WQB#l^sYu(Ou2hN*@zjVYKxlhyAfC}>{(
z|NsC0FD7N>B2a*9vfg4XF38C&0VniZ%sHufx7ZR33R3e@Zn1#!gC-j|u5Ymw<QJDD
zrr+X*WR>KM#LT=~0y(LPY4OM+To6u9W^u_a_S773rY#1=rUDp15(|HNY6-HgDlI&T
z22CwE;jM!t9x<s7?i<pI^KE9?tYEpKVR=#7>WZ}01rCX)+<X`K<u7t8T;Wz&Ab5#e
z=>oUX4N2(^uN%_ZE1XvZt#G~~ZSaACk=F`LOklquAaz|p@sfbz0`=v(i*z@zTvRf>
zqGY-u@rshgMFGnz0+tuR=z)~n6)ElOQU;f#3^qtzl(M-ZWz*q(LsWHX@&zrci)z+a
z)U0<nUR1NaB5K#+_JCh%hT8>xr3)NN;3Qro4azEvHOa_P4GJ7k68roMoEdQ@b0)Ne
zz>>mH%US}`2}&mn3=HT=1)jhykh4J+Tt^C13Uduh3UUHPscvf7YFJVj5lIPqf=AC*
zwXAt!c<e)~(rVdi*lJjz$+HM#*Dtnc16|8l?OP0x^vO~r11g4PK_SOflzNM~xHL(V
z9g-$l^72zsZ}Fw2CYF>IrN-wb7G<Xv-4cND!RfjrwdfWPB<;q71#Yo|<co_GK&22n
z0|Ns%VJbk&F&<EI11TsiN-eHZCy*{-3gtm&RYDS_xb*a@NmUE<E{Ypo5jX7Mxgj9Z
z!TOY&ucPK7x6Bo8nHhzbxD_sNE8G<opAt61b3xGxn;nd6>@SL1UlFzLaJwO*ut0E%
z|8)_~OCp+}G$mqvMZ~(pwZru(T!YC)QG+X@1|4oU_(dm_cGO<rkO8MJlsXYq^nv2~
za|SqFm4Na-G^HR4%oN5HrW*7(VXR?X04f`xsu5HTS{h7Y2E`aezLvR$Iha9{#ji*M
z6knPk0%V9LbCDK^tqmeTQK`uSj=Ulrkbo{ITDfx)i%a5@^K*0a^NK-P0~8~Wl0q;!
zCp9rI9!Wu!4xTu{Pz|!W*bp2scliZ-$|htk5Lys&kzeZyzg7p!4Kb<dS(CCB$XygO
zxFTk-LGX&0aR>JeeyIx_Qjh=z`2gZS1_n?)3l7j*OrSamS4LgNz`(E?riX!%p@wk*
zQqaRC7*ZH(7_#8zuVGro#K5o`&aY)E0i{i-@+?rOfZ3>~*D{xIgN4CF3UdiBm;olx
zBMa4h7lzo+wJbGEH7qI2Xf*~aNE9hz*-}_)*;80+IZ8kcBCy#E3^lAZY#1h<jA3G6
zsO7BXs^P5R$_9lML(!xfh6SLy9;y#P)v%)#XzVqtDQrmga@Vk?up{w#Y8V!9BJ?9z
zH9V*$fnC8{3sMh?GlW7Y3#)pbTD}rcBMPR5qlUePw?qQU1r@IhS@6(Bj=5!Q3=FG5
zg*aGgEq@L30#E}7%tIz>xNCT7_-go<u`n>KhQ}u(10zG8ZVd-Y%yBM23TcEHD7G>p
zw{%ebU&YJ7P|H!nS<BvYs^?1$GxmZzg<}mTsy;>ra2DqB3(;h{#h09)lap9boC>L^
z!Oa730bK;o+C@?f3=A*-{r~^pZ6)I^zRdKz{G!zOr2OLe)cj&ifm=L9sb#4}#i{Wn
zMX9N`_zDtBGU7|}<8x9I%TkLW27=<}7FTL+K}jV<6>CvqUV3T~xVUGo$}A`{0TmOf
zAOe()i$DpW2o!qY*7+^=#FUiyqWp4jC7~$*E?I5~fScBkb}YnHE^s>q<bdK^>^aF0
zLB`BmY#^cdL@1q9WDF{fIP+j-(JjWrTZ~D!SjzK@Qo!{^ks`<;1|U`J$?-X$j!`kF
zg8(Y9kTIn2VoS|S&QD3LQp8hYL6qo&>W_X#a1)+G;yQ=wB@We#9O_p%)Gu(T-w;*3
zE^2Z~)Z~E6h4APr;Tac1O)iRNUJ=dg;JPcMa79S_qLA(tA>9u4r-EV=3g;@%$eO7?
zNB^Rr))hgm4-E303Sgqc@rJ1U0>%Z33z?_HcesH$Q(`;Z9!SY_c;Aqc?(lpnE;Yk!
zf!RfItt;YM9~dNf6~M$q<_U}w6mN)#PAHt@GQs76lG=48i%UutJESivxn5Cno#6d}
zjX_RjfzzC*2`)EemB9?R4{QwD`q#DWE@|2AD7&cTc16qWqKNtg?*(EX*cenbudA3|
zQZe0-c2ULlii+(--wAFrT)(n0D5x)}+@QUq`l?U-g~Ze=iTM`_OTREM6frt8ePm!z
zaAEoaCMUSx5RsnlKgoZA%L=s(syoClia1^oal9bn_&`K*g6jtk20^L0$qN*ht1nVt
zp>jpb`l6D}6(yUCa<*6GY%dDfPT;&DCqIFE0{4#(Yz&+N*EwV^amcK2y}%)Jk;CW;
zhtUNNqZ|BU9ekLT0H`Pf6>Og`u|g_=VnO7ZHH8s9OM&{E$gQ*zP~wH=>2wCvBD9vN
zhN+f0g{c<YwyR;p-t|afUW3*t09P_d=0c5UU|>M4E?gKUFvX_CurM&xvemNJa@2By
z>_e_XYB;mtMH#A3To_^_YPo8d7a&zjxa=urtKq6)$p*DR7>YD%n6Xy?D4_!CL_&>2
z4;55*fC{Mvpkf268bP7@wU)UjvW7DYUOg`0L8wHqYLE(bRC{VT<KcQsK*bSM6SA48
zI#O7(!PR$>M-6ipyZ|pj@)=ZK1lf!fq%LO-b39z%1jalQ6mvlBRj3=PK-CeF-;m7!
z%b}Vh0E%Vgm?h3Xpk_e|E6BWBZj>~_jp}a~hFCFh${;RQ#F5P+&Lt_VAh%%H8ePkS
z5<-|EEsPw}H9UyM1ae5{DWRBxC!CQ@0EG*(DK*SQrplNa<^`ZmEHo|=6l(e{QmA3B
z<wbQrBsQ@7qJ}q}v4%Mw9tL@$B<MxT_3(VFT*JIT7~whutA@RXt%frTG-d-9M9D*F
zjhj5B8dl0pK~B4%p_*FO2~0g{HB1Xc!45zpP{Watp@s>2If|(+m_d`xuSz9aD^|g^
zs3^Zkp*$lqCsiRO6*9<brQlbZlcNA?&FFzUr*1_Sp!NVLLNvv0u@)3%=9LtIN{u2=
z(N|;zYA0}HmZTOH<(C&1*@D!%fyB5oi{ndDi*hsb5_4{Gf|@YN8JRgLMWCYf7JE@V
zga>MjfZH{YrV^+Oy2T1^a}<Hf=v#c5#qkA2sc?fhAlg#%Zt<mM=H$c|<QK<-I>^P~
zR?97(%)E@$qRbL-<42PZ(p2Klfsg5e#c#2Ie0PgCxwNP#HLoN-C$%g!=N4~%PD(tY
zRm2J6f@O+4L4E?|m?BW4s3-{RJFrxIW?o8a#Vx*+)Z*mSycCE@#YN5_6+$Jcxdrhk
zb`*o!%*ahBScjYq9QybhQ4l4OphgrIGpG^ufM4zd0~4q4T^_*;LKYW!EU)lbUf{93
z!6Ve+_LYr6Kx}Hx0;h}o>R0&HJ6LW=$aL^N5EJj<y&)vl!TEqg{5prqB@UGht`|5|
zE^=61;jp^EVRb{x^17DOB`v3mS}s?#Ts|<Ea;kg;5f^#XI$S2G%}`w+`hkr>R<XnP
zuDr^E&?WH~<xQ{1n|@$m;k5u06S!}PC|(!Qy(FT0QAGcWi2er#MnN~m4bcaDFPR2j
zFbxDtYhM!4UhB5i=77*e9hWOQE*C{yuZXx_5OIB=pnF}x^pb+<MFsOK3g#1dC-8n?
zV^CDPqF{Jk!Tgef`3{yV7M>RsysjvCb+}&Pk$uW9G{N+Wu*yY#)hqm}D+Dj`YhB>i
z`oP8@s&qv}eXY$U5%UWo<~OwTuV`8CaJ-^rH^KLci26kl^#@w!SF~)eI)q%*3b_y-
z18Q+*W?c!-zNnQASE8T-wq8kniTqaQ9jqXmO}ws{cwJQVK9P7)(SHKpQ)P`6au<~?
zt|(i8JZb|bCV1aaF}$u~c}d0cqKfqu73&GU6MUaa%FQiaV0uN_1QKK$5--Y|UzD`C
zB5Cn~fmP53OiXaRA)$IjLVIn^B?;>b64p2LjIZd~A7H$q=QM-&iiGwB3GD}Z)>rf#
zuewBB)Qh+fop2>O=R$7YmFWD7dih`_SgiiQ#vr12U0DB;u>M71!z;pu9~jsK?QdwB
zT@X=&h0Kn`oz7RZ9Kc?`q33Wx*Ac|jx*!4yOHI8i8kRd0cR21;zM=sM!4GT<f?`wn
z7ua4BFt{LKa6>@$x`56l0i6|L8$x!NUa|H$k#fZ^{-Qv_6@i2cU<A@3bzMN?l7Pkv
zu?->{O0SrEoKU&q6@5`4=88bf1%a3cQu1^3JA7}5DR+2wdOqObxy~VZi9_-thx8Q=
z=?fgvH!wx`g*&*x?N>idCh)*xks1R7Xy_g^2&u^hnq<gJ%uS7tzr__FpPQdjnge3<
z#K#wwCgwn7ia_Om5vW&Ogy?~RJ7nIVd=HvpDG~#*Ky?AQ&r`$;;(`cJN3FOQJo3`O
z0D&Kvm{>JGFu(~8MpjVLfDvpwtjZr4;Dih(tLz5`R6>lIRr&)1D#4|}D*k~1PJ}SJ
zGqQ?&V8Bj-0|e|yO@Uh~;F%dcP#-NPGfxjRGozQ7R9sS&m|PMM?wDofr5Ax(`?q9K
zm6n!d<`nCJyP1i3CB={qDY(oBmCWFBya?1&xTS!qFE>9W6{Zo=eFS%C(Om*nhE_Hg
zf!bHM<nfpYD!U=|4`|#A>`k=z`Nd%aiE6td(6AtAV5)c@0|UbcW=2NF8w}PLP|*#B
znhV6C8w@5FP|*zr`wOV(27}QBRP=y>vjGf0u!J))ihN+ePA-u82$uN*CNWikV-)}v
CX|}uo

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_relative.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_relative.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..58ce1fee263b5b20fbc8fe069e0ca2f9155706e4
GIT binary patch
literal 3289
zcmd1j<>g{vU|`^5UzDCJ$-wX!#6iX^3=9ko3=9m#DGUq@DGVu$ISjdsQH+crHd78$
zE^`!fE=v?kE^8EPE?X2ESe!YBJ(nYj1I%X0;mqZV;sUc-bGUPPqIke;wjAClUU!BR
z_7sj5h7^ue#%AUyz7)1#22IYFAp12LZ*e&~yXGb5r)1`(YqH!Dc8(8n^>GaG40DZl
z^>g-j@$_@Q#p4_w<nJF6@8js?>T^rPIo{dd&&|ivIV3*VHNY{*F~mOzq{h$R&lRFZ
zlkpb2bG%PtQfiJS<1Id)%)HdZqRgt)l#rs-R87WPY|il@mR~Z+4ak@Y77jWL3=F9Z
zQH&`JQA{a}DNHR4QOqgKDJ(4vQ7kE}DQqnaQLGSOMX{xD1~X`K-4b_>_e;zyOASiR
zNi4}MONIF=nHk9j5F2EPGbpeH7#J987;6~f8ETkn7~&aI7=jrz8T~YwZgCc;79<uW
zmgE=R;wjBbEUJvp%FoP8Ez)GZ#ZsJ_lUBsdz`#(%!@$6>lA(x?fq~&yh<-+XZmNDs
zVo7FVUZP%7PGU-CYLR|&er`d&ZhAq9Zf<@`YL0$!X+a`LG$l1BGfzJ?FS!^*#3$$H
z6_@Deft(*-1a-e&LFFxu`1s7c%#!$cQ1U4Tr4lwqF2*Va9A4FfDNklZ@-v7H!eBpx
z%t&DjX3%8vt5S9bS({l>nwnRl01i6^Sl}tZLJ#aaO~xW#kcUA&1q&4MGcYjRVvmn6
zE-8wS2MHI0LY0NFN*=e<z-p60>R^r&Wnf_7WME(byKE98C^oVfQW$F(vKUjCdYNjO
zN|+WfFJ!1?PGPQPDPc)rE@7=<YGzDfkzi<Ma$$&FU&~s<RKqICP|F6QQ&_|qBpGVi
zQ&?*`QkZKwOW11IYS_UlXT~tqa@BIzaMf^UGZ*bFVPC+J!j{5X!?BRLmZOGa0cQ&P
zLdFzkNrqaE8nzS;NrqaU8nzTpNrqb96oy*98r}t*AXhD9tmQ9Zt>Fi`A)BSBI-Q|b
zpoTw%A%&xrNs_^ZA(p3Buts13SB)UT#D$EE4220G-3z#D1Qs&Z^3}l2kN~-t7i2of
z{#v0FhFakg)*2zG`7`0}6au+zA#*KnjZg}UB*OyE6t0DgwZeJqa232D*%F=_&Ked8
zh8m6<z7pOVhAcjiz0GX3A~nnl_-lA-cx!}fL>96zGSqO^vM@5_@z!vbu-0(FeAmoq
z&QQx)!&S>ss8c9j!yL?@$?X@S$#jb^IX@>Sv7k6L9-JM(Nxuk`s9u7ITMSif(FVGf
zvD#Hk%E~YQ|NsC0<-h;`|NmmF(G<AFSCCke5nqxYpOczcmRbza%K=J2T&cMQC6)0d
zMX9N`Sc?+#(o=6S=cMM{Vy?<8xW!bIdW*TZH0c&=aY0UI$t||Tf`Zh%lv^yItXRYj
zN{^u249<$T*b`Gy;*0XjHATTG^_BoQM?sP{#C)!t)Wo!SkW-3pvF9X%1*3R#5{paX
z^Wu~9b93|aZZT%wVgsp&PlVD*x46M7pz@qBmBqIh6K^pl-C`-vFG{(^R*+v@l9+yr
z8yq(A$r*{6dA9_>_92UKK{z>?#U;1cQ*%;tQ}ar0@j&#(L;T2^mYP^ne2YCfJ_l5I
zLh>3YdqFZBTPmoeP89?dULFh#3<8WCj4VuIj2w(Sj4Vtnj6#eYOngjyj2z4yj4aGN
zAW=pEMlnVnCILn+W)?;sCLu-vMm{DfCIPT|5f(N^rUn+KDmh%a7GfbvrUls!3Vm><
zRbm2V+G36ph7`tTaD5fbP{LTkl+Mu1RLfMuRLh*gRLhdWP|KRaT+5ciP|IG!2+Gnf
z46*NHSZX<HIl<YIJ%u5gxk#&qdjU%gJ1E1{uoaoqaA&cmFl93qnWV7PaL2QPOe<jn
zi8eF3FvN=0^3*UdU|+~k>{`Q9!;;Nf<XgkMfTM)5gcD>t*c9dkT%h8k(7J{@i+cf2
z4MP_1LdF{Ic<vHDkO(-NF%?zSFlX_XaAq?V<%2|1m?Rk%2rOi%VUFj|;|9wKiZj4u
z#KGc7`dNxzf?Ni27fe)w0aO&#@|LjG@PggS26ijNEfY)FVCujH8OSdxwR~WEKyFwM
zvZ;no5^N8u{UA}e{mfaQVuC4~rRZo4%%2Num=_2yWGH%A!<;2l%MURL<Q9l&HT*Tq
z@j^BHE)21(wE{KFH3IP>g}3rJFw}8pv4TVNXAScL(HhPgkP0zy=z$6it{PTMQIP*@
zS!$STS!=j!*$bs>m==gHWME{dVG3r@Wc903iPnl$a4jmzFH$Ja$jnJqNJ)jXI;<4@
zN^^1)K!t!FxJU^p5@ujv(3H5vT2PdkS5gG3A&Nlt)-8_AlGLK2{PN;k+$H((iAlxz
zIi)43MOvV;Knhf#aAy|Bm!uZuX67a4+~Ne43CS6mIVnYKAW8P3cnD7uq+T9GfNJm}
zX^<o<IK$myD=IE2$}A{i1&MJ$l&9w1;>#?KFDOcd8_iabSOm(wd}*0EIq?Pg#qoLh
zDXGOp`XFsQnRywhMVTewB1TgXQXui?z#Bne@mnk)58vWVE-eC?6rYn?mYQ>mH$Nu@
zUK|zQ;skLaG8~!3@oAYw#U;16z$Fscxkb7lPw0UN6A)nwvYs2PAwDxNCAH!fUrK6m
za%x@*#QfqSHINGFlGNOScodtVA(NVSi!m9a)B(p-swb$_$zWh$U}555WC52apfU%9
zMVL64xET4E*%(=v`4|Nl1sJ&)1(^AmxEO^P#hCb*SQtf^c^J7E#TdC5`M@F^j7$w2
z%xsJTjBJb?j2w(i{{@)2n8g@HnAn(D7}=OOm{=Hbmr4)^`DwC)8c2DGxvBB-x47ct
zbMsS5b3kmK`1r!o#2koB5vZA01S++P%s_$U4<f*2DuMttXNo{=EKpi21~E7oI2but
zIGA}Xz~Y+xw^YDwH@##~J1#R%57c(kOH3**DN0N(i3gXHnR)3&pytgjSyZK^C7C(J
zdf*x<F|VY!2wZJ}5;QoOK@z6|supl-5vm7T7l6uKbVopyp{1=N4p1!1<1rDG_8|F6
n78DvF4<p4oI9xzMa*M+T5~g;bTD}-0&ch(V$ODEPOd?DG%57q<

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_relative.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_const/__pycache__/naive_relative.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b42a4c47d2c9a3e7745917396a876bf0af990d50
GIT binary patch
literal 6884
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
Dg$pZZ

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_const/naive_absolute.py b/tania_scripts/supar/codelin/encs/enc_const/naive_absolute.py
new file mode 100644
index 0000000..5dbb984
--- /dev/null
+++ b/tania_scripts/supar/codelin/encs/enc_const/naive_absolute.py
@@ -0,0 +1,144 @@
+from supar.codelin.encs.abstract_encoding import ACEncoding
+from supar.codelin.utils.constants import C_ABSOLUTE_ENCODING, C_ROOT_LABEL, C_CONFLICT_SEPARATOR, C_NONE_LABEL
+from supar.codelin.models.const_label import C_Label
+from supar.codelin.models.linearized_tree import LinearizedTree
+from supar.codelin.models.const_tree import C_Tree
+
+import re
+
+class C_NaiveAbsoluteEncoding(ACEncoding):
+    def __init__(self, separator, unary_joiner):
+        self.separator = separator
+        self.unary_joiner = unary_joiner
+
+    def __str__(self):
+        return "Constituent Naive Absolute Encoding"
+
+    def encode(self, constituent_tree):        
+        lc_tree = LinearizedTree.empty_tree()
+        leaf_paths = constituent_tree.path_to_leaves(collapse_unary=True, unary_joiner=self.unary_joiner)
+        
+        for i in range(0, len(leaf_paths)-1):
+            path_a = leaf_paths[i]
+            path_b = leaf_paths[i+1]
+            
+            last_common = ""
+            n_commons   = 0
+            for a,b in zip(path_a, path_b):
+
+                if (a!=b):
+                    # Remove the digits and aditional feats in the last common node
+                    last_common = re.sub(r'[0-9]+', '', last_common)
+                    last_common = last_common.split("##")[0]
+
+                    # Get word and POS tag
+                    word = path_a[-1]
+                    postag = path_a[-2]
+                    
+                    # Build the Leaf Unary Chain
+                    unary_chain = None
+                    leaf_unary_chain = postag.split(self.unary_joiner)
+                    if len(leaf_unary_chain)>1:
+                        unary_list = []
+                        for element in leaf_unary_chain[:-1]:
+                            unary_list.append(element.split("##")[0])
+
+                        unary_chain = self.unary_joiner.join(unary_list)
+                        postag = leaf_unary_chain[len(leaf_unary_chain)-1]
+                    
+                    # Clean the POS Tag and extract additional features
+                    postag_split = postag.split("##")
+                    feats = [None]
+
+                    if len(postag_split) > 1:
+                        postag = re.sub(r'[0-9]+', '', postag_split[0])
+                        feats = postag_split[1].split("|")
+                    else:
+                        postag = re.sub(r'[0-9]+', '', postag)
+
+                    c_label= C_Label(n_commons, last_common, unary_chain, C_ABSOLUTE_ENCODING, 
+                                                   self.separator, self.unary_joiner)
+                    
+                    # Append the data
+                    lc_tree.add_row(word, postag, feats, c_label)
+                
+                    break
+                
+                n_commons  += len(a.split(self.unary_joiner))
+                last_common = a
+            
+        # n = max number of features of the tree
+        lc_tree.n = max([len(f) for f in lc_tree.additional_feats])
+        return lc_tree
+
+    def decode(self, linearized_tree):
+        # Check valid labels
+        if not linearized_tree:
+            print("[!] Error while decoding: Null tree.")
+            return
+
+        # Create constituent tree
+        tree = C_Tree(C_ROOT_LABEL, [])
+        current_level = tree
+
+        old_n_commons = 0
+        old_level = None
+        for word, postag, feats, label in linearized_tree.iterrows():
+
+            # Descend through the tree until reach the level indicated by last_common
+            current_level = tree
+            for level_index in range(label.n_commons):
+                if (current_level.is_terminal()) or (level_index >= old_n_commons):
+                    current_level.add_child(C_Tree(C_NONE_LABEL, []))
+                
+                current_level = current_level.r_child()
+
+            # Split the Last Common field of the Label in case it has a Unary Chain Collapsed
+            label.last_common = label.last_common.split(self.unary_joiner)
+
+            if len(label.last_common) == 1:
+                # If current level has no label yet, put the label
+                # If current level has label but different than this one, set it as a conflict
+                if (current_level.label == C_NONE_LABEL):
+                    current_level.label = label.last_common[0].rstrip()
+                else:
+                    current_level.label = current_level.label + C_CONFLICT_SEPARATOR + label.last_common[0]
+            if len(label.last_common)>1:
+                current_level = tree
+                
+                # problem when n_commons predicted is LESS than the number of last commons predicted
+                descend_levels = label.n_commons - (len(label.last_common)) + 1
+                for level_index in range(descend_levels):
+                    current_level = current_level.r_child()
+                for i in range(len(label.last_common)-1):
+                    if (current_level.label == C_NONE_LABEL):
+                        current_level.label = label.last_common[i]
+                    else:
+                        current_level.label = current_level.label+C_CONFLICT_SEPARATOR+label.last_common[i]
+
+                    if len(current_level.children)>0:
+                        current_level = current_level.r_child()
+
+                # If we reach a POS tag, set it as child of the current chain
+                if current_level.is_preterminal():
+                    temp_current_level_children = current_level.children
+                    current_level.label = label.last_common[i+1]
+                    current_level.children = temp_current_level_children
+                    for c in temp_current_level_children:
+                        c.parent = current_level
+                else:
+                    current_level.label=label.last_common[i+1]
+            
+            
+            # Fill POS tag in this node or previous one
+            if (label.n_commons >= old_n_commons):
+                current_level.fill_pos_nodes(postag, word, label.unary_chain, self.unary_joiner)
+            else:
+                old_level.fill_pos_nodes(postag, word, label.unary_chain, self.unary_joiner)
+
+            old_n_commons=label.n_commons
+            old_level=current_level
+
+        tree.inherit_tree()
+        
+        return tree
\ No newline at end of file
diff --git a/tania_scripts/supar/codelin/encs/enc_const/naive_dynamic.py b/tania_scripts/supar/codelin/encs/enc_const/naive_dynamic.py
new file mode 100644
index 0000000..c4dc11f
--- /dev/null
+++ b/tania_scripts/supar/codelin/encs/enc_const/naive_dynamic.py
@@ -0,0 +1,166 @@
+from supar.codelin.encs.abstract_encoding import ACEncoding
+from supar.codelin.utils.constants import C_ABSOLUTE_ENCODING, C_RELATIVE_ENCODING, C_ROOT_LABEL, C_CONFLICT_SEPARATOR, C_NONE_LABEL
+from supar.codelin.models.const_label import C_Label
+from supar.codelin.models.linearized_tree import LinearizedTree
+from supar.codelin.models.const_tree import C_Tree
+
+import re
+
+class C_NaiveDynamicEncoding(ACEncoding):
+    def __init__(self, separator, unary_joiner):
+        self.separator = separator
+        self.unary_joiner = unary_joiner
+
+    def __str__(self):
+        return "Constituent Naive Dynamic Encoding"
+
+    def encode(self, constituent_tree):
+        lc_tree = LinearizedTree.empty_tree()
+        leaf_paths = constituent_tree.path_to_leaves(collapse_unary=True, unary_joiner=self.unary_joiner)
+
+        last_n_common=0
+        for i in range(0, len(leaf_paths)-1):
+            path_a=leaf_paths[i]
+            path_b=leaf_paths[i+1]
+            
+            last_common=""
+            n_commons=0
+            for a,b in zip(path_a, path_b):
+
+                if (a!=b):
+                    # Remove the digits and aditional feats in the last common node
+                    last_common = re.sub(r'[0-9]+', '', last_common)
+                    last_common = last_common.split("##")[0]
+
+                    # Get word and POS tag
+                    word = path_a[-1]
+                    postag = path_a[-2]
+                    
+                    # Build the Leaf Unary Chain
+                    unary_chain = None
+                    leaf_unary_chain = postag.split(self.unary_joiner)
+                    if len(leaf_unary_chain)>1:
+                        unary_list = []
+                        for element in leaf_unary_chain[:-1]:
+                            unary_list.append(element.split("##")[0])
+
+                        unary_chain = self.unary_joiner.join(unary_list)
+                        postag = leaf_unary_chain[len(leaf_unary_chain)-1]
+                    
+                    # Clean the POS Tag and extract additional features
+                    postag_split = postag.split("##")
+                    feats = [None]
+
+                    if len(postag_split) > 1:
+                        postag = re.sub(r'[0-9]+', '', postag_split[0])
+                        feats = postag_split[1].split("|")
+                    else:
+                        postag = re.sub(r'[0-9]+', '', postag)
+
+                    # Compute the encoded value
+                    abs_val=n_commons
+                    rel_val=(n_commons-last_n_common)
+
+                    if (abs_val<=3 and rel_val<=-2):
+                        c_label = (C_Label(abs_val, last_common, unary_chain, C_ABSOLUTE_ENCODING, self.separator, self.unary_joiner))
+                    else:
+                        c_label = (C_Label(rel_val, last_common, unary_chain, C_RELATIVE_ENCODING, self.separator, self.unary_joiner))
+                    
+                    lc_tree.add_row(word, postag, feats, c_label)
+
+                    last_n_common=n_commons
+                    break
+                
+                # Store Last Common and increase n_commons 
+                # Note: When increasing n_commons use the number from split the collapsed chains
+                n_commons += len(a.split(self.unary_joiner))
+                last_common = a
+        
+        # n = max number of features of the tree
+        lc_tree.n = max([len(f) for f in lc_tree.additional_feats])
+        return lc_tree
+
+    def decode(self, linearized_tree):
+        # Check valid labels 
+        if not linearized_tree:
+            print("[*] Error while decoding: Null tree.")
+            return
+        
+        # Create constituent tree
+        tree = C_Tree(C_ROOT_LABEL, [])
+        current_level = tree
+
+        old_n_commons=0
+        old_last_common=''
+        old_level=None
+        is_first = True
+        last_label = None
+
+        for word, postag, feats, label in linearized_tree.iterrows():
+            
+            # Convert the labels to absolute scale
+            if last_label!=None and label.encoding_type==C_RELATIVE_ENCODING:
+                label.to_absolute(last_label)
+            
+            # First label must have a positive n_commons value
+            if is_first and label.n_commons <= 0:
+                label.n_commons = 1
+
+            # Descend through the tree until reach the level indicated by last_common
+            current_level = tree
+            for level_index in range(label.n_commons):
+                if (len(current_level.children)==0) or (level_index >= old_n_commons):
+                    current_level.add_child(C_Tree(C_NONE_LABEL, []))
+                
+                current_level = current_level.r_child()
+
+            # Split the Last Common field of the Label in case it has a Unary Chain Collapsed
+            label.last_common = label.last_common.split(self.unary_joiner)
+
+            if len(label.last_common)==1:
+                # If current level has no label yet, put the label
+                # If current level has label but different than this one, set it as a conflict
+                if (current_level.label==C_NONE_LABEL):
+                    current_level.label = label.last_common[0].rstrip()
+                else:
+                    current_level.label = current_level.label + C_CONFLICT_SEPARATOR + label.last_common[0]
+            if len(label.last_common)>1:
+                current_level = tree
+                
+                # problem when n_commons predicted is LESS than the number of last commons predicted
+                descend_levels = label.n_commons - (len(label.last_common)) + 1
+                for level_index in range(descend_levels):
+                    current_level = current_level.r_child()
+                for i in range(len(label.last_common)-1):
+                    if (current_level.label == C_NONE_LABEL):
+                        current_level.label = label.last_common[i]
+                    else:
+                        current_level.label = current_level.label+C_CONFLICT_SEPARATOR+label.last_common[i]
+
+                    if len(current_level.children)>0:
+                        current_level = current_level.r_child()
+
+                # If we reach a POS tag, set it as child of the current chain
+                if current_level.is_preterminal():
+                    temp_current_level_children = current_level.children
+                    current_level.label = label.last_common[i+1]
+                    current_level.children = temp_current_level_children
+                    for c in temp_current_level_children:
+                        c.parent = current_level
+                else:
+                    current_level.label=label.last_common[i+1]
+            
+            
+            # Fill POS tag in this node or previous one
+            if (label.n_commons >= old_n_commons):
+                current_level.fill_pos_nodes(postag, word, label.unary_chain, self.unary_joiner)
+            else:
+                old_level.fill_pos_nodes(postag, word, label.unary_chain, self.unary_joiner)
+
+            old_n_commons=label.n_commons
+            old_level=current_level
+            last_label=label
+        
+        tree.inherit_tree()
+        
+        return tree
\ No newline at end of file
diff --git a/tania_scripts/supar/codelin/encs/enc_const/naive_incremental.py b/tania_scripts/supar/codelin/encs/enc_const/naive_incremental.py
new file mode 100644
index 0000000..8ceb06b
--- /dev/null
+++ b/tania_scripts/supar/codelin/encs/enc_const/naive_incremental.py
@@ -0,0 +1,160 @@
+from supar.codelin.encs.abstract_encoding import ACEncoding
+from supar.codelin.utils.constants import C_ABSOLUTE_ENCODING, C_ROOT_LABEL, C_CONFLICT_SEPARATOR, C_NONE_LABEL, C_DUMMY_END
+from supar.codelin.models.const_label import C_Label
+from supar.codelin.models.linearized_tree import LinearizedTree
+from supar.codelin.models.const_tree import C_Tree
+
+import re
+
+class C_NaiveIncrementalEncoding(ACEncoding):
+    def __init__(self, separator, unary_joiner):
+        self.separator = separator
+        self.unary_joiner = unary_joiner
+
+    def __str__(self):
+        return "Constituent Naive Incremental Encoding"
+
+    def get_unary_chain(self, postag):
+        unary_chain = None
+        leaf_unary_chain = postag.split(self.unary_joiner)
+
+        if len(leaf_unary_chain)>1:
+            unary_list = []
+            for element in leaf_unary_chain[:-1]:
+                unary_list.append(element.split("##")[0])
+
+            unary_chain = self.unary_joiner.join(unary_list)
+            postag = leaf_unary_chain[len(leaf_unary_chain)-1]
+        
+        return unary_chain, postag
+    
+    def get_features(self, node, feature_marker="##", feature_splitter="|"):
+        postag_split = node.split(feature_marker)
+        feats = None
+
+        if len(postag_split) > 1:
+            postag = re.sub(r'[0-9]+', '', postag_split[0])
+            feats = postag_split[1].split(feature_splitter)
+        else:
+            postag = re.sub(r'[0-9]+', '', node)
+        return postag, feats
+    
+    def clean_last_common(self, node, feature_marker="##"):
+        node = re.sub(r'[0-9]+', '', node)
+        last_common = node.split(feature_marker)[0]
+        return last_common
+
+    def encode(self, constituent_tree):
+        constituent_tree.reverse_tree()
+        leaf_paths = constituent_tree.path_to_leaves(collapse_unary=True, unary_joiner=self.unary_joiner)
+        lc_tree = LinearizedTree.empty_tree()
+
+        for i in range(1, len(leaf_paths)):
+            path_a = leaf_paths[i-1]
+            path_b = leaf_paths[i]
+            
+            last_common = ""
+            n_commons   = 0
+
+            for a,b in zip(path_a, path_b):
+                if (a!=b):
+                    # Remove the digits and aditional feats in the last common node
+                    last_common = self.clean_last_common(last_common)
+
+                    # Get word and POS tag
+                    word   = path_a[-1]
+                    postag = path_a[-2]
+                    
+                    # Build the Leaf Unary Chain
+                    unary_chain, postag = self.get_unary_chain(postag)
+                    
+                    # Clean the POS Tag and extract additional features
+                    postag, feats = self.get_features(postag)
+
+                    # Append the data
+                    c_label = (C_Label(n_commons, last_common, unary_chain, C_ABSOLUTE_ENCODING, self.separator, self.unary_joiner))
+                    lc_tree.add_row(word, postag, feats, c_label)
+
+                    break
+                
+                # Store Last Common and increase n_commons 
+                # Note: When increasing n_commons use the number from split the collapsed chains
+                n_commons  += len(a.split(self.unary_joiner))
+                last_common = a
+        
+        # reverse and return
+        lc_tree.reverse_tree(ignore_bos_eos=False)
+        return lc_tree
+
+    def decode(self, linearized_tree):
+        # Check valid labels 
+        if not linearized_tree:
+            print("[*] Error while decoding: Null tree.")
+            return
+
+        # Create constituent tree
+        tree = C_Tree(C_ROOT_LABEL, [])
+        current_level = tree
+
+        old_n_commons=0
+        old_level=None
+
+        linearized_tree.reverse_tree(ignore_bos_eos=False)
+        for word, postag, feats, label in linearized_tree.iterrows():
+            
+            # Descend through the tree until reach the level indicated by last_common
+            current_level = tree
+            for level_index in range(label.n_commons):
+                if (current_level.is_terminal()) or (level_index >= old_n_commons):
+                    current_level.add_child(C_Tree(C_NONE_LABEL, []))
+                
+                current_level = current_level.r_child()
+
+            # Split the Last Common field of the Label in case it has a Unary Chain Collapsed
+            label.last_common = label.last_common.split(self.unary_joiner)
+
+            if len(label.last_common) == 1:
+                # If current level has no label yet, put the label
+                # If current level has label but different than this one, set it as a conflict
+                if (current_level.label == C_NONE_LABEL):
+                    current_level.label = label.last_common[0]
+                else:
+                    current_level.label = current_level.label + C_CONFLICT_SEPARATOR + label.last_common[0]
+            else:
+                current_level = tree
+                
+                # Descend to the beginning of the Unary Chain and fill it
+                descend_levels = label.n_commons - (len(label.last_common)) + 1
+                
+                for level_index in range(descend_levels):
+                    current_level = current_level.r_child()
+                
+                for i in range(len(label.last_common)-1):
+                    if (current_level.label == C_NONE_LABEL):
+                        current_level.label = label.last_common[i]
+                    else:
+                        current_level.label = current_level.label + C_CONFLICT_SEPARATOR + label.last_common[i]
+                    current_level = current_level.r_child()
+
+                # If we reach a POS tag, set it as child of the current chain
+                if current_level.is_preterminal():
+                    temp_current_level = current_level
+                    current_level.label = label.last_common[i+1]
+                    current_level.children = [temp_current_level]
+                
+                else:
+                    current_level.label=label.last_common[i+1]
+            
+            # Fill POS tag in this node or previous one
+            if (label.n_commons >= old_n_commons):
+                current_level.fill_pos_nodes(postag, word, label.unary_chain, self.unary_joiner)
+            
+            else:
+                old_level.fill_pos_nodes(postag, word, label.unary_chain, self.unary_joiner)
+
+            old_n_commons=label.n_commons
+            old_level=current_level
+
+        tree.inherit_tree()
+        tree.reverse_tree()
+        return tree
\ No newline at end of file
diff --git a/tania_scripts/supar/codelin/encs/enc_const/naive_relative.py b/tania_scripts/supar/codelin/encs/enc_const/naive_relative.py
new file mode 100644
index 0000000..0794e3b
--- /dev/null
+++ b/tania_scripts/supar/codelin/encs/enc_const/naive_relative.py
@@ -0,0 +1,152 @@
+from supar.codelin.encs.abstract_encoding import ACEncoding
+from supar.codelin.utils.constants import C_RELATIVE_ENCODING, C_ROOT_LABEL, C_CONFLICT_SEPARATOR, C_NONE_LABEL
+from supar.codelin.models.const_label import C_Label
+from supar.codelin.models.linearized_tree import LinearizedTree
+from supar.codelin.models.const_tree import C_Tree
+
+import re
+
+class C_NaiveRelativeEncoding(ACEncoding):
+    def __init__(self, separator, unary_joiner):
+        self.separator = separator
+        self.unary_joiner = unary_joiner
+
+    def __str__(self):
+        return "Constituent Naive Relative Encoding"
+
+    def encode(self, constituent_tree):
+        leaf_paths = constituent_tree.path_to_leaves(collapse_unary=True, unary_joiner=self.unary_joiner)
+        lc_tree = LinearizedTree.empty_tree()
+
+        last_n_common=0
+        for i in range(0, len(leaf_paths)-1):
+            path_a=leaf_paths[i]
+            path_b=leaf_paths[i+1]
+            
+            last_common=""
+            n_commons=0
+            for a,b in zip(path_a, path_b):
+
+                if (a!=b):
+                    # Remove the digits and aditional feats in the last common node
+                    last_common = re.sub(r'[0-9]+', '', last_common)
+                    last_common = last_common.split("##")[0]
+
+                    # Get word and POS tag
+                    word = path_a[-1]
+                    postag = path_a[-2]
+                    
+                    # Build the Leaf Unary Chain
+                    unary_chain = None
+                    leaf_unary_chain = postag.split(self.unary_joiner)
+                    if len(leaf_unary_chain)>1:
+                        unary_list = []
+                        for element in leaf_unary_chain[:-1]:
+                            unary_list.append(element.split("##")[0])
+
+                        unary_chain = self.unary_joiner.join(unary_list)
+                        postag = leaf_unary_chain[len(leaf_unary_chain)-1]
+                    
+                    # Clean the POS Tag and extract additional features
+                    postag_split = postag.split("##")
+                    feats = None
+
+                    if len(postag_split) > 1:
+                        postag = re.sub(r'[0-9]+', '', postag_split[0])
+                        feats = postag_split[1].split("|")
+                    else:
+                        postag = re.sub(r'[0-9]+', '', postag)
+
+                    c_label = C_Label((n_commons-last_n_common), last_common, unary_chain, C_RELATIVE_ENCODING, self.separator, self.unary_joiner)
+                    lc_tree.add_row(word, postag, feats, c_label)
+
+                    last_n_common=n_commons
+                    break
+                
+                # Store Last Common and increase n_commons 
+                # Note: When increasing n_commons use the number from split the collapsed chains
+                n_commons += len(a.split(self.unary_joiner))
+                last_common = a
+        
+        return lc_tree
+
+    def decode(self, linearized_tree):
+        # Check valid labels 
+        if not linearized_tree:
+            print("[*] Error while decoding: Null tree.")
+            return
+        
+        # Create constituent tree
+        tree = C_Tree(C_ROOT_LABEL, [])
+        current_level = tree
+
+        old_n_commons=0
+        old_level=None
+
+        is_first = True
+        last_label = None
+
+        for word, postag, feats, label in linearized_tree.iterrows():
+            # Convert the labels to absolute scale
+            if last_label!=None:
+                label.to_absolute(last_label)
+            
+            # First label must have a positive n_commons value
+            if is_first and label.n_commons <= 0:
+                label.n_commons = 1
+            
+            # Descend through the tree until reach the level indicated by last_common
+            current_level = tree
+            for level_index in range(label.n_commons):
+                if (current_level.is_terminal()) or (level_index >= old_n_commons):
+                    current_level.add_child(C_Tree(C_NONE_LABEL, []))
+                current_level = current_level.r_child()
+            
+            # Split the Last Common field of the Label in case it has a Unary Chain Collapsed
+            label.last_common = label.last_common.split(self.unary_joiner)            
+
+            if len(label.last_common)==1:
+                if (current_level.label==C_NONE_LABEL):
+                    current_level.label=label.last_common[0].rstrip()
+                else:
+                    current_level.label = current_level.label + C_CONFLICT_SEPARATOR + label.last_common[0]
+            
+            if len(label.last_common)>1:
+                current_level = tree
+                
+                # problem when n_commons predicted is LESS than the number of last commons predicted
+                descend_levels = label.n_commons - (len(label.last_common)) + 1
+                for level_index in range(descend_levels):
+                    current_level = current_level.r_child()
+                for i in range(len(label.last_common)-1):
+                    if (current_level.label == C_NONE_LABEL):
+                        current_level.label = label.last_common[i]
+                    else:
+                        current_level.label = current_level.label+C_CONFLICT_SEPARATOR+label.last_common[i]
+
+                    if len(current_level.children)>0:
+                        current_level = current_level.r_child()
+
+                # If we reach a POS tag, set it as child of the current chain
+                if current_level.is_preterminal():
+                    temp_current_level_children = current_level.children
+                    current_level.label = label.last_common[i+1]
+                    current_level.children = temp_current_level_children
+                    for c in temp_current_level_children:
+                        c.parent = current_level
+                else:
+                    current_level.label=label.last_common[i+1]
+            
+            # Fill POS tag in this node or previous one
+            if (label.n_commons >= old_n_commons):
+                current_level.fill_pos_nodes(postag, word, label.unary_chain, self.unary_joiner)
+            else:
+                old_level.fill_pos_nodes(postag, word, label.unary_chain, self.unary_joiner)
+
+            old_n_commons=label.n_commons
+            old_level=current_level
+            
+            last_label=label
+        
+        tree.inherit_tree()
+        return tree
\ No newline at end of file
diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__init__.py b/tania_scripts/supar/codelin/encs/enc_deps/__init__.py
new file mode 100644
index 0000000..1dd652c
--- /dev/null
+++ b/tania_scripts/supar/codelin/encs/enc_deps/__init__.py
@@ -0,0 +1,6 @@
+## Dependency Encodings Package
+from .naive_absolute import D_NaiveAbsoluteEncoding
+from .naive_relative import D_NaiveRelativeEncoding
+from .brk_based import D_BrkBasedEncoding
+from .pos_based import D_PosBasedEncoding
+from .brk2p_based import D_Brk2PBasedEncoding
\ No newline at end of file
diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d5d526f8782acc6ddb352bc54ce8ef508f64fe80
GIT binary patch
literal 454
zcmd1j<>g{vU|`^5UzE<t$iVOz#6iYP3=9ko3=9m#AR>h!g)xUAmobWwks*a4g(-(A
zmpO_V%x2DE$z_dV1+!Ul*mBvU*uiYp9FAPhC{9L(6t-XnP4<_J3=9mKjJL#H;{6gc
z%TgVait}?yOHy6)lJiqC^U{%|f>Lu5OESxlrG#AKor<!Z5{pw)kTeLn#0TUTql=1w
z)fxq$i2G@BMe*f<ERIiv+FS(kAxy9cYG)BM0|P@8XHrpid=kjEA{H>eAio&OX9e-O
zlZvv93ZNov3=9k_8H(5$7$C$iU;T{y+*JLN#FEU!yhOdEoWzvO)FS=l{M>?k-SmPI
z-Q4_?)Excd(t<>gXi92MW}bd(UUD&rh)+o^DAtdU&&<m#iI3MSsJz8tlbfGXnv-e=
P3c+Gfr13C9pa3HPs4;w&

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..8ce46dfd865d40f78b478a5a314786080bc9266c
GIT binary patch
literal 562
zcmZ3^%ge>Uz`&q*Up0f1k%8echy%k+P{wB`1_p-d3@HpLj5!Rsj8Tk?AU0DDQ!aB9
zGnmbs!;;Gy#R_J#<gn$kN3nz1tT`OHoKc*N3@L2E44UjO85tNDG#PJ+yTtn?W|pNo
zCKc!Bl$NBr<|XH+WagzKNd=|mB$i~BAxjCl#5)ybJ0%vUrXXn$a)}SfFGd#?0jo6%
zKoR%T<hsR|2eLRm5o&W0GXnzyOt1)QXAuiXkTa<$J3a|yTM;XmUyxr6<+FkK+(|{*
zMg>q2b_NE9l?<Oj0ro3eKO;XkRlg*$Br`EDQ7<VcF(os#NIyA0w;*4)B(<VMH?=G=
zN53R7FEcT|IJqdZprly8xU?V<q$VXbCo@k!H7~gsM8v1078L8p$7kkcmc+;F6;%G>
zu*uC&Da}c>D-vK}U;u?@aVi4?!v|(YM#cvW#urf04OH$02ICtHnio(JHWA$m3|LSR
I9|Hpe07RjvbN~PV

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk2p_based.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk2p_based.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..50aeb39bab298e183c8d9afec05cac65fb3f9a5e
GIT binary patch
literal 4874
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk2p_based.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk2p_based.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..dbbe00aafec12095b89292d53a158512e1969458
GIT binary patch
literal 9802
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk_based.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk_based.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..08db178e6917bb38a99b0d745ffe3f08121eeeec
GIT binary patch
literal 2420
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
Zj5ur{p=k#ycZ)$~B@Y7+BLs>t0RYHxX?6er

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk_based.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/brk_based.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..20c2dea9b223e0a9c2a7ac3e40c647b6abc9ca0a
GIT binary patch
literal 4630
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
BMHc`7

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_absolute.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_absolute.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3d7369766076aec1dad859894574c0db23c85e29
GIT binary patch
literal 1873
zcmd1j<>g{vU|`^5Uz9$Lm4V?gh=Yt-7#J8F7#J9e0~i<>QW#Pga~N_NqZk=MY^EHh
zT;?cdFq=7tC6_gd70hPIVasKYVh6KXb2xH2qc|BE+!<2XQrKG<QrJ@&o0+4yQaFMc
zG&x^_?9ybs#pUSYnwOlPl9`vT$#{$1CEh17DK$rv@fM#?W?pJyQD#+YN=Q*^swU$t
zHkWuPi^nD2&)?5A-pA3&)h8Kb5;A6na*9nD7#LC+q8L*cqL|tl(il@1Q<z#fqL@>d
zQ&?IUqF7Q`Q`lM<qF7VdQ#e`}qS)FQSQw(%L9V+c?h@~pm|2$Um{gpfQ(BS=b7L|S
z)Nl|5VuLIL;bH*>28I%bW`+ffHH-_v!4%A}lF?6-=@x5oX+dhyEsps3%)HE!_;^jG
zTP($?Icc{zi&F~{ixNxni&iq;;*5_^&PgmTj*nl-@GDq9BR@A)za+6FGchkwFDWN6
zB{Q{1KRG|QAYV7VphPz}KP5Fszqqs@5hR+Dnv<EQpPH9k3?kxFQVWXp^FYpzPlUQ(
zub{FB6yF@67zMdofU!yehadG|4ozkR`4WmjY!G$^nE*;0DU87knoNFGN-n7dsd*`>
zdC8Ru;4o8w1)2gZ)Qb2S7#K7ei?|sW7{F`@0SdBP?D6r%B}MV^Ah}|Y%UBqz<Z-(U
ztQI8}*cliYKp5<>C<X?GbcR}{8pZ_-3mF(0Y8YJ@Vnu41YnZbbYguZTvzTgGOPFg|
zYglR+vRIm#YuRd;7O>W^fnuzXqlB%7aRK{6h8o5N9AJ`jAwvyQ30DnMGh;JrFhdb2
z_%yk1@f4-z=9i_$r<CUAR^H+$O3g_u$;{8Y#gdVlm{J5v4n;f+3=Fr}5(_{<Qv?dG
zTb${sCGq9?MJdHm+#qH_esM`+dT|t3JS{b`r1%zdPHLVeJ2;qbaipXc#FrGMrrzR9
z1!a)bl=vJ_)+oNkl9!*7dW$J1^A=M@<}LQ*(xRf&yb?%|f&#h-9Ik8-U3{SE0tv7%
zaxii*u`#kS@-gu+Dlk>a;R<AkMwBoH`J0V_fdL%G9pIF{fU$(BhOwD3g;AVgA!995
z3S%vE4dVjlg$ynXv3fBqwJf!)wQRNQHSAd|C9K&@MY1VOHSF;$HB1ZGYM5(S7BVq1
z)G#ezuVJoXg|aznm}}UxIH5eQ8s-viknUziun2Psqd7w@b0L2X(*hoF+%g3-Xfpe~
z1f|L%5TVIi#LB?H5XF_6TToI74!k09P&{yCmZTOH<(C&1$$(NI$R|<Ur3ER8C8^*T
zfpba=@{6PRp)#;&Es_Qq3R4e?;#<s_c_l?cphV39j;$z;oXk9kg%ThO88dIOfTH>q
z8zh!*aeyMYv?#Us7ArUwF=8tvH90>e6=YK}$OIuq7A6r!E=D#+9wr_}K1Lx%E=CR}
z7Dn8$1~EXB160oBCFZ8a$KT?LkI&6dDa`?~dE(;>OA~V-GT@@1NDvejav(w-<Yr!I
z0hFAYlM^40<Un4K5>OH<0%bE0E`}5(Jd7O79Lxf|U~xZ9?kE*-fuslWNls>-9;iUl
zOH3**DN0N(i3caE%)Im>P$rL(M^y?g&x-XxB^M-_gL4tOflyUB@R|V<<e=;oC5PKU
zP%Z+ej9ap(ib_i|bBgtn^Ye;J67x!mi$Dnj>=`8ABXSgn4J0(}KxwTQl)-rzco-p2
Ggb4tX^WjYZ

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_absolute.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_absolute.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7c239f14078cb1d2da6df29f582713a3c14d788e
GIT binary patch
literal 3173
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
L0TF2O;0OT#0&eUt

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_relative.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_relative.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..bda4d2e8d01c87252607b4b5da3424fdb7ff31f0
GIT binary patch
literal 1960
zcmd1j<>g{vU|`^5UzDE1#=!6x#6iX^3=9ko3=9m#0SpWbDGVu$ISjdsQH+crHd78$
zE^`z!n9ZESlFJ&!3TCt9u;sExv4h#HIUKp1QJjnn?hGkxDeNr_DeS3?&CF3;DICEJ
znw&2|c4;!+;&OCx%}dTt$;?aFWW2@h67Q3kl$xW-c#F>`GcPr<D6=XxC8Q`dRg>`+
zn@c>D#p4q1=kMnl@8js?>XQsI2^lj(ImIRn3=F9ZQH&`JQB3U&X^bh1DNHRKQOqgK
zDJ(4vQ7kE}DQqnaQLHKKDI6^fQEcrDEDTZXAlKazcZv5)%q&X{O3g_u$t+8SxiJ}L
zILHnV8-|O;7#J8z7@8RtFxD_GWMpKhVX9$>XG&oRX3%8x(`3HIT3lL?T6BveK0Y%q
zvm`$L7IQ{gktXvkmg3Z$v|F6TsRfBei6!|(xA-y=^U~wfit=;gi}LeJRx;k=jE_&w
zNh~gok6+2~D_B1xKQ~psB(WqjF)vXsDJL-{Gqp%RIX|}`UpKv=L^n4-B{fICxU?V<
zB$|?%lbNTVnwMM*BH~k03ySsgKt78vf_hD_pt6XQfq{Vo6xpCy=V9bxtWv-c0D3U@
zCo_VA0E$6u5O#){k-`|vpvmM{rR0)YkeZj0nwMOu01i+EScodXg0x70fq_Ajv51?2
zfdR~h5P}R047b?h<BLm*;^TQh<}xubFt9LI$>VkzSZy*$9n@V6><kQG40c!n0|P@k
zLoHJc;{t|-42%plj4lkZ^0mx0%vp@JEH%svm=-eBvVwRijM+>@(lrcO%tg{AEVZm9
ztTn7PEHw;SY|YHIY&A>^*lXB8kzB}8!coJxfO8>34dVhXFv-1;p@yl1r-rGSv6&Sd
z2)9^3@u<mri>D|xH@_@3KBY7_xAGPTBm(mDZgHig=9DDHXQU>k6oE2j5gRBdKq;#T
z<ndc<i3OlQECNN&Ezb1RlKArcqLkuW+#qH_esM`+dND*iEj6*E_!e_cYMv%LI6!Z4
zq@)(amlUO@-r`FI<+Ie3_#99UE55~&m!Fb)izz4b7E?v$E%xNnqN3Ei5=h{KqNE5M
z18fjo{GbRB0Y?A_BL^cJBL|}Z6AL3B6Az;TQ<WU9D1m53i4jmT1NjdeBU8YcW&vXf
zQw?J?V+x}<!$QVdrWD3n<{HKY%nKP@7-CIgSZY~nS!>y9*=yLdSV~y4nTix^m=>_r
zFsCprWMX8<<A(4`!1B$EHO%4+An_We1spZZH7rmzXAN@=E0oPu!(79j#SP{$r!bl`
z)G`<H*Dx*M0jCP4U<OTQzn7r&Tm&LCd5c&<iIFQcx1gjF9GFGYAOVidlGLK2{PN-=
z1yF>6e07Vvv>+w1Bo!Q)x0o~YO5h@(ID>Oa3-XI^@k7<Z5<-zY$QV#4YjQwiFDEk(
zVxbJkLdMKnEMQ~UAhCXn0~Fz<MXANNSi!N15ql}A$@wX%a-i6gU|?VnVq{?wVdP@u
zV-jQHVdi1vW8`AwU}9m!9fJ@9G&w*8S6*UnYJB`HuK4)e{FKrh5Su4HzOXbg2O<M5
zMv8<$o=^f2h9EcdLJP0t)SR67cq9k%fs}yKSP?9f7K0K$2Llfy2MY(Y06$pVPm}wW
z3b-)S1NkH;GfxjxnCT@Z6_*qxCYQv6lUQb6dJ!nw-;zgF3N8za^+2T_B-s~%auvFP
zP*pkb3I`J8;Or)c+dxpRf}{*tR7IsFnK{LJ$@zK3C5d?@#gOa_@+6Y)5jl**1`?Wf
SptM#D%J4i4Jd6-1!UO;u4*!P$

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_relative.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/naive_relative.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..269a35bd9bb6605006c7431ea0d320ed293302d0
GIT binary patch
literal 3406
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
C<Q^md

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/pos_based.cpython-310.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/pos_based.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..82512a33f500fe06e096da4cc221deeac69f42c8
GIT binary patch
literal 2476
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/pos_based.cpython-311.pyc b/tania_scripts/supar/codelin/encs/enc_deps/__pycache__/pos_based.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..741e084997009584513b4b9673da439210e63bce
GIT binary patch
literal 4493
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
SJ2^w@BUt7On8Z{CjxPXujUbEw

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/encs/enc_deps/brk2p_based.py b/tania_scripts/supar/codelin/encs/enc_deps/brk2p_based.py
new file mode 100644
index 0000000..665e9e6
--- /dev/null
+++ b/tania_scripts/supar/codelin/encs/enc_deps/brk2p_based.py
@@ -0,0 +1,215 @@
+from supar.codelin.encs.abstract_encoding import ADEncoding
+from supar.codelin.utils.constants import D_2P_GREED, D_2P_PROP, D_NONE_LABEL
+from supar.codelin.models.deps_label import D_Label
+from supar.codelin.models.deps_tree import D_Tree
+from supar.codelin.models.linearized_tree import LinearizedTree
+
+
+class D_Brk2PBasedEncoding(ADEncoding):
+    def __init__(self, separator, displacement, planar_alg):
+        if planar_alg and planar_alg not in [D_2P_GREED, D_2P_PROP]:
+            print("[*] Error: Unknown planar separation algorithm")
+            exit(1)
+        super().__init__(separator)
+        self.displacement = displacement
+        self.planar_alg = planar_alg
+
+    def __str__(self):
+        return "Dependency 2-Planar Bracketing Based Encoding"
+
+    def get_next_edge(self, dep_tree, idx_l, idx_r):
+        next_arc=None
+
+        if dep_tree[idx_l].head==idx_r:
+            next_arc = dep_tree[idx_l]
+        
+        elif dep_tree[idx_r].head==idx_l:
+            next_arc = dep_tree[idx_r]
+        
+        return next_arc
+
+    def two_planar_propagate(self, nodes):
+        p1=[]
+        p2=[]
+        fp1=[]
+        fp2=[]
+
+        for i in range(0, (len(nodes))):
+            for j in range(i, -1, -1):
+                # if the node in position 'i' has an arc to 'j' 
+                # or node in position 'j' has an arc to 'i'
+                next_arc=self.get_next_edge(nodes, i, j)
+                if next_arc is None:
+                    continue
+                else:
+                    # check restrictions
+                    if next_arc not in fp1:
+                        p1.append(next_arc)
+                        fp1, fp2 = self.propagate(nodes, fp1, fp2, next_arc, 2)
+                    
+                    elif next_arc not in fp2:
+                        p2.append(next_arc)
+                        fp1, fp2 = self.propagate(nodes, fp1, fp2, next_arc, 1)
+        return p1, p2
+    def propagate(self, nodes, fp1, fp2, current_edge, i):
+        # add the current edge to the forbidden plane opposite to the plane
+        # where the node has already been added
+        fpi  = None
+        fp3mi= None
+        if i==1:
+            fpi  = fp1
+            fp3mi= fp2
+        if i==2:
+            fpi  = fp2
+            fp3mi= fp1
+
+        fpi.append(current_edge)
+        
+        # add all nodes from the dependency graph that crosses the current edge
+        # to the corresponding forbidden plane
+        for node in nodes:
+            if current_edge.check_cross(node):
+                if node not in fp3mi:
+                    (fp1, fp2)=self.propagate(nodes, fp1, fp2, node, 3-i)
+        
+        return fp1, fp2
+
+    def two_planar_greedy(self, dep_tree):    
+        plane_1 = []
+        plane_2 = []
+
+        for i in range(len(dep_tree)):
+            for j in range(i, -1, -1):
+                # if the node in position 'i' has an arc to 'j' 
+                # or node in position 'j' has an arc to 'i'
+                next_arc = self.get_next_edge(dep_tree, i, j)
+                if next_arc is None:
+                    continue
+
+                else:
+                    cross_plane_1 = False
+                    cross_plane_2 = False
+                    for node in plane_1:                
+                        cross_plane_1 = cross_plane_1 or next_arc.check_cross(node)
+                    for node in plane_2:        
+                        cross_plane_2 = cross_plane_2 or next_arc.check_cross(node)
+                    
+                    if not cross_plane_1:
+                        plane_1.append(next_arc)
+                    elif not cross_plane_2:
+                        plane_2.append(next_arc)
+
+        # processs them separately
+        return plane_1,plane_2
+
+
+    def encode(self, dep_tree):
+        # create brackets array
+        n_nodes = len(dep_tree)
+        labels_brk     = [""] * (n_nodes + 1)
+
+        # separate the planes
+        if self.planar_alg==D_2P_GREED:
+            p1_nodes, p2_nodes = self.two_planar_greedy(dep_tree)
+        elif self.planar_alg==D_2P_PROP:
+            p1_nodes, p2_nodes = self.two_planar_propagate(dep_tree)
+            
+        # get brackets separatelly
+        labels_brk = self.encode_step(p1_nodes, labels_brk, ['>','/','\\','<'])
+        labels_brk = self.encode_step(p2_nodes, labels_brk, ['>*','/*','\\*','<*'])
+        
+        # merge and obtain labels
+        lbls=[]
+        dep_tree.remove_dummy()
+        for node in dep_tree:
+            current = D_Label(labels_brk[node.id], node.relation, self.separator)
+            lbls.append(current)
+        return LinearizedTree(dep_tree.get_words(), dep_tree.get_postags(), dep_tree.get_feats(), lbls, len(lbls))
+
+    def encode_step(self, p, lbl_brk, brk_chars):
+        for node in p:
+            # skip root relations (optional?)
+            if node.head==0:
+                continue
+            if node.id < node.head:
+                if self.displacement:
+                    lbl_brk[node.id+1]+=brk_chars[3]
+                else:
+                    lbl_brk[node.id]+=brk_chars[3]
+
+                lbl_brk[node.head]+=brk_chars[2]
+            else:
+                if self.displacement:
+                    lbl_brk[node.head+1]+=brk_chars[1]
+                else:
+                    lbl_brk[node.head]+=brk_chars[1]
+
+                lbl_brk[node.id]+=brk_chars[0]
+        return lbl_brk
+
+    def decode(self, lin_tree):
+        decoded_tree = D_Tree.empty_tree(len(lin_tree)+1)
+        
+        # create plane stacks
+        l_stack_p1=[]
+        l_stack_p2=[]
+        r_stack_p1=[]
+        r_stack_p2=[]
+        
+        current_node=1
+
+        for word, postag, features, label in lin_tree.iterrows():
+            brks = list(label.xi) if label.xi != D_NONE_LABEL else []
+            temp_brks=[]
+            
+            for i in range(0, len(brks)):
+                current_char=brks[i]
+                if brks[i]=="*":
+                    current_char=temp_brks.pop()+brks[i]
+                temp_brks.append(current_char)
+                    
+            brks=temp_brks
+            
+            # set parameters to the node
+            decoded_tree.update_word(current_node, word)
+            decoded_tree.update_upos(current_node, postag)
+            decoded_tree.update_relation(current_node, label.li)
+            
+            # fill the relation using brks
+            for char in brks:
+                if char == "<":
+                    node_id=current_node + (-1 if self.displacement else 0)
+                    r_stack_p1.append((node_id,char))
+                
+                if char == "\\":
+                    head_id = r_stack_p1.pop()[0] if len(r_stack_p1)>0 else 0
+                    decoded_tree.update_head(head_id, current_node)
+                
+                if char =="/":
+                    node_id=current_node + (-1 if self.displacement else 0)
+                    l_stack_p1.append((node_id,char))
+
+                if char == ">":
+                    head_id = l_stack_p1.pop()[0] if len(l_stack_p1)>0 else 0
+                    decoded_tree.update_head(current_node, head_id)
+
+                if char == "<*":
+                    node_id=current_node + (-1 if self.displacement else 0)
+                    r_stack_p2.append((node_id,char))
+                
+                if char == "\\*":
+                    head_id = r_stack_p2.pop()[0] if len(r_stack_p2)>0 else 0
+                    decoded_tree.update_head(head_id, current_node)
+                
+                if char =="/*":
+                    node_id=current_node + (-1 if self.displacement else 0)
+                    l_stack_p2.append((node_id,char))
+
+                if char == ">*":
+                    head_id = l_stack_p2.pop()[0] if len(l_stack_p2)>0 else 0
+                    decoded_tree.update_head(current_node, head_id)
+            
+            current_node+=1
+
+        decoded_tree.remove_dummy()
+        return decoded_tree   
diff --git a/tania_scripts/supar/codelin/encs/enc_deps/brk_based.py b/tania_scripts/supar/codelin/encs/enc_deps/brk_based.py
new file mode 100644
index 0000000..5875815
--- /dev/null
+++ b/tania_scripts/supar/codelin/encs/enc_deps/brk_based.py
@@ -0,0 +1,87 @@
+from supar.codelin.encs.abstract_encoding import ADEncoding
+from supar.codelin.models.deps_label import D_Label
+from supar.codelin.models.deps_tree import D_Tree
+from supar.codelin.utils.constants import D_NONE_LABEL
+from supar.codelin.models.linearized_tree import LinearizedTree
+
+class D_BrkBasedEncoding(ADEncoding):
+    
+    def __init__(self, separator, displacement):
+        super().__init__(separator)
+        self.displacement = displacement
+
+    def __str__(self):
+        return "Dependency Bracketing Based Encoding"
+
+
+    def encode(self, dep_tree):
+        n_nodes = len(dep_tree)
+        labels_brk     = [""] * (n_nodes + 1)
+        encoded_labels = []
+        
+        # compute brackets array
+        # brackets array should be sorted ?
+        dep_tree.remove_dummy()
+        for node in dep_tree:
+            # skip root relations (optional?)
+            if node.head == 0:
+                continue
+            
+            if node.is_left_arc():
+                labels_brk[node.id + (1 if self.displacement else 0)]+='<'
+                labels_brk[node.head]+='\\'
+            
+            else:
+                labels_brk[node.head + (1 if self.displacement else 0)]+='/'
+                labels_brk[node.id]+='>'
+        
+        # encode labels
+        for node in dep_tree:
+            li = node.relation
+            xi = labels_brk[node.id]
+
+            current = D_Label(xi, li, self.separator)
+            encoded_labels.append(current)
+
+        return LinearizedTree(dep_tree.get_words(), dep_tree.get_postags(), dep_tree.get_feats(), encoded_labels, len(encoded_labels))
+
+    def decode(self, lin_tree):
+        # Create an empty tree with n labels
+        decoded_tree = D_Tree.empty_tree(len(lin_tree)+1)
+        
+        l_stack = []
+        r_stack = []
+        
+        current_node = 1
+        for word, postag, features, label in lin_tree.iterrows():
+            
+            # get the brackets
+            brks = list(label.xi) if label.xi != D_NONE_LABEL else []
+                       
+            # set parameters to the node
+            decoded_tree.update_word(current_node, word)
+            decoded_tree.update_upos(current_node, postag)
+            decoded_tree.update_relation(current_node, label.li)
+
+            # fill the relation using brks
+            for char in brks:
+                if char == "<":
+                    node_id = current_node + (-1 if self.displacement else 0)
+                    r_stack.append(node_id)
+
+                if char == "\\":
+                    head_id = r_stack.pop() if len(r_stack) > 0 else 0
+                    decoded_tree.update_head(head_id, current_node)
+                
+                if char =="/":
+                    node_id = current_node + (-1 if self.displacement else 0)
+                    l_stack.append(node_id)
+
+                if char == ">":
+                    head_id = l_stack.pop() if len(l_stack) > 0 else 0
+                    decoded_tree.update_head(current_node, head_id)
+            
+            current_node+=1
+
+        decoded_tree.remove_dummy()
+        return decoded_tree
\ No newline at end of file
diff --git a/tania_scripts/supar/codelin/encs/enc_deps/naive_absolute.py b/tania_scripts/supar/codelin/encs/enc_deps/naive_absolute.py
new file mode 100644
index 0000000..e624bb3
--- /dev/null
+++ b/tania_scripts/supar/codelin/encs/enc_deps/naive_absolute.py
@@ -0,0 +1,42 @@
+from supar.codelin.encs.abstract_encoding import ADEncoding
+from supar.codelin.models.deps_label import D_Label
+from supar.codelin.models.linearized_tree import LinearizedTree
+from supar.codelin.models.deps_tree import D_Tree
+from supar.codelin.utils.constants import D_NONE_LABEL
+
+class D_NaiveAbsoluteEncoding(ADEncoding):
+    def __init__(self, separator):
+        super().__init__(separator)
+
+    def __str__(self):
+        return "Dependency Naive Absolute Encoding"
+
+    def encode(self, dep_tree):
+        encoded_labels = []
+        dep_tree.remove_dummy()
+        
+        for node in dep_tree:
+            li = node.relation
+            xi = node.head
+            
+            current = D_Label(xi, li, self.separator)
+            encoded_labels.append(current)
+
+        return LinearizedTree(dep_tree.get_words(), dep_tree.get_postags(), dep_tree.get_feats(), encoded_labels, len(encoded_labels))
+    
+    def decode(self, lin_tree):
+        dep_tree = D_Tree.empty_tree(len(lin_tree)+1)
+        
+        i=1
+        for word, postag, features, label in lin_tree.iterrows(): 
+            if label.xi == D_NONE_LABEL:
+                label.xi = 0
+            
+            dep_tree.update_word(i, word)
+            dep_tree.update_upos(i, postag)
+            dep_tree.update_relation(i, label.li)
+            dep_tree.update_head(i, int(label.xi))
+            i+=1
+
+        dep_tree.remove_dummy()
+        return dep_tree
\ No newline at end of file
diff --git a/tania_scripts/supar/codelin/encs/enc_deps/naive_relative.py b/tania_scripts/supar/codelin/encs/enc_deps/naive_relative.py
new file mode 100644
index 0000000..6880f27
--- /dev/null
+++ b/tania_scripts/supar/codelin/encs/enc_deps/naive_relative.py
@@ -0,0 +1,48 @@
+from supar.codelin.encs.abstract_encoding import ADEncoding
+from supar.codelin.models.deps_label import D_Label
+from supar.codelin.models.linearized_tree import LinearizedTree
+from supar.codelin.models.deps_tree import D_Tree
+from supar.codelin.utils.constants import D_NONE_LABEL
+
+class D_NaiveRelativeEncoding(ADEncoding):
+    def __init__(self, separator, hang_from_root):
+        super().__init__(separator)
+        self.hfr = hang_from_root
+
+    def __str__(self):
+        return "Dependency Naive Relative Encoding"
+
+    def encode(self, dep_tree):
+        encoded_labels = []
+        dep_tree.remove_dummy()
+        for node in dep_tree:
+            li = node.relation 
+            xi = node.delta_head()
+
+            if node.relation == 'root' and self.hfr:
+                xi = D_NONE_LABEL
+            
+            current = D_Label(xi, li, self.separator)
+            encoded_labels.append(current)
+
+        return LinearizedTree(dep_tree.get_words(), dep_tree.get_postags(), dep_tree.get_feats(), encoded_labels, len(encoded_labels))
+
+    def decode(self, lin_tree):
+        dep_tree = D_Tree.empty_tree(len(lin_tree)+1)
+
+        i = 1
+        for word, postag, features, label in lin_tree.iterrows():
+            if label.xi == D_NONE_LABEL:
+                # set as root
+                dep_tree.update_head(i, 0)
+            else:
+                dep_tree.update_head(i, int(label.xi)+(i))
+                
+            
+            dep_tree.update_word(i, word)
+            dep_tree.update_upos(i, postag)
+            dep_tree.update_relation(i, label.li)
+            i+=1
+
+        dep_tree.remove_dummy()
+        return dep_tree
\ No newline at end of file
diff --git a/tania_scripts/supar/codelin/encs/enc_deps/pos_based.py b/tania_scripts/supar/codelin/encs/enc_deps/pos_based.py
new file mode 100644
index 0000000..714efd8
--- /dev/null
+++ b/tania_scripts/supar/codelin/encs/enc_deps/pos_based.py
@@ -0,0 +1,89 @@
+from supar.codelin.encs.abstract_encoding import ADEncoding
+from supar.codelin.models.deps_label import D_Label
+from supar.codelin.models.deps_tree import D_Tree
+from supar.codelin.models.linearized_tree import LinearizedTree
+from supar.codelin.utils.constants import D_POSROOT, D_NONE_LABEL
+
+POS_ROOT_LABEL = "0--ROOT"
+
+class D_PosBasedEncoding(ADEncoding):
+    def __init__(self, separator):
+        super().__init__(separator)
+
+    def __str__(self) -> str:
+        return "Dependency Part-of-Speech Based Encoding"
+        
+    def encode(self, dep_tree):
+        
+        print("upar/codelin/encs/enc_deps/pos_based.py")
+        encoded_labels = []
+        
+        for node in dep_tree:
+            if node.id == 0:
+                # skip dummy root
+                continue
+
+            li = node.relation     
+            pi = dep_tree[node.head].upos           
+            oi = 0
+            
+            # move left or right depending if the node 
+            # dependency edge is to the left or to the right
+
+            step = 1 if node.id < node.head else -1
+            for i in range(node.id + step, node.head + step, step):
+                if pi == dep_tree[i].upos:
+                    oi += step
+
+            xi = str(oi)+"--"+pi
+
+            current = D_Label(xi, li, self.separator)
+            encoded_labels.append(current)
+
+        dep_tree.remove_dummy()
+        return LinearizedTree(dep_tree.get_words(), dep_tree.get_postags(), dep_tree.get_feats(), encoded_labels, len(encoded_labels))
+
+    def decode(self, lin_tree):
+        dep_tree = D_Tree.empty_tree(len(lin_tree)+1)
+
+        i = 1
+        postags = lin_tree.postags
+        for word, postag, features, label in lin_tree.iterrows():
+            node_id = i
+            if label.xi == D_NONE_LABEL:
+                label.xi = POS_ROOT_LABEL
+            
+            dep_tree.update_word(node_id, word)
+            dep_tree.update_upos(node_id, postag)
+            dep_tree.update_relation(node_id, label.li)
+            
+            oi, pi = label.xi.split('--')
+            oi = int(oi)
+
+            # Set head for root
+            if (pi==D_POSROOT or oi==0):
+                dep_tree.update_head(node_id, 0)
+                i+=1
+                continue
+
+            # Compute head position
+            target_oi = oi
+
+            step = 1 if oi > 0 else -1
+            stop_point = (len(postags)+1) if oi > 0 else 0
+
+            for j in range(node_id+step, stop_point, step):
+                if (pi == postags[j-1]):
+                    target_oi -= step
+                
+                if (target_oi==0):
+                    break
+            
+            head_id = j
+            dep_tree.update_head(node_id, head_id)
+            
+            i+=1
+
+        
+        dep_tree.remove_dummy()
+        return dep_tree
\ No newline at end of file
diff --git a/tania_scripts/supar/codelin/models/__init__.py b/tania_scripts/supar/codelin/models/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tania_scripts/supar/codelin/models/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/codelin/models/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..055dc41308b5847ea209b4ae31a538031037b6ad
GIT binary patch
literal 163
zcmd1j<>g{vU|`^5Uz84_AA<;F%*epN;K0DZP|U)>z>vZa%%I8Wx00a<B#a<_x#?%*
z=cekHB$i|*<|XPS<s_zLrWWZZ=jRsW>!uf!=;r39q~_=smlh;~L{n08GV}DoV#WIL
i@tJv<CGqik1(mlrY;yBcN^?@}K;{=SF)%Q&FaQ9^q9&IB

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/models/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/codelin/models/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b7f007831d62522735be047094f4cf4fdcc4000c
GIT binary patch
literal 193
zcmZ3^%ge>Uz`&q*Uo`_nKL!yn%m`(CW@BJrn9h*G5X_*-=(m!gh>3xL;WJ3`SBQQ_
zer~FMNn%N6VqT(NQchw@W@?dsa(-?>zHUisMTu@|Sz?ZUNn&1RVtjFOQD#9&v3_xB
zK_W;^N@`AKo_=nAN@`BAetdjpUS>&ryk0@&FAkgB{FKt1RJ$Tp1_lO@Gm7~c7#Kb<
QGcq!MV1N-t%nS?+0C_tx*Z=?k

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/models/__pycache__/const_label.cpython-310.pyc b/tania_scripts/supar/codelin/models/__pycache__/const_label.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0ab31bdd2279ddff308fa26008115f5475640b1c
GIT binary patch
literal 1556
zcmd1j<>g{vU|`^5UzD!L%E0g##6iZ)3=9ko3=9m#Y77hvDGVu$ISjdsQH;4vQB1ka
zQOt}C?hGkRDa<VlDa_4GQ7kDe!3>(LFF__~GT#z*j(2nl_V)=5agBHNbM|-f^m7LZ
z2D$n;hIob{3Gz6{`}zC1#``!rx%wo7v?F7<BMcZA7*ZLc7*iOcm{J&1m|7U3m{XWj
zSXvmOSW;M1*jgB(SX0?j*i$%K7@8TQ*i$%z88o?Wu{+26BqpWiB(o!#3Su)cFfcfS
zd}qPHz)-_d!w}C<!dS!D%vi$^&s4)y!w}D0!(76W&0Hi{!<@&M!cfBy&sxJ;!w}C_
z!&bu(&z`~%%%I8Wr^#`PH#ILgKP59SJ-(!}AoUh=W?soH&b;{K{M_99yy9EjIf=z3
zP+k!W0|Ub??$W%(qRRN>jKs{mTb#wI1&Kw8CHY0Scp&0g`I&jCMVjolSc+3~(rz*3
zCEsGoNxsEYntY2Xwd594altL7(yWyXMIsCg48J_}GxBp&^-B^<G86L>^^$TDQ!-PF
z^po>*3-Wc-3rciz^HWlD^ovUi5<#LVsX3W>`e3nQ{p9?-;*$6rPyp!_RNmr<kI&4@
zEQyZ?xw4ptfq{XIk&B6qQHYU^k&CfP02-EhFlEV%NP!9pP*7}v12qB^s0>*QMcg$E
zS&R#qY8bK@(is;r<}s!))-skb*Dz$UfPy-UwS+C3sYoJ)2_z%VP{WYL4kkIkBtwxV
zNTh~QoI#u+m?4D`L~1ho-D0@KsHMqS1WLd~Aa~wk0R`GE=Hil~A`S)yh9Wi)0dh_e
zH;Bc_z`&r%RK&}`z!1d=31yH{Pym8Mu}BmYFC6jlMX3cv@$n#a#UM#3Mkz)XMyCHD
z%*V*`pNWy>KXN!glqZAy4hsqp8)Pv!9JIjUz`~HlP{WwTV9vnA5D)SrLkeRyW061#
zD4Bth9YZ`5I5{!<6@h~EC5X^uhWG?z9@slD_j7^M6FAZ!ZU;FO;sNfG{P@JA;{2S_
zl2jp3;s%9<03#PD{+OzSVeyBgDjDQdnA1V3L3so0^cb+y7ckT?E@Z4_E@7-;Ze~nj
z%w{SQs$q^{s%5EVO<|~I%VVu!j$sDzYS~hlYFNq`ieyWe@)%2)YuRg97O;Ryh=okG
zEG4WpEH$h(Y&GmPj5SQnY{3kgEPgM+ev<%2kT@uU*lw{F7vyA?++xm2%_{=AtO%sy
z7JE@@K~7?FY7r|)6~`^coLkJrsRc#Cpy(6;hXg2p73Alo=9Lr|@qrBF2N41wLJ&lN
z!w5`(W12gyC_gv8xTGjEFI^H8P#~3DOgu~+;Ghy<;$akGL<AU;YEXvfh>y=p%uS7t
zzr__FpPQdjnge3<#K#wwCgwn7io`&+N`nYlP}1Tl24&FX+|-hc{FEXUkT}>i2m<6T
zum?f@24_AF1`b9JP7YQkc0NY1jGrd!Em?3z)=LIu>dZX7(vr-aVm)v^P6YWK6kd>!
g1La|`E~G>Pwhd&_Ee;!qyX`<ptr(<Mgh7Z209FfKKmY&$

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/models/__pycache__/const_label.cpython-311.pyc b/tania_scripts/supar/codelin/models/__pycache__/const_label.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f6816f095c20760ddde9f1421313ff80f2f8e887
GIT binary patch
literal 2538
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
YMju#|7!5u!U=kleVqZW6nk?Au0ACk1%>V!Z

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/models/__pycache__/const_tree.cpython-310.pyc b/tania_scripts/supar/codelin/models/__pycache__/const_tree.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..069e2ef3ba4d3d9cbe4ae8d6dea1e8105dfb3d47
GIT binary patch
literal 12187
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/models/__pycache__/const_tree.cpython-311.pyc b/tania_scripts/supar/codelin/models/__pycache__/const_tree.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..376f81b9df97423cdc912c3eac7e7063b9e838a0
GIT binary patch
literal 21102
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
QPJRT7e*u%2YQSL$0LKnirvLx|

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/models/__pycache__/deps_label.cpython-310.pyc b/tania_scripts/supar/codelin/models/__pycache__/deps_label.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3a316c2c1296885e31867d3fd9fabd908a3cc177
GIT binary patch
literal 973
zcmd1j<>g{vU|`^5UzC21k%8ech=Yuo85kHG7#J9eg%}tZ+!<0BQW#qpQW%?=q8L(`
zf*CZKlaW<}*l-;t3=9mZ3{i|J3{gxej44bl3{lJ}%qc7_3{fnptSPK1Y%L7Uj8SZ<
ztSRg%9AGwk3TH5bCf6-?mw2DVq|}^b7LbWh3}Q1eFfcfSoFm4-z)-_n!w}C<!&t)*
z&sf7$!w}Du!Vt``lF?6-`4(q!YC&RAVo83{EvAahTTD5bnk=_iic@paia_QRu`)0)
z++r#&SjkYt!N9=q%R@gSKQ~psB(WqjF)vXsDJL-{Gqp%RIX|}`UpKv=L^n4-B{fIC
zxU?V<B$|?%lbNRv7Aw|INi8Uj&jGntub}c4M|^x{US>&rJjkuZYzzzxY>aG7T#Qu$
zP*3T>6eKf3eFmaHY*5f4e8-T*Fq@%<A&U`AGR<a~%N)#51Ts~V8R7|$dazG48H+#`
zfxQADI6?m7h>tHyEhvhQ2YIm=q*DyV84$^2kOasHAPfo|5C%I#3KYl;3m9q`7c#~$
z)iTvGmw*DAxrVVB?i8k5ti=U6nI%Oa4`{MPvF9Y^#21$o-C{0IEr2)^6xI+|f!t99
zb{cnDQGPB+U1nZ7Hz-0umhv(2Fjfh}f(c0lMo58FgPq93z`#(#kiwY4Si=BvlqQqk
zErykh5Z5pkfkOyvE0};-otj%vQVEGL0g%-o|MM^*EJl*|)8qg}XkKD&YJB`HuK4)e
z{FKrh5Su4HzOXbg2O?7h%0xvVf863J2Bo3o+|-hc{FEX-1_p*AK@b79A3=az0(K-Q
v*or~QI2bq>IoOz(xfq#P_#hteD+0L>Dd@oZL0WHd*g#xj2i6brfe-@#O25RU

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/models/__pycache__/deps_label.cpython-311.pyc b/tania_scripts/supar/codelin/models/__pycache__/deps_label.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9643deb605dccdecaca4931fdcf8ec1c1ad66a6b
GIT binary patch
literal 1396
zcmZ3^%ge>Uz`&q*Up3<#BLl-@5C?`?pp4H73=9m@8JHN{8B!Qp7*ZIQF)=W#W`fEx
zL@}f=1v6+eC&L6lG)(rh8(42DLlk2QLljdAV+%tRa|%-nLljFYYYKA<!!ia2hSeY)
zU>wDk%9_H0A<CY@8qA={c8lF5-X}3BH76P7G>|5cRm=<w44)0aR@E@qFvNqz!MKL8
zh9RC2%w%9-s9~yMhzF?$3#2dvGpuCv(`3HIS)5vsSd>_jUv!J9BJ&ngPNpWyEtcZc
zoU|f#1_p*A4h9B>TTI0T#UOhX6ciMGh3RMH=cekHB$i|*<|XPS<s_zLrWWZZ=jRsW
z>z1Tel<20GCFbatB<5u%#uq0SWfqha>lc?6B!bkWq~>Ji>F4IBq~;Xsr=%7X$LD~2
zrB_gSiz7ZhGcU6wKE6r->Q_CO2*};V(hLj?4GcFVr8`)9_#Oy}bg=ZW-+)jZ>>cc%
zK^{wn`<H=%0TePI3=18GERYf~p3P9hkOfx@=7H>h%FSgCW+-B1U|`T>h6Dl|EF?4;
zi#Qn=7>Yq!6^gh)VZ#w0UzA!<gz9XF2q^4|<si-$5}Traf!}0?$sD^2{3a_*)|g-5
zHvu6IlOkRQ28Lv~{R|8YAiKdX4}ruh!ve6&(1{wxWsD3At3i$dOT{oTFw`>DGM9k#
zf<?gb&RoN|jG2L9HCz<tJEmK##RWN;B}E_^O_p2iIY~M3#U(|zn2S>jAU+3s0T%TT
z4|As#<>!KwW#*+<3B#faNe~n)#hPGmKM<6dE;~tfM)5^K<tu{9oopRU9Zq-o#U>QZ
zFq%<(kze@=zw!kRWk?9X{ec_;D&P<(L6S>hOku2HK=+X*liw|dm5dOtFcyJg3^|s#
zQ*#SSDj|st;b<g50Z_DxfF1o5>b}a0{F+zzH7{^zg5Bq*$pK2Ed5O8H@$t8~;^TAk
zQ%Z9{Y@Yb|!qUVXh)fX=D6#N^k_JyPD3c`Trj}&nrxbw<FOpzjU|7ijHV+({VE2Lv
zkPnM9zz%3&fWQw-EUcm*7~ljCBdh5L1~|dSz$Wy8iHTL^0|OJQ%134fHldanhyVvz
zijh?dq+AOw1rq>^LL32#dcPuZkeg*e1Sl<nUG|H^2I4`xB2W?rJI|bff#Cx)BO~Jn
WCP7B64-A;ZN08VT5P>EOwhaI@j3uoA

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/models/__pycache__/deps_tree.cpython-310.pyc b/tania_scripts/supar/codelin/models/__pycache__/deps_tree.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f8e4df612a26f2cf508b2bb5fa7e85648a86b36d
GIT binary patch
literal 13060
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
F2LP%J4k-Wt

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/models/__pycache__/deps_tree.cpython-311.pyc b/tania_scripts/supar/codelin/models/__pycache__/deps_tree.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ca3679ea018cddc145eefe45675c608e6475204d
GIT binary patch
literal 21064
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
WSQxE7FkmM?g2lgpNlZ215CH((uaNNo

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/models/__pycache__/linearized_tree.cpython-310.pyc b/tania_scripts/supar/codelin/models/__pycache__/linearized_tree.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d6b35816c4e91140d23f0a05ada4956a3eca4872
GIT binary patch
literal 5132
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/models/__pycache__/linearized_tree.cpython-311.pyc b/tania_scripts/supar/codelin/models/__pycache__/linearized_tree.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..30e902912d8da97efe2c282ebdf01db36bf1e563
GIT binary patch
literal 9798
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
G2O9u1fGt4)

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/models/const_label.py b/tania_scripts/supar/codelin/models/const_label.py
new file mode 100644
index 0000000..1df73ca
--- /dev/null
+++ b/tania_scripts/supar/codelin/models/const_label.py
@@ -0,0 +1,38 @@
+from supar.codelin.utils.constants import C_ABSOLUTE_ENCODING, C_RELATIVE_ENCODING, C_NONE_LABEL
+
+class C_Label:
+    def __init__(self, nc, lc, uc, et, sp, uj):
+        self.encoding_type = et
+
+        self.n_commons = int(nc)
+        self.last_common = lc
+        self.unary_chain = uc if uc != C_NONE_LABEL else None
+        self.separator = sp
+        self.unary_joiner = uj
+    
+    def __repr__(self):
+        unary_str = self.unary_joiner.join([self.unary_chain]) if self.unary_chain else ""
+        return (str(self.n_commons) + ("*" if self.encoding_type==C_RELATIVE_ENCODING else "")
+        + self.separator + self.last_common + (self.separator + unary_str if self.unary_chain else ""))
+    
+    def to_absolute(self, last_label):
+        self.n_commons+=last_label.n_commons
+        if self.n_commons<=0:
+            self.n_commons = 1
+        
+        self.encoding_type=C_ABSOLUTE_ENCODING
+    
+    @staticmethod
+    def from_string(l, sep, uj):
+        label_components = l.split(sep)
+        
+        if len(label_components)== 2:
+            nc, lc = label_components
+            uc = None
+        else:
+            nc, lc, uc = label_components
+        
+        et = C_RELATIVE_ENCODING if '*' in nc else C_ABSOLUTE_ENCODING
+        nc = nc.replace("*","")
+        return C_Label(nc, lc, uc, et, sep, uj)
+    
\ No newline at end of file
diff --git a/tania_scripts/supar/codelin/models/const_tree.py b/tania_scripts/supar/codelin/models/const_tree.py
new file mode 100644
index 0000000..e546658
--- /dev/null
+++ b/tania_scripts/supar/codelin/models/const_tree.py
@@ -0,0 +1,414 @@
+from supar.codelin.utils.constants import C_END_LABEL, C_START_LABEL, C_NONE_LABEL
+from supar.codelin.utils.constants import C_CONFLICT_SEPARATOR, C_STRAT_MAX, C_STRAT_FIRST, C_STRAT_LAST, C_NONE_LABEL, C_ROOT_LABEL
+import copy
+
+class C_Tree:
+    def __init__(self, label, children=[], feats=None):
+        self.parent = None
+        self.label = label
+        self.children = children
+        self.features = feats
+
+# Adders and deleters
+    def add_child(self, child):
+        '''
+        Function that adds a child to the current tree
+        '''
+        if type(child) is list:
+            for c in child:
+                self.add_child(c)
+        elif type(child) is C_Tree:
+            self.children.append(child)
+            child.parent = self
+
+        else:
+            raise TypeError("[!] Child must be a ConstituentTree or a list of Constituent Trees")
+    
+    def add_left_child(self, child):
+        '''
+        Function that adds a child to the left of the current tree
+        '''
+        if type(child) is not C_Tree:
+            raise TypeError("[!] Child must be a ConstituentTree")
+        
+        self.children = [child] + self.children
+        child.parent = self
+
+    def del_child(self, child):
+        '''
+        Function that deletes a child from the current tree
+        without adding its children to the current tree
+        '''
+        if type(child) is not C_Tree:
+            raise TypeError("[!] Child must be a ConstituentTree")
+
+        self.children.remove(child)
+        child.parent = None
+
+# Getters
+    def r_child(self):
+        '''
+        Function that returns the rightmost child of a tree
+        '''
+        return self.children[len(self.children)-1]
+    
+    def l_child(self):
+        '''
+        Function that returns the leftmost child of a tree
+        '''
+        return self.children[0]
+
+    def r_siblings(self):
+        '''
+        Function that returns the right siblings of a tree
+        '''
+        return self.parent.children[self.parent.children.index(self)+1:]
+
+    def l_siblings(self):
+        '''
+        Function that returns the left siblings of a tree
+        '''
+        return self.parent.children[:self.parent.children.index(self)]
+
+    def get_root(self):
+        '''
+        Function that returns the root of a tree
+        '''
+        if self.parent is None:
+            return self
+        else:
+            return self.parent.get_root()
+
+    def extract_features(self, f_mark = "##", f_sep = "|"):
+        # go through all pre-terminal nodes
+        # of the tree
+        for node in self.get_preterminals():
+            
+            if f_mark in node.label:
+                node.features = {}
+                label = node.label.split(f_mark)[0]
+                features   = node.label.split(f_mark)[1]
+
+                node.label = label
+
+                # add features to the tree
+                for feature in features.split(f_sep):
+                    
+                    if feature == "_":
+                        continue
+                
+                    key = feature.split("=")[0]
+                    value = feature.split("=")[1]
+
+                    node.features[key]=value
+
+    def get_feature_names(self):
+        '''
+        Returns a set containing all feature names
+        for the tree
+        '''
+        feat_names = set()
+
+        for child in self.children:
+            feat_names = feat_names.union(child.get_feature_names())
+        if self.features is not None:
+            feat_names = feat_names.union(set(self.features.keys()))
+
+        return feat_names            
+
+# Word and Postags getters
+    def get_words(self):
+        '''
+        Function that returns the terminal nodes of a tree
+        '''
+        if self.is_terminal():
+            return [self.label]
+        else:
+            return [node for child in self.children for node in child.get_words()]
+
+    def get_postags(self):
+        '''
+        Function that returns the preterminal nodes of a tree
+        '''
+        if self.is_preterminal():
+            return [self.label]
+        else:
+            return [node for child in self.children for node in child.get_postags()]
+
+# Terminal checking
+    def is_terminal(self):
+        '''
+        Function that checks if a tree is a terminal
+        '''
+        return len(self.children) == 0
+
+    def is_preterminal(self):
+        '''
+        Function that checks if a tree is a preterminal
+        '''
+        return len(self.children) == 1 and self.children[0].is_terminal()
+
+# Terminal getters
+    def get_terminals(self):
+        '''
+        Function that returns the terminal nodes of a tree
+        '''
+        if self.is_terminal():
+            return [self]
+        else:
+            return [node for child in self.children for node in child.get_terminals()]
+
+    def get_preterminals(self):
+        '''
+        Function that returns the terminal nodes of a tree
+        '''
+        if self.is_preterminal():
+            return [self]
+        else:
+            return [node for child in self.children for node in child.get_preterminals()]
+
+# Tree processing
+    def collapse_unary(self, unary_joiner="+"):
+        '''
+        Function that collapses unary chains
+        into single nodes using a unary_joiner as join character
+        '''
+        for child in self.children:
+            child.collapse_unary(unary_joiner)
+        if len(self.children)==1 and not self.is_preterminal():
+            self.label += unary_joiner + self.children[0].label
+            self.children = self.children[0].children
+
+    def inherit_tree(self):
+        '''
+        Removes the top node of the tree and delegates it
+        to its firstborn child. 
+        
+        (S (NP (NNP John)) (VP (VBD died))) => (NP (NNP John))
+        '''
+        self.label = self.children[0].label
+        self.children = self.children[0].children
+
+    def add_end_node(self):
+        '''
+        Function that adds a dummy end node to the 
+        rightmost part of the tree
+        '''
+        self.add_child(C_Tree(C_END_LABEL, []))
+
+    def add_start_node(self):
+        '''
+        Function that adds a dummy start node to the leftmost
+        part of the tree
+        '''
+        self.add_left_child(C_Tree(C_START_LABEL, []))
+        
+    def path_to_leaves(self, collapse_unary=True, unary_joiner="+"):
+        '''
+        Function that given a Tree returns a list of paths
+        from the root to the leaves, encoding a level index into
+        nodes to make them unique.
+        '''
+        self.add_end_node()
+                    
+        if collapse_unary:
+            self.collapse_unary(unary_joiner)
+
+        paths = self.path_to_leaves_rec([],[],0)
+        return paths
+
+    def path_to_leaves_rec(self, current_path, paths, idx):
+        '''
+        Recursive step of the path_to_leaves function where we store
+        the common path based on the current node
+        '''
+        # pass by value
+        path = copy.deepcopy(current_path)
+        
+        if (len(self.children)==0):
+            # we are at a leaf. store the path in a new list
+            path.append(self.label)
+            paths.append(path)
+        else:
+            path.append(self.label+str(idx))
+            for child in self.children:
+                child.path_to_leaves_rec(path, paths, idx)
+                idx+=1
+        return paths
+
+    def fill_pos_nodes(self, postag, word, unary_chain, unary_joiner):
+        if self.label == postag:
+            # if the current level is already a postag level. This may happen on 
+            # trees shaped as (NP tree) that exist on the SPMRL treebanks
+            self.children.append(C_Tree(word, []))
+            return
+        
+        if unary_chain:
+            unary_chain = unary_chain.split(unary_joiner)
+            unary_chain.reverse()
+            pos_tree = C_Tree(postag, [C_Tree(word, [])])
+            for node in unary_chain:
+                temp_tree = C_Tree(node, [pos_tree])
+                pos_tree = temp_tree
+        else:
+            pos_tree = C_Tree(postag, [C_Tree(word, [])])
+
+        self.add_child(pos_tree)
+
+    def renounce_children(self):
+        '''
+        Function that deletes current tree from its parent
+        and adds its children to the parent
+        '''
+        self.parent.children = self.l_siblings() + self.children + self.r_siblings()
+        for child in self.children:
+            child.parent = self.parent
+
+
+    def prune_nones(self):
+        """
+        Return a copy of the tree without 
+        null nodes (nodes with label C_NONE_LABEL)
+        """
+        if self.label != C_NONE_LABEL:
+            t = C_Tree(self.label, [])
+            new_childs = [c.prune_nones() for c in self.children]
+            t.add_child(new_childs)
+            return t
+        
+        else:
+            return [c.prune_nones() for c in self.children]
+
+    def remove_conflicts(self, conflict_strat):
+        '''
+        Removes all conflicts in the label of the tree generated
+        during the decoding process. Conflicts will be signaled by -||- 
+        string.
+        '''
+        for c in self.children:
+            if type(c) is C_Tree:
+                c.remove_conflicts(conflict_strat)
+        if C_CONFLICT_SEPARATOR in self.label:
+            labels = self.label.split(C_CONFLICT_SEPARATOR)
+            
+            if conflict_strat == C_STRAT_MAX:
+                self.label = max(set(labels), key=labels.count)
+            if conflict_strat == C_STRAT_FIRST:
+                self.label = labels[0]
+            if conflict_strat == C_STRAT_LAST:
+                self.label = labels[len(labels)-1]
+
+    def postprocess_tree(self, conflict_strat, clean_nulls=True, default_root="S"):
+        '''
+        Returns a C_Tree object with conflicts in node labels removed
+        and with NULL nodes cleaned.
+        '''
+        if clean_nulls:
+            if self.label == C_NONE_LABEL or self.label==C_ROOT_LABEL:
+                self.label = default_root
+            t = self.prune_nones()
+        else:
+            t = self
+        t.remove_conflicts(conflict_strat)
+        return t
+        
+        # print( fix_tree)
+        
+    def reverse_tree(self):
+        '''
+        Reverses the order of all the tree children
+        '''
+        for c in self.children:
+            if type(c) is C_Tree:
+                c.reverse_tree()
+        self.children.reverse()
+
+# Printing and python-related functions
+    def __str__(self):
+        if len(self.children) == 0:
+            label_str = self.label
+            
+            if self.features is not None:
+                features_str = "##" + "|".join([key+"="+value for key,value in self.features.items()])
+            
+            label_str = label_str.replace("(","-LRB-")
+            label_str = label_str.replace(")","-RRB-")
+        else:
+            label_str =  "(" + self.label + " "
+            if self.features is not None:
+                features_str = "##"+ "|".join([key+"="+value for key,value in self.features.items()]) 
+            
+            label_str += " ".join([str(child) for child in self.children]) + ")"
+        return label_str
+
+    def __repr__(self):
+        return self.__str__()
+
+    def __eq__(self, other):
+        if isinstance(other, C_Tree):
+            return self.label == other.label and self.children == other.children
+        return False
+
+    def __hash__(self):
+        return hash((self.label, tuple(self.children)))
+
+    def __len__(self):
+        return len(self.children)
+
+    def __iter__(self):
+        yield self.label
+        for child in self.children:
+            yield child
+
+    def __contains__(self, item):
+        return item in self.label or item in self.children
+
+
+# Tree creation
+    @staticmethod
+    def from_string(s):
+        s = s.replace("(","( ")
+        s = s.replace(")"," )")
+        s = s.split(" ")
+        
+        # create dummy label and append it to the stack
+        stack = []        
+        i=0
+        while i < (len(s)):
+            if s[i]=="(":
+                # If we find a l_brk we create a new tree
+                # with label=next_word. Skip next_word.
+                w = s[i+1]
+                t = C_Tree(w, [])
+                stack.append(t)
+                i+=1
+
+            elif s[i]==")":
+                # If we find a r_brk set top of the stack
+                # as children to the second top of the stack
+
+                t = stack.pop()
+                
+                if len(stack)==0:
+                    return t
+
+                pt = stack.pop()
+                pt.add_child(t)
+                stack.append(pt)
+            
+            else:
+                # If we find a word set it as children
+                # of the current tree.
+                t = stack.pop()
+                w = s[i]
+                c = C_Tree(w, [])
+                t.add_child(c)
+                stack.append(t)
+
+            i+=1
+        return t
+
+# Default trees
+    @staticmethod
+    def empty_tree():
+        return C_Tree(C_NONE_LABEL, [])
\ No newline at end of file
diff --git a/tania_scripts/supar/codelin/models/deps_label.py b/tania_scripts/supar/codelin/models/deps_label.py
new file mode 100644
index 0000000..ada0b83
--- /dev/null
+++ b/tania_scripts/supar/codelin/models/deps_label.py
@@ -0,0 +1,18 @@
+class D_Label:
+    def __init__(self, xi, li, sp):
+        self.separator = sp
+
+        self.xi = xi    # dependency relation
+        self.li = li    # encoding
+
+    def __repr__(self):
+        return f'{self.xi}{self.separator}{self.li}'
+
+    @staticmethod
+    def from_string(lbl_str, sep):
+        xi, li = lbl_str.split(sep)
+        return D_Label(xi, li, sep)
+    
+    @staticmethod
+    def empty_label(separator):
+        return D_Label("", "", separator)
diff --git a/tania_scripts/supar/codelin/models/deps_tree.py b/tania_scripts/supar/codelin/models/deps_tree.py
new file mode 100644
index 0000000..4313026
--- /dev/null
+++ b/tania_scripts/supar/codelin/models/deps_tree.py
@@ -0,0 +1,371 @@
+from supar.codelin.utils.constants import D_ROOT_HEAD, D_NULLHEAD, D_ROOT_REL, D_POSROOT, D_EMPTYREL
+
+class D_Node:
+    def __init__(self, wid, form, lemma=None, upos=None, xpos=None, feats=None, head=None, deprel=None, deps=None, misc=None):
+        self.id = int(wid)                      # word id
+        
+        self.form = form if form else "_"       # word 
+        self.lemma = lemma if lemma else "_"    # word lemma/stem
+        self.upos = upos if upos else "_"       # universal postag
+        self.xpos = xpos if xpos else "_"       # language_specific postag
+        self.feats = self.parse_feats(feats) if feats else "_"    # morphological features
+        
+        self.head = int(head)                   # id of the word that depends on
+        self.relation = deprel                  # type of relation with head
+
+        self.deps = deps if deps else "_"       # enhanced dependency graph
+        self.misc = misc if misc else "_"       # miscelaneous data
+    
+    def is_left_arc(self):
+        return self.head > self.id
+
+    def delta_head(self):
+        return self.head - self.id
+    
+    def parse_feats(self, feats):
+        if feats == '_':
+            return [None]
+        else:
+            return [x for x in feats.split('|')]
+
+    def check_cross(self, other):
+        if ((self.head == other.head) or (self.head==other.id)):
+                return False
+
+        r_id_inside = (other.head < self.id < other.id)
+        l_id_inside = (other.id < self.id < other.head)
+
+        id_inside = r_id_inside or l_id_inside
+
+        r_head_inside = (other.head < self.head < other.id)
+        l_head_inside = (other.id < self.head < other.head)
+
+        head_inside = r_head_inside or l_head_inside
+
+        return head_inside^id_inside
+    
+    def __repr__(self):
+        return '\t'.join(str(e) for e in list(self.__dict__.values()))+'\n'
+
+    def __eq__(self, other):
+        return self.__dict__ == other.__dict__
+    
+
+    @staticmethod
+    def from_string(conll_str):
+        wid,form,lemma,upos,xpos,feats,head,deprel,deps,misc = conll_str.split('\t')
+        return D_Node(int(wid), form, lemma, upos, xpos, feats, int(head), deprel, deps, misc)
+
+    @staticmethod
+    def dummy_root():
+        return D_Node(0, D_POSROOT, None, D_POSROOT, None, None, 0, D_EMPTYREL, None, None)
+    
+    @staticmethod
+    def empty_node():
+        return D_Node(0, None, None, None, None, None, 0, None, None, None)
+
+class D_Tree:
+    def __init__(self, nodes):
+        self.nodes = nodes
+
+# getters    
+    def get_node(self, id):
+        return self.nodes[id-1]
+
+    def get_edges(self):
+        '''
+        Return sentence dependency edges as a tuple 
+        shaped as ((d,h),r) where d is the dependant of the relation,
+        h the head of the relation and r the relationship type
+        '''
+        return list(map((lambda x :((x.id, x.head), x.relation)), self.nodes))
+    
+    def get_arcs(self):
+        '''
+        Return sentence dependency edges as a tuple 
+        shaped as (d,h) where d is the dependant of the relation,
+        and h the head of the relation.
+        '''
+        return list(map((lambda x :(x.id, x.head)), self.nodes))
+
+    def get_relations(self):
+        '''
+        Return a list of relationships betwee nodes
+        '''
+        return list(map((lambda x :x.relation), self.nodes))
+    
+    def get_sentence(self):
+        '''
+        Return the sentence as a string
+        '''
+        return " ".join(list(map((lambda x :x.form), self.nodes)))
+
+    def get_words(self):
+        '''
+        Returns the words of the sentence as a list
+        '''
+        return list(map((lambda x :x.form), self.nodes))
+
+    def get_indexes(self):
+        '''
+        Returns a list of integers representing the words of the 
+        dependency tree
+        '''
+        return list(map((lambda x :x.id), self.nodes))
+
+    def get_postags(self):
+        '''
+        Returns the part of speech tags of the tree
+        '''
+        return list(map((lambda x :x.upos), self.nodes))
+
+    def get_lemmas(self):
+        '''
+        Returns the lemmas of the tree
+        '''
+        return list(map((lambda x :x.lemma), self.nodes))
+
+    def get_heads(self):
+        '''
+        Returns the heads of the tree
+        '''
+        return list(map((lambda x :x.head), self.nodes))
+    
+    def get_feats(self):
+        '''
+        Returns the morphological features of the tree
+        '''
+        return list(map((lambda x :x.feats), self.nodes))
+
+# update functions
+    def append_node(self, node):
+        '''
+        Append a node to the tree and sorts the nodes by id
+        '''
+        self.nodes.append(node)
+        self.nodes.sort(key=lambda x: x.id)
+
+    def update_head(self, node_id, head_value):
+        '''
+        Update the head of a node indicated by its id
+        '''
+        for node in self.nodes:
+            if node.id == node_id:
+                node.head = head_value
+                break
+    
+    def update_relation(self, node_id, relation_value):
+        '''
+        Update the relation of a node indicated by its id
+        '''
+        for node in self.nodes:
+            if node.id == node_id:
+                node.relation = relation_value
+                break
+    
+    def update_word(self, node_id, word):
+        '''
+        Update the word of a node indicated by its id
+        '''
+        for node in self.nodes:
+            if node.id == node_id:
+                node.form = word
+                break
+
+    def update_upos(self, node_id, postag):
+        '''
+        Update the upos field of a node indicated by its id
+        '''
+        for node in self.nodes:
+            if node.id == node_id:
+                node.upos = postag
+                break
+
+# properties functions
+    def is_projective(self):
+        '''
+        Returns a boolean indicating if the dependency tree
+        is projective (i.e. no edges are crossing)
+        '''
+        arcs = self.get_arcs()
+        for (i,j) in arcs:
+            for (k,l) in arcs:
+                if (i,j) != (k,l) and min(i,j) < min(k,l) < max(i,j) < max(k,l):
+                    return False
+        return True
+    
+# postprocessing
+    def remove_dummy(self):
+        self.nodes = self.nodes[1:]
+
+    def postprocess_tree(self, search_root_strat, allow_multi_roots=False):
+        '''
+        Postprocess the tree by finding the root according to the selected 
+        strategy and fixing cycles and out of bounds heads
+        '''
+        # 1) Find the root
+        root = self.root_search(search_root_strat)
+        
+        # 2) Fix oob heads
+        self.fix_oob_heads()
+        
+        # 3) Fix cycles
+        self.fix_cycles(root)
+        
+        # 4) Set all null heads to root and remove other root candidates
+        for node in self.nodes:
+            if node.id == root:
+                node.head = 0
+                continue
+            if node.head == D_NULLHEAD:
+                node.head = root
+            if not allow_multi_roots and node.head == 0:
+                node.head = root
+
+    def root_search(self, search_root_strat):
+        '''
+        Search for the root of the tree using the method indicated
+        '''
+        root = 1 # Default root
+        for node in self.nodes:    
+            if search_root_strat == D_ROOT_HEAD:
+                if node.head == 0:
+                    root = node.id
+                    break
+            
+            elif search_root_strat == D_ROOT_REL:
+                if node.rel == 'root' or node.rel == 'ROOT':
+                    root = node.id
+                    break
+        return root
+
+    def fix_oob_heads(self):
+        '''
+        Fixes heads of the tree (if they dont exist, if they are out of bounds, etc)
+        If a head is out of bounds set it to nullhead
+        '''
+        for node in self.nodes:
+            if node.head==D_NULLHEAD:
+                continue
+            if int(node.head) < 0:
+                node.head = D_NULLHEAD
+            elif int(node.head) > len(self.nodes):
+                node.head = D_NULLHEAD
+    
+    def fix_cycles(self, root):
+        '''
+        Breaks cycles in the tree by setting the head of the node to root_id
+        '''
+        for node in self.nodes:
+            visited = []
+            
+            while (node.id != root) and (node.head !=D_NULLHEAD):
+                if node in visited:
+                    node.head = D_NULLHEAD
+                else:
+                    visited.append(node)
+                    next_node = min(max(node.head-1, 0), len(self.nodes)-1)
+                    node = self.nodes[next_node]
+        
+# python related functions
+    def __repr__(self):
+        return "".join(str(e) for e in self.nodes)+"\n"
+    
+    def __iter__(self):
+        for n in self.nodes:
+            yield n
+
+    def __getitem__(self, key):
+        return self.nodes[key]  
+    
+    def __len__(self):
+        return self.nodes.__len__()
+
+# base tree
+    @staticmethod
+    def empty_tree(l=1):
+        ''' 
+        Creates an empty dependency tree with l nodes
+        '''
+        t = D_Tree([])
+        for i in range(l):
+            n = D_Node.empty_node()
+            n.id = i
+            t.append_node(n)
+        return t
+
+# reader and writter
+    @staticmethod
+    def from_string(conll_str, dummy_root=True, clean_contractions=True, clean_omisions=True):
+        '''
+        Create a ConllTree from a dependency tree conll-u string.
+        '''
+        data = conll_str.split('\n')
+        dependency_tree_start_index = 0
+        for line in data:
+            if len(line)>0 and line[0]!="#":
+                break
+            dependency_tree_start_index+=1
+        data = data[dependency_tree_start_index:]
+        nodes = []
+        if dummy_root:
+            nodes.append(D_Node.dummy_root())
+        
+        for line in data:
+            # check if not valid line (empty or not enough fields)
+            if (len(line)<=1) or len(line.split('\t'))<10:
+                continue 
+            
+            wid = line.split('\t')[0]
+
+            # check if node is a comment (comments are marked with #)
+            if "#" in wid:
+                continue
+            
+            # check if node is a contraction (multiexp lines are marked with .)
+            if clean_contractions and "-" in wid:    
+                continue
+            
+            # check if node is an omited word (empty nodes are marked with .)
+            if clean_omisions and "." in wid:
+                continue
+
+            conll_node = D_Node.from_string(line)
+            nodes.append(conll_node)
+        
+        return D_Tree(nodes)
+    
+    @staticmethod
+    def read_conllu_file(file_path, filter_projective = True):
+        '''
+        Read a conllu file and return a list of ConllTree objects.
+        '''
+        with open(file_path, 'r') as f:
+            data = f.read()
+        data = data.split('\n\n')
+        # remove last empty line
+        data = data[:-1]
+        
+        trees = []
+        for x in data:
+            t = D_Tree.from_string(x)
+            if not filter_projective or t.is_projective():
+                trees.append(t)
+        return trees    
+
+    @staticmethod
+    def write_conllu_file(file_path, trees):
+        '''
+        Write a list of ConllTree objects to a conllu file.
+        '''
+        with open(file_path, 'w') as f:
+            f.write("".join(str(e) for e in trees))
+
+    @staticmethod
+    def write_conllu(file_io, tree):
+        '''
+        Write a single ConllTree to a already open file.
+        Includes the # text = ... line
+        '''
+        file_io.write("# text = "+tree.get_sentence()+"\n")
+        file_io.write("".join(str(e) for e in tree)+"\n")
\ No newline at end of file
diff --git a/tania_scripts/supar/codelin/models/linearized_tree.py b/tania_scripts/supar/codelin/models/linearized_tree.py
new file mode 100644
index 0000000..1619b31
--- /dev/null
+++ b/tania_scripts/supar/codelin/models/linearized_tree.py
@@ -0,0 +1,179 @@
+from supar.codelin.utils.constants import BOS, EOS, C_NO_POSTAG_LABEL
+from supar.codelin.models.const_label import C_Label
+from supar.codelin.models.deps_label import D_Label
+
+class LinearizedTree:
+    def __init__(self, words, postags, additional_feats, labels, n_feats):
+        self.words = words
+        self.postags = postags
+        self.additional_feats = additional_feats
+        self.labels = labels
+        #len(f_idx_dict.keys()) = n_feats
+        
+    def get_sentence(self):
+        return "".join(self.words)
+    
+    def get_labels(self):
+        return self.labels
+
+    def get_word(self, index):
+        return self.words[index]
+
+    def get_postag(self, index):
+        return self.postags[index]
+    
+    def get_additional_feat(self, index):
+        return self.additional_feats[index] if len(self.additional_feats) > 0 else None
+    
+    def get_label(self, index):
+        return self.labels[index]
+    
+    def reverse_tree(self, ignore_bos_eos=True):
+        '''
+        Reverses the lists of words, postags, additional_feats and labels.
+        Do not reverses the first (BOS) and last (EOS) elements
+        '''
+        if ignore_bos_eos:
+            self.words = self.words[1:-1][::-1]
+            self.postags = self.postags[1:-1][::-1]
+            self.additional_feats = self.additional_feats[1:-1][::-1]
+            self.labels = self.labels[1:-1][::-1]
+        else:
+            self.words = self.words[::-1]
+            self.postags = self.postags[::-1]
+            self.additional_feats = self.additional_feats[::-1]
+            self.labels = self.labels[::-1]
+
+    def add_row(self, word, postag, additional_feat, label):
+        self.words.append(word)
+        self.postags.append(postag)
+        self.additional_feats.append(additional_feat)
+        self.labels.append(label)
+    
+    def iterrows(self):
+        for i in range(len(self)):
+            yield self.get_word(i), self.get_postag(i), self.get_additional_feat(i), self.get_label(i)
+            
+    def __len__(self):
+        return len(self.words)
+
+    def __repr__(self):        
+        return self.to_string()
+    
+    def to_string(self, f_idx_dict=None, add_bos_eos=True):
+        if add_bos_eos:
+            self.words = [BOS] + self.words + [EOS]
+            self.postags = [BOS] + self.postags + [EOS]
+            if f_idx_dict:
+                self.additional_feats = [len(f_idx_dict.keys()) * [BOS]] + self.additional_feats + [len(f_idx_dict.keys()) * [EOS]]
+            else:
+                self.additional_feats = []
+            
+            self.labels = [BOS] + self.labels + [EOS]
+        
+        tree_string = ""
+        for w, p, af, l in self.iterrows():
+            # create the output line of the linearized tree
+            output_line = [w,p]
+            
+            # check for features
+            if f_idx_dict:
+                if w == BOS:
+                    f_list = [BOS] * (len(f_idx_dict.keys())+1)
+                elif w == EOS:
+                    f_list = [EOS] * (len(f_idx_dict.keys())+1)
+                else:
+                    f_list = ["_"] * (len(f_idx_dict.keys())+1)
+                
+                if af != [None]:
+                    for element in af:
+                        key, value = element.split("=", 1) if len(element.split("=",1))==2 else (None, None)
+                        if key in f_idx_dict.keys():
+                            f_list[f_idx_dict[key]] = value
+                
+                # append the additional elements or the placehodler
+                for element in f_list:
+                    output_line.append(element)
+
+            # add the label
+            output_line.append(str(l))
+            tree_string+=u"\t".join(output_line)+u"\n"
+        
+        if add_bos_eos:
+            self.words = self.words[1:-1]
+            self.postags = self.postags[1:-1]
+            if f_idx_dict:
+                self.additional_feats = self.additional_feats[len(f_idx_dict.keys()):-len(f_idx_dict.keys())]
+            self.labels = self.labels[1:-1]
+
+        return tree_string
+
+    @staticmethod
+    def empty_tree(n_feats = 1):
+        temp_tree = LinearizedTree(labels=[], words=[], postags=[], additional_feats=[], n_feats=n_feats)
+        return temp_tree
+
+    @staticmethod
+    def from_string(content, mode, separator="_", unary_joiner="|", n_features=0):
+        '''
+        Reads a linearized tree from a string shaped as
+        -BOS- \t -BOS- \t (...) \t -BOS- \n
+        word \t postag \t (...) \t label \n
+        word \t postag \t (...) \t label \n
+        -EOS- \t -EOS- \t (...) \t -EOS- \n
+        '''
+        labels = []
+        words  = []
+        postags = []
+        additional_feats = []
+        
+        linearized_tree = None
+        for line in content.split("\n"):
+            if line=="\n":
+                print("Empty line")
+            # skip empty line
+            if len(line) <= 1:
+                continue
+
+            # Separate the label file into columns
+            line_columns = line.split("\t") if ("\t") in line else line.split(" ")
+            word = line_columns[0]
+
+            if BOS == word:
+                labels = []
+                words  = []
+                postags = []
+                additional_feats = []
+
+                continue
+            
+            if EOS == word:
+                linearized_tree = LinearizedTree(words, postags, additional_feats, labels, n_features)
+                continue
+
+            if len(line_columns) == 2:
+                word, label = line_columns
+                postag = C_NO_POSTAG_LABEL
+                feats = "_"
+            elif len(line_columns) == 3:
+                word, postag, label = line_columns[0], line_columns[1], line_columns[2]
+                feats = "_"
+            else:
+                word, postag, *feats, label = line_columns[0], line_columns[1], line_columns[1:-1], line_columns[-1]
+            
+            # Check for predictions with no label
+            if BOS in label or EOS in label:
+                label = "1"+separator+"ROOT"
+
+            words.append(word)
+            postags.append(postag)
+            if mode == "CONST":
+                labels.append(C_Label.from_string(label, separator, unary_joiner))
+            elif mode == "DEPS":
+                labels.append(D_Label.from_string(label, separator))
+            else:
+                raise ValueError("[!] Unknown mode: %s" % mode)
+            
+            additional_feats.append(feats)
+
+        return linearized_tree
\ No newline at end of file
diff --git a/tania_scripts/supar/codelin/utils/__init__.py b/tania_scripts/supar/codelin/utils/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tania_scripts/supar/codelin/utils/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/codelin/utils/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e624705816d7181d4f932b5d47cf136958510862
GIT binary patch
literal 162
zcmd1j<>g{vU|`^5Uz84_AA<;F%*epN;K0DZP|U)>z>vZa%%I8Wx00a<B#a<_x$0-+
z=cekHB$i|*<|XPS<s_zLrWWZZ=jRsW>!uf!=;r39q~_=smlh;~L{n08GV}CHOEPnc
k_2c6+^D;}~<Mj$EZ*kb<=BJeAq}qXuFJ@w3U|?YY0H7}>LjV8(

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/utils/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/codelin/utils/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6d9b483a30076ad9fcf5cd79e963435945670210
GIT binary patch
literal 192
zcmZ3^%ge>Uz`&q*Uo`_nKL!yn%m`(CW@BJrn9h*G5X_*-=(m!gh>3xL;WJ3`SFnCY
zer~FMNn%N6VqT(NQchw@W@?dsa(-?>zHUisMTu@|Sz?ZUNn&1RVtjFOQD#9&v3_xB
zK_W;^N@`AKo_=XbW=^qwe0*kJW=VX!UP0wA4x8Nkl+v73yCPNw1_qETiuoBB7(OsF
PGBSQ(fDuK^3=9kaLEbTh

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/utils/__pycache__/constants.cpython-310.pyc b/tania_scripts/supar/codelin/utils/__pycache__/constants.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..653174b605a0b2dafa036c155f450c26128665e9
GIT binary patch
literal 1112
zcmd1j<>g{vU|`^5UzEO^nStRkh=Yt785kHG7#J9edl(oPQW&BbQW&EcQ<$QdQkbKd
zQ&^%{Qdpx{Q`n-|QrM%|Q#hhHQaGbHQ@EnIQn;hIQ+T3yQh1|yQ~09zQuw3zQv{*}
zQUs#}Q-q>~QiP*~Q$(UfQuv}oQ`n-!QrM%!Q$(XAQpBPpQ^cdBQY50JQzWBgQlz3}
zQv{;qQlz8gQ)HqPQe>kPQ{;jfH07&UbzS{~b*or)o&1A!Z?QW2`vr&GVsUW|2)@Pa
z>gRlm*~Qg4irLXAIEp#Q)hCMCCDJd7+0)NCio3X^D6u3yEwiY&B#H~d$w@3Oxy1=#
z=O$Lbg!A(AQmfc>{rvr0b*tEQ{rm$!R<h{^`TK`}takNt0f`5PI0l92R<Y>T)aXWW
zx`g`rM#j7Px!ht7@DGk+b_(*2Vsi@ejyDR3Vs#I4b#;m23<&ZMaCCPJaRr+i<m#gf
zvL@8WM>mQW;)?Xtl8n^ElqeoJw<tBoPgCg@v#WpbEoLYG;3!_Vc(AWMLqc8sLZW!w
z;$2(=T>V^J{hTAC*!%<HUHzQFG$<s5o#P#yg8h9$LtH`P{w|(=?oq<d@j<RWjv=05
zNP<Gn@h*{mj=rAG2!&$K@t%IpL9V{8ej$!N2ytHL_~4Kr$B=k8&!FItC>|Ks$1yl0
ziW|oBb&NnrfdUi61JUt5j!v#Vw*;Nz{ruwt{DVUr-629C1)xBN^0+}xae;Ecb~*-y
zK)E8$pipr0@pKM}4|WZ33~~(d4+7bZhzA~*c!X_H!Y<fC!Uao6@VS5-h48JAOT1H%
zqqDbb2trI0Q!L&n;1-ulyiq_rIJR$bg4v)bkK%HPcl8Yji3FucPO#}9UxI}FLVbKZ
zTpeAaxLx8wV)0-O7nBp^>a&ueh?ju@Li}>m&&bbB)h|gb$xO^k)Jw`qOvy|w(ofFM
zEy&kRFDTK?%}+_q(JwA7NCb(dq~>Ji>6eyd<`nBE=jRodB<7VA>lIYq;;_lhPbtkw
swFBk!ViyJm1{Nk3MmT0+VFW{v7>EVqgV>BLEMRpIHb@0TmWhKA0Gn+mj{pDw

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/utils/__pycache__/constants.cpython-311.pyc b/tania_scripts/supar/codelin/utils/__pycache__/constants.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ee60e7632471dbdadeb0deae1b865ffba40f7ef2
GIT binary patch
literal 1260
zcmZ3^%ge>Uz`&q*Uo~SlGXuk85C?`Cp^VRc3=9m@8B!Rc7*ZIc7*m*{m{ORdm{VAy
zSW;M{SX0=d*izV|*i$&7I8r#HI8(TyxKg;IxKntdcv5(ycvJYI_)_?z_)`R;1X2W}
z1XF~fgi?f~gi}PKL{j*oL{r$J#8TL!#8X70BvQnpBvZtrq*5fJq*ElLWKyJ}WK#s9
z<Wi)g<Wpp#6jEfP6jS7a88qdqSan_fgLSJ|b)Ec!b#Jjc`}+ll++uNY4G6x)?CR%y
zi`m81`4+RIQ}8Y3AXlGT%r23Bx0pTsoNsX#mlP$I#HVEz6_?!Nf^c#Yi%V{CLfE;9
z6)@qv{JhjEHeEk|KUdu<c3nUJ0Faezx<UT_At0+={aire!6A-8A-Yv8x-~Vrw>Vuw
zeSIV2UHx2cF$eeu-(q$O^1j996yzOm6mW~xJ;>G7<rZf^kbi)qyJLte*wi3bA6<|&
zp*}vkw|F70NKY-vNKH(+#RKOSrRMl)D&1ms1sm!ge2dpD9_(w+kWg2@kXt-%@h+|b
zu6{1Ae$J7%*!%<HLBRl`K_MaR9Pj89?C%pA;tCS?ck%Rdza{J(ALQ!e7~&a*Bq-z@
z?-J?f=<Df>P$=dc@9F0p<m&6{7vkuH5a)G{4-N@(42gI13<?gp#RKE|I0lE@;)d~j
z9U~A@puhz2Ky<v1qm!%8EkWmaKmYgu|KJcucc>7Lb37=Jp*(JoQ(T}Nu$_)UAyBS}
zGbj|?d_0{);)7iS9D^J~{DVMtBjSO_B_7E(VHa#6;esV3_*_7aLikq5CEh8>(b?NI
z1R*AhDF%vYE|++tfOu$ZgV~@czs2Pe@9G;65(!F?oM6*Iz61&Th5Gn-xH`Jr;&y@f
z9L(W@a)MlaRx*4B<;Pzk`WgATsrn^}C7FqNiF!#ni7A<>Mf%D4xdr*UC8-r9x~XM}
zIr=4ud6|jv#mPmP1trD$#ia#_AT=qeIhlF-r6rj;#rnzldBr7(c_qbq1(m-zY;yBc
zN^?@}imVwJ7(h9{_&5Ut!v|(YM#c|p4D5Uj%s1G08<-ymh&S-w;1_M+dBDlnz;**f
zeBfXZm$|?od_zncM2bpXU=X??DR+TE>;a#21Mdx9$p)SqJmL-9VAcl?1_6l%o*N>v
z7Z?O@@QXL_+~5;!;JzUs*}!{4T=oKk$PGTp25zXb2M{wMq@Y*>-wlZI5(*a>L?7^q
nG;o1T=KR3Hz$Xr3i!^ZF;1zA)dcY?OvQN5!3j~WS85kG<BE5f{

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/codelin/utils/constants.py b/tania_scripts/supar/codelin/utils/constants.py
new file mode 100644
index 0000000..66b0745
--- /dev/null
+++ b/tania_scripts/supar/codelin/utils/constants.py
@@ -0,0 +1,54 @@
+# COMMON CONSTANTS
+
+EOS = "-EOS-"
+BOS = "-BOS-"
+
+F_CONSTITUENT = "CONST"
+F_DEPENDENCY = "DEPS"
+
+OP_ENC = "ENC"
+OP_DEC = "DEC"
+
+# CONSTITUENT ENCODINGS
+
+C_ABSOLUTE_ENCODING = 'ABS'
+C_RELATIVE_ENCODING = 'REL'
+C_DYNAMIC_ENCODING = 'DYN'
+C_INCREMENTAL_ENCODING = 'INC'
+
+C_STRAT_FIRST="strat_first"
+C_STRAT_LAST="strat_last"
+C_STRAT_MAX="strat_max"
+C_STRAT_NONE="strat_none"
+
+# CONSTITUENT MISC
+
+C_NONE_LABEL = "-NONE-"
+C_NO_POSTAG_LABEL = "-NOPOS-"
+C_ROOT_LABEL = "-ROOT-"
+C_END_LABEL = "-END-"
+C_START_LABEL = "-START-"
+C_CONFLICT_SEPARATOR = "-||-"
+C_DUMMY_END = "DUMMY_END"
+
+# DEPENDENCIY ENCODINGS
+
+D_NONE_LABEL = "-NONE-"
+
+D_ABSOLUTE_ENCODING = 'ABS'
+D_RELATIVE_ENCODING = 'REL'
+D_POS_ENCODING = 'POS'
+D_BRACKET_ENCODING = 'BRK'
+D_BRACKET_ENCODING_2P = 'BRK_2P'
+
+D_2P_GREED = 'GREED'
+D_2P_PROP = 'PROPAGATE'
+
+# DEPENDENCY MISC
+
+D_EMPTYREL = "-NOREL-"
+D_POSROOT = "-ROOT-"
+D_NULLHEAD = "-NULL-"
+
+D_ROOT_HEAD = "strat_gethead"
+D_ROOT_REL = "strat_getrel"
diff --git a/tania_scripts/supar/codelin/utils/extract_feats.py b/tania_scripts/supar/codelin/utils/extract_feats.py
new file mode 100644
index 0000000..be867de
--- /dev/null
+++ b/tania_scripts/supar/codelin/utils/extract_feats.py
@@ -0,0 +1,41 @@
+import argparse
+from supar.codelin.models.const_tree import C_Tree
+from supar.codelin.models.deps_tree import D_Tree
+
+def extract_features_const(in_path):
+    file_in = open(in_path, "r")
+    feats_set = set()
+    for line in file_in:
+        line = line.rstrip()
+        tree = C_Tree.from_string(line)
+        tree.extract_features()
+        feats = tree.get_feature_names()
+        
+        feats_set = feats_set.union(feats)
+
+    return sorted(feats_set)
+
+def extract_features_deps(in_path):
+    feats_list=set()
+    trees = D_Tree.read_conllu_file(in_path, filter_projective=False)
+    for t in trees:
+        for node in t:
+            if node.feats != "_":
+                feats_list = feats_list.union(a for a in (node.feats.keys()))
+    return sorted(feats_list)
+    
+
+'''
+Python script that returns a ordered list of the features
+included in a conll tree or a constituent tree
+'''
+
+# parser = argparse.ArgumentParser(description='Prints all features in a constituent treebank')
+# parser.add_argument('form', metavar='formalism', type=str, choices=['CONST','DEPS'], help='Grammar encoding the file to extract features')
+# parser.add_argument('input', metavar='in file', type=str, help='Path of the file to clean (.trees file).')
+# args = parser.parse_args()
+# if args.form=='CONST':
+#     feats = extract_features_const(args.input)
+# elif args.form=='DEPS':
+#     feats = extract_features_conll(args.input)
+# print(" ".join(feats))
diff --git a/tania_scripts/supar/model.py b/tania_scripts/supar/model.py
new file mode 100644
index 0000000..f2d5277
--- /dev/null
+++ b/tania_scripts/supar/model.py
@@ -0,0 +1,249 @@
+# -*- coding: utf-8 -*-
+
+import torch
+import torch.nn as nn
+from torch.nn.utils.rnn import pack_padded_sequence, pad_packed_sequence
+
+from supar.modules import (CharLSTM, ELMoEmbedding, IndependentDropout,
+                           SharedDropout, TransformerEmbedding,
+                           TransformerWordEmbedding, VariationalLSTM)
+from supar.modules.transformer import (TransformerEncoder,
+                                       TransformerEncoderLayer)
+from supar.utils import Config
+#from supar.vector_quantize import VectorQuantize
+
+from vector_quantize_pytorch import VectorQuantize
+
+
+class Model(nn.Module):
+
+    def __init__(self,
+                 n_words,
+                 n_tags=None,
+                 n_chars=None,
+                 n_lemmas=None,
+                 encoder='lstm',
+                 feat=['tag', 'char'],
+                 n_embed=300,
+                 n_pretrained=100,
+                 n_feat_embed=100,
+                 n_char_embed=45,
+                 n_char_hidden=100,
+                 char_pad_index=0,
+                 char_dropout=0,
+                 elmo_bos_eos=(True, True),
+                 elmo_dropout=0.5,
+                 bert=None,
+                 n_bert_layers=4,
+                 mix_dropout=.0,
+                 bert_pooling='mean',
+                 bert_pad_index=0,
+                 finetune=False,
+                 n_plm_embed=0,
+                 embed_dropout=.33,
+                 encoder_dropout=.33,
+                 pad_index=0,
+
+                 n_decoder_layers: int = 2,
+                 bidirectional: bool = False,
+
+                 use_vq=False,
+                 vq_passes: int = 300,
+                 codebook_size=512,
+                 vq_decay=0.3,
+                 commitment_weight=3,
+
+                 **kwargs):
+        super().__init__()
+
+        self.args = Config().update(locals())
+
+        if encoder == 'lstm':
+            self.word_embed = nn.Embedding(num_embeddings=self.args.n_words,
+                                           embedding_dim=self.args.n_embed)
+
+            n_input = self.args.n_embed
+
+            if self.args.n_pretrained != self.args.n_embed:
+                n_input += self.args.n_pretrained
+            if 'tag' in self.args.feat:
+                self.tag_embed = nn.Embedding(num_embeddings=self.args.n_tags,
+                                              embedding_dim=self.args.n_feat_embed)
+                n_input += self.args.n_feat_embed
+
+            if 'char' in self.args.feat:
+                self.char_embed = CharLSTM(n_chars=self.args.n_chars,
+                                           n_embed=self.args.n_char_embed,
+                                           n_hidden=self.args.n_char_hidden,
+                                           n_out=self.args.n_feat_embed,
+                                           pad_index=self.args.char_pad_index,
+                                           dropout=self.args.char_dropout)
+                n_input += self.args.n_feat_embed
+                
+
+            if 'lemma' in self.args.feat:
+                self.lemma_embed = nn.Embedding(num_embeddings=self.args.n_lemmas,
+                                                embedding_dim=self.args.n_feat_embed)
+                n_input += self.args.n_feat_embed
+            if 'elmo' in self.args.feat:
+                self.elmo_embed = ELMoEmbedding(n_out=self.args.n_plm_embed,
+                                                bos_eos=self.args.elmo_bos_eos,
+                                                dropout=self.args.elmo_dropout,
+                                                finetune=self.args.finetune)
+                n_input += self.elmo_embed.n_out
+            if 'bert' in self.args.feat:
+                self.bert_embed = TransformerEmbedding(name=self.args.bert,
+                                                       n_layers=self.args.n_bert_layers,
+                                                       n_out=self.args.n_plm_embed,
+                                                       pooling=self.args.bert_pooling,
+                                                       pad_index=self.args.bert_pad_index,
+                                                       mix_dropout=self.args.mix_dropout,
+                                                       finetune=self.args.finetune)
+                n_input += self.bert_embed.n_out
+            self.embed_dropout = IndependentDropout(p=self.args.embed_dropout)
+            self.encoder = VariationalLSTM(
+                input_size=n_input,
+                hidden_size=self.args.n_encoder_hidden//2 if self.args.bidirectional else self.args.n_encoder_hidden,
+                num_layers=self.args.n_encoder_layers, bidirectional=self.args.bidirectional,
+                dropout=self.args.encoder_dropout)
+            self.encoder_dropout = SharedDropout(p=self.args.encoder_dropout)
+        elif encoder == 'transformer':
+            self.word_embed = TransformerWordEmbedding(n_vocab=self.args.n_words,
+                                                       n_embed=self.args.n_embed,
+                                                       pos=self.args.pos,
+                                                       pad_index=self.args.pad_index)
+            self.embed_dropout = nn.Dropout(p=self.args.embed_dropout)
+            self.encoder = TransformerEncoder(layer=TransformerEncoderLayer(n_heads=self.args.n_encoder_heads,
+                                                                            n_model=self.args.n_encoder_hidden,
+                                                                            n_inner=self.args.n_encoder_inner,
+                                                                            attn_dropout=self.args.encoder_attn_dropout,
+                                                                            ffn_dropout=self.args.encoder_ffn_dropout,
+                                                                            dropout=self.args.encoder_dropout),
+                                              n_layers=self.args.n_encoder_layers,
+                                              n_model=self.args.n_encoder_hidden)
+            self.encoder_dropout = nn.Dropout(p=self.args.encoder_dropout)
+        elif encoder == 'bert':
+            self.encoder = TransformerEmbedding(name=self.args.bert,
+                                                n_layers=self.args.n_bert_layers,
+                                                n_out=self.args.n_encoder_hidden,
+                                                pooling=self.args.bert_pooling,
+                                                pad_index=self.args.pad_index,
+                                                mix_dropout=self.args.mix_dropout,
+                                                finetune=self.args.finetune)
+            self.encoder_dropout = nn.Dropout(p=self.args.encoder_dropout)
+            self.args.n_encoder_hidden = self.encoder.n_out
+
+        self.passes_remaining = vq_passes
+        if use_vq:
+            self.vq = VectorQuantize(dim=self.args.n_encoder_hidden, codebook_size=codebook_size, decay=vq_decay,
+                                     commitment_weight=commitment_weight, eps=1e-5) #, wait_steps=0, observe_steps=vq_passes)
+        else:
+            self.vq = nn.Identity()
+
+    def load_pretrained(self, embed=None):
+        if embed is not None:
+            self.pretrained = nn.Embedding.from_pretrained(embed)
+            if embed.shape[1] != self.args.n_pretrained:
+                self.embed_proj = nn.Linear(embed.shape[1], self.args.n_pretrained)
+            nn.init.zeros_(self.word_embed.weight)
+        return self
+
+    def forward(self):
+        raise NotImplementedError
+
+    def vq_forward(self, x: torch.Tensor):
+        if not self.args.use_vq:
+            return x, torch.tensor(0)
+
+        if self.passes_remaining > (self.args.vq_passes / 2):
+            _, _, commit_loss, _ = self.vq(x)
+            self.passes_remaining -= 1
+        elif 0 < self.passes_remaining < (self.args.vq_passes / 2):
+            x_quantized, _, commit_loss, _ = self.vq(x)
+            x = torch.lerp(x, x_quantized, (self.passes_remaining - self.passes) / self.passes)
+            self.passes_remaining -= 1
+        else:
+            x, _, commit_loss, _ = self.vq(x)
+        qloss = commit_loss.squeeze()
+
+        return x, qloss
+
+    def loss(self):
+        raise NotImplementedError
+
+    def embed(self, words, feats=None):#feats=None
+        ext_words = words
+        # set the indices larger than num_embeddings to unk_index
+        if hasattr(self, 'pretrained'):
+            ext_mask = words.ge(self.word_embed.num_embeddings)
+            ext_words = words.masked_fill(ext_mask, self.args.unk_index)
+
+        # get outputs from embedding layers
+        word_embed = self.word_embed(ext_words)
+        if hasattr(self, 'pretrained'):
+            pretrained = self.pretrained(words)
+            if self.args.n_embed == self.args.n_pretrained:
+                word_embed += pretrained
+            else:
+                word_embed = torch.cat((word_embed, self.embed_proj(pretrained)), -1)
+        feat_embed = []
+
+        if 'tag' in self.args.feat:
+            feat_embed.append(self.tag_embed(feats.pop(0)))
+        if 'char' in self.args.feat:
+          
+            feat_embed.append(self.char_embed(feats.pop(0)))
+        if 'elmo' in self.args.feat:
+            feat_embed.append(self.elmo_embed(feats.pop(0)))
+        if 'bert' in self.args.feat:
+            feat_embed.append(self.bert_embed(feats.pop(0)))
+        if 'lemma' in self.args.feat:
+            feat_embed.append(self.lemma_embed(feats.pop(0)))
+        if isinstance(self.embed_dropout, IndependentDropout):
+            if len(feat_embed) == 0:
+                raise RuntimeError(f"`feat` is not allowed to be empty, which is {self.args.feat} now")
+            embed = torch.cat(self.embed_dropout(word_embed, torch.cat(feat_embed, -1)), -1)
+        else:
+            embed = word_embed
+            if len(feat_embed) > 0:
+                embed = torch.cat((embed, torch.cat(feat_embed, -1)), -1)
+            embed = self.embed_dropout(embed)
+        return embed
+
+    def encode(self, words, feats):#=None):
+        if self.args.encoder == 'lstm':
+            x = pack_padded_sequence(self.embed(words, feats), words.ne(self.args.pad_index).sum(1).tolist(), True, False)
+
+            x, _ = self.encoder(x)
+            x, _ = pad_packed_sequence(x, True, total_length=words.shape[1])
+        elif self.args.encoder == 'transformer':
+            x = self.encoder(self.embed(words, feats), words.ne(self.args.pad_index))
+        else:
+            x = self.encoder(words)
+        return self.encoder_dropout(x)
+
+    def decode(self):
+        raise NotImplementedError
+
+    def vq_forward(self, x: torch.Tensor):
+        if not self.args.use_vq:
+            return x, torch.tensor(0)
+
+        if self.passes_remaining > (self.args.vq_passes / 2):
+            _, _, commit_loss = self.vq(x)
+            self.passes_remaining -= 1
+        elif 0 < self.passes_remaining < (self.args.vq_passes / 2):
+            x_quantized, _, commit_loss = self.vq(x)
+            x = torch.lerp(x, x_quantized, (self.passes_remaining - self.passes) / self.passes)
+            self.passes_remaining -= 1
+        else:
+            x, indices, commit_loss  = self.vq(x)
+        qloss = commit_loss.squeeze()
+        return x, qloss
+    
+    @property 
+    def device(self):
+        if self.args.device == 'cpu':
+            return 'cpu'
+        else:
+            return f'cuda:{self.args.device}'
diff --git a/tania_scripts/supar/models/.ipynb_checkpoints/__init__-checkpoint.py b/tania_scripts/supar/models/.ipynb_checkpoints/__init__-checkpoint.py
new file mode 100644
index 0000000..e54ae9f
--- /dev/null
+++ b/tania_scripts/supar/models/.ipynb_checkpoints/__init__-checkpoint.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+
+from .const import (AttachJuxtaposeConstituencyParser, AttachJuxtaposeConstituencyParserPos, CRFConstituencyParser,
+                    TetraTaggingConstituencyParser, VIConstituencyParser, SLConstituentParser)
+from .dep import (BiaffineDependencyParser, CRF2oDependencyParser,
+                  CRFDependencyParser, VIDependencyParser,
+                  SLDependencyParser, ArcEagerDependencyParser)
+from .sdp import BiaffineSemanticDependencyParser, VISemanticDependencyParser
+
+__all__ = ['BiaffineDependencyParser',
+           'CRFDependencyParser',
+           'CRF2oDependencyParser',
+           'VIDependencyParser',
+           'AttachJuxtaposeConstituencyParser',
+           'CRFConstituencyParser',
+           'TetraTaggingConstituencyParser',
+           'VIConstituencyParser',
+           'SLConstituentParser',
+           'BiaffineSemanticDependencyParser',
+           'VISemanticDependencyParser',
+           'SLDependencyParser',
+           'ArcEagerDependencyParser']
\ No newline at end of file
diff --git a/tania_scripts/supar/models/__init__.py b/tania_scripts/supar/models/__init__.py
new file mode 100644
index 0000000..e54ae9f
--- /dev/null
+++ b/tania_scripts/supar/models/__init__.py
@@ -0,0 +1,22 @@
+# -*- coding: utf-8 -*-
+
+from .const import (AttachJuxtaposeConstituencyParser, AttachJuxtaposeConstituencyParserPos, CRFConstituencyParser,
+                    TetraTaggingConstituencyParser, VIConstituencyParser, SLConstituentParser)
+from .dep import (BiaffineDependencyParser, CRF2oDependencyParser,
+                  CRFDependencyParser, VIDependencyParser,
+                  SLDependencyParser, ArcEagerDependencyParser)
+from .sdp import BiaffineSemanticDependencyParser, VISemanticDependencyParser
+
+__all__ = ['BiaffineDependencyParser',
+           'CRFDependencyParser',
+           'CRF2oDependencyParser',
+           'VIDependencyParser',
+           'AttachJuxtaposeConstituencyParser',
+           'CRFConstituencyParser',
+           'TetraTaggingConstituencyParser',
+           'VIConstituencyParser',
+           'SLConstituentParser',
+           'BiaffineSemanticDependencyParser',
+           'VISemanticDependencyParser',
+           'SLDependencyParser',
+           'ArcEagerDependencyParser']
\ No newline at end of file
diff --git a/tania_scripts/supar/models/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4c56ad26f856966acabe985c3781a35035bb4d79
GIT binary patch
literal 742
zcmd1j<>g{vU|`^5UzC2FnStRkh=Yuo7#J8F7#J9eBN!MMQW#Pga~N_NqZo6UqL^}-
zqnLA9qF8cSqgWY1a!fgFx$IHwxg1d(xtvj)xm;0Px!h6Qxja!kV0q>o-dw&YzFht&
zeny6Lh7^`Xj8Ot9ticSLY%duZ7#K8JZz(#Klq4o+c$HR^Bo^csr#k276_;d|l&0n-
zR|X^&6{i;65_Jx8!y+sfl3G%f7?PNto|%`9MP4M#6N{*Dun$7C1Y(0G+bs#F%*3>`
z%)C^W)PmH!6g1n7@-c*korByk1ckypF~x#?FvKJri;`Uv(^HGkWi**?DZpG3oSK`M
zSCW~GuI83hm?thdP2M7Q1_p*AP7uKXB0!N{1d7ulW)PPJM6iMgHW0xJBKSZAH;CY2
zU|{gm6uiZn42lJu+HNtYq!vId0^0$$4QvtIlv~WjDFsDv<8QIY$0z3G#K*5>C=v$Q
z1R{Rf>1X8Urs|g@mSiU8CF&*RB&KAh7U?JF=N9DarWcgx=H{oQ=I9rf79<wwgW1LU
n@$s2?nI-Y@dIgoYIBatBQ%ZAE?LcX%7~~WgCIuz|W*#O0YAw@<

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9521805749c757cbf900e8dbd4ebb1339359dd88
GIT binary patch
literal 1043
zcmZ3^%ge>Uz`&q*Up3<mGXuk85C?{tpp4IP3=9m@8B!Qh7;_kM8KW3;nWC6-nWLC<
zS)y2SS)*8U*`nAOLGnyF?719K9J!oPoVi?4T)Es)+_^kaJh{A4ykL3e9KKxsDE?f5
zC;>)>bcPg`MT}8`DXhT^nrtr_85kHe*={L1mXstWXLyxXlq4497pFSs=M|S^mXxOE
zC07O{78R!!-BKZ_Bp|=|mZ)=(8y3xSA*m%ri6M#U>6v-ySmZ^*Jh6xh2m2sIOCavh
zWV<Edl$n^8mYJ98l3I|OmxAO*knKkK7{bENL2ej=LSdemV!=KbViJx;$*zg%sYU2A
znoPG8U@i$x%}vZJ$xKF9b4x1B6PKJOZxJU0149uvhybOBA|4Qn8APyx2sRMG4k9=}
z1V4xn01><(f{%fL!B11@7Hcvnu8P3gSU?h3^xk4lNiBfb2DS)nCD=B&QMZ_jQwoaU
zcHCl*k5A0WiH~2&@EMdKfBEQV<maa9mn4>CCgvsTCFLZhWTqDBC+FuD<m;BCR+Q+b
zmL=xsmn7z8CdL;h7iAWd6zdn479<ww=jNxR<`nD4$7kkcmc+;F6;%G>u*uC&Da}c>
zE0SPfU;rh;;;#%03?G;o85uvYF*3$8eqf*($->0w!1#fIW+WQ}qaWi12476{frW=#
R{R0DxXkZ7yA~6OA1^~TRC5iw5

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/__pycache__/__init__.cpython-39.pyc b/tania_scripts/supar/models/__pycache__/__init__.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..8ca2e6217fc9a781a4fd1f5df3b0ce2c9a6ddf79
GIT binary patch
literal 731
zcmYe~<>g{vU|`_PGe|$q%)sy%#6iYP3=9ko3=9m#5ey6rDGVu$ISjdsQH;4vQB1ka
zQOvn4Q7pNvQLKz0Ii?)8T=ppTT#hJ?T+S%YT&^gtT<$3DT%IT%usm}PZ!TXHUoL+X
zKO;jrLki0x#wdXl)?fxrwwH_y3=EpAw-g;qN)nSZyh<xd5)1N+Q=Rkkic2y}N>lTa
zD+3aXic^bji8=?lVG))KNi8W#3`tB+&&*55A}<o=iA7X6*asn60<l4p?Usa7W@1`e
zW?rgGYC&pV3YzUk`53~&&OvS%f<j@Qm}0>`7-ABRMaiy->8VBNGMY@c6ksk1PR&is
zE6GeoS941$%oCTKCT|ft0|P@5Cy3wx5unH}0>x<&Gl<IqB3MBL8;IZq5quzm8$|Fh
zFfjOO3f^K(2E_tSZMT?HQVSp!f$ad>2DS)pN)&T(N<k6a_*?Ap@rgM(@$oAeiiAKm
zfrwwG`WgATsrn^}C7FqNiF!#ni7A<>Mf#a}$pwi;`o*OnGB-aZHK$lVK0Y%qvm`!V
dub}c4hfQvNN@-529mq$;Ab-d(DKHB#0RX63&w2m=

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/__init__.py b/tania_scripts/supar/models/const/__init__.py
new file mode 100644
index 0000000..1a15c16
--- /dev/null
+++ b/tania_scripts/supar/models/const/__init__.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+
+from .aj import (AttachJuxtaposeConstituencyModel,AttachJuxtaposeConstituencyModelPos,
+                 AttachJuxtaposeConstituencyParser, AttachJuxtaposeConstituencyParserPos)
+from .crf import CRFConstituencyModel, CRFConstituencyParser
+from .tt import TetraTaggingConstituencyModel, TetraTaggingConstituencyParser
+from .vi import VIConstituencyModel, VIConstituencyParser
+from .sl import SLConstituentParser, SLConstituentModel
+
+__all__ = ['AttachJuxtaposeConstituencyModel', 'AttachJuxtaposeConstituencyModelPos',   'AttachJuxtaposeConstituencyParser', 'AttachJuxtaposeConstituencyParserPos',
+           'CRFConstituencyModel', 'CRFConstituencyParser',
+           'TetraTaggingConstituencyModel', 'TetraTaggingConstituencyParser',
+           'VIConstituencyModel', 'VIConstituencyParser',
+           'SLConstituentModel', 'SLConstituentParser']
diff --git a/tania_scripts/supar/models/const/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/const/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9d250b33146033de8f6e222867a4f01c6f2d8a54
GIT binary patch
literal 758
zcmd1j<>g{vU|{h1`zJk<nStRkh=Yuo7#J8F7#J9eQy3T+QW#Pga~N_NqZo6UqL^}-
zqnLA9qF5L~;!HWLxolBvx$IHwU_NsWM=oa+XD(M17nskI!=1|$#goe$#S7-M=J4h6
zNAc$hL<ul5q%)+jEn<ukOkodZ(Byc@$iTp$$#P4<v7{t1Im4^8q9m~(zc|%7Kd-nX
zv!paNFS*h;KP5HimNFp~0r|zZ6!9nuNGvK&ExM&bP)R_3u_n_k5$7N`Ojn4ai9!t3
zWV$6Al3G%f7?PNto|%`9sZS1<G~58;Fi%WvBB+80#lb!Z#U&8oTS6#;;84@#DFQ`m
z5i<h=LlFyzU<DCuAc7r4aDWI-5CKXWMcg13FNok_U|{gm6pCU>%)(~GE#~B+v?91U
zx0p&wir{A5Vk*llf}3}XsW_(yWLy!*;9KnR@rgM(@$oAeiiANHfrww$`WgATsrn^}
zC7FqNiF!#ni7A<>Mf#a}$pwi;`o*OnG8dE#iuIF0DMLR#J~J<~BtBlRpz;=nO>TZl
XX-=vgC@mF(Y?5FSU=m;iK^`UmF%R03

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/const/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..24326643d82fa6033432ee9bbd7ebf061b74a4d0
GIT binary patch
literal 966
zcmZ3^%ge>Uz`&q%Uo|6>nStRkhy%k+P{!vp1_p-d3@HpLj5!Rsj8TlaOi@g^%u&p_
zEKw|sAaSM~)?BtIwp{iob}*kgha;CWiZhohiVMtV$>GlBiQ>uSjp7CKS#$Vu`J?!A
z1)>BP8PXY2*cLHH38t_IGiY+WWMp7q&}6x#;8;?Un4IBNT2Yc%kYAkYoS#=*l37xk
znwMPZo1c=Jb4!_!ih%s$TZ(uT1tb;~rxx8(A*duEzgUy$mWXqZ8>TBn(L^DJYBJrD
z4M{C2N(@O%PtVLt$J8f>OB!x~aF{2iHW5@ogyLWygyIs2@GT(}L2#&P@)R*MFfbIc
zfCyF)!3HAOK?Dbg-~<t%G*QG2V)1|oJ`lmnz`)?ADRhe|F$<d!x0sWQ(u&~b++r#z
zDT14Ii>WLVVcspK;+!IoaYZ15Z?VV6C+6hD$FF4g3`%gng7h=;b5r$85=$}@^Ah!v
zauQQAQ;YPI^K%RGbxTq!N_11p5_9xR67w<><BOAvG7CzI^@~dj5{vY6K?$Q+KN*x(
z^yA|*^D;}~<Mj$Ee{tC4=BJeAq}mlpFfcHHl34K}1_p)?%#4hTAJ`ZfqZmIhP)a^v
su(^N@-C*#&fDPSXu)Kf`-C!`kfDL_MVd1v;zyKo}*g>#JjDdjx07BIrcmMzZ

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/__pycache__/__init__.cpython-39.pyc b/tania_scripts/supar/models/const/__pycache__/__init__.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..19a59b8eb7ae83aa8e4089626004ec916d1b1ec8
GIT binary patch
literal 653
zcmYe~<>g{vU|`_PGe|$j#K7<v#6iYP3=9ko3=9m#F$@e0DGVu$ISjdsQH;4vQA~^=
zK2r{JE=v?kE^8Dkn9rQUmdhT+p34!%0p_#haOQGFapiJHafA7+IXt<%QM|c)QGARH
z=?p1six{K$Q`mzUG&x=}GB7Y`GTl;eEGbD$&hRR&C`l~HFHUvN&nqs;EGbRRORn_I
zPf5+WrHDsGKw?pGYLO<>EfMD+H%zUfXrgfCvLUG@MTsGa>FJqy>6rTDa7n`r5DxRi
z)Fy%|h)^8tgHT)o5xymaA_(@XCRY(C28x&&7#NCJKm;p@U;`2CAc6x#aDoVK5CMuz
zKTUxsro=3S##_wEMQI4#QA{NzMQ{_Mn94GX;HE?|73UOz3@HK`cZ)qfJ~1aJK7J)b
z5g*8S5b?`eKO;XkRlg*$Br`EDQ7<VcF(os#NIx?#xgfDfzqk}c=7Qp>SU(vQb^7t~
jnR%Hd@$q^EmA5!-a`RJ4b5iX<J}L&;B)}xV2!>1mws5rH

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/__init__-checkpoint.py b/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/__init__-checkpoint.py
new file mode 100644
index 0000000..1fe4855
--- /dev/null
+++ b/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/__init__-checkpoint.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+
+from .model import AttachJuxtaposeConstituencyModel, AttachJuxtaposeConstituencyModelPos
+from .parser import AttachJuxtaposeConstituencyParser, AttachJuxtaposeConstituencyParserPos
+
+__all__ = ['AttachJuxtaposeConstituencyModel', 'AttachJuxtaposeConstituencyModelPos', 'AttachJuxtaposeConstituencyParser', 'AttachJuxtaposeConstituencyParserPos']
diff --git a/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/model-checkpoint.py b/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/model-checkpoint.py
new file mode 100644
index 0000000..30de07c
--- /dev/null
+++ b/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/model-checkpoint.py
@@ -0,0 +1,786 @@
+# -*- coding: utf-8 -*-
+
+from typing import List, Tuple
+
+import torch
+import torch.nn as nn
+from supar.model import Model
+from supar.models.const.aj.transform import AttachJuxtaposeTree
+from supar.modules import GraphConvolutionalNetwork, MLP, DecoderLSTM
+from supar.utils import Config
+from supar.utils.common import INF
+from supar.utils.fn import pad
+
+class DecoderLSTMPos(nn.Module):
+    def __init__(self, input_dim, hidden_dim, output_dim, num_layers, dropout, device):
+        super().__init__()
+        self.lstm = nn.LSTM(input_dim, hidden_dim, num_layers=num_layers,
+                            batch_first=True, dropout=dropout)
+        self.classifier = nn.Linear(hidden_dim, output_dim)
+
+    def forward(self, x):
+        # x: [batch_size, seq_len, input_dim]
+        output, _ = self.lstm(x)
+        logits = self.classifier(output)
+        return logits
+
+class AttachJuxtaposeConstituencyModel(Model):
+    r"""
+    The implementation of AttachJuxtapose Constituency Parser :cite:`yang-deng-2020-aj`.
+
+    Args:
+        n_words (int):
+            The size of the word vocabulary.
+        n_labels (int):
+            The number of labels in the treebank.
+        n_tags (int):
+            The number of POS tags, required if POS tag embeddings are used. Default: ``None``.
+        n_chars (int):
+            The number of characters, required if character-level representations are used. Default: ``None``.
+        encoder (str):
+            Encoder to use.
+            ``'lstm'``: BiLSTM encoder.
+            ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``.
+            Default: ``'lstm'``.
+        feat (List[str]):
+            Additional features to use, required if ``encoder='lstm'``.
+            ``'tag'``: POS tag embeddings.
+            ``'char'``: Character-level representations extracted by CharLSTM.
+            ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible.
+            Default: [``'char'``].
+        n_embed (int):
+            The size of word embeddings. Default: 100.
+        n_pretrained (int):
+            The size of pretrained word embeddings. Default: 100.
+        n_feat_embed (int):
+            The size of feature representations. Default: 100.
+        n_char_embed (int):
+            The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50.
+        n_char_hidden (int):
+            The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100.
+        char_pad_index (int):
+            The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0.
+        elmo (str):
+            Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``.
+        elmo_bos_eos (Tuple[bool]):
+            A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs.
+            Default: ``(True, False)``.
+        bert (str):
+            Specifies which kind of language model to use, e.g., ``'bert-base-cased'``.
+            This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_.
+            Default: ``None``.
+        n_bert_layers (int):
+            Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features.
+            The final outputs would be weighted sum of the hidden states of these layers.
+            Default: 4.
+        mix_dropout (float):
+            The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0.
+        bert_pooling (str):
+            Pooling way to get token embeddings.
+            ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all.
+            Default: ``mean``.
+        bert_pad_index (int):
+            The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features.
+            Default: 0.
+        finetune (bool):
+            If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``.
+        n_plm_embed (int):
+            The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0.
+        embed_dropout (float):
+            The dropout ratio of input embeddings. Default: .33.
+        n_encoder_hidden (int):
+            The size of encoder hidden states. Default: 800.
+        n_encoder_layers (int):
+            The number of encoder layers. Default: 3.
+        encoder_dropout (float):
+            The dropout ratio of encoder layers. Default: .33.
+        n_gnn_layers (int):
+            The number of GNN layers. Default: 3.
+        gnn_dropout (float):
+            The dropout ratio of GNN layers. Default: .33.
+        pad_index (int):
+            The index of the padding token in the word vocabulary. Default: 0.
+        unk_index (int):
+            The index of the unknown token in the word vocabulary. Default: 1.
+
+    .. _transformers:
+        https://github.com/huggingface/transformers
+    """
+
+    def __init__(self,
+                 n_words,
+                 n_labels,
+                 n_tags=None,
+                 n_chars=None,
+                 encoder='lstm',
+                 feat=['char'],
+                 n_embed=100,
+                 n_pretrained=100,
+                 n_feat_embed=100,
+                 n_char_embed=50,
+                 n_char_hidden=100,
+                 char_pad_index=0,
+                 elmo='original_5b',
+                 elmo_bos_eos=(True, True),
+                 bert=None,
+                 n_bert_layers=4,
+                 mix_dropout=.0,
+                 bert_pooling='mean',
+                 bert_pad_index=0,
+                 finetune=False,
+                 n_plm_embed=0,
+                 embed_dropout=.33,
+                 n_encoder_hidden=800,
+                 n_encoder_layers=3,
+                 encoder_dropout=.33,
+                 n_gnn_layers=3,
+                 gnn_dropout=.33,
+                 pad_index=0,
+                 unk_index=1,
+                 **kwargs):
+        super().__init__(**Config().update(locals()))
+
+        # the last one represents the dummy node in the initial states
+        self.label_embed = nn.Embedding(n_labels+1, self.args.n_encoder_hidden)
+        self.gnn_layers = GraphConvolutionalNetwork(n_model=self.args.n_encoder_hidden,
+                                                    n_layers=self.args.n_gnn_layers,
+                                                    dropout=self.args.gnn_dropout)
+
+        self.node_classifier = nn.Sequential(
+            nn.Linear(2 * self.args.n_encoder_hidden, self.args.n_encoder_hidden // 2),
+            nn.LayerNorm(self.args.n_encoder_hidden // 2),
+            nn.ReLU(),
+            nn.Linear(self.args.n_encoder_hidden // 2, 1),
+        )
+        self.label_classifier = nn.Sequential(
+            nn.Linear(2 * self.args.n_encoder_hidden, self.args.n_encoder_hidden // 2),
+            nn.LayerNorm(self.args.n_encoder_hidden // 2),
+            nn.ReLU(),
+            nn.Linear(self.args.n_encoder_hidden // 2, 2 * n_labels),
+        )
+
+        # create delay projection
+        if self.args.delay != 0:
+            self.delay_proj = MLP(n_in=self.args.n_encoder_hidden * (self.args.delay+1),
+                                       n_out=self.args.n_encoder_hidden, dropout=gnn_dropout)
+
+        self.criterion = nn.CrossEntropyLoss()
+
+    def forward(
+        self,
+        words: torch.LongTensor,
+        feats: List[torch.LongTensor]
+    ) -> Tuple[torch.Tensor]:
+        r"""
+        Args:
+            words (~torch.LongTensor): ``[batch_size, seq_len]``.
+                Word indices.
+            feats (List[~torch.LongTensor]):
+                A list of feat indices.
+                The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``,
+                or ``[batch_size, seq_len]`` otherwise.
+                Default: ``None``.
+
+        Returns:
+            ~torch.Tensor:
+                Contextualized output hidden states of shape ``[batch_size, seq_len, n_model]`` of the input.
+        """
+        x = self.encode(words, feats)
+
+        # adjust lengths to allow delay predictions
+        if self.args.delay != 0:
+            x = torch.cat([x[:, i:(x.shape[1] - self.args.delay + i)] for i in range(self.args.delay + 1)], dim=2)
+            x = self.delay_proj(x)
+
+        # pass through vector quantization
+        x, qloss = self.vq_forward(x)
+
+        return x, qloss
+
+    def loss(
+        self,
+        x: torch.Tensor,
+        nodes: torch.LongTensor,
+        parents: torch.LongTensor,
+        news: torch.LongTensor,
+        mask: torch.BoolTensor
+    ) -> torch.Tensor:
+        r"""
+        Args:
+            x (~torch.Tensor): ``[batch_size, seq_len, n_model]``.
+                Contextualized output hidden states.
+            nodes (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The target node positions on rightmost chains.
+            parents (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The parent node labels of terminals.
+            news (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The parent node labels of juxtaposed targets and terminals.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens in each chart.
+
+        Returns:
+            ~torch.Tensor:
+                The training loss.
+        """
+
+        spans, s_node, x_node = None, [], []
+        actions = torch.stack((nodes, parents, news))
+        for t, action in enumerate(actions.unbind(-1)):
+            if t == 0:
+                x_span = self.label_embed(actions.new_full((x.shape[0], 1), self.args.n_labels))
+                span_mask = mask[:, :1]
+            else:
+                x_span = self.rightmost_chain(x, spans, mask, t)
+                span_lens = spans[:, :-1, -1].ge(0).sum(-1)
+                span_mask = span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max())))
+            x_rightmost = torch.cat((x_span, x[:, t].unsqueeze(1).expand_as(x_span)), -1)
+            s_node.append(self.node_classifier(x_rightmost).squeeze(-1))
+            # we found softmax is slightly better than sigmoid in the original paper
+            s_node[-1] = s_node[-1].masked_fill_(~span_mask, -INF).masked_fill(~span_mask.any(-1).unsqueeze(-1), 0)
+            x_node.append(torch.bmm(s_node[-1].softmax(-1).unsqueeze(1), x_span).squeeze(1))
+            spans = AttachJuxtaposeTree.action2span(action, spans, self.args.nul_index, mask[:, t])
+        attach_mask = x.new_tensor(range(self.args.n_labels)).eq(self.args.nul_index)
+        s_node, x_node = pad(s_node, -INF).transpose(0, 1), torch.stack(x_node, 1)
+        s_parent, s_new = self.label_classifier(torch.cat((x, x_node), -1)).chunk(2, -1)
+        s_parent = torch.cat((s_parent[:, :1].masked_fill(attach_mask, -INF), s_parent[:, 1:]), 1)
+        s_new = torch.cat((s_new[:, :1].masked_fill(~attach_mask, -INF), s_new[:, 1:]), 1)
+        node_loss = self.criterion(s_node[mask], nodes[mask])
+        label_loss = self.criterion(s_parent[mask], parents[mask]) + self.criterion(s_new[mask], news[mask])
+        return node_loss + label_loss
+
+    def decode(
+        self,
+        x: torch.Tensor,
+        mask: torch.BoolTensor,
+        beam_size: int = 1
+    ) -> List[List[Tuple]]:
+        r"""
+        Args:
+            x (~torch.Tensor): ``[batch_size, seq_len, n_model]``.
+                Contextualized output hidden states.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens in each chart.
+            beam_size (int):
+                Beam size for decoding. Default: 1.
+
+        Returns:
+            List[List[Tuple]]:
+                Sequences of factorized labeled trees.
+        """
+        tokenwise_predictions = []
+        spans = None
+        batch_size, *_ = x.shape
+        n_labels = self.args.n_labels
+        # [batch_size * beam_size, ...]
+        x = x.unsqueeze(1).repeat(1, beam_size, 1, 1).view(-1, *x.shape[1:])
+        mask = mask.unsqueeze(1).repeat(1, beam_size, 1).view(-1, *mask.shape[1:])
+        # [batch_size]
+        batches = x.new_tensor(range(batch_size)).long() * beam_size
+        # accumulated scores
+        scores = x.new_full((batch_size, beam_size), -INF).index_fill_(-1, x.new_tensor(0).long(), 0).view(-1)
+        for t in range(x.shape[1]):
+            if t == 0:
+                x_span = self.label_embed(batches.new_full((x.shape[0], 1), n_labels))
+                span_mask = mask[:, :1]
+            else:
+                x_span = self.rightmost_chain(x, spans, mask, t)
+                span_lens = spans[:, :-1, -1].ge(0).sum(-1)
+                span_mask = span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max())))
+            s_node = self.node_classifier(torch.cat((x_span, x[:, t].unsqueeze(1).expand_as(x_span)), -1)).squeeze(-1)
+            s_node = s_node.masked_fill_(~span_mask, -INF).masked_fill(~span_mask.any(-1).unsqueeze(-1), 0).log_softmax(-1)
+            # we found softmax is slightly better than sigmoid in the original paper
+            x_node = torch.bmm(s_node.exp().unsqueeze(1), x_span).squeeze(1)
+            s_parent, s_new = self.label_classifier(torch.cat((x[:, t], x_node), -1)).chunk(2, -1)
+            s_parent, s_new = s_parent.log_softmax(-1), s_new.log_softmax(-1)
+            if t == 0:
+                s_parent[:, self.args.nul_index] = -INF
+                s_new[:, s_new.new_tensor(range(self.args.n_labels)).ne(self.args.nul_index)] = -INF
+            s_node, nodes = s_node.topk(min(s_node.shape[-1], beam_size), -1)
+            s_parent, parents = s_parent.topk(min(n_labels, beam_size), -1)
+            s_new, news = s_new.topk(min(n_labels, beam_size), -1)
+            s_action = s_node.unsqueeze(2) + (s_parent.unsqueeze(2) + s_new.unsqueeze(1)).view(x.shape[0], 1, -1)
+            s_action = s_action.view(x.shape[0], -1)
+            k_beam, k_node, k_parent = s_action.shape[-1], parents.shape[-1] * news.shape[-1], news.shape[-1]
+            # [batch_size * beam_size, k_beam]
+            scores = scores.unsqueeze(-1) + s_action
+            # [batch_size, beam_size]
+            scores, cands = scores.view(batch_size, -1).topk(beam_size, -1)
+            # [batch_size * beam_size]
+            scores = scores.view(-1)
+            beams = cands.div(k_beam, rounding_mode='floor')
+            nodes = nodes.view(batch_size, -1).gather(-1, cands.div(k_node, rounding_mode='floor'))
+            indices = (batches.unsqueeze(-1) + beams).view(-1)
+            
+            #print('indices', indices)
+            parents = parents[indices].view(batch_size, -1).gather(-1, cands.div(k_parent, rounding_mode='floor') % k_parent)
+            news = news[indices].view(batch_size, -1).gather(-1, cands % k_parent)
+            action = torch.stack((nodes, parents, news)).view(3, -1)
+            tokenwise_predictions.append([t, [x[0] for x in action.tolist()]])
+            spans = spans[indices] if spans is not None else None
+            spans = AttachJuxtaposeTree.action2span(action, spans, self.args.nul_index, mask[:, t])
+            #print("SPANS", spans)
+        mask = mask.view(batch_size, beam_size, -1)[:, 0]
+        # select an 1-best tree for each sentence
+        spans = spans[batches + scores.view(batch_size, -1).argmax(-1)]
+        span_mask = spans.ge(0)
+        span_indices = torch.where(span_mask)
+        span_labels = spans[span_indices]
+        chart_preds = [[] for _ in range(x.shape[0])]
+        for i, *span in zip(*[s.tolist() for s in span_indices], span_labels.tolist()):
+            chart_preds[i].append(span)
+        kk = [chart_preds + tokenwise_predictions]
+        return kk
+
+    def rightmost_chain(
+        self,
+        x: torch.Tensor,
+        spans: torch.LongTensor,
+        mask: torch.BoolTensor,
+        t: int
+    ) -> torch.Tensor:
+        x_p, mask_p = x[:, :t], mask[:, :t]
+        lens = mask_p.sum(-1)
+        span_mask = spans[:, :-1, 1:].ge(0)
+        span_lens = span_mask.sum((-1, -2))
+        span_indices = torch.where(span_mask)
+        span_labels = spans[:, :-1, 1:][span_indices]
+        x_span = self.label_embed(span_labels)
+        x_span += x[span_indices[0], span_indices[1]] + x[span_indices[0], span_indices[2]]
+        node_lens = lens + span_lens
+        adj_mask = node_lens.unsqueeze(-1).gt(x.new_tensor(range(node_lens.max())))
+        x_mask = lens.unsqueeze(-1).gt(x.new_tensor(range(adj_mask.shape[-1])))
+        span_mask = ~x_mask & adj_mask
+        # concatenate terminals and spans
+        x_tree = x.new_zeros(*adj_mask.shape, x.shape[-1]).masked_scatter_(x_mask.unsqueeze(-1), x_p[mask_p])
+        x_tree = x_tree.masked_scatter_(span_mask.unsqueeze(-1), x_span)
+        adj = mask.new_zeros(*x_tree.shape[:-1], x_tree.shape[1])
+        adj_spans = lens.new_tensor(range(x_tree.shape[1])).view(1, 1, -1).repeat(2, x.shape[0], 1)
+        adj_spans = adj_spans.masked_scatter_(span_mask.unsqueeze(0), torch.stack(span_indices[1:]))
+        adj_l, adj_r, adj_w = *adj_spans.unbind(), adj_spans[1] - adj_spans[0]
+        adj_parent = adj_l.unsqueeze(-1).ge(adj_l.unsqueeze(-2)) & adj_r.unsqueeze(-1).le(adj_r.unsqueeze(-2))
+        # set the parent of root as itself
+        adj_parent.diagonal(0, 1, 2).copy_(adj_w.eq(t - 1))
+        adj_parent = adj_parent & span_mask.unsqueeze(1)
+        # closet ancestor spans as parents
+        adj_parent = (adj_w.unsqueeze(-2) - adj_w.unsqueeze(-1)).masked_fill_(~adj_parent, t).argmin(-1)
+        adj.scatter_(-1, adj_parent.unsqueeze(-1), 1)
+        adj = (adj | adj.transpose(-1, -2)).float()
+        x_tree = self.gnn_layers(x_tree, adj, adj_mask)
+        span_mask = span_mask.masked_scatter(span_mask, span_indices[2].eq(t - 1))
+        span_lens = span_mask.sum(-1)
+        x_tree, span_mask = x_tree[span_mask], span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max())))
+        x_span = x.new_zeros(*span_mask.shape, x.shape[-1]).masked_scatter_(span_mask.unsqueeze(-1), x_tree)
+        return x_span
+
+
+class AttachJuxtaposeConstituencyModelPos(Model):
+    r"""
+    The implementation of AttachJuxtapose Constituency Parser :cite:`yang-deng-2020-aj`.
+
+    Args:
+        n_words (int):
+            The size of the word vocabulary.
+        n_labels (int):
+            The number of labels in the treebank.
+        n_tags (int):
+            The number of POS tags, required if POS tag embeddings are used. Default: ``None``.
+        n_chars (int):
+            The number of characters, required if character-level representations are used. Default: ``None``.
+        encoder (str):
+            Encoder to use.
+            ``'lstm'``: BiLSTM encoder.
+            ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``.
+            Default: ``'lstm'``.
+        feat (List[str]):
+            Additional features to use, required if ``encoder='lstm'``.
+            ``'tag'``: POS tag embeddings.
+            ``'char'``: Character-level representations extracted by CharLSTM.
+            ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible.
+            Default: [``'char'``].
+        n_embed (int):
+            The size of word embeddings. Default: 100.
+        n_pretrained (int):
+            The size of pretrained word embeddings. Default: 100.
+        n_feat_embed (int):
+            The size of feature representations. Default: 100.
+        n_char_embed (int):
+            The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50.
+        n_char_hidden (int):
+            The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100.
+        char_pad_index (int):
+            The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0.
+        elmo (str):
+            Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``.
+        elmo_bos_eos (Tuple[bool]):
+            A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs.
+            Default: ``(True, False)``.
+        bert (str):
+            Specifies which kind of language model to use, e.g., ``'bert-base-cased'``.
+            This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_.
+            Default: ``None``.
+        n_bert_layers (int):
+            Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features.
+            The final outputs would be weighted sum of the hidden states of these layers.
+            Default: 4.
+        mix_dropout (float):
+            The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0.
+        bert_pooling (str):
+            Pooling way to get token embeddings.
+            ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all.
+            Default: ``mean``.
+        bert_pad_index (int):
+            The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features.
+            Default: 0.
+        finetune (bool):
+            If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``.
+        n_plm_embed (int):
+            The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0.
+        embed_dropout (float):
+            The dropout ratio of input embeddings. Default: .33.
+        n_encoder_hidden (int):
+            The size of encoder hidden states. Default: 800.
+        n_encoder_layers (int):
+            The number of encoder layers. Default: 3.
+        encoder_dropout (float):
+            The dropout ratio of encoder layers. Default: .33.
+        n_gnn_layers (int):
+            The number of GNN layers. Default: 3.
+        gnn_dropout (float):
+            The dropout ratio of GNN layers. Default: .33.
+        pad_index (int):
+            The index of the padding token in the word vocabulary. Default: 0.
+        unk_index (int):
+            The index of the unknown token in the word vocabulary. Default: 1.
+
+    .. _transformers:
+        https://github.com/huggingface/transformers
+    """
+
+    def __init__(self,
+                 n_words,
+                 n_labels,
+                 n_tags=16,
+                 n_chars=None,
+                 encoder='lstm',
+                 feat=['char', 'tag'],
+                 n_embed=100,
+                 n_pretrained=100,
+                 n_feat_embed=100,
+                 n_char_embed=50,
+                 n_char_hidden=100,
+                 char_pad_index=0,
+                 elmo='original_5b',
+                 elmo_bos_eos=(True, True),
+                 bert=None,
+                 n_bert_layers=4,
+                 mix_dropout=.0,
+                 bert_pooling='mean',
+                 bert_pad_index=0,
+                 finetune=False,
+                 n_plm_embed=0,
+                 embed_dropout=.33,
+                 n_encoder_hidden=800,
+                 n_encoder_layers=3,
+                 encoder_dropout=.33,
+                 n_gnn_layers=3,
+                 gnn_dropout=.33,
+                 pad_index=0,
+                 unk_index=1,
+                 **kwargs):
+        super().__init__(**Config().update(locals()))
+
+        # the last one represents the dummy node in the initial states
+        self.label_embed = nn.Embedding(n_labels+1, self.args.n_encoder_hidden)
+        self.gnn_layers = GraphConvolutionalNetwork(n_model=self.args.n_encoder_hidden,
+                                                    n_layers=self.args.n_gnn_layers,
+                                                    dropout=self.args.gnn_dropout)
+
+        self.node_classifier = nn.Sequential(
+            nn.Linear(2 * self.args.n_encoder_hidden, self.args.n_encoder_hidden // 2),
+            nn.LayerNorm(self.args.n_encoder_hidden // 2),
+            nn.ReLU(),
+            nn.Linear(self.args.n_encoder_hidden // 2, 1),
+        )
+        self.label_classifier = nn.Sequential(
+            nn.Linear(2 * self.args.n_encoder_hidden, self.args.n_encoder_hidden // 2),
+            nn.LayerNorm(self.args.n_encoder_hidden // 2),
+            nn.ReLU(),
+            nn.Linear(self.args.n_encoder_hidden // 2, 2 * n_labels),
+        )
+        self.pos_classifier = DecoderLSTMPos(
+                self.args.n_encoder_hidden, self.args.n_encoder_hidden, self.args.n_tags, 
+                num_layers=1, dropout=encoder_dropout, device=self.device
+            )
+        
+        #self.pos_tagger = nn.Identity()
+        # create delay projection
+        if self.args.delay != 0:
+            self.delay_proj = MLP(n_in=self.args.n_encoder_hidden * (self.args.delay+1),
+                                       n_out=self.args.n_encoder_hidden, dropout=gnn_dropout)
+
+        self.criterion = nn.CrossEntropyLoss()
+        
+    def encoder_forward(self, words: torch.Tensor, feats: List[torch.Tensor]) -> Tuple[torch.Tensor]:
+        """
+        Applies encoding forward pass. Maps a tensor of word indices (`words`) to their corresponding neural
+        representation.
+        Args:
+            words: torch.IntTensor ~ [batch_size, bos + pad(seq_len) + eos + delay]
+            feats: List[torch.Tensor]
+            lens: List[int]
+
+        Returns: x, qloss
+            x: torch.FloatTensor ~ [batch_size, bos + pad(seq_len) + eos, embed_dim]
+            qloss: torch.FloatTensor ~ 1
+
+        """
+
+        x = super().encode(words, feats)
+        s_tag = self.pos_classifier(x[:, 1:-(1+self.args.delay), :])
+
+        # adjust lengths to allow delay predictions
+        # x ~ [batch_size, bos + pad(seq_len) + eos, embed_dim]
+        if self.args.delay != 0:
+            x = torch.cat([x[:, i:(x.shape[1] - self.args.delay + i), :] for i in range(self.args.delay + 1)], dim=2)
+            x = self.delay_proj(x)
+
+        # pass through vector quantization
+        x, qloss = self.vq_forward(x)
+        return x, s_tag, qloss
+    
+    
+    def forward(
+        self,
+        words: torch.LongTensor,
+        feats: List[torch.LongTensor]
+    ) -> Tuple[torch.Tensor]:
+        r"""
+        Args:
+            words (~torch.LongTensor): ``[batch_size, seq_len]``.
+                Word indices.
+            feats (List[~torch.LongTensor]):
+                A list of feat indices.
+                The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``,
+                or ``[batch_size, seq_len]`` otherwise.
+                Default: ``None``.
+
+        Returns:
+            ~torch.Tensor:
+                Contextualized output hidden states of shape ``[batch_size, seq_len, n_model]`` of the input.
+        """
+        x, s_tag, qloss = self.encoder_forward(words, feats)
+
+        return x, s_tag, qloss
+
+    def loss(
+        self,
+        x: torch.Tensor,
+        nodes: torch.LongTensor,
+        parents: torch.LongTensor,
+        news: torch.LongTensor,
+        mask: torch.BoolTensor, s_tags: torch.LongTensor, tags: torch.LongTensor
+    ) -> torch.Tensor:
+        r"""
+        Args:
+            x (~torch.Tensor): ``[batch_size, seq_len, n_model]``.
+                Contextualized output hidden states.
+            nodes (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The target node positions on rightmost chains.
+            parents (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The parent node labels of terminals.
+            news (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The parent node labels of juxtaposed targets and terminals.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens in each chart.
+
+        Returns:
+            ~torch.Tensor:
+                The training loss.
+        """
+
+        spans, s_node, x_node = None, [], []
+        actions = torch.stack((nodes, parents, news))
+        for t, action in enumerate(actions.unbind(-1)):
+            if t == 0:
+                x_span = self.label_embed(actions.new_full((x.shape[0], 1), self.args.n_labels))
+                span_mask = mask[:, :1]
+            else:
+                x_span = self.rightmost_chain(x, spans, mask, t)
+                span_lens = spans[:, :-1, -1].ge(0).sum(-1)
+                span_mask = span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max())))
+            x_rightmost = torch.cat((x_span, x[:, t].unsqueeze(1).expand_as(x_span)), -1)
+            s_node.append(self.node_classifier(x_rightmost).squeeze(-1))
+            # we found softmax is slightly better than sigmoid in the original paper
+            s_node[-1] = s_node[-1].masked_fill_(~span_mask, -INF).masked_fill(~span_mask.any(-1).unsqueeze(-1), 0)
+            x_node.append(torch.bmm(s_node[-1].softmax(-1).unsqueeze(1), x_span).squeeze(1))
+            spans = AttachJuxtaposeTree.action2span(action, spans, self.args.nul_index, mask[:, t])
+        attach_mask = x.new_tensor(range(self.args.n_labels)).eq(self.args.nul_index)
+        s_node, x_node = pad(s_node, -INF).transpose(0, 1), torch.stack(x_node, 1)
+        s_parent, s_new = self.label_classifier(torch.cat((x, x_node), -1)).chunk(2, -1)
+        #s_postag = self.pos_classifier(x[:, 1:-(1+self.args.delay), :]).chunk(2, -1)
+        s_parent = torch.cat((s_parent[:, :1].masked_fill(attach_mask, -INF), s_parent[:, 1:]), 1)
+        s_new = torch.cat((s_new[:, :1].masked_fill(~attach_mask, -INF), s_new[:, 1:]), 1)
+        node_loss = self.criterion(s_node[mask], nodes[mask])
+        #print('node loss', node_loss)
+        label_loss = self.criterion(s_parent[mask], parents[mask]) + self.criterion(s_new[mask], news[mask])
+        #print('label loss', label_loss)
+
+        #print(s_tag[mask].shape, tags[mask].shape)
+        tag_loss = self.criterion(s_tags[mask], tags[mask])
+        #print('tag loss', tag_loss)
+        #tag_loss = self.pos_loss(s_tags, tags, mask)
+        print("node loss, label loss, tag loss", node_loss, label_loss, tag_loss, node_loss + label_loss + tag_loss)
+        return node_loss + label_loss + tag_loss
+
+    def decode(
+        self,
+        x: torch.Tensor,
+        mask: torch.BoolTensor,
+        beam_size: int = 1
+    ) -> List[List[Tuple]]:
+        r"""
+        Args:
+            x (~torch.Tensor): ``[batch_size, seq_len, n_model]``.
+                Contextualized output hidden states.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens in each chart.
+            beam_size (int):
+                Beam size for decoding. Default: 1.
+
+        Returns:
+            List[List[Tuple]]:
+                Sequences of factorized labeled trees.
+        """
+        tokenwise_predictions = []
+        spans = None
+        batch_size, *_ = x.shape
+        n_labels = self.args.n_labels
+        # [batch_size * beam_size, ...]
+        x = x.unsqueeze(1).repeat(1, beam_size, 1, 1).view(-1, *x.shape[1:])
+        mask = mask.unsqueeze(1).repeat(1, beam_size, 1).view(-1, *mask.shape[1:])
+        # [batch_size]
+        batches = x.new_tensor(range(batch_size)).long() * beam_size
+        # accumulated scores
+        scores = x.new_full((batch_size, beam_size), -INF).index_fill_(-1, x.new_tensor(0).long(), 0).view(-1)
+        for t in range(x.shape[1]):
+            if t == 0:
+                x_span = self.label_embed(batches.new_full((x.shape[0], 1), n_labels))
+                span_mask = mask[:, :1]
+            else:
+                x_span = self.rightmost_chain(x, spans, mask, t)
+                span_lens = spans[:, :-1, -1].ge(0).sum(-1)
+                span_mask = span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max())))
+            s_node = self.node_classifier(torch.cat((x_span, x[:, t].unsqueeze(1).expand_as(x_span)), -1)).squeeze(-1)
+            s_node = s_node.masked_fill_(~span_mask, -INF).masked_fill(~span_mask.any(-1).unsqueeze(-1), 0).log_softmax(-1)
+            # we found softmax is slightly better than sigmoid in the original paper
+            x_node = torch.bmm(s_node.exp().unsqueeze(1), x_span).squeeze(1)
+            s_parent, s_new = self.label_classifier(torch.cat((x[:, t], x_node), -1)).chunk(2, -1)
+            s_parent, s_new = s_parent.log_softmax(-1), s_new.log_softmax(-1)
+            if t == 0:
+                s_parent[:, self.args.nul_index] = -INF
+                s_new[:, s_new.new_tensor(range(self.args.n_labels)).ne(self.args.nul_index)] = -INF
+            s_node, nodes = s_node.topk(min(s_node.shape[-1], beam_size), -1)
+            s_parent, parents = s_parent.topk(min(n_labels, beam_size), -1)
+            s_new, news = s_new.topk(min(n_labels, beam_size), -1)
+            s_action = s_node.unsqueeze(2) + (s_parent.unsqueeze(2) + s_new.unsqueeze(1)).view(x.shape[0], 1, -1)
+            s_action = s_action.view(x.shape[0], -1)
+            k_beam, k_node, k_parent = s_action.shape[-1], parents.shape[-1] * news.shape[-1], news.shape[-1]
+            # [batch_size * beam_size, k_beam]
+            scores = scores.unsqueeze(-1) + s_action
+            # [batch_size, beam_size]
+            scores, cands = scores.view(batch_size, -1).topk(beam_size, -1)
+            # [batch_size * beam_size]
+            scores = scores.view(-1)
+            beams = cands.div(k_beam, rounding_mode='floor')
+            nodes = nodes.view(batch_size, -1).gather(-1, cands.div(k_node, rounding_mode='floor'))
+            indices = (batches.unsqueeze(-1) + beams).view(-1)
+            
+            #print('indices', indices)
+            parents = parents[indices].view(batch_size, -1).gather(-1, cands.div(k_parent, rounding_mode='floor') % k_parent)
+            news = news[indices].view(batch_size, -1).gather(-1, cands % k_parent)
+            action = torch.stack((nodes, parents, news)).view(3, -1)
+            tokenwise_predictions.append([t, [x[0] for x in action.tolist()]])
+            spans = spans[indices] if spans is not None else None
+            spans = AttachJuxtaposeTree.action2span(action, spans, self.args.nul_index, mask[:, t])
+            #print("SPANS", spans)
+        mask = mask.view(batch_size, beam_size, -1)[:, 0]
+        # select an 1-best tree for each sentence
+        spans = spans[batches + scores.view(batch_size, -1).argmax(-1)]
+        span_mask = spans.ge(0)
+        span_indices = torch.where(span_mask)
+        span_labels = spans[span_indices]
+        chart_preds = [[] for _ in range(x.shape[0])]
+        for i, *span in zip(*[s.tolist() for s in span_indices], span_labels.tolist()):
+            chart_preds[i].append(span)
+        kk = [chart_preds + tokenwise_predictions]
+        return kk
+
+    def rightmost_chain(
+        self,
+        x: torch.Tensor,
+        spans: torch.LongTensor,
+        mask: torch.BoolTensor,
+        t: int
+    ) -> torch.Tensor:
+        x_p, mask_p = x[:, :t], mask[:, :t]
+        lens = mask_p.sum(-1)
+        span_mask = spans[:, :-1, 1:].ge(0)
+        span_lens = span_mask.sum((-1, -2))
+        span_indices = torch.where(span_mask)
+        span_labels = spans[:, :-1, 1:][span_indices]
+        x_span = self.label_embed(span_labels)
+        x_span += x[span_indices[0], span_indices[1]] + x[span_indices[0], span_indices[2]]
+        node_lens = lens + span_lens
+        adj_mask = node_lens.unsqueeze(-1).gt(x.new_tensor(range(node_lens.max())))
+        x_mask = lens.unsqueeze(-1).gt(x.new_tensor(range(adj_mask.shape[-1])))
+        span_mask = ~x_mask & adj_mask
+        # concatenate terminals and spans
+        x_tree = x.new_zeros(*adj_mask.shape, x.shape[-1]).masked_scatter_(x_mask.unsqueeze(-1), x_p[mask_p])
+        x_tree = x_tree.masked_scatter_(span_mask.unsqueeze(-1), x_span)
+        adj = mask.new_zeros(*x_tree.shape[:-1], x_tree.shape[1])
+        adj_spans = lens.new_tensor(range(x_tree.shape[1])).view(1, 1, -1).repeat(2, x.shape[0], 1)
+        adj_spans = adj_spans.masked_scatter_(span_mask.unsqueeze(0), torch.stack(span_indices[1:]))
+        adj_l, adj_r, adj_w = *adj_spans.unbind(), adj_spans[1] - adj_spans[0]
+        adj_parent = adj_l.unsqueeze(-1).ge(adj_l.unsqueeze(-2)) & adj_r.unsqueeze(-1).le(adj_r.unsqueeze(-2))
+        # set the parent of root as itself
+        adj_parent.diagonal(0, 1, 2).copy_(adj_w.eq(t - 1))
+        adj_parent = adj_parent & span_mask.unsqueeze(1)
+        # closet ancestor spans as parents
+        adj_parent = (adj_w.unsqueeze(-2) - adj_w.unsqueeze(-1)).masked_fill_(~adj_parent, t).argmin(-1)
+        adj.scatter_(-1, adj_parent.unsqueeze(-1), 1)
+        adj = (adj | adj.transpose(-1, -2)).float()
+        x_tree = self.gnn_layers(x_tree, adj, adj_mask)
+        span_mask = span_mask.masked_scatter(span_mask, span_indices[2].eq(t - 1))
+        span_lens = span_mask.sum(-1)
+        x_tree, span_mask = x_tree[span_mask], span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max())))
+        x_span = x.new_zeros(*span_mask.shape, x.shape[-1]).masked_scatter_(span_mask.unsqueeze(-1), x_tree)
+        return x_span
+
+    
+    def pos_loss(self, pos_logits: torch.Tensor, pos_tags: torch.LongTensor, mask: torch.BoolTensor) -> torch.Tensor:
+        """
+        Args:
+            pos_logits (~torch.Tensor): [batch_size, seq_len, n_tags].
+            pos_tags (~torch.LongTensor): [batch_size, seq_len].
+            mask (~torch.BoolTensor): [batch_size, seq_len].
+
+        Returns:
+            torch.Tensor: The POS tagging loss.
+        """
+        loss_fn = nn.CrossEntropyLoss()
+        return loss_fn(pos_logits[mask], pos_tags[mask])
+
+    def decode_pos(self, s_tag: torch.Tensor):
+        """
+        Decode the most likely POS tags.
+
+        Args:
+            pos_logits (~torch.Tensor): [batch_size, seq_len, n_tags]
+            mask (~torch.BoolTensor): [batch_size, seq_len]
+
+        Returns:
+            List[List[int]]: POS tags per token for each sentence in the batch.
+        """
+        pos_preds = pos_logits.argmax(-1)
+        #return [seq[mask[i]].tolist() for i, seq in enumerate(pos_preds)]
+        return pos_preds
diff --git a/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/parser-checkpoint.py b/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/parser-checkpoint.py
new file mode 100644
index 0000000..543e828
--- /dev/null
+++ b/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/parser-checkpoint.py
@@ -0,0 +1,534 @@
+# -*- coding: utf-8 -*-
+
+import os
+from typing import Dict, Iterable, Set, Union
+
+import torch
+
+from supar.models.const.aj.model import AttachJuxtaposeConstituencyModel, AttachJuxtaposeConstituencyModelPos
+from supar.models.const.aj.transform import AttachJuxtaposeTree
+from supar.parser import Parser
+from supar.utils import Config, Dataset, Embedding
+from supar.utils.common import BOS, EOS, NUL, PAD, UNK
+from supar.utils.field import Field, RawField, SubwordField
+from supar.utils.logging import get_logger
+from supar.utils.metric import SpanMetric
+from supar.utils.tokenizer import TransformerTokenizer
+from supar.utils.transform import Batch
+from torch.nn.utils.rnn import pad_sequence
+
+
+logger = get_logger(__name__)
+
+
+def compute_pos_accuracy(pos_gold, pos_preds):
+    correct = 0
+    total = 0
+    for gold_seq, pred_seq in zip(pos_gold, pos_preds):
+        for g, p in zip(gold_seq, pred_seq):
+            if g == p:
+                correct += 1
+        total += len(gold_seq)
+    return correct, total
+
+
+    
+
+class AttachJuxtaposeConstituencyParser(Parser):
+    r"""
+    The implementation of AttachJuxtapose Constituency Parser :cite:`yang-deng-2020-aj`.
+    """
+
+    NAME = 'attach-juxtapose-constituency'
+    MODEL = AttachJuxtaposeConstituencyModel
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self.TREE = self.transform.TREE
+        self.NODE = self.transform.NODE
+        self.PARENT = self.transform.PARENT
+        self.NEW = self.transform.NEW
+
+    def train(
+        self,
+        train: Union[str, Iterable],
+        dev: Union[str, Iterable],
+        test: Union[str, Iterable],
+        epochs: int = 1000,
+        patience: int = 100,
+        batch_size: int = 5000,
+        update_steps: int = 1,
+        buckets: int = 32,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        beam_size: int = 1,
+        delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''},
+        equal: Dict = {'ADVP': 'PRT'},
+        verbose: bool = True,
+        **kwargs
+    ):
+        print("here")
+        return super().train(**Config().update(locals()))
+
+    def evaluate(
+        self,
+        data: Union[str, Iterable],
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        beam_size: int = 1,
+        delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''},
+        equal: Dict = {'ADVP': 'PRT'},
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().evaluate(**Config().update(locals()))
+
+    def predict(
+        self,
+        data: Union[str, Iterable],
+        pred: str = None,
+        lang: str = None,
+        prob: bool = False,
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        beam_size: int = 1,
+        verbose: bool = True,
+        **kwargs
+    ):
+
+        return super().predict(**Config().update(locals()))
+
+    def train_step(self, batch: Batch) -> torch.Tensor:
+        #print("TRAIN STEP")
+        words, *feats, trees, nodes, parents, news = batch
+        mask = batch.mask[:, (2+self.args.delay):]
+        x, s_tag, qloss = self.model(words, feats)
+        #print("s_tag", s_tag)
+        loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask) + qloss
+        return loss
+
+    @torch.no_grad()
+    def eval_step(self, batch: Batch) -> SpanMetric:
+        #print("EVAL STEP")
+        words, *feats, trees, nodes, parents, news = batch
+        #print("WORDS", words.shape, words)
+        mask = batch.mask[:, (2+self.args.delay):]
+        x, qloss = self.model(words, feats)
+        loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask) + qloss
+        chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size)
+        #print("CHART PREDS")
+        #print("self new vocab", self.NEW.vocab.items())
+        #print()
+        preds = [AttachJuxtaposeTree.build(tree, [(i, j, self.NEW.vocab[label]) for i, j, label in chart], {UNK, NUL})
+                 for tree, chart in zip(trees, chart_preds)]
+
+        for tree, chart in zip(trees, chart_preds):
+            print(tree, chart)
+
+        print()
+        for tree in trees:
+            print("ORIG TREE", tree)
+        print()
+        for tree in preds:
+            print("PRED TREE", tree)
+
+        print("=========================")
+
+        return SpanMetric(loss,
+                          [AttachJuxtaposeTree.factorize(tree, self.args.delete, self.args.equal) for tree in preds],
+                          [AttachJuxtaposeTree.factorize(tree, self.args.delete, self.args.equal) for tree in trees])
+
+    @torch.no_grad()
+    def pred_step(self, batch: Batch) -> Batch:
+        words, *feats, trees = batch
+        mask = batch.mask[:, (2+self.args.delay):]
+        x, _ = self.model(words, feats)
+        chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size)
+        chart_preds = chart_preds[0]
+        batch.trees = [AttachJuxtaposeTree.build(tree, [(i, j, self.NEW.vocab[label]) for i, j, label in chart], {UNK, NUL})
+                       for tree, chart in zip(trees, chart_preds)]
+        if self.args.prob:
+            raise NotImplementedError("Returning action probs are currently not supported yet.")
+
+        new_tokenwise_preds = []
+        for k, y in chart_preds[1:]:
+            new_tokenwise_preds.append([k, y[0], self.NEW.vocab[y[1]], self.NEW.vocab[y[2]]])
+
+        chart_preds = [[[x[0], x[1], self.NEW.vocab[x[2]]] for x in chart_preds[0]]] + new_tokenwise_preds
+        #for x in chart_preds[1:]:
+        #    new_item = [x[0], [x[1][0], self.NEW.vocab[x[1][1]], self.NEW.vocab[x[1][2]]]
+
+        return chart_preds #batch
+
+    @classmethod
+    def build(cls, path, min_freq=2, fix_len=20, **kwargs):
+        r"""
+        Build a brand-new Parser, including initialization of all data fields and model parameters.
+
+        Args:
+            path (str):
+                The path of the model to be saved.
+            min_freq (str):
+                The minimum frequency needed to include a token in the vocabulary. Default: 2.
+            fix_len (int):
+                The max length of all subword pieces. The excess part of each piece will be truncated.
+                Required if using CharLSTM/BERT.
+                Default: 20.
+            kwargs (Dict):
+                A dict holding the unconsumed arguments.
+        """
+
+        args = Config(**locals())
+        os.makedirs(os.path.dirname(path) or './', exist_ok=True)
+        if os.path.exists(path) and not args.build:
+            parser = cls.load(**args)
+            parser.model = cls.MODEL(**parser.args)
+            parser.model.load_pretrained(parser.transform.WORD[0].embed).to(parser.device)
+            return parser
+
+        logger.info("Building the fields")
+        TAG, CHAR = None, None
+        if args.encoder == 'bert':
+            t = TransformerTokenizer(args.bert)
+            pad_token = t.pad if t.pad else PAD
+            WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, eos=t.eos, fix_len=args.fix_len, tokenize=t, delay=args.delay)
+            WORD.vocab = t.vocab
+        else:
+            WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True, delay=args.delay)
+            if 'char' in args.feat:
+                CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, eos=EOS, fix_len=args.fix_len, delay=args.delay)
+        TAG = Field('tags', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True, delay=args.delay)
+        TREE = RawField('trees')
+        NODE, PARENT, NEW = Field('node', use_vocab=False), Field('parent', unk=UNK), Field('new', unk=UNK)
+        transform = AttachJuxtaposeTree(WORD=(WORD, CHAR), POS=TAG, TREE=TREE, NODE=NODE, PARENT=PARENT, NEW=NEW)
+
+        train = Dataset(transform, args.train, **args)
+        if args.encoder != 'bert':
+            WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x))
+            if CHAR is not None:
+                CHAR.build(train)
+        TAG.build(train)
+        PARENT, NEW = PARENT.build(train), NEW.build(train)
+        PARENT.vocab = NEW.vocab.update(PARENT.vocab)
+        args.update({
+            'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init,
+            'n_labels': len(NEW.vocab),
+            'n_tags': len(TAG.vocab) if TAG is not None else None,
+            'n_chars': len(CHAR.vocab) if CHAR is not None else None,
+            'char_pad_index': CHAR.pad_index if CHAR is not None else None,
+            'pad_index': WORD.pad_index,
+            'unk_index': WORD.unk_index,
+            'bos_index': WORD.bos_index,
+            'eos_index': WORD.eos_index,
+            'nul_index': NEW.vocab[NUL]
+        })
+        logger.info(f"{transform}")
+
+        logger.info("Building the model")
+        model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None)
+        logger.info(f"{model}\n")
+
+        parser = cls(args, model, transform)
+        parser.model.to(parser.device)
+        return parser
+
+def flatten(x):
+    result = []
+    for el in x:
+        if isinstance(el, list):
+            result.extend(flatten(el))
+        else:
+            result.append(el)
+    return result
+
+
+
+
+class AttachJuxtaposeConstituencyParserPos(Parser):
+    r"""
+    The implementation of AttachJuxtapose Constituency Parser :cite:`yang-deng-2020-aj`.
+    """
+
+    NAME = 'attach-juxtapose-constituency'
+    MODEL = AttachJuxtaposeConstituencyModelPos
+
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self.TREE = self.transform.TREE
+        self.NODE = self.transform.NODE
+        self.PARENT = self.transform.PARENT
+        self.NEW = self.transform.NEW
+        self.TAG = self.transform.POS
+        
+        #print(self.TAG)
+
+    def train(
+        self,
+        train: Union[str, Iterable],
+        dev: Union[str, Iterable],
+        test: Union[str, Iterable],
+        epochs: int = 1000,
+        patience: int = 100,
+        batch_size: int = 5000,
+        update_steps: int = 1,
+        buckets: int = 32,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        beam_size: int = 1,
+        delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''},
+        equal: Dict = {'ADVP': 'PRT'},
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().train(**Config().update(locals()))
+
+    def evaluate(
+        self,
+        data: Union[str, Iterable],
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        beam_size: int = 1,
+        delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''},
+        equal: Dict = {'ADVP': 'PRT'},
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().evaluate(**Config().update(locals()))
+
+    def predict(
+        self,
+        data: Union[str, Iterable],
+        pred: str = None,
+        lang: str = None,
+        prob: bool = False,
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        beam_size: int = 1,
+        verbose: bool = True,
+        **kwargs
+    ):
+
+        return super().predict(**Config().update(locals()))
+
+    def train_step(self, batch: Batch) -> torch.Tensor:
+        #print("TRAIN STEP")
+        words, *feats, postags, nodes, parents, news = batch
+        mask = batch.mask[:, (2+self.args.delay):]
+        x, s_tag, qloss = self.model(words, feats)
+        tags = feats[-1]
+        #loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask) + qloss + pos_logits
+        #loss = loss.mean()
+        loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask, s_tag, tags[:, 1:-1]) + qloss
+        
+        return loss
+
+    @torch.no_grad()
+    def eval_step(self, batch: Batch) -> SpanMetric:
+        
+        #print("EVAL STEP")
+        words, *feats, trees, nodes, parents, news = batch
+
+        tags = feats[-1]
+        #loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask) + qloss + pos_logits
+        #loss = loss.mean()
+        mask = batch.mask[:, (2+self.args.delay):]
+        x, s_tag, qloss = self.model(words, feats)
+        
+        loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask, s_tag, tags[:, 1:-1]) + qloss
+        chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size)
+        #print('CHART PREDS', chart_preds[0])
+
+        pos_preds = [[self.TAG.vocab[p.item()] for p in sent] for sent in s_tag.argmax(-1)]
+        trimmed_tags = [tag_seq[1:-1] for tag_seq in tags]
+        trimmed_tags_list = [x.cpu().tolist() for x in trimmed_tags]
+        pos_gold = [[self.TAG.vocab[p] for p in sent] for sent in trimmed_tags_list]
+
+        pos_correct, pos_total = compute_pos_accuracy(pos_gold, pos_preds)
+        pos_acc = pos_correct/pos_total
+        print(pos_acc)
+  
+        """
+        tags = [*feats[-1:]]
+        trimmed_tags = [tag_seq[1:-1] for tag_seq in tags[0]]
+        gtags = [*feats[-1:]][0].cpu().tolist()
+        gtags = [x[1:-1] for x in gtags]
+        mask = batch.mask[:, (2+self.args.delay):]
+        x, s_tag, qloss = self.model(words, feats)
+
+        tag_tensor = pad_sequence(trimmed_tags, batch_first=True, padding_value=self.TAG.pad_index).to(s_tag.device)
+
+        assert s_tag.shape[:2] == tag_tensor.shape[:2]
+        print("s_tag shape", s_tag.shape[:2], "tag_tensor shape", tag_tensor.shape[:2])
+        
+
+        loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask, s_tag, tag_tensor) + qloss
+
+        chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size)
+        #pos_preds = [self.TAG.vocab[x] for x in s_tag.argmax(-1)]
+
+        for tag_seq in gtags:
+            for pos in tag_seq:
+                assert 0 <= pos < len(self.TAG.vocab)
+        
+        pos_preds = [[self.TAG.vocab[p.item()] for p in sent] for sent in s_tag.argmax(-1)]
+        pos_gold = [[self.TAG.vocab[pos] for pos in tag_seq] for tag_seq in gtags]
+
+        #print("357!", len(pos_gold), len(pos_preds))
+        pos_correct, pos_total = compute_pos_accuracy(pos_gold, pos_preds)
+        print("358!", pos_correct, pos_total, pos_correct/pos_total)
+
+            
+        #print('%%% POS preds', pos_preds)
+        #print('%%%% POS gold', pos_gold)
+        """
+
+        #batch.trees = [AttachJuxtaposeTree.build(tree, [(i, j, self.NEW.vocab[label]) for i, j, label in chart], {UNK, NUL})
+         #              for tree, chart in zip(trees, chart_preds)]
+        #print(batch.trees)
+              
+        preds = [AttachJuxtaposeTree.build(tree, [[x[0], x[1], self.NEW.vocab[x[2]]] for x in chart], {UNK, NUL})
+                 for tree, chart in zip(trees, chart_preds[0])]
+        #print('POS preds', s_tag.argmax(-1))
+        #print("PREDS", len(preds))
+      
+
+        """
+        span_preds = [[x[0], x[1], self.NEW.vocab[x[2]]] for x in chart_preds[0][0]]
+        #print("new SPAN preds", span_preds)
+        verbalized_preds = []
+
+
+        for x in chart_preds[1:]:
+            new_item = [x[0], [x[1][0], self.NEW.vocab[x[1][1]], self.NEW.vocab[x[1][2]]]]
+            #print(new_item)
+            verbalized_preds.append(new_item)
+        """
+        
+        print("424", loss, pos_acc)
+        return SpanMetric(loss,
+                          [AttachJuxtaposeTree.factorize(tree, self.args.delete, self.args.equal) for tree in preds],
+                          [AttachJuxtaposeTree.factorize(tree, self.args.delete, self.args.equal) for tree in trees], pos_acc)
+
+    @torch.no_grad()
+    def pred_step(self, batch: Batch) -> Batch:
+        words, *feats, trees = batch
+        mask = batch.mask[:, (2+self.args.delay):]
+        x, s_tag, qloss = self.model(words, feats)
+        chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size)
+        #print('VHART PREDS: ', chart_preds)
+        #print('LEN VHART PREDS: ', len(chart_preds))
+
+        chart_preds = chart_preds[0]
+        batch.trees = [AttachJuxtaposeTree.build(tree, [(i, j, self.NEW.vocab[label]) for i, j, label in chart], {UNK, NUL})
+                       for tree, chart in zip(trees, chart_preds)]
+        if self.args.prob:
+            raise NotImplementedError("Returning action probs are currently not supported yet.")
+
+        new_tokenwise_preds = []
+        #for pred in chart_preds:
+        #    print("PRED", pred)
+        #    new_tokenwise_preds.append([k, y[0], self.NEW.vocab[y[1]], self.NEW.vocab[y[2]]])
+
+
+        span_preds = [[x[0], x[1], self.NEW.vocab[x[2]]] for x in chart_preds[0]] + new_tokenwise_preds
+        #print("new chart preds", span_preds)
+        verbalized_preds = []
+        for x in chart_preds[1:]:
+            new_item = [x[0], [x[1][0], self.NEW.vocab[x[1][1]], self.NEW.vocab[x[1][2]]]]
+            #print(new_item)
+            verbalized_preds.append(new_item)
+        #print('POS preds', s_tag.argmax(-1))
+        pos_preds = [self.TAG.vocab[x] for x in s_tag.argmax(-1)]
+        return span_preds, verbalized_preds, pos_preds #batch
+
+    @classmethod
+    def build(cls, path, min_freq=2, fix_len=20, **kwargs):
+        r"""
+        Build a brand-new Parser, including initialization of all data fields and model parameters.
+
+        Args:
+            path (str):
+                The path of the model to be saved.
+            min_freq (str):
+                The minimum frequency needed to include a token in the vocabulary. Default: 2.
+            fix_len (int):
+                The max length of all subword pieces. The excess part of each piece will be truncated.
+                Required if using CharLSTM/BERT.
+                Default: 20.
+            kwargs (Dict):
+                A dict holding the unconsumed arguments.
+        """
+
+        args = Config(**locals())
+        os.makedirs(os.path.dirname(path) or './', exist_ok=True)
+        if os.path.exists(path) and not args.build:
+            parser = cls.load(**args)
+            parser.model = cls.MODEL(**parser.args)
+            parser.model.load_pretrained(parser.transform.WORD[0].embed).to(parser.device)
+            return parser
+
+        logger.info("Building the fields")
+        TAG, CHAR = None, None
+        if args.encoder == 'bert':
+            t = TransformerTokenizer(args.bert)
+            pad_token = t.pad if t.pad else PAD
+            WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, eos=t.eos, fix_len=args.fix_len, tokenize=t, delay=args.delay)
+            WORD.vocab = t.vocab
+        else:
+            WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True, delay=args.delay)
+            if 'char' in args.feat:
+                CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, eos=EOS, fix_len=args.fix_len, delay=args.delay)
+        TAG = Field('tags', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True, delay=args.delay)
+        TREE = RawField('trees')
+        NODE, PARENT, NEW = Field('node', use_vocab=False), Field('parent', unk=UNK), Field('new', unk=UNK)
+        transform = AttachJuxtaposeTree(WORD=(WORD, CHAR), POS=TAG, TREE=TREE, NODE=NODE, PARENT=PARENT, NEW=NEW)
+
+        train = Dataset(transform, args.train, **args)
+        if args.encoder != 'bert':
+            WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x))
+            if CHAR is not None:
+                CHAR.build(train)
+        TAG.build(train)
+        #print("203 TAG VOCAB", [x for x in TAG.vocab.items()])
+        PARENT, NEW = PARENT.build(train), NEW.build(train)
+        PARENT.vocab = NEW.vocab.update(PARENT.vocab)
+        args.update({
+            'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init,
+            'n_labels': len(NEW.vocab),
+            'n_tags': len(TAG.vocab) if TAG is not None else None,
+            'n_chars': len(CHAR.vocab) if CHAR is not None else None,
+            'char_pad_index': CHAR.pad_index if CHAR is not None else None,
+            'pad_index': WORD.pad_index,
+            'unk_index': WORD.unk_index,
+            'bos_index': WORD.bos_index,
+            'eos_index': WORD.eos_index,
+            'nul_index': NEW.vocab[NUL]
+        })
+        logger.info(f"{transform}")
+        
+        #print('TAG VOCAB', TAG.vocab.items())
+
+        logger.info("Building the model")
+        model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None)
+        logger.info(f"{model}\n")
+
+        parser = cls(args, model, transform)
+        parser.model.to(parser.device)
+        return parser
\ No newline at end of file
diff --git a/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/transform-checkpoint.py b/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/transform-checkpoint.py
new file mode 100644
index 0000000..56e0f51
--- /dev/null
+++ b/tania_scripts/supar/models/const/aj/.ipynb_checkpoints/transform-checkpoint.py
@@ -0,0 +1,459 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+import os
+from typing import TYPE_CHECKING, Iterable, List, Optional, Tuple, Union
+
+import nltk
+import torch
+
+from supar.models.const.crf.transform import Tree
+from supar.utils.common import NUL
+from supar.utils.logging import get_logger
+from supar.utils.tokenizer import Tokenizer
+from supar.utils.transform import Sentence
+
+if TYPE_CHECKING:
+    from supar.utils import Field
+
+logger = get_logger(__name__)
+
+
+class AttachJuxtaposeTree(Tree):
+    r"""
+    :class:`AttachJuxtaposeTree` is derived from the :class:`Tree` class,
+    supporting back-and-forth transformations between trees and AttachJuxtapose actions :cite:`yang-deng-2020-aj`.
+
+    Attributes:
+        WORD:
+            Words in the sentence.
+        POS:
+            Part-of-speech tags, or underscores if not available.
+        TREE:
+            The raw constituency tree in :class:`nltk.tree.Tree` format.
+        NODE:
+            The target node on each rightmost chain.
+        PARENT:
+            The label of the parent node of each terminal.
+        NEW:
+            The label of each newly inserted non-terminal with a target node and a terminal as juxtaposed children.
+            ``NUL`` represents the `Attach` action.
+    """
+
+    fields = ['WORD', 'POS', 'TREE', 'NODE', 'PARENT', 'NEW']
+
+    def __init__(
+        self,
+        WORD: Optional[Union[Field, Iterable[Field]]] = None,
+        POS: Optional[Union[Field, Iterable[Field]]] = None,
+        TREE: Optional[Union[Field, Iterable[Field]]] = None,
+        NODE: Optional[Union[Field, Iterable[Field]]] = None,
+        PARENT: Optional[Union[Field, Iterable[Field]]] = None,
+        NEW: Optional[Union[Field, Iterable[Field]]] = None
+    ) -> Tree:
+        super().__init__()
+
+        self.WORD = WORD
+        self.POS = POS
+        self.TREE = TREE
+        self.NODE = NODE
+        self.PARENT = PARENT
+        self.NEW = NEW
+
+    @property
+    def src(self):
+        return self.WORD, self.POS, self.TREE
+
+    @property
+    def tgt(self):
+        return self.NODE, self.PARENT, self.NEW
+
+    @classmethod
+    def tree2action(cls, tree: nltk.Tree):
+        r"""
+        Converts a constituency tree into AttachJuxtapose actions.
+
+        Args:
+            tree (nltk.tree.Tree):
+                A constituency tree in :class:`nltk.tree.Tree` format.
+
+        Returns:
+            A sequence of AttachJuxtapose actions.
+
+        Examples:
+            >>> from supar.models.const.aj.transform import AttachJuxtaposeTree
+            >>> tree = nltk.Tree.fromstring('''
+                                            (TOP
+                                              (S
+                                                (NP (_ Arthur))
+                                                (VP
+                                                  (_ is)
+                                                  (NP (NP (_ King)) (PP (_ of) (NP (_ the) (_ Britons)))))
+                                                (_ .)))
+                                            ''')
+            >>> tree.pretty_print()
+                            TOP
+                             |
+                             S
+               ______________|_______________________
+              |              VP                      |
+              |      ________|___                    |
+              |     |            NP                  |
+              |     |    ________|___                |
+              |     |   |            PP              |
+              |     |   |     _______|___            |
+              NP    |   NP   |           NP          |
+              |     |   |    |        ___|_____      |
+              _     _   _    _       _         _     _
+              |     |   |    |       |         |     |
+            Arthur  is King  of     the     Britons  .
+            >>> AttachJuxtaposeTree.tree2action(tree)
+            [(0, 'NP', '<nul>'), (0, 'VP', 'S'), (1, 'NP', '<nul>'),
+             (2, 'PP', 'NP'), (3, 'NP', '<nul>'), (4, '<nul>', '<nul>'),
+             (0, '<nul>', '<nul>')]
+        """
+
+        def isroot(node):
+            return node == tree[0]
+
+        def isterminal(node):
+            return len(node) == 1 and not isinstance(node[0], nltk.Tree)
+
+        def last_leaf(node):
+            pos = ()
+            while True:
+                pos += (len(node) - 1,)
+                node = node[-1]
+                if isterminal(node):
+                    return node, pos
+
+        def parent(position):
+            return tree[position[:-1]]
+
+        def grand(position):
+            return tree[position[:-2]]
+
+        def detach(tree):
+            last, last_pos = last_leaf(tree)
+            siblings = parent(last_pos)[:-1]
+
+            if len(siblings) > 0:
+                last_subtree = last
+                last_subtree_siblings = siblings
+                parent_label = NUL
+            else:
+                last_subtree, last_pos = parent(last_pos), last_pos[:-1]
+                last_subtree_siblings = [] if isroot(last_subtree) else parent(last_pos)[:-1]
+                parent_label = last_subtree.label()
+
+            target_pos, new_label, last_tree = 0, NUL, tree
+            if isroot(last_subtree):
+                last_tree = None
+            
+            elif len(last_subtree_siblings) == 1 and not isterminal(last_subtree_siblings[0]):
+                new_label = parent(last_pos).label()
+                new_label = new_label
+                target = last_subtree_siblings[0]
+                last_grand = grand(last_pos)
+                if last_grand is None:
+                    last_tree = targetistermina
+                else:
+                    last_grand[-1] = target
+                target_pos = len(last_pos) - 2
+            else:
+                target = parent(last_pos)
+                target.pop()
+                target_pos = len(last_pos) - 2
+            action = target_pos, parent_label, new_label
+            return action, last_tree
+        if tree is None:
+            return []
+        action, last_tree = detach(tree)
+        return cls.tree2action(last_tree) + [action]
+
+    @classmethod
+    def action2tree(
+        cls,
+        tree: nltk.Tree,
+        actions: List[Tuple[int, str, str]],
+        join: str = '::',
+    ) -> nltk.Tree:
+        r"""
+        Recovers a constituency tree from a sequence of AttachJuxtapose actions.
+
+        Args:
+            tree (nltk.tree.Tree):
+                An empty tree that provides a base for building a result tree.
+            actions (List[Tuple[int, str, str]]):
+                A sequence of AttachJuxtapose actions.
+            join (str):
+                A string used to connect collapsed node labels. Non-terminals containing this will be expanded to unary chains.
+                Default: ``'::'``.
+
+        Returns:
+            A result constituency tree.
+
+        Examples:
+            >>> from supar.models.const.aj.transform import AttachJuxtaposeTree
+            >>> tree = AttachJuxtaposeTree.totree(['Arthur', 'is', 'King', 'of', 'the', 'Britons', '.'], 'TOP')
+            >>> AttachJuxtaposeTree.action2tree(tree,
+                                                [(0, 'NP', '<nul>'), (0, 'VP', 'S'), (1, 'NP', '<nul>'),
+                                                 (2, 'PP', 'NP'), (3, 'NP', '<nul>'), (4, '<nul>', '<nul>'),
+                                                 (0, '<nul>', '<nul>')]).pretty_print()
+                            TOP
+                             |
+                             S
+               ______________|_______________________
+              |              VP                      |
+              |      ________|___                    |
+              |     |            NP                  |
+              |     |    ________|___                |
+              |     |   |            PP              |
+              |     |   |     _______|___            |
+              NP    |   NP   |           NP          |
+              |     |   |    |        ___|_____      |
+              _     _   _    _       _         _     _
+              |     |   |    |       |         |     |
+            Arthur  is King  of     the     Britons  .
+        """
+
+        def target(node, depth):
+            node_pos = ()
+            for _ in range(depth):
+                node_pos += (len(node) - 1,)
+                node = node[-1]
+            return node, node_pos
+
+        def parent(tree, position):
+            return tree[position[:-1]]
+
+        def execute(tree: nltk.Tree, terminal: Tuple(str, str), action: Tuple[int, str, str]) -> nltk.Tree:
+            target_pos, parent_label, new_label, post = action
+            #print(target_pos, parent_label, new_label)
+            new_leaf = nltk.Tree(post, [terminal[0]])
+
+            # create the subtree to be inserted
+            new_subtree = new_leaf if parent_label == NUL else nltk.Tree(parent_label, [new_leaf])
+            # find the target position at which to insert the new subtree
+            target_node = tree
+            if target_node is not None:
+                target_node, target_pos = target(target_node, target_pos)
+
+            # Attach
+            if new_label == NUL:
+                # attach the first token
+                if target_node is None:
+                    return new_subtree
+                target_node.append(new_subtree)
+            # Juxtapose
+            else:
+                new_subtree = nltk.Tree(new_label, [target_node, new_subtree])
+                if len(target_pos) > 0:
+                    parent_node = parent(tree, target_pos)
+                    parent_node[-1] = new_subtree
+                else:
+                    tree = new_subtree
+            return tree
+
+        tree, root, terminals = None, tree.label(), tree.pos()
+        for terminal, action in zip(terminals, actions):
+            tree = execute(tree, terminal, action)
+        # recover unary chains
+        nodes = [tree]
+        while nodes:
+            node = nodes.pop()
+            if isinstance(node, nltk.Tree):
+                nodes.extend(node)
+                if join in node.label():
+                    labels = node.label().split(join)
+                    node.set_label(labels[0])
+                    subtree = nltk.Tree(labels[-1], node)
+                    for label in reversed(labels[1:-1]):
+                        subtree = nltk.Tree(label, [subtree])
+                    node[:] = [subtree]
+        return nltk.Tree(root, [tree])
+
+    @classmethod
+    def action2span(
+        cls,
+        action: torch.Tensor,
+        spans: torch.Tensor = None,
+        nul_index: int = -1,
+        mask: torch.BoolTensor = None
+    ) -> torch.Tensor:
+        r"""
+        Converts a batch of the tensorized action at a given step into spans.
+
+        Args:
+            action (~torch.Tensor): ``[3, batch_size]``.
+                A batch of the tensorized action at a given step, containing indices of target nodes, parent and new labels.
+            spans (~torch.Tensor):
+                Spans generated at previous steps, ``None`` at the first step. Default: ``None``.
+            nul_index (int):
+                The index for the obj:`NUL` token, representing the Attach action. Default: -1.
+            mask (~torch.BoolTensor): ``[batch_size]``.
+                The mask for covering the unpadded tokens.
+
+        Returns:
+            A tensor representing a batch of spans for the given step.
+
+        Examples:
+            >>> from collections import Counter
+            >>> from supar.models.const.aj.transform import AttachJuxtaposeTree, Vocab
+            >>> from supar.utils.common import NUL
+            >>> nodes, parents, news = zip(*[(0, 'NP', NUL), (0, 'VP', 'S'), (1, 'NP', NUL),
+                                             (2, 'PP', 'NP'), (3, 'NP', NUL), (4, NUL, NUL),
+                                             (0, NUL, NUL)])
+            >>> vocab = Vocab(Counter(sorted(set([*parents, *news]))))
+            >>> actions = torch.tensor([nodes, vocab[parents], vocab[news]]).unsqueeze(1)
+            >>> spans = None
+            >>> for action in actions.unbind(-1):
+            ...     spans = AttachJuxtaposeTree.action2span(action, spans, vocab[NUL])
+            ...
+            >>> spans
+            tensor([[[-1,  1, -1, -1, -1, -1, -1,  3],
+                     [-1, -1, -1, -1, -1, -1,  4, -1],
+                     [-1, -1, -1,  1, -1, -1,  1, -1],
+                     [-1, -1, -1, -1, -1, -1,  2, -1],
+                     [-1, -1, -1, -1, -1, -1,  1, -1],
+                     [-1, -1, -1, -1, -1, -1, -1, -1],
+                     [-1, -1, -1, -1, -1, -1, -1, -1],
+                     [-1, -1, -1, -1, -1, -1, -1, -1]]])
+            >>> sequence = torch.where(spans.ge(0))
+            >>> sequence = list(zip(sequence[1].tolist(), sequence[2].tolist(), vocab[spans[sequence]]))
+            >>> sequence
+            [(0, 1, 'NP'), (0, 7, 'S'), (1, 6, 'VP'), (2, 3, 'NP'), (2, 6, 'NP'), (3, 6, 'PP'), (4, 6, 'NP')]
+            >>> tree = AttachJuxtaposeTree.totree(['Arthur', 'is', 'King', 'of', 'the', 'Britons', '.'], 'TOP')
+            >>> AttachJuxtaposeTree.build(tree, sequence).pretty_print()
+                            TOP
+                             |
+                             S
+               ______________|_______________________
+              |              VP                      |
+              |      ________|___                    |
+              |     |            NP                  |
+              |     |    ________|___                |
+              |     |   |            PP              |
+              |     |   |     _______|___            |
+              NP    |   NP   |           NP          |
+              |     |   |    |        ___|_____      |
+              _     _   _    _       _         _     _
+              |     |   |    |       |         |     |
+            Arthur  is King  of     the     Britons  .
+
+        """
+
+        # [batch_size]
+        target, parent, new = action
+        if spans is None:
+            spans = action.new_full((action.shape[1], 2, 2), -1)
+            spans[:, 0, 1] = parent
+            return spans
+        if mask is None:
+            mask = torch.ones_like(target, dtype=bool)
+        juxtapose_mask = new.ne(nul_index) & mask
+        # ancestor nodes are those on the rightmost chain and higher than the target node
+        # [batch_size, seq_len]
+        rightmost_mask = spans[..., -1].ge(0)
+        ancestors = rightmost_mask.cumsum(-1).masked_fill_(~rightmost_mask, -1) - 1
+        # should not include the target node for the Juxtapose action
+        ancestor_mask = mask.unsqueeze(-1) & ancestors.ge(0) & ancestors.le((target - juxtapose_mask.long()).unsqueeze(-1))
+        target_pos = torch.where(ancestors.eq(target.unsqueeze(-1))[juxtapose_mask])[-1]
+        # the right boundaries of ancestor nodes should be aligned with the new generated terminals
+        spans = torch.cat((spans, torch.where(ancestor_mask, spans[..., -1], -1).unsqueeze(-1)), -1)
+        spans[..., -2].masked_fill_(ancestor_mask, -1)
+        spans[juxtapose_mask, target_pos, -1] = new.masked_fill(new.eq(nul_index), -1)[juxtapose_mask]
+        spans[mask, -1, -1] = parent.masked_fill(parent.eq(nul_index), -1)[mask]
+        # [batch_size, seq_len+1, seq_len+1]
+        spans = torch.cat((spans, torch.full_like(spans[:, :1], -1)), 1)
+        return spans
+
+    def load(
+        self,
+        data: Union[str, Iterable],
+        lang: Optional[str] = None,
+        **kwargs
+    ) -> List[AttachJuxtaposeTreeSentence]:
+        r"""
+        Args:
+            data (Union[str, Iterable]):
+                A filename or a list of instances.
+            lang (str):
+                Language code (e.g., ``en``) or language name (e.g., ``English``) for the text to tokenize.
+                ``None`` if tokenization is not required.
+                Default: ``None``.
+
+        Returns:
+            A list of :class:`AttachJuxtaposeTreeSentence` instances.
+        """
+
+        if lang is not None:
+            tokenizer = Tokenizer(lang)
+        if isinstance(data, str) and os.path.exists(data):
+            if data.endswith('.txt'):
+                data = (s.split() if lang is None else tokenizer(s) for s in open(data) if len(s) > 1)
+            else:
+                data = open(data)
+        else:
+            if lang is not None:
+                data = [tokenizer(i) for i in ([data] if isinstance(data, str) else data)]
+            else:
+                data = [data] if isinstance(data[0], str) else data
+
+        index = 0
+        for s in data:
+
+            try:
+                tree = nltk.Tree.fromstring(s) if isinstance(s, str) else self.totree(s, self.root)
+                sentence = AttachJuxtaposeTreeSentence(self, tree, index)
+            except ValueError:
+                logger.warning(f"Error found while converting Sentence {index} to a tree:\n{s}\nDiscarding it!")
+                continue
+            except IndexError:
+                tree = nltk.Tree.fromstring('(S ' + s + ')')
+                sentence = AttachJuxtaposeTreeSentence(self, tree, index)
+            else:
+                yield sentence
+                index += 1
+        self.root = tree.label()
+
+
+class AttachJuxtaposeTreeSentence(Sentence):
+    r"""
+    Args:
+        transform (AttachJuxtaposeTree):
+            A :class:`AttachJuxtaposeTree` object.
+        tree (nltk.tree.Tree):
+            A :class:`nltk.tree.Tree` object.
+        index (Optional[int]):
+            Index of the sentence in the corpus. Default: ``None``.
+    """
+
+    def __init__(
+        self,
+        transform: AttachJuxtaposeTree,
+        tree: nltk.Tree,
+        index: Optional[int] = None
+    ) -> AttachJuxtaposeTreeSentence:
+        super().__init__(transform, index)
+
+        words, tags = zip(*tree.pos())
+        nodes, parents, news = None, None, None
+        if transform.training:
+            oracle_tree = tree.copy(True)
+            # the root node must have a unary chain
+            if len(oracle_tree) > 1:
+                oracle_tree[:] = [nltk.Tree('*', oracle_tree)]
+            oracle_tree.collapse_unary(joinChar='::')
+            if len(oracle_tree) == 1 and not isinstance(oracle_tree[0][0], nltk.Tree):
+                oracle_tree[0] = nltk.Tree('*', [oracle_tree[0]])
+            nodes, parents, news = zip(*transform.tree2action(oracle_tree))
+        tags = [x.split("##")[0] for x in tags]
+        self.values = [words, tags, tree, nodes, parents, news]
+
+    def __repr__(self):
+        return self.values[-4].pformat(1000000)
+
+    def pretty_print(self):
+        self.values[-4].pretty_print()
diff --git a/tania_scripts/supar/models/const/aj/__init__.py b/tania_scripts/supar/models/const/aj/__init__.py
new file mode 100644
index 0000000..1fe4855
--- /dev/null
+++ b/tania_scripts/supar/models/const/aj/__init__.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+
+from .model import AttachJuxtaposeConstituencyModel, AttachJuxtaposeConstituencyModelPos
+from .parser import AttachJuxtaposeConstituencyParser, AttachJuxtaposeConstituencyParserPos
+
+__all__ = ['AttachJuxtaposeConstituencyModel', 'AttachJuxtaposeConstituencyModelPos', 'AttachJuxtaposeConstituencyParser', 'AttachJuxtaposeConstituencyParserPos']
diff --git a/tania_scripts/supar/models/const/aj/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/const/aj/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..cf09a38138e561426e88c74ad582913e27d79d0e
GIT binary patch
literal 415
zcmd1j<>g{vU|`7k^C!KCk%8ech=Yuo7#J8F7#J9ebr={JQW#Pga~N_NqZo6UqL>&#
ze5M@cT$U)7T-GR7Muv2T6y`;YQEVwJ!3>(LFBusa7&Mt~DL9stBqnEgl~$A_7UUPF
zI_KvVmt>ZdrsgGA`sSyk=G;;yq#_`{Sd;0NA|7P{iABY!MYmK4DghbAQUvl=5i<h=
zLlFyzU}a!n@Y7_!#hMFp4?^}9TLIWygsNNY@$rc{Iq~r;8HzYTT0z7wJN=CO+*JLN
z#FEU!yhOdEoWzvO)FS=NyySw!BK_i05D7NASU(x$d;P>L{rLFIyv&mLc)fzkTO2mI
Y`6;D2sdk_sD`sP0U=UyuVB}!}01#Yv+W-In

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/aj/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/const/aj/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7bd79cb4caac4fa72e4cd50659aee9fc13dcc3d4
GIT binary patch
literal 515
zcmZ3^%ge>Uz`&q%Up1qMk%8echy%k+P{wCH1_p-d3@HpLj5!Rsj8TlaOi@gXAU;zL
zb1q91OD<~^D<eZXLkjaE#wfNFmS6@=)|ZS73=En~w-g*pN)nSZyh<xd5)1N+Q=Rkk
zic2y}N>lTaD}D1*Qgd!86H*b7U#!V=OA(K<fW)HW)S_D|1eJh{Vku%~U|=X>0THYq
zf{lTJ!B3O@7HclZJqX!bYz1I*i{PqmvB$?J=H$f3uVnZP3Y=e|`WgATsrn^}C7FqN
ziF!#ni7A<>Mf%D4xdr*UC8-r9x~XM}Ir=4ud6|jv#mPmP1trD$#ia#_MfzaNiuIF0
z;h~?Hr5_)knU`4-AFo$X`HRCQH$SB`C)KWqmw|x+6q3aO3=9k(m>C%vKd><{MlxPt
gh`>ZQ7@{v=LmyZexRaSaFd)bVb`UJ$W?*0d0O``3g8%>k

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/aj/__pycache__/__init__.cpython-39.pyc b/tania_scripts/supar/models/const/aj/__pycache__/__init__.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fb0340d7a5173f1782e452ef95c2faf9025e674d
GIT binary patch
literal 308
zcmYe~<>g{vU|`_PGf2O|z`*br#6iYP3=9ko3=9m#Dhvz^DGVu$ISjdsQH+crHd78$
zE^`z!BSQ*v3QIau6iW(gFoP!BOGX9;22I9W3XUZuiOCsWr4=QK1^LCP&iQ%8C7C6q
zsd>qjzWFJsIhu^O6!EADNGvK&Eh+-Jpop1)fx%CcHHtMCq!BE3i>&~n03>&dJw84$
zCnr9BB|{M#0|SKkWv8E!pPQ;*l30?Nn3t%Rl#`f}nOdZunU`FUSfpQE3L?P<7V9U2
q9H*a{r5_)knU`4-AFo$Xd5gm)H$SB`C)EyQMKKEl0|O5u4-)_uyi)N1

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/aj/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/const/aj/__pycache__/model.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4da15ae58bc418dda6f19b8e44874d984ba30fda
GIT binary patch
literal 22080
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
U1Vz9k52Fy1053y5L%m2m01eenIRF3v

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/aj/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/const/aj/__pycache__/model.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7a76052d5e93b7b2ce0a33eae863662d4a4a1438
GIT binary patch
literal 47523
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/aj/__pycache__/model.cpython-39.pyc b/tania_scripts/supar/models/const/aj/__pycache__/model.cpython-39.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5d40ac4f8b95a668781a063d3ee4aa591fe26927
GIT binary patch
literal 13878
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
YR69^)6@%7b2rzLl@_?ZLnB-vw0Lc>K>;M1&

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/aj/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/const/aj/__pycache__/parser.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..080b0dba88ea7c05edcde2a12f2d5e17b2756b70
GIT binary patch
literal 14431
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/aj/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/const/aj/__pycache__/parser.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3b58212f55501521f49a41f39da967e6efed3566
GIT binary patch
literal 32140
zcmZ3^%ge>Uz`&q%Uo}G^kb&Vbhy%l{P{wBiMh1rI3@HpLj5!QZAet$MF_$TdDVI5l
zIhQ4hC6_gdl@TP)n8Oyumco$2oWq{W5yg?q8N~?}XUXBp<&NS8vsrU^a(Sb8!ECl1
zzFht&{#=15fn32TL9iHmj!>>}lyI&{lt`{<lxVJ4lvu8KlsH(9BS#`vGD<R6DoQF>
zI!YQW#+f6ND;p&XW^?7p<;q9NgW23U3b~3=ieNTRj#932lrosjo1>De8l}p}z{HR$
zo2s^qk%3_~Bh;r1QR*ptEeuf_ObqS}Df}%ADFUgy%a|D$Rx`s@Xr>6ZFhpsARS2~(
zqzGfE&`x0tX3!LQ3DV-H$#RRuB{R9?7Kdj^YEfcRPU<b@;M9^^tf6_C`FWa5w-g*p
zN)nSZyh<xd5)1N+Q=Rkkic2y}N>lTaD}D1*Qgd!86H*b7U#!V^OBhXANKtC4CgUx(
zfW)HW)FMshTWrqxd1;yHx7b}0OA?DyOKx$x<|d`4q-5r$YqH*AcJdFt#q0_q{6c+h
zF$Xxh++q&(^VVd(#p;%snv-&iBPg*P!r}=oO)AeXN&)jU8E<i=r<TO$<fo^n7J+!d
z1&MjSsU=03$(oF}L_&%Z^NQ2*i*i$oLh`dy^D?Wzs#u*8OOi7*8E^3vB&Ng{rxt>I
zoSMu83N<JOB|uQXe_p}>PJoQHOeu`D%q8&XVqmCYs9{{j#K5o`uFr)b)*^<9fuWYA
zmK8-MOARZAN&&D+wp#WYwi@<quo*?HHB2c?RlE!gwM;#NHOwU-7eF0U!-ASzz^a&g
zENhr*nA4bo88n&wia>_E1i4U?=@xTUX2C7yoYXu`j$0fB`Ni?+`8g@KI6<s}qSTb)
zTkOgCMMbH}CAU~h@=FqPZgGGVfCA$d2S@>!#h8AJv7nfPfq_8*3VsFaXXNLm>X#&z
zWG3b%>LukQrevlT=_lvs7Ub)eq*j#Zrj{k<=$9nsWhTZKCl_TFloab1mlh-z>F0uy
zRIz?CD3$3aX6YAzQ-@wb<t-7A_R^Bnc#!iFlaot}5|b;7G#D5dBp4VNipv-n7#bLE
z@bNde-{9eGaJ?(1xIklt=S4ZQD{^KZ7+6^4!Nf%lsSb__8h1s+XK*agxG181MMV1p
z0~4n#nCNuraO^0&!7nhuv8$}3?1q5&48w^$6WD*;;NYDqJRxGD>=fCH9C9739jrIF
zg(kRm*j-?e{0s{HWDo(v@=(TS4JHPLc82K;sSHt!DGX6eDU4CfDNIo;sjN|K9SmuV
zDa<V#QS2!!DXb}MDeNg6DV!->DO@S+84M}hiy2dRQg|~NQ~1(&QutFjQaMw((wHQn
zMl*o&KBkx;7Ii|Y+$qAT+$kcd+$o}|+$mzI+$rLz+$j>NJSmc?JSkGC+$qwjyeTrN
zd?~W2JZW-Zm&vv8M)9YxrO4xO6K9G77P~-p5Heo`Y`$U(Z<GKh113z-$7-^2DrbsH
zDrbsnDi7Ev*lYp0UJPuyS_^NKV2XOGP>M#XaFz%x(9&2^G+S7rM41>;g|oz9qRSW<
z7*@kL3{YL-X)GyPEi9;VQ4&Px6iQ=B(Z<jznJSfHkfPVZh-RX62SWv8luR&#rr|9`
zv?3C@tc4Vlzv8$+nJgqDRUtFCASX39H4l`_^79n()6h$51!V0C5d8{P$(bdoRtc4f
zdFi?-sd?$TMg~R(x`|l{dSHWp$tHq}d)+Kpd9Mr3iqHZ-8B}n<LJCy;@iQ<md_Kg$
zz%Z3@Is+2}a)E~G&n&pk8pce98m1+TeT<9@H4Isx@(65V7Q7&<VTea!BdK5kD`Wr_
ztMN!|Bo!bxffdy-#3QkhRIq`iA!fkYDGb33D;fPX*>ABHmlmWJ-QtLk&&<m#iI2a<
zSpuscZn1;}xw_tB@$+|ay~P&b806{~a*Nr|HGCz@EtcZcoU~gkiACwfx7f1F!8B)l
zd~!}=adCWnG03qB3JMKH>I@7FMTQIv3{_eL<5~~q23=737R<oF@S}m@28Tp1YbSdT
z`xOp}87dbzG#98{;LwDi2O<(v{H}<ocd+zu-auxHNlnSSBBtHJ(!+g2SbU1z6=Bs5
zmL84{jt-6@O$G*rmoJzZ7+$7;SRKL)3`H^^mIBDBpxAM<<7QxBxW#ab(f$@wu;DG{
z5dVN*jEcV)b$&7G{bIEG#iXwOizy-D7n`o1zn`n_Efz<Yuz*|40YM=lw^&Px5;OB|
zF{h-K-C`+8EiSpmmRgXXoKbv>qad*)Gc_+c^%hqWsH%-G&a6tk#Zy|4l30=&UtE$}
zP<)F$sWdq|wWRnKdwG6Qc4|@aE#}1Bf?KS~iOCtMw>Xnh6LTTj*iuq+QcF^Av8EQ5
zCg$8?FH0>-$}dh$7J$Vz0|Nu7iURrM^D1b1MNX|LjHp#7sQrapwW6hFP`H4NPGQPq
zC}9UP!33(h1)zuriz5>yAXh*IP}QTl0hC9;mG&)`jMSpkl?<9}w^$2`GV@A`3_y|N
z3nD;f-C~1;+AX%6{N%)(;*~;079csW0zVMTA4CLzh(Hh#1R_8wswf1+3I!2iAR-(@
zM1Y7$5D^6;qCtceh_D7FL?NV_9#j^AF*Id^EUZ!|oU*}*!W3kh10-30Rb$}f>qzV5
z?cwd<y}>WjTiRLPQ{Gd1f#321zvbMrnH6&?=GV`vUt6}aVok+Gd5bIZ77)1$9F~wY
z42s@cEGda4iOHZafrc+4)_b6_PFyLK!kEcW0xv-r7*OMB0la*ISp%X=I6))?qpHUi
zuPd4SisBd;7*?`^WAhdVs7+LwSdv-<a(+<)D8Lgz^1P791ZB@6aKw=wXS`@}292%^
zA`2pz%e+CQy%{9NKFBZ#C_tj=3cvgXewz#YHcQnOYAn%MuD?istJ+45EgBb<tgk3p
zL*y=S*ns27?-mQF>3EAJCowM_#LiDj=7EG6m;^;5C;&bWw)iSa14RZjve-d>$V@Il
zk1IZ;xXK2_U=E1L1rhk84lR@Mp+y+1>L>ukm?q&226Z0D)X$)N_M?H}g93wqJS4(;
z>M!tHU*NZ1Dz;E!iNtdGMe<w4HcD)fxTt7#MbQc(cY(ti9ACFs!KL#pwxZOM(xN<+
z4iKo^1LcIz&%hm^8pa7Mag4Q0walQ-O)aR~!k7h)R1lHEkiyW)l)_lUfM^RK>g6g1
z2CzJG3%8b|h5>s{19fOnJ4-Rl3=FlLwOqB_H4KQB1orZ`h7;-*rWEE@CS)6HSV0}F
z8jfYG3=FH`xxa=R<hoj(8lGSVO%}hGpu!(gNB;l+|NlzXTP(SW#o0xcpjwhOB{e6p
z@)j$&A9IT(C%?E@6PkgG!SbMfY4I)AwA93sVo>dvnp%8|H7`FUwfGi$L1IyAUP<vS
zmb}#R;-X5Bdd7-dti|yqiRrgk3qghz)qqM(^!%&<Zdlyn0+*}cy0c1$a3Vpd1|`tq
zHgFH>fvMF+4x<j%39J)JXQVC&Uy*WyU!<pMh9VdyE?`;0xrG0soc;w_LlBZOyuxqP
z!E!@NZobwmtp%YgTrWx)U6C^C<nLhYFrA?KfM2+$s=vOgen#N}K`?Y&khH*Mf%u%N
z6{Z{1cbFUyxybK!h2QOj=tX|N4wf7I!X4b;goiz)9fS6$h)ZjoB&4-Y;?o+a`_5U*
z)k*!7#syAk+$bi)(;+Aq!7!dQ%z@%-cpDdWoT!!u+)rX@;V1#M;i1OXu+;FN<|`Mp
zny;3Zkos6r@Sp`>Eq{q1)L2k!o3Dl+)nrD79x-GUs5K@dLk)`yL#$9OAF`Sh)*3zx
zQ-qOKV3@*-#S}I|rlhc=*4T^;CBjI4;Rc5tM+-*{FM9ZZWjI?nK(0r13u^cWGiY-8
z6@dmVz$HmhIRgU&O799(4}$FcTm)^mq%+ho#2SOcma&!zx$TN5Piq)En9~?j7+N@L
zn9yBTg47l*fu{-vh72ZDmrZ2qF$reSWJGZdNIlp!PROp22A8_v62FGAhN+VUQQ9N9
zi5W3wk;XicsYfQ50n+ecDgw17Zn2i-CnqMYWWB|tXK;%#^A=;)E!LdGq|_X6U0MuE
z{-8D{q|Ne+%O)qYxCAs7WLM=yxQqieUBCsRo(-gJY^R4X0EyWIDprjlO`8jbnGkd_
zB>qB3=!Niz3sLbK3^ye15ZNQKNA3jc6-&PhM*a{r7YsAO#nnodB2e@17Hd*zW=={G
zsFhp<>V2$aDe46k<SZpcsj0VElQR;FN+2Es#RsBOI1yB{+f(QvurEL@cTj!Lz$j?@
z0Z!Z$RhSSm!}KdNgOKVKL9G=gaOZ;<$r%?6GcOuuUNOwPnv;LEu;fB^=|#b^D}rSR
z6TmF6U#mF%gFM|8K;7Xg&VV3S7YI|*78gKCOQ2Q*I4yx%w4iYVaLU%HWyF=HJDCve
z1Vr7AA_@via0bOl%et`C#tMla&a}kjlKdjjC@-kOE&_#C5vZTDk{KLPMN>hIHBk4d
z7}T_ZciO2EKa-Fe&=;gipeQZts<hq}X^R~qJ4*IcUa|MT5EyzTFzQNR!bR!CE7FNj
zWl|;Jz#jx*Su_I_MzcU!hWcSN8D#cs5CIyR(BuNQgTRfeB2eX6R1J~>wSsQ3rKBe3
zr=%8v`>V1b;dl@s&cMK+DFDu6MW8lUQ7uTc4n)+0hz1bR2qHk)1!8<Nh}#Mxz$SBp
zvuQl26<rMKa;K&gL(;`Gke@->IssH9Az?@Zj1ykmRB4ltl|j`&@c~Bg0M7?D1~Y54
z7T5z~T42KB)2$|1%}8AkdQn*Wim-Mk2dD*hgVgqynADW4>tgDc#MD<Xu22NSz!gO+
zLRP4+;o9J`LuHTV6)WG1Vt!Y|{5rTlaG;bi;1c4liuwxH71bA2tgon8e_&=5wEYMw
zguZ}?4%V-13^MXFN*82bls38|ZS;YGky9Q_bb5EVOi;bcBRD~22J1y0xhp(!7r^K#
z2QO&6tAqW9h$Kj*DwybS0V&m<QF4(-<qD6=1u(ixywax}ychU1FLG#I;n2Fkq4kts
za)!zcc#f1RxsX?UL8|1URLK>o5?taRS(yaN7{4%pNYL~_86zZvg8B#G!ia%^0aPb|
z^2ldU#SNMYs9~JI2<s%(VCf#AG~VDQfl@xG`-I$CsbwXx$;wvCj?%D%7n(4~g6JC1
z1SzPahNW|a;x<sd4AQ`WTIAMp)NrJ*AgcUY4ser*wS}Vu)N29jU|^_Wso_9v$e}k^
zY8c}|6$My5ioKwQ5m>Z{AGuMM!iL&pYhp}isO7BTNMQnn8^S#<46y;AxBzz*ITwJZ
zm%+v%5j9*j+{k|DWXJ*yNq|*k!3Qg9xKog(V-PmrRLzJ`gJ7kj&Dk+B^aO%KjJ*Xd
zB+)}Cow0@!lrBIa9?YQ0f!>@1PxYbH7NDR5*Sy2FO<B|hD#JlTM`-QFB5?gpM1v7j
z<`dIkoCB)LVGTy}{0m@oF)H;!RP=?|xC;rXI|O$)?kL$)v8V1t>J|Ht3l^aeH5bhD
z!No)os4-A91yrH1Kt_8YEnJ98iD(Jpbt%|+pz09P5)^l4{J_8nCvQrt%`jOY`jweM
zLi>ui!3Ghy(?E>OybI>}7tQmpnCD+DD!p1>b)m5OqIk^}@fu_^AZ)N#ewhb>2Zu8A
z(iIYuOEUBG6bg#+lZq7*i&7PmON&6G8ab5;dHE#@#ia!W`9&qEDGHUTC3+~S6O`S-
zsS`9R3U3!`)-u*GrZ6BfObufSQby`z!rJFx#GW<NLH!S{V1|{<;LHK(dX<5a3@F{e
zT7clj0QoIIyz#OW6yMMhxeMaK5VWIkhTsgtIU=Ajk~t*{LY71<iQC|~A#sb#6;;a%
z5>^mZ7sP|Xp{>aaX|sTvub=_|(j=M-@&=+Q1a9hp#&vE9`{kE-!X^t-Q(TLR@{4Y<
zB^DH<=B0ppU`5@a784Kd787VBst6P+w;1D#=7D-M!g;CX@g<<;66Kl2snCWJWA-h^
z%3@IYh}=4Ywv6DRLQKmDt{Bu9FV2Rvj2_6VT;z~}j7$+VCdDt@U)5DLLv?}ZMSk@w
z{OX-79gH1@H%MyX+z?Y-pg1M3gZl#$BKts+K7_ohrMn_^L-a*0$17TnADBUkK7w=F
z7ckku+Qa>To4?1h#}3qPNo2e$q<TRu{-RLA6`_O+JP8lv6fST`-w=^sz_@^E0n-$J
zkg7OPX61}ygf2(mk-yHPc8N!A1>*|C6@hC^Hi&GI*dlj;@qpqHmMey?2TG1q9I3ky
z7JeZj@=93L75C^1>M<92Vz2PTUI3#9uyl4oJote3g@C{#eiy`pFNz0W5f8o~7IGmx
z>!Mf|s4>SNAbo*D3Y^HmLlZAS6X(gG(g|GkF)%QIs&G(M_&JLcwB!Z3$Ce_S$$)#t
z3^bQj%Zfasg6PR1k4$92ZCe0uV8AQ~(KTrEbOnqlj44cOm{A)Oj0`x;1dU^Wj6uQZ
zW)_vyux5cuBe1ICTqe*wHK^_c^FjWsVFmk#4J-p{;vr<%vbew;1_lO@ni{rvP<Vlb
zYS<9Xhy|c*0v1IkYS^+sAq*DE0?h${S;$S1Ecj?0YIA1+s8a$~jZD<AWx>bbP}MUs
z)UX9Jl&Bz7F94Oj2riVB!iughg$>+%Vz1?>VMVO0NP#U+$}Z7{Y6Xq@u_CRqKv~IF
z%UQ#j1?s7R6&JB1^YYkAK=Yem83u-0t`bl+3+1J7Agiq5%#wmiFw}5nNh7gAbJ$>R
z4Qm#tZwO&?*05&Dftd^p3~M--aWF8fhR19zcMWG2Z0!z14R<`8otIPM2-C&DkivoN
zz7o)o7*w*v1<GJxU?_1zuv3^&?B!a<&cLu5p2BLmQ@Cqbv*2-2#!zH};%6RG?L+Z1
zvX6PuZ011m7ayti5bzg!324R;8Vo7?s41zI2gPoI6u~t@sJR$LUKlx?*NEUzDT+^J
zEq^UvEpG{Eq8jS18txj7G^QH%8lD>78onC-HDb%y7#LQ=ONv^7642~9OtnA_YZhqH
z8JM5Ol*s@s3k1<}1E|x-P!w9jy#OB1U@cIh2BaP|zyaphup;txkz@&IJ{~O2z>oz`
zoyclXLo$ysMLb2Kg<%;B1H)=~`N_yo!_g>O!-30wR5KVEYS@WZ$w!>Z8h+x`f#Rfw
zACdDGAeA7{U;vdRd<Ye&Zm;1(<kT8g9J;ZURU##z(LbmaHQcz&&*Mgx%K|OO0qa50
zjpTkb*ReOE+QW|19>x^$8V)qo90XLe*KlO%ft|y^zyL}KHQWe(4R@A4Os<AI3tp<$
zaA$!QA%UfkL%swwBnuX0Kx%QPNY3Fx^%ElzHAjuWYzESGrAVRcVFJ~@sC6v3_QhU<
zmZU?S4@xoIDblFrL=k%pHzKEjLJQTlS|P$UVvW#jh7_5(OsG0R>xF6<YFKN8Y6Q>*
zMA%U3eX{ClO}U3@ObiU*C3>JiM<>u6gF>Q0Qc+@Fif&$NIdplSjzVT$a!x5|$+QA!
z{aR*XPG(gixI>norjVGEqX1eTqmTw#FI}vVn3tjeo~KqQNGwXsO)W_+D%RtITjE%h
zUTg*Dfvhb^EXh#NC@v||L=^|gftDnK<@3`NN-|QR2AAY3B&8}8CzhqAKo%H+l!9<>
zW?p<+QEDMR<8m|eGIL9F6+r4htFJ2+@={Y%Qd1O4@}d4rRY+6-_d*mh^T4)(r;<u@
z5{oMJ6kJl%5=(PRtQ3q;txn6Vh|fvQQ_#rFE5YHB+{6lnoYcJZk_^zgN>I2JLspb4
z6lA6*rxxoefV`Vpk(^pw3<|swkh0Xo<P3<sLV0FR4#?vrMWuPki6!Ws2L(V-YGG++
zQEG}pW|~52F{tP4oRL`M6CC2J@8lX3g6d?D284GEP$ePD4HYy%%lNVQ$5A0AGr2?|
zBR>b6EI@HnnwOlPS6rH#nxc?clwJy2L|Tk6^B0qze#lD3TO6qsnZ+gX`PtyU@-Ja<
zq60Y;WCSD$tz`1^yTy`}T2ulaWM9dCi@6{%<rZ^kUiK~Kr2OJr%&Gasx7eW}ev1Pf
zSD>jEP`7m@ThVS%pLGw2*b5@|fx4EgIr-(OMc}diTP&b)c*vw#F?Que`#~B(#@%8m
zNlY&;0`+@uv49p-xUFQo#aUXM8V^nsx7Z-7D^@ZVfh@emoR?a@lI<2txPOq#E#?6K
z;37~fv&aNw9H@T|?iu@`3{ZfoR!}4PGpHP$&QOE0+!blU6Rp^*;$~n7W+>7JEgxb6
zt)wqX&bY-~T#~Yq5!|UR1}%++tl;>?VUv@Xo0O7hS7k|f{s27Fh&-<e(Rv*;G6fnh
zX<)dJn|HOa>`GzPh3cA%g|$}-YcJ;3HZXvDcq_SXvFF7@mZNaw#e-*Di*K>zffkz-
zgQP%VUwn%XM8$*lKxF2nq*mPGL}HfaWyeEBlk$sU%v1z3uQUfD`b!8U^?*yATdb*|
z{T;U$xggWQCXmHcpfzu|nDUEnapWdur>0~U72je36)d;dQ!<P45_3~;v4In2aS>>y
z2(-i|G36GkufL0{4`h}IG(mKWKPNvi1vD-JUgVORQe*^**mEEPw29~zQ%OE({-`W7
zIrSDBWNXMRmdw1g{9Ej)dEi;4BG9&iqMaZe;A9HwNEL~KxS;e?1W&Mt6bK$iDFUSs
z$n-C$16Ks<uiat+E%zw`^`^m-kVT-*UlFJcdW!>A5Eg+tevnmvpbiQsB0wd0(Or;@
z_dvvb5b*#+fa;K2>=}v0i6tdPD}`?{C+8Fwy#UF40TJLV0bZ~P8X^KG{NmK2Tg)Mj
z?zdQ+Jsg8>F_u8$5u6{3z@dUA^+Uo8<V^4gQ!&VApppm;g9muPkwMJTPjI3It+p?A
zWC88i_^QGnAa;RY@dCf%T(+4Ub2uRE4wkzdTs_=Vou;@?_n+jyz~!Qd<`ogm3nGRq
zLUy=Z;BdUi;dq6^@dAhAU2fhU^M1Q7yBR7Mx#h2LgZ6oFO08g7!}WoIg;VN=sO*H`
zDG?V$RWFFDE?|Ms9d0+IRc08^vAiH{d_mfHLD`aO2&==b$L9u*P>;`b9*s*p8Y{%E
zXj)#;wA)d5Mbq($ru#)6k1ISL*Ll1z@pzwbJL7wiC+Z4M)CHcX8^V$uzE3&$`nkKf
zFNh%Km2Qa0b#itvcZA&F=I^nYVRngI@dCHvT>+H^Axk1J3g}-E(C=`(p{TS(^n!%`
z48}REGg#L;cX-|vmS4cWB5+OU4#qvK2Mmvxo=7~CdLcIPN^ItZlF|<h40Vi7OkY5h
z2h#@z1`$uDk6`i(nCx)5At^OSyu+o(tHbN5u*3}UrO9iH_c9+9KH+j9BIZg&(goq<
zi^9oQgp)g5Zt#oF5Sb%+fnVtYztUZC<pu6rh4(5SH9qTnAu{$#Wa@?7!YjGu7sM+r
zidS3_ub9Acmrr<t+fwGW!dsR18Xrix5EOPLDCPoR>_xuVD}1pX%y;?4XRu%7SGdBj
z(7|$7Msb1K2G<KRRu^TguE<#Jbv>YQH6ZwcO~^%?kSjJJSHq$&#3Wu#&$<wneK9Qi
zN?7)U<c_osmb)VAD^fPNtcclBd_v?xNW_K2^b5HK7eop#iWFWEDeT~UDj+_CbAibc
zs|x~V7X-{Uh(Ku2z8s{0zQH5V@73isp>#&doZJ&GXS^=xC9KU{leZ&ePt-*{k1Ki}
z7xX+X#3WouuDy_4dy%K^3Qyeyp1K?S!Wa1EZwQD?=bFSd!}Own;uQhK3j&HaIJo;c
zyErGPUgVIt!Xa^iL*j;*%=DZ|ISWiLifLXE(_CS^-g1@YhR}=J)>pKxCop%g-4K_W
zQh8lm{gSx)3br*o7sXAlh?{n>_3+%_-~lC;8(Mm6batp+(sH<<<uJ8)hRGbOiS<+J
zC)6KEIg)k7E&Q&8^bF@Yo-_I8@ZHeRUco;#d4}>F&53za@+Rc%2)Uu9cR|YvMH|Zv
z1Ct8|4l`2b<ju%Cka9y(c8(kdAu~sEsqq}S52D<nTpt*?MY%pQaC35h0TCZS#8(Lh
zPJWQ{CR9%FyU3w@g+uuQhcY~UYh2{eyaL{Ja6>?H0`nBk3*g|H;R2zr3m9G!Fg(hB
zg5^Z|MTf8}4q+FJ5;mx8(b}MOAtvFXK;jjF#17WGklZq%bb=2EUgS``!l8J9L-B#2
z$OK`~Qk4ao7X@{$2<mjO-QeKs;pyk^;-A4bhxa0f+7%A93mj@U_(eN-p;eimpIea~
zsO$sn!veQg+}yyU`ynftz(biu8$n~-vY?F}pgJTz{uWn!d~SY9X-;Z<{4JjNc+kE9
zs0@32d`f<DeEcmIKSy8JB2fRm=ncqlP@ky?G%x_FzKe=L?SWg&nRz9*Sd#MdbBaI%
zmPMd`Ke%Ww0<Eqt0xj4r0#(LEmq3jhwvg1k;{2i_&|1q|?0Na|=|zbtMWAu8q6Huu
zHh>gygSU<3rj}&nr+~}VTfES%B+02cIq~r;8H>Ox@j>kdha&Kn5>Su12t=rY<`=4&
z!Al7m7$EQi6B8@P2L=$q!N8;4;BtdUr@{3D3mdE22L>#J6oa_*4GHNRQgSzBWN(N|
z-Vm3#AtHH0O!|hT)D5w)3t)6ZTy{q3g!~&4G9MI0Sgk%Vh_G5c;1`(?JVRqb>=l0H
z53C?jHU>W73C1%xCfHu#Rs6sX65?Rs7n$HZLt=vO6+Wd8oFE}C20@Vz+#nVYgRs~K
zUJ#3qK~&-cKZqs3ATISm5X2H<5EA_$3}T6ZSfU`77z3Zs2XPQff<Zv!gCvM0#ULX7
zK^nx80hufdV#$GI<v}b31|czoo52o8CyW@R<w3qC;Bj$2R@)B@e5|$)_=FK&Vg-q^
zft=3{VsU_+$_Zj|fmqxi77xhLydV}I$XWa#mH^1nf*_U<$kD<emIz2z6vPq(IT~&s
z*iv*tjX_lMhKR%sQ7KT&iA#Vy0FO2anGccztTrDQ1XyiQT?-OrW8fG1zz$+@fLNR$
z78e7*@CR-XiwEQvUJ#29<O6;XO8~?Y1hIrbeh~(-Ag%?m#6W%#2eBkT?uOe8wjP~O
zVP_Rt!1{rKomFIo>KYv|1Dz0JU=wZ#ZHaA+Z;AiFB*R+9IHU9f1BhNB1)-72kIW2g
zqA-OYY*6$Hvr2=s3bRVD5dFX)%qoo_;Mzc<S`2K0ADCPjS;amuAV`oB!Io%D31mg!
zG6|d;QMwPHf&)}Kd|n4$EuYR%%UHwU!Vv3^x|*|wsRX|4gMk5U{6e{gaRHJnVypvs
z4^j=<*aZ4WMUPbtBaW5vXgV1gdID+~p`8~^)>~Ye#hH1<C5fP2TP&b;n4q?JNoroo
zE%vmW#FCQKydqH3PLmnju>tKFC@#$@xy6*4Qw;LCf&!$QQzXd9zyKydduNMd!3)oC
z@bWjf-QeQ~ZPS$l6CF%<xkV==&4st?m^tNc@Cfz$cKOa#U!XKodye)+9<?hxY8Sxh
z0Yqws(nTKGD?G9nz~~0IV1q9>LO?YGJiK5d`=3X5=wjIcJi0>{X+Llj@(x`Ug1z#9
z{Nf@VP*n~ZCPvBspymOnH~9GpbPY8V$^ZiDYH_6D1jfO)UlwKGE~tG3&R8`J@$lIS
z(2iR0kcTEGczYXo(<`JyiLIx39u#7~K!iD{0Rw7TA(lpinq5`8#DqM2%Pa>Y14A)%
z`3p6-%wpX>TVw-rxGjhPw?RQuk45$%E~u!6Y@aOxZFDRGO(GV7<_n9QLDHbv!Xj4?
z3p7_)<PKtafCx_z;RPZ<6KF*~3=9k*kVYj{c5`Ci77JQ61zL7PT(YG72FW7OhC5Bj
zhC7JoK{M%)ArjCaQBe{osel&RqYX&F*KC7^E{ND@9gttF2OcI82BjL%;2&twlp2G8
zEOfgZ3ENPMK-EkUXc}c`>_P<xauI0Kq$m><oS;!C<luy^Ndxs|h|GeZCD5R4tQw#?
z9<(?MT>JVJWrLD4d^_Y2+VfeI4{~`SD0Dz0ddQ)JvMrPFjyq6711)XJOfInig$`&L
zCOC8;>(om?dw@Vi2Dmh3U|;|Z6N1`JpM}6D91*wYjpq9+nUUAl)$)+A-;z0n3HyG_
z8m<~1=$=drHK;2VpnEZSYk0wXF(G|>(B>&{Z@;Jl)XRr%!bM&Ce~Y~!zZg72fOGwS
z3n-q!n*ff1SfHH%#TYRTZNY*%@KyRm)k)x@1-zux3sk<W1-Et|nA=?BFaa-SD__96
zpnL-hQA^rzZL_?=FESyhr?P|P0~>>Y2%#O92TD(*TnG+<BGAIIs0(3H7lNbC<X+^D
zxxycFAwK0Ie@X|-1MIso;pvi(8FIc2mXyhiyh^i{1Ito(CX{8}@N^HF%K<IfMp^34
zNy1Wh&`w~kTJBmNA{M)I!BZV0)|AN!S{;H*4O+_N0lB=E7sXakn-7+o;dBjdTRBm}
z1k_^$>q47R<^wMfXKCTUwYmiTGz;{l<F))LtSt;R92nvPDQqnaH3Asof?yj#OVR}~
z<b;s-U)Bhr@ACw&789-&sS&Ob0ZoO~iXt!DuMtJ>opLgO?c!+RC;`p3fc+2NFu<3>
z2^vU)2%z?hG2A4^iLzreg{y|QMiey^85v4I<8Bb+7;1RIwsN;{)QF**2A1K$wx_d3
z6m`u_FoPzqA9yb(q+kNI1X20`poT4I8s#&nivVhDrGs{L3e+-oFhTciGNRi)k*P-z
zV?QP+U4hL3E%=3-qgKm^YdtjfQ3KRI2O@MQGWDoK_swZC7lGU5pf$p`STajeb79M*
z)j)+Lj%CumM3s!7rUJNNM4rTi?e0X{oS6nHH?^RfGevDLfYAoS2`N)DrsORMTpqS4
zY+=Nbh$~`x5UC5IwvcKy4m9Tq+1Cd;q9+f!^Ac32!W)U;jR8)SyBF+8&`O*i4Gb4V
zq9N#j3fx5(L~VDlToARrC~A8})D|LrK_nXNP?R(Rk6R_^I8hBlEKe<X6?_U~E7F#e
ziA+79T964+^?@rvkcTyyioiQg*-H}BK_|2ogNjzz$P2Z6n+}Q+&=Elm3>U<$AZUg9
z4E6<#3zQbH%;ANIToAXy^dCGAfOcI@X8`8_4UqppBjC{Nh(w{L(FLGEZzNd=6IIPb
zrXEdL>SemcoLo?Pi>)LdG+YG@8t~{8O@bu@6fB^W+Q4u@#sz{lD9#9+A37^^X84@&
z`Ej%2F3Rd&k=2FBU666X6F?Le67YZqEoy)l5+b+@36ugr6dHspnGgj)kpjqnnAwNA
z**z0v2`KS{bCT%=5fEBoI3Z+8#FV%Nj#ot0AVL>JOu>N%UOrHy2-1b=G%Dn5uzO%R
zTR7wb80}DjJK}<f=?0byBBmEbOs|NTLZmMUhk)INlCwdhBj8dS)bNK#$UyDs2aVf+
zT>~mK;I5&`ew(5dpt=II$EIi{s2_zHP1H?6(?DqfG?D~LL53+8ASg0wgW-n2Ehakz
zcNp#g?X?E&%}Trw5O^l#ihb|}qY$V%!xV7T;oqP|g>(gWC3KJqv~|`2wCzI>Mq=5p
z5A%p&%7wV(3x+8d4O6Zdrd&<Wx|)-JA+6w|VBr<PLQIn&z5&$&x0p?gOi+>}JQ09~
zEZ~WN)|>J1ZXl;Z$gTqQuHk#gM}UVxM+6taJ*>%tb%z+JLt6yjCU%Q0u_!$^u>yRA
zY7r<I7J>FjfG49h#c^*2L+d_+yUOqlVnv8PG}t!KX0akrGvO9bNl|8QZfXi-d6^(G
zFCJ7i7lEc^ZgGPScZD4~3qFVza_}su^B$j=oLn>?RD6Ki?Z{iqkcMO+)8U|&M3o+C
zZMrZ}nIXgko;m-(fprr;qKhp`(-V=1?w^ykm+b=^gJ=vRyyba9^}Nn0oeSZS7rmmc
zctu?hiM}WjeMKa?gYyQsMYkd3g1FU1ajPrhRvkPyz^$1LH5X)DF3PxEk#V`eA$bE_
z5kl)br{D|1As2;1t_X*8a6DBs-H>sB^P-~H6-6)5fw|lhB5w%E&d9tdq~5`PmxH$>
zy_2tpuY>Ociy|k_2R}wec(I3Ed_j*A*kQP)?xKp_6%{+saRLsEpz{PA7(oXLI52jw
ze&FHa<N+;M;p<495HiCYzFg%lIeYpql+}W^_1A;9_180kw)NLz+13v#HbIrx=NpLg
zs0LzNKWMCjt(LtObmkMtJ>cdrj=5b*H}-SZa3b$StK|gui!nF$bK>utQ)Od67uasl
zcm#@@(EH9c(DSs?8EScIII$cBkWtH4!-nju8aCw7O=Ou)2E@)j#6CVW^+>%lL}QvL
zok)9{5jxYE)0t{{Yj_rbM%=)0i%it;qK}>QWP-y5bTSqD0?<%CvT`sxg&9>3dWhBX
z)o|DF)bOP-2Qz4Ljvgt%z(C+g0pc32pizHfMmn~G8ZMyY<RNXgNuXx)6i}51>dPT!
zL`mqy<Fy%V9cW8B#5zzn8hc}DFmw@!YZv16?;%hf51rt<AQ}ikI|3&Z&JdhZG9z$C
z;hc~KCQB@q*lkeU;J8KQin93yF$;*Q3!;JGKtc&0P^^HvP$tkReehrgsXgo>El{lE
z=onGK*QY?fhWDo(FNlB;T7McObV0-s>_tsJtj$Mw%MsE}1Z}h^0v#|=1UgR{yj=pa
z03Nggs0ef?hbBMnRwT9-Be<~$njX2uRa}sm2U@+KQhZCGEVU>Jw2vtjyq-U$_!bA~
z@Bz?BB)DZ+3|dox)*6Jg0zr!@iEIVJQ_WgXSZyZrzyX}IGb9~3@PUItT!{{c4t(HY
z5DQ|2r|tvVClZh7T@VetC>nT0H1I-5`bE+74z35%vY>U&f-*A#X9Ud%nj-&!ftgbe
zOmsNjkdU0AIEMv#ZiVBV@)ay=IM(oODBK~qrDTWWmhvka_6J0cNF0&75D<7FDELZ1
z$c50bD*@qG93w8sMP3k(>hO5LBXgZc`4W%v0*{M4x>tB~FM!bla4LnQ)eWrMc{cIv
z2)bzCaK*skf{5cq5yvYcjvbsg_$4n$Yp;mBz;AYe!wj5wAp`HA)xM(#7l5};f(D%+
zRljT|Y_sy{!3ChbIFL{oJ-7gLSOI7$5;#0Y4=!L}sAV5LxB%DG^60?@ps_YcRvA6G
z01^&)qX!o-j2>KoI<NpaU`SK0Xfvn}y9K<0bt{MonujRb4r1*95#SBB;1gPRfw%`j
z#9<I|1VkJK5#S+aaChT40|SFw(Fu^?DG+fQM4SN;XBik6sJ&ae=pxAEE1>Q-Xx16J
z^6M%C14ES!QDe*Cy{^b>8z39Be}cMu*Fa{24uB~F?bj}P1mc2rCKrKLheKvGpMu1`
zgRBSjF_8wjVN6Ij2eb{E$W^Xj2b~3Vahyjt-;Qp+9pamBAB?2Uw_iD+TXHXm47TmJ
zMgKqr)ql{^TiGH8P~pZ1BA7q~Gl*aT5uko3+BVuER*(c}5Uq#}#9{{#pyf|Rpt%gl
znt#yBbF^KwMWEds;4QR8oFE;b=|IHx*&;5G7^qMz;s&vJK*b%X{Dy9o6$J@`2#|w|
zn+R@|)o*b9z{U>RDvO0sAa$#(Flei+F#1+mkSN+#S&$IgR#}h`WUDNQ1=%VKVnMdb
zf>@BPvLF^@t1O5G*(wWSLAJ_*Sdgu<AQoh+EQkf!Dhpykw#tH7kgc*H76UHAV05eO
z2l{Q5<$`RL<$`UM<zf~2z<^3fplo*yVPvfb@0A5JK$~U3j1LUR6lhl~c)u(}Foy}n
z2w7Hh(2iMIR&&sfSy@)|4-7B@t`Q_)2i`I30p2l-AVEsNJ7y6=9~jWtkdZr3rqt9a
z0$nC`i>;)xATuu=QV@Vk2ynRoS`iJ|NiPk)FIEqHl1#B4=scqmy~HdCAF^d1RN&l_
z$F8gdcBv!yJeFHL5LJ-NW{bGMoA4n*r6rj;#gKz(Kyz^5Q(A5bA<5|_=jZ0;=M{lA
z3V;uL0pI#j1U@YWv^VLNAhKfcu}P34Vn8EM;PYf|2_vfjokaukIOuj#REu&`L01-o
z*Js=kMb-j7#RYV#68Oj(G&#6OL9>dtgi7*@k~8%3^7OzS(<{o$E0O}0-r!>U1BeAW
z+z`BZ8N5Na2ox!h<|w$a3Oa4z7l#ex<OI7SA4Ud{PKM%}j0_APm>C%vKd><{ay4**
z;0*@d3xv=E2A&2me87-<0UNr(V1EG>-C&TvfQoJ~7+t`PZZMc#AP(JNu)csB-C)qV
zfQoJ~XkI`?n0DP@P``kRZZK$HKt&(e7`Q|_q$YS=<dnU_DcivIfsKPv>H`Cukn&+>
y6#Kw{om|285iIisOhQ$~u(2}=ePDnS65%W$6R?vj%sw)JWWIpO4;UmkdjbHEFaT=+

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/aj/__pycache__/transform.cpython-310.pyc b/tania_scripts/supar/models/const/aj/__pycache__/transform.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..731814f0b914ad90ae5e604f6a0883b85690c09e
GIT binary patch
literal 17396
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/aj/__pycache__/transform.cpython-311.pyc b/tania_scripts/supar/models/const/aj/__pycache__/transform.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..aba0194d23a0b3d6f8024b35018c2b00be0c9752
GIT binary patch
literal 24903
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
Cl!Jx<

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/aj/model.py b/tania_scripts/supar/models/const/aj/model.py
new file mode 100644
index 0000000..8f4a8ce
--- /dev/null
+++ b/tania_scripts/supar/models/const/aj/model.py
@@ -0,0 +1,786 @@
+# -*- coding: utf-8 -*-
+
+from typing import List, Tuple
+
+import torch
+import torch.nn as nn
+from supar.model import Model
+from supar.models.const.aj.transform import AttachJuxtaposeTree
+from supar.modules import GraphConvolutionalNetwork, MLP, DecoderLSTM
+from supar.utils import Config
+from supar.utils.common import INF
+from supar.utils.fn import pad
+
+class DecoderLSTMPos(nn.Module):
+    def __init__(self, input_dim, hidden_dim, output_dim, num_layers, dropout, device):
+        super().__init__()
+        self.lstm = nn.LSTM(input_dim, hidden_dim, num_layers=num_layers,
+                            batch_first=True, dropout=dropout)
+        self.classifier = nn.Linear(hidden_dim, output_dim)
+
+    def forward(self, x):
+        # x: [batch_size, seq_len, input_dim]
+        output, _ = self.lstm(x)
+        logits = self.classifier(output)
+        return logits
+
+class AttachJuxtaposeConstituencyModel(Model):
+    r"""
+    The implementation of AttachJuxtapose Constituency Parser :cite:`yang-deng-2020-aj`.
+
+    Args:
+        n_words (int):
+            The size of the word vocabulary.
+        n_labels (int):
+            The number of labels in the treebank.
+        n_tags (int):
+            The number of POS tags, required if POS tag embeddings are used. Default: ``None``.
+        n_chars (int):
+            The number of characters, required if character-level representations are used. Default: ``None``.
+        encoder (str):
+            Encoder to use.
+            ``'lstm'``: BiLSTM encoder.
+            ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``.
+            Default: ``'lstm'``.
+        feat (List[str]):
+            Additional features to use, required if ``encoder='lstm'``.
+            ``'tag'``: POS tag embeddings.
+            ``'char'``: Character-level representations extracted by CharLSTM.
+            ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible.
+            Default: [``'char'``].
+        n_embed (int):
+            The size of word embeddings. Default: 100.
+        n_pretrained (int):
+            The size of pretrained word embeddings. Default: 100.
+        n_feat_embed (int):
+            The size of feature representations. Default: 100.
+        n_char_embed (int):
+            The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50.
+        n_char_hidden (int):
+            The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100.
+        char_pad_index (int):
+            The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0.
+        elmo (str):
+            Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``.
+        elmo_bos_eos (Tuple[bool]):
+            A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs.
+            Default: ``(True, False)``.
+        bert (str):
+            Specifies which kind of language model to use, e.g., ``'bert-base-cased'``.
+            This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_.
+            Default: ``None``.
+        n_bert_layers (int):
+            Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features.
+            The final outputs would be weighted sum of the hidden states of these layers.
+            Default: 4.
+        mix_dropout (float):
+            The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0.
+        bert_pooling (str):
+            Pooling way to get token embeddings.
+            ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all.
+            Default: ``mean``.
+        bert_pad_index (int):
+            The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features.
+            Default: 0.
+        finetune (bool):
+            If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``.
+        n_plm_embed (int):
+            The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0.
+        embed_dropout (float):
+            The dropout ratio of input embeddings. Default: .33.
+        n_encoder_hidden (int):
+            The size of encoder hidden states. Default: 800.
+        n_encoder_layers (int):
+            The number of encoder layers. Default: 3.
+        encoder_dropout (float):
+            The dropout ratio of encoder layers. Default: .33.
+        n_gnn_layers (int):
+            The number of GNN layers. Default: 3.
+        gnn_dropout (float):
+            The dropout ratio of GNN layers. Default: .33.
+        pad_index (int):
+            The index of the padding token in the word vocabulary. Default: 0.
+        unk_index (int):
+            The index of the unknown token in the word vocabulary. Default: 1.
+
+    .. _transformers:
+        https://github.com/huggingface/transformers
+    """
+
+    def __init__(self,
+                 n_words,
+                 n_labels,
+                 n_tags=None,
+                 n_chars=None,
+                 encoder='lstm',
+                 feat=['char'],
+                 n_embed=100,
+                 n_pretrained=100,
+                 n_feat_embed=100,
+                 n_char_embed=50,
+                 n_char_hidden=100,
+                 char_pad_index=0,
+                 elmo='original_5b',
+                 elmo_bos_eos=(True, True),
+                 bert=None,
+                 n_bert_layers=4,
+                 mix_dropout=.0,
+                 bert_pooling='mean',
+                 bert_pad_index=0,
+                 finetune=False,
+                 n_plm_embed=0,
+                 embed_dropout=.33,
+                 n_encoder_hidden=800,
+                 n_encoder_layers=3,
+                 encoder_dropout=.33,
+                 n_gnn_layers=3,
+                 gnn_dropout=.33,
+                 pad_index=0,
+                 unk_index=1,
+                 **kwargs):
+        super().__init__(**Config().update(locals()))
+
+        # the last one represents the dummy node in the initial states
+        self.label_embed = nn.Embedding(n_labels+1, self.args.n_encoder_hidden)
+        self.gnn_layers = GraphConvolutionalNetwork(n_model=self.args.n_encoder_hidden,
+                                                    n_layers=self.args.n_gnn_layers,
+                                                    dropout=self.args.gnn_dropout)
+
+        self.node_classifier = nn.Sequential(
+            nn.Linear(2 * self.args.n_encoder_hidden, self.args.n_encoder_hidden // 2),
+            nn.LayerNorm(self.args.n_encoder_hidden // 2),
+            nn.ReLU(),
+            nn.Linear(self.args.n_encoder_hidden // 2, 1),
+        )
+        self.label_classifier = nn.Sequential(
+            nn.Linear(2 * self.args.n_encoder_hidden, self.args.n_encoder_hidden // 2),
+            nn.LayerNorm(self.args.n_encoder_hidden // 2),
+            nn.ReLU(),
+            nn.Linear(self.args.n_encoder_hidden // 2, 2 * n_labels),
+        )
+
+        # create delay projection
+        if self.args.delay != 0:
+            self.delay_proj = MLP(n_in=self.args.n_encoder_hidden * (self.args.delay+1),
+                                       n_out=self.args.n_encoder_hidden, dropout=gnn_dropout)
+
+        self.criterion = nn.CrossEntropyLoss()
+
+    def forward(
+        self,
+        words: torch.LongTensor,
+        feats: List[torch.LongTensor]
+    ) -> Tuple[torch.Tensor]:
+        r"""
+        Args:
+            words (~torch.LongTensor): ``[batch_size, seq_len]``.
+                Word indices.
+            feats (List[~torch.LongTensor]):
+                A list of feat indices.
+                The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``,
+                or ``[batch_size, seq_len]`` otherwise.
+                Default: ``None``.
+
+        Returns:
+            ~torch.Tensor:
+                Contextualized output hidden states of shape ``[batch_size, seq_len, n_model]`` of the input.
+        """
+        x = self.encode(words, feats)
+
+        # adjust lengths to allow delay predictions
+        if self.args.delay != 0:
+            x = torch.cat([x[:, i:(x.shape[1] - self.args.delay + i)] for i in range(self.args.delay + 1)], dim=2)
+            x = self.delay_proj(x)
+
+        # pass through vector quantization
+        x, qloss = self.vq_forward(x)
+
+        return x, qloss
+
+    def loss(
+        self,
+        x: torch.Tensor,
+        nodes: torch.LongTensor,
+        parents: torch.LongTensor,
+        news: torch.LongTensor,
+        mask: torch.BoolTensor
+    ) -> torch.Tensor:
+        r"""
+        Args:
+            x (~torch.Tensor): ``[batch_size, seq_len, n_model]``.
+                Contextualized output hidden states.
+            nodes (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The target node positions on rightmost chains.
+            parents (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The parent node labels of terminals.
+            news (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The parent node labels of juxtaposed targets and terminals.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens in each chart.
+
+        Returns:
+            ~torch.Tensor:
+                The training loss.
+        """
+
+        spans, s_node, x_node = None, [], []
+        actions = torch.stack((nodes, parents, news))
+        for t, action in enumerate(actions.unbind(-1)):
+            if t == 0:
+                x_span = self.label_embed(actions.new_full((x.shape[0], 1), self.args.n_labels))
+                span_mask = mask[:, :1]
+            else:
+                x_span = self.rightmost_chain(x, spans, mask, t)
+                span_lens = spans[:, :-1, -1].ge(0).sum(-1)
+                span_mask = span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max())))
+            x_rightmost = torch.cat((x_span, x[:, t].unsqueeze(1).expand_as(x_span)), -1)
+            s_node.append(self.node_classifier(x_rightmost).squeeze(-1))
+            # we found softmax is slightly better than sigmoid in the original paper
+            s_node[-1] = s_node[-1].masked_fill_(~span_mask, -INF).masked_fill(~span_mask.any(-1).unsqueeze(-1), 0)
+            x_node.append(torch.bmm(s_node[-1].softmax(-1).unsqueeze(1), x_span).squeeze(1))
+            spans = AttachJuxtaposeTree.action2span(action, spans, self.args.nul_index, mask[:, t])
+        attach_mask = x.new_tensor(range(self.args.n_labels)).eq(self.args.nul_index)
+        s_node, x_node = pad(s_node, -INF).transpose(0, 1), torch.stack(x_node, 1)
+        s_parent, s_new = self.label_classifier(torch.cat((x, x_node), -1)).chunk(2, -1)
+        s_parent = torch.cat((s_parent[:, :1].masked_fill(attach_mask, -INF), s_parent[:, 1:]), 1)
+        s_new = torch.cat((s_new[:, :1].masked_fill(~attach_mask, -INF), s_new[:, 1:]), 1)
+        node_loss = self.criterion(s_node[mask], nodes[mask])
+        label_loss = self.criterion(s_parent[mask], parents[mask]) + self.criterion(s_new[mask], news[mask])
+        return node_loss + label_loss
+
+    def decode(
+        self,
+        x: torch.Tensor,
+        mask: torch.BoolTensor,
+        beam_size: int = 1
+    ) -> List[List[Tuple]]:
+        r"""
+        Args:
+            x (~torch.Tensor): ``[batch_size, seq_len, n_model]``.
+                Contextualized output hidden states.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens in each chart.
+            beam_size (int):
+                Beam size for decoding. Default: 1.
+
+        Returns:
+            List[List[Tuple]]:
+                Sequences of factorized labeled trees.
+        """
+        tokenwise_predictions = []
+        spans = None
+        batch_size, *_ = x.shape
+        n_labels = self.args.n_labels
+        # [batch_size * beam_size, ...]
+        x = x.unsqueeze(1).repeat(1, beam_size, 1, 1).view(-1, *x.shape[1:])
+        mask = mask.unsqueeze(1).repeat(1, beam_size, 1).view(-1, *mask.shape[1:])
+        # [batch_size]
+        batches = x.new_tensor(range(batch_size)).long() * beam_size
+        # accumulated scores
+        scores = x.new_full((batch_size, beam_size), -INF).index_fill_(-1, x.new_tensor(0).long(), 0).view(-1)
+        for t in range(x.shape[1]):
+            if t == 0:
+                x_span = self.label_embed(batches.new_full((x.shape[0], 1), n_labels))
+                span_mask = mask[:, :1]
+            else:
+                x_span = self.rightmost_chain(x, spans, mask, t)
+                span_lens = spans[:, :-1, -1].ge(0).sum(-1)
+                span_mask = span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max())))
+            s_node = self.node_classifier(torch.cat((x_span, x[:, t].unsqueeze(1).expand_as(x_span)), -1)).squeeze(-1)
+            s_node = s_node.masked_fill_(~span_mask, -INF).masked_fill(~span_mask.any(-1).unsqueeze(-1), 0).log_softmax(-1)
+            # we found softmax is slightly better than sigmoid in the original paper
+            x_node = torch.bmm(s_node.exp().unsqueeze(1), x_span).squeeze(1)
+            s_parent, s_new = self.label_classifier(torch.cat((x[:, t], x_node), -1)).chunk(2, -1)
+            s_parent, s_new = s_parent.log_softmax(-1), s_new.log_softmax(-1)
+            if t == 0:
+                s_parent[:, self.args.nul_index] = -INF
+                s_new[:, s_new.new_tensor(range(self.args.n_labels)).ne(self.args.nul_index)] = -INF
+            s_node, nodes = s_node.topk(min(s_node.shape[-1], beam_size), -1)
+            s_parent, parents = s_parent.topk(min(n_labels, beam_size), -1)
+            s_new, news = s_new.topk(min(n_labels, beam_size), -1)
+            s_action = s_node.unsqueeze(2) + (s_parent.unsqueeze(2) + s_new.unsqueeze(1)).view(x.shape[0], 1, -1)
+            s_action = s_action.view(x.shape[0], -1)
+            k_beam, k_node, k_parent = s_action.shape[-1], parents.shape[-1] * news.shape[-1], news.shape[-1]
+            # [batch_size * beam_size, k_beam]
+            scores = scores.unsqueeze(-1) + s_action
+            # [batch_size, beam_size]
+            scores, cands = scores.view(batch_size, -1).topk(beam_size, -1)
+            # [batch_size * beam_size]
+            scores = scores.view(-1)
+            beams = cands.div(k_beam, rounding_mode='floor')
+            nodes = nodes.view(batch_size, -1).gather(-1, cands.div(k_node, rounding_mode='floor'))
+            indices = (batches.unsqueeze(-1) + beams).view(-1)
+            
+            #print('indices', indices)
+            parents = parents[indices].view(batch_size, -1).gather(-1, cands.div(k_parent, rounding_mode='floor') % k_parent)
+            news = news[indices].view(batch_size, -1).gather(-1, cands % k_parent)
+            action = torch.stack((nodes, parents, news)).view(3, -1)
+            tokenwise_predictions.append([t, [x[0] for x in action.tolist()]])
+            spans = spans[indices] if spans is not None else None
+            spans = AttachJuxtaposeTree.action2span(action, spans, self.args.nul_index, mask[:, t])
+            #print("SPANS", spans)
+        mask = mask.view(batch_size, beam_size, -1)[:, 0]
+        # select an 1-best tree for each sentence
+        spans = spans[batches + scores.view(batch_size, -1).argmax(-1)]
+        span_mask = spans.ge(0)
+        span_indices = torch.where(span_mask)
+        span_labels = spans[span_indices]
+        chart_preds = [[] for _ in range(x.shape[0])]
+        for i, *span in zip(*[s.tolist() for s in span_indices], span_labels.tolist()):
+            chart_preds[i].append(span)
+        kk = [chart_preds + tokenwise_predictions]
+        return kk
+
+    def rightmost_chain(
+        self,
+        x: torch.Tensor,
+        spans: torch.LongTensor,
+        mask: torch.BoolTensor,
+        t: int
+    ) -> torch.Tensor:
+        x_p, mask_p = x[:, :t], mask[:, :t]
+        lens = mask_p.sum(-1)
+        span_mask = spans[:, :-1, 1:].ge(0)
+        span_lens = span_mask.sum((-1, -2))
+        span_indices = torch.where(span_mask)
+        span_labels = spans[:, :-1, 1:][span_indices]
+        x_span = self.label_embed(span_labels)
+        x_span += x[span_indices[0], span_indices[1]] + x[span_indices[0], span_indices[2]]
+        node_lens = lens + span_lens
+        adj_mask = node_lens.unsqueeze(-1).gt(x.new_tensor(range(node_lens.max())))
+        x_mask = lens.unsqueeze(-1).gt(x.new_tensor(range(adj_mask.shape[-1])))
+        span_mask = ~x_mask & adj_mask
+        # concatenate terminals and spans
+        x_tree = x.new_zeros(*adj_mask.shape, x.shape[-1]).masked_scatter_(x_mask.unsqueeze(-1), x_p[mask_p])
+        x_tree = x_tree.masked_scatter_(span_mask.unsqueeze(-1), x_span)
+        adj = mask.new_zeros(*x_tree.shape[:-1], x_tree.shape[1])
+        adj_spans = lens.new_tensor(range(x_tree.shape[1])).view(1, 1, -1).repeat(2, x.shape[0], 1)
+        adj_spans = adj_spans.masked_scatter_(span_mask.unsqueeze(0), torch.stack(span_indices[1:]))
+        adj_l, adj_r, adj_w = *adj_spans.unbind(), adj_spans[1] - adj_spans[0]
+        adj_parent = adj_l.unsqueeze(-1).ge(adj_l.unsqueeze(-2)) & adj_r.unsqueeze(-1).le(adj_r.unsqueeze(-2))
+        # set the parent of root as itself
+        adj_parent.diagonal(0, 1, 2).copy_(adj_w.eq(t - 1))
+        adj_parent = adj_parent & span_mask.unsqueeze(1)
+        # closet ancestor spans as parents
+        adj_parent = (adj_w.unsqueeze(-2) - adj_w.unsqueeze(-1)).masked_fill_(~adj_parent, t).argmin(-1)
+        adj.scatter_(-1, adj_parent.unsqueeze(-1), 1)
+        adj = (adj | adj.transpose(-1, -2)).float()
+        x_tree = self.gnn_layers(x_tree, adj, adj_mask)
+        span_mask = span_mask.masked_scatter(span_mask, span_indices[2].eq(t - 1))
+        span_lens = span_mask.sum(-1)
+        x_tree, span_mask = x_tree[span_mask], span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max())))
+        x_span = x.new_zeros(*span_mask.shape, x.shape[-1]).masked_scatter_(span_mask.unsqueeze(-1), x_tree)
+        return x_span
+
+
+class AttachJuxtaposeConstituencyModelPos(Model):
+    r"""
+    The implementation of AttachJuxtapose Constituency Parser :cite:`yang-deng-2020-aj`.
+
+    Args:
+        n_words (int):
+            The size of the word vocabulary.
+        n_labels (int):
+            The number of labels in the treebank.
+        n_tags (int):
+            The number of POS tags, required if POS tag embeddings are used. Default: ``None``.
+        n_chars (int):
+            The number of characters, required if character-level representations are used. Default: ``None``.
+        encoder (str):
+            Encoder to use.
+            ``'lstm'``: BiLSTM encoder.
+            ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``.
+            Default: ``'lstm'``.
+        feat (List[str]):
+            Additional features to use, required if ``encoder='lstm'``.
+            ``'tag'``: POS tag embeddings.
+            ``'char'``: Character-level representations extracted by CharLSTM.
+            ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible.
+            Default: [``'char'``].
+        n_embed (int):
+            The size of word embeddings. Default: 100.
+        n_pretrained (int):
+            The size of pretrained word embeddings. Default: 100.
+        n_feat_embed (int):
+            The size of feature representations. Default: 100.
+        n_char_embed (int):
+            The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50.
+        n_char_hidden (int):
+            The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100.
+        char_pad_index (int):
+            The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0.
+        elmo (str):
+            Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``.
+        elmo_bos_eos (Tuple[bool]):
+            A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs.
+            Default: ``(True, False)``.
+        bert (str):
+            Specifies which kind of language model to use, e.g., ``'bert-base-cased'``.
+            This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_.
+            Default: ``None``.
+        n_bert_layers (int):
+            Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features.
+            The final outputs would be weighted sum of the hidden states of these layers.
+            Default: 4.
+        mix_dropout (float):
+            The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0.
+        bert_pooling (str):
+            Pooling way to get token embeddings.
+            ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all.
+            Default: ``mean``.
+        bert_pad_index (int):
+            The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features.
+            Default: 0.
+        finetune (bool):
+            If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``.
+        n_plm_embed (int):
+            The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0.
+        embed_dropout (float):
+            The dropout ratio of input embeddings. Default: .33.
+        n_encoder_hidden (int):
+            The size of encoder hidden states. Default: 800.
+        n_encoder_layers (int):
+            The number of encoder layers. Default: 3.
+        encoder_dropout (float):
+            The dropout ratio of encoder layers. Default: .33.
+        n_gnn_layers (int):
+            The number of GNN layers. Default: 3.
+        gnn_dropout (float):
+            The dropout ratio of GNN layers. Default: .33.
+        pad_index (int):
+            The index of the padding token in the word vocabulary. Default: 0.
+        unk_index (int):
+            The index of the unknown token in the word vocabulary. Default: 1.
+
+    .. _transformers:
+        https://github.com/huggingface/transformers
+    """
+
+    def __init__(self,
+                 n_words,
+                 n_labels,
+                 n_tags=16,
+                 n_chars=None,
+                 encoder='lstm',
+                 feat=['char', 'tag'],
+                 n_embed=100,
+                 n_pretrained=100,
+                 n_feat_embed=100,
+                 n_char_embed=50,
+                 n_char_hidden=100,
+                 char_pad_index=0,
+                 elmo='original_5b',
+                 elmo_bos_eos=(True, True),
+                 bert=None,
+                 n_bert_layers=4,
+                 mix_dropout=.0,
+                 bert_pooling='mean',
+                 bert_pad_index=0,
+                 finetune=False,
+                 n_plm_embed=0,
+                 embed_dropout=.33,
+                 n_encoder_hidden=800,
+                 n_encoder_layers=3,
+                 encoder_dropout=.33,
+                 n_gnn_layers=3,
+                 gnn_dropout=.33,
+                 pad_index=0,
+                 unk_index=1,
+                 **kwargs):
+        super().__init__(**Config().update(locals()))
+
+        # the last one represents the dummy node in the initial states
+        self.label_embed = nn.Embedding(n_labels+1, self.args.n_encoder_hidden)
+        self.gnn_layers = GraphConvolutionalNetwork(n_model=self.args.n_encoder_hidden,
+                                                    n_layers=self.args.n_gnn_layers,
+                                                    dropout=self.args.gnn_dropout)
+
+        self.node_classifier = nn.Sequential(
+            nn.Linear(2 * self.args.n_encoder_hidden, self.args.n_encoder_hidden // 2),
+            nn.LayerNorm(self.args.n_encoder_hidden // 2),
+            nn.ReLU(),
+            nn.Linear(self.args.n_encoder_hidden // 2, 1),
+        )
+        self.label_classifier = nn.Sequential(
+            nn.Linear(2 * self.args.n_encoder_hidden, self.args.n_encoder_hidden // 2),
+            nn.LayerNorm(self.args.n_encoder_hidden // 2),
+            nn.ReLU(),
+            nn.Linear(self.args.n_encoder_hidden // 2, 2 * n_labels),
+        )
+        self.pos_classifier = DecoderLSTMPos(
+                self.args.n_encoder_hidden, self.args.n_encoder_hidden, self.args.n_tags, 
+                num_layers=1, dropout=encoder_dropout, device=self.device
+            )
+        
+        #self.pos_tagger = nn.Identity()
+        # create delay projection
+        if self.args.delay != 0:
+            self.delay_proj = MLP(n_in=self.args.n_encoder_hidden * (self.args.delay+1),
+                                       n_out=self.args.n_encoder_hidden, dropout=gnn_dropout)
+
+        self.criterion = nn.CrossEntropyLoss()
+        
+    def encoder_forward(self, words: torch.Tensor, feats: List[torch.Tensor]) -> Tuple[torch.Tensor]:
+        """
+        Applies encoding forward pass. Maps a tensor of word indices (`words`) to their corresponding neural
+        representation.
+        Args:
+            words: torch.IntTensor ~ [batch_size, bos + pad(seq_len) + eos + delay]
+            feats: List[torch.Tensor]
+            lens: List[int]
+
+        Returns: x, qloss
+            x: torch.FloatTensor ~ [batch_size, bos + pad(seq_len) + eos, embed_dim]
+            qloss: torch.FloatTensor ~ 1
+
+        """
+
+        x = super().encode(words, feats)
+        s_tag = self.pos_classifier(x[:, 1:-(1+self.args.delay), :])
+
+        # adjust lengths to allow delay predictions
+        # x ~ [batch_size, bos + pad(seq_len) + eos, embed_dim]
+        if self.args.delay != 0:
+            x = torch.cat([x[:, i:(x.shape[1] - self.args.delay + i), :] for i in range(self.args.delay + 1)], dim=2)
+            x = self.delay_proj(x)
+
+        # pass through vector quantization
+        x, qloss = self.vq_forward(x)
+        return x, s_tag, qloss
+    
+    
+    def forward(
+        self,
+        words: torch.LongTensor,
+        feats: List[torch.LongTensor]
+    ) -> Tuple[torch.Tensor]:
+        r"""
+        Args:
+            words (~torch.LongTensor): ``[batch_size, seq_len]``.
+                Word indices.
+            feats (List[~torch.LongTensor]):
+                A list of feat indices.
+                The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``,
+                or ``[batch_size, seq_len]`` otherwise.
+                Default: ``None``.
+
+        Returns:
+            ~torch.Tensor:
+                Contextualized output hidden states of shape ``[batch_size, seq_len, n_model]`` of the input.
+        """
+        x, s_tag, qloss = self.encoder_forward(words, feats)
+
+        return x, s_tag, qloss
+
+    def loss(
+        self,
+        x: torch.Tensor,
+        nodes: torch.LongTensor,
+        parents: torch.LongTensor,
+        news: torch.LongTensor,
+        mask: torch.BoolTensor, s_tags: torch.LongTensor, tags: torch.LongTensor
+    ) -> torch.Tensor:
+        r"""
+        Args:
+            x (~torch.Tensor): ``[batch_size, seq_len, n_model]``.
+                Contextualized output hidden states.
+            nodes (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The target node positions on rightmost chains.
+            parents (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The parent node labels of terminals.
+            news (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The parent node labels of juxtaposed targets and terminals.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens in each chart.
+
+        Returns:
+            ~torch.Tensor:
+                The training loss.
+        """
+
+        spans, s_node, x_node = None, [], []
+        actions = torch.stack((nodes, parents, news))
+        for t, action in enumerate(actions.unbind(-1)):
+            if t == 0:
+                x_span = self.label_embed(actions.new_full((x.shape[0], 1), self.args.n_labels))
+                span_mask = mask[:, :1]
+            else:
+                x_span = self.rightmost_chain(x, spans, mask, t)
+                span_lens = spans[:, :-1, -1].ge(0).sum(-1)
+                span_mask = span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max())))
+            x_rightmost = torch.cat((x_span, x[:, t].unsqueeze(1).expand_as(x_span)), -1)
+            s_node.append(self.node_classifier(x_rightmost).squeeze(-1))
+            # we found softmax is slightly better than sigmoid in the original paper
+            s_node[-1] = s_node[-1].masked_fill_(~span_mask, -INF).masked_fill(~span_mask.any(-1).unsqueeze(-1), 0)
+            x_node.append(torch.bmm(s_node[-1].softmax(-1).unsqueeze(1), x_span).squeeze(1))
+            spans = AttachJuxtaposeTree.action2span(action, spans, self.args.nul_index, mask[:, t])
+        attach_mask = x.new_tensor(range(self.args.n_labels)).eq(self.args.nul_index)
+        s_node, x_node = pad(s_node, -INF).transpose(0, 1), torch.stack(x_node, 1)
+        s_parent, s_new = self.label_classifier(torch.cat((x, x_node), -1)).chunk(2, -1)
+        #s_postag = self.pos_classifier(x[:, 1:-(1+self.args.delay), :]).chunk(2, -1)
+        s_parent = torch.cat((s_parent[:, :1].masked_fill(attach_mask, -INF), s_parent[:, 1:]), 1)
+        s_new = torch.cat((s_new[:, :1].masked_fill(~attach_mask, -INF), s_new[:, 1:]), 1)
+        node_loss = self.criterion(s_node[mask], nodes[mask])
+        #print('node loss', node_loss)
+        label_loss = self.criterion(s_parent[mask], parents[mask]) + self.criterion(s_new[mask], news[mask])
+        #print('label loss', label_loss)
+
+        #print(s_tag[mask].shape, tags[mask].shape)
+        tag_loss = self.criterion(s_tags[mask], tags[mask])
+        #print('tag loss', tag_loss)
+        #tag_loss = self.pos_loss(s_tags, tags, mask)
+        #print("node loss, label loss, tag loss", node_loss, label_loss, tag_loss, node_loss + label_loss + tag_loss)
+        return node_loss + label_loss + tag_loss
+
+    def decode(
+        self,
+        x: torch.Tensor,
+        mask: torch.BoolTensor,
+        beam_size: int = 1
+    ) -> List[List[Tuple]]:
+        r"""
+        Args:
+            x (~torch.Tensor): ``[batch_size, seq_len, n_model]``.
+                Contextualized output hidden states.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens in each chart.
+            beam_size (int):
+                Beam size for decoding. Default: 1.
+
+        Returns:
+            List[List[Tuple]]:
+                Sequences of factorized labeled trees.
+        """
+        tokenwise_predictions = []
+        spans = None
+        batch_size, *_ = x.shape
+        n_labels = self.args.n_labels
+        # [batch_size * beam_size, ...]
+        x = x.unsqueeze(1).repeat(1, beam_size, 1, 1).view(-1, *x.shape[1:])
+        mask = mask.unsqueeze(1).repeat(1, beam_size, 1).view(-1, *mask.shape[1:])
+        # [batch_size]
+        batches = x.new_tensor(range(batch_size)).long() * beam_size
+        # accumulated scores
+        scores = x.new_full((batch_size, beam_size), -INF).index_fill_(-1, x.new_tensor(0).long(), 0).view(-1)
+        for t in range(x.shape[1]):
+            if t == 0:
+                x_span = self.label_embed(batches.new_full((x.shape[0], 1), n_labels))
+                span_mask = mask[:, :1]
+            else:
+                x_span = self.rightmost_chain(x, spans, mask, t)
+                span_lens = spans[:, :-1, -1].ge(0).sum(-1)
+                span_mask = span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max())))
+            s_node = self.node_classifier(torch.cat((x_span, x[:, t].unsqueeze(1).expand_as(x_span)), -1)).squeeze(-1)
+            s_node = s_node.masked_fill_(~span_mask, -INF).masked_fill(~span_mask.any(-1).unsqueeze(-1), 0).log_softmax(-1)
+            # we found softmax is slightly better than sigmoid in the original paper
+            x_node = torch.bmm(s_node.exp().unsqueeze(1), x_span).squeeze(1)
+            s_parent, s_new = self.label_classifier(torch.cat((x[:, t], x_node), -1)).chunk(2, -1)
+            s_parent, s_new = s_parent.log_softmax(-1), s_new.log_softmax(-1)
+            if t == 0:
+                s_parent[:, self.args.nul_index] = -INF
+                s_new[:, s_new.new_tensor(range(self.args.n_labels)).ne(self.args.nul_index)] = -INF
+            s_node, nodes = s_node.topk(min(s_node.shape[-1], beam_size), -1)
+            s_parent, parents = s_parent.topk(min(n_labels, beam_size), -1)
+            s_new, news = s_new.topk(min(n_labels, beam_size), -1)
+            s_action = s_node.unsqueeze(2) + (s_parent.unsqueeze(2) + s_new.unsqueeze(1)).view(x.shape[0], 1, -1)
+            s_action = s_action.view(x.shape[0], -1)
+            k_beam, k_node, k_parent = s_action.shape[-1], parents.shape[-1] * news.shape[-1], news.shape[-1]
+            # [batch_size * beam_size, k_beam]
+            scores = scores.unsqueeze(-1) + s_action
+            # [batch_size, beam_size]
+            scores, cands = scores.view(batch_size, -1).topk(beam_size, -1)
+            # [batch_size * beam_size]
+            scores = scores.view(-1)
+            beams = cands.div(k_beam, rounding_mode='floor')
+            nodes = nodes.view(batch_size, -1).gather(-1, cands.div(k_node, rounding_mode='floor'))
+            indices = (batches.unsqueeze(-1) + beams).view(-1)
+            
+            #print('indices', indices)
+            parents = parents[indices].view(batch_size, -1).gather(-1, cands.div(k_parent, rounding_mode='floor') % k_parent)
+            news = news[indices].view(batch_size, -1).gather(-1, cands % k_parent)
+            action = torch.stack((nodes, parents, news)).view(3, -1)
+            tokenwise_predictions.append([t, [x[0] for x in action.tolist()]])
+            spans = spans[indices] if spans is not None else None
+            spans = AttachJuxtaposeTree.action2span(action, spans, self.args.nul_index, mask[:, t])
+            #print("SPANS", spans)
+        mask = mask.view(batch_size, beam_size, -1)[:, 0]
+        # select an 1-best tree for each sentence
+        spans = spans[batches + scores.view(batch_size, -1).argmax(-1)]
+        span_mask = spans.ge(0)
+        span_indices = torch.where(span_mask)
+        span_labels = spans[span_indices]
+        chart_preds = [[] for _ in range(x.shape[0])]
+        for i, *span in zip(*[s.tolist() for s in span_indices], span_labels.tolist()):
+            chart_preds[i].append(span)
+        kk = [chart_preds + tokenwise_predictions]
+        return kk
+
+    def rightmost_chain(
+        self,
+        x: torch.Tensor,
+        spans: torch.LongTensor,
+        mask: torch.BoolTensor,
+        t: int
+    ) -> torch.Tensor:
+        x_p, mask_p = x[:, :t], mask[:, :t]
+        lens = mask_p.sum(-1)
+        span_mask = spans[:, :-1, 1:].ge(0)
+        span_lens = span_mask.sum((-1, -2))
+        span_indices = torch.where(span_mask)
+        span_labels = spans[:, :-1, 1:][span_indices]
+        x_span = self.label_embed(span_labels)
+        x_span += x[span_indices[0], span_indices[1]] + x[span_indices[0], span_indices[2]]
+        node_lens = lens + span_lens
+        adj_mask = node_lens.unsqueeze(-1).gt(x.new_tensor(range(node_lens.max())))
+        x_mask = lens.unsqueeze(-1).gt(x.new_tensor(range(adj_mask.shape[-1])))
+        span_mask = ~x_mask & adj_mask
+        # concatenate terminals and spans
+        x_tree = x.new_zeros(*adj_mask.shape, x.shape[-1]).masked_scatter_(x_mask.unsqueeze(-1), x_p[mask_p])
+        x_tree = x_tree.masked_scatter_(span_mask.unsqueeze(-1), x_span)
+        adj = mask.new_zeros(*x_tree.shape[:-1], x_tree.shape[1])
+        adj_spans = lens.new_tensor(range(x_tree.shape[1])).view(1, 1, -1).repeat(2, x.shape[0], 1)
+        adj_spans = adj_spans.masked_scatter_(span_mask.unsqueeze(0), torch.stack(span_indices[1:]))
+        adj_l, adj_r, adj_w = *adj_spans.unbind(), adj_spans[1] - adj_spans[0]
+        adj_parent = adj_l.unsqueeze(-1).ge(adj_l.unsqueeze(-2)) & adj_r.unsqueeze(-1).le(adj_r.unsqueeze(-2))
+        # set the parent of root as itself
+        adj_parent.diagonal(0, 1, 2).copy_(adj_w.eq(t - 1))
+        adj_parent = adj_parent & span_mask.unsqueeze(1)
+        # closet ancestor spans as parents
+        adj_parent = (adj_w.unsqueeze(-2) - adj_w.unsqueeze(-1)).masked_fill_(~adj_parent, t).argmin(-1)
+        adj.scatter_(-1, adj_parent.unsqueeze(-1), 1)
+        adj = (adj | adj.transpose(-1, -2)).float()
+        x_tree = self.gnn_layers(x_tree, adj, adj_mask)
+        span_mask = span_mask.masked_scatter(span_mask, span_indices[2].eq(t - 1))
+        span_lens = span_mask.sum(-1)
+        x_tree, span_mask = x_tree[span_mask], span_lens.unsqueeze(-1).gt(x.new_tensor(range(span_lens.max())))
+        x_span = x.new_zeros(*span_mask.shape, x.shape[-1]).masked_scatter_(span_mask.unsqueeze(-1), x_tree)
+        return x_span
+
+    
+    def pos_loss(self, pos_logits: torch.Tensor, pos_tags: torch.LongTensor, mask: torch.BoolTensor) -> torch.Tensor:
+        """
+        Args:
+            pos_logits (~torch.Tensor): [batch_size, seq_len, n_tags].
+            pos_tags (~torch.LongTensor): [batch_size, seq_len].
+            mask (~torch.BoolTensor): [batch_size, seq_len].
+
+        Returns:
+            torch.Tensor: The POS tagging loss.
+        """
+        loss_fn = nn.CrossEntropyLoss()
+        return loss_fn(pos_logits[mask], pos_tags[mask])
+
+    def decode_pos(self, s_tag: torch.Tensor):
+        """
+        Decode the most likely POS tags.
+
+        Args:
+            pos_logits (~torch.Tensor): [batch_size, seq_len, n_tags]
+            mask (~torch.BoolTensor): [batch_size, seq_len]
+
+        Returns:
+            List[List[int]]: POS tags per token for each sentence in the batch.
+        """
+        pos_preds = pos_logits.argmax(-1)
+        #return [seq[mask[i]].tolist() for i, seq in enumerate(pos_preds)]
+        return pos_preds
diff --git a/tania_scripts/supar/models/const/aj/parser.py b/tania_scripts/supar/models/const/aj/parser.py
new file mode 100644
index 0000000..543e828
--- /dev/null
+++ b/tania_scripts/supar/models/const/aj/parser.py
@@ -0,0 +1,534 @@
+# -*- coding: utf-8 -*-
+
+import os
+from typing import Dict, Iterable, Set, Union
+
+import torch
+
+from supar.models.const.aj.model import AttachJuxtaposeConstituencyModel, AttachJuxtaposeConstituencyModelPos
+from supar.models.const.aj.transform import AttachJuxtaposeTree
+from supar.parser import Parser
+from supar.utils import Config, Dataset, Embedding
+from supar.utils.common import BOS, EOS, NUL, PAD, UNK
+from supar.utils.field import Field, RawField, SubwordField
+from supar.utils.logging import get_logger
+from supar.utils.metric import SpanMetric
+from supar.utils.tokenizer import TransformerTokenizer
+from supar.utils.transform import Batch
+from torch.nn.utils.rnn import pad_sequence
+
+
+logger = get_logger(__name__)
+
+
+def compute_pos_accuracy(pos_gold, pos_preds):
+    correct = 0
+    total = 0
+    for gold_seq, pred_seq in zip(pos_gold, pos_preds):
+        for g, p in zip(gold_seq, pred_seq):
+            if g == p:
+                correct += 1
+        total += len(gold_seq)
+    return correct, total
+
+
+    
+
+class AttachJuxtaposeConstituencyParser(Parser):
+    r"""
+    The implementation of AttachJuxtapose Constituency Parser :cite:`yang-deng-2020-aj`.
+    """
+
+    NAME = 'attach-juxtapose-constituency'
+    MODEL = AttachJuxtaposeConstituencyModel
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self.TREE = self.transform.TREE
+        self.NODE = self.transform.NODE
+        self.PARENT = self.transform.PARENT
+        self.NEW = self.transform.NEW
+
+    def train(
+        self,
+        train: Union[str, Iterable],
+        dev: Union[str, Iterable],
+        test: Union[str, Iterable],
+        epochs: int = 1000,
+        patience: int = 100,
+        batch_size: int = 5000,
+        update_steps: int = 1,
+        buckets: int = 32,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        beam_size: int = 1,
+        delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''},
+        equal: Dict = {'ADVP': 'PRT'},
+        verbose: bool = True,
+        **kwargs
+    ):
+        print("here")
+        return super().train(**Config().update(locals()))
+
+    def evaluate(
+        self,
+        data: Union[str, Iterable],
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        beam_size: int = 1,
+        delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''},
+        equal: Dict = {'ADVP': 'PRT'},
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().evaluate(**Config().update(locals()))
+
+    def predict(
+        self,
+        data: Union[str, Iterable],
+        pred: str = None,
+        lang: str = None,
+        prob: bool = False,
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        beam_size: int = 1,
+        verbose: bool = True,
+        **kwargs
+    ):
+
+        return super().predict(**Config().update(locals()))
+
+    def train_step(self, batch: Batch) -> torch.Tensor:
+        #print("TRAIN STEP")
+        words, *feats, trees, nodes, parents, news = batch
+        mask = batch.mask[:, (2+self.args.delay):]
+        x, s_tag, qloss = self.model(words, feats)
+        #print("s_tag", s_tag)
+        loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask) + qloss
+        return loss
+
+    @torch.no_grad()
+    def eval_step(self, batch: Batch) -> SpanMetric:
+        #print("EVAL STEP")
+        words, *feats, trees, nodes, parents, news = batch
+        #print("WORDS", words.shape, words)
+        mask = batch.mask[:, (2+self.args.delay):]
+        x, qloss = self.model(words, feats)
+        loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask) + qloss
+        chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size)
+        #print("CHART PREDS")
+        #print("self new vocab", self.NEW.vocab.items())
+        #print()
+        preds = [AttachJuxtaposeTree.build(tree, [(i, j, self.NEW.vocab[label]) for i, j, label in chart], {UNK, NUL})
+                 for tree, chart in zip(trees, chart_preds)]
+
+        for tree, chart in zip(trees, chart_preds):
+            print(tree, chart)
+
+        print()
+        for tree in trees:
+            print("ORIG TREE", tree)
+        print()
+        for tree in preds:
+            print("PRED TREE", tree)
+
+        print("=========================")
+
+        return SpanMetric(loss,
+                          [AttachJuxtaposeTree.factorize(tree, self.args.delete, self.args.equal) for tree in preds],
+                          [AttachJuxtaposeTree.factorize(tree, self.args.delete, self.args.equal) for tree in trees])
+
+    @torch.no_grad()
+    def pred_step(self, batch: Batch) -> Batch:
+        words, *feats, trees = batch
+        mask = batch.mask[:, (2+self.args.delay):]
+        x, _ = self.model(words, feats)
+        chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size)
+        chart_preds = chart_preds[0]
+        batch.trees = [AttachJuxtaposeTree.build(tree, [(i, j, self.NEW.vocab[label]) for i, j, label in chart], {UNK, NUL})
+                       for tree, chart in zip(trees, chart_preds)]
+        if self.args.prob:
+            raise NotImplementedError("Returning action probs are currently not supported yet.")
+
+        new_tokenwise_preds = []
+        for k, y in chart_preds[1:]:
+            new_tokenwise_preds.append([k, y[0], self.NEW.vocab[y[1]], self.NEW.vocab[y[2]]])
+
+        chart_preds = [[[x[0], x[1], self.NEW.vocab[x[2]]] for x in chart_preds[0]]] + new_tokenwise_preds
+        #for x in chart_preds[1:]:
+        #    new_item = [x[0], [x[1][0], self.NEW.vocab[x[1][1]], self.NEW.vocab[x[1][2]]]
+
+        return chart_preds #batch
+
+    @classmethod
+    def build(cls, path, min_freq=2, fix_len=20, **kwargs):
+        r"""
+        Build a brand-new Parser, including initialization of all data fields and model parameters.
+
+        Args:
+            path (str):
+                The path of the model to be saved.
+            min_freq (str):
+                The minimum frequency needed to include a token in the vocabulary. Default: 2.
+            fix_len (int):
+                The max length of all subword pieces. The excess part of each piece will be truncated.
+                Required if using CharLSTM/BERT.
+                Default: 20.
+            kwargs (Dict):
+                A dict holding the unconsumed arguments.
+        """
+
+        args = Config(**locals())
+        os.makedirs(os.path.dirname(path) or './', exist_ok=True)
+        if os.path.exists(path) and not args.build:
+            parser = cls.load(**args)
+            parser.model = cls.MODEL(**parser.args)
+            parser.model.load_pretrained(parser.transform.WORD[0].embed).to(parser.device)
+            return parser
+
+        logger.info("Building the fields")
+        TAG, CHAR = None, None
+        if args.encoder == 'bert':
+            t = TransformerTokenizer(args.bert)
+            pad_token = t.pad if t.pad else PAD
+            WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, eos=t.eos, fix_len=args.fix_len, tokenize=t, delay=args.delay)
+            WORD.vocab = t.vocab
+        else:
+            WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True, delay=args.delay)
+            if 'char' in args.feat:
+                CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, eos=EOS, fix_len=args.fix_len, delay=args.delay)
+        TAG = Field('tags', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True, delay=args.delay)
+        TREE = RawField('trees')
+        NODE, PARENT, NEW = Field('node', use_vocab=False), Field('parent', unk=UNK), Field('new', unk=UNK)
+        transform = AttachJuxtaposeTree(WORD=(WORD, CHAR), POS=TAG, TREE=TREE, NODE=NODE, PARENT=PARENT, NEW=NEW)
+
+        train = Dataset(transform, args.train, **args)
+        if args.encoder != 'bert':
+            WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x))
+            if CHAR is not None:
+                CHAR.build(train)
+        TAG.build(train)
+        PARENT, NEW = PARENT.build(train), NEW.build(train)
+        PARENT.vocab = NEW.vocab.update(PARENT.vocab)
+        args.update({
+            'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init,
+            'n_labels': len(NEW.vocab),
+            'n_tags': len(TAG.vocab) if TAG is not None else None,
+            'n_chars': len(CHAR.vocab) if CHAR is not None else None,
+            'char_pad_index': CHAR.pad_index if CHAR is not None else None,
+            'pad_index': WORD.pad_index,
+            'unk_index': WORD.unk_index,
+            'bos_index': WORD.bos_index,
+            'eos_index': WORD.eos_index,
+            'nul_index': NEW.vocab[NUL]
+        })
+        logger.info(f"{transform}")
+
+        logger.info("Building the model")
+        model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None)
+        logger.info(f"{model}\n")
+
+        parser = cls(args, model, transform)
+        parser.model.to(parser.device)
+        return parser
+
+def flatten(x):
+    result = []
+    for el in x:
+        if isinstance(el, list):
+            result.extend(flatten(el))
+        else:
+            result.append(el)
+    return result
+
+
+
+
+class AttachJuxtaposeConstituencyParserPos(Parser):
+    r"""
+    The implementation of AttachJuxtapose Constituency Parser :cite:`yang-deng-2020-aj`.
+    """
+
+    NAME = 'attach-juxtapose-constituency'
+    MODEL = AttachJuxtaposeConstituencyModelPos
+
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self.TREE = self.transform.TREE
+        self.NODE = self.transform.NODE
+        self.PARENT = self.transform.PARENT
+        self.NEW = self.transform.NEW
+        self.TAG = self.transform.POS
+        
+        #print(self.TAG)
+
+    def train(
+        self,
+        train: Union[str, Iterable],
+        dev: Union[str, Iterable],
+        test: Union[str, Iterable],
+        epochs: int = 1000,
+        patience: int = 100,
+        batch_size: int = 5000,
+        update_steps: int = 1,
+        buckets: int = 32,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        beam_size: int = 1,
+        delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''},
+        equal: Dict = {'ADVP': 'PRT'},
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().train(**Config().update(locals()))
+
+    def evaluate(
+        self,
+        data: Union[str, Iterable],
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        beam_size: int = 1,
+        delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''},
+        equal: Dict = {'ADVP': 'PRT'},
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().evaluate(**Config().update(locals()))
+
+    def predict(
+        self,
+        data: Union[str, Iterable],
+        pred: str = None,
+        lang: str = None,
+        prob: bool = False,
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        beam_size: int = 1,
+        verbose: bool = True,
+        **kwargs
+    ):
+
+        return super().predict(**Config().update(locals()))
+
+    def train_step(self, batch: Batch) -> torch.Tensor:
+        #print("TRAIN STEP")
+        words, *feats, postags, nodes, parents, news = batch
+        mask = batch.mask[:, (2+self.args.delay):]
+        x, s_tag, qloss = self.model(words, feats)
+        tags = feats[-1]
+        #loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask) + qloss + pos_logits
+        #loss = loss.mean()
+        loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask, s_tag, tags[:, 1:-1]) + qloss
+        
+        return loss
+
+    @torch.no_grad()
+    def eval_step(self, batch: Batch) -> SpanMetric:
+        
+        #print("EVAL STEP")
+        words, *feats, trees, nodes, parents, news = batch
+
+        tags = feats[-1]
+        #loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask) + qloss + pos_logits
+        #loss = loss.mean()
+        mask = batch.mask[:, (2+self.args.delay):]
+        x, s_tag, qloss = self.model(words, feats)
+        
+        loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask, s_tag, tags[:, 1:-1]) + qloss
+        chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size)
+        #print('CHART PREDS', chart_preds[0])
+
+        pos_preds = [[self.TAG.vocab[p.item()] for p in sent] for sent in s_tag.argmax(-1)]
+        trimmed_tags = [tag_seq[1:-1] for tag_seq in tags]
+        trimmed_tags_list = [x.cpu().tolist() for x in trimmed_tags]
+        pos_gold = [[self.TAG.vocab[p] for p in sent] for sent in trimmed_tags_list]
+
+        pos_correct, pos_total = compute_pos_accuracy(pos_gold, pos_preds)
+        pos_acc = pos_correct/pos_total
+        print(pos_acc)
+  
+        """
+        tags = [*feats[-1:]]
+        trimmed_tags = [tag_seq[1:-1] for tag_seq in tags[0]]
+        gtags = [*feats[-1:]][0].cpu().tolist()
+        gtags = [x[1:-1] for x in gtags]
+        mask = batch.mask[:, (2+self.args.delay):]
+        x, s_tag, qloss = self.model(words, feats)
+
+        tag_tensor = pad_sequence(trimmed_tags, batch_first=True, padding_value=self.TAG.pad_index).to(s_tag.device)
+
+        assert s_tag.shape[:2] == tag_tensor.shape[:2]
+        print("s_tag shape", s_tag.shape[:2], "tag_tensor shape", tag_tensor.shape[:2])
+        
+
+        loss = self.model.loss(x[:, 1:-1], nodes, parents, news, mask, s_tag, tag_tensor) + qloss
+
+        chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size)
+        #pos_preds = [self.TAG.vocab[x] for x in s_tag.argmax(-1)]
+
+        for tag_seq in gtags:
+            for pos in tag_seq:
+                assert 0 <= pos < len(self.TAG.vocab)
+        
+        pos_preds = [[self.TAG.vocab[p.item()] for p in sent] for sent in s_tag.argmax(-1)]
+        pos_gold = [[self.TAG.vocab[pos] for pos in tag_seq] for tag_seq in gtags]
+
+        #print("357!", len(pos_gold), len(pos_preds))
+        pos_correct, pos_total = compute_pos_accuracy(pos_gold, pos_preds)
+        print("358!", pos_correct, pos_total, pos_correct/pos_total)
+
+            
+        #print('%%% POS preds', pos_preds)
+        #print('%%%% POS gold', pos_gold)
+        """
+
+        #batch.trees = [AttachJuxtaposeTree.build(tree, [(i, j, self.NEW.vocab[label]) for i, j, label in chart], {UNK, NUL})
+         #              for tree, chart in zip(trees, chart_preds)]
+        #print(batch.trees)
+              
+        preds = [AttachJuxtaposeTree.build(tree, [[x[0], x[1], self.NEW.vocab[x[2]]] for x in chart], {UNK, NUL})
+                 for tree, chart in zip(trees, chart_preds[0])]
+        #print('POS preds', s_tag.argmax(-1))
+        #print("PREDS", len(preds))
+      
+
+        """
+        span_preds = [[x[0], x[1], self.NEW.vocab[x[2]]] for x in chart_preds[0][0]]
+        #print("new SPAN preds", span_preds)
+        verbalized_preds = []
+
+
+        for x in chart_preds[1:]:
+            new_item = [x[0], [x[1][0], self.NEW.vocab[x[1][1]], self.NEW.vocab[x[1][2]]]]
+            #print(new_item)
+            verbalized_preds.append(new_item)
+        """
+        
+        print("424", loss, pos_acc)
+        return SpanMetric(loss,
+                          [AttachJuxtaposeTree.factorize(tree, self.args.delete, self.args.equal) for tree in preds],
+                          [AttachJuxtaposeTree.factorize(tree, self.args.delete, self.args.equal) for tree in trees], pos_acc)
+
+    @torch.no_grad()
+    def pred_step(self, batch: Batch) -> Batch:
+        words, *feats, trees = batch
+        mask = batch.mask[:, (2+self.args.delay):]
+        x, s_tag, qloss = self.model(words, feats)
+        chart_preds = self.model.decode(x[:, 1:-1], mask, self.args.beam_size)
+        #print('VHART PREDS: ', chart_preds)
+        #print('LEN VHART PREDS: ', len(chart_preds))
+
+        chart_preds = chart_preds[0]
+        batch.trees = [AttachJuxtaposeTree.build(tree, [(i, j, self.NEW.vocab[label]) for i, j, label in chart], {UNK, NUL})
+                       for tree, chart in zip(trees, chart_preds)]
+        if self.args.prob:
+            raise NotImplementedError("Returning action probs are currently not supported yet.")
+
+        new_tokenwise_preds = []
+        #for pred in chart_preds:
+        #    print("PRED", pred)
+        #    new_tokenwise_preds.append([k, y[0], self.NEW.vocab[y[1]], self.NEW.vocab[y[2]]])
+
+
+        span_preds = [[x[0], x[1], self.NEW.vocab[x[2]]] for x in chart_preds[0]] + new_tokenwise_preds
+        #print("new chart preds", span_preds)
+        verbalized_preds = []
+        for x in chart_preds[1:]:
+            new_item = [x[0], [x[1][0], self.NEW.vocab[x[1][1]], self.NEW.vocab[x[1][2]]]]
+            #print(new_item)
+            verbalized_preds.append(new_item)
+        #print('POS preds', s_tag.argmax(-1))
+        pos_preds = [self.TAG.vocab[x] for x in s_tag.argmax(-1)]
+        return span_preds, verbalized_preds, pos_preds #batch
+
+    @classmethod
+    def build(cls, path, min_freq=2, fix_len=20, **kwargs):
+        r"""
+        Build a brand-new Parser, including initialization of all data fields and model parameters.
+
+        Args:
+            path (str):
+                The path of the model to be saved.
+            min_freq (str):
+                The minimum frequency needed to include a token in the vocabulary. Default: 2.
+            fix_len (int):
+                The max length of all subword pieces. The excess part of each piece will be truncated.
+                Required if using CharLSTM/BERT.
+                Default: 20.
+            kwargs (Dict):
+                A dict holding the unconsumed arguments.
+        """
+
+        args = Config(**locals())
+        os.makedirs(os.path.dirname(path) or './', exist_ok=True)
+        if os.path.exists(path) and not args.build:
+            parser = cls.load(**args)
+            parser.model = cls.MODEL(**parser.args)
+            parser.model.load_pretrained(parser.transform.WORD[0].embed).to(parser.device)
+            return parser
+
+        logger.info("Building the fields")
+        TAG, CHAR = None, None
+        if args.encoder == 'bert':
+            t = TransformerTokenizer(args.bert)
+            pad_token = t.pad if t.pad else PAD
+            WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, eos=t.eos, fix_len=args.fix_len, tokenize=t, delay=args.delay)
+            WORD.vocab = t.vocab
+        else:
+            WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True, delay=args.delay)
+            if 'char' in args.feat:
+                CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, eos=EOS, fix_len=args.fix_len, delay=args.delay)
+        TAG = Field('tags', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True, delay=args.delay)
+        TREE = RawField('trees')
+        NODE, PARENT, NEW = Field('node', use_vocab=False), Field('parent', unk=UNK), Field('new', unk=UNK)
+        transform = AttachJuxtaposeTree(WORD=(WORD, CHAR), POS=TAG, TREE=TREE, NODE=NODE, PARENT=PARENT, NEW=NEW)
+
+        train = Dataset(transform, args.train, **args)
+        if args.encoder != 'bert':
+            WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x))
+            if CHAR is not None:
+                CHAR.build(train)
+        TAG.build(train)
+        #print("203 TAG VOCAB", [x for x in TAG.vocab.items()])
+        PARENT, NEW = PARENT.build(train), NEW.build(train)
+        PARENT.vocab = NEW.vocab.update(PARENT.vocab)
+        args.update({
+            'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init,
+            'n_labels': len(NEW.vocab),
+            'n_tags': len(TAG.vocab) if TAG is not None else None,
+            'n_chars': len(CHAR.vocab) if CHAR is not None else None,
+            'char_pad_index': CHAR.pad_index if CHAR is not None else None,
+            'pad_index': WORD.pad_index,
+            'unk_index': WORD.unk_index,
+            'bos_index': WORD.bos_index,
+            'eos_index': WORD.eos_index,
+            'nul_index': NEW.vocab[NUL]
+        })
+        logger.info(f"{transform}")
+        
+        #print('TAG VOCAB', TAG.vocab.items())
+
+        logger.info("Building the model")
+        model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None)
+        logger.info(f"{model}\n")
+
+        parser = cls(args, model, transform)
+        parser.model.to(parser.device)
+        return parser
\ No newline at end of file
diff --git a/tania_scripts/supar/models/const/aj/transform.py b/tania_scripts/supar/models/const/aj/transform.py
new file mode 100644
index 0000000..56e0f51
--- /dev/null
+++ b/tania_scripts/supar/models/const/aj/transform.py
@@ -0,0 +1,459 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+import os
+from typing import TYPE_CHECKING, Iterable, List, Optional, Tuple, Union
+
+import nltk
+import torch
+
+from supar.models.const.crf.transform import Tree
+from supar.utils.common import NUL
+from supar.utils.logging import get_logger
+from supar.utils.tokenizer import Tokenizer
+from supar.utils.transform import Sentence
+
+if TYPE_CHECKING:
+    from supar.utils import Field
+
+logger = get_logger(__name__)
+
+
+class AttachJuxtaposeTree(Tree):
+    r"""
+    :class:`AttachJuxtaposeTree` is derived from the :class:`Tree` class,
+    supporting back-and-forth transformations between trees and AttachJuxtapose actions :cite:`yang-deng-2020-aj`.
+
+    Attributes:
+        WORD:
+            Words in the sentence.
+        POS:
+            Part-of-speech tags, or underscores if not available.
+        TREE:
+            The raw constituency tree in :class:`nltk.tree.Tree` format.
+        NODE:
+            The target node on each rightmost chain.
+        PARENT:
+            The label of the parent node of each terminal.
+        NEW:
+            The label of each newly inserted non-terminal with a target node and a terminal as juxtaposed children.
+            ``NUL`` represents the `Attach` action.
+    """
+
+    fields = ['WORD', 'POS', 'TREE', 'NODE', 'PARENT', 'NEW']
+
+    def __init__(
+        self,
+        WORD: Optional[Union[Field, Iterable[Field]]] = None,
+        POS: Optional[Union[Field, Iterable[Field]]] = None,
+        TREE: Optional[Union[Field, Iterable[Field]]] = None,
+        NODE: Optional[Union[Field, Iterable[Field]]] = None,
+        PARENT: Optional[Union[Field, Iterable[Field]]] = None,
+        NEW: Optional[Union[Field, Iterable[Field]]] = None
+    ) -> Tree:
+        super().__init__()
+
+        self.WORD = WORD
+        self.POS = POS
+        self.TREE = TREE
+        self.NODE = NODE
+        self.PARENT = PARENT
+        self.NEW = NEW
+
+    @property
+    def src(self):
+        return self.WORD, self.POS, self.TREE
+
+    @property
+    def tgt(self):
+        return self.NODE, self.PARENT, self.NEW
+
+    @classmethod
+    def tree2action(cls, tree: nltk.Tree):
+        r"""
+        Converts a constituency tree into AttachJuxtapose actions.
+
+        Args:
+            tree (nltk.tree.Tree):
+                A constituency tree in :class:`nltk.tree.Tree` format.
+
+        Returns:
+            A sequence of AttachJuxtapose actions.
+
+        Examples:
+            >>> from supar.models.const.aj.transform import AttachJuxtaposeTree
+            >>> tree = nltk.Tree.fromstring('''
+                                            (TOP
+                                              (S
+                                                (NP (_ Arthur))
+                                                (VP
+                                                  (_ is)
+                                                  (NP (NP (_ King)) (PP (_ of) (NP (_ the) (_ Britons)))))
+                                                (_ .)))
+                                            ''')
+            >>> tree.pretty_print()
+                            TOP
+                             |
+                             S
+               ______________|_______________________
+              |              VP                      |
+              |      ________|___                    |
+              |     |            NP                  |
+              |     |    ________|___                |
+              |     |   |            PP              |
+              |     |   |     _______|___            |
+              NP    |   NP   |           NP          |
+              |     |   |    |        ___|_____      |
+              _     _   _    _       _         _     _
+              |     |   |    |       |         |     |
+            Arthur  is King  of     the     Britons  .
+            >>> AttachJuxtaposeTree.tree2action(tree)
+            [(0, 'NP', '<nul>'), (0, 'VP', 'S'), (1, 'NP', '<nul>'),
+             (2, 'PP', 'NP'), (3, 'NP', '<nul>'), (4, '<nul>', '<nul>'),
+             (0, '<nul>', '<nul>')]
+        """
+
+        def isroot(node):
+            return node == tree[0]
+
+        def isterminal(node):
+            return len(node) == 1 and not isinstance(node[0], nltk.Tree)
+
+        def last_leaf(node):
+            pos = ()
+            while True:
+                pos += (len(node) - 1,)
+                node = node[-1]
+                if isterminal(node):
+                    return node, pos
+
+        def parent(position):
+            return tree[position[:-1]]
+
+        def grand(position):
+            return tree[position[:-2]]
+
+        def detach(tree):
+            last, last_pos = last_leaf(tree)
+            siblings = parent(last_pos)[:-1]
+
+            if len(siblings) > 0:
+                last_subtree = last
+                last_subtree_siblings = siblings
+                parent_label = NUL
+            else:
+                last_subtree, last_pos = parent(last_pos), last_pos[:-1]
+                last_subtree_siblings = [] if isroot(last_subtree) else parent(last_pos)[:-1]
+                parent_label = last_subtree.label()
+
+            target_pos, new_label, last_tree = 0, NUL, tree
+            if isroot(last_subtree):
+                last_tree = None
+            
+            elif len(last_subtree_siblings) == 1 and not isterminal(last_subtree_siblings[0]):
+                new_label = parent(last_pos).label()
+                new_label = new_label
+                target = last_subtree_siblings[0]
+                last_grand = grand(last_pos)
+                if last_grand is None:
+                    last_tree = targetistermina
+                else:
+                    last_grand[-1] = target
+                target_pos = len(last_pos) - 2
+            else:
+                target = parent(last_pos)
+                target.pop()
+                target_pos = len(last_pos) - 2
+            action = target_pos, parent_label, new_label
+            return action, last_tree
+        if tree is None:
+            return []
+        action, last_tree = detach(tree)
+        return cls.tree2action(last_tree) + [action]
+
+    @classmethod
+    def action2tree(
+        cls,
+        tree: nltk.Tree,
+        actions: List[Tuple[int, str, str]],
+        join: str = '::',
+    ) -> nltk.Tree:
+        r"""
+        Recovers a constituency tree from a sequence of AttachJuxtapose actions.
+
+        Args:
+            tree (nltk.tree.Tree):
+                An empty tree that provides a base for building a result tree.
+            actions (List[Tuple[int, str, str]]):
+                A sequence of AttachJuxtapose actions.
+            join (str):
+                A string used to connect collapsed node labels. Non-terminals containing this will be expanded to unary chains.
+                Default: ``'::'``.
+
+        Returns:
+            A result constituency tree.
+
+        Examples:
+            >>> from supar.models.const.aj.transform import AttachJuxtaposeTree
+            >>> tree = AttachJuxtaposeTree.totree(['Arthur', 'is', 'King', 'of', 'the', 'Britons', '.'], 'TOP')
+            >>> AttachJuxtaposeTree.action2tree(tree,
+                                                [(0, 'NP', '<nul>'), (0, 'VP', 'S'), (1, 'NP', '<nul>'),
+                                                 (2, 'PP', 'NP'), (3, 'NP', '<nul>'), (4, '<nul>', '<nul>'),
+                                                 (0, '<nul>', '<nul>')]).pretty_print()
+                            TOP
+                             |
+                             S
+               ______________|_______________________
+              |              VP                      |
+              |      ________|___                    |
+              |     |            NP                  |
+              |     |    ________|___                |
+              |     |   |            PP              |
+              |     |   |     _______|___            |
+              NP    |   NP   |           NP          |
+              |     |   |    |        ___|_____      |
+              _     _   _    _       _         _     _
+              |     |   |    |       |         |     |
+            Arthur  is King  of     the     Britons  .
+        """
+
+        def target(node, depth):
+            node_pos = ()
+            for _ in range(depth):
+                node_pos += (len(node) - 1,)
+                node = node[-1]
+            return node, node_pos
+
+        def parent(tree, position):
+            return tree[position[:-1]]
+
+        def execute(tree: nltk.Tree, terminal: Tuple(str, str), action: Tuple[int, str, str]) -> nltk.Tree:
+            target_pos, parent_label, new_label, post = action
+            #print(target_pos, parent_label, new_label)
+            new_leaf = nltk.Tree(post, [terminal[0]])
+
+            # create the subtree to be inserted
+            new_subtree = new_leaf if parent_label == NUL else nltk.Tree(parent_label, [new_leaf])
+            # find the target position at which to insert the new subtree
+            target_node = tree
+            if target_node is not None:
+                target_node, target_pos = target(target_node, target_pos)
+
+            # Attach
+            if new_label == NUL:
+                # attach the first token
+                if target_node is None:
+                    return new_subtree
+                target_node.append(new_subtree)
+            # Juxtapose
+            else:
+                new_subtree = nltk.Tree(new_label, [target_node, new_subtree])
+                if len(target_pos) > 0:
+                    parent_node = parent(tree, target_pos)
+                    parent_node[-1] = new_subtree
+                else:
+                    tree = new_subtree
+            return tree
+
+        tree, root, terminals = None, tree.label(), tree.pos()
+        for terminal, action in zip(terminals, actions):
+            tree = execute(tree, terminal, action)
+        # recover unary chains
+        nodes = [tree]
+        while nodes:
+            node = nodes.pop()
+            if isinstance(node, nltk.Tree):
+                nodes.extend(node)
+                if join in node.label():
+                    labels = node.label().split(join)
+                    node.set_label(labels[0])
+                    subtree = nltk.Tree(labels[-1], node)
+                    for label in reversed(labels[1:-1]):
+                        subtree = nltk.Tree(label, [subtree])
+                    node[:] = [subtree]
+        return nltk.Tree(root, [tree])
+
+    @classmethod
+    def action2span(
+        cls,
+        action: torch.Tensor,
+        spans: torch.Tensor = None,
+        nul_index: int = -1,
+        mask: torch.BoolTensor = None
+    ) -> torch.Tensor:
+        r"""
+        Converts a batch of the tensorized action at a given step into spans.
+
+        Args:
+            action (~torch.Tensor): ``[3, batch_size]``.
+                A batch of the tensorized action at a given step, containing indices of target nodes, parent and new labels.
+            spans (~torch.Tensor):
+                Spans generated at previous steps, ``None`` at the first step. Default: ``None``.
+            nul_index (int):
+                The index for the obj:`NUL` token, representing the Attach action. Default: -1.
+            mask (~torch.BoolTensor): ``[batch_size]``.
+                The mask for covering the unpadded tokens.
+
+        Returns:
+            A tensor representing a batch of spans for the given step.
+
+        Examples:
+            >>> from collections import Counter
+            >>> from supar.models.const.aj.transform import AttachJuxtaposeTree, Vocab
+            >>> from supar.utils.common import NUL
+            >>> nodes, parents, news = zip(*[(0, 'NP', NUL), (0, 'VP', 'S'), (1, 'NP', NUL),
+                                             (2, 'PP', 'NP'), (3, 'NP', NUL), (4, NUL, NUL),
+                                             (0, NUL, NUL)])
+            >>> vocab = Vocab(Counter(sorted(set([*parents, *news]))))
+            >>> actions = torch.tensor([nodes, vocab[parents], vocab[news]]).unsqueeze(1)
+            >>> spans = None
+            >>> for action in actions.unbind(-1):
+            ...     spans = AttachJuxtaposeTree.action2span(action, spans, vocab[NUL])
+            ...
+            >>> spans
+            tensor([[[-1,  1, -1, -1, -1, -1, -1,  3],
+                     [-1, -1, -1, -1, -1, -1,  4, -1],
+                     [-1, -1, -1,  1, -1, -1,  1, -1],
+                     [-1, -1, -1, -1, -1, -1,  2, -1],
+                     [-1, -1, -1, -1, -1, -1,  1, -1],
+                     [-1, -1, -1, -1, -1, -1, -1, -1],
+                     [-1, -1, -1, -1, -1, -1, -1, -1],
+                     [-1, -1, -1, -1, -1, -1, -1, -1]]])
+            >>> sequence = torch.where(spans.ge(0))
+            >>> sequence = list(zip(sequence[1].tolist(), sequence[2].tolist(), vocab[spans[sequence]]))
+            >>> sequence
+            [(0, 1, 'NP'), (0, 7, 'S'), (1, 6, 'VP'), (2, 3, 'NP'), (2, 6, 'NP'), (3, 6, 'PP'), (4, 6, 'NP')]
+            >>> tree = AttachJuxtaposeTree.totree(['Arthur', 'is', 'King', 'of', 'the', 'Britons', '.'], 'TOP')
+            >>> AttachJuxtaposeTree.build(tree, sequence).pretty_print()
+                            TOP
+                             |
+                             S
+               ______________|_______________________
+              |              VP                      |
+              |      ________|___                    |
+              |     |            NP                  |
+              |     |    ________|___                |
+              |     |   |            PP              |
+              |     |   |     _______|___            |
+              NP    |   NP   |           NP          |
+              |     |   |    |        ___|_____      |
+              _     _   _    _       _         _     _
+              |     |   |    |       |         |     |
+            Arthur  is King  of     the     Britons  .
+
+        """
+
+        # [batch_size]
+        target, parent, new = action
+        if spans is None:
+            spans = action.new_full((action.shape[1], 2, 2), -1)
+            spans[:, 0, 1] = parent
+            return spans
+        if mask is None:
+            mask = torch.ones_like(target, dtype=bool)
+        juxtapose_mask = new.ne(nul_index) & mask
+        # ancestor nodes are those on the rightmost chain and higher than the target node
+        # [batch_size, seq_len]
+        rightmost_mask = spans[..., -1].ge(0)
+        ancestors = rightmost_mask.cumsum(-1).masked_fill_(~rightmost_mask, -1) - 1
+        # should not include the target node for the Juxtapose action
+        ancestor_mask = mask.unsqueeze(-1) & ancestors.ge(0) & ancestors.le((target - juxtapose_mask.long()).unsqueeze(-1))
+        target_pos = torch.where(ancestors.eq(target.unsqueeze(-1))[juxtapose_mask])[-1]
+        # the right boundaries of ancestor nodes should be aligned with the new generated terminals
+        spans = torch.cat((spans, torch.where(ancestor_mask, spans[..., -1], -1).unsqueeze(-1)), -1)
+        spans[..., -2].masked_fill_(ancestor_mask, -1)
+        spans[juxtapose_mask, target_pos, -1] = new.masked_fill(new.eq(nul_index), -1)[juxtapose_mask]
+        spans[mask, -1, -1] = parent.masked_fill(parent.eq(nul_index), -1)[mask]
+        # [batch_size, seq_len+1, seq_len+1]
+        spans = torch.cat((spans, torch.full_like(spans[:, :1], -1)), 1)
+        return spans
+
+    def load(
+        self,
+        data: Union[str, Iterable],
+        lang: Optional[str] = None,
+        **kwargs
+    ) -> List[AttachJuxtaposeTreeSentence]:
+        r"""
+        Args:
+            data (Union[str, Iterable]):
+                A filename or a list of instances.
+            lang (str):
+                Language code (e.g., ``en``) or language name (e.g., ``English``) for the text to tokenize.
+                ``None`` if tokenization is not required.
+                Default: ``None``.
+
+        Returns:
+            A list of :class:`AttachJuxtaposeTreeSentence` instances.
+        """
+
+        if lang is not None:
+            tokenizer = Tokenizer(lang)
+        if isinstance(data, str) and os.path.exists(data):
+            if data.endswith('.txt'):
+                data = (s.split() if lang is None else tokenizer(s) for s in open(data) if len(s) > 1)
+            else:
+                data = open(data)
+        else:
+            if lang is not None:
+                data = [tokenizer(i) for i in ([data] if isinstance(data, str) else data)]
+            else:
+                data = [data] if isinstance(data[0], str) else data
+
+        index = 0
+        for s in data:
+
+            try:
+                tree = nltk.Tree.fromstring(s) if isinstance(s, str) else self.totree(s, self.root)
+                sentence = AttachJuxtaposeTreeSentence(self, tree, index)
+            except ValueError:
+                logger.warning(f"Error found while converting Sentence {index} to a tree:\n{s}\nDiscarding it!")
+                continue
+            except IndexError:
+                tree = nltk.Tree.fromstring('(S ' + s + ')')
+                sentence = AttachJuxtaposeTreeSentence(self, tree, index)
+            else:
+                yield sentence
+                index += 1
+        self.root = tree.label()
+
+
+class AttachJuxtaposeTreeSentence(Sentence):
+    r"""
+    Args:
+        transform (AttachJuxtaposeTree):
+            A :class:`AttachJuxtaposeTree` object.
+        tree (nltk.tree.Tree):
+            A :class:`nltk.tree.Tree` object.
+        index (Optional[int]):
+            Index of the sentence in the corpus. Default: ``None``.
+    """
+
+    def __init__(
+        self,
+        transform: AttachJuxtaposeTree,
+        tree: nltk.Tree,
+        index: Optional[int] = None
+    ) -> AttachJuxtaposeTreeSentence:
+        super().__init__(transform, index)
+
+        words, tags = zip(*tree.pos())
+        nodes, parents, news = None, None, None
+        if transform.training:
+            oracle_tree = tree.copy(True)
+            # the root node must have a unary chain
+            if len(oracle_tree) > 1:
+                oracle_tree[:] = [nltk.Tree('*', oracle_tree)]
+            oracle_tree.collapse_unary(joinChar='::')
+            if len(oracle_tree) == 1 and not isinstance(oracle_tree[0][0], nltk.Tree):
+                oracle_tree[0] = nltk.Tree('*', [oracle_tree[0]])
+            nodes, parents, news = zip(*transform.tree2action(oracle_tree))
+        tags = [x.split("##")[0] for x in tags]
+        self.values = [words, tags, tree, nodes, parents, news]
+
+    def __repr__(self):
+        return self.values[-4].pformat(1000000)
+
+    def pretty_print(self):
+        self.values[-4].pretty_print()
diff --git a/tania_scripts/supar/models/const/crf/__init__.py b/tania_scripts/supar/models/const/crf/__init__.py
new file mode 100644
index 0000000..b3a1e58
--- /dev/null
+++ b/tania_scripts/supar/models/const/crf/__init__.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+
+from .model import CRFConstituencyModel
+from .parser import CRFConstituencyParser
+
+__all__ = ['CRFConstituencyModel', 'CRFConstituencyParser']
diff --git a/tania_scripts/supar/models/const/crf/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/const/crf/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1b23ae21ab8db14bfbcb97e155b4203d8c61d82a
GIT binary patch
literal 287
zcmd1j<>g{vU|`_PGe}>-z`*br#6iYP3=9ko3=9m#Dhvz^DGVu$ISjdsQH+crHd78$
zE^`z!BSQ*v3QIau6iW(gFoP!BOGX9;22I9WBF;f>&iQ%8C7C6qsd>qjzWFJsIhu^O
zMA5_p5{rsci;6%t6)`g~F!*V*-eS!KDF%z(Vk>|s0Lk5AkB?8x$%&6&$xy`3zyKkB
z+3RQI=cekHB$i|*<|XPS<s_zLrWWaE<|P*-7U>t4f=IA|#rnx02k9plrRm4VXXa&=
h#K-FuRNmsS$<0qG%}KQbIlY*Tfq{XCiHDJg2>_fANj?Ao

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/crf/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/const/crf/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9ebb3eb81e33d0ac6cbfe3c6b1f467617348d959
GIT binary patch
literal 365
zcmZ3^%ge>Uz`&q%Uo~R|0|Ucj5C?{tpp4II3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI
zW=4h-<`kB6rYM#a)?fxrwwH_y3=Eo#w?v$S+?@0Cic2y}N>lTaD}D1*QgbvJZ;7Ib
z2P761rxq14GcYg|u`n<&_-V4<V$B6928-QdD}X2f$=za)k5A0WiH~2&@EPQ`Ut#(g
z`MIh3C5a`OiFt{7NjZrrnW;tk$@#ej`MM>k6(zc<Wr;cZC5d^NiSfnBMVSR9#rnmi
z1&KxaU@MCClR-|@PcBN+kB`sH%PfhH*DI*}#bJ}1pHiBWYFEU~z`y|VQLz;R1H%Vq
pMn=XDYz&MV7Z}u$(G3R83#jM;x8en5s|#G#4eTIT#L2+G007|NX2Jjf

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/crf/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/const/crf/__pycache__/model.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d01854d3d9e7b162c4bbd2903109ba1d1b0384a1
GIT binary patch
literal 9776
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/crf/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/const/crf/__pycache__/model.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5ba33210adee6c2b20457972f93ac9ce0b2e68e0
GIT binary patch
literal 12210
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
IY!ujM02sh72><{9

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/crf/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/const/crf/__pycache__/parser.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b7e69785c24d5aba0b6e9363ddd28806b9f04cfa
GIT binary patch
literal 8295
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/crf/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/const/crf/__pycache__/parser.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7282c0aa3c3e6e0aa427723393109f9b057bba50
GIT binary patch
literal 15580
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/crf/__pycache__/transform.cpython-310.pyc b/tania_scripts/supar/models/const/crf/__pycache__/transform.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fec7bc1c3fc13a4209bb5c3f1be993b016f7cd7a
GIT binary patch
literal 19620
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
WhlvNYOoWMtk%LKqnV}v8MQj0r*q0Xo

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/crf/__pycache__/transform.cpython-311.pyc b/tania_scripts/supar/models/const/crf/__pycache__/transform.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..284c610e9e875040233cc1a2d0138345a2c0e4ae
GIT binary patch
literal 26740
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/crf/model.py b/tania_scripts/supar/models/const/crf/model.py
new file mode 100644
index 0000000..03199e8
--- /dev/null
+++ b/tania_scripts/supar/models/const/crf/model.py
@@ -0,0 +1,221 @@
+# -*- coding: utf-8 -*-
+
+import torch
+import torch.nn as nn
+from supar.model import Model
+from supar.modules import MLP, Biaffine
+from supar.structs import ConstituencyCRF
+from supar.utils import Config
+
+
+class CRFConstituencyModel(Model):
+    r"""
+    The implementation of CRF Constituency Parser :cite:`zhang-etal-2020-fast`,
+    also called FANCY (abbr. of Fast and Accurate Neural Crf constituencY) Parser.
+
+    Args:
+        n_words (int):
+            The size of the word vocabulary.
+        n_labels (int):
+            The number of labels in the treebank.
+        n_tags (int):
+            The number of POS tags, required if POS tag embeddings are used. Default: ``None``.
+        n_chars (int):
+            The number of characters, required if character-level representations are used. Default: ``None``.
+        encoder (str):
+            Encoder to use.
+            ``'lstm'``: BiLSTM encoder.
+            ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``.
+            Default: ``'lstm'``.
+        feat (List[str]):
+            Additional features to use, required if ``encoder='lstm'``.
+            ``'tag'``: POS tag embeddings.
+            ``'char'``: Character-level representations extracted by CharLSTM.
+            ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible.
+            Default: [``'char'``].
+        n_embed (int):
+            The size of word embeddings. Default: 100.
+        n_pretrained (int):
+            The size of pretrained word embeddings. Default: 100.
+        n_feat_embed (int):
+            The size of feature representations. Default: 100.
+        n_char_embed (int):
+            The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50.
+        n_char_hidden (int):
+            The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100.
+        char_pad_index (int):
+            The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0.
+        elmo (str):
+            Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``.
+        elmo_bos_eos (Tuple[bool]):
+            A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs.
+            Default: ``(True, False)``.
+        bert (str):
+            Specifies which kind of language model to use, e.g., ``'bert-base-cased'``.
+            This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_.
+            Default: ``None``.
+        n_bert_layers (int):
+            Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features.
+            The final outputs would be weighted sum of the hidden states of these layers.
+            Default: 4.
+        mix_dropout (float):
+            The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0.
+        bert_pooling (str):
+            Pooling way to get token embeddings.
+            ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all.
+            Default: ``mean``.
+        bert_pad_index (int):
+            The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features.
+            Default: 0.
+        finetune (bool):
+            If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``.
+        n_plm_embed (int):
+            The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0.
+        embed_dropout (float):
+            The dropout ratio of input embeddings. Default: .33.
+        n_encoder_hidden (int):
+            The size of encoder hidden states. Default: 800.
+        n_encoder_layers (int):
+            The number of encoder layers. Default: 3.
+        encoder_dropout (float):
+            The dropout ratio of encoder layer. Default: .33.
+        n_span_mlp (int):
+            Span MLP size. Default: 500.
+        n_label_mlp  (int):
+            Label MLP size. Default: 100.
+        mlp_dropout (float):
+            The dropout ratio of MLP layers. Default: .33.
+        pad_index (int):
+            The index of the padding token in the word vocabulary. Default: 0.
+        unk_index (int):
+            The index of the unknown token in the word vocabulary. Default: 1.
+
+    .. _transformers:
+        https://github.com/huggingface/transformers
+    """
+
+    def __init__(self,
+                 n_words,
+                 n_labels,
+                 n_tags=None,
+                 n_chars=None,
+                 encoder='lstm',
+                 feat=['char'],
+                 n_embed=100,
+                 n_pretrained=100,
+                 n_feat_embed=100,
+                 n_char_embed=50,
+                 n_char_hidden=100,
+                 char_pad_index=0,
+                 elmo='original_5b',
+                 elmo_bos_eos=(True, True),
+                 bert=None,
+                 n_bert_layers=4,
+                 mix_dropout=.0,
+                 bert_pooling='mean',
+                 bert_pad_index=0,
+                 finetune=False,
+                 n_plm_embed=0,
+                 embed_dropout=.33,
+                 n_encoder_hidden=800,
+                 n_encoder_layers=3,
+                 encoder_dropout=.33,
+                 n_span_mlp=500,
+                 n_label_mlp=100,
+                 mlp_dropout=.33,
+                 pad_index=0,
+                 unk_index=1,
+                 **kwargs):
+        super().__init__(**Config().update(locals()))
+
+        self.span_mlp_l = MLP(n_in=self.args.n_encoder_hidden, n_out=n_span_mlp, dropout=mlp_dropout)
+        self.span_mlp_r = MLP(n_in=self.args.n_encoder_hidden, n_out=n_span_mlp, dropout=mlp_dropout)
+        self.label_mlp_l = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=mlp_dropout)
+        self.label_mlp_r = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=mlp_dropout)
+
+        self.span_attn = Biaffine(n_in=n_span_mlp, bias_x=True, bias_y=False)
+        self.label_attn = Biaffine(n_in=n_label_mlp, n_out=n_labels, bias_x=True, bias_y=True)
+        self.criterion = nn.CrossEntropyLoss()
+
+    def forward(self, words, feats=None):
+        r"""
+        Args:
+            words (~torch.LongTensor): ``[batch_size, seq_len]``.
+                Word indices.
+            feats (List[~torch.LongTensor]):
+                A list of feat indices.
+                The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``,
+                or ``[batch_size, seq_len]`` otherwise.
+                Default: ``None``.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor:
+                The first tensor of shape ``[batch_size, seq_len, seq_len]`` holds scores of all possible constituents.
+                The second of shape ``[batch_size, seq_len, seq_len, n_labels]`` holds
+                scores of all possible labels on each constituent.
+        """
+
+        x = self.encode(words, feats)
+
+        x_f, x_b = x.chunk(2, -1)
+        x = torch.cat((x_f[:, :-1], x_b[:, 1:]), -1)
+
+        span_l = self.span_mlp_l(x)
+        span_r = self.span_mlp_r(x)
+        label_l = self.label_mlp_l(x)
+        label_r = self.label_mlp_r(x)
+
+        # [batch_size, seq_len, seq_len]
+        s_span = self.span_attn(span_l, span_r)
+        # [batch_size, seq_len, seq_len, n_labels]
+        s_label = self.label_attn(label_l, label_r).permute(0, 2, 3, 1)
+
+        return s_span, s_label
+
+    def loss(self, s_span, s_label, charts, mask, mbr=True):
+        r"""
+        Args:
+            s_span (~torch.Tensor): ``[batch_size, seq_len, seq_len]``.
+                Scores of all constituents.
+            s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``.
+                Scores of all constituent labels.
+            charts (~torch.LongTensor): ``[batch_size, seq_len, seq_len]``.
+                The tensor of gold-standard labels. Positions without labels are filled with -1.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``.
+                The mask for covering the unpadded tokens in each chart.
+            mbr (bool):
+                If ``True``, returns marginals for MBR decoding. Default: ``True``.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor:
+                The training loss and original constituent scores
+                of shape ``[batch_size, seq_len, seq_len]`` if ``mbr=False``, or marginals otherwise.
+        """
+
+        span_mask = charts.ge(0) & mask
+        span_dist = ConstituencyCRF(s_span, mask[:, 0].sum(-1))
+        span_loss = -span_dist.log_prob(charts).sum() / mask[:, 0].sum()
+        span_probs = span_dist.marginals if mbr else s_span
+        label_loss = self.criterion(s_label[span_mask], charts[span_mask])
+        loss = span_loss + label_loss
+
+        return loss, span_probs
+
+    def decode(self, s_span, s_label, mask):
+        r"""
+        Args:
+            s_span (~torch.Tensor): ``[batch_size, seq_len, seq_len]``.
+                Scores of all constituents.
+            s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``.
+                Scores of all constituent labels.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``.
+                The mask for covering the unpadded tokens in each chart.
+
+        Returns:
+            List[List[Tuple]]:
+                Sequences of factorized labeled trees.
+        """
+
+        span_preds = ConstituencyCRF(s_span, mask[:, 0].sum(-1)).argmax
+        label_preds = s_label.argmax(-1).tolist()
+        return [[(i, j, labels[i][j]) for i, j in spans] for spans, labels in zip(span_preds, label_preds)]
diff --git a/tania_scripts/supar/models/const/crf/parser.py b/tania_scripts/supar/models/const/crf/parser.py
new file mode 100644
index 0000000..ad5bd16
--- /dev/null
+++ b/tania_scripts/supar/models/const/crf/parser.py
@@ -0,0 +1,205 @@
+# -*- coding: utf-8 -*-
+
+import os
+from typing import Dict, Iterable, Set, Union
+
+import torch
+
+from supar.models.const.crf.model import CRFConstituencyModel
+from supar.models.const.crf.transform import Tree
+from supar.parser import Parser
+from supar.structs import ConstituencyCRF
+from supar.utils import Config, Dataset, Embedding
+from supar.utils.common import BOS, EOS, PAD, UNK
+from supar.utils.field import ChartField, Field, RawField, SubwordField
+from supar.utils.logging import get_logger
+from supar.utils.metric import SpanMetric
+from supar.utils.tokenizer import TransformerTokenizer
+from supar.utils.transform import Batch
+
+logger = get_logger(__name__)
+
+
+class CRFConstituencyParser(Parser):
+    r"""
+    The implementation of CRF Constituency Parser :cite:`zhang-etal-2020-fast`.
+    """
+
+    NAME = 'crf-constituency'
+    MODEL = CRFConstituencyModel
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self.TREE = self.transform.TREE
+        self.CHART = self.transform.CHART
+
+    def train(
+        self,
+        train: Union[str, Iterable],
+        dev: Union[str, Iterable],
+        test: Union[str, Iterable],
+        epochs: int = 1000,
+        patience: int = 100,
+        batch_size: int = 5000,
+        update_steps: int = 1,
+        buckets: int = 32,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        mbr: bool = True,
+        delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''},
+        equal: Dict = {'ADVP': 'PRT'},
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().train(**Config().update(locals()))
+
+    def evaluate(
+        self,
+        data: Union[str, Iterable],
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        mbr: bool = True,
+        delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''},
+        equal: Dict = {'ADVP': 'PRT'},
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().evaluate(**Config().update(locals()))
+
+    def predict(
+        self,
+        data: Union[str, Iterable],
+        pred: str = None,
+        lang: str = None,
+        prob: bool = False,
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        mbr: bool = True,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().predict(**Config().update(locals()))
+
+    def train_step(self, batch: Batch) -> torch.Tensor:
+        words, *feats, _, charts = batch
+        mask = batch.mask[:, 1:]
+        mask = (mask.unsqueeze(1) & mask.unsqueeze(2)).triu_(1)
+        s_span, s_label = self.model(words, feats)
+        loss, _ = self.model.loss(s_span, s_label, charts, mask, self.args.mbr)
+        return loss
+
+    @torch.no_grad()
+    def eval_step(self, batch: Batch) -> SpanMetric:
+        words, *feats, trees, charts = batch
+        mask = batch.mask[:, 1:]
+        mask = (mask.unsqueeze(1) & mask.unsqueeze(2)).triu_(1)
+        s_span, s_label = self.model(words, feats)
+        loss, s_span = self.model.loss(s_span, s_label, charts, mask, self.args.mbr)
+        chart_preds = self.model.decode(s_span, s_label, mask)
+        preds = [Tree.build(tree, [(i, j, self.CHART.vocab[label]) for i, j, label in chart])
+                 for tree, chart in zip(trees, chart_preds)]
+        return SpanMetric(loss,
+                          [Tree.factorize(tree, self.args.delete, self.args.equal) for tree in preds],
+                          [Tree.factorize(tree, self.args.delete, self.args.equal) for tree in trees])
+
+    @torch.no_grad()
+    def pred_step(self, batch: Batch) -> Batch:
+        words, *feats, trees = batch
+        mask, lens = batch.mask[:, 1:], batch.lens - 2
+        mask = (mask.unsqueeze(1) & mask.unsqueeze(2)).triu_(1)
+        s_span, s_label = self.model(words, feats)
+        s_span = ConstituencyCRF(s_span, mask[:, 0].sum(-1)).marginals if self.args.mbr else s_span
+        chart_preds = self.model.decode(s_span, s_label, mask)
+        batch.trees = [Tree.build(tree, [(i, j, self.CHART.vocab[label]) for i, j, label in chart])
+                       for tree, chart in zip(trees, chart_preds)]
+        if self.args.prob:
+            batch.probs = [prob[:i-1, 1:i].cpu() for i, prob in zip(lens, s_span)]
+        return batch
+
+    @classmethod
+    def build(cls, path, min_freq=2, fix_len=20, **kwargs):
+        r"""
+        Build a brand-new Parser, including initialization of all data fields and model parameters.
+
+        Args:
+            path (str):
+                The path of the model to be saved.
+            min_freq (str):
+                The minimum frequency needed to include a token in the vocabulary. Default: 2.
+            fix_len (int):
+                The max length of all subword pieces. The excess part of each piece will be truncated.
+                Required if using CharLSTM/BERT.
+                Default: 20.
+            kwargs (Dict):
+                A dict holding the unconsumed arguments.
+        """
+
+        args = Config(**locals())
+        os.makedirs(os.path.dirname(path) or './', exist_ok=True)
+        if os.path.exists(path) and not args.build:
+            parser = cls.load(**args)
+            parser.model = cls.MODEL(**parser.args)
+            parser.model.load_pretrained(parser.transform.WORD[0].embed).to(parser.device)
+            return parser
+
+        logger.info("Building the fields")
+        TAG, CHAR, ELMO, BERT = None, None, None, None
+        if args.encoder == 'bert':
+            t = TransformerTokenizer(args.bert)
+            WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, eos=t.eos, fix_len=args.fix_len, tokenize=t)
+            WORD.vocab = t.vocab
+        else:
+            WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True)
+            if 'tag' in args.feat:
+                TAG = Field('tags', bos=BOS, eos=EOS)
+            if 'char' in args.feat:
+                CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, eos=EOS, fix_len=args.fix_len)
+            if 'elmo' in args.feat:
+                from allennlp.modules.elmo import batch_to_ids
+                ELMO = RawField('elmo')
+                ELMO.compose = lambda x: batch_to_ids(x).to(WORD.device)
+            if 'bert' in args.feat:
+                t = TransformerTokenizer(args.bert)
+                BERT = SubwordField('bert', pad=t.pad, unk=t.unk, bos=t.bos, eos=t.eos, fix_len=args.fix_len, tokenize=t)
+                BERT.vocab = t.vocab
+        TREE = RawField('trees')
+        CHART = ChartField('charts')
+        transform = Tree(WORD=(WORD, CHAR, ELMO, BERT), POS=TAG, TREE=TREE, CHART=CHART)
+
+        train = Dataset(transform, args.train, **args)
+        if args.encoder != 'bert':
+            WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x))
+            if TAG is not None:
+                TAG.build(train)
+            if CHAR is not None:
+                CHAR.build(train)
+        CHART.build(train)
+        args.update({
+            'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init,
+            'n_labels': len(CHART.vocab),
+            'n_tags': len(TAG.vocab) if TAG is not None else None,
+            'n_chars': len(CHAR.vocab) if CHAR is not None else None,
+            'char_pad_index': CHAR.pad_index if CHAR is not None else None,
+            'bert_pad_index': BERT.pad_index if BERT is not None else None,
+            'pad_index': WORD.pad_index,
+            'unk_index': WORD.unk_index,
+            'bos_index': WORD.bos_index,
+            'eos_index': WORD.eos_index
+        })
+        logger.info(f"{transform}")
+
+        logger.info("Building the model")
+        model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None)
+        logger.info(f"{model}\n")
+
+        parser = cls(args, model, transform)
+        parser.model.to(parser.device)
+        return parser
diff --git a/tania_scripts/supar/models/const/crf/transform.py b/tania_scripts/supar/models/const/crf/transform.py
new file mode 100644
index 0000000..b3ba03c
--- /dev/null
+++ b/tania_scripts/supar/models/const/crf/transform.py
@@ -0,0 +1,494 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+import os
+from typing import (TYPE_CHECKING, Dict, Iterable, List, Optional, Set, Tuple,
+                    Union)
+
+import nltk
+
+from supar.utils.logging import get_logger
+from supar.utils.tokenizer import Tokenizer
+from supar.utils.transform import Sentence, Transform
+
+if TYPE_CHECKING:
+    from supar.utils import Field
+
+logger = get_logger(__name__)
+
+
+class Tree(Transform):
+    r"""
+    A :class:`Tree` object factorize a constituency tree into four fields,
+    each associated with one or more :class:`~supar.utils.field.Field` objects.
+
+    Attributes:
+        WORD:
+            Words in the sentence.
+        POS:
+            Part-of-speech tags, or underscores if not available.
+        TREE:
+            The raw constituency tree in :class:`nltk.tree.Tree` format.
+        CHART:
+            The factorized sequence of binarized tree traversed in post-order.
+    """
+
+    root = ''
+    fields = ['WORD', 'POS', 'TREE', 'CHART']
+
+    def __init__(
+        self,
+        WORD: Optional[Union[Field, Iterable[Field]]] = None,
+        POS: Optional[Union[Field, Iterable[Field]]] = None,
+        TREE: Optional[Union[Field, Iterable[Field]]] = None,
+        CHART: Optional[Union[Field, Iterable[Field]]] = None
+    ) -> Tree:
+        super().__init__()
+
+        self.WORD = WORD
+        self.POS = POS
+        self.TREE = TREE
+        self.CHART = CHART
+
+    @property
+    def src(self):
+        return self.WORD, self.POS, self.TREE
+
+    @property
+    def tgt(self):
+        return self.CHART,
+
+    @classmethod
+    def totree(
+        cls,
+        tokens: List[Union[str, Tuple]],
+        root: str = '',
+        normalize: Dict[str, str] = {'(': '-LRB-', ')': '-RRB-'}
+    ) -> nltk.Tree:
+        r"""
+        Converts a list of tokens to a :class:`nltk.tree.Tree`, with missing fields filled in with underscores.
+
+        Args:
+            tokens (List[Union[str, Tuple]]):
+                This can be either a list of words or word/pos pairs.
+            root (str):
+                The root label of the tree. Default: ''.
+            normalize (Dict):
+                Keys within the dict in each token will be replaced by the values. Default: ``{'(': '-LRB-', ')': '-RRB-'}``.
+
+        Returns:
+            A :class:`nltk.tree.Tree` object.
+
+        Examples:
+            >>> from supar.models.const.crf.transform import Tree
+            >>> Tree.totree(['She', 'enjoys', 'playing', 'tennis', '.'], 'TOP').pprint()
+            (TOP ( (_ She)) ( (_ enjoys)) ( (_ playing)) ( (_ tennis)) ( (_ .)))
+            >>> Tree.totree(['(', 'If', 'You', 'Let', 'It', ')'], 'TOP').pprint()
+            (TOP
+              ( (_ -LRB-))
+              ( (_ If))
+              ( (_ You))
+              ( (_ Let))
+              ( (_ It))
+              ( (_ -RRB-)))
+        """
+
+        normalize = str.maketrans(normalize)
+        if isinstance(tokens[0], str):
+            tokens = [(token, '_') for token in tokens]
+        return nltk.Tree(root, [nltk.Tree('', [nltk.Tree(pos, [word.translate(normalize)])]) for word, pos in tokens])
+
+    @classmethod
+    def binarize(
+        cls,
+        tree: nltk.Tree,
+        left: bool = True,
+        mark: str = '*',
+        join: str = '::',
+        implicit: bool = False
+    ) -> nltk.Tree:
+        r"""
+        Conducts binarization over the tree.
+
+        First, the tree is transformed to satisfy `Chomsky Normal Form (CNF)`_.
+        Here we call :meth:`~nltk.tree.Tree.chomsky_normal_form` to conduct left-binarization.
+        Second, all unary productions in the tree are collapsed.
+
+        Args:
+            tree (nltk.tree.Tree):
+                The tree to be binarized.
+            left (bool):
+                If ``True``, left-binarization is conducted. Default: ``True``.
+            mark (str):
+                A string used to mark newly inserted nodes, working if performing explicit binarization. Default: ``'*'``.
+            join (str):
+                A string used to connect collapsed node labels. Default: ``'::'``.
+            implicit (bool):
+                If ``True``, performs implicit binarization. Default: ``False``.
+
+        Returns:
+            The binarized tree.
+
+        Examples:
+            >>> from supar.models.const.crf.transform import Tree
+            >>> tree = nltk.Tree.fromstring('''
+                                            (TOP
+                                              (S
+                                                (NP (_ She))
+                                                (VP (_ enjoys) (S (VP (_ playing) (NP (_ tennis)))))
+                                                (_ .)))
+                                            ''')
+            >>> tree.pretty_print()
+                         TOP
+                          |
+                          S
+              ____________|________________
+             |            VP               |
+             |     _______|_____           |
+             |    |             S          |
+             |    |             |          |
+             |    |             VP         |
+             |    |        _____|____      |
+             NP   |       |          NP    |
+             |    |       |          |     |
+             _    _       _          _     _
+             |    |       |          |     |
+            She enjoys playing     tennis  .
+
+            >>> Tree.binarize(tree).pretty_print()
+                             TOP
+                              |
+                              S
+                         _____|__________________
+                        S*                       |
+              __________|_____                   |
+             |                VP                 |
+             |     ___________|______            |
+             |    |                S::VP         |
+             |    |            ______|_____      |
+             NP  VP*         VP*           NP    S*
+             |    |           |            |     |
+             _    _           _            _     _
+             |    |           |            |     |
+            She enjoys     playing       tennis  .
+
+            >>> Tree.binarize(tree, implicit=True).pretty_print()
+                             TOP
+                              |
+                              S
+                         _____|__________________
+                                                 |
+              __________|_____                   |
+             |                VP                 |
+             |     ___________|______            |
+             |    |                S::VP         |
+             |    |            ______|_____      |
+             NP                            NP
+             |    |           |            |     |
+             _    _           _            _     _
+             |    |           |            |     |
+            She enjoys     playing       tennis  .
+
+            >>> Tree.binarize(tree, left=False).pretty_print()
+                         TOP
+                          |
+                          S
+              ____________|______
+             |                   S*
+             |             ______|___________
+             |            VP                 |
+             |     _______|______            |
+             |    |            S::VP         |
+             |    |        ______|_____      |
+             NP  VP*     VP*           NP    S*
+             |    |       |            |     |
+             _    _       _            _     _
+             |    |       |            |     |
+            She enjoys playing       tennis  .
+
+        .. _Chomsky Normal Form (CNF):
+            https://en.wikipedia.org/wiki/Chomsky_normal_form
+        """
+
+        tree = tree.copy(True)
+        nodes = [tree]
+        if len(tree) == 1:
+            if not isinstance(tree[0][0], nltk.Tree):
+                tree[0] = nltk.Tree(f'{tree.label()}{mark}', [tree[0]])
+            nodes = [tree[0]]
+        while nodes:
+            node = nodes.pop()
+            if isinstance(node, nltk.Tree):
+                if implicit:
+                    label = ''
+                else:
+                    label = node.label()
+                    if mark not in label:
+                        label = f'{label}{mark}'
+                # ensure that only non-terminals can be attached to a n-ary subtree
+                if len(node) > 1:
+                    for child in node:
+                        if not isinstance(child[0], nltk.Tree):
+                            child[:] = [nltk.Tree(child.label(), child[:])]
+                            child.set_label(label)
+                # chomsky normal form factorization
+                if len(node) > 2:
+                    if left:
+                        node[:-1] = [nltk.Tree(label, node[:-1])]
+                    else:
+                        node[1:] = [nltk.Tree(label, node[1:])]
+                nodes.extend(node)
+        # collapse unary productions, shoule be conducted after binarization
+        tree.collapse_unary(joinChar=join)
+        return tree
+
+    @classmethod
+    def factorize(
+        cls,
+        tree: nltk.Tree,
+        delete_labels: Optional[Set[str]] = None,
+        equal_labels: Optional[Dict[str, str]] = None
+    ) -> Iterable[Tuple]:
+        r"""
+        Factorizes the tree into a sequence traversed in post-order.
+
+        Args:
+            tree (nltk.tree.Tree):
+                The tree to be factorized.
+            delete_labels (Optional[Set[str]]):
+                A set of labels to be ignored. This is used for evaluation.
+                If it is a pre-terminal label, delete the word along with the brackets.
+                If it is a non-terminal label, just delete the brackets (don't delete children).
+                In `EVALB`_, the default set is:
+                {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''}
+                Default: ``None``.
+            equal_labels (Optional[Dict[str, str]]):
+                The key-val pairs in the dict are considered equivalent (non-directional). This is used for evaluation.
+                The default dict defined in `EVALB`_ is: {'ADVP': 'PRT'}
+                Default: ``None``.
+
+        Returns:
+            The sequence of the factorized tree.
+
+        Examples:
+            >>> from supar.models.const.crf.transform import Tree
+            >>> tree = nltk.Tree.fromstring('''
+                                            (TOP
+                                              (S
+                                                (NP (_ She))
+                                                (VP (_ enjoys) (S (VP (_ playing) (NP (_ tennis)))))
+                                                (_ .)))
+                                            ''')
+            >>> Tree.factorize(tree)
+            [(0, 1, 'NP'), (3, 4, 'NP'), (2, 4, 'VP'), (2, 4, 'S'), (1, 4, 'VP'), (0, 5, 'S'), (0, 5, 'TOP')]
+            >>> Tree.factorize(tree, delete_labels={'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''})
+            [(0, 1, 'NP'), (3, 4, 'NP'), (2, 4, 'VP'), (2, 4, 'S'), (1, 4, 'VP'), (0, 5, 'S')]
+
+        .. _EVALB:
+            https://nlp.cs.nyu.edu/evalb/
+        """
+
+        def track(tree, i):
+            label = tree if isinstance(tree, str) else tree.label()
+            if delete_labels is not None and label in delete_labels:
+                label = None
+            if equal_labels is not None:
+                label = equal_labels.get(label, label)
+            if len(tree) == 1 and not isinstance(tree[0], nltk.Tree):
+                return (i + 1 if label is not None else i), []
+            j, spans = i, []
+            for child in tree:
+                j, s = track(child, j)
+                spans += s
+            if label is not None and j > i:
+                spans = spans + [(i, j, label)]
+            return j, spans
+        return track(tree, 0)[1]
+
+    @classmethod
+    def build(
+        cls,
+        sentence: Union[nltk.Tree, Iterable],
+        spans: Iterable[Tuple],
+        delete_labels: Optional[Set[str]] = None,
+        mark: Union[str, Tuple[str]] = ('*', '|<>'),
+        root: str = '',
+        join: str = '::',
+        postorder: bool = True
+    ) -> nltk.Tree:
+        r"""
+        Builds a constituency tree from a span sequence.
+        During building, the sequence is recovered, i.e., de-binarized to the original format.
+
+        Args:
+            sentence (Union[nltk.tree.Tree, Iterable]):
+                Sentence to provide a base for building a result tree, both `nltk.tree.Tree` and tokens are allowed.
+            spans (Iterable[Tuple]):
+                A list of spans, each consisting of the indices of left/right boundaries and label of the constituent.
+            delete_labels (Optional[Set[str]]):
+                A set of labels to be ignored. Default: ``None``.
+            mark (Union[str, List[str]]):
+                A string used to mark newly inserted nodes. Non-terminals containing this will be removed.
+                Default: ``('*', '|<>')``.
+            root (str):
+                The root label of the tree, needed if input a list of tokens. Default: ''.
+            join (str):
+                A string used to connect collapsed node labels. Non-terminals containing this will be expanded to unary chains.
+                Default: ``'::'``.
+            postorder (bool):
+                If ``True``, enforces the sequence is sorted in post-order. Default: ``True``.
+
+        Returns:
+            A result constituency tree.
+
+        Examples:
+            >>> from supar.models.const.crf.transform import Tree
+            >>> Tree.build(['She', 'enjoys', 'playing', 'tennis', '.'],
+                           [(0, 5, 'S'), (0, 4, 'S*'), (0, 1, 'NP'), (1, 4, 'VP'), (1, 2, 'VP*'),
+                            (2, 4, 'S::VP'), (2, 3, 'VP*'), (3, 4, 'NP'), (4, 5, 'S*')],
+                           root='TOP').pretty_print()
+                         TOP
+                          |
+                          S
+              ____________|________________
+             |            VP               |
+             |     _______|_____           |
+             |    |             S          |
+             |    |             |          |
+             |    |             VP         |
+             |    |        _____|____      |
+             NP   |       |          NP    |
+             |    |       |          |     |
+             _    _       _          _     _
+             |    |       |          |     |
+            She enjoys playing     tennis  .
+
+            >>> Tree.build(['She', 'enjoys', 'playing', 'tennis', '.'],
+                           [(0, 1, 'NP'), (3, 4, 'NP'), (2, 4, 'VP'), (2, 4, 'S'), (1, 4, 'VP'), (0, 5, 'S')],
+                           root='TOP').pretty_print()
+                         TOP
+                          |
+                          S
+              ____________|________________
+             |            VP               |
+             |     _______|_____           |
+             |    |             S          |
+             |    |             |          |
+             |    |             VP         |
+             |    |        _____|____      |
+             NP   |       |          NP    |
+             |    |       |          |     |
+             _    _       _          _     _
+             |    |       |          |     |
+            She enjoys playing     tennis  .
+
+        """
+
+        tree = sentence if isinstance(sentence, nltk.Tree) else Tree.totree(sentence, root)
+        leaves = [subtree for subtree in tree.subtrees() if not isinstance(subtree[0], nltk.Tree)]
+        if postorder:
+            spans = sorted(spans, key=lambda x: (x[1], x[1] - x[0]))
+
+        root = tree.label()
+        start, stack = 0, []
+        for span in spans:
+            i, j, label = span
+            if delete_labels is not None and label in delete_labels:
+                continue
+            stack.extend([(n, n + 1, leaf) for n, leaf in enumerate(leaves[start:i], start)])
+            children = []
+            while len(stack) > 0 and i <= stack[-1][0]:
+                children = [stack.pop()] + children
+            start = children[-1][1] if len(children) > 0 else i
+            children.extend([(n, n + 1, leaf) for n, leaf in enumerate(leaves[start:j], start)])
+            start = j
+            if not label or label.endswith(mark):
+                stack.extend(children)
+                continue
+            labels = label.split(join)
+            tree = nltk.Tree(labels[-1], [child[-1] for child in children])
+            for label in reversed(labels[:-1]):
+                tree = nltk.Tree(label, [tree])
+            stack.append((i, j, tree))
+        stack.extend([(n, n + 1, leaf) for n, leaf in enumerate(leaves[start:], start)])
+        return nltk.Tree(root, [i[-1] for i in stack])
+
+    def load(
+        self,
+        data: Union[str, Iterable],
+        lang: Optional[str] = None,
+        **kwargs
+    ) -> List[TreeSentence]:
+        r"""
+        Args:
+            data (Union[str, Iterable]):
+                A filename or a list of instances.
+            lang (str):
+                Language code (e.g., ``en``) or language name (e.g., ``English``) for the text to tokenize.
+                ``None`` if tokenization is not required.
+                Default: ``None``.
+
+        Returns:
+            A list of :class:`TreeSentence` instances.
+        """
+
+        if lang is not None:
+            tokenizer = Tokenizer(lang)
+        if isinstance(data, str) and os.path.exists(data):
+            if data.endswith('.txt'):
+                data = (s.split() if lang is None else tokenizer(s) for s in open(data) if len(s) > 1)
+            else:
+                data = open(data)
+        else:
+            if lang is not None:
+                data = [tokenizer(i) for i in ([data] if isinstance(data, str) else data)]
+            else:
+                data = [data] if isinstance(data[0], str) else data
+
+        index = 0
+        for s in data:
+            try:
+                tree = nltk.Tree.fromstring(s) if isinstance(s, str) else self.totree(s, self.root)
+                sentence = TreeSentence(self, tree, index, **kwargs)
+            except ValueError:
+                logger.warning(f"Error found while converting Sentence {index} to a tree:\n{s}\nDiscarding it!")
+                continue
+            else:
+                yield sentence
+                index += 1
+        self.root = tree.label()
+
+
+class TreeSentence(Sentence):
+    r"""
+    Args:
+        transform (Tree):
+            A :class:`Tree` object.
+        tree (nltk.tree.Tree):
+            A :class:`nltk.tree.Tree` object.
+        index (Optional[int]):
+            Index of the sentence in the corpus. Default: ``None``.
+    """
+
+    def __init__(
+        self,
+        transform: Tree,
+        tree: nltk.Tree,
+        index: Optional[int] = None,
+        **kwargs
+    ) -> TreeSentence:
+        super().__init__(transform, index)
+
+        words, tags, chart = *zip(*tree.pos()), None
+        if transform.training:
+            chart = [[None] * (len(words) + 1) for _ in range(len(words) + 1)]
+            for i, j, label in Tree.factorize(Tree.binarize(tree, implicit=kwargs.get('implicit', False))[0]):
+                chart[i][j] = label
+        self.values = [words, tags, tree, chart]
+
+    def __repr__(self):
+        return self.values[-2].pformat(1000000)
+
+    def pretty_print(self):
+        self.values[-2].pretty_print()
diff --git a/tania_scripts/supar/models/const/sl/__init__.py b/tania_scripts/supar/models/const/sl/__init__.py
new file mode 100644
index 0000000..1b6b7bd
--- /dev/null
+++ b/tania_scripts/supar/models/const/sl/__init__.py
@@ -0,0 +1,4 @@
+from .model import SLConstituentModel
+from .parser import SLConstituentParser
+
+__all__ = ['SLConstituentModel', 'SLConstituentParser']
\ No newline at end of file
diff --git a/tania_scripts/supar/models/const/sl/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/const/sl/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..25ff091642789417721ecf105676e6aa0cec7ae7
GIT binary patch
literal 282
zcmd1j<>g{vU|`_PGe~b^U|@I*;vi!t1_lNP1_p*=6$S=|6owSW9EM!RC`LvQn<<AW
zmpO`=ks*aSg(aOSiY0|Lm_d{6B_jg^gC^rGp<o~9{Ji3l%#za7yb|C1l++we##_QD
zq5+9T#i>O_AX|!<85kJ+G+A%4=7N-h#cr_`Koo%FZn4M5C+6hD$FF24VrO805Wnp7
zGxBp&^-B^<G86L>^^$TDQ!-PF^fU943lfX;i%UTy*uY}_WRPq0i*xkj<1_OzOXB18
e3My}L*yQG?l;)(`fm~h8#=yY9!@$GH!vp~Rsz-4E

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/sl/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/const/sl/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5d46638efe8006ba326a4c8302ee488c3cbf8e14
GIT binary patch
literal 358
zcmZ3^%ge>Uz`&q%Up1qRfq~&Mhy%k+P{wC91_p-d3@HpLj5!Rsj8Tk?AU0DDQ!aB9
zGb2L^a|%m3Qxr=IYcPW*+e=0U1_n*WTSCD;&iQ%8C7C6qsd**7`6;P6nvA!EQA7h0
zi;7c=ikKM~7>ZaJ7#RFCS#PoCf|P>AZm|_W6oBMzvB$?J=H$f3uVnZPa@Vg={fzwF
zRQ-~~lFY=sM7^Y(#FWg`BK_q2+=6`FlGKV4-PE$g9Q~5Syv)S-;^d;tf|6qW;?jb|
zB7LwG#rnx0_vshs=*P!r=4F<|$LkeT{^GF7%}*)KNwq8DW?*0dd8XKcfq~%zGb1D8
i4F=T<sOScR`UO<<fLs28qS*y5^9FVhEaGHfU;qH~mSnL2

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/sl/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/const/sl/__pycache__/model.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f671041ff9274200b3afc20f09983fcd26145c5b
GIT binary patch
literal 3360
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
HDiLM?{Wf2!

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/sl/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/const/sl/__pycache__/model.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1dc15de997aec065667819a9092434d52331791f
GIT binary patch
literal 5671
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
Tu#+=HKZ0exfJsbM;4lOL%9U$q

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/sl/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/const/sl/__pycache__/parser.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5d61fb3dc0394c8bb1146467f5c1b762d37cca0b
GIT binary patch
literal 8808
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/sl/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/const/sl/__pycache__/parser.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fdce8977c12fc63d881480ee1b0a5cde8a562fd9
GIT binary patch
literal 18487
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/sl/__pycache__/transform.cpython-310.pyc b/tania_scripts/supar/models/const/sl/__pycache__/transform.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1874e521ca0c7d7e3004a1b69a4ae48e1f6bf140
GIT binary patch
literal 3612
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
ORJAb+=m@Zjumb>QxgZDt

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/sl/__pycache__/transform.cpython-311.pyc b/tania_scripts/supar/models/const/sl/__pycache__/transform.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..bbffb6675228c80bd72bea723d3dbbfbcbec55b4
GIT binary patch
literal 6748
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/sl/model.py b/tania_scripts/supar/models/const/sl/model.py
new file mode 100644
index 0000000..640c1f9
--- /dev/null
+++ b/tania_scripts/supar/models/const/sl/model.py
@@ -0,0 +1,102 @@
+# -*- coding: utf-8 -*-
+
+import torch
+import torch.nn as nn
+from supar.model import Model
+from supar.modules import MLP, DecoderLSTM
+from supar.utils import Config
+from typing import List
+
+
+class SLConstituentModel(Model):
+
+    def __init__(self,
+                 n_words,
+                 n_commons,
+                 n_ancestors,
+                 n_tags=None,
+                 n_chars=None,
+                 encoder='lstm',
+                 feat: List[str] =['char'],
+                 n_embed=100,
+                 n_pretrained=100,
+                 n_feat_embed=100,
+                 n_char_embed=50,
+                 n_char_hidden=100,
+                 char_pad_index=0,
+                 elmo='original_5b',
+                 elmo_bos_eos=(True, False),
+                 bert=None,
+                 n_bert_layers=4,
+                 mix_dropout=.0,
+                 bert_pooling='mean',
+                 bert_pad_index=0,
+                 finetune=False,
+                 n_plm_embed=0,
+                 embed_dropout=.33,
+                 n_encoder_hidden=800,
+                 n_encoder_layers=3,
+                 encoder_dropout=.33,
+                 n_arc_mlp=500,
+                 n_rel_mlp=100,
+                 mlp_dropout=.33,
+                 scale=0,
+                 pad_index=0,
+                 unk_index=1,
+                 **kwargs):
+        super().__init__(**Config().update(locals()))
+
+        # create decoder
+        self.common_decoder, self.ancestor_decoder = None, None
+        if self.args.decoder == 'lstm':
+            decoder = lambda out_dim: DecoderLSTM(
+                self.args.n_encoder_hidden, self.args.n_encoder_hidden, out_dim, 
+                self.args.n_decoder_layers, dropout=mlp_dropout, device=self.device
+            )
+        else:
+            decoder = lambda out_dim: MLP(
+                n_in=self.args.n_encoder_hidden, n_out=out_dim,
+                dropout=mlp_dropout, activation=True
+            )
+
+        self.common_decoder = decoder(self.args.n_commons)
+        self.ancestor_decoder = decoder(self.args.n_ancestors)
+
+        # create delay projection
+        if self.args.delay != 0:
+            self.delay_proj = MLP(n_in=self.args.n_encoder_hidden * (self.args.delay + 1),
+                                  n_out=self.args.n_encoder_hidden, dropout=mlp_dropout)
+
+        self.criterion = nn.CrossEntropyLoss()
+
+    def forward(self, words: torch.Tensor, feats: List[torch.Tensor]=None):
+        # words, *feats ~ [batch_size, bos + pad(seq_len) + delay, n_encoder_hidden]
+        x = self.encode(words, feats)
+        x = x[:, 1:, :]
+
+        # x ~ [batch_size, pad(seq_len), n_encoder_hidden]
+        batch_size, pad_seq_len, embed_size = x.shape
+        if self.args.delay != 0:
+            x = torch.cat([x[:, i:(pad_seq_len - self.args.delay + i), :] for i in range(self.args.delay+1)], dim=2)
+            x = self.delay_proj(x)
+
+        x, qloss = self.vq_forward(x)   # vector quantization
+
+        # s_common ~ [batch_size, pad(seq_len), n_commons]
+        # s_ancestor ~ [batch_size, pad(seq_len), n_ancestors]
+        s_common, s_ancestor = self.common_decoder(x), self.ancestor_decoder(x)
+        return s_common, s_ancestor, qloss
+
+    def loss(self,
+             s_common: torch.Tensor, s_ancestor: torch.Tensor, 
+             commons: torch.Tensor, ancestors: torch.Tensor, mask: torch.Tensor):
+        s_common, commons = s_common[mask], commons[mask]
+        s_ancestor, ancestors = s_ancestor[mask], ancestors[mask]
+        common_loss = self.criterion(s_common, commons)
+        ancestor_loss = self.criterion(s_ancestor, ancestors)
+        return common_loss + ancestor_loss
+
+    def decode(self, s_common, s_ancestor):
+        common_pred = s_common.argmax(-1)
+        ancestor_pred = s_ancestor.argmax(-1)
+        return common_pred, ancestor_pred
\ No newline at end of file
diff --git a/tania_scripts/supar/models/const/sl/parser.py b/tania_scripts/supar/models/const/sl/parser.py
new file mode 100644
index 0000000..17e8a3a
--- /dev/null
+++ b/tania_scripts/supar/models/const/sl/parser.py
@@ -0,0 +1,219 @@
+# -*- coding: utf-8 -*-
+
+import os
+from typing import Dict, Iterable, Set, Union
+
+import torch, nltk
+from supar.models.const.sl.model import SLConstituentModel
+from supar.parser import Parser
+from supar.utils import Config, Dataset, Embedding
+from supar.utils.common import BOS, EOS, PAD, UNK
+from supar.utils.field import ChartField, Field, RawField, SubwordField
+from supar.utils.logging import get_logger
+from supar.utils.metric import SpanMetric
+from supar.utils.tokenizer import TransformerTokenizer
+from supar.models.const.sl.transform import SLConstituent
+from supar.utils.transform import Batch
+from supar.models.const.crf.transform import Tree
+from supar.codelin import get_con_encoder, LinearizedTree, C_Label
+from supar.codelin.utils.constants import BOS as C_BOS, EOS as C_EOS
+
+logger = get_logger(__name__)
+
+
+class SLConstituentParser(Parser):
+
+    NAME = 'SLConstituentParser'
+    MODEL = SLConstituentModel
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self.COMMON = self.transform.COMMON
+        self.ANCESTOR = self.transform.ANCESTOR
+        self.encoder = self.transform.encoder
+
+    def train(
+        self,
+        train: Union[str, Iterable],
+        dev: Union[str, Iterable],
+        test: Union[str, Iterable],
+        epochs: int = 1000,
+        patience: int = 100,
+        batch_size: int = 5000,
+        update_steps: int = 1,
+        buckets: int = 32,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().train(**Config().update(locals()))
+
+    def evaluate(
+        self,
+        data: Union[str, Iterable],
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().evaluate(**Config().update(locals()))
+
+    def predict(
+        self,
+        data: Union[str, Iterable],
+        pred: str = None,
+        lang: str = None,
+        prob: bool = False,
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().predict(**Config().update(locals()))
+
+    def train_step(self, batch: Batch) -> torch.Tensor:
+        words, texts, *feats, commons, ancestors, trees = batch
+        mask = batch.mask[:, (1+self.args.delay):]
+        s_common, s_ancestor, qloss = self.model(words, feats)
+        loss = self.model.loss(s_common, s_ancestor, commons, ancestors, mask) + qloss
+        return loss
+
+    @torch.no_grad()
+    def eval_step(self, batch: Batch) -> SpanMetric:
+        words, texts, *feats, commons, ancestors, trees = batch
+        mask = batch.mask[:, (1+self.args.delay):]
+
+        # forward pass
+        s_common, s_ancestor, qloss = self.model(words, feats)
+        loss = self.model.loss(s_common, s_ancestor, commons, ancestors, mask) + qloss
+
+        # make predictions of the output of the network
+        common_preds, ancestor_preds = self.model.decode(s_common, s_ancestor)
+
+        # obtain original tokens to compute decoding
+        lens = (batch.lens - 1 - self.args.delay).tolist()
+        common_preds = [self.COMMON.vocab[i.tolist()] for i in common_preds[mask].split(lens)]
+        ancestor_preds = [self.ANCESTOR.vocab[i.tolist()] for i in ancestor_preds[mask].split(lens)]
+        # tag_preds = [self.transform.POS.vocab[i.tolist()] for i in tags[mask].split(lens)]
+        tag_preds = map(lambda tree: tuple(zip(*tree.pos()))[1], trees)
+
+        preds = list()
+        for i, (forms, upos, common_pred, ancestor_pred) in enumerate(zip(texts, tag_preds, common_preds, ancestor_preds)):
+            labels = list(map(lambda x: self.encoder.separator.join(x), zip(common_pred, ancestor_pred)))
+            linearized = list(map(lambda x: '\t'.join(x), zip(forms, upos, labels)))
+            linearized = [f'{C_BOS}\t{C_BOS}\t{C_BOS}'] + linearized + [f'{C_EOS}\t{C_EOS}\t{C_EOS}']
+            linearized = '\n'.join(linearized)
+            tree = LinearizedTree.from_string(linearized, mode='CONST', separator=self.encoder.separator,
+                                              unary_joiner=self.encoder.unary_joiner)
+            tree = self.encoder.decode(tree)
+            tree = tree.postprocess_tree('strat_max', clean_nulls=False)
+            preds.append(nltk.Tree.fromstring(str(tree)))
+
+            if len(preds[-1].leaves()) != len(trees[i].leaves()):
+                with open('error', 'w') as file:
+                    file.write(linearized)
+
+
+        return SpanMetric(loss,
+                          [Tree.factorize(tree, None, None) for tree in preds],
+                          [Tree.factorize(tree, None, None) for tree in trees])
+
+    @torch.no_grad()
+    def pred_step(self, batch: Batch) -> Batch:
+        words, texts, *feats = batch
+        tags = feats[-1][:, (1+self.args.delay):]
+        mask = batch.mask[:, (1 + self.args.delay):]
+
+        # forward pass
+        s_common, s_ancestor, _ = self.model(words, feats)
+
+        # make predictions of the output of the network
+        common_preds, ancestor_preds = self.model.decode(s_common, s_ancestor)
+
+        # obtain original tokens to compute decoding
+        lens = (batch.lens - 1 - self.args.delay).tolist()
+        common_preds = [self.COMMON.vocab[i.tolist()] for i in common_preds[mask].split(lens)]
+        ancestor_preds = [self.ANCESTOR.vocab[i.tolist()] for i in ancestor_preds[mask].split(lens)]
+        tag_preds = [self.transform.POS.vocab[i.tolist()] for i in tags[mask].split(lens)]
+
+        preds = list()
+        for i, (forms, upos, common_pred, ancestor_pred) in enumerate(zip(texts, tag_preds, common_preds, ancestor_preds)):
+            labels = list(map(lambda x: self.encoder.separator.join(x), zip(common_pred, ancestor_pred)))
+            linearized = list(map(lambda x: '\t'.join(x), zip(forms, upos, labels)))
+            linearized = [f'{C_BOS}\t{C_BOS}\t{C_BOS}'] + linearized + [f'{C_EOS}\t{C_EOS}\t{C_EOS}']
+            linearized = '\n'.join(linearized)
+            tree = LinearizedTree.from_string(linearized, mode='CONST', separator=self.encoder.separator, unary_joiner=self.encoder.unary_joiner)
+            tree = self.encoder.decode(tree)
+            tree = tree.postprocess_tree('strat_max', clean_nulls=False)
+            preds.append(nltk.Tree.fromstring(str(tree)))
+        batch.trees = preds
+        return batch
+
+    @classmethod
+    def build(cls, path, min_freq=2, fix_len=20, **kwargs):
+
+        args = Config(**locals())
+        os.makedirs(os.path.dirname(path) or './', exist_ok=True)
+        if os.path.exists(path) and not args.build:
+            parser = cls.load(**args)
+            parser.model = cls.MODEL(**parser.args)
+            parser.model.load_pretrained(parser.transform.WORD[0].embed).to(parser.device)
+            return parser
+
+        logger.info("Building the fields")
+        TAG, CHAR = None, None
+        if args.encoder == 'bert':
+            t = TransformerTokenizer(args.bert)
+            pad_token = t.pad if t.pad else PAD
+            WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, fix_len=args.fix_len, tokenize=t, delay=args.delay)
+            WORD.vocab = t.vocab
+        else:
+            WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, lower=True, delay=args.delay)
+            if 'char' in args.feat:
+                CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, fix_len=args.fix_len, delay=args.delay)
+        TAG = Field('tags', bos=BOS,)
+        TEXT = RawField('texts')
+        COMMON = Field('commons')
+        ANCESTOR = Field('ancestors')
+        TREE = RawField('trees')
+        encoder = get_con_encoder(args.codes)
+        transform = SLConstituent(encoder=encoder, WORD=(WORD, TEXT, CHAR), POS=TAG,
+                                  COMMON=COMMON, ANCESTOR=ANCESTOR, TREE=TREE)
+
+        train = Dataset(transform, args.train, **args)
+        if args.encoder != 'bert':
+            WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x))
+            if CHAR is not None:
+                CHAR.build(train)
+        TAG.build(train)
+        COMMON.build(train)
+        ANCESTOR.build(train)
+        args.update({
+            'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init,
+            'n_commons': len(COMMON.vocab),
+            'n_ancestors': len(ANCESTOR.vocab),
+            'n_tags': len(TAG.vocab),
+            'n_chars': len(CHAR.vocab) if CHAR is not None else None,
+            'char_pad_index': CHAR.pad_index if CHAR is not None else None,
+            'pad_index': WORD.pad_index,
+            'unk_index': WORD.unk_index,
+            'delay': 0 if 'delay' not in args.keys() else args.delay,
+        })
+        logger.info(f"{transform}")
+
+        logger.info("Building the model")
+        model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None)
+        logger.info(f"{model}\n")
+
+        parser = cls(args, model, transform)
+        parser.model.to(parser.device)
+        return parser
diff --git a/tania_scripts/supar/models/const/sl/transform.py b/tania_scripts/supar/models/const/sl/transform.py
new file mode 100644
index 0000000..b94b966
--- /dev/null
+++ b/tania_scripts/supar/models/const/sl/transform.py
@@ -0,0 +1,94 @@
+from typing import Union, Iterable, Optional, Set
+from supar.utils.field import Field
+from supar.utils.transform import Sentence, Transform
+from supar.codelin import C_Tree, UNARY_JOINER, LABEL_SEPARATOR
+import nltk, re
+
+
+class SLConstituent(Transform):
+    fields = ['WORD', 'POS', 'COMMON', 'ANCESTOR', 'TREE']
+
+    def __init__(
+        self,
+        encoder,
+        WORD: Union[Field, Iterable[Field]],
+        POS: Union[Field, Iterable[Field]],
+        COMMON: Union[Field, Iterable[Field]],
+        ANCESTOR: Union[Field, Iterable[Field]],
+        TREE: Union[Field, Iterable[Field]]
+    ):
+        super().__init__()
+
+        self.WORD = WORD
+        self.POS = POS
+        self.COMMON = COMMON
+        self.ANCESTOR = ANCESTOR
+        self.TREE = TREE
+        self.encoder = encoder
+
+
+    @property
+    def src(self):
+        return self.WORD, self.POS
+
+    @property
+    def tgt(self):
+        return self.COMMON, self.ANCESTOR, self.TREE
+    def load(
+        self,
+        data: Union[str, Iterable],
+        **kwargs
+    ) -> Iterable[Sentence]:
+        lines = open(data)
+        index = 0
+        for line in lines:
+            line = line.strip()
+            if len(line) > 0:
+                sentence = SLConstituentSentence(self, line, self.encoder, index)
+                yield sentence
+                index += 1
+
+
+def get_nodes(tree: nltk.Tree):
+    nodes = {tree.label()}
+    for subtree in tree:
+        if isinstance(subtree[0], nltk.Tree):
+            nodes = {*nodes, *get_nodes(subtree)}
+    return nodes
+
+def remove_doubles(tree: nltk.Tree):
+    for i, subtree in enumerate(tree):
+        if isinstance(subtree, str) and len(tree) > 1:
+            tree.pop(i)
+        elif isinstance(subtree, nltk.Tree):
+            remove_doubles(subtree)
+
+class SLConstituentSentence(Sentence):
+
+    def __init__(self, transform: SLConstituent, line: str, encoder, index: Optional[int] = None):
+        super().__init__(transform, index)
+
+        # get nodes of the tree
+        gold = nltk.Tree.fromstring(line)
+        nodes = ''.join(get_nodes(gold))
+        assert (encoder.separator not in nodes) and (encoder.unary_joiner not in nodes)
+
+        # create linearized tree
+        tree = C_Tree.from_string(line)
+        linearized_tree = encoder.encode(tree)
+        self.annotations = []
+        commons = list(map(lambda x: repr(x).split(encoder.separator)[0], linearized_tree.labels))
+        ancestors = list(map(lambda x: encoder.separator.join(repr(x).split(encoder.separator)[1:]), linearized_tree.labels))
+
+        _, postags = zip(*gold.pos())
+        self.values = [
+            linearized_tree.words,
+            postags,
+            commons, ancestors
+        ]
+        self.values.append(
+            nltk.Tree.fromstring(line)
+        )
+    def __repr__(self):
+        remove_doubles(self.values[-1])
+        return re.sub(' +', ' ', str(self.values[-1]).replace('\n', '').replace('\t', ''))
diff --git a/tania_scripts/supar/models/const/tt/__init__.py b/tania_scripts/supar/models/const/tt/__init__.py
new file mode 100644
index 0000000..4389219
--- /dev/null
+++ b/tania_scripts/supar/models/const/tt/__init__.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+
+from .model import TetraTaggingConstituencyModel
+from .parser import TetraTaggingConstituencyParser
+
+__all__ = ['TetraTaggingConstituencyModel', 'TetraTaggingConstituencyParser']
diff --git a/tania_scripts/supar/models/const/tt/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/const/tt/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6a577e63e231c15d7c6ffbde1d8660f3f458b985
GIT binary patch
literal 304
zcmd1j<>g{vU|`_PGe|$fz`*br#6iYP3=9ko3=9m#Dhvz^DGVu$ISjdsQH+crHd78$
zE^`z!BSQ*v3QIau6iW(gFoP!BOGX9;22I9WvLUG@MTsGa>FJqy>CX9i#U+^~rKx$z
zmA?5YsX3aAx8!gs2uLg{PAw_|*<HlUz`)?A$$E=57o-a;c8je5q5vd!i#<L*F()TJ
zekDT@I|BoR_+_V`k)NBYUy@jonV6TTmz0y3l9^hhpP83jkXWQ&TnZw=1{UilgIuOx
pQlcLppP83g5+AQuP<e~PCO1E&G$+*#<d<SL1_lNmCLTr}CIErDQ0xEz

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/tt/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/const/tt/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f242de08b1629939a1184b1ebf706bb4b2b2cbda
GIT binary patch
literal 382
zcmZ3^%ge>Uz`&q%Up3<l0|Ucj5C?{tpp4II3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI
zW=4h-<`kB6rYM#a)?fxrwwH_y3=Eo#w`4<7ONtUh64TQ&^U|I3^NLF{OG;Dok}G}l
zQ&Mv@8E?tqQV@_>RGeB=#LU3JP{hK(z~HCJdW$s|qzf!|i>&~n03>&dJw84$Cnr9B
zCBtWsYk!66XXNLm>X#&zWG3b%>LukQrevlT=_lvs7Ub)eq*j#Zrj{k<=$9nsWhTZK
zCl_TFloab1mlh-z>4U8()=vhxRllS}KR!M)FS8^*Uaz3?7l%!5eoARhs$CH`0|Nud
xi^Wz93=AKb85tQrurV+iUSKdlMmHFYE})_Z+*%iOd@gYLHn4+W5hnu!0{~YAZxR3i

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/tt/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/const/tt/__pycache__/model.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4deac65c29f9618638ef3d168e5f3799e148ae96
GIT binary patch
literal 10462
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
O4kjK(9uQ^}VFm!NZ@HfU

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/tt/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/const/tt/__pycache__/model.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..08a12831d12bab671d404d55859b4bb81ba4c6e0
GIT binary patch
literal 15368
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/tt/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/const/tt/__pycache__/parser.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..740bf37c4d0abed35cbd2fe734b4899404da1c63
GIT binary patch
literal 8248
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
QD8VSg2x5US2a^ah0MyVEd;kCd

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/tt/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/const/tt/__pycache__/parser.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3d0f9c3cecab729455b1cf901cfed200de9a4883
GIT binary patch
literal 15371
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/tt/__pycache__/transform.cpython-310.pyc b/tania_scripts/supar/models/const/tt/__pycache__/transform.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2226fc4c38750791963263a693f1896078972e05
GIT binary patch
literal 11481
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/tt/__pycache__/transform.cpython-311.pyc b/tania_scripts/supar/models/const/tt/__pycache__/transform.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ee00f85bb15eed4b144ed777f9dbfeef8c753e8c
GIT binary patch
literal 17156
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/tt/model.py b/tania_scripts/supar/models/const/tt/model.py
new file mode 100644
index 0000000..9bce1b6
--- /dev/null
+++ b/tania_scripts/supar/models/const/tt/model.py
@@ -0,0 +1,265 @@
+# -*- coding: utf-8 -*-
+
+from typing import List, Tuple
+
+import torch
+import torch.nn as nn
+
+from supar.model import Model
+from supar.utils import Config
+from supar.utils.common import INF
+
+
+class TetraTaggingConstituencyModel(Model):
+    r"""
+    The implementation of TetraTagging Constituency Parser :cite:`kitaev-klein-2020-tetra`.
+
+    Args:
+        n_words (int):
+            The size of the word vocabulary.
+        n_tags (int):
+            The number of POS tags, required if POS tag embeddings are used. Default: ``None``.
+        n_chars (int):
+            The number of characters, required if character-level representations are used. Default: ``None``.
+        encoder (str):
+            Encoder to use.
+            ``'lstm'``: BiLSTM encoder.
+            ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``.
+            Default: ``'lstm'``.
+        feat (List[str]):
+            Additional features to use, required if ``encoder='lstm'``.
+            ``'tag'``: POS tag embeddings.
+            ``'char'``: Character-level representations extracted by CharLSTM.
+            ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible.
+            Default: [``'char'``].
+        n_embed (int):
+            The size of word embeddings. Default: 100.
+        n_pretrained (int):
+            The size of pretrained word embeddings. Default: 100.
+        n_feat_embed (int):
+            The size of feature representations. Default: 100.
+        n_char_embed (int):
+            The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50.
+        n_char_hidden (int):
+            The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100.
+        char_pad_index (int):
+            The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0.
+        elmo (str):
+            Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``.
+        elmo_bos_eos (Tuple[bool]):
+            A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs.
+            Default: ``(True, False)``.
+        bert (str):
+            Specifies which kind of language model to use, e.g., ``'bert-base-cased'``.
+            This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_.
+            Default: ``None``.
+        n_bert_layers (int):
+            Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features.
+            The final outputs would be weighted sum of the hidden states of these layers.
+            Default: 4.
+        mix_dropout (float):
+            The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0.
+        bert_pooling (str):
+            Pooling way to get token embeddings.
+            ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all.
+            Default: ``mean``.
+        bert_pad_index (int):
+            The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features.
+            Default: 0.
+        finetune (bool):
+            If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``.
+        n_plm_embed (int):
+            The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0.
+        embed_dropout (float):
+            The dropout ratio of input embeddings. Default: .33.
+        n_encoder_hidden (int):
+            The size of encoder hidden states. Default: 800.
+        n_encoder_layers (int):
+            The number of encoder layers. Default: 3.
+        encoder_dropout (float):
+            The dropout ratio of encoder layers. Default: .33.
+        n_gnn_layers (int):
+            The number of GNN layers. Default: 3.
+        gnn_dropout (float):
+            The dropout ratio of GNN layers. Default: .33.
+        pad_index (int):
+            The index of the padding token in the word vocabulary. Default: 0.
+        unk_index (int):
+            The index of the unknown token in the word vocabulary. Default: 1.
+
+    .. _transformers:
+        https://github.com/huggingface/transformers
+    """
+
+    def __init__(self,
+                 n_words,
+                 n_tags=None,
+                 n_chars=None,
+                 encoder='lstm',
+                 feat=['char'],
+                 n_embed=100,
+                 n_pretrained=100,
+                 n_feat_embed=100,
+                 n_char_embed=50,
+                 n_char_hidden=100,
+                 char_pad_index=0,
+                 elmo='original_5b',
+                 elmo_bos_eos=(True, True),
+                 bert=None,
+                 n_bert_layers=4,
+                 mix_dropout=.0,
+                 bert_pooling='mean',
+                 bert_pad_index=0,
+                 finetune=False,
+                 n_plm_embed=0,
+                 embed_dropout=.33,
+                 n_encoder_hidden=800,
+                 n_encoder_layers=3,
+                 encoder_dropout=.33,
+                 n_gnn_layers=3,
+                 gnn_dropout=.33,
+                 pad_index=0,
+                 unk_index=1,
+                 **kwargs):
+        super().__init__(**Config().update(locals()))
+
+        self.proj = nn.Linear(self.args.n_encoder_hidden, self.args.n_leaves + self.args.n_nodes)
+        self.criterion = nn.CrossEntropyLoss()
+
+    def forward(
+        self,
+        words: torch.LongTensor,
+        feats: List[torch.LongTensor] = None
+    ) -> torch.Tensor:
+        r"""
+        Args:
+            words (~torch.LongTensor): ``[batch_size, seq_len]``.
+                Word indices.
+            feats (List[~torch.LongTensor]):
+                A list of feat indices.
+                The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``,
+                or ``[batch_size, seq_len]`` otherwise.
+                Default: ``None``.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor:
+                Scores for all leaves (``[batch_size, seq_len, n_leaves]``) and nodes (``[batch_size, seq_len, n_nodes]``).
+        """
+
+        s = self.proj(self.encode(words, feats)[:, 1:-1])
+        s_leaf, s_node = s[..., :self.args.n_leaves], s[..., self.args.n_leaves:]
+        return s_leaf, s_node
+
+    def loss(
+        self,
+        s_leaf: torch.Tensor,
+        s_node: torch.Tensor,
+        leaves: torch.LongTensor,
+        nodes: torch.LongTensor,
+        mask: torch.BoolTensor
+    ) -> torch.Tensor:
+        r"""
+        Args:
+            s_leaf (~torch.Tensor): ``[batch_size, seq_len, n_leaves]``.
+                Leaf scores.
+            s_node (~torch.Tensor): ``[batch_size, seq_len, n_leaves]``.
+                Non-terminal scores.
+            leaves (~torch.LongTensor): ``[batch_size, seq_len]``.
+                Actions for leaves.
+            nodes (~torch.LongTensor): ``[batch_size, seq_len]``.
+                Actions for non-terminals.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens in each chart.
+
+        Returns:
+            ~torch.Tensor:
+                The training loss.
+        """
+
+        leaf_mask, node_mask = mask, mask[:, 1:]
+        leaf_loss = self.criterion(s_leaf[leaf_mask], leaves[leaf_mask])
+        node_loss = self.criterion(s_node[:, :-1][node_mask], nodes[node_mask]) if nodes.shape[1] > 0 else 0
+        return leaf_loss + node_loss
+
+    def decode(
+        self,
+        s_leaf: torch.Tensor,
+        s_node: torch.Tensor,
+        mask: torch.BoolTensor,
+        left_mask: torch.BoolTensor,
+        depth: int = 8
+    ) -> List[List[Tuple]]:
+        r"""
+        Args:
+            s_leaf (~torch.Tensor): ``[batch_size, seq_len, n_leaves]``.
+                Leaf scores.
+            s_node (~torch.Tensor): ``[batch_size, seq_len, n_leaves]``.
+                Non-terminal scores.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens in each chart.
+            left_mask (~torch.BoolTensor): ``[n_leaves + n_nodes]``.
+                The mask for distingushing left/rightward actions.
+            depth (int):
+                Stack depth. Default: 8.
+
+        Returns:
+            List[List[Tuple]]:
+                Sequences of factorized labeled trees.
+        """
+        from torch_scatter import scatter_max
+
+        lens = mask.sum(-1)
+        batch_size, seq_len, n_leaves = s_leaf.shape
+        end_mask = (lens - 1).unsqueeze(-1).eq(lens.new_tensor(range(seq_len)))
+        leaf_left_mask, node_left_mask = left_mask[:n_leaves], left_mask[n_leaves:]
+        s_leaf = s_leaf.masked_fill_(end_mask.unsqueeze(-1) & leaf_left_mask, -INF)
+        # [n_leaves], [n_nodes]
+        changes = (torch.where(leaf_left_mask, 1, 0), torch.where(node_left_mask, 0, -1))
+        # [batch_size, depth]
+        depths = lens.new_full((depth,), -2).index_fill_(-1, lens.new_tensor(0), -1).repeat(batch_size, 1)
+        # [2, batch_size, depth, seq_len]
+        labels, paths = lens.new_zeros(2, batch_size, depth, seq_len), lens.new_zeros(2, batch_size, depth, seq_len)
+        # [batch_size, depth]
+        s = s_leaf.new_zeros(batch_size, depth)
+
+        def advance(s, s_t, depths, changes):
+            batch_size, n_labels = s_t.shape
+            # [batch_size, depth * n_labels]
+            depths = (depths.unsqueeze(-1) + changes).view(batch_size, -1)
+            # [batch_size, depth, n_labels]
+            s_t = s.unsqueeze(-1) + s_t.unsqueeze(1)
+            # [batch_size, depth * n_labels]
+            # fill scores of invalid depths with -INF
+            s_t = s_t.view(batch_size, -1).masked_fill_((depths < 0).logical_or_(depths >= depth), -INF)
+            # [batch_size, depth]
+            # for each depth, we use the `scatter_max` trick to obtain the 1-best label
+            s, ls = scatter_max(s_t, depths.clamp(0, depth - 1), -1, s_t.new_full((batch_size, depth), -INF))
+            # [batch_size, depth]
+            depths = depths.gather(-1, ls.clamp(0, depths.shape[1] - 1)).masked_fill_(s.eq(-INF), -1)
+            ll = ls % n_labels
+            lp = depths - changes[ll]
+            return s, ll, lp, depths
+
+        for t in range(seq_len):
+            m = lens.gt(t)
+            s[m], labels[0, m, :, t], paths[0, m, :, t], depths[m] = advance(s[m], s_leaf[m, t], depths[m], changes[0])
+            if t == seq_len - 1:
+                break
+            m = lens.gt(t + 1)
+            s[m], labels[1, m, :, t], paths[1, m, :, t], depths[m] = advance(s[m], s_node[m, t], depths[m], changes[1])
+
+        lens = lens.tolist()
+        labels, paths = labels.movedim((0, 2), (2, 3))[mask].split(lens), paths.movedim((0, 2), (2, 3))[mask].split(lens)
+        leaves, nodes = [], []
+        for i, length in enumerate(lens):
+            leaf_labels, node_labels = labels[i].transpose(0, 1).tolist()
+            leaf_paths, node_paths = paths[i].transpose(0, 1).tolist()
+            leaf_pred, node_pred, prev = [leaf_labels[-1][0]], [], leaf_paths[-1][0]
+            for j in reversed(range(length - 1)):
+                node_pred.append(node_labels[j][prev])
+                prev = node_paths[j][prev]
+                leaf_pred.append(leaf_labels[j][prev])
+                prev = leaf_paths[j][prev]
+            leaves.append(list(reversed(leaf_pred)))
+            nodes.append(list(reversed(node_pred)))
+        return leaves, nodes
diff --git a/tania_scripts/supar/models/const/tt/parser.py b/tania_scripts/supar/models/const/tt/parser.py
new file mode 100644
index 0000000..7289c22
--- /dev/null
+++ b/tania_scripts/supar/models/const/tt/parser.py
@@ -0,0 +1,205 @@
+# -*- coding: utf-8 -*-
+
+import os
+from typing import Dict, Iterable, Set, Union
+
+import torch
+
+from supar.models.const.tt.model import TetraTaggingConstituencyModel
+from supar.models.const.tt.transform import TetraTaggingTree
+from supar.parser import Parser
+from supar.utils import Config, Dataset, Embedding
+from supar.utils.common import BOS, EOS, PAD, UNK
+from supar.utils.field import Field, RawField, SubwordField
+from supar.utils.logging import get_logger
+from supar.utils.metric import SpanMetric
+from supar.utils.tokenizer import TransformerTokenizer
+from supar.utils.transform import Batch
+
+logger = get_logger(__name__)
+
+
+class TetraTaggingConstituencyParser(Parser):
+    r"""
+    The implementation of TetraTagging Constituency Parser :cite:`kitaev-klein-2020-tetra`.
+    """
+
+    NAME = 'tetra-tagging-constituency'
+    MODEL = TetraTaggingConstituencyModel
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self.TREE = self.transform.TREE
+        self.LEAF = self.transform.LEAF
+        self.NODE = self.transform.NODE
+
+        self.left_mask = torch.tensor([*(i.startswith('l') for i in self.LEAF.vocab.itos),
+                                       *(i.startswith('L') for i in self.NODE.vocab.itos)]).to(self.device)
+
+    def train(
+        self,
+        train: Union[str, Iterable],
+        dev: Union[str, Iterable],
+        test: Union[str, Iterable],
+        epochs: int = 1000,
+        patience: int = 100,
+        batch_size: int = 5000,
+        update_steps: int = 1,
+        buckets: int = 32,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        depth: int = 1,
+        delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''},
+        equal: Dict = {'ADVP': 'PRT'},
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().train(**Config().update(locals()))
+
+    def evaluate(
+        self,
+        data: Union[str, Iterable],
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        depth: int = 1,
+        delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''},
+        equal: Dict = {'ADVP': 'PRT'},
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().evaluate(**Config().update(locals()))
+
+    def predict(
+        self,
+        data: Union[str, Iterable],
+        pred: str = None,
+        lang: str = None,
+        prob: bool = False,
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        depth: int = 1,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().predict(**Config().update(locals()))
+
+    def train_step(self, batch: Batch) -> torch.Tensor:
+        words, *feats, _, leaves, nodes = batch
+        mask = batch.mask[:, 2:]
+        s_leaf, s_node = self.model(words, feats)
+        loss = self.model.loss(s_leaf, s_node, leaves, nodes, mask)
+        return loss
+
+    @torch.no_grad()
+    def eval_step(self, batch: Batch) -> SpanMetric:
+        words, *feats, trees, leaves, nodes = batch
+        mask = batch.mask[:, 2:]
+        s_leaf, s_node = self.model(words, feats)
+        loss = self.model.loss(s_leaf, s_node, leaves, nodes, mask)
+        preds = self.model.decode(s_leaf, s_node, mask, self.left_mask, self.args.depth)
+        preds = [TetraTaggingTree.action2tree(tree, (self.LEAF.vocab[i], self.NODE.vocab[j] if len(j) > 0 else []))
+                 for tree, i, j in zip(trees, *preds)]
+        return SpanMetric(loss,
+                          [TetraTaggingTree.factorize(tree, self.args.delete, self.args.equal) for tree in preds],
+                          [TetraTaggingTree.factorize(tree, self.args.delete, self.args.equal) for tree in trees])
+
+    @torch.no_grad()
+    def pred_step(self, batch: Batch) -> Batch:
+        words, *feats, trees = batch
+        mask = batch.mask[:, 2:]
+        s_leaf, s_node = self.model(words, feats)
+        preds = self.model.decode(s_leaf, s_node, mask, self.left_mask, self.args.depth)
+        batch.trees = [TetraTaggingTree.action2tree(tree, (self.LEAF.vocab[i], self.NODE.vocab[j] if len(j) > 0 else []))
+                       for tree, i, j in zip(trees, *preds)]
+        if self.args.prob:
+            raise NotImplementedError("Returning action probs are currently not supported yet.")
+        return batch
+
+    @classmethod
+    def build(cls, path, min_freq=2, fix_len=20, **kwargs):
+        r"""
+        Build a brand-new Parser, including initialization of all data fields and model parameters.
+
+        Args:
+            path (str):
+                The path of the model to be saved.
+            min_freq (str):
+                The minimum frequency needed to include a token in the vocabulary. Default: 2.
+            fix_len (int):
+                The max length of all subword pieces. The excess part of each piece will be truncated.
+                Required if using CharLSTM/BERT.
+                Default: 20.
+            kwargs (Dict):
+                A dict holding the unconsumed arguments.
+        """
+
+        args = Config(**locals())
+        os.makedirs(os.path.dirname(path) or './', exist_ok=True)
+        if os.path.exists(path) and not args.build:
+            parser = cls.load(**args)
+            parser.model = cls.MODEL(**parser.args)
+            parser.model.load_pretrained(parser.transform.WORD[0].embed).to(parser.device)
+            return parser
+
+        logger.info("Building the fields")
+        TAG, CHAR, ELMO, BERT = None, None, None, None
+        if args.encoder == 'bert':
+            t = TransformerTokenizer(args.bert)
+            WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, eos=t.eos, fix_len=args.fix_len, tokenize=t)
+            WORD.vocab = t.vocab
+        else:
+            WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True)
+            if 'tag' in args.feat:
+                TAG = Field('tags', bos=BOS, eos=EOS)
+            if 'char' in args.feat:
+                CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, eos=EOS, fix_len=args.fix_len)
+            if 'elmo' in args.feat:
+                from allennlp.modules.elmo import batch_to_ids
+                ELMO = RawField('elmo')
+                ELMO.compose = lambda x: batch_to_ids(x).to(WORD.device)
+            if 'bert' in args.feat:
+                t = TransformerTokenizer(args.bert)
+                BERT = SubwordField('bert', pad=t.pad, unk=t.unk, bos=t.bos, eos=t.eos, fix_len=args.fix_len, tokenize=t)
+                BERT.vocab = t.vocab
+        TREE = RawField('trees')
+        LEAF, NODE = Field('leaf'), Field('node')
+        transform = TetraTaggingTree(WORD=(WORD, CHAR, ELMO, BERT), POS=TAG, TREE=TREE, LEAF=LEAF, NODE=NODE)
+
+        train = Dataset(transform, args.train, **args)
+        if args.encoder != 'bert':
+            WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x))
+            if TAG is not None:
+                TAG.build(train)
+            if CHAR is not None:
+                CHAR.build(train)
+        LEAF, NODE = LEAF.build(train), NODE.build(train)
+        args.update({
+            'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init,
+            'n_leaves': len(LEAF.vocab),
+            'n_nodes': len(NODE.vocab),
+            'n_tags': len(TAG.vocab) if TAG is not None else None,
+            'n_chars': len(CHAR.vocab) if CHAR is not None else None,
+            'char_pad_index': CHAR.pad_index if CHAR is not None else None,
+            'bert_pad_index': BERT.pad_index if BERT is not None else None,
+            'pad_index': WORD.pad_index,
+            'unk_index': WORD.unk_index,
+            'bos_index': WORD.bos_index,
+            'eos_index': WORD.eos_index
+        })
+        logger.info(f"{transform}")
+
+        logger.info("Building the model")
+        model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None)
+        logger.info(f"{model}\n")
+
+        parser = cls(args, model, transform)
+        parser.model.to(parser.device)
+        return parser
diff --git a/tania_scripts/supar/models/const/tt/transform.py b/tania_scripts/supar/models/const/tt/transform.py
new file mode 100644
index 0000000..a337b94
--- /dev/null
+++ b/tania_scripts/supar/models/const/tt/transform.py
@@ -0,0 +1,301 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+import os
+from typing import TYPE_CHECKING, Iterable, List, Optional, Tuple, Union, Sequence
+
+import nltk
+
+from supar.models.const.crf.transform import Tree
+from supar.utils.logging import get_logger
+from supar.utils.tokenizer import Tokenizer
+from supar.utils.transform import Sentence
+
+if TYPE_CHECKING:
+    from supar.utils import Field
+
+logger = get_logger(__name__)
+
+
+class TetraTaggingTree(Tree):
+    r"""
+    :class:`TetraTaggingTree` is derived from the :class:`Tree` class and is defined for supporting the transition system of
+    tetra tagger :cite:`kitaev-klein-2020-tetra`.
+
+    Attributes:
+        WORD:
+            Words in the sentence.
+        POS:
+            Part-of-speech tags, or underscores if not available.
+        TREE:
+            The raw constituency tree in :class:`nltk.tree.Tree` format.
+        LEAF:
+            Action labels in tetra tagger transition system.
+        NODE:
+            Non-terminal labels.
+    """
+
+    fields = ['WORD', 'POS', 'TREE', 'LEAF', 'NODE']
+
+    def __init__(
+        self,
+        WORD: Optional[Union[Field, Iterable[Field]]] = None,
+        POS: Optional[Union[Field, Iterable[Field]]] = None,
+        TREE: Optional[Union[Field, Iterable[Field]]] = None,
+        LEAF: Optional[Union[Field, Iterable[Field]]] = None,
+        NODE: Optional[Union[Field, Iterable[Field]]] = None
+    ) -> Tree:
+        super().__init__()
+
+        self.WORD = WORD
+        self.POS = POS
+        self.TREE = TREE
+        self.LEAF = LEAF
+        self.NODE = NODE
+
+    @property
+    def tgt(self):
+        return self.LEAF, self.NODE
+
+    @classmethod
+    def tree2action(cls, tree: nltk.Tree) -> Tuple[Sequence, Sequence]:
+        r"""
+        Converts a (binarized) constituency tree into tetra-tagging actions.
+
+        Args:
+            tree (nltk.tree.Tree):
+                A constituency tree in :class:`nltk.tree.Tree` format.
+
+        Returns:
+            Tetra-tagging actions for leaves and non-terminals.
+
+        Examples:
+            >>> from supar.models.const.tt.transform import TetraTaggingTree
+            >>> tree = nltk.Tree.fromstring('''
+                                            (TOP
+                                              (S
+                                                (NP (_ She))
+                                                (VP (_ enjoys) (S (VP (_ playing) (NP (_ tennis)))))
+                                                (_ .)))
+                                            ''')
+            >>> tree.pretty_print()
+                         TOP
+                          |
+                          S
+              ____________|________________
+             |            VP               |
+             |     _______|_____           |
+             |    |             S          |
+             |    |             |          |
+             |    |             VP         |
+             |    |        _____|____      |
+             NP   |       |          NP    |
+             |    |       |          |     |
+             _    _       _          _     _
+             |    |       |          |     |
+            She enjoys playing     tennis  .
+
+            >>> tree = TetraTaggingTree.binarize(tree, left=False, implicit=True)
+            >>> tree.pretty_print()
+                         TOP
+                          |
+                          S
+              ____________|______
+             |
+             |             ______|___________
+             |            VP                 |
+             |     _______|______            |
+             |    |            S::VP         |
+             |    |        ______|_____      |
+             NP                        NP
+             |    |       |            |     |
+             _    _       _            _     _
+             |    |       |            |     |
+            She enjoys playing       tennis  .
+
+            >>> TetraTaggingTree.tree2action(tree)
+            (['l/NP', 'l/', 'l/', 'r/NP', 'r/'], ['L/S', 'L/VP', 'R/S::VP', 'R/'])
+        """
+
+        def traverse(tree: nltk.Tree, left: bool = True) -> List:
+            if len(tree) == 1 and not isinstance(tree[0], nltk.Tree):
+                return ['l' if left else 'r'], []
+            if len(tree) == 1 and not isinstance(tree[0][0], nltk.Tree):
+                return [f"{'l' if left else 'r'}/{tree.label()}"], []
+            return tuple(sum(i, []) for i in zip(*[traverse(tree[0]),
+                                                   ([], [f'{("L" if left else "R")}/{tree.label()}']),
+                                                   traverse(tree[1], False)]))
+        return traverse(tree[0])
+
+    @classmethod
+    def action2tree(
+        cls,
+        tree: nltk.Tree,
+        actions: Tuple[Sequence, Sequence],
+        mark: Union[str, Tuple[str]] = ('*', '|<>'),
+        join: str = '::',
+    ) -> nltk.Tree:
+        r"""
+        Recovers a constituency tree from tetra-tagging actions.
+
+        Args:
+            tree (nltk.tree.Tree):
+                An empty tree that provides a base for building a result tree.
+            actions (Tuple[Sequence, Sequence]):
+                Tetra-tagging actions.
+            mark (Union[str, List[str]]):
+                A string used to mark newly inserted nodes. Non-terminals containing this will be removed.
+                Default: ``('*', '|<>')``.
+            join (str):
+                A string used to connect collapsed node labels. Non-terminals containing this will be expanded to unary chains.
+                Default: ``'::'``.
+
+        Returns:
+            A result constituency tree.
+
+        Examples:
+            >>> from supar.models.const.tt.transform import TetraTaggingTree
+            >>> tree = TetraTaggingTree.totree(['She', 'enjoys', 'playing', 'tennis', '.'], 'TOP')
+            >>> actions = (['l/NP', 'l/', 'l/', 'r/NP', 'r/'], ['L/S', 'L/VP', 'R/S::VP', 'R/'])
+            >>> TetraTaggingTree.action2tree(tree, actions).pretty_print()
+                         TOP
+                          |
+                          S
+              ____________|________________
+             |            VP               |
+             |     _______|_____           |
+             |    |             S          |
+             |    |             |          |
+             |    |             VP         |
+             |    |        _____|____      |
+             NP   |       |          NP    |
+             |    |       |          |     |
+             _    _       _          _     _
+             |    |       |          |     |
+            She enjoys playing     tennis  .
+
+        """
+
+        stack = []
+        leaves = [nltk.Tree(pos, [token]) for token, pos in tree.pos()]
+        for i, (al, an) in enumerate(zip(*actions)):
+            leaf = nltk.Tree(al.split('/', 1)[1], [leaves[i]])
+            if al.startswith('l'):
+                stack.append([leaf, None])
+            else:
+                slot = stack[-1][1]
+                slot.append(leaf)
+            if an.startswith('L'):
+                node = nltk.Tree(an.split('/', 1)[1], [stack[-1][0]])
+                stack[-1][0] = node
+            else:
+                node = nltk.Tree(an.split('/', 1)[1], [stack.pop()[0]])
+                slot = stack[-1][1]
+                slot.append(node)
+            stack[-1][1] = node
+        # the last leaf must be leftward
+        leaf = nltk.Tree(actions[0][-1].split('/', 1)[1], [leaves[-1]])
+        if len(stack) > 0:
+            stack[-1][1].append(leaf)
+        else:
+            stack.append([leaf, None])
+
+        def debinarize(tree):
+            if len(tree) == 1 and not isinstance(tree[0], nltk.Tree):
+                return [tree]
+            label, children = tree.label(), []
+            for child in tree:
+                children.extend(debinarize(child))
+            if not label or label.endswith(mark):
+                return children
+            labels = label.split(join) if join in label else [label]
+            tree = nltk.Tree(labels[-1], children)
+            for label in reversed(labels[:-1]):
+                tree = nltk.Tree(label, [tree])
+            return [tree]
+        return debinarize(nltk.Tree(tree.label(), [stack[0][0]]))[0]
+
+    def load(
+        self,
+        data: Union[str, Iterable],
+        lang: Optional[str] = None,
+        **kwargs
+    ) -> List[TetraTaggingTreeSentence]:
+        r"""
+        Args:
+            data (Union[str, Iterable]):
+                A filename or a list of instances.
+            lang (str):
+                Language code (e.g., ``en``) or language name (e.g., ``English``) for the text to tokenize.
+                ``None`` if tokenization is not required.
+                Default: ``None``.
+
+        Returns:
+            A list of :class:`TetraTaggingTreeSentence` instances.
+        """
+
+        if lang is not None:
+            tokenizer = Tokenizer(lang)
+        if isinstance(data, str) and os.path.exists(data):
+            if data.endswith('.txt'):
+                data = (s.split() if lang is None else tokenizer(s) for s in open(data) if len(s) > 1)
+            else:
+                data = open(data)
+        else:
+            if lang is not None:
+                data = [tokenizer(i) for i in ([data] if isinstance(data, str) else data)]
+            else:
+                data = [data] if isinstance(data[0], str) else data
+
+        index = 0
+        for s in data:
+            try:
+                tree = nltk.Tree.fromstring(s) if isinstance(s, str) else self.totree(s, self.root)
+                sentence = TetraTaggingTreeSentence(self, tree, index)
+            except ValueError:
+                logger.warning(f"Error found while converting Sentence {index} to a tree:\n{s}\nDiscarding it!")
+                continue
+            else:
+                yield sentence
+                index += 1
+        self.root = tree.label()
+
+
+class TetraTaggingTreeSentence(Sentence):
+    r"""
+    Args:
+        transform (TetraTaggingTree):
+            A :class:`TetraTaggingTree` object.
+        tree (nltk.tree.Tree):
+            A :class:`nltk.tree.Tree` object.
+        index (Optional[int]):
+            Index of the sentence in the corpus. Default: ``None``.
+    """
+
+    def __init__(
+        self,
+        transform: TetraTaggingTree,
+        tree: nltk.Tree,
+        index: Optional[int] = None
+    ) -> TetraTaggingTreeSentence:
+        super().__init__(transform, index)
+
+        words, tags = zip(*tree.pos())
+        leaves, nodes = None, None
+        if transform.training:
+            oracle_tree = tree.copy(True)
+            # the root node must have a unary chain
+            if len(oracle_tree) > 1:
+                oracle_tree[:] = [nltk.Tree('*', oracle_tree)]
+            oracle_tree = TetraTaggingTree.binarize(oracle_tree, left=False, implicit=True)
+            if len(oracle_tree) == 1 and not isinstance(oracle_tree[0][0], nltk.Tree):
+                oracle_tree[0] = nltk.Tree('*', [oracle_tree[0]])
+            leaves, nodes = transform.tree2action(oracle_tree)
+        self.values = [words, tags, tree, leaves, nodes]
+
+    def __repr__(self):
+        return self.values[-3].pformat(1000000)
+
+    def pretty_print(self):
+        self.values[-3].pretty_print()
diff --git a/tania_scripts/supar/models/const/vi/__init__.py b/tania_scripts/supar/models/const/vi/__init__.py
new file mode 100644
index 0000000..db91608
--- /dev/null
+++ b/tania_scripts/supar/models/const/vi/__init__.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+
+from .model import VIConstituencyModel
+from .parser import VIConstituencyParser
+
+__all__ = ['VIConstituencyModel', 'VIConstituencyParser']
diff --git a/tania_scripts/supar/models/const/vi/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/const/vi/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..061ba0053d502449b355ff1e49fecf53cd5b85e9
GIT binary patch
literal 284
zcmd1j<>g{vU|`_PGe}>;z`*br#6iYP3=9ko3=9m#Dhvz^DGVu$ISjdsQH+crHd78$
zE^`z!BSQ*v3QIau6iW(gFoP!BOGX9;22I9W!eO4y`FX`9nI)yEdC8T&`6;P6nvAzZ
zP=x~$i;7c=ia_=hF*7hQ_-V4<V$B7q1&iHcD}X2f$=za)k5A0WiH~2&P{hu_03m+a
z>1X8Urs|g@mSiU8CF&*RB&KAh7U^f^B^M+X=@*xRNU(v$`pF>o=$B>c$H!;pWtPOp
f>lIYq;;_lhPbtkwwF9}kn2mvffrp8Qk%tKY(bPy|

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/vi/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/const/vi/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5780eac044e7f23e6effee39efea6913adc7c972
GIT binary patch
literal 362
zcmZ3^%ge>Uz`&q%Uo~S10|Ucj5C?{tpp4II3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI
zW=4h-<`kB6rYM#a)?fxrwwH_y3=Eo#w}ityo%8dGOEODJQ}dE5ee+XNb2J%miJ%Gx
zBo-B?78NlwFfbIcFfcIqX|mp8%>}6ii``-?fG7aT-C~cAPt3`Qk6+2~8RW8Gq52v5
zxvBaki6xndd5L;SIf*HmsYUw9`MCx8x+SR<CAz6)i8=ZuiFuic@x{qSnFS@q`o*OM
ziADNgD~k1#K`zuU%hZpL&&<m#iI3MSsQkrYlbfGXnv-f*#Ld9K0P;?;6$1mq2WCb_
n#t&=^jOrH{)R55)28|1-=mEFF1tp6MT$T;&AXvo7z`y_i$h>9M

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/vi/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/const/vi/__pycache__/model.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..74c5b353f48c7a6aaa1d1f8944496ff7070b89ec
GIT binary patch
literal 10359
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
B)gAx<

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/vi/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/const/vi/__pycache__/model.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ef42262709e0f807a94447a265c803f5688b9c97
GIT binary patch
literal 13244
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/vi/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/const/vi/__pycache__/parser.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6aec5892d74be8c41b6e936b63abef924b1a5841
GIT binary patch
literal 4769
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
RCJrVZCLTrv<X{qE1^|nnV%Pux

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/vi/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/const/vi/__pycache__/parser.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c2279ac265980ece4415c326074e52e8ec8ef509
GIT binary patch
literal 8761
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
Q+TbHt>I;~}R0a+q0Hd?)Gynhq

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/const/vi/model.py b/tania_scripts/supar/models/const/vi/model.py
new file mode 100644
index 0000000..c44daac
--- /dev/null
+++ b/tania_scripts/supar/models/const/vi/model.py
@@ -0,0 +1,237 @@
+# -*- coding: utf-8 -*-
+
+import torch
+import torch.nn as nn
+from supar.models.const.crf.model import CRFConstituencyModel
+from supar.modules import MLP, Biaffine, Triaffine
+from supar.structs import ConstituencyCRF, ConstituencyLBP, ConstituencyMFVI
+from supar.utils import Config
+
+
+class VIConstituencyModel(CRFConstituencyModel):
+    r"""
+    The implementation of Constituency Parser using variational inference.
+
+    Args:
+        n_words (int):
+            The size of the word vocabulary.
+        n_labels (int):
+            The number of labels in the treebank.
+        n_tags (int):
+            The number of POS tags, required if POS tag embeddings are used. Default: ``None``.
+        n_chars (int):
+            The number of characters, required if character-level representations are used. Default: ``None``.
+        encoder (str):
+            Encoder to use.
+            ``'lstm'``: BiLSTM encoder.
+            ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``.
+            Default: ``'lstm'``.
+        feat (List[str]):
+            Additional features to use, required if ``encoder='lstm'``.
+            ``'tag'``: POS tag embeddings.
+            ``'char'``: Character-level representations extracted by CharLSTM.
+            ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible.
+            Default: [``'char'``].
+        n_embed (int):
+            The size of word embeddings. Default: 100.
+        n_pretrained (int):
+            The size of pretrained word embeddings. Default: 100.
+        n_feat_embed (int):
+            The size of feature representations. Default: 100.
+        n_char_embed (int):
+            The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50.
+        n_char_hidden (int):
+            The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100.
+        char_pad_index (int):
+            The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0.
+        elmo (str):
+            Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``.
+        elmo_bos_eos (Tuple[bool]):
+            A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs.
+            Default: ``(True, False)``.
+        bert (str):
+            Specifies which kind of language model to use, e.g., ``'bert-base-cased'``.
+            This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_.
+            Default: ``None``.
+        n_bert_layers (int):
+            Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features.
+            The final outputs would be weighted sum of the hidden states of these layers.
+            Default: 4.
+        mix_dropout (float):
+            The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0.
+        bert_pooling (str):
+            Pooling way to get token embeddings.
+            ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all.
+            Default: ``mean``.
+        bert_pad_index (int):
+            The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features.
+            Default: 0.
+        finetune (bool):
+            If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``.
+        n_plm_embed (int):
+            The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0.
+        embed_dropout (float):
+            The dropout ratio of input embeddings. Default: .33.
+        n_encoder_hidden (int):
+            The size of encoder hidden states. Default: 800.
+        n_encoder_layers (int):
+            The number of encoder layers. Default: 3.
+        encoder_dropout (float):
+            The dropout ratio of encoder layer. Default: .33.
+        n_span_mlp (int):
+            Span MLP size. Default: 500.
+        n_pair_mlp (int):
+            Binary factor MLP size. Default: 100.
+        n_label_mlp  (int):
+            Label MLP size. Default: 100.
+        mlp_dropout (float):
+            The dropout ratio of MLP layers. Default: .33.
+        inference (str):
+            Approximate inference methods. Default: ``mfvi``.
+        max_iter (int):
+            Max iteration times for inference. Default: 3.
+        interpolation (int):
+            Constant to even out the label/edge loss. Default: .1.
+        pad_index (int):
+            The index of the padding token in the word vocabulary. Default: 0.
+        unk_index (int):
+            The index of the unknown token in the word vocabulary. Default: 1.
+
+    .. _transformers:
+        https://github.com/huggingface/transformers
+    """
+
+    def __init__(self,
+                 n_words,
+                 n_labels,
+                 n_tags=None,
+                 n_chars=None,
+                 encoder='lstm',
+                 feat=['char'],
+                 n_embed=100,
+                 n_pretrained=100,
+                 n_feat_embed=100,
+                 n_char_embed=50,
+                 n_char_hidden=100,
+                 char_pad_index=0,
+                 elmo='original_5b',
+                 elmo_bos_eos=(True, True),
+                 bert=None,
+                 n_bert_layers=4,
+                 mix_dropout=.0,
+                 bert_pooling='mean',
+                 bert_pad_index=0,
+                 finetune=False,
+                 n_plm_embed=0,
+                 embed_dropout=.33,
+                 n_encoder_hidden=800,
+                 n_encoder_layers=3,
+                 encoder_dropout=.33,
+                 n_span_mlp=500,
+                 n_pair_mlp=100,
+                 n_label_mlp=100,
+                 mlp_dropout=.33,
+                 inference='mfvi',
+                 max_iter=3,
+                 interpolation=0.1,
+                 pad_index=0,
+                 unk_index=1,
+                 **kwargs):
+        super().__init__(**Config().update(locals()))
+
+        self.span_mlp_l = MLP(n_in=self.args.n_encoder_hidden, n_out=n_span_mlp, dropout=mlp_dropout)
+        self.span_mlp_r = MLP(n_in=self.args.n_encoder_hidden, n_out=n_span_mlp, dropout=mlp_dropout)
+        self.pair_mlp_l = MLP(n_in=self.args.n_encoder_hidden, n_out=n_pair_mlp, dropout=mlp_dropout)
+        self.pair_mlp_r = MLP(n_in=self.args.n_encoder_hidden, n_out=n_pair_mlp, dropout=mlp_dropout)
+        self.pair_mlp_b = MLP(n_in=self.args.n_encoder_hidden, n_out=n_pair_mlp, dropout=mlp_dropout)
+        self.label_mlp_l = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=mlp_dropout)
+        self.label_mlp_r = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=mlp_dropout)
+
+        self.span_attn = Biaffine(n_in=n_span_mlp, bias_x=True, bias_y=False)
+        self.pair_attn = Triaffine(n_in=n_pair_mlp, bias_x=True, bias_y=False)
+        self.label_attn = Biaffine(n_in=n_label_mlp, n_out=n_labels, bias_x=True, bias_y=True)
+        self.inference = (ConstituencyMFVI if inference == 'mfvi' else ConstituencyLBP)(max_iter)
+        self.criterion = nn.CrossEntropyLoss()
+
+    def forward(self, words, feats):
+        r"""
+        Args:
+            words (~torch.LongTensor): ``[batch_size, seq_len]``.
+                Word indices.
+            feats (List[~torch.LongTensor]):
+                A list of feat indices.
+                The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``,
+                or ``[batch_size, seq_len]`` otherwise.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor, ~torch.Tensor:
+                Scores of all possible constituents (``[batch_size, seq_len, seq_len]``),
+                second-order triples (``[batch_size, seq_len, seq_len, n_labels]``) and
+                all possible labels on each constituent (``[batch_size, seq_len, seq_len, n_labels]``).
+        """
+
+        x = self.encode(words, feats)
+
+        x_f, x_b = x.chunk(2, -1)
+        x = torch.cat((x_f[:, :-1], x_b[:, 1:]), -1)
+
+        span_l = self.span_mlp_l(x)
+        span_r = self.span_mlp_r(x)
+        pair_l = self.pair_mlp_l(x)
+        pair_r = self.pair_mlp_r(x)
+        pair_b = self.pair_mlp_b(x)
+        label_l = self.label_mlp_l(x)
+        label_r = self.label_mlp_r(x)
+
+        # [batch_size, seq_len, seq_len]
+        s_span = self.span_attn(span_l, span_r)
+        s_pair = self.pair_attn(pair_l, pair_r, pair_b).permute(0, 3, 1, 2)
+        # [batch_size, seq_len, seq_len, n_labels]
+        s_label = self.label_attn(label_l, label_r).permute(0, 2, 3, 1)
+
+        return s_span, s_pair, s_label
+
+    def loss(self, s_span, s_pair, s_label, charts, mask):
+        r"""
+        Args:
+            s_span (~torch.Tensor): ``[batch_size, seq_len, seq_len]``.
+                Scores of all constituents.
+            s_pair (~torch.Tensor): ``[batch_size, seq_len, seq_len, seq_len]``.
+                Scores of second-order triples.
+            s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``.
+                Scores of all constituent labels.
+            charts (~torch.LongTensor): ``[batch_size, seq_len, seq_len]``.
+                The tensor of gold-standard labels. Positions without labels are filled with -1.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``.
+                The mask for covering the unpadded tokens in each chart.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor:
+                The training loss and marginals of shape ``[batch_size, seq_len, seq_len]``.
+        """
+
+        span_mask = charts.ge(0) & mask
+        span_loss, span_probs = self.inference((s_span, s_pair), mask, span_mask)
+        label_loss = self.criterion(s_label[span_mask], charts[span_mask])
+        loss = self.args.interpolation * label_loss + (1 - self.args.interpolation) * span_loss
+
+        return loss, span_probs
+
+    def decode(self, s_span, s_label, mask):
+        r"""
+        Args:
+            s_span (~torch.Tensor): ``[batch_size, seq_len, seq_len]``.
+                Scores of all constituents.
+            s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``.
+                Scores of all constituent labels.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``.
+                The mask for covering the unpadded tokens in each chart.
+
+        Returns:
+            List[List[Tuple]]:
+                Sequences of factorized labeled trees.
+        """
+
+        span_preds = ConstituencyCRF(s_span, mask[:, 0].sum(-1)).argmax
+        label_preds = s_label.argmax(-1).tolist()
+        return [[(i, j, labels[i][j]) for i, j in spans] for spans, labels in zip(span_preds, label_preds)]
diff --git a/tania_scripts/supar/models/const/vi/parser.py b/tania_scripts/supar/models/const/vi/parser.py
new file mode 100644
index 0000000..5721a9d
--- /dev/null
+++ b/tania_scripts/supar/models/const/vi/parser.py
@@ -0,0 +1,108 @@
+# -*- coding: utf-8 -*-
+
+from typing import Dict, Iterable, Set, Union
+
+import torch
+
+from supar.models.const.crf.parser import CRFConstituencyParser
+from supar.models.const.crf.transform import Tree
+from supar.models.const.vi.model import VIConstituencyModel
+from supar.utils import Config
+from supar.utils.logging import get_logger
+from supar.utils.metric import SpanMetric
+from supar.utils.transform import Batch
+
+logger = get_logger(__name__)
+
+
+class VIConstituencyParser(CRFConstituencyParser):
+    r"""
+    The implementation of Constituency Parser using variational inference.
+    """
+
+    NAME = 'vi-constituency'
+    MODEL = VIConstituencyModel
+
+    def train(
+        self,
+        train,
+        dev,
+        test,
+        epochs: int = 1000,
+        patience: int = 100,
+        batch_size: int = 5000,
+        update_steps: int = 1,
+        buckets: int = 32, workers: int = 0, amp: bool = False, cache: bool = False,
+        delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''},
+        equal: Dict = {'ADVP': 'PRT'},
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().train(**Config().update(locals()))
+
+    def evaluate(
+        self,
+        data: Union[str, Iterable],
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        delete: Set = {'TOP', 'S1', '-NONE-', ',', ':', '``', "''", '.', '?', '!', ''},
+        equal: Dict = {'ADVP': 'PRT'},
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().evaluate(**Config().update(locals()))
+
+    def predict(
+        self,
+        data: Union[str, Iterable],
+        pred: str = None,
+        lang: str = None,
+        prob: bool = False,
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().predict(**Config().update(locals()))
+
+    def train_step(self, batch: Batch) -> torch.Tensor:
+        words, *feats, _, charts = batch
+        mask = batch.mask[:, 1:]
+        mask = (mask.unsqueeze(1) & mask.unsqueeze(2)).triu_(1)
+        s_span, s_pair, s_label = self.model(words, feats)
+        loss, _ = self.model.loss(s_span, s_pair, s_label, charts, mask)
+        return loss
+
+    @torch.no_grad()
+    def eval_step(self, batch: Batch) -> SpanMetric:
+        words, *feats, trees, charts = batch
+        mask = batch.mask[:, 1:]
+        mask = (mask.unsqueeze(1) & mask.unsqueeze(2)).triu_(1)
+        s_span, s_pair, s_label = self.model(words, feats)
+        loss, s_span = self.model.loss(s_span, s_pair, s_label, charts, mask)
+        chart_preds = self.model.decode(s_span, s_label, mask)
+        preds = [Tree.build(tree, [(i, j, self.CHART.vocab[label]) for i, j, label in chart])
+                 for tree, chart in zip(trees, chart_preds)]
+        return SpanMetric(loss,
+                          [Tree.factorize(tree, self.args.delete, self.args.equal) for tree in preds],
+                          [Tree.factorize(tree, self.args.delete, self.args.equal) for tree in trees])
+
+    @torch.no_grad()
+    def pred_step(self, batch: Batch) -> Batch:
+        words, *feats, trees = batch
+        mask, lens = batch.mask[:, 1:], batch.lens - 2
+        mask = (mask.unsqueeze(1) & mask.unsqueeze(2)).triu_(1)
+        s_span, s_pair, s_label = self.model(words, feats)
+        s_span = self.model.inference((s_span, s_pair), mask)
+        chart_preds = self.model.decode(s_span, s_label, mask)
+        batch.trees = [Tree.build(tree, [(i, j, self.CHART.vocab[label]) for i, j, label in chart])
+                       for tree, chart in zip(trees, chart_preds)]
+        if self.args.prob:
+            batch.probs = [prob[:i-1, 1:i].cpu() for i, prob in zip(lens, s_span)]
+        return batch
diff --git a/tania_scripts/supar/models/dep/__init__.py b/tania_scripts/supar/models/dep/__init__.py
new file mode 100644
index 0000000..aad5357
--- /dev/null
+++ b/tania_scripts/supar/models/dep/__init__.py
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+
+from .biaffine import BiaffineDependencyModel, BiaffineDependencyParser
+from .crf import CRFDependencyModel, CRFDependencyParser
+from .crf2o import CRF2oDependencyModel, CRF2oDependencyParser
+from .vi import VIDependencyModel, VIDependencyParser
+from .sl import SLDependencyModel, SLDependencyParser
+from .eager import ArcEagerDependencyModel, ArcEagerDependencyParser
+
+__all__ = ['BiaffineDependencyModel', 'BiaffineDependencyParser',
+           'CRFDependencyModel', 'CRFDependencyParser',
+           'CRF2oDependencyModel', 'CRF2oDependencyParser',
+           'VIDependencyModel', 'VIDependencyParser',
+           'SLDependencyModel', 'SLDependencyParser',
+           'ArcEagerDependencyModel', 'ArcEagerDependencyParser']
diff --git a/tania_scripts/supar/models/dep/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/dep/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7861152ee2c2a8276035f9246170cd9dc9cc615c
GIT binary patch
literal 723
zcmd1j<>g{vU|`^9UzGlyiGkrUh=Yuo7#J8F7#J9ea~K#HQW#Pga~N_NqZo6UqL>&#
ze5M@cT$U)7T-GR7FrPVxEtfrtJ(nYj1I%a1;mqZV;>zWY;s*0sb9i!jqj+=qqWHjk
zwjBOkfhd7o!6-pShIED$_C<_QLMa@<44RxT85tNDG?{LRJ7p%OrDf)&x}+AQ=B1?O
zC0F|9r=;fGlE9P*NGvK&Ez)GVCFC6BhOS;1MGUS~#5u^#C?8$1D4Hl-xnP(lx>_M*
zA%wzU9}I=aLU4uRjz!6?iRr0D=*lH9C7_ykia-%l#LU3JP{aZvSV06Eh+qd193X-d
zM1Z2Vh#SP>0TH|m3=Dpn!nZh*pn-}o=oWKwQ5wRuDAwenG^6|?xS_Y0$})@K2H#>T
z&MAT$ev35~<bfi%9k<xy;}dgo;^S8`6p4T=1`)rU^fU5vQ}s&{OEMGl67`aD5>ql$
zi}aK8a|`ly(+f&;b3qZSUtC&{SfmeT7we~_7U;*vXXa&=#K-FuRNmsS$<0qG%}KQb
TC68i01_lNJCILnm<Y58;EAhg|

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/dep/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e046f387fd327180d2c8a0e599fbf49639f9884c
GIT binary patch
literal 902
zcmZ3^%ge>Uz`&q%Up3=B69dCz5C?{tpp4IX3=9m@8B!Qh7;_kM8KW3;nWC5&L42kh
z=3JI2mR!~-RxqDAhb@;qianPjiUZ7N$>Gf9isH)Uj^YOMS#x-Dd82r9`J(v1e6}3^
zT!AQoT)`+oMuv2T6!t}oQ9>yk!3>(5FBusa7&Mt~i92N`rln=(rMjdRq~@ih<|SA9
z=BK3Q+>*eQ2uLg{PA$@8x+UZs<c6+Z7)1=ORKz*R%_tvTu_&4-T)AMFC%Rf8WFdsY
zU>^*H$U<<1;*Lehu8HZXMd->UFeRXxc#4=A7#NCJKm;p@U;`2CAc6x#aDoU>ycThT
zSUezt7ew$eFfjOO3g6;Lf(9zWpj*tzMQKHF({8aQ7o{2H7r_m^#Z;DA1UL8=Q*jQ$
z@LQ~@AP*G5?YPArAD@_$6Cb~l;WH=^{R+^}$j?pHFG(!POw3EvOUg-1$xJQMPtMOR
z$k#1Nttin=ElbSNFG<YHOpGs1F3Kz@Db_D8El4cV&jrPHv3^Qwfqr~^W?p7Ve7s&k
z<u4AK-29Z%oK(9aNd^W6P+}?Gz`(%pftit!@dFzJqX**!26s$!gTdkgHgto*?gBP+
jgTeFyHiTQ;<pKj1^nrzy+llc51A=T|2f-q71_lNI{1pWG

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/biaffine/__init__.py b/tania_scripts/supar/models/dep/biaffine/__init__.py
new file mode 100644
index 0000000..d757c65
--- /dev/null
+++ b/tania_scripts/supar/models/dep/biaffine/__init__.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+
+from .model import BiaffineDependencyModel
+from .parser import BiaffineDependencyParser
+
+__all__ = ['BiaffineDependencyModel', 'BiaffineDependencyParser']
diff --git a/tania_scripts/supar/models/dep/biaffine/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/dep/biaffine/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a03c15f409c6cb82e0c38e8de1c728163143075d
GIT binary patch
literal 305
zcmd1j<>g{vU|`^9UzEOufq~&Mh=Yuo7#J8F7#J9eRTvl;QW#Pga~N_NqZk=MY^EHh
zT;?cdMursT6qa<RD3%n~U<OULmy8Sy44RC$#GNt|)6z2YQe9FDQu9($^O7rl^HWlD
zG#PJ6U`hof78R!!6@lz4VrF1q@Y7_y#hMFJ4;H({Rsc}|lDowoAD@_$6Cb~lp@^M<
z0Yd!p*3Zb#P1P?+EXhpFOVmrsNleL1Ez(cU&n?K;O)n_X1)HW{Tw0J=qz`5n>!+j^
s=qEv)sUIJonU`4-AFo$Xd5gm)H$SB`C)Ez*nPN5u1_mA`9!4G}0KsxlF8}}l

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/biaffine/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/dep/biaffine/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6cc85e00431ce55159ade848598530026f4c870f
GIT binary patch
literal 374
zcmZ3^%ge>Uz`&q%Uo~S30|Ucj5C?{tpp4II3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI
zW=4h-<`kB6rYM#a)?fxrwwH_y3=Eo#x5S+?6VuW%^HN<>3sUn^QuC54ee+XNb2J%m
zNnlC^Bo-B?78NlwFfbIcFfcIqX|mp8%>}6ki``-?fG7aT-C~cAPt3`Qk6+2~8RWuW
zk@^|=xvBaki6xndd5L;SIf*HmsYUw9`MCx8x+SR<CAz6)i8=ZuiFuic@x{qSnFS@q
z`o*OMiADNgD~k0~QVaBxpzhU=kI&4@EQycTE2#X%VUwGmQks)$SH#W0zyR`Eu@wUY
s!v|(YM#c|p42;?r7_^Yl4F;VHsOSN=$^|ut3tWy3>>yag$-uw>067+FcmMzZ

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/biaffine/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/dep/biaffine/__pycache__/model.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7c463ffc47a61e67f929c1d390efdc163db1ecc9
GIT binary patch
literal 10021
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
ISCt~n0A#*l(EtDd

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/biaffine/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/dep/biaffine/__pycache__/model.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ec57b786c69963f7b6418e915051312869bea45f
GIT binary patch
literal 12885
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/biaffine/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/dep/biaffine/__pycache__/parser.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0a161c0ca80e6f499166fc7e4f195252909a9dc8
GIT binary patch
literal 8024
zcmd1j<>g{vU|`^9UzEOFo`K;ph=Yt-7#J8F7#J9eZ!j=0q%fo~<}gHoXr>&-T&5_d
zT;?cdMi8Gdhb4+7g&~DGhc%ZiiVZBrlEa?M5yb&!v*vK-az$~0*=#x7xja!kxx7)l
zxqMN4U@`U_{#=15fn32T!CavzA+Q)nj&QC>lt`{<lxVJ4lo(iyGe<mEB1!_x=E{-G
zm5P!Av$=Dmb7i7rz-*oz*<86OIWU_yM?O~}N`a9fRVr1nnK4SqogsxUg};R%g+G<6
znK?>1g)x{xQ{W}Y&wiRrw>UgYQi~Fka#C-xhUR7F=V>zD5_if>OiRnmOLa*tNX<)0
z%}cKI%}+_q(PX^E>YVTA<D<!Vi!C6rs5rGqllc~#bADc0X8J95m&B69;?$B`oUXY^
zsVOO$dFh(Wx0s#$gKsehIJ(?o4)ycaWWL4fmYJH9a*HD<u^htU2`)`4&o4>=^E4T6
zv1b++l;$OuXfod7N>43`&&f|uPc719yd~gRQj(aQk(-)V;+tAhl$or_cuORtC^4@%
zEx#x?wJ0P%J2fw}3apmZDX}CuBN^mLWUL6~6mMf>U`S<%VoYI(VoG6*VoqU-Vo7C<
zVryqeV@zRAVQJxrV&`P#WaDJ#<lyAw<l^K;f;=gvDZHs1shp`?X-tv~DSSw5ek8U)
zDtC%tDtC%dDtC%-DtC%VDtC%#DtC%lDo=`dDo=_;Do=`JDo=`3Do=`ZDo=_`Do>gM
z*afmFaxJ`3yqxTu@^HI(z%JlPF-uWEvIAr`G3JVa%~ecMYT=FI<5cEU=Hx~)9b`67
ziaCnODyf_)s;QhQYN<S6AE4U;b2-S>5@6HSQ#4w5qxe%aQw37AQU$Yw(pXZoQ*>Hb
zqJ&cg7l<rmfXaxbv83px=(VskGe(J_$Oxpdr0Ay@fMvu}B~mO>j8jZn7@HZRB-<HS
z7^0+t88j_#NnoZ=NNTK#;ZjggPzcFLRmjXO$VmkymBf<F{5*yHGzFL@1w^V=fM`>&
zO3o}vwMt0IuSzV@O)W{x(KRwKG}ldnW`hJhu(4IbFag~Zc*aO(geEBv#mvCK04hKD
zLFI=T0|P?|Lo-7bV+~^_Lk-gs#y&<yh8l(}rYz<fhIke*ixo_=F)`IJ#Ix5h#B-!D
z1T(B;^wZ?L#adiikXm$$BR)PeFS8^*{uXBmEUn*SaSi}ws}M)`TPz-~jxM*@TwDW!
zTzzgaI|e!5Vh(ck(PX~GQk<HTc8evkD82X=TXs2!UdeciGd?~!C$YFVK7J*`FHil9
z{M=OilEjkC#Johkq@2W*%+w<N<ow)%eBJbd65U)-zSl1<El4cV2eXUyQ&J1`VF96E
z04@de3Mz{v7#JAjLH=fAU|<kp<YJOytWt!9IU>j*A+87W)XNvl3=A(*7#J8{b_g>t
zyaa{jO9ci7h9VHlE#ww!Nl{{E-Yw>o)UsPFC8@<Fx7bn(@{==)Z*dePmSm>pC8yrv
zN&;o}_~Oi})LT5I1u2Oosqw`nsRhNi*po_=vr|ioZ?Tu>7iFgw72je`%q_UZnw*%N
zk$Q_2T+ZBLDJe=#y~R>cl%I8ry&$ouBr`GR7JFH0QBr<!YO)|GVxd@wfq?<!J#GdD
zhR-ta_)THVWGG>3W>~;n!qUvJkP#Hq!3-;z{EAc=7#K8Ji^M@5(g6|d3=9mn*dT7a
z#g>zwoS0LrDO3dZF<5~vNR=Ll&<7C)Ai@wt7=Z|55Mcr$OhE)Fi4~cHSQa3{5=2;m
z2x}0b1R|6{1jrdhY9JQK4iK-HiGhJZMx;s(XAFVE{Ury;y(}q-C5g#A&_DoDyhs62
zWCJqT7U9!d9I0iAIi-musYM{~7TJO1?LqRq5RW>71i+r6*gsAT3=AO8Lj1#zC&j_s
z<OhoB)RbE+If;4cAa;IIGRQk1Z-Fo$Uazqi6s4wQCYPZ5j1S3Y&LHo(fCyI*fzzXi
zI0N~h2wQZyF)%RrfHD<0x&*4=g&0PLg1YM#D>yIQVk=55DJ{xN2I&L&3WPza78IW#
z_Z5dQFfi0GPGE{-s%5HWu4SoZt!1lW%wnizPhqTKPhm)5Xk|)aOk=WPs9{*ZSi@Aq
zvXCi;sg|RbvxXsyaRE~eM-68UYYkfsdksSta~8`&wpy+lu3!dDCO>f2)nvWJlABnZ
zeTx-bY}{hW$uBN00@c4opcJaf4GA!JQ2Js8RsY4e7~^lTrlls96obmF<l<W_MX5Q(
zMV??4#qo(n$+uXG<BL*rio8L=3QEP``~^<fx46LR6`bwkKmi6ytpbc}i~>voj8cp&
zj8)3`Q#x2DN^pS^1w6Qp&?2}%0m%vuNJt>EfrFBLA!`g%Eq5&sn8#A&T*F?&x_~2v
zaUr8GLoGxlXK{E9`vR^S_8RsD+$l^c%q<Kxj9EM`49$!S8TlC&GBGlg@YZnEaM$pp
zF@d5fjj4vcnI)J(lLZnz7}XXl0|P@aDBwUvQ945nLo81%BPc<*FvPOeGL<maFf}ty
zWG-YcWC~^ghr1?I5h!UE34n4o^DQPlgIkQnw;0R8k`Mw^<lN%2$;m7(0aYn>B_Inx
zNm7BK$_!_GfO0B0I`nKH1*DxG!U#=1aEd7M0;K_PLV%~KTWl$*$@wX%MevMuizz)7
zTt4372c^Z-l=$N0#FCQKqWD`}d8y^`C8>GE`9-%li&OJTKs8Bm5vYXMgcehvv<dN|
zFUT@K5aACZ0zd>PT^0p`SV15H<dj>SiABlrpqyBIi?b*-2f~B|1vt5a!-Es<zjRP=
zh%qoQ2r$7CssbYiBOfCNlLDg{W0ex&AVNv8pbQQwaY4<HVn~XGWp7YS)-Yx<rZ7q{
zEMQv5z{CW~@F`3+tkA5^1j_0i3=5dyS)IL>qk|!fc>zledkseoYX?IXYZe=rgrrc;
zS}t%)nE_M~NHQ$os9{^k2ugu9jPab{_8=>$9bLm!!-^)$1vZ7dC?SO{g{6g|ga=fN
zEZ|LHU&y$CZy`f76Vw#`8c<h-!>>pS6vChe0ZOt3B_vR53!H347#JA9$(9Y2Y!@&r
zWSGc=NUDst*h=z2$#5l85vb(5#h8f}Ek)rB3=H+42mu)@f-il7A{b}-#Bd=fV+n)I
z1+^EzF663Z>|n?Ow+lg0A&KHr<|0rd>K1EResW?`Q3A;0i3|)3D;Xi>B|I5{-P-^%
z7vx?U1{8Zi2>_H3z##)_LV)cRiD9Z`tYxZUN@1vBOkofQm+&was3U_2HBBaPnEPom
z-eOKJDAi;Jhgwk*$T{Fj4eSmu0ZP+g$27qlW5Dq8|NsC0H3h&q^%hG`YF;tKC*VvQ
z0Wt)fX%YF9wYVTBv!n=-yFixQVy?<8xW!(apH`BaSaFN3G%qPLFXa|%K~a8EF>(ch
zo=L%36O_4-@@Fi_R#43ViFZ(o6H;+-!lSbs<N;7R;$jj5*Bc6qQjBtp9E=K}`U7`n
zgd6Y@6csN)CM1K>C8*8?VNjU@s*XU}v)F(c)GJ6)%w#BGY-Rwp6l+;an6j8ln6g+F
zu+}gxWGoO&VFVTFy`VxIB+3R7Epn`3&0;ThtYOIF0O_t_1?vS>8Ju7~TNW2cq=qe?
zyM`@`djU@kTNZB?UkZyPLl*x+#sva3Y*~T}K|K(*V1^Q*1;Qz;AYKYv3`;FLs9vw-
zs$tC%Nny`sD#|Potzpd)Yi6wFE)h@RsNv3%sNv3%tl`d*s$tENuHjDM>}Bg@sNv3%
z>0pSL$qOryP2nh!E0HfzNMTCh>SgU@Na3zw%~C95D5@=yP2nj~Na5{es%1~%gNpW)
zh^O#Fbbw4u5$I*D<wy~P$}Ub}NfF9X%2n=UWMn8&NfB&jtmSNHXlG1gN)b*GY2m2h
zj8{!zhpOI>;#zj>uC3()xweKYUZzAPMYNf*mZwBEMXW?2MZ82UOFc!Rm!+1sL^eed
z>QcTEwGM_F9&qK%mBw1bUc+0%mm<~6Qp;bWQNv%unx&b>l*s^%1p#QtF;8GD67OJG
zz+M9q(W+t1;xGDJqP>6v#9GLh$Cx6WB9kK0!myBqk)eh?MY@!60%H+x4Le8&C^l+1
zpkm@R9B?r{IE!_G4%8;535-RWCAu99Su)LxdCVX>ORq$?h7ZJtn`~90Tf+_#0oe>U
z+qFcuh66*?uZAN_AFPfG>W1(dE{I46LzaFALzY1YLzZER>>N&zOF=29hJQ8#jGZC}
zV%0EYK~f_)buQp3G3sDQk#7dMwyuLAiyvhELdIG_ux`QG3@Hk8nIQUVSZf4p_?ww)
z*}$n6CADfQC2nM5U;uZ*LH&ED(#)I`g+zs<qQtxu-MrLtXg^*@Au}&IrxY~uqyXwO
zXC~%kR>AxKi8(n6DTyVC3TdDLsA7f0yc7j++f<<-u_!S&wIsEuSdR;CiDOZEu@#&L
zvbG?xBtt=?xTHuERU9M-8gc;3=cg%@WTZk3F3DF&N>wOMEK5y+3?YD&f^cqTUVK_n
zY9T)3ax?QXb4zm-K<Y|CV{i(2si`TcDGDX|P=BT>Br25TXQ$>VWafcw1y>rSIf+G;
zsMdk33`#95%`8eyQOHbFC`ruD%u81QH@g)QixpDy!0jf5%)Elq5=^ZwscDI&IVDyK
zMyPUWnHBLlsd)+-nRz8R!X!7bLLnzLFTErKGz0^Rf?~*MpF%-qYI16^9(b@OwIVsS
zxEK@<B_L&~iOCrdd4=-KoE%UXmK2rdB`21kha<YjN{d1Ma?VIB@(B*{)pv3Y3PE);
zNCUz<2B?ydF%kt0m&{~r{&7?Q_52hv@^io`3>3|!dCB>C#ihBaDGG^2>7}6YrecJd
zRZM#NA)1W0I8rMzi%a73v%x*1Dq(Q?1vwOC1SB<TviSM=`Q2hkN-Zh@S7(~6x0nkO
zQ*JSr=4IbvPRcL7#SRVbTO8mx&#X$-WGN~FRcpl{0@Sv?#hQ~}o?3K^xg;_D7E4KD
zda)*B5m<sHIU}*?7AuG>#?V$&3hHCAq~_%2Yck&A0rw!|OY-A0Q;JcV6`&RvsA&Oi
z&VZWz9gH;$&5R2eIvBDT7cvGj6oDGEnoPHtO7cOC@v_Y1)Rm047%NsX-C_y%4{|B0
z1-TU7Y`Dc?larX6l#*z-0aW#ZYEJ=%Dg&IY-Xu`INA46rG~Z$^Nv$X;2DcvEG?^hD
z<}58vjR)t4TTE$rMW80TCd(}rH~%2tA}Nq7K+UltSq26MKMX&DDsOPp2{aZ^!%zb1
z05dFPlx9HqkhLVgC^_R6b8$&Z5vUagX;r{|R@B14z_17ADLw{G&Rgtx@!<S+i!Be-
zi7f`vpcn#4fTQIWABc)CNKA>(%u7kFxWxxb3`l%VgcN6KUN%$}XHtGKgjpqolCZ#K
z+bz~q&|v&6MlP@mHH{$y7ogFYTTJ=Iw>WYWvr|(ti;8ctfQqkM>?xT=d5O8Hx7fgG
zw)hq+IM6}e_r#Q2tiJv(u0D`nJg6;qi$5nnF$L7k0r$RBQ;H-(LE8Z$rhte#5CLjc
zgT}f*!}zyYGV{{%Z?Qv5oFY(CDk=o20*#rXC1-HDECLPU7lAtCMW6;$5vV0q1e(IR
z#R3{ExFwpHlard4ms6mZo1apelUl3?O2?3t28zF1?4Yh^esO9Ms3m@j12m<OSd?5`
z1nS!tfyTpbalne>B2JJ?K;u=nm~&F|Kv4v$M~WtbgeQTB$)KFVo{?CbSW;4?DRhfD
zIj6X221sTZhyZ0I$UqLLfqRP$GCW!&4bsKp?BN)6i^bK)*Z&p^sARguSaORc#5E$M
zNDibI)b59bAIMRV4lX!Bfg0A}wrbIA1_p*!P^u~bbs9ya7=;)G7)2Q67+Dy(n0Oeu
z7`Yf_7`YgQn79~0JP}3^&A})DmEmCIU=(8HVU%JNVd7!b0E>e3a51tl$}n;;iZO~Y
z3NZ>XvVbAScOGsoCJjabMjj?UPzxCMSRpu#Xz~`RgZ!ZZA~Zn+xZ9=;Vu4ByH!uj%
z<SGJ7g67!3<)NFKTZo%mh$gq6pBsi$h+BvzQ&AqsjC{~IgEVM79F#!g<8N`r$3vn#
zKK>R@e0*VPVh&V>Jw84qKRG`B7K@*wuWJz~KNrmfnE@K4E&>%{pqyJ&1S)ZEF=ytL
z++s<}&(8s;h9c0AVi9QItq9bTFX{xv9a~5$Xr!PBR4UwJ&&!WbFG@@S4;B=~gUrnZ
zDdGl?tLLVcWaOuSqv{qfbgVr&H76%N9-IRq1b9>y+;b9TU|;|Z4;TMqU|`^2U}0oo
zVPWK9V&Z0E#12{Bb1^af<6>s|%f-U<hl!QxHxnDvFD7=TpG+J~KbSa~zB6$#ePiNg
z`pU$^^o5C+=`#}_(<df=rjJYlOdps8`Q9^0Vw%kI1!O7{Gt*xtf~N9)VG_YKfr*jj
zGx27CT*miVM2L-3gprM3gpr9?gs}(|7MdzW(?EgAR#I7znU@ZZB5;g>BO*#3JQV@T
z>Zv)!dMT*|da$Voh!{AoZz<ze1)oEK6bC#ImC$_32C|tOB2-$EnNtiYEx{!PsA#w)
zge0ezoS&PUp9e0B5JgjzAhHs0<qj#lKxI)8sF1tGhoT}6Jb-pf7+DZB<q7gUXzn2j
z#m-#t#3wlA-4aFC0&5c#fs0f$IoP}rBt>rorP%o(0u<no1PLx^zyv5&-r}%<<SaW-
f#w`X7334zAFmf>QF!3<*Fp7X7hy}qMOd`wx6TPrY

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/biaffine/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/dep/biaffine/__pycache__/parser.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..41daea0ef2c2181fcba2b5fbf9a540eded84891b
GIT binary patch
literal 14692
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
O2$uN*CNWikV*&uma3O2}

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/biaffine/__pycache__/transform.cpython-310.pyc b/tania_scripts/supar/models/dep/biaffine/__pycache__/transform.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a172f6c96a8bba92e2b94ef264d11b820f66f204
GIT binary patch
literal 16984
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/biaffine/__pycache__/transform.cpython-311.pyc b/tania_scripts/supar/models/dep/biaffine/__pycache__/transform.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0b880c597dadc460d71c38295eb68e34d01977a2
GIT binary patch
literal 24798
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
P@ewTZ1x#Y90*5UC3;Bf3

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/biaffine/model.py b/tania_scripts/supar/models/dep/biaffine/model.py
new file mode 100644
index 0000000..14420cb
--- /dev/null
+++ b/tania_scripts/supar/models/dep/biaffine/model.py
@@ -0,0 +1,234 @@
+# -*- coding: utf-8 -*-
+
+import torch
+import torch.nn as nn
+from supar.model import Model
+from supar.models.dep.biaffine.transform import CoNLL
+from supar.modules import MLP, Biaffine
+from supar.structs import DependencyCRF, MatrixTree
+from supar.utils import Config
+from supar.utils.common import MIN
+
+
+class BiaffineDependencyModel(Model):
+    r"""
+    The implementation of Biaffine Dependency Parser :cite:`dozat-etal-2017-biaffine`.
+
+    Args:
+        n_words (int):
+            The size of the word vocabulary.
+        n_rels (int):
+            The number of labels in the treebank.
+        n_tags (int):
+            The number of POS tags, required if POS tag embeddings are used. Default: ``None``.
+        n_chars (int):
+            The number of characters, required if character-level representations are used. Default: ``None``.
+        encoder (str):
+            Encoder to use.
+            ``'lstm'``: BiLSTM encoder.
+            ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``.
+            Default: ``'lstm'``.
+        feat (List[str]):
+            Additional features to use, required if ``encoder='lstm'``.
+            ``'tag'``: POS tag embeddings.
+            ``'char'``: Character-level representations extracted by CharLSTM.
+            ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible.
+            Default: [``'char'``].
+        n_embed (int):
+            The size of word embeddings. Default: 100.
+        n_pretrained (int):
+            The size of pretrained word embeddings. Default: 100.
+        n_feat_embed (int):
+            The size of feature representations. Default: 100.
+        n_char_embed (int):
+            The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50.
+        n_char_hidden (int):
+            The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100.
+        char_pad_index (int):
+            The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0.
+        elmo (str):
+            Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``.
+        elmo_bos_eos (Tuple[bool]):
+            A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs.
+            Default: ``(True, False)``.
+        bert (str):
+            Specifies which kind of language model to use, e.g., ``'bert-base-cased'``.
+            This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_.
+            Default: ``None``.
+        n_bert_layers (int):
+            Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features.
+            The final outputs would be weighted sum of the hidden states of these layers.
+            Default: 4.
+        mix_dropout (float):
+            The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0.
+        bert_pooling (str):
+            Pooling way to get token embeddings.
+            ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all.
+            Default: ``mean``.
+        bert_pad_index (int):
+            The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features.
+            Default: 0.
+        finetune (bool):
+            If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``.
+        n_plm_embed (int):
+            The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0.
+        embed_dropout (float):
+            The dropout ratio of input embeddings. Default: .33.
+        n_encoder_hidden (int):
+            The size of encoder hidden states. Default: 800.
+        n_encoder_layers (int):
+            The number of encoder layers. Default: 3.
+        encoder_dropout (float):
+            The dropout ratio of encoder layer. Default: .33.
+        n_arc_mlp (int):
+            Arc MLP size. Default: 500.
+        n_rel_mlp  (int):
+            Label MLP size. Default: 100.
+        mlp_dropout (float):
+            The dropout ratio of MLP layers. Default: .33.
+        scale (float):
+            Scaling factor for affine scores. Default: 0.
+        pad_index (int):
+            The index of the padding token in the word vocabulary. Default: 0.
+        unk_index (int):
+            The index of the unknown token in the word vocabulary. Default: 1.
+
+    .. _transformers:
+        https://github.com/huggingface/transformers
+    """
+
+    def __init__(self,
+                 n_words,
+                 n_rels,
+                 n_tags=None,
+                 n_chars=None,
+                 encoder='lstm',
+                 feat=['tag', 'char'],
+                 n_embed=100,
+                 n_pretrained=100,
+                 n_feat_embed=100,
+                 n_char_embed=50,
+                 n_char_hidden=100,
+                 char_pad_index=0,
+                 elmo='original_5b',
+                 elmo_bos_eos=(True, False),
+                 bert=None,
+                 n_bert_layers=4,
+                 mix_dropout=.0,
+                 bert_pooling='mean',
+                 bert_pad_index=0,
+                 finetune=False,
+                 n_plm_embed=0,
+                 embed_dropout=.33,
+                 n_encoder_hidden=800,
+                 n_encoder_layers=3,
+                 encoder_dropout=.33,
+                 n_arc_mlp=500,
+                 n_rel_mlp=100,
+                 mlp_dropout=.33,
+                 scale=0,
+                 pad_index=0,
+                 unk_index=1,
+                 **kwargs):
+        super().__init__(**Config().update(locals()))
+
+        self.arc_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_arc_mlp, dropout=mlp_dropout)
+        self.arc_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_arc_mlp, dropout=mlp_dropout)
+        self.rel_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_rel_mlp, dropout=mlp_dropout)
+        self.rel_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_rel_mlp, dropout=mlp_dropout)
+
+        self.arc_attn = Biaffine(n_in=n_arc_mlp, scale=scale, bias_x=True, bias_y=False)
+        self.rel_attn = Biaffine(n_in=n_rel_mlp, n_out=n_rels, bias_x=True, bias_y=True)
+        self.criterion = nn.CrossEntropyLoss()
+
+    def forward(self, words, feats=None):
+        r"""
+        Args:
+            words (~torch.LongTensor): ``[batch_size, seq_len]``.
+                Word indices.
+            feats (List[~torch.LongTensor]):
+                A list of feat indices.
+                The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``,
+                or ``[batch_size, seq_len]`` otherwise.
+                Default: ``None``.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor:
+                The first tensor of shape ``[batch_size, seq_len, seq_len]`` holds scores of all possible arcs.
+                The second of shape ``[batch_size, seq_len, seq_len, n_labels]`` holds
+                scores of all possible labels on each arc.
+        """
+
+        x = self.encode(words, feats)
+        mask = words.ne(self.args.pad_index) if len(words.shape) < 3 else words.ne(self.args.pad_index).any(-1)
+
+        arc_d = self.arc_mlp_d(x)
+        arc_h = self.arc_mlp_h(x)
+        rel_d = self.rel_mlp_d(x)
+        rel_h = self.rel_mlp_h(x)
+
+        # [batch_size, seq_len, seq_len]
+        s_arc = self.arc_attn(arc_d, arc_h).masked_fill_(~mask.unsqueeze(1), MIN)
+        # [batch_size, seq_len, seq_len, n_rels]
+        s_rel = self.rel_attn(rel_d, rel_h).permute(0, 2, 3, 1)
+
+        return s_arc, s_rel
+
+    def loss(self, s_arc, s_rel, arcs, rels, mask, partial=False):
+        r"""
+        Args:
+            s_arc (~torch.Tensor): ``[batch_size, seq_len, seq_len]``.
+                Scores of all possible arcs.
+            s_rel (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``.
+                Scores of all possible labels on each arc.
+            arcs (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The tensor of gold-standard arcs.
+            rels (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The tensor of gold-standard labels.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens.
+            partial (bool):
+                ``True`` denotes the trees are partially annotated. Default: ``False``.
+
+        Returns:
+            ~torch.Tensor:
+                The training loss.
+        """
+
+        if partial:
+            mask = mask & arcs.ge(0)
+        s_arc, arcs = s_arc[mask], arcs[mask]
+        s_rel, rels = s_rel[mask], rels[mask]
+        s_rel = s_rel[torch.arange(len(arcs)), arcs]
+        arc_loss = self.criterion(s_arc, arcs)
+        rel_loss = self.criterion(s_rel, rels)
+
+        return arc_loss + rel_loss
+
+    def decode(self, s_arc, s_rel, mask, tree=False, proj=False):
+        r"""
+        Args:
+            s_arc (~torch.Tensor): ``[batch_size, seq_len, seq_len]``.
+                Scores of all possible arcs.
+            s_rel (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``.
+                Scores of all possible labels on each arc.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens.
+            tree (bool):
+                If ``True``, ensures to output well-formed trees. Default: ``False``.
+            proj (bool):
+                If ``True``, ensures to output projective trees. Default: ``False``.
+
+        Returns:
+            ~torch.LongTensor, ~torch.LongTensor:
+                Predicted arcs and labels of shape ``[batch_size, seq_len]``.
+        """
+
+        lens = mask.sum(1)
+        arc_preds = s_arc.argmax(-1)
+        bad = [not CoNLL.istree(seq[1:i+1], proj) for i, seq in zip(lens.tolist(), arc_preds.tolist())]
+        if tree and any(bad):
+            arc_preds[bad] = (DependencyCRF if proj else MatrixTree)(s_arc[bad], mask[bad].sum(-1)).argmax
+        rel_preds = s_rel.argmax(-1).gather(-1, arc_preds.unsqueeze(-1)).squeeze(-1)
+
+        return arc_preds, rel_preds
diff --git a/tania_scripts/supar/models/dep/biaffine/parser.py b/tania_scripts/supar/models/dep/biaffine/parser.py
new file mode 100644
index 0000000..d7b3093
--- /dev/null
+++ b/tania_scripts/supar/models/dep/biaffine/parser.py
@@ -0,0 +1,213 @@
+# -*- coding: utf-8 -*-
+
+import os
+from typing import Iterable, Union
+
+import torch
+
+from supar.models.dep.biaffine.model import BiaffineDependencyModel
+from supar.models.dep.biaffine.transform import CoNLL
+from supar.parser import Parser
+from supar.utils import Config, Dataset, Embedding
+from supar.utils.common import BOS, PAD, UNK
+from supar.utils.field import Field, RawField, SubwordField
+from supar.utils.fn import ispunct
+from supar.utils.logging import get_logger
+from supar.utils.metric import AttachmentMetric
+from supar.utils.tokenizer import TransformerTokenizer
+from supar.utils.transform import Batch
+
+logger = get_logger(__name__)
+
+
+class BiaffineDependencyParser(Parser):
+    r"""
+    The implementation of Biaffine Dependency Parser :cite:`dozat-etal-2017-biaffine`.
+    """
+
+    NAME = 'biaffine-dependency'
+    MODEL = BiaffineDependencyModel
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self.TAG = self.transform.CPOS
+        self.ARC, self.REL = self.transform.HEAD, self.transform.DEPREL
+
+    def train(
+        self,
+        train: Union[str, Iterable],
+        dev: Union[str, Iterable],
+        test: Union[str, Iterable],
+        epochs: int = 1000,
+        patience: int = 100,
+        batch_size: int = 5000,
+        update_steps: int = 1,
+        buckets: int = 32,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        punct: bool = False,
+        tree: bool = False,
+        proj: bool = False,
+        partial: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().train(**Config().update(locals()))
+
+    def evaluate(
+        self,
+        data: Union[str, Iterable],
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        punct: bool = False,
+        tree: bool = True,
+        proj: bool = False,
+        partial: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().evaluate(**Config().update(locals()))
+
+    def predict(
+        self,
+        data: Union[str, Iterable],
+        pred: str = None,
+        lang: str = None,
+        prob: bool = False,
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        tree: bool = True,
+        proj: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().predict(**Config().update(locals()))
+
+    def train_step(self, batch: Batch) -> torch.Tensor:
+        words, _, *feats, arcs, rels = batch
+        mask = batch.mask
+        # ignore the first token of each sentence
+        mask[:, 0] = 0
+        s_arc, s_rel = self.model(words, feats)
+        loss = self.model.loss(s_arc, s_rel, arcs, rels, mask, self.args.partial)
+        return loss
+
+    @torch.no_grad()
+    def eval_step(self, batch: Batch) -> AttachmentMetric:
+        words, _, *feats, arcs, rels = batch
+        mask = batch.mask
+        # ignore the first token of each sentence
+        mask[:, 0] = 0
+        s_arc, s_rel = self.model(words, feats)
+        loss = self.model.loss(s_arc, s_rel, arcs, rels, mask, self.args.partial)
+        arc_preds, rel_preds = self.model.decode(s_arc, s_rel, mask, self.args.tree, self.args.proj)
+        if self.args.partial:
+            mask &= arcs.ge(0)
+        # ignore all punctuation if not specified
+        if not self.args.punct:
+            mask.masked_scatter_(mask, ~mask.new_tensor([ispunct(w) for s in batch.sentences for w in s.words]))
+        return AttachmentMetric(loss, (arc_preds, rel_preds), (arcs, rels), mask)
+
+    @torch.no_grad()
+    def pred_step(self, batch: Batch) -> Batch:
+        words, _, *feats = batch
+        mask, lens = batch.mask, (batch.lens - 1).tolist()
+        # ignore the first token of each sentence
+        mask[:, 0] = 0
+        s_arc, s_rel = self.model(words, feats)
+        arc_preds, rel_preds = self.model.decode(s_arc, s_rel, mask, self.args.tree, self.args.proj)
+        batch.arcs = [i.tolist() for i in arc_preds[mask].split(lens)]
+        batch.rels = [self.REL.vocab[i.tolist()] for i in rel_preds[mask].split(lens)]
+        if self.args.prob:
+            batch.probs = [prob[1:i+1, :i+1].cpu() for i, prob in zip(lens, s_arc.softmax(-1).unbind())]
+        return batch
+
+    @classmethod
+    def build(cls, path, min_freq=2, fix_len=20, **kwargs):
+        r"""
+        Build a brand-new Parser, including initialization of all data fields and model parameters.
+
+        Args:
+            path (str):
+                The path of the model to be saved.
+            min_freq (str):
+                The minimum frequency needed to include a token in the vocabulary.
+                Required if taking words as encoder input.
+                Default: 2.
+            fix_len (int):
+                The max length of all subword pieces. The excess part of each piece will be truncated.
+                Required if using CharLSTM/BERT.
+                Default: 20.
+            kwargs (Dict):
+                A dict holding the unconsumed arguments.
+        """
+
+        args = Config(**locals())
+        os.makedirs(os.path.dirname(path) or './', exist_ok=True)
+        if os.path.exists(path) and not args.build:
+            parser = cls.load(**args)
+            parser.model = cls.MODEL(**parser.args)
+            parser.model.load_pretrained(parser.transform.FORM[0].embed).to(parser.device)
+            return parser
+
+        logger.info("Building the fields")
+        TAG, CHAR, ELMO, BERT = None, None, None, None
+        if args.encoder == 'bert':
+            t = TransformerTokenizer(args.bert)
+            WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, fix_len=args.fix_len, tokenize=t)
+            WORD.vocab = t.vocab
+        else:
+            WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, lower=True)
+            if 'tag' in args.feat:
+                TAG = Field('tags', bos=BOS)
+            if 'char' in args.feat:
+                CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, fix_len=args.fix_len)
+            if 'elmo' in args.feat:
+                from allennlp.modules.elmo import batch_to_ids
+                ELMO = RawField('elmo')
+                ELMO.compose = lambda x: batch_to_ids(x).to(WORD.device)
+            if 'bert' in args.feat:
+                t = TransformerTokenizer(args.bert)
+                BERT = SubwordField('bert', pad=t.pad, unk=t.unk, bos=t.bos, fix_len=args.fix_len, tokenize=t)
+                BERT.vocab = t.vocab
+        TEXT = RawField('texts')
+        ARC = Field('arcs', bos=BOS, use_vocab=False, fn=CoNLL.get_arcs)
+        REL = Field('rels', bos=BOS)
+        transform = CoNLL(FORM=(WORD, TEXT, CHAR, ELMO, BERT), CPOS=TAG, HEAD=ARC, DEPREL=REL)
+
+        train = Dataset(transform, args.train, **args)
+        if args.encoder != 'bert':
+            WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x))
+            if TAG is not None:
+                TAG.build(train)
+            if CHAR is not None:
+                CHAR.build(train)
+        REL.build(train)
+        args.update({
+            'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init,
+            'n_rels': len(REL.vocab),
+            'n_tags': len(TAG.vocab) if TAG is not None else None,
+            'n_chars': len(CHAR.vocab) if CHAR is not None else None,
+            'char_pad_index': CHAR.pad_index if CHAR is not None else None,
+            'bert_pad_index': BERT.pad_index if BERT is not None else None,
+            'pad_index': WORD.pad_index,
+            'unk_index': WORD.unk_index,
+            'bos_index': WORD.bos_index
+        })
+        logger.info(f"{transform}")
+
+        logger.info("Building the model")
+        model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None)
+        logger.info(f"{model}\n")
+
+        parser = cls(args, model, transform)
+        parser.model.to(parser.device)
+        return parser
diff --git a/tania_scripts/supar/models/dep/biaffine/transform.py b/tania_scripts/supar/models/dep/biaffine/transform.py
new file mode 100644
index 0000000..073572b
--- /dev/null
+++ b/tania_scripts/supar/models/dep/biaffine/transform.py
@@ -0,0 +1,379 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+import os
+from io import StringIO
+from typing import TYPE_CHECKING, Iterable, List, Optional, Tuple, Union
+
+from supar.utils.logging import get_logger
+from supar.utils.tokenizer import Tokenizer
+from supar.utils.transform import Sentence, Transform
+
+if TYPE_CHECKING:
+    from supar.utils import Field
+
+logger = get_logger(__name__)
+
+
+class CoNLL(Transform):
+    r"""
+    A :class:`CoNLL` object holds ten fields required for CoNLL-X data format :cite:`buchholz-marsi-2006-conll`.
+    Each field can be bound to one or more :class:`~supar.utils.field.Field` objects.
+    For example, ``FORM`` can contain both :class:`~supar.utils.field.Field` and :class:`~supar.utils.field.SubwordField`
+    to produce tensors for words and subwords.
+
+    Attributes:
+        ID:
+            Token counter, starting at 1.
+        FORM:
+            Words in the sentence.
+        LEMMA:
+            Lemmas or stems (depending on the particular treebank) of words, or underscores if not available.
+        CPOS:
+            Coarse-grained part-of-speech tags, where the tagset depends on the treebank.
+        POS:
+            Fine-grained part-of-speech tags, where the tagset depends on the treebank.
+        FEATS:
+            Unordered set of syntactic and/or morphological features (depending on the particular treebank),
+            or underscores if not available.
+        HEAD:
+            Heads of the tokens, which are either values of ID or zeros.
+        DEPREL:
+            Dependency relations to the HEAD.
+        PHEAD:
+            Projective heads of tokens, which are either values of ID or zeros, or underscores if not available.
+        PDEPREL:
+            Dependency relations to the PHEAD, or underscores if not available.
+    """
+
+    fields = ['ID', 'FORM', 'LEMMA', 'CPOS', 'POS', 'FEATS', 'HEAD', 'DEPREL', 'PHEAD', 'PDEPREL']
+
+    def __init__(
+        self,
+        ID: Optional[Union[Field, Iterable[Field]]] = None,
+        FORM: Optional[Union[Field, Iterable[Field]]] = None,
+        LEMMA: Optional[Union[Field, Iterable[Field]]] = None,
+        CPOS: Optional[Union[Field, Iterable[Field]]] = None,
+        POS: Optional[Union[Field, Iterable[Field]]] = None,
+        FEATS: Optional[Union[Field, Iterable[Field]]] = None,
+        HEAD: Optional[Union[Field, Iterable[Field]]] = None,
+        DEPREL: Optional[Union[Field, Iterable[Field]]] = None,
+        PHEAD: Optional[Union[Field, Iterable[Field]]] = None,
+        PDEPREL: Optional[Union[Field, Iterable[Field]]] = None
+    ) -> CoNLL:
+        super().__init__()
+
+        self.ID = ID
+        self.FORM = FORM
+        self.LEMMA = LEMMA
+        self.CPOS = CPOS
+        self.POS = POS
+        self.FEATS = FEATS
+        self.HEAD = HEAD
+        self.DEPREL = DEPREL
+        self.PHEAD = PHEAD
+        self.PDEPREL = PDEPREL
+
+    @property
+    def src(self):
+        return self.FORM, self.LEMMA, self.CPOS, self.POS, self.FEATS
+
+    @property
+    def tgt(self):
+        return self.HEAD, self.DEPREL, self.PHEAD, self.PDEPREL
+
+    @classmethod
+    def get_arcs(cls, sequence, placeholder='_'):
+        return [-1 if i == placeholder else int(i) for i in sequence]
+
+    @classmethod
+    def get_sibs(cls, sequence, placeholder='_'):
+        sibs = [[0] * (len(sequence) + 1) for _ in range(len(sequence) + 1)]
+        heads = [0] + [-1 if i == placeholder else int(i) for i in sequence]
+
+        for i, hi in enumerate(heads[1:], 1):
+            for j, hj in enumerate(heads[i + 1:], i + 1):
+                di, dj = hi - i, hj - j
+                if hi >= 0 and hj >= 0 and hi == hj and di * dj > 0:
+                    if abs(di) > abs(dj):
+                        sibs[i][hi] = j
+                    else:
+                        sibs[j][hj] = i
+                    break
+        return sibs[1:]
+
+    @classmethod
+    def get_edges(cls, sequence):
+        edges = [[0] * (len(sequence) + 1) for _ in range(len(sequence) + 1)]
+        for i, s in enumerate(sequence, 1):
+            if s != '_':
+                for pair in s.split('|'):
+                    edges[i][int(pair.split(':')[0])] = 1
+        return edges
+
+    @classmethod
+    def get_labels(cls, sequence):
+        labels = [[None] * (len(sequence) + 1) for _ in range(len(sequence) + 1)]
+        for i, s in enumerate(sequence, 1):
+            if s != '_':
+                for pair in s.split('|'):
+                    edge, label = pair.split(':', 1)
+                    labels[i][int(edge)] = label
+        return labels
+
+    @classmethod
+    def build_relations(cls, chart):
+        sequence = ['_'] * len(chart)
+        for i, row in enumerate(chart):
+            pairs = [(j, label) for j, label in enumerate(row) if label is not None]
+            if len(pairs) > 0:
+                sequence[i] = '|'.join(f"{head}:{label}" for head, label in pairs)
+        return sequence
+
+    @classmethod
+    def toconll(cls, tokens: List[Union[str, Tuple]]) -> str:
+        r"""
+        Converts a list of tokens to a string in CoNLL-X format with missing fields filled with underscores.
+
+        Args:
+            tokens (List[Union[str, Tuple]]):
+                This can be either a list of words, word/pos pairs or word/lemma/pos triples.
+
+        Returns:
+            A string in CoNLL-X format.
+
+        Examples:
+            >>> print(CoNLL.toconll(['She', 'enjoys', 'playing', 'tennis', '.']))
+            1       She     _       _       _       _       _       _       _       _
+            2       enjoys  _       _       _       _       _       _       _       _
+            3       playing _       _       _       _       _       _       _       _
+            4       tennis  _       _       _       _       _       _       _       _
+            5       .       _       _       _       _       _       _       _       _
+
+            >>> print(CoNLL.toconll([('She',     'she',    'PRP'),
+                                     ('enjoys',  'enjoy',  'VBZ'),
+                                     ('playing', 'play',   'VBG'),
+                                     ('tennis',  'tennis', 'NN'),
+                                     ('.',       '_',      '.')]))
+            1       She     she     PRP     _       _       _       _       _       _
+            2       enjoys  enjoy   VBZ     _       _       _       _       _       _
+            3       playing play    VBG     _       _       _       _       _       _
+            4       tennis  tennis  NN      _       _       _       _       _       _
+            5       .       _       .       _       _       _       _       _       _
+
+        """
+
+        if isinstance(tokens[0], str):
+            s = '\n'.join([f"{i}\t{word}\t" + '\t'.join(['_'] * 8)
+                           for i, word in enumerate(tokens, 1)])
+        elif len(tokens[0]) == 2:
+            s = '\n'.join([f"{i}\t{word}\t_\t{tag}\t" + '\t'.join(['_'] * 6)
+                           for i, (word, tag) in enumerate(tokens, 1)])
+        elif len(tokens[0]) == 3:
+            s = '\n'.join([f"{i}\t{word}\t{lemma}\t{tag}\t" + '\t'.join(['_'] * 6)
+                           for i, (word, lemma, tag) in enumerate(tokens, 1)])
+        else:
+            raise RuntimeError(f"Invalid sequence {tokens}. Only list of str or list of word/pos/lemma tuples are support.")
+        return s + '\n'
+
+    @classmethod
+    def isprojective(cls, sequence: List[int]) -> bool:
+        r"""
+        Checks if a dependency tree is projective.
+        This also works for partial annotation.
+
+        Besides the obvious crossing arcs, the examples below illustrate two non-projective cases
+        which are hard to detect in the scenario of partial annotation.
+
+        Args:
+            sequence (List[int]):
+                A list of head indices.
+
+        Returns:
+            ``True`` if the tree is projective, ``False`` otherwise.
+
+        Examples:
+            >>> CoNLL.isprojective([2, -1, 1])  # -1 denotes un-annotated cases
+            False
+            >>> CoNLL.isprojective([3, -1, 2])
+            False
+        """
+
+        pairs = [(h, d) for d, h in enumerate(sequence, 1) if h >= 0]
+        for i, (hi, di) in enumerate(pairs):
+            for hj, dj in pairs[i + 1:]:
+                (li, ri), (lj, rj) = sorted([hi, di]), sorted([hj, dj])
+                if li <= hj <= ri and hi == dj:
+                    return False
+                if lj <= hi <= rj and hj == di:
+                    return False
+                if (li < lj < ri or li < rj < ri) and (li - lj) * (ri - rj) > 0:
+                    return False
+        return True
+
+    @classmethod
+    def istree(cls, sequence: List[int], proj: bool = False, multiroot: bool = False) -> bool:
+        r"""
+        Checks if the arcs form an valid dependency tree.
+
+        Args:
+            sequence (List[int]):
+                A list of head indices.
+            proj (bool):
+                If ``True``, requires the tree to be projective. Default: ``False``.
+            multiroot (bool):
+                If ``False``, requires the tree to contain only a single root. Default: ``True``.
+
+        Returns:
+            ``True`` if the arcs form an valid tree, ``False`` otherwise.
+
+        Examples:
+            >>> CoNLL.istree([3, 0, 0, 3], multiroot=True)
+            True
+            >>> CoNLL.istree([3, 0, 0, 3], proj=True)
+            False
+        """
+
+        from supar.structs.fn import tarjan
+        if proj and not cls.isprojective(sequence):
+            return False
+        n_roots = sum(head == 0 for head in sequence)
+        if n_roots == 0:
+            return False
+        if not multiroot and n_roots > 1:
+            return False
+        if any(i == head for i, head in enumerate(sequence, 1)):
+            return False
+        return next(tarjan(sequence), None) is None
+
+    def load(
+        self,
+        data: Union[str, Iterable],
+        lang: Optional[str] = None,
+        proj: bool = False,
+        **kwargs
+    ) -> Iterable[CoNLLSentence]:
+        r"""
+        Loads the data in CoNLL-X format.
+        Also supports for loading data from CoNLL-U file with comments and non-integer IDs.
+
+        Args:
+            data (Union[str, Iterable]):
+                A filename or a list of instances.
+            lang (str):
+                Language code (e.g., ``en``) or language name (e.g., ``English``) for the text to tokenize.
+                ``None`` if tokenization is not required.
+                Default: ``None``.
+            proj (bool):
+                If ``True``, discards all non-projective sentences. Default: ``False``.
+
+        Returns:
+            A list of :class:`CoNLLSentence` instances.
+        """
+
+        isconll = False
+        if lang is not None:
+            tokenizer = Tokenizer(lang)
+        if isinstance(data, str) and os.path.exists(data):
+            f = open(data)
+            if data.endswith('.txt'):
+                lines = (i
+                         for s in f
+                         if len(s) > 1
+                         for i in StringIO(self.toconll(s.split() if lang is None else tokenizer(s)) + '\n'))
+            else:
+                lines, isconll = f, True
+        else:
+            if lang is not None:
+                data = [tokenizer(s) for s in ([data] if isinstance(data, str) else data)]
+            else:
+                data = [data] if isinstance(data[0], str) else data
+            lines = (i for s in data for i in StringIO(self.toconll(s) + '\n'))
+
+        index, sentence = 0, []
+        for line in lines:
+            line = line.strip()
+            if len(line) == 0:
+                sentence = CoNLLSentence(self, sentence, index)
+                if isconll and self.training and proj and not self.isprojective(list(map(int, sentence.arcs))):
+                    logger.warning(f"Sentence {index} is not projective. Discarding it!")
+                else:
+                    yield sentence
+                    index += 1
+                sentence = []
+            else:
+                sentence.append(line)
+
+
+class CoNLLSentence(Sentence):
+    r"""
+    Sencence in CoNLL-X format.
+
+    Args:
+        transform (CoNLL):
+            A :class:`~supar.utils.transform.CoNLL` object.
+        lines (List[str]):
+            A list of strings composing a sentence in CoNLL-X format.
+            Comments and non-integer IDs are permitted.
+        index (Optional[int]):
+            Index of the sentence in the corpus. Default: ``None``.
+
+    Examples:
+        >>> lines = ['# text = But I found the location wonderful and the neighbors very kind.',
+                     '1\tBut\t_\t_\t_\t_\t_\t_\t_\t_',
+                     '2\tI\t_\t_\t_\t_\t_\t_\t_\t_',
+                     '3\tfound\t_\t_\t_\t_\t_\t_\t_\t_',
+                     '4\tthe\t_\t_\t_\t_\t_\t_\t_\t_',
+                     '5\tlocation\t_\t_\t_\t_\t_\t_\t_\t_',
+                     '6\twonderful\t_\t_\t_\t_\t_\t_\t_\t_',
+                     '7\tand\t_\t_\t_\t_\t_\t_\t_\t_',
+                     '7.1\tfound\t_\t_\t_\t_\t_\t_\t_\t_',
+                     '8\tthe\t_\t_\t_\t_\t_\t_\t_\t_',
+                     '9\tneighbors\t_\t_\t_\t_\t_\t_\t_\t_',
+                     '10\tvery\t_\t_\t_\t_\t_\t_\t_\t_',
+                     '11\tkind\t_\t_\t_\t_\t_\t_\t_\t_',
+                     '12\t.\t_\t_\t_\t_\t_\t_\t_\t_']
+        >>> sentence = CoNLLSentence(transform, lines)  # fields in transform are built from ptb.
+        >>> sentence.arcs = [3, 3, 0, 5, 6, 3, 6, 9, 11, 11, 6, 3]
+        >>> sentence.rels = ['cc', 'nsubj', 'root', 'det', 'nsubj', 'xcomp',
+                             'cc', 'det', 'dep', 'advmod', 'conj', 'punct']
+        >>> sentence
+        # text = But I found the location wonderful and the neighbors very kind.
+        1       But     _       _       _       _       3       cc      _       _
+        2       I       _       _       _       _       3       nsubj   _       _
+        3       found   _       _       _       _       0       root    _       _
+        4       the     _       _       _       _       5       det     _       _
+        5       location        _       _       _       _       6       nsubj   _       _
+        6       wonderful       _       _       _       _       3       xcomp   _       _
+        7       and     _       _       _       _       6       cc      _       _
+        7.1     found   _       _       _       _       _       _       _       _
+        8       the     _       _       _       _       9       det     _       _
+        9       neighbors       _       _       _       _       11      dep     _       _
+        10      very    _       _       _       _       11      advmod  _       _
+        11      kind    _       _       _       _       6       conj    _       _
+        12      .       _       _       _       _       3       punct   _       _
+    """
+
+    def __init__(self, transform: CoNLL, lines: List[str], index: Optional[int] = None) -> CoNLLSentence:
+        super().__init__(transform, index)
+
+        self.values = []
+        # record annotations for post-recovery
+        self.annotations = dict()
+
+        for i, line in enumerate(lines):
+            value = line.split('\t')
+            if value[0].startswith('#') or not value[0].isdigit():
+                self.annotations[-i - 1] = line
+            else:
+                self.annotations[len(self.values)] = line
+                self.values.append(value)
+        self.values = list(zip(*self.values))
+
+    def __repr__(self):
+        # cover the raw lines
+        merged = {**self.annotations,
+                  **{i: '\t'.join(map(str, line))
+                     for i, line in enumerate(zip(*self.values))}}
+        return '\n'.join(merged.values()) + '\n'
diff --git a/tania_scripts/supar/models/dep/crf/__init__.py b/tania_scripts/supar/models/dep/crf/__init__.py
new file mode 100644
index 0000000..27cae45
--- /dev/null
+++ b/tania_scripts/supar/models/dep/crf/__init__.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+
+from .model import CRFDependencyModel
+from .parser import CRFDependencyParser
+
+__all__ = ['CRFDependencyModel', 'CRFDependencyParser']
diff --git a/tania_scripts/supar/models/dep/crf/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/dep/crf/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5810074dccba6a92cf481e86ef69ece8be74592c
GIT binary patch
literal 290
zcmd1j<>g{vU|`^9UzEOpfq~&Mh=Yuo7#J8F7#J9eRTvl;QW#Pga~N_NqZk=MY^EHh
zT;?cdMursT6qa<RD3%n~U<OULmy8Sy44RC$gq(xiTv7{C^HNgtk}G}lQ&Mv@8E*-r
zhz2AU6{i*zfov&aW?*3O(`3EHnhR127Q4k(08s#vyTu+KpO}*qAHR~Jh@F7}Li}>m
z&&bbB)h|gb$xO^k)Jw`qOvy|w(ofFMEy&kRFDTIko2Fk}T98<z4`vtZr=%9>Cl{sZ
n$H!;pWtPOp>lIYq;;_lhPbtkwwF9}nn2mvffrp8Qk%tKY171m?

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/crf/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/dep/crf/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3609fddab845fa29cbbf98125bf4f14117dacd7c
GIT binary patch
literal 359
zcmZ3^%ge>Uz`&q%Uo~R^0|Ucj5C?{tpp4II3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI
zW=4h-<`kB6rYM#a)?fxrwwH_y3=Eo#w}hO7++0!%Qu9($^O7rl^HWlDG#PIRqlgA1
z78R!!6)`g~Fch&cFfjOOvfg6N1t|rK-C`?%C;-XbVvmnc%*lz5U&-(p<gQ;K`WgAT
zsrn^}C7FqNiF!#ni7A<>Mf%D4xdr*UC8-r9x~XM}Ir=4ud6|jv#mPmP1trD$#ia#_
zMfzYXiuF@c3-ptV()8owGxIV_;^XxSDt~d<<mRW8=A_ycaWgP5fc#Qy#lXPuftit!
n@dFzJquK=qRb+I7LHz<MdcZAzLDB32mw5v_2o`ZNFfafBeO_ab

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/crf/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/dep/crf/__pycache__/model.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..350a941b0ad158a2c7ec7f74b109e4200050bd1e
GIT binary patch
literal 6656
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/crf/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/dep/crf/__pycache__/model.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..82c5f8a1f3181f461f6d3f7c6d863af8093a12ca
GIT binary patch
literal 7412
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
E0H`}!!T<mO

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/crf/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/dep/crf/__pycache__/parser.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a0a41a163099e2b9eb112143902fdc323def85a0
GIT binary patch
literal 4987
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/crf/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/dep/crf/__pycache__/parser.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b93724d0f7d60bbc3af66307c55579f66b3ed2c5
GIT binary patch
literal 8854
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
Uz)oI}GWrOX`T`~~m4QPG0BKj>M*si-

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/crf/model.py b/tania_scripts/supar/models/dep/crf/model.py
new file mode 100644
index 0000000..472bd35
--- /dev/null
+++ b/tania_scripts/supar/models/dep/crf/model.py
@@ -0,0 +1,134 @@
+# -*- coding: utf-8 -*-
+
+import torch
+from supar.models.dep.biaffine.model import BiaffineDependencyModel
+from supar.structs import DependencyCRF, MatrixTree
+
+
+class CRFDependencyModel(BiaffineDependencyModel):
+    r"""
+    The implementation of first-order CRF Dependency Parser
+    :cite:`zhang-etal-2020-efficient,ma-hovy-2017-neural,koo-etal-2007-structured`).
+
+    Args:
+        n_words (int):
+            The size of the word vocabulary.
+        n_rels (int):
+            The number of labels in the treebank.
+        n_tags (int):
+            The number of POS tags, required if POS tag embeddings are used. Default: ``None``.
+        n_chars (int):
+            The number of characters, required if character-level representations are used. Default: ``None``.
+        encoder (str):
+            Encoder to use.
+            ``'lstm'``: BiLSTM encoder.
+            ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``.
+            Default: ``'lstm'``.
+        feat (List[str]):
+            Additional features to use, required if ``encoder='lstm'``.
+            ``'tag'``: POS tag embeddings.
+            ``'char'``: Character-level representations extracted by CharLSTM.
+            ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible.
+            Default: [``'char'``].
+        n_embed (int):
+            The size of word embeddings. Default: 100.
+        n_pretrained (int):
+            The size of pretrained word embeddings. Default: 100.
+        n_feat_embed (int):
+            The size of feature representations. Default: 100.
+        n_char_embed (int):
+            The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50.
+        n_char_hidden (int):
+            The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100.
+        char_pad_index (int):
+            The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0.
+        elmo (str):
+            Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``.
+        elmo_bos_eos (Tuple[bool]):
+            A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs.
+            Default: ``(True, False)``.
+        bert (str):
+            Specifies which kind of language model to use, e.g., ``'bert-base-cased'``.
+            This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_.
+            Default: ``None``.
+        n_bert_layers (int):
+            Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features.
+            The final outputs would be weighted sum of the hidden states of these layers.
+            Default: 4.
+        mix_dropout (float):
+            The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0.
+        bert_pooling (str):
+            Pooling way to get token embeddings.
+            ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all.
+            Default: ``mean``.
+        bert_pad_index (int):
+            The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features.
+            Default: 0.
+        finetune (bool):
+            If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``.
+        n_plm_embed (int):
+            The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0.
+        embed_dropout (float):
+            The dropout ratio of input embeddings. Default: .33.
+        n_encoder_hidden (int):
+            The size of encoder hidden states. Default: 800.
+        n_encoder_layers (int):
+            The number of encoder layers. Default: 3.
+        encoder_dropout (float):
+            The dropout ratio of encoder layer. Default: .33.
+        n_arc_mlp (int):
+            Arc MLP size. Default: 500.
+        n_rel_mlp  (int):
+            Label MLP size. Default: 100.
+        mlp_dropout (float):
+            The dropout ratio of MLP layers. Default: .33.
+        scale (float):
+            Scaling factor for affine scores. Default: 0.
+        pad_index (int):
+            The index of the padding token in the word vocabulary. Default: 0.
+        unk_index (int):
+            The index of the unknown token in the word vocabulary. Default: 1.
+        proj (bool):
+            If ``True``, takes :class:`DependencyCRF` as inference layer, :class:`MatrixTree` otherwise.
+            Default: ``True``.
+
+    .. _transformers:
+        https://github.com/huggingface/transformers
+    """
+
+    def loss(self, s_arc, s_rel, arcs, rels, mask, mbr=True, partial=False):
+        r"""
+        Args:
+            s_arc (~torch.Tensor): ``[batch_size, seq_len, seq_len]``.
+                Scores of all possible arcs.
+            s_rel (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``.
+                Scores of all possible labels on each arc.
+            arcs (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The tensor of gold-standard arcs.
+            rels (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The tensor of gold-standard labels.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens.
+            mbr (bool):
+                If ``True``, returns marginals for MBR decoding. Default: ``True``.
+            partial (bool):
+                ``True`` denotes the trees are partially annotated. Default: ``False``.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor:
+                The training loss and
+                original arc scores of shape ``[batch_size, seq_len, seq_len]`` if ``mbr=False``, or marginals otherwise.
+        """
+
+        CRF = DependencyCRF if self.args.proj else MatrixTree
+        arc_dist = CRF(s_arc, mask.sum(-1))
+        arc_loss = -arc_dist.log_prob(arcs, partial=partial).sum() / mask.sum()
+        arc_probs = arc_dist.marginals if mbr else s_arc
+        # -1 denotes un-annotated arcs
+        if partial:
+            mask = mask & arcs.ge(0)
+        s_rel, rels = s_rel[mask], rels[mask]
+        s_rel = s_rel[torch.arange(len(rels)), arcs[mask]]
+        rel_loss = self.criterion(s_rel, rels)
+        loss = arc_loss + rel_loss
+        return loss, arc_probs
diff --git a/tania_scripts/supar/models/dep/crf/parser.py b/tania_scripts/supar/models/dep/crf/parser.py
new file mode 100644
index 0000000..2ed1689
--- /dev/null
+++ b/tania_scripts/supar/models/dep/crf/parser.py
@@ -0,0 +1,131 @@
+# -*- coding: utf-8 -*-
+
+from typing import Iterable, Union
+
+import torch
+
+from supar.models.dep.biaffine.parser import BiaffineDependencyParser
+from supar.models.dep.crf.model import CRFDependencyModel
+from supar.structs import DependencyCRF, MatrixTree
+from supar.utils import Config
+from supar.utils.fn import ispunct
+from supar.utils.logging import get_logger
+from supar.utils.metric import AttachmentMetric
+from supar.utils.transform import Batch
+
+logger = get_logger(__name__)
+
+
+class CRFDependencyParser(BiaffineDependencyParser):
+    r"""
+    The implementation of first-order CRF Dependency Parser :cite:`zhang-etal-2020-efficient`.
+    """
+
+    NAME = 'crf-dependency'
+    MODEL = CRFDependencyModel
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+    def train(
+        self,
+        train: Union[str, Iterable],
+        dev: Union[str, Iterable],
+        test: Union[str, Iterable],
+        epochs: int = 1000,
+        patience: int = 100,
+        batch_size: int = 5000,
+        update_steps: int = 1,
+        buckets: int = 32,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        punct: bool = False,
+        mbr: bool = True,
+        tree: bool = False,
+        proj: bool = False,
+        partial: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().train(**Config().update(locals()))
+
+    def evaluate(
+        self,
+        data: Union[str, Iterable],
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        punct: bool = False,
+        mbr: bool = True,
+        tree: bool = True,
+        proj: bool = True,
+        partial: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().evaluate(**Config().update(locals()))
+
+    def predict(
+        self,
+        data: Union[str, Iterable],
+        pred: str = None,
+        lang: str = None,
+        prob: bool = False,
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        mbr: bool = True,
+        tree: bool = True,
+        proj: bool = True,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().predict(**Config().update(locals()))
+
+    def train_step(self, batch: Batch) -> torch.Tensor:
+        words, _, *feats, arcs, rels = batch
+        mask = batch.mask
+        # ignore the first token of each sentence
+        mask[:, 0] = 0
+        s_arc, s_rel = self.model(words, feats)
+        loss, s_arc = self.model.loss(s_arc, s_rel, arcs, rels, mask, self.args.mbr, self.args.partial)
+        return loss
+
+    @torch.no_grad()
+    def eval_step(self, batch: Batch) -> AttachmentMetric:
+        words, _, *feats, arcs, rels = batch
+        mask = batch.mask
+        # ignore the first token of each sentence
+        mask[:, 0] = 0
+        s_arc, s_rel = self.model(words, feats)
+        loss, s_arc = self.model.loss(s_arc, s_rel, arcs, rels, mask, self.args.mbr, self.args.partial)
+        arc_preds, rel_preds = self.model.decode(s_arc, s_rel, mask, self.args.tree, self.args.proj)
+        if self.args.partial:
+            mask &= arcs.ge(0)
+        # ignore all punctuation if not specified
+        if not self.args.punct:
+            mask.masked_scatter_(mask, ~mask.new_tensor([ispunct(w) for s in batch.sentences for w in s.words]))
+        return AttachmentMetric(loss, (arc_preds, rel_preds), (arcs, rels), mask)
+
+    @torch.no_grad()
+    def pred_step(self, batch: Batch) -> Batch:
+        CRF = DependencyCRF if self.args.proj else MatrixTree
+        words, _, *feats = batch
+        mask, lens = batch.mask, batch.lens - 1
+        # ignore the first token of each sentence
+        mask[:, 0] = 0
+        s_arc, s_rel = self.model(words, feats)
+        s_arc = CRF(s_arc, lens).marginals if self.args.mbr else s_arc
+        arc_preds, rel_preds = self.model.decode(s_arc, s_rel, mask, self.args.tree, self.args.proj)
+        lens = lens.tolist()
+        batch.arcs = [i.tolist() for i in arc_preds[mask].split(lens)]
+        batch.rels = [self.REL.vocab[i.tolist()] for i in rel_preds[mask].split(lens)]
+        if self.args.prob:
+            arc_probs = s_arc if self.args.mbr else s_arc.softmax(-1)
+            batch.probs = [prob[1:i+1, :i+1].cpu() for i, prob in zip(lens, arc_probs.unbind())]
+        return batch
diff --git a/tania_scripts/supar/models/dep/crf2o/__init__.py b/tania_scripts/supar/models/dep/crf2o/__init__.py
new file mode 100644
index 0000000..d2acf9c
--- /dev/null
+++ b/tania_scripts/supar/models/dep/crf2o/__init__.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+
+from .model import CRF2oDependencyModel
+from .parser import CRF2oDependencyParser
+
+__all__ = ['CRF2oDependencyModel', 'CRF2oDependencyParser']
diff --git a/tania_scripts/supar/models/dep/crf2o/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/dep/crf2o/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fb6754d2364431258038d51a7d60f97240ef9d09
GIT binary patch
literal 296
zcmd1j<>g{vU|`^9UzEOrfq~&Mh=Yuo7#J8F7#J9eRTvl;QW#Pga~N_NqZk=MY^EHh
zT;?cdMursT6qa<RD3%n~U<OULmy8Sy44RC$M4W@%jPhMl3sUn^QuC54ee+XNb2J%m
ziK2-IBo-B?78QYPDq?0}VDQsqy~UafQVbTm#Z~}O0Ft}K9v`2WlM^4mlA(y5fdNAN
z^3c!7&rQ`YNi4}s%uCcu%1KPgOfAw+&d)8#*G(@d(FL2PUtC&{SfmeT7we~_7U(Az
rr5WYx$H!;pWtPOp>lIYq;;_lhPbtkwwFCK~n2mvffrp8Qk%tKY+LKF?

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/crf2o/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/dep/crf2o/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4cf033823fb198f1abbc2c5fe24ab7427a6e3819
GIT binary patch
literal 365
zcmZ3^%ge>Uz`&q%Uo~R|0|Ucj5C?{tpp4II3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI
zW=4h-<`kB6rYM#a)?fxrwwH_y3=Eo#w?v$S+>G*FQVUY^Qd0AhD}D1*QgbvJZ;7Ib
z2P761rxq14GcYg|u`n<&_-V4<V$B6928-QdD}X2f$=za)k5A0WiH~2&@EPQ`Ut#(g
z`MIh3C5a`OiFt{7NjZrrnW;tk$@#ej`MM>k6(zc<Wr;cZC5d^NiSfnBMVSR9#rnmi
z1&KxaU@MCCQ&J1`lZ(=f^7Z56GxIV_;^XxSDt~d<<mRW8=A_ycaWgP5fP7SJ#lXPu
rftit!@dFzJqs9dWb!2pdLGuDCdcduCLD}j8mvsX>2o`ZNFfafB@r-4q

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/crf2o/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/dep/crf2o/__pycache__/model.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6243392a5a1c5d884a93eb8cd18fbcf1edad6ec4
GIT binary patch
literal 11378
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
E0ROS|?*IS*

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/crf2o/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/dep/crf2o/__pycache__/model.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7586c6f2981ac0dc9e8dbe7252d6f9ed741d5805
GIT binary patch
literal 15100
zcmZ3^%ge>Uz`&q%Up3>0J_EyJ5C?`?p^VR63=9m@8B!Qh7;_k+AT(nxQxp>;h|QG4
zoXZl$0%kMku;#Kwv4PnvIqbO{Q5?CPQJlG4QCwg#)*S9!o+zGN-Y8x$pDl+kmp_Uh
z%x2FK$Q6tdWMp7saA!#2Xkkd<Ol4Wd%)qdk8R`y(D4`U_U<OUDmmmQ@O~zZ|PML{m
zX_<McE~y2nc`2!R$(6qODXBS{jJH^w^Zk5$G?{NP`}zdj;(#f<#Tilr)uYLDiyxuS
zDBn5A?G~4BVo6bEMMzO<swU$tHs}1jw9Ir(##_w3o_@(7TVYrZ%J^Kxz`)SXFr6Wl
zA&N1DA&M!5F^V~bDTOJ8IfW&iF@+Tj*-}_j*i$%CI8&HXxKg-Ncv9F?cvIL@_)_>&
z1XB1?1i`BKQrJ`2Q-spwIvCOzQ-oVMqgYZTQbbx9qgYcoQ^Z;rqu5d;Q^Z>squ4tb
zDj1_Uf*CZWZizStxf$gnJOU1YL}x(;1}+5!1%;4|RE5mkf}GUc)Vz|!lFa-(h5R&y
z;?(5)ycFI1qLkDk1?M0)1%!TufW)HW)FK6|<jj&(tAwhI#JqIf)RM#;T_Xb{1KrfL
zw9Mqp)Vz`eJua{Xjz#IkR$vy$y1e-E{Gya%1&z$S5>13KNDAbV;>@a4ko_eYsR|&4
z3T64piAkk7iA9xqNM;nJ=HN6UuQWF)wFqQLPGS;BU1pvF$heZC)YPQJyliB1N)pqF
zFeku2SOKI`N1-USur#wMHANvaO#v#ZkeZv6nv#;4mtL%pSd^+zTAZ4qr{I#BmROoo
zVx^Ff;Fq75nvj5OYjQ?n5fRpclqDvYq!tyUS_~K0%}Fgw%~2>yEhtJYhQ%I{u1L*G
z&IiS<MsZ0IT0FQyrAqQao<TSq6h{dO>N&+Fx#|fCRtip;KEWZr3Q&_U)Fq`Bl|a<F
z28HP6WM-!-6cnYF6eVWnrKTw4B<7`;CZ?w<<bv{}f<{_?kpd{AmXzjY=A~=uD5UD8
z>***YB&dVT(M?J$PSs6LEKW^PM-EGnlaPWM<~D>|(oz#k6f}G?i%X)5ONwIAeCn8z
zk_k%ji8%@&g{4KQ#R?E#qlS1w0@RbXm^Of%kdUBWl9&$mEM}@eI0mW|6n|i~&KZeC
z;0VSMk*O6WVEGh<q)G*lVo-Qv7zYX;uyIbVK_TdgK}R9KBqOy5cgPnjfMX^oAEY}G
zoPrZ`it|C?QJk5SlZt8`JglP=64asoh(##Liw9>0LYW(!vB4_A*#;@M7#bKLn}(EL
z2$UB{Dv3576y?M@7^JeaC>1?$aXTCoG{hMVQVC82$mK|JYEfBcUb;eJu|j5EL1{@b
zs5FBm0Mw*eS`1PMlS6WmDN0C!tclOaOi4-2BNRJORmCNVC8^|Cj1q@ndkYd%;xqG7
zQY&y-4Ux=G1DDeUiQv*yp(H;$HBSLrc!SJ=1QVh{ATl73!XY&$H(vouiRYJ?3$JyM
zQj)8WZ@xlNYI<gINh-L|&r?VMiMhf`d_Dhw5Kn)<1f*b3NKnr&%1qD9OU#KkO+qQG
zK(@yx<rl}N<`*kygp?NKq(&#@=jULQN(v<)IZ&LJl;<mel%yu+DU>DVl%|3bL`r6I
zVhJeL%QI5JnY$!kAv-m-K%uxKv8Y5pH7`XWDZex?C9x<I5`iF#74l0<Kq(24y+EZA
zJU=HSXoM7%rs^oTCFT^TY9g1hpz;M<pamDCCTFIBtSHaOOwLfq&df^zxf!iwhn1&9
zm**iFnZ*j3#VB<xQUMHdj(S3ZLVl3~B<+I=E>Lk*0xG`s!0nl|(wrQHoXp}9h2+FM
zg``x4G*Ebe(o#Z6QDR<kT7FS(YEf}QJkHR-th7P)#^)qfred$U5uuThU#^gwm{+Ng
zlUQ7$0M!8t1>^<<@t%UWd_ZvqY9^(D(ibdB70UBVb5cOwEKki$&nQVvQ7A6W1w{p@
z*@KatOEOZ6Q=#s{;eQi^cy4Azd`eM%L4Ik8f<{_Sej>J38%#kFsQn1C7#t@MucPKt
z;{A+hLg^vpU~nuH<mcyr(m$4*8~~LnPpkyh<mss;&~gN+x<LuegoL!rqT&)zd!{5Y
zI~804fkhOGOOwDwke)(90w^j`lz;?KROF^6=D}4YDuB2O`DLj^3W+&6dMGv`<vEZl
z^sE+7VQC2tdR&Dh@xhPX$w)B)ZLFm#Xn+bRw1$;unnFSXxF|_T&{0S$N=>awEd~XJ
zLP26tVs0vCqZX2vkqTc(>Om=4p#~y?GcUd%CzrT-Ho(UhsfN{4@Jv%M&;hk?i@{Nj
z-0whg1U%J1nyE;xK?(`5A~G@wxN1jn6g+9@85<+}659GCvI2*yRzS)5NKUsvZDc`}
z<0;!fB@Uuj1yv6#K@j;A$;nVPWCRLSC&Y9lN27&EVo`E@ZcYKV28Cl$vVyNqfC4B=
zkqj_J^>uM(5-tORGn2r@3l>9A+BSLdMX5PpL$Eo+2h{n*<`5J!a&rpE2qcipF!BdV
z2o)zM=A>dTu!EBm!QM+tOfCU+y7G$@AY&v7#mV_asl`ZPhLp%DER{et5x8NFD4DR^
zQ<|4eLR+ykFFP;4JP%sNL)(hD?J<N7N$BY*#3MHZ5aSRTB_##LR{HwsnI##eNqWio
zx%wHU>FJqy>1m0{srty8z$K*LEf!FJ_!bMOf%-Cqfq~(r5d#B55fcLg!!2&4mY^n6
zh}%mR1_p+7=)e%eEf!Gm@0Kp#`Z{oj+*SKb1!e|@m!Pq%%rA@#3@;fO7#NZjVX7Gz
z7&sUh7`Pc27(UA}GcZhLoX)_+Py$i}RkDnMfnhb2&A^Zamq}sEWGI0R)iE$IpsHH{
zvJkEd#wg*0vC!2oV`N}h4L5rUV;>_ULkY-LPz^N<S!_@yLl!%XRU=g+yM_^Uu&#z7
z9^@mi60%KzyORhLq_MgIJiG~V1lcCQeNVOtJRti)m<SVOu=;`*q#K0EHh~YM8-z>b
zK_mp%NY%)JhAP*vEMs9{SPe?QV2K)rcmXhjfq|h!8OCB@sF4P%XTqXh2&M|fe3=^1
zP$<(HRt)on;p#PEECz-wQ5YLF71uDti@{`47=jrz+5I$`Z?WXXXXf2v&5O@3ExE-G
zZKQ^{X|fbafU+kmxRAWXmXw)T9A5#YE1|MQlAvrX10rM@7#LPEXo}xrEiNrcExN@K
zAD@|*SrQ*#1WG%%*h&jh5=&BVvE}3^C*~9vfwI~ymc*j;;#&fF@zDAVT6N#zgjQVf
zDF|l9Ely}{6km*BrXZLZw>Y6S4M-b|nNbAFXty{(CMK4Y<Q0K(+bs@|Q6TOu4v<1H
zizzSfmVk3nesQsDUP)1YL8VWAaq%tA<f6=y)S}G%JWb_WEXAogX}8#+qqDczz;#<O
zhz1ROf+Ro%T=6Y-sDEy;fW|~X;^5ZLEuOr1M6(IR14%<#W*{C&GnB`h7Z2t^S|_*o
zz#Mq(a*GAjS-r&rB4K^yTP&bf|1I9Ucn}S3r`+O3>Y3c)0n0%91-JMhJlLqiEe=>)
z^%gf$i}4mO*y*t9w@3w)CXiwbQo-Khhx!<%?iOcWJSfO>a|%FAP;f(;pzsDUxsfXM
zB59DRoCyDM!YjC2Y}w`DRKgh_pPZ9eTpS-?49ZHNJ|2GD@GDq9BR@A)A2eQ{n3t%R
zl#`f}nOdZuoS$2euUnE@QKFk#mYAbol9-p77+;)Rlvz+xtY2JOkXWP-9&atyPf0D%
zPcBL`%7+N(6;u`}FfcGw$zq!=(1WG;GzJES;wVN2h93<KA6yt2I3;^oJK1~KuW(3Q
z;4r<wVLI1rro|kK`S!Ey*P5-gSYvTf+T@C~2}JG!hv`#EnFT6KG_NSx9Pqplo^(Mn
z`J!a<70KidmL9&lLqzVWgu;T%4W$P{E(C>NkchY_5phK#qJyP}_pXHEg32AN2U0Es
zqf3BvlwpyOl)fUVb5T<7iliPW2s-#W_&$Tmv1H_08I;XI{LdN8plP-mh6Nxc7`TS9
zhG`iS1H)=i+XF0H%UlA|2WB%c)G%hjWl(GJ6vk|@nj-lcM(pi@8ip)**`Ea};K1rp
zP02H)ME3%aFTtiF6DdrncGR-eFf0I-bI6Lo>>6e?m8>-k3*hYwuo5VNp^~kJVF4#p
z5{1H0$zH>-0959qr~+{?RC3fXEP%HQKq_DuLnUVo!vc8y4^suAF;sHZFf4%A^B@&4
zjG>adhG7A`K8L9S(KW0!Y^Z5u0Y69_9oMidfY<NHaw%w`%+FAwgpfxyxt6DfVFA3>
zN2p?8s9~?+sNqCy4K9G!_sA+!SW*~Mm{ZVN2erI43=2e%)xp>`Ts7RNuE1$7E68Nj
zR!1#g4Nnbk4PP2_FoPyr;uj|96e*}QMxDh3iGaEp#R?jACHY0k8G1hXdFdgkdByof
znxIL)=%mDw<c#>@%&Jr!h2qr0_?*<dSmdD|kO?3ho?n!rkeQc~nVedT=<<VPKs9JF
zbnXhn67(@+kOoJ{kY|1xcr+Bdp&)gj?mWn0ph4EuOz;SDLIO4i>nNmURzO`2n(<6X
z0J$k40i+Qz{{tF{g-+9{CnV^AyG0;tU^u@>0lV?Bpix|q_2rqxX!A@Uz3{;h#1tyr
z?4Z<=(xN=1X=RWGXdppiK}P`}7t!GZX$0Y5aNid+cA1!yqfn4v44(Z`NGwV&R?xui
ze&mSN#PoLxbjd-9ZboWiiY~}J(4b{WQD#9-Dq%xWOjk(EOM!bH<XjL&aVT`IJ3mh$
zH8D8@<Zgn_)=|idhiHpUNYF$iz9LW~`{n=t|Nj?(8r9&w>`PG9p(%Qc4bmFA#hjCx
zcZ;<+Be5X$7E@ko5vbu(<PU1=Fem0!7O8^T&1xV*9Ykn=2v9S=NDIW$1`#?S#XPx*
z#o4JT@oAYkIq|nROY@2gOF?6WMWC{?NEf7py&$zHx3na+NRNSmL6g4-)V;pN3eJ4D
zSV8Hr_!eWuEf$bLw^%_9vlIxGaf=nyHY<iuDG(~-7AvTgmI9$bN<eM7Tdc+L#hFPU
z3be2QR3d`H7YP>ygPoF=UsRr0lu{*wwUGpsoepXv6)-X|G%$QnVc-?)_wMqZ!8)V#
zB9H179@P%Uy9UM^T(@{%G;p|L;Bdh3l7Y(w1DB4{{)(=O87y-+uSjTL<kz{vuXBN4
z=Y;BcjZ+#Ig2S%_$6N_cyXcjE#Vh@~SN0{Z><c-07rpYYc;$DnJP;6>&Nqo~M&U&P
z#VZ1e9jrI#BJhEYK~Qu$?<C$CsS83c3TR&u(7rBUaY?{phsu7vU3w=3FIstDvGTrP
z>3uf%qCnskfxr${kW-;LR=8diFuEdObX~yel7Q6?!ySnS1P?e~6mYvD;D(|QX0-7o
z0pksh8wz(Q?g+dnV1GrxzJv7vzsQ8t8KD>Wl`e276@@S`FoYx{SJ0qF1*i%1`357X
z>4ZF70%|U$G1agyfDdNCDiIK!!id_OK&@12xoWr;fN}&#DGIJ(sbNiHs^MIN))d2T
z3u-5pn*o<=P}Nm&GceS0*KibZ)o^8jd<S+x3=;!GEn_WH4QG)=4SNmC0(gTBEDa^l
zEAT2t28LSp8s-{yP=6PqsD=%hSIbt*T*F)f%8(Fgqye51P*#D8*07<47|K9V4GXfF
zX-o*)YMF62)X*C%wLCT4H9VjdRkge|yx<rFRn;tseyn(_>S9nXhga2*3Ib;}ja={|
z3Po69fTx~7RSYgtNVbzK%kkGV=*}ui%^|~CNL2-@fuMlF5h#$#MFFW!Le&bXT%q+e
zxeX{#Yo-L;@B&rd>G?S+y2T}lpxN&fP%Vhos4C7(BB{-WKR)o;4Xy9d><85^@X)7)
zmmy(}8qT1)5pJndetr&t9Duc<3i2!1Aka#!WYE+mxHXfJs!*B-TC$Ov0vUxz^Kfob
z5!M+(P_hBf5`vZ;fF=oxAWb@j+{7aA>WN|nkVU>uK?*6U$@!p#LP!$^2?-EwsQxTS
zEGo%N%)x0NOqW7RYF<8QaSLcx0<<g;vStpdJ*QG3F)uG4wEP8iAs>AD5#ACbxfzPt
z?gRxZcugEAG;{Kci?KHKU=s<T6b+rG0i||u`wK_w8ad@c8t=JDMYd2s=ztpSh>!-a
z5kqZ-7lnbETa35Zp`ik91!{5@fx6VUn2SquZ*k=0r^go*<tN?Zgqw7WDLwTTE4W8=
zi!HGzF)ux}C=%4#GX$B&2X4F-fd(6jazLWFpjH(Ns2I4#0?L`USU~xs2(*y)7ISV=
zQBeU%0eFNnC9}8$GS&$SB*@?<n8gAji$T3zP?ADmaFea54m74EiM6=~(zh4XR(s9>
zYO8&<U=UGW;JU(ef!zj^?G~FXb~tUc*<y21*x`z>LkGtV5t-{Es+UAm7nH0BS&*~C
z{ep<<MG==PA}-fOJT8fNTom!TBI0#H*y}{d`G`{yC!@|pT@()Q;JCrf_kn?tQ}2ef
z@)c>_PM;3f38oLYg+OAeH-yD!sLWTNrM^IMrq&#-i^3`$E;q!aXShtsUSP6<Wr<Zs
z38*nAIyH4l&QjwAB?~Q=SY8y<y&|T&qGW^1nyL$8mRAI<I#_QAi%++kWVb+dg~&x=
zy(_|c9UM3K#b;<-<X7roxxp_yA#{f81%AZ~9E#v3QZgtGp|v&xyoEH0iGiV=eL6!8
z3-;k9^cGPqM-3zPRt?6W4QB^?8e<A`3kUKvR1F9Ap(fO}P7Nn9s!&^JE@)F+wOlo<
zMIFdfS~Xm#ZIz<RPWB=P<Tg$XV+|LgjZ(ve%u8dcVL|5O2rsmuD^xckrsrxnYq)F}
z7#Q-*OOOV4(CnvyeKpL)#UA$IwiKosPVB>L=&_ILZ|nnY=z40oYdCAT)0l!8G+7dV
zFpswFQuDBnBB0iP#h?WV@QR*5B@eG3P=*0e4Fr{@WVY?VO$FHC7@gZ3peh|_BLJn*
zk(yTwS~Un-Dh62}sZgGplcNh>ADE&5G6#7%1bj&oYA6xi#3@KE0-0Q_Kw7J&C_jr_
z-xL((XQd{WWR|7k^9)h#8AM|hKD34q!fe+B6s4wQCWF=@f~t2=qecPJG$qt-L1}zK
z2B1Jqk!0j<I;a8zjTe88V1TTINN1>Fh*g7ifswoUNChoZ3PTNJ3InM7*oxEv?PNwR
zqIei4GWDnjGiWk`ZP#Qf0`;VCv1Jy6(t{?;EhasKTa1~vn2S>jZ?S+vxEQ2BK|!Gb
z+~)YjWdmAz3Yv?vtJ25X^Z>VLQ}t{hGsbp$2o3*14H63m@C4fhzH|uMn6@EthwxO>
zDK-n37dS3RT*0_7d4cN^t`#m9g$=I=8(!cygebhgmkzGsHMxokK`ke?#G>@v#EM(Y
zRhb31*h=z2?kb7_wY)$fSOl8%xW$&92pWSeiUVn2hmOB#@?dMKK^kT(pkOEhg<?@F
zNDoU+YF;s9HoKrGHKq6#b5ddoWX2lIF9ywSfJzbt1%(6<4GyJSY>+^xlExE4&p@G}
z4xMh)V-OGl50Wu<R`*nQu-p)lobEHpXMxZ~5tS<<Djl3RVBvLvFa0R<0hi<6hrAE^
z9`U^p9CJN5`BHH5#o*K{!KoJ=(yln9UEoW<$d`VFFTI2L1~>l)1{TgB#;MLTm?wHn
z@qqAd@C$!nVCD^CysK!iL3Ic77Ofqr2b}k0T`=@KVR9iL_>ARw+f%j|BBL*Q$6WD_
zxu_U>1%y&2aL!Pk$TxxSsiO7@*A2>Rymqkc2;RfFpLZAUfuxHTo>we9FDiOn0ii&M
zS~Q<r7ty{XqP@at1Lt)E=Sv382b?Y%xL+}FzbN8yMa1K}NWdkLfD3`a7ezv@h=g=-
zKH!&_p?QH{`2vSBB=Q;kG@0E(+%!2sD;4q*b5rBvZ*j%P=jNxB=788d@$rSFi8)Xi
z_W1ae{N(s}@bqs{9w>2u8qGx$L2=6qotjQg&B=+6*JLaT0>ua@D>{H<u?W;;0TUob
z@e4@8ZD4@F4@_Z<tQ;R0z+@Q{gQV;Y5R$(kE;}LPhNR35IYls1xFN4}LqYL|nDPxd
z?HgiJH{=y=$jaZ4QvnG|$={Hb11V5ay`iLhLs8|1v>X)4D%=p4xFIcbLt5s8Bcnd6
z{s#tJL=vM4tMUg1RKkZ*omJ@r11b^3sK~1Ffq@_a4r{R2HHC{xL4m~q?)T{B<rV3J
zxboonc0I^^yIx9afnE}HV<AMW2sCteOBuH+_+m3i0mKVeS(=jyS!M!W0Rma~0hKK-
zDJo4aDF%1bAo-gcqOG(fGp87`U_}T?1hm2}H$M+D-VTbxBGAS~h~GeC-oH3(AnC@g
zXdVLt11RQ;?=vtkd|+l|Wc<L!z{uOc1A;dgL@%JC8w}1DP|*zr(+jBR27}QB+z3-W
pMEeZ}xeKW127}TCRP=$ZikVU60|R#Qg0#^`u+$eYiKz@6005TF%^Ls!

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/crf2o/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/dep/crf2o/__pycache__/parser.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7cf299268ee7bd3bd211e8bd3d917638bd104180
GIT binary patch
literal 8249
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/crf2o/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/dep/crf2o/__pycache__/parser.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ec22eb9df296b742697cdd799d431ff90162da41
GIT binary patch
literal 15194
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/crf2o/model.py b/tania_scripts/supar/models/dep/crf2o/model.py
new file mode 100644
index 0000000..1b53bdd
--- /dev/null
+++ b/tania_scripts/supar/models/dep/crf2o/model.py
@@ -0,0 +1,263 @@
+# -*- coding: utf-8 -*-
+
+import torch
+import torch.nn as nn
+from supar.models.dep.biaffine.model import BiaffineDependencyModel
+from supar.models.dep.biaffine.transform import CoNLL
+from supar.modules import MLP, Biaffine, Triaffine
+from supar.structs import Dependency2oCRF, MatrixTree
+from supar.utils import Config
+from supar.utils.common import MIN
+
+
+class CRF2oDependencyModel(BiaffineDependencyModel):
+    r"""
+    The implementation of second-order CRF Dependency Parser :cite:`zhang-etal-2020-efficient`.
+
+    Args:
+        n_words (int):
+            The size of the word vocabulary.
+        n_rels (int):
+            The number of labels in the treebank.
+        n_tags (int):
+            The number of POS tags, required if POS tag embeddings are used. Default: ``None``.
+        n_chars (int):
+            The number of characters, required if character-level representations are used. Default: ``None``.
+        encoder (str):
+            Encoder to use.
+            ``'lstm'``: BiLSTM encoder.
+            ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``.
+            Default: ``'lstm'``.
+        feat (List[str]):
+            Additional features to use, required if ``encoder='lstm'``.
+            ``'tag'``: POS tag embeddings.
+            ``'char'``: Character-level representations extracted by CharLSTM.
+            ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible.
+            Default: [``'char'``].
+        n_embed (int):
+            The size of word embeddings. Default: 100.
+        n_pretrained (int):
+            The size of pretrained word embeddings. Default: 100.
+        n_feat_embed (int):
+            The size of feature representations. Default: 100.
+        n_char_embed (int):
+            The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50.
+        n_char_hidden (int):
+            The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100.
+        char_pad_index (int):
+            The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0.
+        elmo (str):
+            Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``.
+        elmo_bos_eos (Tuple[bool]):
+            A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs.
+            Default: ``(True, False)``.
+        bert (str):
+            Specifies which kind of language model to use, e.g., ``'bert-base-cased'``.
+            This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_.
+            Default: ``None``.
+        n_bert_layers (int):
+            Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features.
+            The final outputs would be weighted sum of the hidden states of these layers.
+            Default: 4.
+        mix_dropout (float):
+            The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0.
+        bert_pooling (str):
+            Pooling way to get token embeddings.
+            ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all.
+            Default: ``mean``.
+        bert_pad_index (int):
+            The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features.
+            Default: 0.
+        finetune (bool):
+            If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``.
+        n_plm_embed (int):
+            The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0.
+        embed_dropout (float):
+            The dropout ratio of input embeddings. Default: .33.
+        n_encoder_hidden (int):
+            The size of encoder hidden states. Default: 800.
+        n_encoder_layers (int):
+            The number of encoder layers. Default: 3.
+        encoder_dropout (float):
+            The dropout ratio of encoder layer. Default: .33.
+        n_arc_mlp (int):
+            Arc MLP size. Default: 500.
+        n_sib_mlp (int):
+            Sibling MLP size. Default: 100.
+        n_rel_mlp  (int):
+            Label MLP size. Default: 100.
+        mlp_dropout (float):
+            The dropout ratio of MLP layers. Default: .33.
+        scale (float):
+            Scaling factor for affine scores. Default: 0.
+        pad_index (int):
+            The index of the padding token in the word vocabulary. Default: 0.
+        unk_index (int):
+            The index of the unknown token in the word vocabulary. Default: 1.
+
+    .. _transformers:
+        https://github.com/huggingface/transformers
+    """
+
+    def __init__(self,
+                 n_words,
+                 n_rels,
+                 n_tags=None,
+                 n_chars=None,
+                 encoder='lstm',
+                 feat=['char'],
+                 n_embed=100,
+                 n_pretrained=100,
+                 n_feat_embed=100,
+                 n_char_embed=50,
+                 n_char_hidden=100,
+                 char_pad_index=0,
+                 elmo='original_5b',
+                 elmo_bos_eos=(True, False),
+                 bert=None,
+                 n_bert_layers=4,
+                 mix_dropout=.0,
+                 bert_pooling='mean',
+                 bert_pad_index=0,
+                 finetune=False,
+                 n_plm_embed=0,
+                 embed_dropout=.33,
+                 n_encoder_hidden=800,
+                 n_encoder_layers=3,
+                 encoder_dropout=.33,
+                 n_arc_mlp=500,
+                 n_sib_mlp=100,
+                 n_rel_mlp=100,
+                 mlp_dropout=.33,
+                 scale=0,
+                 pad_index=0,
+                 unk_index=1,
+                 **kwargs):
+        super().__init__(**Config().update(locals()))
+
+        self.arc_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_arc_mlp, dropout=mlp_dropout)
+        self.arc_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_arc_mlp, dropout=mlp_dropout)
+        self.sib_mlp_s = MLP(n_in=self.args.n_encoder_hidden, n_out=n_sib_mlp, dropout=mlp_dropout)
+        self.sib_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_sib_mlp, dropout=mlp_dropout)
+        self.sib_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_sib_mlp, dropout=mlp_dropout)
+        self.rel_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_rel_mlp, dropout=mlp_dropout)
+        self.rel_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_rel_mlp, dropout=mlp_dropout)
+
+        self.arc_attn = Biaffine(n_in=n_arc_mlp, scale=scale, bias_x=True, bias_y=False)
+        self.sib_attn = Triaffine(n_in=n_sib_mlp, scale=scale, bias_x=True, bias_y=True)
+        self.rel_attn = Biaffine(n_in=n_rel_mlp, n_out=n_rels, bias_x=True, bias_y=True)
+        self.criterion = nn.CrossEntropyLoss()
+
+    def forward(self, words, feats=None):
+        r"""
+        Args:
+            words (~torch.LongTensor): ``[batch_size, seq_len]``.
+                Word indices.
+            feats (List[~torch.LongTensor]):
+                A list of feat indices.
+                The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``,
+                or ``[batch_size, seq_len]`` otherwise.
+                Default: ``None``.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor, ~torch.Tensor:
+                Scores of all possible arcs (``[batch_size, seq_len, seq_len]``),
+                dependent-head-sibling triples (``[batch_size, seq_len, seq_len, seq_len]``) and
+                all possible labels on each arc (``[batch_size, seq_len, seq_len, n_labels]``).
+        """
+
+        x = self.encode(words, feats)
+        mask = words.ne(self.args.pad_index) if len(words.shape) < 3 else words.ne(self.args.pad_index).any(-1)
+
+        arc_d = self.arc_mlp_d(x)
+        arc_h = self.arc_mlp_h(x)
+        sib_s = self.sib_mlp_s(x)
+        sib_d = self.sib_mlp_d(x)
+        sib_h = self.sib_mlp_h(x)
+        rel_d = self.rel_mlp_d(x)
+        rel_h = self.rel_mlp_h(x)
+
+        # [batch_size, seq_len, seq_len]
+        s_arc = self.arc_attn(arc_d, arc_h).masked_fill_(~mask.unsqueeze(1), MIN)
+        # [batch_size, seq_len, seq_len, seq_len]
+        s_sib = self.sib_attn(sib_s, sib_d, sib_h).permute(0, 3, 1, 2)
+        # [batch_size, seq_len, seq_len, n_rels]
+        s_rel = self.rel_attn(rel_d, rel_h).permute(0, 2, 3, 1)
+
+        return s_arc, s_sib, s_rel
+
+    def loss(self, s_arc, s_sib, s_rel, arcs, sibs, rels, mask, mbr=True, partial=False):
+        r"""
+        Args:
+            s_arc (~torch.Tensor): ``[batch_size, seq_len, seq_len]``.
+                Scores of all possible arcs.
+            s_sib (~torch.Tensor): ``[batch_size, seq_len, seq_len, seq_len]``.
+                Scores of all possible dependent-head-sibling triples.
+            s_rel (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``.
+                Scores of all possible labels on each arc.
+            arcs (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The tensor of gold-standard arcs.
+            sibs (~torch.LongTensor): ``[batch_size, seq_len, seq_len]``.
+                The tensor of gold-standard siblings.
+            rels (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The tensor of gold-standard labels.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens.
+            mbr (bool):
+                If ``True``, returns marginals for MBR decoding. Default: ``True``.
+            partial (bool):
+                ``True`` denotes the trees are partially annotated. Default: ``False``.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor:
+                The training loss and
+                original arc scores of shape ``[batch_size, seq_len, seq_len]`` if ``mbr=False``, or marginals otherwise.
+        """
+
+        arc_dist = Dependency2oCRF((s_arc, s_sib), mask.sum(-1))
+        arc_loss = -arc_dist.log_prob((arcs, sibs), partial=partial).sum() / mask.sum()
+        if mbr:
+            s_arc, s_sib = arc_dist.marginals
+        # -1 denotes un-annotated arcs
+        if partial:
+            mask = mask & arcs.ge(0)
+        s_rel, rels = s_rel[mask], rels[mask]
+        s_rel = s_rel[torch.arange(len(rels)), arcs[mask]]
+        rel_loss = self.criterion(s_rel, rels)
+        loss = arc_loss + rel_loss
+        return loss, s_arc, s_sib
+
+    def decode(self, s_arc, s_sib, s_rel, mask, tree=False, mbr=True, proj=False):
+        r"""
+        Args:
+            s_arc (~torch.Tensor): ``[batch_size, seq_len, seq_len]``.
+                Scores of all possible arcs.
+            s_sib (~torch.Tensor): ``[batch_size, seq_len, seq_len, seq_len]``.
+                Scores of all possible dependent-head-sibling triples.
+            s_rel (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``.
+                Scores of all possible labels on each arc.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens.
+            tree (bool):
+                If ``True``, ensures to output well-formed trees. Default: ``False``.
+            mbr (bool):
+                If ``True``, performs MBR decoding. Default: ``True``.
+            proj (bool):
+                If ``True``, ensures to output projective trees. Default: ``False``.
+
+        Returns:
+            ~torch.LongTensor, ~torch.LongTensor:
+                Predicted arcs and labels of shape ``[batch_size, seq_len]``.
+        """
+
+        lens = mask.sum(1)
+        arc_preds = s_arc.argmax(-1)
+        bad = [not CoNLL.istree(seq[1:i+1], proj) for i, seq in zip(lens.tolist(), arc_preds.tolist())]
+        if tree and any(bad):
+            if proj:
+                arc_preds[bad] = Dependency2oCRF((s_arc[bad], s_sib[bad]), mask[bad].sum(-1)).argmax
+            else:
+                arc_preds[bad] = MatrixTree(s_arc[bad], mask[bad].sum(-1)).argmax
+        rel_preds = s_rel.argmax(-1).gather(-1, arc_preds.unsqueeze(-1)).squeeze(-1)
+
+        return arc_preds, rel_preds
diff --git a/tania_scripts/supar/models/dep/crf2o/parser.py b/tania_scripts/supar/models/dep/crf2o/parser.py
new file mode 100644
index 0000000..c822b2a
--- /dev/null
+++ b/tania_scripts/supar/models/dep/crf2o/parser.py
@@ -0,0 +1,216 @@
+# -*- coding: utf-8 -*-
+
+import os
+from typing import Iterable, Union
+
+import torch
+
+from supar.models.dep.biaffine.parser import BiaffineDependencyParser
+from supar.models.dep.biaffine.transform import CoNLL
+from supar.models.dep.crf2o.model import CRF2oDependencyModel
+from supar.structs import Dependency2oCRF
+from supar.utils import Config, Dataset, Embedding
+from supar.utils.common import BOS, PAD, UNK
+from supar.utils.field import ChartField, Field, RawField, SubwordField
+from supar.utils.fn import ispunct
+from supar.utils.logging import get_logger
+from supar.utils.metric import AttachmentMetric
+from supar.utils.tokenizer import TransformerTokenizer
+from supar.utils.transform import Batch
+
+logger = get_logger(__name__)
+
+
+class CRF2oDependencyParser(BiaffineDependencyParser):
+    r"""
+    The implementation of second-order CRF Dependency Parser :cite:`zhang-etal-2020-efficient`.
+    """
+
+    NAME = 'crf2o-dependency'
+    MODEL = CRF2oDependencyModel
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+    def train(
+        self,
+        train: Union[str, Iterable],
+        dev: Union[str, Iterable],
+        test: Union[str, Iterable],
+        epochs: int = 1000,
+        patience: int = 100,
+        batch_size: int = 5000,
+        update_steps: int = 1,
+        buckets: int = 32,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        punct: bool = False,
+        mbr: bool = True,
+        tree: bool = False,
+        proj: bool = False,
+        partial: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().train(**Config().update(locals()))
+
+    def evaluate(
+        self,
+        data: Union[str, Iterable],
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        punct: bool = False,
+        mbr: bool = True,
+        tree: bool = True,
+        proj: bool = True,
+        partial: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().evaluate(**Config().update(locals()))
+
+    def predict(
+        self,
+        data: Union[str, Iterable],
+        pred: str = None,
+        lang: str = None,
+        prob: bool = False,
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        mbr: bool = True,
+        tree: bool = True,
+        proj: bool = True,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().predict(**Config().update(locals()))
+
+    def train_step(self, batch: Batch) -> torch.Tensor:
+        words, _, *feats, arcs, sibs, rels = batch
+        mask = batch.mask
+        # ignore the first token of each sentence
+        mask[:, 0] = 0
+        s_arc, s_sib, s_rel = self.model(words, feats)
+        loss, *_ = self.model.loss(s_arc, s_sib, s_rel, arcs, sibs, rels, mask, self.args.mbr, self.args.partial)
+        return loss
+
+    @torch.no_grad()
+    def eval_step(self, batch: Batch) -> AttachmentMetric:
+        words, _, *feats, arcs, sibs, rels = batch
+        mask = batch.mask
+        # ignore the first token of each sentence
+        mask[:, 0] = 0
+        s_arc, s_sib, s_rel = self.model(words, feats)
+        loss, s_arc, s_sib = self.model.loss(s_arc, s_sib, s_rel, arcs, sibs, rels, mask, self.args.mbr, self.args.partial)
+        arc_preds, rel_preds = self.model.decode(s_arc, s_sib, s_rel, mask, self.args.tree, self.args.mbr, self.args.proj)
+        if self.args.partial:
+            mask &= arcs.ge(0)
+        # ignore all punctuation if not specified
+        if not self.args.punct:
+            mask.masked_scatter_(mask, ~mask.new_tensor([ispunct(w) for s in batch.sentences for w in s.words]))
+        return AttachmentMetric(loss, (arc_preds, rel_preds), (arcs, rels), mask)
+
+    @torch.no_grad()
+    def pred_step(self, batch: Batch) -> Batch:
+        words, _, *feats = batch
+        mask, lens = batch.mask, batch.lens - 1
+        # ignore the first token of each sentence
+        mask[:, 0] = 0
+        s_arc, s_sib, s_rel = self.model(words, feats)
+        s_arc, s_sib = Dependency2oCRF((s_arc, s_sib), lens).marginals if self.args.mbr else (s_arc, s_sib)
+        arc_preds, rel_preds = self.model.decode(s_arc, s_sib, s_rel, mask, self.args.tree, self.args.mbr, self.args.proj)
+        lens = lens.tolist()
+        batch.arcs = [i.tolist() for i in arc_preds[mask].split(lens)]
+        batch.rels = [self.REL.vocab[i.tolist()] for i in rel_preds[mask].split(lens)]
+        if self.args.prob:
+            arc_probs = s_arc if self.args.mbr else s_arc.softmax(-1)
+            batch.probs = [prob[1:i+1, :i+1].cpu() for i, prob in zip(lens, arc_probs.unbind())]
+        return batch
+
+    @classmethod
+    def build(cls, path, min_freq=2, fix_len=20, **kwargs):
+        r"""
+        Build a brand-new Parser, including initialization of all data fields and model parameters.
+
+        Args:
+            path (str):
+                The path of the model to be saved.
+            min_freq (str):
+                The minimum frequency needed to include a token in the vocabulary. Default: 2.
+            fix_len (int):
+                The max length of all subword pieces. The excess part of each piece will be truncated.
+                Required if using CharLSTM/BERT.
+                Default: 20.
+            kwargs (Dict):
+                A dict holding the unconsumed arguments.
+        """
+
+        args = Config(**locals())
+        os.makedirs(os.path.dirname(path) or './', exist_ok=True)
+        if os.path.exists(path) and not args.build:
+            parser = cls.load(**args)
+            parser.model = cls.MODEL(**parser.args)
+            parser.model.load_pretrained(parser.transform.FORM[0].embed).to(parser.device)
+            return parser
+
+        logger.info("Building the fields")
+        TAG, CHAR, ELMO, BERT = None, None, None, None
+        if args.encoder == 'bert':
+            t = TransformerTokenizer(args.bert)
+            WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, fix_len=args.fix_len, tokenize=t)
+            WORD.vocab = t.vocab
+        else:
+            WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, lower=True)
+            if 'tag' in args.feat:
+                TAG = Field('tags', bos=BOS)
+            if 'char' in args.feat:
+                CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, fix_len=args.fix_len)
+            if 'elmo' in args.feat:
+                from allennlp.modules.elmo import batch_to_ids
+                ELMO = RawField('elmo')
+                ELMO.compose = lambda x: batch_to_ids(x).to(WORD.device)
+            if 'bert' in args.feat:
+                t = TransformerTokenizer(args.bert)
+                BERT = SubwordField('bert', pad=t.pad, unk=t.unk, bos=t.bos, fix_len=args.fix_len, tokenize=t)
+                BERT.vocab = t.vocab
+        TEXT = RawField('texts')
+        ARC = Field('arcs', bos=BOS, use_vocab=False, fn=CoNLL.get_arcs)
+        SIB = ChartField('sibs', bos=BOS, use_vocab=False, fn=CoNLL.get_sibs)
+        REL = Field('rels', bos=BOS)
+        transform = CoNLL(FORM=(WORD, TEXT, CHAR, ELMO, BERT), CPOS=TAG, HEAD=(ARC, SIB), DEPREL=REL)
+
+        train = Dataset(transform, args.train, **args)
+        if args.encoder != 'bert':
+            WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x))
+            if TAG is not None:
+                TAG.build(train)
+            if CHAR is not None:
+                CHAR.build(train)
+        REL.build(train)
+        args.update({
+            'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init,
+            'n_rels': len(REL.vocab),
+            'n_tags': len(TAG.vocab) if TAG is not None else None,
+            'n_chars': len(CHAR.vocab) if CHAR is not None else None,
+            'char_pad_index': CHAR.pad_index if CHAR is not None else None,
+            'bert_pad_index': BERT.pad_index if BERT is not None else None,
+            'pad_index': WORD.pad_index,
+            'unk_index': WORD.unk_index,
+            'bos_index': WORD.bos_index
+        })
+        logger.info(f"{transform}")
+
+        logger.info("Building the model")
+        model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None)
+        logger.info(f"{model}\n")
+
+        parser = cls(args, model, transform)
+        parser.model.to(parser.device)
+        return parser
diff --git a/tania_scripts/supar/models/dep/eager/__init__.py b/tania_scripts/supar/models/dep/eager/__init__.py
new file mode 100644
index 0000000..c3e9859
--- /dev/null
+++ b/tania_scripts/supar/models/dep/eager/__init__.py
@@ -0,0 +1,2 @@
+from .parser import ArcEagerDependencyParser
+from .model import ArcEagerDependencyModel
\ No newline at end of file
diff --git a/tania_scripts/supar/models/dep/eager/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..69b6b347907cd94bda81a4738bf8e7e85860c421
GIT binary patch
literal 273
zcmd1j<>g{vU|`^9Uz8rsz`*br#6iYP3=9ko3=9m#G7Jn1DGVu$ISjdsQH+crHd78$
zE^`z!BSQ*vFoPz`OGX9;22I9W5{^a5u8HZXMJ}lYsd*`>dC8RliABY!MVgGa#4+W3
z^HWlD{4`l^u@!(-6@je0#hMEeE@Eb2U|7je#Kyn?A%1!2XXNLm>X#&zWG3b%>LukQ
zrevlT=_lvs7Ub)u7nJCN_30Ov79<wwgW1LUDX9hesUQdG$H!;pWtPOp>lIYq;;_lh
VPbtkwwF5c3n1z9XfrmkW5db~bNI3ui

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e4eb2047d9191fa7725d4f6c991fbd42ac25afea
GIT binary patch
literal 333
zcmZ3^%ge>Uz`&q%Uo|6~fq~&Mhy%k+P{wCD1_p-d3@HpLj5!Rsj8Tk?AU0DDQ!aB9
zGb2L^b1;J@%S%QE1_n*WTM~{%$*zg%sYNcS1*v%{sd>qj0f|M$sYRNMx5P2!eDhOM
zbNn<}Zm|`BRTVKaFfiO=%>@Y;u`n<&tYr8Ma>lPP{fzwFRQ-~~lFY=sM7^Y(#FWg`
zBK_q2+=6`FlGKV4-PE$g9Q~5Syv)S-;^d;tf|6qW;?jb|B7Lx7#ri3!1^THVm+8mH
zXXa&=#K-FuRQ}?y$<0qG%}KQ@0tE!f6UF)r3=AKb85tRGFz8%BMK>6<E?`4N91IK$
E0J_UxVgLXD

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/__pycache__/model.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c35f8752a167848718305af293b7ba376172b991
GIT binary patch
literal 6877
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/__pycache__/model.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..cd043bef1f8af3f5ca69f649ed48a44101524e37
GIT binary patch
literal 11595
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
FPXNKi27dqm

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/__pycache__/parser.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4f44d08db4b5106cd902edd53576ffd54fc22572
GIT binary patch
literal 14058
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/__pycache__/parser.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c53842f2152b6d56e2c6e8626ae48e37586c53a4
GIT binary patch
literal 29283
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/__pycache__/transform.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/__pycache__/transform.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..35d39d5378eae49dfe2f72c59831aec35703b2ca
GIT binary patch
literal 7792
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
R3?mOCq*Wxq%up}F3;;PSl=J`q

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/__pycache__/transform.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/__pycache__/transform.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fbdee27774e2be073b02a1de3f1e5540e6c700cf
GIT binary patch
literal 13871
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/model.py b/tania_scripts/supar/models/dep/eager/model.py
new file mode 100644
index 0000000..300e829
--- /dev/null
+++ b/tania_scripts/supar/models/dep/eager/model.py
@@ -0,0 +1,198 @@
+import torch
+import torch.nn as nn
+from supar.model import Model
+from supar.modules import MLP, DecoderLSTM
+from supar.utils import Config
+from typing import Tuple, List
+
+class ArcEagerDependencyModel(Model):
+
+    def __init__(self,
+                 n_words,
+                 n_transitions,
+                 n_trels,
+                 n_tags=None,
+                 n_chars=None,
+                 encoder='lstm',
+                 feat=['char'],
+                 n_embed=100,
+                 n_pretrained=100,
+                 n_feat_embed=100,
+                 n_char_embed=50,
+                 n_char_hidden=100,
+                 char_pad_index=0,
+                 elmo='original_5b',
+                 elmo_bos_eos=(True, False),
+                 bert=None,
+                 n_bert_layers=4,
+                 mix_dropout=.0,
+                 bert_pooling='mean',
+                 bert_pad_index=0,
+                 finetune=False,
+                 n_plm_embed=0,
+                 embed_dropout=.33,
+                 n_encoder_hidden=800,
+                 n_encoder_layers=3,
+                 encoder_dropout=.33,
+                 n_arc_mlp=500,
+                 n_rel_mlp=100,
+                 mlp_dropout=.33,
+                 scale=0,
+                 pad_index=0,
+                 unk_index=1,
+                 n_decoder_layers=4,
+                 **kwargs):
+        super().__init__(**Config().update(locals()))
+
+        # create decoder for buffer front, stack top and rels
+        self.transition_decoder = self.rel_decoder = None, None
+
+        stack_size, buffer_size = [self.args.n_encoder_hidden//2] * 2 if (self.args.n_encoder_hidden % 2) == 0 \
+            else [self.args.n_encoder_hidden//2, self.args.n_encoder_hidden//2+1]
+
+        # create projection to reduce dimensionality of the encoder
+        self.stack_proj = MLP(
+                n_in=self.args.n_encoder_hidden, n_out=stack_size,
+                dropout=mlp_dropout)
+        self.buffer_proj = MLP(
+            n_in=self.args.n_encoder_hidden, n_out=buffer_size,
+            dropout=mlp_dropout
+        )
+
+        if self.args.decoder == 'lstm':
+            decoder = lambda out_dim: DecoderLSTM(
+                self.args.n_encoder_hidden, self.args.n_encoder_hidden, out_dim,
+                self.args.n_decoder_layers, dropout=mlp_dropout, device=self.device
+            )
+        else:
+            decoder = lambda out_dim: MLP(
+                n_in=self.args.n_encoder_hidden, n_out=out_dim, dropout=mlp_dropout
+            )
+
+        self.transition_decoder = decoder(n_transitions)
+        self.trel_decoder = decoder(n_trels)
+
+        # create delay projection
+        if self.args.delay != 0:
+            self.delay_proj = MLP(n_in=self.args.n_encoder_hidden * (self.args.delay + 1),
+                                  n_out=self.args.n_encoder_hidden, dropout=mlp_dropout)
+
+        # create PoS tagger
+        if self.args.encoder in ['lstm', 'bert']:
+            self.pos_tagger = DecoderLSTM(
+                self.args.n_encoder_hidden, self.args.n_encoder_hidden, self.args.n_tags, 
+                num_layers=1, dropout=mlp_dropout, device=self.device
+            )
+        else:
+            #args.encoder is bert
+            self.pos_tagger = nn.Identity()
+
+        self.criterion = nn.CrossEntropyLoss()
+
+    def encoder_forward(self, words: torch.Tensor, feats: List[torch.Tensor]) -> Tuple[torch.Tensor]:
+        """
+        Applies encoding forward pass. Maps a tensor of word indices (`words`) to their corresponding neural
+        representation.
+        Args:
+            words: torch.IntTensor ~ [batch_size, bos + pad(seq_len) + eos + delay]
+            feats: List[torch.Tensor]
+            lens: List[int]
+
+        Returns: x, qloss
+            x: torch.FloatTensor ~ [batch_size, bos + pad(seq_len) + eos, embed_dim]
+            qloss: torch.FloatTensor ~ 1
+
+        """
+
+        x = super().encode(words, feats)
+        s_tag = self.pos_tagger(x[:, 1:-(1+self.args.delay), :])
+
+        # adjust lengths to allow delay predictions
+        # x ~ [batch_size, bos + pad(seq_len) + eos, embed_dim]
+        if self.args.delay != 0:
+            x = torch.cat([x[:, i:(x.shape[1] - self.args.delay + i), :] for i in range(self.args.delay + 1)], dim=2)
+            x = self.delay_proj(x)
+
+        # pass through vector quantization
+        x, qloss = self.vq_forward(x)
+        return x, s_tag, qloss
+
+    def decoder_forward(self, x: torch.Tensor, stack_top: torch.Tensor, buffer_front: torch.Tensor) -> Tuple[torch.Tensor]:
+        """
+        Args:
+            x: torch.FloatTensor ~ [batch_size, bos + pad(seq_len) + eos, embed_dim]
+            stack_top: torch.IntTensor ~ [batch_size, pad(tr_len)]
+            buffer_front: torch.IntTensor ~ [batch_size, pad(tr_len)]
+
+        Returns: s_transition, s_trel
+            s_transition: torch.FloatTensor ~ [batch_size, pad(tr_len), n_transitions]
+            s_trel: torch.FloatTensor ~ [batch_size, pad(tr_len), n_trels]
+        """
+        batch_size = x.shape[0]
+
+        # obtain encoded embeddings for stack_top and buffer_front
+        stack_top = torch.stack([x[i, stack_top[i], :] for i in range(batch_size)])
+        buffer_front = torch.stack([x[i, buffer_front[i], :] for i in range(batch_size)])
+
+        # pass through projections
+        stack_top = self.stack_proj(stack_top)
+        buffer_front = self.buffer_proj(buffer_front)
+
+        # stack_top ~ [batch_size, pad(tr_len), embed_dim//2]
+        # buffer_front ~ [batch_size, pad(tr_len), embed_dim//2]
+        # x ~ [batch_size, pad(tr_len), embed_dim]
+        x = torch.concat([stack_top, buffer_front], dim=-1)
+        
+        # s_transition ~ [batch_size, pad(tr_len), n_transitions]
+        # s_trel = [batch_size, pad(tr_len), n_trels]
+        s_transition = self.transition_decoder(x)
+        s_trel = self.trel_decoder(x)
+
+        return s_transition, s_trel
+
+    def forward(self, words: torch.Tensor, stack_top: torch.Tensor, buffer_front: torch.Tensor, feats: List[torch.Tensor]) -> Tuple[torch.Tensor]:
+        """
+        Args:
+            words: torch.IntTensor ~ [batch_size, bos + pad(seq_len) + eos + delay].
+            stack_top: torch.IntTensor ~ [batch_size, pad(tr_len)]
+            buffer_front: torch.IntTensor ~ [batch_size, pad(tr_len)]
+            feats: List[torch.Tensor]
+
+        Returns: s_transition, s_trel, qloss
+            s_transition: torch.FloatTensor ~ [batch_size, pad(tr_len), n_transitions]
+            s_trel: torch.FloatTensor ~ [batch_size, pad(tr_len), n_trels]
+            qloss: torch.FloatTensor ~ 1
+        """
+        x, s_tag, qloss = self.encoder_forward(words, feats)
+
+        s_transition, s_trel = self.decoder_forward(x, stack_top, buffer_front)
+        return s_transition, s_trel, s_tag, qloss
+
+    def decode(self, s_transition: torch.Tensor, s_trel: torch.Tensor, exclude: list = None):
+        transition_preds = s_transition.argsort(-1, descending=True)
+        if exclude:
+            s_trel[:, :, exclude] = -1
+        trel_preds = s_trel.argmax(-1)
+        return transition_preds, trel_preds
+    
+    def decode_stag(self, s_tag: torch.Tensor):
+        stag_preds = s_tag.argmax(-1)
+        #stag_preds = s_tag.argsort(-1, descending=True)
+        return stag_preds
+
+    def loss(self, s_transition: torch.Tensor, s_trel: torch.Tensor, s_tag,
+             transitions: torch.Tensor, trels: torch.Tensor, tags,
+             smask: torch.Tensor, trmask: torch.Tensor, TRANSITION):
+        s_transition, transitions = s_transition[trmask], transitions[trmask]
+        s_trel, trels = s_trel[trmask], trels[trmask]
+
+        # remove those values in trels that correspond to shift and reduce actions
+        transition_pred = TRANSITION.vocab[s_transition.argmax(-1).flatten().tolist()]
+        trel_mask = torch.tensor(list(map(lambda x: x not in ['reduce', 'shift'], transition_pred)))
+        s_trel, trels = s_trel[trel_mask], trels[trel_mask]
+
+        tag_loss = self.criterion(s_tag[smask], tags[smask]) if self.args.encoder == 'lstm' else torch.tensor(0).to(self.device)
+        transition_loss = self.criterion(s_transition, transitions)
+        trel_loss = self.criterion(s_trel, trels)
+
+        return transition_loss + trel_loss + tag_loss
diff --git a/tania_scripts/supar/models/dep/eager/oracle/__init__.py b/tania_scripts/supar/models/dep/eager/oracle/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5cf072a90eda87b6f954a0a161965c253cafd1b1
GIT binary patch
literal 172
zcmd1j<>g{vU|`^9Uz84_AA<;F%*epN;K0DZP|U)>z>vZa%%I8Wx00a<B#a<_`Rixo
z=cekHB$i|*<|XPS<s_zLrWWZZ=jRsW>!uf!=;r39q~_=smlh-z>4VwD`YEXe`l*TO
tsYUwvMTyBdsrvEpnR%Hd@$q^EmA5!-a`RJ4b5iX<78NrwFfgz%002-#DbxS}

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..13ce2553293d74a70524325df69e92ffe8f7771d
GIT binary patch
literal 202
zcmZ3^%ge>Uz`&q%Uo`_nKL!yn%m`(CW@BJrn9h*G5X_*-=(m!gh>3xL;WJ3`SFC<U
zer~FMNn%N6VqT(NQchw@W@?dsa(-?>zHUisMTu@|Sz?ZUNn&1RVtjFOQD#9&v3_xB
zL1K}9ZhlH?PO*MUYJq-gVtQ(ketuD6a!#s#e0*kJW=VX!UP0wA4x8Nkl+v73yCPNw
b1_qFOiuoBB7(OsFGBSQ(fDuK^3=9kajjc5m

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/arceager.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/arceager.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..93488668e82fa23ba9e3ff1768cb420f90132ce3
GIT binary patch
literal 7330
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
Q0rN0GhL{8x`Iv;_0n}~H=>Px#

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/arceager.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/arceager.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..09ee22f8790adc5bbc67d6acfbc51c23685850e4
GIT binary patch
literal 15872
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
FP5^kB=zstK

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/buffer.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/buffer.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..41d88bf55396dcd614cb06abfdcd6cdd80a64562
GIT binary patch
literal 1286
zcmd1j<>g{vU|`^9Uz9G-#K7<v#6iZ)3=9ko3=9m#dJGH<DGVu$ISjdsQH;4vQA~^=
zK2r{JE=v>(BZE6b3Udle3quM^GgB063TrTfCfiGpNt#TzIQ$DrGV}8ib8fNtWEPib
zGTvhG%TGy721z4h7MNu*3=9mZ3{i|J3{gxejH%42EUB!L43Z3KOest$%q=WYY$+_M
ztZ7UstSM|QEK%%G9(xK$3riG73MW{OD}}p-C5khJCxy3#A&M)7FNME_A&NUiAecc@
z@D`g>X<Axp(Jj`@lGNPdWF{ncfY>1H4Dz=G0|P@1V-b4|V+}(*LkdGMLplSDwUW_q
zC1VjA0|SF5(=C?b)SNUhXC*@sC{Ta->SyHVrs|g@mSiU8CF&*RB&KAh7U?JF=N9Da
zrWcgx=H{oQ=I9rf79<wwgW1LUDX9hesfp>SMf&+giOD&s`bl7C>J?Pp;)svW%*!l^
zk7otB3uG$`BNrnVQx!kND|#^bTWm$CC8b4q$&5&z0<qzq0y(dSA&Vh}QIa8;VI`Aa
z5lFg-gMoozC1VjM0|UedU~d$0GcYjRVopyj0Wm&<%-~|I;)2?lo?3!o4Jgfk!;S|O
zb_`hz3m8)v7cvGj6!C$B3LHqcm<#d?iukcu#a5J>n_rd+Qd<nNjfb&{7it?s<`xSm
z&M=}3Zmj^^+8V}%jG$y1%uvLRWHno2K|yL>iY61pt0I_=C=z90U=Rd_Gsp!32p2$f
zVt5&(3gqR_ppY$LsA0%rYzBE4V(TsDoYXw9ud#ZVJw84sH7`CM><*BnReVtYLM3oo
zS0n~<I?R&dk|NxeaKy(Kr4|&$$BTosfNepf8;FdbCJ!i)<t65(#>d~{ijU9DPbtj-
zv3cU-3riDoATmWD&lZ6~y9ktFi$Jkl1Pb#aVUW?FkShY^nj$F>7Zf0nbOdIB(ohj7
z0fV#_gW{NjL5z`)jgOg+nS+^!87$|g$##paq_QA0FCAgoEhTV9(Su|Zy_D1fJ#a?R
ngJcxFy!@0@h=V}JBUuTz_ZEi@#7B0Z)LsnAK>`dsj6zHRAy@Y>

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/buffer.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/buffer.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c22b12dc825c9a45c4c9b0f8e44b31477268e653
GIT binary patch
literal 1846
zcmZ3^%ge>Uz`&q%Uo}IXiGkrUhy%kcP{wB)1_p-d3@HpLj5!Rsj8TlaOi@gXAU;zL
zb1q913nK#)gF8bCa|=TX%Q7YghSf|^oeWW|DXhT^nrtsY0-8*>IQ$DrGV}8ib8fNt
zWEPibGTvhG%TGy721&y(+}b3twW$nIj42FJOeu`1%&9D?tdcNw3<y>lQwmcHOB7oQ
zb1G{ZQwmE9OB6el&Dz2e#gW1W7H4l^iQ-J*Xkm!rO5to_h~iG+3TDvczQyKLnwFMY
zbc;2!BsI4<8SZ)p1_ltDnSp`fvliGfHH<}^HH<Y3@o-0^Fa$HCGoXvCWb|9fSj54=
zz@W)=i={X<Ck@Og1{tTI@GDwBBR@A)za+6FGchkwFDWN6B{Q{1KRG|QAYZp6wW35f
zwJb45za%j)Gcmq6xhS)sq*%YWv>>raKQ})mHK$lVCAC05H8DN4NI$<QF*zqyKMCvw
zy@JYH9P#m)d6^~g@m2f~f9b&lSQ!`?iWL|b7#bLEa0`53VCIy$At~44(&N?P)#3F(
zQX0nm4D#MBwxZOM(xSX%Mi38*K^_2yhYTb<7_y)e3=AoZhzJR0Sjps91X5hY&A`C0
zlCg*fWH-npg(6-C28LVA>8T}ETu=w5r<Q<}74t#d#xLAcHAAtd_5z1Y5kCV11Bwek
zwuA6zGYl6j0GSVW4~&t*xQvm3VKrPXn4w4r95LW1xy4+NUr;2B<~p{b)ZF~C)GA)6
z10h_H^NPg~ZtSn?s+*B`kze5ozrqC$1+ZIhv49d0N*V&W7KA@r5$WO@G#7*NS};Qq
zD5q*NL0rw2SWu9fm!io84%i|Iko!TwtpEw$A}Iz22Ds}XY6U@R<RGr+;OXJI&LMe;
zLvn`7MGpBZ9P$@n2<!{&Ar8p{CGe1BV5nipg7Yv!8RFhs%sHufU`JzwGJAY{PHJ9!
zd=(!wn4x?TP=*r#yYw!<&;*kyR-N@d^%pqgsPDGok|OMG<A{$hN-Zct$wd$WaRvs4
zB2YMjUE`<81IlrEiMgrq@wd3*<8$*<N^?MLp7{8}(!?ByOc5vn6oHDiB2X?Y0wtv)
zkUxvS#(|=%NET$UA}G5sfQ<%clp=PJD2M=QE?y1}l?Da~{J_M*Dl;QvLCFf2B~@4C
zj6N{1u*#qlJdCWe6GA>PFtW;`6KssEiZfV1qKfDQ8zZa23=@#30y@FQ$SMyKgA!<5
z2AC|w4<MKOX|mm7E2%8V%u7dv!!0Fnfu;v3(DYJL3-rJRnjWM;)62_GNri+J$cQ3U
zP%wZB18}JP;;?~)vt5w}0|Nsn4HhRdFfe>zW@Kc%!Jv2n8@j<@d;t}GU=d-I|G<Dr
Pd<2Po0TF1jU{3)6zrJ=@

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/dependency.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/dependency.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7fce37dccace89b6d7436c953040e05640fbe754
GIT binary patch
literal 1544
zcmd1j<>g{vU|`^9UzBdk%)sy%#6iZ)3=9ko3=9m#HVh05DGVu$ISjdsQH;4vQA~^=
zK2r{JE=v>(BZE6b3Udle3quM^GgB0+J3|U<3R??93R^Q%6k7^=FoPz?OOUymOt(1v
z3raHc^AdAzvG`;bmuNEHV)4sQNlgYxBV#t0)kX{q45<uJj42FJOeu`1%qdK%EGf*X
zENN^hEGeulEK#f}Y$@z53{h+;94VYF3{mVUT)_;Q+_$(~QVUY^Qd0AhD{t|nK-nen
znJKr}Gg1>%Kn%8&)PkbaoMaXxn?Y<Q1_lOakiW$k7#M08YZ&4gYM5#m;u&k0YZ&60
zQW%06Rx<i&G8chdS;Wr3z)-}&z`&r%a*L%nH75;CcqKy-Hv<F1uR#5b{M=OilEjkC
z#Johkq@2W*%+w<N<ow)%eBJbd65ZVVl++yk;?jb|B7HEsSU)ATKtDAxJ+(+bzbG*|
zClw?B^^{&g<t>i*_{_Y_lK6O5kZVD%VPj-t<YKH6MtEKirY4yY$(tZH+?ycB*Dx$#
zSjZ5}P{axH3F9sHlKkZSyquhsj76YC0`>xg;9+230NGrWT2K@p50WefnZ$u^D?}c{
zR*+M{fhz|}RE!H4N*HSxvY46~!8CI-h{ux7ypS=NVI`B_FGfyH)>|xD`I&jQn2Sq_
z(89Ke9~AhY;6=Eth>wARffp7aEQ}(IZ2zl-kOBniGe1oZkT>!Yb5rBvZ*j%P=jNxB
z=788d@$rSFi8)Xi=FGg3A`y^1AVZ4;KrE0I5F63#2Kf$@go;67%E2JU$id3PTm%xu
zNa7$B;M}E$BZ;T5q%x;*fb$Y4nX{*GfRj0AFoP!7Ev}HF#Ju86P-eQtQc_uvdW*BT
zBr!QVz9hfk7Ee-XT3TvRd|FX{UI{pDCWD*+i+>Os6lLIOkYT`<#%ow=7~+{hDIJm^
zSc;@T{+0$2ARS;sHCZ8P1B(<=;DFLg5h&<{L2&}|H7Jonk}1LyxRWU;S%Y1whLT{i
zn4w9A1;nah$YQNw$YM)l0VSLwK~N%QF9O*Ji8_$OZ?U-f2l*C(oey?0$Sqh?5Gal%
zL9PXbk{V-`Fp4`N3ENMTy+{-k9H2s?NF2lhClXNXgS`t$DTwp|W`P3(WV8^-c#zjP
z7^E0^*or`6ewysJ*h(r3GV{`lKsFbF3gBBx;1WR(QX=T3q!#FbO9VYgiJ+I4pORVx
jwiFbtU~`ZHA8zR_4jV}NwgY8-aPkyj;9=xr65;~@R5>pn

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/dependency.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/dependency.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e9534220075a54bc9b129b311b945ea708d02dc8
GIT binary patch
literal 2377
zcmZ3^%ge>Uz`&q%Up2#)nStRkhy%kcP{!vl1_p-d3@HpLj5!Rsj8TlaOi@gXAU;zL
zb1q913nK#)gF8bCa|=TX%Q7YghSf|^oeWW|U>VjHh7>k58MYMmU<OT&mmsB@Ot(1v
z3raHc^AdAzvG`;bmuNEHV)4sQNlgYx!!R3^@mUY-pj3t^#uSDqrWD3h<`kw>mK5ex
zmNd2$mKK&M))dwjhA6fawibpcc8Eo{xLi^TQu9($^O7rX@uWc6CGnXlx7agM6H`D8
zwv^O@qSTyZn9o7>f&9YEz`*d?0BmUuV+}(*NF0o7m}(f}8No~j28J5u8isg~daytW
zLomZiMn6sFA`S)yh9XW70SatQmRl^vsX1wA!o?s<6%-T{e#Pr&<maa9mn4>CCgvsT
zCFLZhWTqDBC+FuD<m;BCR+Q+bmL=xsmn7z8CdL;h7iAWd6zdn479<ww=jNxR<`nCv
zq!#F>CZ?wr>E{<ECg-Gr1fX8mE2zB15g(tKmst`YUnPtP6Frz9D+2>Vu?zzPLj%JN
z8I2B>D;$zH#N|3zdU$S#$#k&vaCdNbaDN7QF&XZ21_lO@zro?81qmmH1t29Dco_o&
z!)mx_Fhda!0|SF5<1O}*{N((+oSc=6MZ6#ffQ(is;$vW706DiPwV(*Yxe!56kQNI-
zoXaoVU(;37S=Uo{fkU<kB#7cfQ2GHou?6hJ6h`b$ECH#3I<bZ!3*<2{Zy6&4!)lPb
zz&tcna6PE1Y8bLW@e0<F&WtJ-%&?Nl?-wJdChIMhto+QpTg=5JMQEv_NEkIRii8*#
z7^;Mjq752u;6Ss62Sa67<y{{B2`pCx6fg29UExt$>b!zw4bMdt(<>^b8%nlRe_&>k
z;`+$IB*6UzM0{Xi;^YR0n4cyGD8%y;b5rBvZ*j%P=jNxB=788d@$rSFi8)Xi=FGg3
zB1ur9<_8fXAOhsLl?-5Gz)@Gk4iW_spg<^&20O2T0RlfTF|*1p2>!sp%qqLV7)%{t
z22<z+7bC0O2L?F7#>~nMQi4uE>;>6|Qfh#5A1M4k>wse&Td9%4lFFRMk-`ctIY4Cw
zv~aq`6;hO#SDXndnQpO^R2HP(;w&ynOwNuk$uGFYlT@0PmRb~_R+OJtQUpqe$)LOg
zvI~Sk=?0W4KHGuqCBEROVX0w=2k8Wv!T>5pAen@vND&mAN+3cRM1ZW+WCiCJY*NJ_
z*MLeCNIoh8#Z#3q!bk8N4^Cqs6B`(Ah)8s>^l;vgRO(>q;e+RYM8*dPGWJ}x1nf^z
zb5$1Hr>MCDEq{R$5I8(=sjp$k0{IuLriLL4l-I%RG!|5IgBgm%Kt&FFkpw6V!6_IN
zq_<ey{DXXpK*0bBOi<`zWIs?cM+-wpF$6NF*a4itZ}1EES9Vp-Ri2SDC+~`!;YBH<
zD^f;Vop-QYvGBZN;djx*|B8wKg}~4&fl(J?60XFgUy#hW$e($IKl1`dCOCloG}()!
zK+cl}5um~tlGQ*y1jl0$$RR~?AX!i`2gz*;ATEdi<-_6#uwx*3t%2bK6AP>CjNlIp
zEUdCCLcr7k5ioV47)+rPJdCVajG$bHjRZTg2xOI?Ci^Y6lFEY2y!0YaOcsG6>Xs6?
zI?{twM|vr#1$yA>NDopS>E-38q!xkw0?MsmbI|<qi^B#|?${M+GB7ZJO5Nhg3=9k(
zm>C%vZ!jocz=m!x7+*j|A6R%8xj!&q5+6ZgUqA#zR)&KS<WKD6M+T7i7clt&g9L{K
E04+P;O#lD@

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/node.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/node.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d76682cca61dd66a9aa936ace916052a3ae2e0f7
GIT binary patch
literal 2800
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/node.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/node.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1a8d46ef4a1c5317321c19f8323f13e6319c4fe0
GIT binary patch
literal 5581
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/stack.cpython-310.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/stack.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f963a4cfe22b0dc6246066d745d20c9344ac44ed
GIT binary patch
literal 1180
zcmd1j<>g{vU|`^9UzGlxk%8ech=Yuo85kHG7#J9ejTjghQW#Pga~N_NqZo6UqL^}-
zqnH^%VoW(KxvWvFj12A!Da<J>Eet6v%}h~jDXhT^nrtsYrfD+YVhzp9%+I^U;*(ii
za*M;ipd>RtFEK}x@fM3;eoAUGNEI?>h1na%z`&5o5XG3n5XF?jpTd;NoXV2QD#;+p
zkj4bIjTK~5Dr*{33R?<$3riGx3I~|SnZnh=62+0i3g&UA@U*Z*ai;L5@U<{RaiuT@
zGiVCjVht`yOwRVZ#hO`?np>RAgyaGc8-$%fo|j-?V5ng%Vy|JWVTfl)VF+eOXMnL*
zGWxA#EMjM1V9;c`#ZsJ_lLqFjWGLchU|{&=qo0wVo2p-uSdy8Tm#CMNlbDj3TBM(x
zpIeZxn_f_&o134KnxkJ_T98<z4`vtZr=%9>rzWPS7U|~~B_`*j>KB8YsaH^Wiz7Zh
zGcU6wJ{}Z4#cT`=3@nUXj9g4rd|;pG!K81o6{VJx7Ud-~B6$hK2E`}XOFSSiF=R0;
zU`%0L$QaD9lF9Go|NsC0YcheIe~Y;wzhEU}5h!(lJpv&>x{3rD7#O%g!2${&9>yw8
zh}{MG1-Dp00f`Zga7zW?mew#XWCSIiV1^<NaL_?)WlJn5NX<*pWP(^M%)kH%MuhFR
zSPDvuGx%WE3our3L9H(>&cN_4$c13<g8Wg#kj0R~D9I4aP{a>1m=i<@fe4UqkgQ-%
zPb~p?@-s*~7u<vCsU`R=C}F5!$YN|}gnQ~1OHpb;5!h=**ev3Rj|VA;j~4;CLY#qt
z0TGc92}tO0gCagJF*h|n{uWn!d~SY9X%2|Z6CYn#nwSHTDPjQ`0t)LQQ0ge+1#v;%
zC=vy+#6W~3h(P!j%mT+LI4OYw6~yCUkYMCv<74Jy=3y=Z$@poq-(oANEXd4DF9L;0
z5!e=xeYcdrDOV4Ya`jSD3-rJ#R}YeM_44vlQX$R(nF9%9u&rPMWZ5ka8;F1GK<N{l
LrbQTd7=@Ss0w?KM

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/oracle/__pycache__/stack.cpython-311.pyc b/tania_scripts/supar/models/dep/eager/oracle/__pycache__/stack.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5a362f4b907de1716061719405def54b641c7abd
GIT binary patch
literal 1703
zcmZ3^%ge>Uz`&q%Up3=9BLl-@5C?`?pp4HB3=9m@8B!Qh7;_kM8KW3;nWC6-nWLB)
zL1IifEV-;vtc(my4DJjm%q<KlEX$Y}7*;bubu&b<rLYDwXtKQo31~9kVhzp9%+I^U
z;*(iia*M;ipd>RtFEK}x@fM3;eoAUGNEHmTLK&aqz%EE-h+<4(h+<0NN?}T6PGw1D
zm4qr_U_h|am{OQqSfkidSW;Qjm{M3<Sfbcd*uZS|7M3Uus5nOpOB81cXA46VR|;b=
zgC_Sa*5H!F<ZQoNteGXLxy8wF4=^w=fY{6o3=E&Ozz(TlEaI$TtYL_UTc5%Z%#hB2
zF0zu*ZzW?9Cj$e6CetmJ;?$fpFsB$~oPxryDE*B5+*JLN#FEU!yhOdEoWzvO)FS=l
z{M>?k-ICOb65Z6Y#2o#S#JtSJ_~PWE%z~0){o>Ms#3KFN{FKz3V*QlV0{zs)^wc8#
z{G!C<oK*c{kQej{DsOSb$7kkcmc++b@qxXi2jhdnv{-?GfuVun2DiWm24+r~8<KJz
zE<IiyUL9T!B&A`@&mhm;Vk=55DJ{xNW(4t|7!(p9{Mif=8Vp%b2?mA*$m-ytDU8b)
z85mZ><$@VjGWosy|NsAgO(t-N++r@sFIdS~#LK|IPz+M0P{hZ;z)&R0z`#(&3GqNd
zegQW~S`6ZLe&L>~{<^NZ8A%uU6|e9sUf@tH5@29pxWxjBK9tx4xfO&zTM_Br8Z`HU
z5_&L05y*O&gV_=b3R3e@G?~C|E)oa13=*wim)~M3C@s#Y;(|K8v^WFgpJF+P+c|i8
zxUO?ZUgD6Pp>mN!{tAcu1sDSR0VT9Srh;8BgW>uVMntj?W+)N{1sM;B0EH1!INoAT
zPc4CkV|r?dAjq{K2Q@I<0EOcWrJlMA9I}{pgX{%iXu2-}MGZ7oYZ$WNJoMOwhSV*V
zqSS&Sa0C~jyNDw`9wdpJJ|TP&klTd7;dGZ@c!J9muZ#ThSNK681a=?9Y;I5j&r8fr
zjgP;@6(66QpHi9wV)Mku7nUaGKxB$QX}t(kj1{qgLWLhhfRa>^6o>^1&mwsS28NXk
z5R*Y6Qp5q00udm6#dE<9X<&fB4@@kqG9MUNSY>8pEGSvwvZU&YoDrChPVg|YDoqIa
zz`)3=gif$AvMS6F0f{Q06KssEau8i|ASq-5qzfd5t_R|BkbC_!*>ACxR2F3Br5AzX
z4B~N65ZqD%7aDqyLPIYlwLlMCXy`!-4ZXbllvGFvfy^mV28949D}ht;FAf_>=-L&j
zF)%QI;=DMWfq~%zGb1D84F-)1xX}#;;|r+h1B)P|!UqOS;v-1x3y46I1^W*GP#|Ra

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/eager/oracle/arceager.py b/tania_scripts/supar/models/dep/eager/oracle/arceager.py
new file mode 100644
index 0000000..b65dad1
--- /dev/null
+++ b/tania_scripts/supar/models/dep/eager/oracle/arceager.py
@@ -0,0 +1,219 @@
+from supar.models.dep.eager.oracle.stack import Stack
+from supar.models.dep.eager.oracle.buffer import Buffer
+from supar.models.dep.eager.oracle.node import Node
+from supar.models.dep.eager.oracle.dependency import Transition
+from typing import List, Dict
+
+class ArcEagerEncoder:
+    def __init__(self, bos: str, eos: str):
+        self.stack = None
+        self.buffer = None
+        self.transitions = []
+        self.dependencies = []
+        self.nodes_assigned = []
+        self.bos, self.eos = bos, eos
+        self.shift_token = '<shift>'
+        self.reduce_token = '<reduce>'
+        self.n = 0
+
+    def left_arc(self):
+        # head = buffer_front, dependent = stack_top (stack_top <- buffer_front)
+        stack_top = self.stack.pop()
+        buffer_front = self.buffer.get()
+        self.transitions.append(
+            Transition(type='left-arc', stack_top=stack_top, buffer_front=buffer_front, deprel=stack_top.DEPREL)
+        )
+        self.dependencies.append(
+            Node(ID=stack_top.ID, FORM=stack_top.FORM, UPOS=stack_top.UPOS, HEAD=buffer_front.ID, DEPREL=stack_top.DEPREL)
+        )
+        self.nodes_assigned.append(stack_top.ID)
+        return self.transitions
+
+    def right_arc(self):
+        # head = stack_top, dependent = buffer_front (stack_top -> buffer_front)
+        stack_top = self.stack.get()
+        buffer_front = self.buffer.remove()
+        self.stack.push(buffer_front)
+        self.transitions.append(
+            Transition(type='right-arc', stack_top=stack_top, buffer_front=buffer_front, deprel=buffer_front.DEPREL)
+        )
+        self.dependencies.append(
+            Node(ID=buffer_front.ID, FORM=buffer_front.FORM, UPOS=buffer_front.UPOS, HEAD=stack_top.ID, DEPREL=buffer_front.DEPREL)
+        )
+        self.nodes_assigned.append(buffer_front.ID)
+        return self.transitions
+
+    def shift(self):
+        front_item = self.buffer.remove()
+        stack_top = self.stack.get()
+        self.stack.push(front_item)
+        self.transitions.append(
+            Transition(type='shift', stack_top=stack_top, buffer_front=front_item, deprel=front_item.DEPREL))
+        return self.transitions
+
+    def reduce(self):
+        stack_top = self.stack.get()
+        buffer_front = self.buffer.get() if len(self.buffer) > 0 else Node.create_eos(self.n, self.eos)
+        self.stack.pop()
+        self.transitions.append(
+            Transition(type='reduce', stack_top=stack_top, buffer_front=buffer_front, deprel=stack_top.DEPREL)
+        )
+        return self.transitions
+
+    def next_action(self):
+        stack_top = self.stack.get()
+        try:
+            buffer_front = self.buffer.get()
+        except IndexError:
+            if stack_top.ID in self.nodes_assigned:
+                return self.reduce()
+            return None
+
+        if buffer_front.ID == stack_top.HEAD:
+            return self.left_arc()
+        elif (buffer_front.ID not in self.nodes_assigned) and (stack_top.ID == buffer_front.HEAD):
+            return self.right_arc()
+        elif (stack_top.ID in self.nodes_assigned) and (buffer_front.HEAD in [node.ID for node in self.stack.items]):
+            return self.reduce()
+        elif (stack_top.ID in self.nodes_assigned) and (buffer_front.ID in [node.HEAD for node in self.stack.items]):
+            return self.reduce()
+        else:
+            return self.shift()
+
+    def encode(self, sentence: List[Node]):
+        # create stack and buffer
+        self.stack = Stack([Node.create_root(self.bos)])
+        self.buffer = Buffer(sentence.copy())
+        self.n = len(sentence)
+
+        # reset
+        self.transitions, self.dependencies = [], []
+
+        next_action = self.next_action()
+        while next_action:
+            next_action = self.next_action()
+
+        # remove values
+        self.dependencies = sorted(self.dependencies, key=lambda dep: dep.ID)
+        return self.transitions
+
+
+
+class ArcEagerDecoder:
+    def __init__(self, sentence: List[Node], bos: str, eos: str, unk: str):
+        self.sentence = sentence.copy()
+        self.decoded_nodes = [Node(ID=node.ID, FORM=node.FORM, UPOS=node.UPOS, HEAD=0, DEPREL=unk) for node in sentence]
+        self.transitions = list()
+        self.nodes_assigned = list()
+        self.stack = Stack([Node.create_root(bos)])
+        self.buffer = Buffer(sentence.copy())
+        self.bos, self.eos, self.unk = bos, eos, unk
+        self.shift_token, self.reduce_token = '<shift>',  '<reduce>'
+
+
+    def left_arc(self, deprel: str):
+        # head = buffer_front, dependent = stack_top (stack_top <- buffer_front)
+        stack_top = self.stack.pop()
+        buffer_front = self.buffer.get()
+        self.nodes_assigned.append(stack_top.ID)
+        self.transitions.append(
+            Transition(type='left-arc', stack_top=stack_top, buffer_front=buffer_front, deprel=deprel)
+        )
+        self.decoded_nodes[stack_top.ID - 1].HEAD = buffer_front.ID
+        self.decoded_nodes[stack_top.ID - 1].DEPREL = deprel
+        # get next states
+        stack_top = self.stack.get()
+        buffer_front = self.buffer.get() if len(self.buffer) > 0 else Node.create_eos(len(self.sentence), self.eos)
+        return stack_top, buffer_front
+
+    def right_arc(self, deprel: str):
+        # head = stack_top, dependent = buffer_front (stack_top -> buffer_front)
+        stack_top = self.stack.get()
+        buffer_front = self.buffer.remove()
+        self.stack.push(buffer_front)
+        self.transitions.append(
+            Transition(type='right-arc', stack_top=stack_top, buffer_front=buffer_front, deprel=deprel)
+        )
+        self.nodes_assigned.append(buffer_front.ID)
+        self.decoded_nodes[buffer_front.ID - 1].HEAD = stack_top.ID
+        self.decoded_nodes[buffer_front.ID - 1].DEPREL = deprel
+
+        # get next states
+        stack_top = self.stack.get()
+        buffer_front = self.buffer.get() if len(self.buffer) > 0 else Node.create_eos(len(self.sentence), self.eos)
+        return stack_top, buffer_front
+
+
+    def shift(self, deprel):
+        front_item = self.buffer.remove()
+        stack_top = self.stack.get()
+        self.stack.push(front_item)
+        self.transitions.append(
+            Transition(type='shift', stack_top=stack_top, buffer_front=front_item, deprel=deprel))
+        # get next states
+        stack_top = self.stack.get()
+        buffer_front = self.buffer.get() if len(self.buffer) > 0 else Node.create_eos(len(self.sentence), self.eos)
+        return stack_top, buffer_front
+
+    def reduce(self, deprel):
+        stack_top = self.stack.get()
+        try:
+            buffer_front = self.buffer.get()
+        except IndexError:
+            buffer_front = Node.create_eos(len(self.sentence), self.eos)
+        self.stack.pop()
+        self.transitions.append(
+            Transition(type='reduce', stack_top=stack_top, buffer_front=buffer_front, deprel=deprel)
+        )
+        # get next states
+        stack_top = self.stack.get()
+        buffer_front = self.buffer.get() if len(self.buffer) > 0 else Node.create_eos(len(self.sentence), self.eos)
+        return stack_top, buffer_front
+
+    def apply_transition(self, transitions: List[str], deprel: str):
+        stack_top = self.stack.get()
+        try:
+            buffer_front = self.buffer.get()
+        except IndexError:
+            if stack_top.ID in self.nodes_assigned:
+                self.reduce(deprel)
+            return None
+
+        for transition in transitions:
+            if (transition == 'left-arc') and (stack_top.ID not in self.nodes_assigned) and (not stack_top.is_root):
+                return self.left_arc(deprel)
+            if (transition == 'right-arc') and (buffer_front.ID not in self.nodes_assigned):
+                return self.right_arc(deprel)
+            if (transition == 'reduce') and (stack_top.ID in self.nodes_assigned):
+                return self.reduce(deprel)
+            return self.shift(deprel)
+
+    def apply(self, transition: str, deprel: str):
+        if transition == 'left-arc':
+            return self.left_arc(deprel)
+        if transition == 'right-arc':
+            return self.right_arc(deprel)
+        if transition == 'reduce':
+            return self.reduce(deprel)
+        if transition == 'shift':
+            return self.shift(deprel)
+
+    def decode_sentence(self, transitions: List[List[str]], deprels: List[str]):
+        for transition_ops, deprel in zip(transitions, deprels):
+            info = self.apply_transition(transition_ops, deprel)
+            if info is None:
+                break
+        self.postprocess()
+        return self.decoded_nodes
+
+    def postprocess(self):
+        # check if there are more than one node with root head
+        roots = sum([node.HEAD == 0 for node in self.decoded_nodes])
+        if roots > 1:
+            # get leftmost root
+            for node in self.decoded_nodes:
+                if node.HEAD == 0:
+                    root = node.ID
+            for node in self.decoded_nodes[root:]:
+                if node.HEAD == 0:
+                    node.HEAD = root
diff --git a/tania_scripts/supar/models/dep/eager/oracle/buffer.py b/tania_scripts/supar/models/dep/eager/oracle/buffer.py
new file mode 100644
index 0000000..9a1f5d4
--- /dev/null
+++ b/tania_scripts/supar/models/dep/eager/oracle/buffer.py
@@ -0,0 +1,24 @@
+from typing import Optional, List
+from supar.models.dep.eager.oracle.node import Node
+
+class Buffer:
+    def __init__(self, items: Optional[List[Node]]):
+        if items:
+            self.items = items
+        else:
+            self.items = []
+
+    def get(self) -> Node:
+        return self.items[0]
+
+    def remove(self) -> Node:
+        return self.items.pop(0)
+
+    def append(self, item: Node):
+        self.items.append(item)
+
+    def __len__(self):
+        return len(self.items)
+
+    def __repr__(self):
+        return str(self.items)
\ No newline at end of file
diff --git a/tania_scripts/supar/models/dep/eager/oracle/dependency.py b/tania_scripts/supar/models/dep/eager/oracle/dependency.py
new file mode 100644
index 0000000..a4825ba
--- /dev/null
+++ b/tania_scripts/supar/models/dep/eager/oracle/dependency.py
@@ -0,0 +1,30 @@
+from typing import Optional, List
+from supar.models.dep.eager.oracle.node import Node
+
+class Dependency:
+    def __init__(self, dependent_id: int, head_id: str, deprel: str):
+        self.dependent_id = dependent_id
+        self.head_id = head_id
+        self.deprel = deprel
+
+    def __repr__(self):
+        return self.toconll()
+
+    def toconll(self):
+        return '\t'.join([
+            str(self.dependent_id), str(self.head_id), self.deprel
+        ])
+
+class Transition:
+    def __init__(self, type: str, stack_top: Node, buffer_front: Node, deprel: str):
+        self.type = type
+        self.stack_top = stack_top
+        self.buffer_front = buffer_front
+        self.deprel = deprel
+
+    def __repr__(self):
+        return '\t'.join((str(self.stack_top.FORM), str(self.buffer_front.FORM), self.type, self.deprel))
+
+
+
+
diff --git a/tania_scripts/supar/models/dep/eager/oracle/node.py b/tania_scripts/supar/models/dep/eager/oracle/node.py
new file mode 100644
index 0000000..7aa07a9
--- /dev/null
+++ b/tania_scripts/supar/models/dep/eager/oracle/node.py
@@ -0,0 +1,74 @@
+from typing import List
+
+class Node:
+
+    def __init__(self, ID: int, FORM: str, UPOS: str, HEAD: int, DEPREL: str, is_root: bool = False):
+        self.ID = ID
+        self.FORM = FORM
+        self.UPOS = UPOS
+        self.HEAD = HEAD
+        self.DEPREL = DEPREL
+        self.is_root = is_root
+
+    def __str__(self):
+        return f'Node(ID={self.ID}, FORM={self.FORM}, UPOS={self.UPOS}, HEAD={self.HEAD})'
+
+    def __repr__(self):
+        return f'Node(ID={self.ID}, FORM={self.FORM}, UPOS={self.UPOS}, HEAD={self.HEAD})'
+
+    @classmethod
+    def from_conllu(cls, conll: str):
+        ID, FORM, LEMMA, UPOS, XPOS, FEATS, HEAD, DEPREL, DEPS, MISC = conll.split('\t')
+        if HEAD == '_':
+             return Node(int(ID), FORM, UPOS, HEAD, DEPREL)
+        else:
+             return Node(int(ID), FORM, UPOS, int(HEAD), DEPREL)
+
+    @classmethod
+    def create_root(cls, token: str):
+        return Node(0, token, token, 0, token, is_root=True)
+
+    @classmethod
+    def create_eos(cls, position: int, token: str):
+        return Node(position, token, token, 0, token, is_root=False)
+
+    def coverage(self) -> range:
+        limits = sorted([self.ID, self.HEAD])
+        return range(*limits)
+
+    def isprojective(heads: List[int]):
+        pairs = [(h, d) for d, h in enumerate(heads, 1) if h >= 0]
+        for i, (hi, di) in enumerate(pairs):
+            for hj, dj in pairs[i + 1:]:
+                (li, ri), (lj, rj) = sorted([hi, di]), sorted([hj, dj])
+                if li <= hj <= ri and hi == dj:
+                    print('1')
+                    return False
+                if lj <= hi <= rj and hj == di:
+                    print('2')
+                    return False
+                if (li < lj < ri or li < rj < ri) and (li - lj) * (ri - rj) > 0:
+                    print('3')
+                    print(di, hi, dj, hj)
+                    return False
+        return True
+
+def isprojective(heads: List[int]):
+    pairs = [(h, d) for d, h in enumerate(heads, 1) if h >= 0]
+    for i, (hi, di) in enumerate(pairs):
+        for hj, dj in pairs[i + 1:]:
+            (li, ri), (lj, rj) = sorted([hi, di]), sorted([hj, dj])
+            if li <= hj <= ri and hi == dj:
+                print('1')
+                return False
+            if lj <= hi <= rj and hj == di:
+                print('2')
+                return False
+            if (li < lj < ri or li < rj < ri) and (li - lj) * (ri - rj) > 0:
+                print('3')
+                print(di, hi, dj, hj)
+                return False
+    return True
+
+
+
diff --git a/tania_scripts/supar/models/dep/eager/oracle/stack.py b/tania_scripts/supar/models/dep/eager/oracle/stack.py
new file mode 100644
index 0000000..ee5545a
--- /dev/null
+++ b/tania_scripts/supar/models/dep/eager/oracle/stack.py
@@ -0,0 +1,24 @@
+from typing import Union, List, Optional
+from supar.models.dep.eager.oracle.node import Node
+
+class Stack:
+    def __init__(self, items: Optional[List[Node]] = None):
+        if items:
+            self.items = items
+        else:
+            self.items = []
+
+    def pop(self) -> Node:
+        return self.items.pop(-1)
+
+    def push(self, item: Node):
+        self.items.append(item)
+
+    def get(self) -> Node:
+        return self.items[-1]
+
+    def __repr__(self):
+        return repr(self.items)
+
+
+
diff --git a/tania_scripts/supar/models/dep/eager/parser.py b/tania_scripts/supar/models/dep/eager/parser.py
new file mode 100644
index 0000000..f4857de
--- /dev/null
+++ b/tania_scripts/supar/models/dep/eager/parser.py
@@ -0,0 +1,380 @@
+import os
+from supar.models.dep.eager.oracle.node import Node
+
+import torch
+from supar.models.dep.eager.model import ArcEagerDependencyModel
+from supar.parser import Parser
+from supar.utils import Config, Dataset, Embedding
+from supar.utils.common import BOS, PAD, UNK, EOS
+from supar.utils.field import Field, RawField, SubwordField
+from supar.utils.fn import ispunct
+from supar.utils.logging import get_logger
+from supar.utils.metric import AttachmentMetric
+from supar.utils.tokenizer import TransformerTokenizer
+from supar.utils.transform import Batch
+from supar.models.dep.eager.transform import ArcEagerTransform
+from supar.models.dep.eager.oracle.arceager import ArcEagerDecoder
+from itertools import groupby
+
+
+logger = get_logger(__name__)
+from typing import Tuple, List, Union
+
+def consecutive_duplicate_spans(L):
+    new_list = []
+    for group in groupby(L):
+        f = list(group[1])
+        if len(f) > 1:
+            new_el = f[0].replace('-arc', '') + "*"
+            new_list.append(new_el)
+        elif len(f) == 1:
+            new_el = f[0].replace('-arc', '')
+            new_list.append(new_el)
+    return new_list
+
+
+class ArcEagerDependencyParser(Parser):
+    MODEL = ArcEagerDependencyModel
+    NAME = 'arceager-dependency'
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self.FORM = self.transform.FORM
+        self.STACK_TOP = self.transform.STACK_TOP
+        self.BUFFER_FRONT = self.transform.BUFFER_FRONT
+        self.TRANSITION, self.TREL = self.transform.TRANSITION, self.transform.TREL
+        self.TAG = self.transform.UPOS
+        self.HEAD = self.transform.HEAD
+
+    def train_step(self, batch: Batch) -> torch.Tensor:
+        words, texts, *feats, tags, _, _, stack_top, buffer_front, transitions, trels = batch
+        #print('dep eager parser feats', len(*feats))
+        tmask = self.get_padding_mask(stack_top)
+
+        # pad stack_top and buffer_front vectors: note that padding index must be the length of the sequence
+        pad_indices = (batch.lens - 1 - self.args.delay).tolist()
+        stack_top, buffer_front = self.pad_tensor(stack_top, pad_indices), self.pad_tensor(buffer_front, pad_indices)
+        # forward pass
+        #   stack_top: torch.Tensor ~ [batch_size, pad(tr_len), n_transitions]
+        #   buffer_front: torch.Tensor ~ [batch_size, pad(tr_len), n_trels]
+        s_transition, s_trel, s_tag, qloss = self.model(words, stack_top, buffer_front, feats)
+
+        # compute loss
+        smask = batch.mask[:, (2+self.args.delay):]
+        loss = self.model.loss(s_transition, s_trel, s_tag, transitions, trels, tags, smask, tmask, self.TRANSITION) + qloss
+        return loss
+
+    @torch.no_grad()
+    def eval_step(self, batch: Batch) -> AttachmentMetric:
+        words, texts, *feats, tags, heads, deprels, stack_top, buffer_front, transitions, trels = batch
+        transition_mask = self.get_padding_mask(stack_top)
+
+
+        # obtain transition loss
+        stack_top, buffer_front = \
+            self.pad_tensor(stack_top, (batch.lens - 1 - self.args.delay).tolist()), \
+                self.pad_tensor(buffer_front, (batch.lens - 1 - self.args.delay).tolist())
+        s_transition, s_trel, s_tag, qloss = self.model(words, stack_top, buffer_front, feats.copy())
+        smask = batch.mask[:, (2+self.args.delay):]
+        loss = self.model.loss(s_transition, s_trel, s_tag, transitions, trels, tags, smask, transition_mask, self.TRANSITION) + qloss
+
+        # obtain indices of deprels from TREL field
+        batch_size = words.shape[0]
+        deprels = [self.TREL.vocab[deprels[b]] for b in range(batch_size)]
+
+        # create decoders
+        lens = list(map(len, texts))
+        sentences = list()
+        for b in range(batch_size):
+            sentences.append(
+                [
+                    Node(ID=i + 1, FORM=form, UPOS='', HEAD=head, DEPREL=deprel) for i, (form, head, deprel) in \
+                    enumerate(zip(texts[b], heads[b, :lens[b]].tolist(), deprels[b]))
+                ]
+            )
+        decoders = list(map(
+            lambda sentence: ArcEagerDecoder(sentence=sentence, bos='', eos='', unk=self.transform.TREL.unk_index),
+            sentences
+        ))
+         
+        # compute oracle simulation for all elements in batch
+        head_preds, deprel_preds, *_ = self.oracle_decoding(decoders, words, feats)
+        head_preds, deprel_preds = self.pad_tensor(head_preds), self.pad_tensor(deprel_preds)
+        deprels = self.pad_tensor(deprels)
+
+        seq_mask = batch.mask[:, (2 + self.args.delay):]
+        return AttachmentMetric(loss, (head_preds, deprel_preds), (heads, deprels), seq_mask)
+
+    @torch.no_grad()
+    def pred_step(self, batch: Batch) -> Batch:
+        words, texts, *feats = batch
+        #print('SENTENCE: ', ' '.join(list(texts[0])))
+        #print()
+        lens = (batch.lens - 2 - self.args.delay).tolist()
+
+
+        batch_size = words.shape[0]
+        # create decoders
+        sentences = list()
+        for b in range(batch_size):
+            sentences.append(
+                [
+                    Node(ID=i + 1, FORM='', UPOS='', HEAD=None, DEPREL=None) for i in range(lens[b])
+                ]
+            )
+        decoders = list(map(
+            lambda sentence: ArcEagerDecoder(sentence=sentence, bos='', eos='', unk=self.transform.TREL.unk_index),
+            sentences
+        ))
+        # compute oracle simulation for all elements in batch
+        head_preds, deprel_preds, stack_list, buffer_list,actions_list, act_dict_list, deprel_preds_decoded, pos_preds_decoded, act_dict = self.oracle_decoding(decoders, words, feats)
+        batch.heads = head_preds
+        batch.rels = deprel_preds
+        return batch, head_preds, deprel_preds, stack_list, buffer_list, actions_list, act_dict_list, deprel_preds_decoded, pos_preds_decoded, list(texts[0]), act_dict
+
+    def get_padding_mask(self, tensor_list: List[torch.Tensor]) -> torch.Tensor:
+        """
+        From a list of tensors of different lengths, creates a padding mask where False values indicates
+        padding tokens. True otherwise.
+        Args:
+            tensor_list: List of tensors.
+        Returns: torch.Tensor ~ [len(tensor_list), max(lenghts)]
+
+        """
+        lens = list(map(len, tensor_list))
+        max_len = max(lens)
+        return torch.tensor([[True] * length + [False] * (max_len - length) for length in lens]).to(self.model.device)
+
+    def pad_tensor(
+            self,
+            tensor_list: Union[List[torch.Tensor], List[List[int]]],
+            pad_index: Union[int, List[int]] = 0
+    ):
+        """
+        Applies padding to a list of tensors or list of lists.
+        Args:
+            tensor_list: List of tensors or list of lists.
+            pad_index: Index used for padding or list of indices used for padding for each item of tensor_list.
+        Returns: torch.Tensor ~ [len(tensor_list), max(lengths)]
+        """
+        max_length = max(map(len, tensor_list))
+        if isinstance(pad_index, int):
+            if isinstance(tensor_list[0], list):
+                return torch.tensor(
+                    [tensor + [pad_index] * (max_length - len(tensor)) for tensor in tensor_list]).to(self.model.device)
+            else:
+                return torch.tensor(
+                    [tensor.tolist() + [pad_index] * (max_length - len(tensor)) for tensor in tensor_list]).to(self.model.device)
+        else:
+            pad_indexes = pad_index
+            if isinstance(tensor_list[0], list):
+                return torch.tensor(
+                    [tensor + [pad_index] * (max_length - len(tensor)) for tensor, pad_index in
+                     zip(tensor_list, pad_indexes)]).to(self.model.device)
+            else:
+                return torch.tensor(
+                    [tensor.tolist() + [pad_index] * (max_length - len(tensor)) for tensor, pad_index in
+                     zip(tensor_list, pad_indexes)]).to(self.model.device)
+
+    def get_text_mask(self, batch):
+        text_lens = (batch.lens - 2 - self.args.delay).tolist()
+        mask = batch.mask
+        mask[:, 0] = 0  # remove bos token
+        for i, text_len in enumerate(text_lens):
+            mask[i, (1 + text_len):] = 0
+        return mask
+
+    def oracle_decoding(self, decoders: List[ArcEagerDecoder], words: torch.Tensor, feats: List[torch.Tensor]) -> Tuple[
+        List[List[int]]]:
+        """
+        Implements Arc-Eager decoding. Using words indices, creates the initial state of the Arc-Eager oracle
+        and predicts each (transition, trel) with the TransitionDependencyModel.
+        Args:
+            decoders: List[ArcEagerDecoder] ~ batch_size
+            words: torch.Tensor ~ [batch_size, seq_len]
+            feats: List[torch.Tensor ~ [batch_size, seq_len, feat_embed]] ~ n_feat
+
+
+        Returns: head_preds, deprel_preds
+            head_preds: List[List[int] ~ sen_len] ~ batch_size: Head values for each sentence in batch.
+            deprel_preds: List[List[int] ~ sen_len] ~ batch_size: Indices of dependency relations for each sentence in batch.
+        """
+        # create a mask vector to filter those decoders that achieved the final state
+        compute = [True for _ in range(len(decoders))]
+        batch_size = len(decoders)
+        #print('ORACLE DECO TAG VOCAB', self.TAG.vocab.items())
+
+        exclude = self.TREL.vocab[['<reduce>', '<shift>']]
+
+        # obtain word representations of the encoder
+        x, s_tag, _ = self.model.encoder_forward(words, feats)
+        transition_stags = self.model.decode_stag(s_tag)
+
+
+        stack_top = [torch.tensor([decoders[b].stack.get().ID]).reshape(1) for b in range(batch_size)]
+        buffer_front = [torch.tensor([decoders[b].buffer.get().ID]).reshape(1) for b in range(batch_size)]
+        counter = 0
+        
+        stack_list = []
+        buffer_list = []
+        actions_list = []
+        
+        #print('stack_top', stack_top[-1].item())
+        #print('buffer_front', buffer_front[-1].item())
+        stack_list.append(stack_top[-1].item())
+        buffer_list.append(buffer_front[-1].item())
+        
+        while any(compute):
+            s_transition, s_trel = self.model.decoder_forward(x, torch.stack(stack_top), torch.stack(buffer_front))
+            transition_preds, trel_preds = self.model.decode(s_transition, s_trel, exclude)
+            transition_preds, trel_preds = transition_preds[:, counter, :], trel_preds[:, counter]
+            transition_preds = [self.TRANSITION.vocab[i.tolist()] for i in
+                                transition_preds.reshape(batch_size, self.args.n_transitions)]
+            for b, decoder in enumerate(decoders):
+                #print('209', transition_preds[b][0])
+                actions_list.append(transition_preds[b][0])
+                if not compute[b]:
+                    stop, bfront = stack_top[b][-1].item(), buffer_front[b][-1].item()
+
+                else:
+                    result = decoder.apply_transition(transition_preds[b], trel_preds[b].item())
+                    if result is None:
+                        stop, bfront = stack_top[b][-1].item(), buffer_front[b][-1].item()
+                        #print("2019 stop, bfront", stop, bfront)
+
+                        
+                        compute[b] = False
+                    else:
+                        #print()
+                        stop, bfront = result[0].ID, result[1].ID
+                        stack_list.append(stop)
+                        buffer_list.append(bfront)
+                        #print("225 stop, bfront", stop, bfront)
+
+ 
+                stack_top[b] = torch.concat([stack_top[b], torch.tensor([stop])])
+                buffer_front[b] = torch.concat([buffer_front[b], torch.tensor([bfront])])
+            counter += 1
+
+        head_preds = [[node.HEAD for node in decoder.decoded_nodes] for decoder in decoders]
+        deprel_preds = [[node.DEPREL for node in decoder.decoded_nodes] for decoder in decoders]
+        deprel_preds_decoded = [[self.TREL.vocab[i] for i in dep_pre] for dep_pre in deprel_preds]
+        pos_preds = [[i.item() for i in trans_stag] for trans_stag in transition_stags]
+        pos_preds_decoded =  [[self.TAG.vocab[i.item()] for i in trans_stag] for trans_stag in transition_stags]   
+        form_preds = [[node.FORM for node in decoder.decoded_nodes] for decoder in decoders]
+        #print(len(stack_list), stack_list)
+        #print(len(buffer_list), buffer_list)
+        #print(len(actions_list), actions_list)
+        #assert len(stack_list) == len(buffer_list) == len(actions_list)
+        
+        """
+        print()
+        
+        print('stack list: ', stack_list)
+        print('buffer list: ', buffer_list)
+        print('actions list: ', actions_list)
+        print()
+        print('head_preds: ', head_preds)
+        print('deprel_preds: ', deprel_preds, deprel_preds_decoded)
+        print('pos_preds: ', pos_preds, pos_preds_decoded)
+        print()
+        """
+                
+        act_dict  = {}
+        for i, j in zip(buffer_list, actions_list):
+            act_dict.setdefault(i, []).append(j)
+        
+        act_dict_list = []
+        for _,vel in act_dict.items():        
+            new_list = consecutive_duplicate_spans(vel)
+            act_dict_list.append(" ".join(new_list))
+         
+        #print('macro actions: ', act_dict_list)
+      
+        #assert len(act_dict_list) == len(head_preds[0])
+        
+        
+        return head_preds, deprel_preds, stack_list, buffer_list, actions_list, act_dict_list, deprel_preds_decoded, pos_preds_decoded, act_dict
+
+    @classmethod
+    def build(cls, path, min_freq=1, fix_len=20, **kwargs):
+        args = Config(**locals())
+        os.makedirs(os.path.dirname(path) or './', exist_ok=True)
+
+        if os.path.exists(path) and not args.build:
+            parser = cls.load(**args)
+            parser.model = cls.MODEL(**parser.args)
+            parser.model.load_pretrained(parser.transform.FORM[0].embed).to(parser.device)
+            return parser
+
+        logger.info("Building the fields")
+
+        # ------------------------------- source fields -------------------------------
+        WORD, TAG, CHAR = None, None, None
+        if args.encoder == 'bert':
+            t = TransformerTokenizer(args.bert)
+            pad_token = t.pad if t.pad else PAD
+            WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, eos=t.eos, fix_len=args.fix_len, tokenize=t, delay=args.delay)
+            WORD.vocab = t.vocab
+        else:
+            WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, eos=EOS, lower=True, delay=args.delay)
+            if 'char' in args.feat:
+                CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, eos=EOS, fix_len=args.fix_len, delay=args.delay)
+            if 'tag' in args.feat:
+                TAG = Field('tags')
+        TAG = Field('tags')
+        TEXT = RawField('texts')
+        STACK_TOP = RawField('stack_top', fn=lambda x: torch.tensor(x))
+        BUFFER_FRONT = RawField('buffer_front', fn=lambda x: torch.tensor(x))
+
+        # ------------------------------- target fields -------------------------------
+        TRANSITION = Field('transition')
+        TREL = Field('trels')
+        HEAD = Field('heads', use_vocab=False)
+        DEPREL = RawField('rels')
+
+        transform = ArcEagerTransform(
+            FORM=(WORD, TEXT, CHAR), UPOS=TAG, HEAD=HEAD, DEPREL=DEPREL,
+            STACK_TOP=STACK_TOP, BUFFER_FRONT=BUFFER_FRONT, TRANSITION=TRANSITION, TREL=TREL,
+        )
+        train = Dataset(transform, args.train, **args)
+
+        if args.encoder != 'bert':
+            print('HOLY SH dep eager parser')
+            WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None),
+                       lambda x: x / torch.std(x))
+            if TAG:
+                TAG.build(train)
+            if CHAR:
+
+                CHAR.build(train)
+        TAG.build(train)
+        TREL.build(train)
+        TRANSITION.build(train)
+        
+        print('TAG VOCAB', TAG.vocab.items())
+        #print('CHAR VOCAB', CHAR.vocab.items())
+
+
+        args.update({
+            'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init,
+            'n_transitions': len(TRANSITION.vocab),
+            'n_trels': len(TREL.vocab),
+            'n_tags': len(TAG.vocab) if TAG is not None else None,
+            'n_chars': len(CHAR.vocab) if CHAR is not None else None,
+            'char_pad_index': CHAR.pad_index if CHAR is not None else None,
+            'pad_index': WORD.pad_index,
+            'unk_index': WORD.unk_index,
+            'bos_index': WORD.bos_index
+        })
+        
+        
+        logger.info(f"{transform}")
+        logger.info("Building the model")
+        model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None)
+        logger.info(f"{model}\n")
+
+        parser = cls(args, model, transform)
+        parser.model.to(parser.device)
+        return parser
diff --git a/tania_scripts/supar/models/dep/eager/transform.py b/tania_scripts/supar/models/dep/eager/transform.py
new file mode 100644
index 0000000..be5c883
--- /dev/null
+++ b/tania_scripts/supar/models/dep/eager/transform.py
@@ -0,0 +1,176 @@
+from supar.utils.transform import Transform, Sentence
+from supar.utils.field import Field
+from typing import Iterable, Union, Optional, List, Tuple
+from supar.models.dep.eager.oracle.arceager import ArcEagerEncoder
+from supar.models.dep.eager.oracle.node import Node
+import os
+from io import StringIO
+
+
+class ArcEagerTransform(Transform):
+
+    fields = ['ID', 'FORM', 'LEMMA', 'UPOS', 'XPOS', 'FEATS', 'HEAD', 'DEPREL', 'DEPS', 'MISC', 'STACK_TOP', 'BUFFER_FRONT', 'TRANSITION', 'TREL']
+
+    def __init__(
+        self,
+        ID: Optional[Union[Field, Iterable[Field]]] = None,
+        FORM: Optional[Union[Field, Iterable[Field]]] = None,
+        LEMMA: Optional[Union[Field, Iterable[Field]]] = None,
+        UPOS: Optional[Union[Field, Iterable[Field]]] = None,
+        XPOS: Optional[Union[Field, Iterable[Field]]] = None,
+        FEATS: Optional[Union[Field, Iterable[Field]]] = None,
+        HEAD: Optional[Union[Field, Iterable[Field]]] = None,
+        DEPREL: Optional[Union[Field, Iterable[Field]]] = None,
+        DEPS: Optional[Union[Field, Iterable[Field]]] = None,
+        MISC: Optional[Union[Field, Iterable[Field]]] = None,
+        STACK_TOP: Optional[Union[Field, Iterable[Field]]] = None,
+        BUFFER_FRONT: Optional[Union[Field, Iterable[Field]]] = None,
+        TRANSITION: Optional[Union[Field, Iterable[Field]]] = None,
+        TREL: Optional[Union[Field, Iterable[Field]]] = None
+    ):
+        super().__init__()
+
+        self.ID = ID
+        self.FORM = FORM
+        self.LEMMA = LEMMA
+        self.UPOS = UPOS
+        self.XPOS = XPOS
+        self.FEATS = FEATS
+        self.HEAD = HEAD
+        self.DEPREL = DEPREL
+        self.DEPS = DEPS
+        self.MISC = MISC
+        self.STACK_TOP = STACK_TOP
+        self.BUFFER_FRONT = BUFFER_FRONT
+        self.TRANSITION = TRANSITION
+        self.TREL = TREL
+
+    @property
+    def src(self):
+        return self.FORM, self.LEMMA, self.UPOS, self.XPOS, self.FEATS
+    
+    @classmethod
+    def toconll(cls, tokens: List[Union[str, Tuple]]) -> str:
+        r"""
+        Converts a list of tokens to a string in CoNLL-X format with missing fields filled with underscores.
+
+        Args:
+            tokens (List[Union[str, Tuple]]):
+                This can be either a list of words, word/pos pairs or word/lemma/pos triples.
+
+        Returns:
+            A string in CoNLL-X format.
+
+        Examples:
+            >>> print(CoNLL.toconll(['She', 'enjoys', 'playing', 'tennis', '.']))
+            1       She     _       _       _       _       _       _       _       _
+            2       enjoys  _       _       _       _       _       _       _       _
+            3       playing _       _       _       _       _       _       _       _
+            4       tennis  _       _       _       _       _       _       _       _
+            5       .       _       _       _       _       _       _       _       _
+
+            >>> print(CoNLL.toconll([('She',     'she',    'PRP'),
+                                     ('enjoys',  'enjoy',  'VBZ'),
+                                     ('playing', 'play',   'VBG'),
+                                     ('tennis',  'tennis', 'NN'),
+                                     ('.',       '_',      '.')]))
+            1       She     she     PRP     _       _       _       _       _       _
+                2       enjoys  enjoy   VBZ     _       _       _       _       _       _
+            3       playing play    VBG     _       _       _       _       _       _
+            4       tennis  tennis  NN      _       _       _       _       _       _
+            5       .       _       .       _       _       _       _       _       _
+
+        """
+        if isinstance(tokens[0], str):
+            s = '\n'.join([f"{i}\t{word}\t" + '\t'.join(['_'] * 8)
+                           for i, word in enumerate(tokens, 1)])
+        elif len(tokens[0]) == 2:
+            s = '\n'.join([f"{i}\t{word}\t_\t{tag}\t" + '\t'.join(['_'] * 6)
+                           for i, (word, tag) in enumerate(tokens, 1)])
+        elif len(tokens[0]) == 3:
+            s = '\n'.join([f"{i}\t{word}\t{lemma}\t{tag}\t" + '\t'.join(['_'] * 6)
+                           for i, (word, lemma, tag) in enumerate(tokens, 1)])
+        elif len('85!!', tokens[0]) == 10:
+            s = '\n'.join([f"{i}\t{word}\t{lemma}\t{tag}\t{xpos}\t{upos}\t{head}\t{rel}\t{comm}\t{morph}"
+                           for (i, word, lemma, tag, xpos, upos, head, rel, comm, morph) in tokens])
+        else:
+            raise RuntimeError(f"Invalid sequence {tokens}. Only list of str or list of word/pos/lemma tuples are support.")
+        return s + '\n'
+
+    @property
+    def tgt(self):
+        return self.HEAD, self.DEPREL, self.DEPS, self.MISC, self.STACK_TOP, self.BUFFER_FRONT, self.TRANSITION, self.TREL
+
+    def load(
+        self,
+        data: Union[str, Iterable],
+        lang: Optional[str] = None,
+        **kwargs
+    ): 
+        if isinstance(data, str) and os.path.exists(data):
+            if os.path.isfile(data):
+                lines = open(data)
+            if os.path.isdir(data):
+                lines = []
+                for filepath in data:
+                    if filepath.endswith('.conllu'):
+                        l = open(filepath)
+                        lines.append(l)
+        else:
+            if lang is not None:
+                #data = [tokenizer(s) for s in ([data] if isinstance(data, str) else data)]
+                data = [data.split() if isinstance(data, str) else data]
+            else:
+                data = [data] if isinstance(data[0], str) else data
+            lines = (i for s in data for i in StringIO(self.toconll(s) + '\n'))
+
+        index, sentence = 0, []
+        for line in lines:
+            line = line.strip()
+            if len(line) == 0:
+                sentence = ArcEagerSentence(self, sentence, index)
+                yield sentence
+                index += 1
+                sentence = []
+            else:
+                sentence.append(line)
+
+
+
+class ArcEagerSentence(Sentence):
+    def __init__(self, transform: ArcEagerEncoder, lines: List[str], index: Optional[int] = None):
+        super().__init__(transform, index)
+        self.values = list()
+        self.annotations = dict()
+
+        for i, line in enumerate(lines):
+            value = line.split('\t')
+            if value[0].startswith('#') or not value[0].isdigit():
+                self.annotations[-i-1] = line
+            else:
+                self.annotations[len(self.values)] = line
+                self.values.append(value)
+
+        nodes = [Node.from_conllu('\t'.join(value)) for value in self.values]
+
+
+        algorithm = ArcEagerEncoder(bos=transform.FORM[0].bos, eos=transform.FORM[0].eos)
+        transitions = algorithm.encode(nodes.copy())
+        stack_top, buffer_front, transition, trel = zip(
+            *[(transition.stack_top.ID, transition.buffer_front.ID, transition.type, transition.deprel)
+              for transition in transitions])
+
+        self.values = list(zip(*self.values))
+        if self.values[6][0] != '_':
+            self.values[6] = tuple(map(int, self.values[6]))
+        self.values += [stack_top, buffer_front, transition, trel]
+
+
+    def __repr__(self):
+        # cover the raw lines
+        #print('µµµµµµµµ', self.values[:-4])
+        merged = {**self.annotations,
+                  **{i: '\t'.join(map(str, line))
+                     for i, line in enumerate(zip(*self.values[:-4]))}}
+        
+        return '\n'.join(merged.values()) + '\n'
\ No newline at end of file
diff --git a/tania_scripts/supar/models/dep/sl/__init__.py b/tania_scripts/supar/models/dep/sl/__init__.py
new file mode 100644
index 0000000..c0e75ee
--- /dev/null
+++ b/tania_scripts/supar/models/dep/sl/__init__.py
@@ -0,0 +1,2 @@
+from .model import SLDependencyModel
+from .parser import SLDependencyParser
\ No newline at end of file
diff --git a/tania_scripts/supar/models/dep/sl/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/dep/sl/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e84041e18d76d00c1a56d47aa5947ed6eabe7f48
GIT binary patch
literal 258
zcmd1j<>g{vU|`^9UzG06z`*br#6iYP3=9ko3=9m#G7Jn1DGVu$ISjdsQH+crHd78$
zE^`z!BSQ*vFoPz`OGX9;22I9Wg26s6sRgNdDXDqMmA?5YsX3aAw}g-d0}_jhQ;YmG
zS#GiBg5--pw%lSX01Fo}GcYi$WGG@|V1N+6T=g^Zb5r$85=$}@^Ah!vauQQAQ;YPI
z^K%RGb<+z<bisz`7nc?!7U_f8#ri3!1^UG~`tk9Zd6^~g@p=W7w>WHa^HWN5Qtd$Q
OEM{R~VBld8U<3en0zyLo

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/sl/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/dep/sl/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7da5b0abda7bcaada2f81498ced6765d9b1bb222
GIT binary patch
literal 318
zcmZ3^%ge>Uz`&q%Up2#<fq~&Mhy%k+P{wCD1_p-d3@HpLj5!Rsj8Tk?AU0DDQ!aB9
zGb2L^b1;J@%S%QE1_n*WTY|wpE~y2nc`2!R$(6qODXBS{jJJf41p^X`ic^dHG+A!3
z=7Qvlm>C!tZm|`Bg^O4i7#LPEd<I$lD_B1xKQ~psB(WqjF)vXsDJL-{Gqp%RIX|}`
zU$-Q+qC_{fEHOvFBrz{DF}^stD6^oXSiiWmAhAdvY;v)FN@{_AagKg`d}dx|NqoFs
xLFF$Fo80`A(wtPgB9PBPt}fPRU|{&b%*e=igF)p2D!Rd-b^#kI;$UE4003LQSsVZW

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/sl/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/dep/sl/__pycache__/model.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0eca97c4fc223779fc95ca035a2bb17aa33cb321
GIT binary patch
literal 5672
zcmd1j<>g{vU|`^9Uz9#cf`Q>Nh=Yt-7#J8F7#J9eQy3T+QW#Pga~Pr^G-EDP6cZze
z&6LBO%M!%`W;5ro=CVbx<+4YygZV5u9J!oPoM1L<4p%OB6n8F96i+U16fYx#J3|Uv
z3VRDf3VSL`GjkMQ3S%&XCdW&V{eGH^w^)7iQ&Mv@nQk%r`UKqKc1canPf0EE2@dhq
zWW2@ZoS&DLnXbuvi#4RQASd+}i%({8$t~8<yv+Q(WRMZaSQg4DHezI8NM(p(Oks#(
zN?}Z4OkqlANMQy;mK5d`R*-{I7*jY>I8(S%SW~!DSW|dXcvJXNcvARNm{WLCSW{S2
z1kz+v1XGz)gi={jSyP!M8B&?km?Rlegj1PQL{gbkL{phl#8TN(#8cT**(4d#_}UrL
z7*ixtBwKi+I8wAyq*6JvxKgB3*+H}<LyAl)D}<HCmLi)X*TNdbogxo5n=^|`k^v+K
zHeUh6N>K!pN?7ET!7?gfQWZ?ffXFm~6txuf7M3U;f~JCXrE#Qaq-eIVMDeyWurNgN
z1v6-B-x3V=aY-#m%}YtmORfY*jNdJmoZ^z)m!OpK(uje9p@@-zf#DW+eo<z6W?o`W
zylIjqQ;6G3P!dXqhCjnCmfY0DJhycD*4KeM<gVIhDljuJykurzV95N!$iVOtYy^8=
ze0hFRO7Sg@y!f2Nq|}_^TWoppMNqmVF}?T}dtQ8UMq*L%E%wwraI(0?l9rlSlB@``
zh=GAYnSp_UgMop88<c)E7#SE!7@8Tf7*lvM8A_O%85S^?urxC)WL(17$H>T#!WhHU
z!5Gil!5Gih!I;IK#gW34%~Yh+&d|=7#+1UG!qUP~tCYtM<+DQgV3nLHY}rgjo;6Bf
z9#;yxBttV}2V*=pT!aHE!qd)}#+bqh(hIUHj~%80tezFh;|22|uHZ{y&t@*lFX0E9
zEdVC@QaHpJL>RzqfewZgu3qL2#&|(6UkL2#juK%o527AIillIKfb@u_aQCuxFvg4J
zv6hH0kXXn7VwZ?7kOZ@&QW%06G<p3rnf&~UKt)3`C`Mp`3SxsoR2USZCJdkuEn!^1
zRKl3WyntmPLlIXBV;*A)(?Z4$#w^w>kPl!adj~@eLke>*TQGwri{CAl<kFPHTg=G?
zrJ8KF*iur<GLutpab@Nel$OL7XI7=&;?BrSNlDFvaJceHbK`RoD^o%7ol=xvkY8GI
zi#xxx1g2b*qX?ABZn2i+7bRyDNrMujBq%ZRWERIKmL+E9Bqo81h{U4w;#&fF@z69A
z53vL!k^(7Qpth`Jyv3ehS`wd<nY)td7I$t=K|IV_mg3Z$w3Q6Mob)sDb5r$85=$}@
z^Ah!vauQQAQ;YPI^K%RGb<+z<baO$4mws_+L1K|Um|d)&l3Ji&oCD$M6;$5hu*pfx
zO-f0$1LdA#P-sgq@Gx>PGBL9Kt<u5BaC-6anR%Hd@$q^#Ir+(nImLE*Fat1RiIstY
z0US$0;8^Nl%wo)9s$uA0NMY<{4rb6~@>|J#izP2UGw&8_UVMIONs&AQ1A``W5hyDb
zfpSif3MdrSK!gT}&;}7YAVQacfx#S<0@xTB7?>Ei7}@^cVlpZKXa6EW1_lNU*MK4i
z>>3dU28IrX1q?L|3mH2Y7BGV7G^SvNm5hFxOt<*JnLQpF7lvqjqm_)e7%Maxi?l$F
zKy{8C$T>_53=AR+MS38QuocOGRDsI<A_Wjj4n%<b2uU3v?V8fJSc^*wQj2bJz(TeN
z6mGZJN()jFOHyyKL4x@fFN(WvaTlfLz#It<s$1+(C*NWPl|{uxAiowFgKRVb5g=dR
zVogcSNvwo~FDPhlae)Qm3ySiyio`+6K%rD53Sxm0@GY)_{NnhM#PsykqFYRPdAB$`
zQ&RIvGD|9N2{;$!7Z<zcl@#R{RQlu>7vJJcF3K!PEy~Q#(^Q6p4=COt?f}^iF;)y@
zHrOf&Q08FIi%-o>N=>=NlNVo5lv+}hn3)IRfr?Uu9H^j$@^~S|E-d5lfu#x(Q{pr8
zQc^2!v83kY=HKE0k?~3S#qp{6#kW|JQj1D%@#e*YXlVYr#hsg30nbuAV3~sa{G80Z
z^jmxo9^6chw9LHJlG41?Tiki^1v$Aemw=rPGXtDhLHQV#v!SI0Ka3B{zMOgSiABlr
zxj6;5IKfp4h*_iw3J%ud<iwoRTbu~*aF*s}Lw&}UT@ETdifkDe7*;ag;*5_^&PgmT
zj*l+_XAW?_uz=MyAfAj84>J#=03#nO4~r0^5QxRZ$Hc=d!pOnM@t=o<iIInqkCE#i
z7YiR#l@#v0ev1`S6|#cjr1%zFQEEwPQC>1Ao5D(EP{F~@z`y_!E4~KHVT?6Q3z<3@
zJ3x&b##W{jrW6p#2qM#%B^f%w`LBZ^iz$mag*lt4NVbD9j~}j@5hBCQ&<buQwK9S9
zEM%-@hKQ#yXEPW1m9S*7LhD186xJ4w5;mwTlQ=^&qYFbbBd9sm3vva+0`?BZg^VEg
zWO2kW*Rs^I*0OalEZ_u*#xQj<*0OgnEZ_q1YB@R>7I1@EoHZOZoHfif>}f2ZmSG|n
z3j+g}0u(qFr59Vlc_2Y>NGWL4folOhpZvV^kkq{5{31;&g@lCYq{Ncs3~+^_qfne$
z7@w1x7n_ivhhhTAl<@qb6ot&Zl+5JRVpLgh6ewtb8k*4<mc(kJItFBvqe4z*afw2H
zngU2Gc0)nxLNZbnK-Hc?X0bwQW=TeB5e^6ID5PapKwYkonWm7C05Uis0i-b@K^>GG
z)e{mF@<IC5K^aLsAwdVjhhS+O;h~TZvc5dCI2G0JAZNOyrX`l<lz>9hFF!986nJp6
zgTUz$EkcSR%{K*&I&iZ*8WJ&(NYPOMx7$&~Vq<Yem5xFl#IWMngao*)AXkAf#7L08
zjdW8ob5rw*GxPHja}-Lz@vl$<>LDm-WTq(?=@#T9<|P&>Bo!qlXQ!5A=A|nn=cj<E
z%wmP4R1l-II5kC6p*$lqIYS{MKPRPFp(G;}!^-01{G!xiP~0Zw<R}#67Z+zH<)kWr
zs|vJqQw(am!qX+ht#~~OYU*P1rU%$HIBZUVH_sJ{QgaeZGV}8=+)<L4j>R1c*wO+h
zz(GxIlHCE)q>z?hq>!4JoS^{9lc*`FFeksb7{e79;Tx8kT#{d;P*|FnSCUx;_KpHb
zC&Dm4aAO19>_BO8fZ73|@(@%D7lR7rbcPy+SczItS;&yW(8^Q;YM(NsFiJ9XFo4=c
z5)3tr;-HcaEDI{>CNdQ=fm=ynD?pvh;*7+CRB&xyWDja!Fx_I(Gq}Z=xsnM|-<pBy
zR#2;=2vqvt;<5qdd{Ar9t{B!fv0$ju#VqL4@{7t7i&Bu=beY8^V4W{PKG9^n#hj9v
ztI2bV4O*Ewf~*2J(LgRK0(E(AF()UM++r<C%u7!#0`=F6KwaQlTxEsvQ1gqdLAq=}
zPUnKSH~}P(2&wr%?TlMoh!XM^H>ehbmXfy^<8QHoW9=3@G)LcJ1*hpEu!qw?27!Ie
z4z(;8<YiE6gGWM&(TtggS&Na2k%yU&nTwf=k%y^D5@#?JfkLaO1Y}|!$Z2el{B(;2
zlqGJlfYR12mfXbR>|{_s1XcrbGB7ZJ8l&JEuntrMGG>8#dW_l3MFJg+3qUc>Ajwd}
z(!n6fu#hQ_uY?&|Z!x7Xw{VoO)G*etG&6x}tY*eqjv5ZI9ww0L8deawkjb2(mZJk?
zDr*W$HdB!;R1GsowuTKvLe$i71T$!|`V|?Xw}U}$1Gy2@EGz~!8X7^Vl0Sy2ma&$p
zgK+^v4I{{u8nCSknZg(t848&|y|E%t??98W$Q2ZK%tfH?_ANF@8E}g=9aJK$WGboz
zg&1nX_!g&4dTL&3MM05WFDO1h%}b^RHHIop%+LpCEJUvYrVrc$)MSGsdr%u2?1)>;
z#ihBon5!}i!0lE|PDpw}jk%&Skc-MeL<NWdIq((>$R0?dsR0Rs5=~J90|P@7$bq1C
zj2*WG6AzOFBMW1d7<OkSgPQ2DhzBJCkiVQk`okC)7-|^c5zk%2xPS@N8O`G;VJ-oU
z?y$5l)G#(PH8a+-)-XZjYT3X#SW{TDnTk|um?5Hhj42GY>@}=4Y&Gm@pzabIBtl>Q
z|Ns9#N?8Ny5rbkDoZ>+qs9{*ZkixhSG?K;SSJViKGsatNiACwTi4{erAWwty4443W
zAJm(g4st#yvvV<2X<>RB(z`$|At2pG%;*7y<1JQjb$5$7HxU{^99Sa=93$M|`~_<M
zrxf4f1a)i*ic&$$lEid~C?vYz?gjPML7kkbASZ)@UxSH@QHqg^u}T7$!yyTnAJogr
zOUzA;kH5tgAD^3_Qknx|^Tfv&mL}#vWtcPbN{T?n7J>50E#~5qq9RaPUIZ$~Aw?Y<
zqyjA}1qCK3@f3A{N(x?RlRP;!Cnr80$<=Wnb>N@|6%(L1DsBOf3^B1XF_H&a9xyR7
z{pVw1`p3k~^p}Z+=?@bt({Cm=reAFAd_UDZnDm91nEtUaGyP>@VfrJ)%JiFsjp-K)
zJJU}V4yGS0oLt|PgjpDc{uhB<q{$EQ7YC$ul$TfJ1o96zc<4Y6JakY5N*lL$;Uc9u
zsl||<Bq;IUf+{U7$;>H+_FzjY3o`T4!GQ<~KX90WtV0SJM5J=qK;pv=l%9+EK*7Vr
P!wBlX@Gy!niZB5H9bvLQ

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/sl/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/dep/sl/__pycache__/model.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6f0f4cad3dcc22e7872d1c2ee274f49f8582da16
GIT binary patch
literal 9943
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
CL@h}G

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/sl/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/dep/sl/__pycache__/parser.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..95e1cddfd1b7d2af2f9bbf1573def416297a278b
GIT binary patch
literal 12083
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/sl/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/dep/sl/__pycache__/parser.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9b16ba48675cbab2d7e21471d46322179b0928fb
GIT binary patch
literal 25291
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
PeFV#V0h5@j!0815$xn+h

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/sl/__pycache__/transform.cpython-310.pyc b/tania_scripts/supar/models/dep/sl/__pycache__/transform.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7df4678723720a507453f379f951e9dbd859a3a2
GIT binary patch
literal 3766
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/sl/__pycache__/transform.cpython-311.pyc b/tania_scripts/supar/models/dep/sl/__pycache__/transform.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..027f048a42a233403d83761297506d43e3d196b9
GIT binary patch
literal 7098
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
BzHk5l

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/sl/model.py b/tania_scripts/supar/models/dep/sl/model.py
new file mode 100644
index 0000000..79e5ec7
--- /dev/null
+++ b/tania_scripts/supar/models/dep/sl/model.py
@@ -0,0 +1,154 @@
+# -*- coding: utf-8 -*-
+
+import torch
+import torch.nn as nn
+from supar.model import Model
+from supar.modules import MLP, DecoderLSTM
+from supar.utils import Config
+from typing import Tuple, List, Union
+
+class SLDependencyModel(Model):
+    def __init__(self,
+                 n_words: int,
+                 n_labels: Union[Tuple[int], int],
+                 n_rels: int,
+                 n_tags: int = None,
+                 n_chars: int = None,
+                 encoder: str ='lstm',
+                 feat: List[str] = [],
+                 n_embed=100,
+                 n_pretrained=100,
+                 n_feat_embed=100,
+                 n_char_embed=50,
+                 n_char_hidden=100,
+                 char_pad_index=0,
+                 elmo='original_5b',
+                 elmo_bos_eos=(True, False),
+                 bert=None,
+                 n_bert_layers=4,
+                 mix_dropout=.0,
+                 bert_pooling='mean',
+                 bert_pad_index=0,
+                 finetune=False,
+                 n_plm_embed=0,
+                 embed_dropout=.33,
+                 n_encoder_hidden=800,
+                 n_encoder_layers=3,
+                 encoder_dropout=.33,
+                 n_arc_mlp=500,
+                 n_rel_mlp=100,
+                 mlp_dropout=.33,
+                 scale=0,
+                 pad_index=0,
+                 unk_index=1,
+                 **kwargs):
+        super().__init__(**Config().update(locals()))
+
+        # create decoder
+        self.label_decoder, self.rel_decoder = None, None
+        if self.args.decoder == 'lstm':
+            decoder = lambda out_dim: DecoderLSTM(device=torch.device("cuda" if torch.cuda.is_available() else "cpu"),
+                input_size=self.args.n_encoder_hidden, hidden_size=self.args.n_encoder_hidden,
+                num_layers=self.args.n_decoder_layers, dropout=mlp_dropout,
+                output_size=out_dim)
+        else:
+            decoder = lambda out_dim: MLP(
+                n_in=self.args.n_encoder_hidden, n_out=out_dim, dropout=mlp_dropout
+            )
+
+        if self.args.codes == '2p':
+            self.label_decoder1 = decoder(self.args.n_labels[0])
+            self.label_decoder2 = decoder(self.args.n_labels[1])
+            self.label_decoder = lambda x: (self.label_decoder1(x), self.label_decoder2(x))
+        else:
+            self.label_decoder = decoder(self.args.n_labels)
+
+        self.rel_decoder = decoder(self.args.n_rels)
+
+        # create delay projection
+        if self.args.delay != 0:
+            self.delay_proj = MLP(n_in=self.args.n_encoder_hidden * (self.args.delay + 1),
+                                  n_out=self.args.n_encoder_hidden, dropout=mlp_dropout)
+
+        # create PoS tagger
+        if self.args.encoder == 'lstm':
+            self.pos_tagger = DecoderLSTM(
+                input_size=self.args.n_encoder_hidden, hidden_size=self.args.n_encoder_hidden,
+                output_size=self.args.n_tags, num_layers=1, dropout=mlp_dropout, device=self.device)
+        else:
+            self.pos_tagger = nn.Identity()
+
+        self.criterion = nn.CrossEntropyLoss()
+
+    def forward(self, words: torch.Tensor, feats: List[torch.Tensor] = None) -> Tuple[torch.Tensor]:
+        r"""
+        Args:
+            words (~torch.LongTensor): ``[batch_size, seq_len]``.
+                Word indices.
+            feats (List[~torch.LongTensor]):
+                A list of feat indices.
+                The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``,
+                or ``[batch_size, seq_len]`` otherwise.
+                Default: ``None``.
+
+        Returns:
+            s_label (~Union[torch.Tensor, Tuple[torch.Tensor]]): ``[batch_size, seq_len, n_labels]``
+                Tensor or 2-dimensional tensor tuple (if 2-planar bracketing coding is being used) which holds the
+                scores of all possible labels.
+            s_rel (~torch.Tensor): ``[batch_size, seq_len, n_rels]``
+                Holds scores of all possible dependency relations.
+            s_tag (~torch.Tensor): ` [batch_size, seq_len, n_tags]``
+                Holds scores of all possible tags for each word.
+            qloss (~torch.Tensor):
+                Vector quantization loss.
+        """
+
+        # x ~ [batch_size, bos + pad(seq_len) + delay, n_encoder_hidden]
+        x = self.encode(words, feats)
+        x = x[:, 1:, :]                 # remove BoS token
+
+        # s_tag ~ [batch_size, pad(seq_len), n_tags]
+        s_tag = self.pos_tagger(x if self.args.delay == 0 else x[:, :-self.args.delay, :])
+
+        # map or concatenate delayed representations
+        if self.args.delay != 0:
+            x = torch.cat([x[:, i:(x.shape[1] - self.args.delay + i), :] for i in range(self.args.delay+1)], dim=2)
+            x = self.delay_proj(x)
+
+        # x ~ [batch_size, pad(seq_len), n_encoder_hidden]
+        batch_size, pad_seq_len, _ = x.shape
+
+        # pass through vector quantization module
+        x, qloss = self.vq_forward(x)
+
+        # make predictions of labels/relations
+        s_label = self.label_decoder(x)
+        s_rel = self.rel_decoder(x)
+
+        return s_label, s_rel, s_tag, qloss
+
+    def loss(
+        self,
+        s_label: Union[Tuple[torch.Tensor], torch.Tensor],
+        s_rel: torch.Tensor,
+        s_tag: torch.Tensor,
+        labels: Union[Tuple[torch.Tensor], torch.Tensor],
+        rels: torch.Tensor,
+        tags: torch.Tensor,
+        mask: torch.Tensor
+         ) -> torch.Tensor:
+
+        loss = self.criterion(s_label[mask], labels[mask]) if self.args.codes != '2p' else sum(self.criterion(scores[mask], golds[mask]) for scores, golds in zip(s_label, labels))
+
+        loss += self.criterion(s_rel[mask], rels[mask])
+
+        if self.args.encoder == 'lstm':
+            loss += self.criterion(s_tag[mask], tags[mask])
+        return loss
+
+    def decode(self, s_label: Union[Tuple[torch.Tensor], torch.Tensor], s_rel: torch.Tensor, s_tag: torch.Tensor,
+               mask: torch.Tensor):
+        label_preds = s_label.argmax(-1) if self.args.codes != '2p' else tuple(map(lambda x: x.argmax(-1), s_label))
+        rel_preds = s_rel.argmax(-1)
+        tag_preds = s_tag.argmax(-1) if self.args.encoder == 'lstm' else None
+        return label_preds, rel_preds, tag_preds
diff --git a/tania_scripts/supar/models/dep/sl/parser.py b/tania_scripts/supar/models/dep/sl/parser.py
new file mode 100644
index 0000000..af95475
--- /dev/null
+++ b/tania_scripts/supar/models/dep/sl/parser.py
@@ -0,0 +1,323 @@
+# -*- coding: utf-8 -*-
+
+import os, re
+from typing import Iterable, Union, List
+
+import torch
+from supar.models.dep.sl.model import SLDependencyModel
+from supar.parser import Parser
+from supar.utils import Config, Dataset, Embedding
+from supar.utils.common import BOS, PAD, UNK
+from supar.utils.field import Field, RawField, SubwordField
+from supar.utils.logging import get_logger
+from supar.utils.metric import AttachmentMetric
+from supar.utils.tokenizer import TransformerTokenizer
+from supar.utils.transform import Batch
+from supar.models.dep.sl.transform import SLDependency
+from supar.codelin import get_dep_encoder, LinearizedTree, D_Label
+from supar.codelin.utils.constants import D_ROOT_HEAD
+from supar.codelin import LABEL_SEPARATOR
+logger = get_logger(__name__)
+from typing import Tuple, List, Union
+
+
+NONE = '<none>'
+OPTIONS = [r'>\*', r'<\*', r'/\*', r'\\\*']
+
+
+def split_planes(labels: Tuple[str], plane: int) -> Tuple[str]:
+
+    split = lambda label: min(match.span()[0] if match is not None else len(label) for match in map(lambda x: re.search(x, label), OPTIONS))
+    splits = list(map(split, labels))
+    if plane == 0:
+        return tuple(label[:i] for label, i in zip(labels, splits))
+    else:
+        return tuple(label[i:] if i < len(label) else NONE for label, i in zip(labels, splits))
+
+class SLDependencyParser(Parser):
+
+    NAME = 'SLDependencyParser'
+    MODEL = SLDependencyModel
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self.TAG = self.transform.UPOS
+        self.LABEL, self.DEPREL = self.transform.LABEL, self.transform.DEPREL
+        self.encoder = get_dep_encoder(self.args.codes, LABEL_SEPARATOR)
+
+    def train(
+        self,
+        train: Union[str, Iterable],
+        dev: Union[str, Iterable],
+        test: Union[str, Iterable],
+        epochs: int = 1000,
+        patience: int = 100,
+        batch_size: int = 1000,
+        update_steps: int = 1,
+        buckets: int = 32,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        punct: bool = False,
+        tree: bool = False,
+        proj: bool = False,
+        partial: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().train(**Config().update(locals()))
+
+    def few_shot(
+            self,
+            train: str,
+            dev: Union[str, Iterable],
+            test: Union[str, Iterable],
+            n_samples: int,
+            epochs: int = 2,
+            batch_size: int = 50
+    ) -> None:
+        return super().few_shot(**Config().update(locals()))
+
+    def predict(
+            self,
+            data: Union[str, Iterable],
+            pred: str = None,
+            lang: str = None,
+            prob: bool = False,
+            batch_size: int = 5000,
+            buckets: int = 8,
+            workers: int = 0,
+            amp: bool = False,
+            cache: bool = False,
+            tree: bool = True,
+            proj: bool = False,
+            verbose: bool = True,
+            **kwargs
+    ):
+        return super().predict(**Config().update(locals()))
+
+    def evaluate(
+        self,
+        data: Union[str, Iterable],
+        batch_size: int = 500,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        punct: bool = False,
+        tree: bool = True,
+        proj: bool = False,
+        partial: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().evaluate(**Config().update(locals()))
+
+    def train_step(self, batch: Batch) -> torch.Tensor:
+        if self.args.encoder == 'lstm':
+            words, texts, chars, tags, _, rels, *labels = batch
+            feats = [chars]
+        else:
+            words, texts, tags, _, rels, *labels = batch
+            feats = []
+        labels = labels[0] if len(labels) == 1 else labels
+        mask = batch.mask[:, (1+self.args.delay):]
+
+        # forward pass
+        s_label, s_rel, s_tag, qloss = self.model(words, feats)
+
+        # compute loss
+        loss = self.model.loss(s_label, s_rel, s_tag, labels, rels, tags, mask) + qloss
+
+        return loss
+
+    @torch.no_grad()
+    def eval_step(self, batch: Batch) -> AttachmentMetric:
+        if self.args.encoder == 'lstm':
+            words, texts, chars, tags, heads, rels, *labels = batch
+            feats = [chars]
+        else:
+            words, texts, tags, heads, rels, *labels = batch
+            feats = []
+        labels = labels[0] if len(labels) == 1 else labels
+        mask = batch.mask[:, (1+self.args.delay):]
+        lens = (batch.lens - 1 - self.args.delay).tolist()
+
+        # forward pass
+        s_label, s_rel, s_tag, qloss = self.model(words, feats)
+
+        # compute loss and decode
+        loss = self.model.loss(s_label, s_rel, s_tag, labels, rels, tags, mask) + qloss
+        label_preds, rel_preds, tag_preds = self.model.decode(s_label, s_rel, s_tag, mask)
+
+        # obtain original label and deprel strings to compute decoding
+        if self.args.codes == '2p':
+            label_preds = [
+                (self.LABEL[0].vocab[l1.tolist()], self.LABEL[1].vocab[l2.tolist()])
+                for l1, l2 in zip(*map(lambda x: x[mask].split(lens), label_preds))
+            ]
+            label_preds = [
+                list(map(lambda x: x[0] + (x[1] if x[1] != NONE else ''), zip(*label_pred)))
+                for label_pred in label_preds
+            ]
+        else:
+            label_preds = [self.LABEL.vocab[i.tolist()] for i in label_preds[mask].split(lens)]
+        deprel_preds = [self.DEPREL.vocab[i.tolist()] for i in rel_preds[mask].split(lens)]
+
+        if self.args.encoder == 'lstm':
+            tag_preds = [self.TAG.vocab[i.tolist()] for i in tag_preds[mask].split(lens)]
+        else:
+            tag_preds = [self.TAG.vocab[i.tolist()] for i in tags[mask].split(lens)]
+
+        # decode
+        head_preds = list()
+        for label_pred, deprel_pred, tag_pred, forms in zip(label_preds, deprel_preds, tag_preds, texts):
+            labels = [D_Label(label, deprel, self.encoder.separator) for label, deprel in zip(label_pred, deprel_pred)]
+            linearized_tree = LinearizedTree(list(forms), tag_pred, ['_']*len(forms), labels, 0)
+
+            decoded_tree = self.encoder.decode(linearized_tree)
+            decoded_tree.postprocess_tree(D_ROOT_HEAD)
+            head_preds.append(torch.tensor([int(node.head) for node in decoded_tree.nodes]))
+
+
+        # resize head predictions (add padding)
+        resize = lambda list_of_tensors: \
+            torch.stack([
+                torch.concat([x, torch.zeros(mask.shape[1] - len(x))])
+                for x in list_of_tensors])
+
+        head_preds = resize(head_preds).to(torch.int32).to(self.model.device)
+
+        return AttachmentMetric(loss, (head_preds, rel_preds), (heads, rels), mask)
+
+
+    @torch.no_grad()
+    def pred_step(self, batch: Batch) -> Batch:
+        if self.args.encoder == 'lstm':
+            words, texts, *feats, tags = batch
+        else:
+            words, texts, *feats, tags = batch
+        mask = batch.mask[:, (1 + self.args.delay):]
+        lens = (batch.lens - 1 - self.args.delay).tolist()
+
+        # forward pass
+        s_label, s_rel, s_tag, qloss = self.model(words, feats)
+
+        # compute loss and decode
+        label_preds, rel_preds, tag_preds = self.model.decode(s_label, s_rel, s_tag, mask)
+
+        # obtain original label and deprel strings to compute decoding
+        if self.args.codes == '2p':
+            label_preds = [
+                (self.LABEL[0].vocab[l1.tolist()], self.LABEL[1].vocab[l2.tolist()])
+                for l1, l2 in zip(*map(lambda x: x[mask].split(lens), label_preds))
+            ]
+            label_preds = [
+                list(map(lambda x: x[0] + (x[1] if x[1] != NONE else ''), zip(*label_pred)))
+                for label_pred in label_preds
+            ]
+        else:
+            label_preds = [self.LABEL.vocab[i.tolist()] for i in label_preds[mask].split(lens)]
+
+        deprel_preds = [self.DEPREL.vocab[i.tolist()] for i in rel_preds[mask].split(lens)]
+
+        if self.args.encoder == 'lstm':
+            tag_preds = [self.TAG.vocab[i.tolist()] for i in tag_preds[mask].split(lens)]
+        else:
+            tag_preds = [self.TAG.vocab[i.tolist()] for i in tags[mask].split(lens)]
+
+        # decode
+        head_preds = list()
+        for label_pred, deprel_pred, tag_pred, forms in zip(label_preds, deprel_preds, tag_preds, texts):
+            labels = [D_Label(label, deprel, self.encoder.separator) for label, deprel in zip(label_pred, deprel_pred)]
+            linearized_tree = LinearizedTree(forms, tag_pred, ['_'] * len(forms), labels, 0)
+
+            decoded_tree = self.encoder.decode(linearized_tree)
+            decoded_tree.postprocess_tree(D_ROOT_HEAD)
+
+            head_preds.append([int(node.head) for node in decoded_tree.nodes])
+
+        batch.heads = head_preds
+        batch.rels = deprel_preds
+
+        return batch
+
+    @classmethod
+    def build(cls, path, min_freq=2, fix_len=20, **kwargs):
+        args = Config(**locals())
+
+        os.makedirs(os.path.dirname(path) or './', exist_ok=True)
+        if os.path.exists(path) and not args.build:
+            parser = cls.load(**args)
+            parser.model = cls.MODEL(**parser.args)
+            parser.model.load_pretrained(parser.transform.FORM[0].embed).to(parser.device)
+            return parser
+
+        logger.info("Building the fields")
+        CHAR = None
+        if args.encoder == 'bert':
+            t = TransformerTokenizer(args.bert)
+            pad_token = t.pad if t.pad else PAD
+            WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, fix_len=args.fix_len, tokenize=t, delay=args.delay)
+            WORD.vocab = t.vocab
+        else:
+            WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, lower=True, delay=args.delay)
+            if 'char' in args.feat:
+                CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, fix_len=args.fix_len, delay=args.delay)
+        TEXT = RawField('texts')
+        TAG = Field('tags')
+
+
+        if args.codes == '2p':
+            LABEL1 = Field('labels1', fn=lambda seq: split_planes(seq, 0))
+            LABEL2 = Field('labels2', fn=lambda seq: split_planes(seq, 1))
+            LABEL = (LABEL1, LABEL2)
+        else:
+            LABEL = Field('labels')
+
+        DEPREL = Field('rels')
+        HEAD = Field('heads', use_vocab=False)
+
+        transform = SLDependency(
+            encoder=get_dep_encoder(args.codes, LABEL_SEPARATOR),
+            FORM=(WORD, TEXT, CHAR), UPOS=TAG, HEAD=HEAD, DEPREL=DEPREL, LABEL=LABEL)
+
+        train = Dataset(transform, args.train, **args)
+        if args.encoder != 'bert':
+            WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x))
+            if CHAR:
+                CHAR.build(train)
+        TAG.build(train)
+        DEPREL.build(train)
+
+        if args.codes == '2p':
+            LABEL[0].build(train)
+            LABEL[1].build(train)
+        else:
+            LABEL.build(train)
+
+        args.update({
+            'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init,
+            'n_labels': len(LABEL.vocab) if args.codes != '2p' else (len(LABEL[0].vocab), len(LABEL[1].vocab)),
+            'n_rels': len(DEPREL.vocab),
+            'n_tags': len(TAG.vocab),
+            'n_chars': len(CHAR.vocab) if CHAR is not None else None,
+            'char_pad_index': CHAR.pad_index if CHAR is not None else None,
+            'pad_index': WORD.pad_index,
+            'unk_index': WORD.unk_index,
+            'bos_index': WORD.bos_index,
+            'delay': args.delay
+        })
+        logger.info(f"{transform}")
+
+        logger.info("Building the model")
+        model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None)
+        logger.info(f"{model}\n")
+
+        parser = cls(args, model, transform)
+        parser.model.to(parser.device)
+        return parser
+
+
+
diff --git a/tania_scripts/supar/models/dep/sl/transform.py b/tania_scripts/supar/models/dep/sl/transform.py
new file mode 100644
index 0000000..8603cb8
--- /dev/null
+++ b/tania_scripts/supar/models/dep/sl/transform.py
@@ -0,0 +1,102 @@
+from supar.utils.transform import Transform, Sentence
+from supar.utils.field import Field
+from typing import Iterable, List, Optional, Union
+from supar.codelin import D_Tree
+
+class SLDependency(Transform):
+
+    fields = ['ID', 'FORM', 'LEMMA', 'UPOS', 'XPOS', 'FEATS', 'HEAD', 'DEPREL', 'DEPS', 'MISC', 'LABEL']
+
+    def __init__(
+        self,
+        encoder,
+        ID: Optional[Union[Field, Iterable[Field]]] = None,
+        FORM: Optional[Union[Field, Iterable[Field]]] = None,
+        LEMMA: Optional[Union[Field, Iterable[Field]]] = None,
+        UPOS: Optional[Union[Field, Iterable[Field]]] = None,
+        XPOS: Optional[Union[Field, Iterable[Field]]] = None,
+        FEATS: Optional[Union[Field, Iterable[Field]]] = None,
+        HEAD: Optional[Union[Field, Iterable[Field]]] = None,
+        DEPREL: Optional[Union[Field, Iterable[Field]]] = None,
+        DEPS: Optional[Union[Field, Iterable[Field]]] = None,
+        MISC: Optional[Union[Field, Iterable[Field]]] = None,
+        LABEL: Optional[Union[Field, Iterable[Field]]] = None
+    ):
+        super().__init__()
+
+        self.encoder = encoder
+        self.ID = ID
+        self.FORM = FORM
+        self.LEMMA = LEMMA
+        self.UPOS = UPOS
+        self.XPOS = XPOS
+        self.FEATS = FEATS
+        self.HEAD = HEAD
+        self.DEPREL = DEPREL
+        self.DEPS = DEPS
+        self.MISC = MISC
+        self.LABEL = LABEL
+
+    @property
+    def src(self):
+        return self.FORM, self.LEMMA, self.UPOS, self.XPOS, self.FEATS
+
+    @property
+    def tgt(self):
+        return self.HEAD, self.DEPREL, self.DEPS, self.MISC, self.LABEL
+
+    def load(
+        self,
+        data: str,
+        **kwargs
+    ):
+        lines = open(data)
+        index, sentence = 0, []
+        for line in lines:
+            line = line.strip()
+            if len(line) == 0:
+                sentence = SLDependencySentence(self, sentence, self.encoder, index)
+                if sentence.values:
+                    yield sentence
+                    index += 1
+                sentence = []
+            else:
+                sentence.append(line)
+
+
+
+class SLDependencySentence(Sentence):
+    def __init__(self, transform: SLDependency, lines: List[str], encoder, index: Optional[int] = None):
+        super().__init__(transform, index)
+        self.annotations = dict()
+        self.values = list()
+
+        for i, line in enumerate(lines):
+            value = line.split('\t')
+            if value[0].startswith('#') or not value[0].isdigit():
+                self.annotations[-i-1] = line
+            else:
+                self.annotations[len(self.values)] = line
+                self.values.append(value)
+
+        # convert values into nodes
+        tree = D_Tree.from_string('\n'.join(['\t'.join(value) for value in self.values]))
+
+        # linearize tree
+        linearized_tree = encoder.encode(tree)
+
+        self.values = list(zip(*self.values))
+        self.values[6] = tuple(map(int, self.values[6]))
+
+        # add labels
+        labels = tuple(str(label.xi) for label in linearized_tree.labels)
+        self.values.append(labels)
+
+
+
+    def __repr__(self):
+        # cover the raw lines
+        merged = {**self.annotations,
+                  **{i: '\t'.join(map(str, line))
+                     for i, line in enumerate(zip(*self.values[:-1]))}}
+        return '\n'.join(merged.values()) + '\n'
diff --git a/tania_scripts/supar/models/dep/vi/__init__.py b/tania_scripts/supar/models/dep/vi/__init__.py
new file mode 100644
index 0000000..18dc355
--- /dev/null
+++ b/tania_scripts/supar/models/dep/vi/__init__.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+
+from .model import VIDependencyModel
+from .parser import VIDependencyParser
+
+__all__ = ['VIDependencyModel', 'VIDependencyParser']
diff --git a/tania_scripts/supar/models/dep/vi/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/dep/vi/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..78075f4745b4926add51043c086c330542182c05
GIT binary patch
literal 287
zcmd1j<>g{vU|`^9Uz9$Ffq~&Mh=Yuo7#J8F7#J9eRTvl;QW#Pga~N_NqZk=MY^EHh
zT;?cdMursT6qa<RD3%n~U<OULmy8Sy44RC$1j9UCQVUY^Qd0AhD}D1*QgbvJZwVm_
z1|$|0rxq1~>?mSpU|{gmWWB|j3sMOdyTw)jQ2>&=#U3A@n3EG9zmlPdoq+*D{BqUL
z$j?pHFG(!POw3EvOUg-1$xJQMPtMOR$k$CTDA5I*re9oIkXWP-W*6(Hq!#FxW$MSr
lXXa&=#K-FuRNmsS$<0qG%}KQbIlY*Tfq{XCiHDJg2>>_3NX7sF

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/vi/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/dep/vi/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..01b920378d10fc9cdbec8a67d9522ea76e4b0702
GIT binary patch
literal 356
zcmZ3^%ge>Uz`&q%Uo~S60|Ucj5C?{tpp4II3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI
zW=4h-<`kB6rYM#a)?fxrwwH_y3=Eo#w*<pHT~Z5D^HNgtk}G}lQ&Mv@8E*+83kD<>
z6{i*zF*7hQ6tOTcF!*V*-eS!KsRWDNVk>|s0Lk5AkB?8x$%&6&$?zHEs$aqS8Tq-X
z`Xz}anTdIcdPzBnDVeE7`pNmZ1^K!qsTC!<sbz^d`Xz~ZnThem$wiq3CB^#1r3Hya
z`d}-H^;1#{^vg2!<Kr{)GE3s)^$IF~aoFVMr<CTT+7)p#Fff2TQf$S*!0>^Yk&*EO
l8v~>21qKylbb~?d0xEjIEq6h|<N}vz13L&7aWXJ4003*_Vxs^6

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/vi/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/dep/vi/__pycache__/model.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9a980f9eebf2cc021c1f6a146c773ebb86340a75
GIT binary patch
literal 10828
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/vi/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/dep/vi/__pycache__/model.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d903b7c1fad5509a97624f635495068bf48f4a90
GIT binary patch
literal 14278
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/vi/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/dep/vi/__pycache__/parser.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..daf22311cfc35994234b5e1731ac3cb9e418b269
GIT binary patch
literal 4732
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
WBZ@&;MSzKeiHC`Y5dk@vM3@0cNiekl

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/vi/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/dep/vi/__pycache__/parser.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..94aaa00287400fd00c2dabd76be8508ea9161706
GIT binary patch
literal 8333
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/dep/vi/model.py b/tania_scripts/supar/models/dep/vi/model.py
new file mode 100644
index 0000000..8ad8c3a
--- /dev/null
+++ b/tania_scripts/supar/models/dep/vi/model.py
@@ -0,0 +1,253 @@
+# -*- coding: utf-8 -*-
+
+import torch
+import torch.nn as nn
+from supar.models.dep.biaffine.model import BiaffineDependencyModel
+from supar.models.dep.biaffine.transform import CoNLL
+from supar.modules import MLP, Biaffine, Triaffine
+from supar.structs import (DependencyCRF, DependencyLBP, DependencyMFVI,
+                           MatrixTree)
+from supar.utils import Config
+from supar.utils.common import MIN
+
+
+class VIDependencyModel(BiaffineDependencyModel):
+    r"""
+    The implementation of Dependency Parser using Variational Inference :cite:`wang-tu-2020-second`.
+
+    Args:
+        n_words (int):
+            The size of the word vocabulary.
+        n_rels (int):
+            The number of labels in the treebank.
+        n_tags (int):
+            The number of POS tags, required if POS tag embeddings are used. Default: ``None``.
+        n_chars (int):
+            The number of characters, required if character-level representations are used. Default: ``None``.
+        encoder (str):
+            Encoder to use.
+            ``'lstm'``: BiLSTM encoder.
+            ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``.
+            Default: ``'lstm'``.
+        feat (List[str]):
+            Additional features to use, required if ``encoder='lstm'``.
+            ``'tag'``: POS tag embeddings.
+            ``'char'``: Character-level representations extracted by CharLSTM.
+            ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible.
+            Default: [``'char'``].
+        n_embed (int):
+            The size of word embeddings. Default: 100.
+        n_pretrained (int):
+            The size of pretrained word embeddings. Default: 100.
+        n_feat_embed (int):
+            The size of feature representations. Default: 100.
+        n_char_embed (int):
+            The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50.
+        n_char_hidden (int):
+            The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100.
+        char_pad_index (int):
+            The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0.
+        elmo (str):
+            Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``.
+        elmo_bos_eos (Tuple[bool]):
+            A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs.
+            Default: ``(True, False)``.
+        bert (str):
+            Specifies which kind of language model to use, e.g., ``'bert-base-cased'``.
+            This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_.
+            Default: ``None``.
+        n_bert_layers (int):
+            Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features.
+            The final outputs would be weighted sum of the hidden states of these layers.
+            Default: 4.
+        mix_dropout (float):
+            The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0.
+        bert_pooling (str):
+            Pooling way to get token embeddings.
+            ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all.
+            Default: ``mean``.
+        bert_pad_index (int):
+            The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features.
+            Default: 0.
+        finetune (bool):
+            If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``.
+        n_plm_embed (int):
+            The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0.
+        embed_dropout (float):
+            The dropout ratio of input embeddings. Default: .33.
+        n_encoder_hidden (int):
+            The size of encoder hidden states. Default: 800.
+        n_encoder_layers (int):
+            The number of encoder layers. Default: 3.
+        encoder_dropout (float):
+            The dropout ratio of encoder layer. Default: .33.
+        n_arc_mlp (int):
+            Arc MLP size. Default: 500.
+        n_sib_mlp (int):
+            Binary factor MLP size. Default: 100.
+        n_rel_mlp  (int):
+            Label MLP size. Default: 100.
+        mlp_dropout (float):
+            The dropout ratio of MLP layers. Default: .33.
+        scale (float):
+            Scaling factor for affine scores. Default: 0.
+        inference (str):
+            Approximate inference methods. Default: ``mfvi``.
+        max_iter (int):
+            Max iteration times for inference. Default: 3.
+        interpolation (int):
+            Constant to even out the label/edge loss. Default: .1.
+        pad_index (int):
+            The index of the padding token in the word vocabulary. Default: 0.
+        unk_index (int):
+            The index of the unknown token in the word vocabulary. Default: 1.
+
+    .. _transformers:
+        https://github.com/huggingface/transformers
+    """
+
+    def __init__(self,
+                 n_words,
+                 n_rels,
+                 n_tags=None,
+                 n_chars=None,
+                 encoder='lstm',
+                 feat=['char'],
+                 n_embed=100,
+                 n_pretrained=100,
+                 n_feat_embed=100,
+                 n_char_embed=50,
+                 n_char_hidden=100,
+                 char_pad_index=0,
+                 elmo='original_5b',
+                 elmo_bos_eos=(True, False),
+                 bert=None,
+                 n_bert_layers=4,
+                 mix_dropout=.0,
+                 bert_pooling='mean',
+                 bert_pad_index=0,
+                 finetune=False,
+                 n_plm_embed=0,
+                 embed_dropout=.33,
+                 n_encoder_hidden=800,
+                 n_encoder_layers=3,
+                 encoder_dropout=.33,
+                 n_arc_mlp=500,
+                 n_sib_mlp=100,
+                 n_rel_mlp=100,
+                 mlp_dropout=.33,
+                 scale=0,
+                 inference='mfvi',
+                 max_iter=3,
+                 pad_index=0,
+                 unk_index=1,
+                 **kwargs):
+        super().__init__(**Config().update(locals()))
+
+        self.arc_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_arc_mlp, dropout=mlp_dropout)
+        self.arc_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_arc_mlp, dropout=mlp_dropout)
+        self.sib_mlp_s = MLP(n_in=self.args.n_encoder_hidden, n_out=n_sib_mlp, dropout=mlp_dropout)
+        self.sib_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_sib_mlp, dropout=mlp_dropout)
+        self.sib_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_sib_mlp, dropout=mlp_dropout)
+        self.rel_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_rel_mlp, dropout=mlp_dropout)
+        self.rel_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_rel_mlp, dropout=mlp_dropout)
+
+        self.arc_attn = Biaffine(n_in=n_arc_mlp, scale=scale, bias_x=True, bias_y=False)
+        self.sib_attn = Triaffine(n_in=n_sib_mlp, scale=scale, bias_x=True, bias_y=True)
+        self.rel_attn = Biaffine(n_in=n_rel_mlp, n_out=n_rels, bias_x=True, bias_y=True)
+        self.inference = (DependencyMFVI if inference == 'mfvi' else DependencyLBP)(max_iter)
+        self.criterion = nn.CrossEntropyLoss()
+
+    def forward(self, words, feats=None):
+        r"""
+        Args:
+            words (~torch.LongTensor): ``[batch_size, seq_len]``.
+                Word indices.
+            feats (List[~torch.LongTensor]):
+                A list of feat indices.
+                The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``,
+                or ``[batch_size, seq_len]`` otherwise.
+                Default: ``None``.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor, ~torch.Tensor:
+                Scores of all possible arcs (``[batch_size, seq_len, seq_len]``),
+                dependent-head-sibling triples (``[batch_size, seq_len, seq_len, seq_len]``) and
+                all possible labels on each arc (``[batch_size, seq_len, seq_len, n_labels]``).
+        """
+
+        x = self.encode(words, feats)
+        mask = words.ne(self.args.pad_index) if len(words.shape) < 3 else words.ne(self.args.pad_index).any(-1)
+
+        arc_d = self.arc_mlp_d(x)
+        arc_h = self.arc_mlp_h(x)
+        sib_s = self.sib_mlp_s(x)
+        sib_d = self.sib_mlp_d(x)
+        sib_h = self.sib_mlp_h(x)
+        rel_d = self.rel_mlp_d(x)
+        rel_h = self.rel_mlp_h(x)
+
+        # [batch_size, seq_len, seq_len]
+        s_arc = self.arc_attn(arc_d, arc_h).masked_fill_(~mask.unsqueeze(1), MIN)
+        # [batch_size, seq_len, seq_len, seq_len]
+        s_sib = self.sib_attn(sib_s, sib_d, sib_h).permute(0, 3, 1, 2)
+        # [batch_size, seq_len, seq_len, n_rels]
+        s_rel = self.rel_attn(rel_d, rel_h).permute(0, 2, 3, 1)
+
+        return s_arc, s_sib, s_rel
+
+    def loss(self, s_arc, s_sib, s_rel, arcs, rels, mask):
+        r"""
+        Args:
+            s_arc (~torch.Tensor): ``[batch_size, seq_len, seq_len]``.
+                Scores of all possible arcs.
+            s_sib (~torch.Tensor): ``[batch_size, seq_len, seq_len, seq_len]``.
+                Scores of all possible dependent-head-sibling triples.
+            s_rel (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``.
+                Scores of all possible labels on each arc.
+            arcs (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The tensor of gold-standard arcs.
+            rels (~torch.LongTensor): ``[batch_size, seq_len]``.
+                The tensor of gold-standard labels.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens.
+
+        Returns:
+            ~torch.Tensor:
+                The training loss.
+        """
+
+        arc_loss, marginals = self.inference((s_arc, s_sib), mask, arcs)
+        s_rel, rels = s_rel[mask], rels[mask]
+        s_rel = s_rel[torch.arange(len(rels)), arcs[mask]]
+        rel_loss = self.criterion(s_rel, rels)
+        loss = arc_loss + rel_loss
+        return loss, marginals
+
+    def decode(self, s_arc, s_rel, mask, tree=False, proj=False):
+        r"""
+        Args:
+            s_arc (~torch.Tensor): ``[batch_size, seq_len, seq_len]``.
+                Scores of all possible arcs.
+            s_rel (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``.
+                Scores of all possible labels on each arc.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens.
+            tree (bool):
+                If ``True``, ensures to output well-formed trees. Default: ``False``.
+            proj (bool):
+                If ``True``, ensures to output projective trees. Default: ``False``.
+
+        Returns:
+            ~torch.LongTensor, ~torch.LongTensor:
+                Predicted arcs and labels of shape ``[batch_size, seq_len]``.
+        """
+
+        lens = mask.sum(1)
+        arc_preds = s_arc.argmax(-1)
+        bad = [not CoNLL.istree(seq[1:i+1], proj) for i, seq in zip(lens.tolist(), arc_preds.tolist())]
+        if tree and any(bad):
+            arc_preds[bad] = (DependencyCRF if proj else MatrixTree)(s_arc[bad], mask[bad].sum(-1)).argmax
+        rel_preds = s_rel.argmax(-1).gather(-1, arc_preds.unsqueeze(-1)).squeeze(-1)
+
+        return arc_preds, rel_preds
diff --git a/tania_scripts/supar/models/dep/vi/parser.py b/tania_scripts/supar/models/dep/vi/parser.py
new file mode 100644
index 0000000..3808a3d
--- /dev/null
+++ b/tania_scripts/supar/models/dep/vi/parser.py
@@ -0,0 +1,124 @@
+# -*- coding: utf-8 -*-
+
+from typing import Iterable, Union
+
+import torch
+
+from supar.models.dep.biaffine.parser import BiaffineDependencyParser
+from supar.models.dep.vi.model import VIDependencyModel
+from supar.utils import Config
+from supar.utils.fn import ispunct
+from supar.utils.logging import get_logger
+from supar.utils.metric import AttachmentMetric
+from supar.utils.transform import Batch
+
+logger = get_logger(__name__)
+
+
+class VIDependencyParser(BiaffineDependencyParser):
+    r"""
+    The implementation of Dependency Parser using Variational Inference :cite:`wang-tu-2020-second`.
+    """
+
+    NAME = 'vi-dependency'
+    MODEL = VIDependencyModel
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+    def train(
+        self,
+        train: Union[str, Iterable],
+        dev: Union[str, Iterable],
+        test: Union[str, Iterable],
+        epochs: int = 1000,
+        patience: int = 100,
+        batch_size: int = 5000,
+        update_steps: int = 1,
+        buckets: int = 32,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        punct: bool = False,
+        tree: bool = False,
+        proj: bool = False,
+        partial: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().train(**Config().update(locals()))
+
+    def evaluate(
+        self,
+        data: Union[str, Iterable],
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        punct: bool = False,
+        tree: bool = True,
+        proj: bool = True,
+        partial: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().evaluate(**Config().update(locals()))
+
+    def predict(
+        self,
+        data: Union[str, Iterable],
+        pred: str = None,
+        lang: str = None,
+        prob: bool = False,
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        tree: bool = True,
+        proj: bool = True,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().predict(**Config().update(locals()))
+
+    def train_step(self, batch: Batch) -> torch.Tensor:
+        words, _, *feats, arcs, rels = batch
+        mask = batch.mask
+        # ignore the first token of each sentence
+        mask[:, 0] = 0
+        s_arc, s_sib, s_rel = self.model(words, feats)
+        loss, *_ = self.model.loss(s_arc, s_sib, s_rel, arcs, rels, mask)
+        return loss
+
+    @torch.no_grad()
+    def eval_step(self, batch: Batch) -> AttachmentMetric:
+        words, _, *feats, arcs, rels = batch
+        mask = batch.mask
+        # ignore the first token of each sentence
+        mask[:, 0] = 0
+        s_arc, s_sib, s_rel = self.model(words, feats)
+        loss, s_arc = self.model.loss(s_arc, s_sib, s_rel, arcs, rels, mask)
+        arc_preds, rel_preds = self.model.decode(s_arc, s_rel, mask, self.args.tree, self.args.proj)
+        if self.args.partial:
+            mask &= arcs.ge(0)
+        # ignore all punctuation if not specified
+        if not self.args.punct:
+            mask.masked_scatter_(mask, ~mask.new_tensor([ispunct(w) for s in batch.sentences for w in s.words]))
+        return AttachmentMetric(loss, (arc_preds, rel_preds), (arcs, rels), mask)
+
+    @torch.no_grad()
+    def pred_step(self, batch: Batch) -> Batch:
+        words, _, *feats = batch
+        mask, lens = batch.mask, (batch.lens - 1).tolist()
+        # ignore the first token of each sentence
+        mask[:, 0] = 0
+        s_arc, s_sib, s_rel = self.model(words, feats)
+        s_arc = self.model.inference((s_arc, s_sib), mask)
+        arc_preds, rel_preds = self.model.decode(s_arc, s_rel, mask, self.args.tree, self.args.proj)
+        batch.arcs = [i.tolist() for i in arc_preds[mask].split(lens)]
+        batch.rels = [self.REL.vocab[i.tolist()] for i in rel_preds[mask].split(lens)]
+        if self.args.prob:
+            batch.probs = [prob[1:i+1, :i+1].cpu() for i, prob in zip(lens, s_arc.unbind())]
+        return batch
diff --git a/tania_scripts/supar/models/sdp/__init__.py b/tania_scripts/supar/models/sdp/__init__.py
new file mode 100644
index 0000000..633e238
--- /dev/null
+++ b/tania_scripts/supar/models/sdp/__init__.py
@@ -0,0 +1,7 @@
+# -*- coding: utf-8 -*-
+
+from .biaffine import BiaffineSemanticDependencyModel, BiaffineSemanticDependencyParser
+from .vi import VISemanticDependencyModel, VISemanticDependencyParser
+
+__all__ = ['BiaffineSemanticDependencyModel', 'BiaffineSemanticDependencyParser',
+           'VISemanticDependencyModel', 'VISemanticDependencyParser']
diff --git a/tania_scripts/supar/models/sdp/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/sdp/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..02080dfc284fa4d868f12d9e49fca7f0775a90f5
GIT binary patch
literal 396
zcmd1j<>g{vU|`^9Uz8re$iVOz#6iYP3=9ko3=9m#It&a9DGVu$ISjdsQH;4vQA~^=
zK2r{JE=v?kE^8DkBSShv3iBeyD7F-qU<OUrmy8Sy44O>0<ef4T)6z2YQiD@-6Z1+k
zlU-5^Qu9($^O7rl^HWlDZYkha5Rh0@oLZ#GbW1YK6PI==Y*J8-EJYv>6frX}Fch(X
z2v!CL20u;qTO3JHM<Ep4Vk*l-D7wWSAD@_$6Cb~lp@<Wt6GZ%S($C1xP1P?+EXhpF
zOVmrsNleL1Ez(cU&n?K;O)n_X%?0^Lzqqs@u}B}xF4iwjDbSCP&&<m#iI3MSsJz8t
ZlbfGXnv-e=3ZG&&1_lNJCILnsCII-mY&rk{

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/sdp/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/sdp/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f809f66bbc799ef64855403f747872f7bcc4dc85
GIT binary patch
literal 487
zcmZ3^%ge>Uz`&q%Uo|6uk%8echy%k+P{wCH1_p-d3@HpLj5!Rsj8TlaOi@gXAU;zL
zb1q91OD<~^D<eZXLkjaE#wfNFmS6@=)|ZS73=En~x8$8N6VuW%^HPITa})DQGLv0W
z3sUn^QuC54ee+XNb8ac%RuGU_RGeC*$#hFH%oCS(DQr?ujVwjX3=9lKEFgjvM6fY1
zF!*V*-{MGuItroS7E@Vf5nRzN_W1b3oSgXhl?<Ojq3|m}KO;XkRlg*$Br`EDQ7<Vc
zF(os#NIyA0w;*4)B(<VMH?=G=N53R7FEcT|IJqdZprly8xU?X#NIw_k&0_uHlmh+u
z_{_Y_lK6PNg34bUHo5sJr8%i~MZ63Q44}{|4q#wl_`uA_$oPScfiZ&d0z)_^y20Rj
Z0UP?j!pQB$_<;dIHn4+W5jO(^0|4UdjUNC2

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/sdp/biaffine/__init__.py b/tania_scripts/supar/models/sdp/biaffine/__init__.py
new file mode 100644
index 0000000..ab2feee
--- /dev/null
+++ b/tania_scripts/supar/models/sdp/biaffine/__init__.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+
+from .model import BiaffineSemanticDependencyModel
+from .parser import BiaffineSemanticDependencyParser
+
+__all__ = ['BiaffineSemanticDependencyModel', 'BiaffineSemanticDependencyParser']
diff --git a/tania_scripts/supar/models/sdp/biaffine/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/sdp/biaffine/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4845ca571234eecab6e183073d4864e1ec667a85
GIT binary patch
literal 321
zcmd1j<>g{vU|`^9UzC1@fq~&Mh=Yuo7#J8F7#J9eRTvl;QW#Pga~N_NqZk=MY^EHh
zT;?cdMursT6qa<RD3%n~U<OULmy8Sy44RC$<ef4T)6z2YQiD@-6Z1+klU-5^Qu9($
z^O7rl^HWlDG#PIx;8qflSX7)^R0OiWh?#+b!B3O*7Hcj@A6V=bTLDA?NbVMUe0*X~
zPJH}Ih9Y(b1_<%XTR$T|H&wqRu_QAwFHtWkCov^6wMaiXKer%XH@%=l7i^k-acMzf
zkv^DRtY4f`pq~VFwtjqkW?p7Ve7s&k<t+}I-29Z%oK!oI=Ze`F7#Mh%co=z@06(-=
A)c^nh

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/sdp/biaffine/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/sdp/biaffine/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9896718732a155aafb0ff99c6979f1448f90fcda
GIT binary patch
literal 390
zcmZ3^%ge>Uz`&q%Up3<j0|Ucj5C?{tpp4II3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI
zW=4h-<`kB6rYM#a)?fxrwwH_y3=Eo#x8$8N6VuW%^HPITa})DQGLv0W3sUn^QuC54
zee+XNb2J%mDd1KTkXTflT2#c$z`#(%!oa}br^$MYH5a50EOv{n0HOdScZ)qfJ~1aJ
zK7J*`XON43Me1kd=cekHB$i|*<|XPS<s_zLrWWZZ=jRsW>z1Tel<20GCFbatB<5u%
z#uq0SWfqha>lc?6Bo^s|tti$nPASk&g1TQnK0Y%qvm`!Vub}c5hfQvNN@-52T@g0}
z0|Usb#a0Xq3?G;o85uvYF)$imU@$^PHyBJVprQxdIv4Z;E^q}lu!CR`Cj$cm0Jnp2
At^fc4

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/sdp/biaffine/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/sdp/biaffine/__pycache__/model.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d3927ea658cbef06b9e352886b378c4743b3c16b
GIT binary patch
literal 9519
zcmd1j<>g{vU|`^9UzGk*je+4Yh=Yt-7#J8F7#J9eJs21mQW#Pga~N_NqZk=MY^EHh
zT;?cdFq=7tC6_gdHJ2@l4a{fBVbA4=;$UQOXGmd9VQXPXVM}FhW{%=aVGL%_WPb^=
z!%vg(7OQW5N@|WK(=BFSpMYB&PML{mX_<McnvA#Dob&V2GSibmDv_}QlvCWrz`&5o
z5XG3n5XF?j7{#2z1cuD%3@I#&7(uqCu%@u5aHMdiaHVjk@T4%M@TTyk@TYL52&8bP
z2&M?72&ZtRh@^<5h^BC*h^26*h^HyEGo&%5NTf)%a7MADD5XfHNVhOXv8E`c$fU@&
zFh;SZ$fd})FhsGZD5NO1Fhp^*Gq5m3aRxJJD&LZaxjr~GH!-gyGub7zAT=)~H7~gm
z?8`(4AqEC61qB6#kc?D?%-n*U)ZEm(lEjkC{5*yHGzFM;1(<#XgaHZxiABY!MG98Q
znI)-K2`Twii6y$ZiFtXMdFi@F28I^8#b5)A67;yhRyY==7h8c@APe*2%kzs;iWM|6
z^GY-k!XPP-TZ%KQQb8^#$w*ZIDO4!SPfkoK%}Fe()I%~OCow5C2d5!<rMXF|MId9K
z>N4{bKn9i+rKTn&=4B(BRFarZggF8J!3rRiItoRpg{7HAsVNGXX$nwLh1A@n)RdIW
zy!2v)#G+J%(&E$<Jq4H4w8YY!5-Wv-1i$>e)Pw|NTaz;qi-@omq%1MHB(<m*)nd4~
zZcb`hYK}rtYC%zIF)Rj&c12EVZf+tG&VZ;xbplw7WS^(zCFiH47Aa^HmlUDJzAIF!
zBp(!jh`<7+jD!UBoZ^yP^@Ic~1*c4(;1FL0s7V;=l2VIGAnII$LUeO7vr`ocic(98
z5;OBsQxtL%^U_Nb(^D04L781aBQ3v30hG&2N<qn2Q%50HFI`VZAt6B>WR7l9VsWZ&
za$<36iaK)qft-XCy)d^S+>(}>SfZfelUZC6U0hNWi{?|ul$1<RPD{*D04XdjN-b7^
z_!>2c6B3}Fw8gXm<b;F-^^(MNuxBw-BEm6HrJyteR_mORSOiW~I1*24MG06wMIotD
z0i+ld-WbM#;~#9E4=5EOr34J6pr8b+baD*}K~JkX3i%}&sYSRWsaOFVi9z`w-HG4~
zmY7qV4+^^C%%q%DRO{f;5)Fz(NbrE;6Y7018|L;{gx<V(a3&^HEP;z8uu5=tN6O`f
z1_sEcA*DG2B^{DVu<2-d8QBUWQ)DYZX@@vhgH)ClrJ@HtveBrn2L%>!MuSv>6BAMb
zP$*6<D$C4ES4b>Y$jmD!Ehz>S#juown#N0uK?-4VNG>u(2~LnT@fn#ZDXDpcq6n(0
zxFoS8l^lyvA`)zGL1IdLW?o8a1um;0lKE-iN~RzYToovk<Y%YmDL`u;kU5ZGLeytO
z1_V+#q~_%2V=FrS5_92|CQ@>8_3_PDC`wJwEG|g}*I0Q92_P|7Saqf69}wc{@0WlS
z><J0#`9+!OnR$sh@uo>Ar5?!k_@w;e_|*Jj1&xr>f}GUor2PCGjN(n91SAKF^OEv>
z1(1@|#5{$v#GKMpP=ZLwOinBT#d>*0Dmd$x<SS&SrWPm^mn0UI=%?nTC?w^V=A|SS
zWkMnlWU)eiX$dGLAu<4{ScB*GganO{qS90y1-HbU;#5uK!WvZiU<<V1g4E>9G>{eL
z8JWo$3fY-?DIhnaRS~d)ndpikBqOs}A+s2zp@3A9gPfzDkf4xXqyS0#pkfVFn3aI)
z0X=YoEUh#rM<FM(xI`g2F;5{WRUr)&9-y?8P*RkbSDcn#l$%;qoDh#QG%#BnAbaC;
z5-U@&w>uD_k&$1nkeirSsgRRcT%rKg0Sg7>)(`QXf;ZeiaRzGTrGe5HEJ_v1^GkD5
zK;A4*%}mcINlj5GF3kl+1*px2k)2C2Qj1fe?!w`J6NGqfW<`8TQGP*wX^DbHT26i<
zwnisRK@q3{46+y;ClIfr=2GJQjA;MqA?09jEEMGD=YY~bmPSwjRH{6&64WF}Pc4C#
zBS>`)N@yk|q-7Qrmw*~ZC5hRo;1UQdqEK9#1TKQ~6cQ3ZQHi1iB!HqKH#IR2t|CzZ
z#8t>IOD$4J%*oM1u@NcHfmESqwRj3kOK{NRDkO;ye(X+0iV0||FI7PUR6wD%&^*%=
z5)!~gNkW2-LRwL3YE^16C@2&P5{nXZQ!!iQki3jk_(D<-O34Z}5D}bt@dY`##MQF_
zKE6mbte%2rnu382sG(d8j&kH~6Otp~sRq*CMRE;NNPrcQkx9T+JBp*=Nkh*F*^|&#
zERpp$RJ8(1#z%6wp%H3Z1*#rT*#;_c5M4s3dRPg9$fw2#H$&Bs5hzfd5Yv%dt!Ip6
zd|rHNN_uL1ZcYKV7KLj{da8o2Pk;g_Qjv@>L-jYfYYR35n;|}+4l+SgV9p@NqcB%u
zBy>IGW-8p3WLN>#3-$x19mv6%nOBlpRFIzoD!s8b51sS#ic1pnKxL^yYFTO?sOAA@
z8?X)fpiofA$uBNO3T!<?L~5Y0L<7}g;Fdk2R70`|DI=EVWs}g(EX~W#%P-G^)(_Bj
zCT@ESp`$T+dJ6H#jR?dLOh!pbL9vy-etKp}Mro2>a(=FUMrnF_W?p()VsffJvL<lp
z>UWC;)G60wzQtUUn0|`|)W*HV3hrCIOkrSPcv%Y~j2IXgGAA%HFcdK|FfgRcx4sVC
zA$QgO7B^BeQ<Evg?Imb@FC99f#&C-TRJXXL&zcDWC+#ygurM&ZWCocP!NkA-Rd>N2
zs$i%6OOWZw$}s&53=Ap^3=C`x3=G_$F~emH3=Aa<%?w$LDQuYxB}~l>3z$n-ni&={
zE@A9rWMn8|tzpPw%VMvQsgX-zOkwI}sbPrcz$(fK7nQA%hpXknD#~5LQzMhYoWhdA
zlEMl$ledJYMz)3tNrbP2e}TY4h8l)=!4wA2h@_vJCd)0By!gz#TdaBU`K2Yd*r5%S
zTU?3BC7EU5bpDcwfq@}Jlch+Qfq|h&gn@zK7F$wgVsU&0l&)OKpeb~VwYan(wdfW{
ze0*kJW=VW}5i3|_X+cV2N$M@Ooc!d(oZ=!-z}{j>EJ`oFC6E^nEyJMY^(`(?{s0v;
z@hM2`j9c8`+yj+B;$#$oqVg6eSX*LAN!~3kh)OV<DKGDqfOAoPaj|P&Nl|`5rB8lw
z@h#5eqRf)iqRjj}O_f_L#i==Ix7eX0g||5J;=%fhZ?WaYg9hP1QlP|E43+|oJ`~?#
zhdTNe3#hXTQUR{kZt>*BBkDsC4<rq#azQ+hF;E_FUObowsdsMifjRK3e~SmqheZSn
zs84c>2SmcUM7LN#jk{aCdGR0`S{>cuMrwfG;sMJ*n}4_XAUs&-@)ifINpg!DsbO%7
z7wi#O@mT~KbViOONYQwUAL@UYx+pG0B?B@K9D<;@iV^_FOKwg9T&W;j5+-zu7o|+S
z#fb<9PIxJGi!Hkxlw?*i-r|gpPtHj!E{=~cl44+B_~oIWk)NBY4;oNT%uCcu%1KPg
zOfAw+&d)8#*G(@d(FG5`=@*w4Bo^s|*~R+BDFymT&_Q>Im|j6;kqmffoq?fPfPsNQ
zMn#NCj1dHdn1mSl7^^g31J$r`YQ!)#c$`}gmh6*3xdm1@fY_iU>I^CwTo@P_Y8X=(
zN*Rk3N*J;j7ckW@E@Z4>h-a>0%wkDllw_!3$YRZ6%Vq}2FJMO%UC0C~Cu%_XmdUS3
zh=GAYle0)2l*KsVz3f~3X+`<D$jOikDM_*xXCxM+7RiHhu`x&^n@?t5YGTnXE=ar=
z6y;}WG8Jioq*%d1;2?$&J|I#4oczQTB;%)myak#|;b7!r6k?QMWMQn*ClpX<W+a13
z1Xy^1%mS69;PA=;g%`sDh8o5iriDzk%ry)P7;BgpGS;%xFf3pKvsh~w7BGWZY&8rE
zSimgy8ioa|H7qr(3z-(Mfl5tKsko4(mZOGY0ecNw4Lh1RXAMUUXBty5gC=X@O(y7M
z1*rRoI-39z0o8fM3L14K`9;YYdOrDi=^?3k#rZ{=prQBZq{NcsjQHZrs#G0?;?%<U
zoYcHn<UR|?1P~6-FG^9!%uC5kPAx`M{U8}oiBSw4&Bd?;eeeUM!4cAT&rbt)>#-XO
zQU_|6f*b}KElAA-4}~NoU~{mJLRw}8)a9UghlB)>n-UU08WR%KK_wG(NC7%<t)7se
z1FoY%*1&Lnkpgz(V?o0aAnVIBi_wNtL3-h>dc;Hq-0Yy#lG36)r0E@y252BbVnIg%
zg^OrzfK-AoC=?()))H{Ef%@OzJb}Zt@MzRgFao(eBR?mlSfMyMA2f`fp9blr<rjm;
zh7~|%9a?n4>?}@A&WDWn5NTT;v>Jk23J(R4ksyr25#ZvrSRp@8AvG~M1MDV53IjKb
zio`+LUl2rq%MgxRY|!#t5hSJrB0z1MB2c5INEMXp*$YyOa!X56i_}1c4i~h50Oy5U
ztf1ske2cLniVYM1@hMO`BZ?jDmiQDHBjXlZF}O2wi@g})JxIX<D#eSyr3-sneo=X1
zQOayksRAm5d4#x_xEMiDf?0xzgQ-fLP}u@CAsN*4fR!m63=9k)KDbN?1C=Sv3m8&B
zB`=EuLoKKTVXR@SVUc90VFi&3m=-cDWU2*~CyX^rHLQ{hHOwG#AyX}T4MP@l7E2Ag
z2tx`Jge}2P!zRKY4l0$I6SMJ`9uV)tiw{Vm#aVQqB|bznf}$UUgNaUu(C{Y1W~78j
zv;)BLjw=m<91c}LLNN*t3#{cSC|e^kbb5YHiY}-RmXcTmnuSYB%|XkSxrxQu@UU>o
z&(9$c6F4me8w8ryO9qW!fyUWD9k9|o(71eR3Z%PK4DAeoJWjX>!(L{ArxZcPgL{tf
zvH+5w!MT|A7E^j^ktQg&vgG9Fr9&!tH&A}%0O!}DC{V_Z1}R{Jg#RrTkn^J;ZD%AV
z$PQRD8pKA=r7R%9-JmQA%2<4Y5{x2@GK^I!gt8_`8%kXds`ugfQVx_anIQRc0b>m#
zl*N?7w2(1{aUrO7W=@>Ph_`kg$@vSODDb5*M1uu0odp!7rer3AM#Le>gXp>uC3n31
z|NsAgNaK|G7F%LbdTwIHEgn$nN==DR%go7%zr~bOqREVwCehOvTS_Wu^8O+ym4TYj
za=cY)gwhv8izcI=CKsp=nwOZH8Xtd)D?UCqKczGW#O8^QFDy;Wfy%JQ$EV~c$H#-)
z{Y4?5>=6SZl0XEg*MEx_+SN!-&B=jwHy{r60x1DiSw*0>DksR5ehdr@91JXsOmR$%
zAjk$LK`hcR-#spUE_MzD0Wq-IAiqEwn|XPV#y&T=C!+`M$rORY<`yqpq%<cL(!qvw
xi=j$OOEPnc!JToikq|F{Yh5q_^2aR>8%QYGfyOq9L9K8eCLTrsMjl2HW&jcx>J<P0

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/sdp/biaffine/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/sdp/biaffine/__pycache__/model.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5c1c571e2bcd578989340f70f59cc638e9cb644e
GIT binary patch
literal 11764
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
JV57hR1OR(;uR8z$

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/sdp/biaffine/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/sdp/biaffine/__pycache__/parser.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f9143362fa65ddfd6a27203f97dd01c2a6a45f3e
GIT binary patch
literal 8024
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/sdp/biaffine/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/sdp/biaffine/__pycache__/parser.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e3e9e25a0966252386b63bb170c782847ca49afb
GIT binary patch
literal 14949
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
C#ZJ-y

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/sdp/biaffine/model.py b/tania_scripts/supar/models/sdp/biaffine/model.py
new file mode 100644
index 0000000..7a7afa4
--- /dev/null
+++ b/tania_scripts/supar/models/sdp/biaffine/model.py
@@ -0,0 +1,222 @@
+# -*- coding: utf-8 -*-
+
+import torch.nn as nn
+from supar.model import Model
+from supar.modules import MLP, Biaffine
+from supar.utils import Config
+
+
+class BiaffineSemanticDependencyModel(Model):
+    r"""
+    The implementation of Biaffine Semantic Dependency Parser :cite:`dozat-manning-2018-simpler`.
+
+    Args:
+        n_words (int):
+            The size of the word vocabulary.
+        n_labels (int):
+            The number of labels in the treebank.
+        n_tags (int):
+            The number of POS tags, required if POS tag embeddings are used. Default: ``None``.
+        n_chars (int):
+            The number of characters, required if character-level representations are used. Default: ``None``.
+        n_lemmas (int):
+            The number of lemmas, required if lemma embeddings are used. Default: ``None``.
+        encoder (str):
+            Encoder to use.
+            ``'lstm'``: BiLSTM encoder.
+            ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``.
+            Default: ``'lstm'``.
+        feat (List[str]):
+            Additional features to use, required if ``encoder='lstm'``.
+            ``'tag'``: POS tag embeddings.
+            ``'char'``: Character-level representations extracted by CharLSTM.
+            ``'lemma'``: Lemma embeddings.
+            ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible.
+            Default: [ ``'tag'``, ``'char'``, ``'lemma'``].
+        n_embed (int):
+            The size of word embeddings. Default: 100.
+        n_pretrained (int):
+            The size of pretrained word representations. Default: 125.
+        n_feat_embed (int):
+            The size of feature representations. Default: 100.
+        n_char_embed (int):
+            The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50.
+        n_char_hidden (int):
+            The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100.
+        char_pad_index (int):
+            The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0.
+        elmo (str):
+            Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``.
+        elmo_bos_eos (Tuple[bool]):
+            A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs.
+            Default: ``(True, False)``.
+        bert (str):
+            Specifies which kind of language model to use, e.g., ``'bert-base-cased'``.
+            This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_.
+            Default: ``None``.
+        n_bert_layers (int):
+            Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features.
+            The final outputs would be weighted sum of the hidden states of these layers.
+            Default: 4.
+        mix_dropout (float):
+            The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0.
+        bert_pooling (str):
+            Pooling way to get token embeddings.
+            ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all.
+            Default: ``mean``.
+        bert_pad_index (int):
+            The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features.
+            Default: 0.
+        finetune (bool):
+            If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``.
+        n_plm_embed (int):
+            The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0.
+        embed_dropout (float):
+            The dropout ratio of input embeddings. Default: .2.
+        n_encoder_hidden (int):
+            The size of encoder hidden states. Default: 1200.
+        n_encoder_layers (int):
+            The number of encoder layers. Default: 3.
+        encoder_dropout (float):
+            The dropout ratio of encoder layer. Default: .33.
+        n_edge_mlp (int):
+            Edge MLP size. Default: 600.
+        n_label_mlp  (int):
+            Label MLP size. Default: 600.
+        edge_mlp_dropout (float):
+            The dropout ratio of edge MLP layers. Default: .25.
+        label_mlp_dropout (float):
+            The dropout ratio of label MLP layers. Default: .33.
+        interpolation (int):
+            Constant to even out the label/edge loss. Default: .1.
+        pad_index (int):
+            The index of the padding token in the word vocabulary. Default: 0.
+        unk_index (int):
+            The index of the unknown token in the word vocabulary. Default: 1.
+
+    .. _transformers:
+        https://github.com/huggingface/transformers
+    """
+
+    def __init__(self,
+                 n_words,
+                 n_labels,
+                 n_tags=None,
+                 n_chars=None,
+                 n_lemmas=None,
+                 encoder='lstm',
+                 feat=['tag', 'char', 'lemma'],
+                 n_embed=100,
+                 n_pretrained=125,
+                 n_feat_embed=100,
+                 n_char_embed=50,
+                 n_char_hidden=400,
+                 char_pad_index=0,
+                 char_dropout=0.33,
+                 elmo='original_5b',
+                 elmo_bos_eos=(True, False),
+                 bert=None,
+                 n_bert_layers=4,
+                 mix_dropout=.0,
+                 bert_pooling='mean',
+                 bert_pad_index=0,
+                 finetune=False,
+                 n_plm_embed=0,
+                 embed_dropout=.2,
+                 n_encoder_hidden=1200,
+                 n_encoder_layers=3,
+                 encoder_dropout=.33,
+                 n_edge_mlp=600,
+                 n_label_mlp=600,
+                 edge_mlp_dropout=.25,
+                 label_mlp_dropout=.33,
+                 interpolation=0.1,
+                 pad_index=0,
+                 unk_index=1,
+                 **kwargs):
+        super().__init__(**Config().update(locals()))
+
+        self.edge_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_edge_mlp, dropout=edge_mlp_dropout, activation=False)
+        self.edge_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_edge_mlp, dropout=edge_mlp_dropout, activation=False)
+        self.label_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=label_mlp_dropout, activation=False)
+        self.label_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=label_mlp_dropout, activation=False)
+
+        self.edge_attn = Biaffine(n_in=n_edge_mlp, n_out=2, bias_x=True, bias_y=True)
+        self.label_attn = Biaffine(n_in=n_label_mlp, n_out=n_labels, bias_x=True, bias_y=True)
+        self.criterion = nn.CrossEntropyLoss()
+
+    def load_pretrained(self, embed=None):
+        if embed is not None:
+            self.pretrained = nn.Embedding.from_pretrained(embed)
+            if embed.shape[1] != self.args.n_pretrained:
+                self.embed_proj = nn.Linear(embed.shape[1], self.args.n_pretrained)
+        return self
+
+    def forward(self, words, feats=None):
+        r"""
+        Args:
+            words (~torch.LongTensor): ``[batch_size, seq_len]``.
+                Word indices.
+            feats (List[~torch.LongTensor]):
+                A list of feat indices.
+                The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``,
+                or ``[batch_size, seq_len]`` otherwise.
+                Default: ``None``.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor:
+                The first tensor of shape ``[batch_size, seq_len, seq_len, 2]`` holds scores of all possible edges.
+                The second of shape ``[batch_size, seq_len, seq_len, n_labels]`` holds
+                scores of all possible labels on each edge.
+        """
+
+        x = self.encode(words, feats)
+
+        edge_d = self.edge_mlp_d(x)
+        edge_h = self.edge_mlp_h(x)
+        label_d = self.label_mlp_d(x)
+        label_h = self.label_mlp_h(x)
+
+        # [batch_size, seq_len, seq_len, 2]
+        s_edge = self.edge_attn(edge_d, edge_h).permute(0, 2, 3, 1)
+        # [batch_size, seq_len, seq_len, n_labels]
+        s_label = self.label_attn(label_d, label_h).permute(0, 2, 3, 1)
+
+        return s_edge, s_label
+
+    def loss(self, s_edge, s_label, labels, mask):
+        r"""
+        Args:
+            s_edge (~torch.Tensor): ``[batch_size, seq_len, seq_len, 2]``.
+                Scores of all possible edges.
+            s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``.
+                Scores of all possible labels on each edge.
+            labels (~torch.LongTensor): ``[batch_size, seq_len, seq_len]``.
+                The tensor of gold-standard labels.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens.
+
+        Returns:
+            ~torch.Tensor:
+                The training loss.
+        """
+
+        edge_mask = labels.ge(0) & mask
+        edge_loss = self.criterion(s_edge[mask], edge_mask[mask].long())
+        label_loss = self.criterion(s_label[edge_mask], labels[edge_mask])
+        return self.args.interpolation * label_loss + (1 - self.args.interpolation) * edge_loss
+
+    def decode(self, s_edge, s_label):
+        r"""
+        Args:
+            s_edge (~torch.Tensor): ``[batch_size, seq_len, seq_len, 2]``.
+                Scores of all possible edges.
+            s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``.
+                Scores of all possible labels on each edge.
+
+        Returns:
+            ~torch.LongTensor:
+                Predicted labels of shape ``[batch_size, seq_len, seq_len]``.
+        """
+
+        return s_label.argmax(-1).masked_fill_(s_edge.argmax(-1).lt(1), -1)
diff --git a/tania_scripts/supar/models/sdp/biaffine/parser.py b/tania_scripts/supar/models/sdp/biaffine/parser.py
new file mode 100644
index 0000000..c28f6c2
--- /dev/null
+++ b/tania_scripts/supar/models/sdp/biaffine/parser.py
@@ -0,0 +1,202 @@
+# -*- coding: utf-8 -*-
+
+import os
+from typing import Iterable, Union
+
+import torch
+
+from supar.models.dep.biaffine.transform import CoNLL
+from supar.models.sdp.biaffine import BiaffineSemanticDependencyModel
+from supar.parser import Parser
+from supar.utils import Config, Dataset, Embedding
+from supar.utils.common import BOS, PAD, UNK
+from supar.utils.field import ChartField, Field, RawField, SubwordField
+from supar.utils.logging import get_logger
+from supar.utils.metric import ChartMetric
+from supar.utils.tokenizer import TransformerTokenizer
+from supar.utils.transform import Batch
+
+logger = get_logger(__name__)
+
+
+class BiaffineSemanticDependencyParser(Parser):
+    r"""
+    The implementation of Biaffine Semantic Dependency Parser :cite:`dozat-manning-2018-simpler`.
+    """
+
+    NAME = 'biaffine-semantic-dependency'
+    MODEL = BiaffineSemanticDependencyModel
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self.LEMMA = self.transform.LEMMA
+        self.TAG = self.transform.POS
+        self.LABEL = self.transform.PHEAD
+
+    def train(
+        self,
+        train: Union[str, Iterable],
+        dev: Union[str, Iterable],
+        test: Union[str, Iterable],
+        epochs: int = 1000,
+        patience: int = 100,
+        batch_size: int = 5000,
+        update_steps: int = 1,
+        buckets: int = 32,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().train(**Config().update(locals()))
+
+    def evaluate(
+        self,
+        data: Union[str, Iterable],
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().evaluate(**Config().update(locals()))
+
+    def predict(
+        self,
+        data: Union[str, Iterable],
+        pred: str = None,
+        lang: str = None,
+        prob: bool = False,
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().predict(**Config().update(locals()))
+
+    def train_step(self, batch: Batch) -> torch.Tensor:
+        words, *feats, labels = batch
+        mask = batch.mask
+        mask = mask.unsqueeze(1) & mask.unsqueeze(2)
+        mask[:, 0] = 0
+        s_edge, s_label = self.model(words, feats)
+        loss = self.model.loss(s_edge, s_label, labels, mask)
+        return loss
+
+    @torch.no_grad()
+    def eval_step(self, batch: Batch) -> ChartMetric:
+        words, *feats, labels = batch
+        mask = batch.mask
+        mask = mask.unsqueeze(1) & mask.unsqueeze(2)
+        mask[:, 0] = 0
+        s_edge, s_label = self.model(words, feats)
+        loss = self.model.loss(s_edge, s_label, labels, mask)
+        label_preds = self.model.decode(s_edge, s_label)
+        return ChartMetric(loss, label_preds.masked_fill(~mask, -1), labels.masked_fill(~mask, -1))
+
+    @torch.no_grad()
+    def pred_step(self, batch: Batch) -> Batch:
+        words, *feats = batch
+        mask, lens = batch.mask, (batch.lens - 1).tolist()
+        mask = mask.unsqueeze(1) & mask.unsqueeze(2)
+        mask[:, 0] = 0
+        with torch.autocast(self.device, enabled=self.args.amp):
+            s_edge, s_label = self.model(words, feats)
+        label_preds = self.model.decode(s_edge, s_label).masked_fill(~mask, -1)
+        batch.labels = [CoNLL.build_relations([[self.LABEL.vocab[i] if i >= 0 else None for i in row]
+                                               for row in chart[1:i, :i].tolist()])
+                        for i, chart in zip(lens, label_preds)]
+        if self.args.prob:
+            batch.probs = [prob[1:i, :i].cpu() for i, prob in zip(lens, s_edge.softmax(-1).unbind())]
+        return batch
+
+    @classmethod
+    def build(cls, path, min_freq=7, fix_len=20, **kwargs):
+        r"""
+        Build a brand-new Parser, including initialization of all data fields and model parameters.
+
+        Args:
+            path (str):
+                The path of the model to be saved.
+            min_freq (str):
+                The minimum frequency needed to include a token in the vocabulary. Default:7.
+            fix_len (int):
+                The max length of all subword pieces. The excess part of each piece will be truncated.
+                Required if using CharLSTM/BERT.
+                Default: 20.
+            kwargs (Dict):
+                A dict holding the unconsumed arguments.
+        """
+
+        args = Config(**locals())
+        os.makedirs(os.path.dirname(path) or './', exist_ok=True)
+        if os.path.exists(path) and not args.build:
+            parser = cls.load(**args)
+            parser.model = cls.MODEL(**parser.args)
+            parser.model.load_pretrained(parser.transform.FORM[0].embed).to(parser.device)
+            return parser
+
+        logger.info("Building the fields")
+        WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, lower=True)
+        TAG, CHAR, LEMMA, ELMO, BERT = None, None, None, None, None
+        if args.encoder == 'bert':
+            t = TransformerTokenizer(args.bert)
+            WORD = SubwordField('words', pad=t.pad, unk=t.unk, bos=t.bos, fix_len=args.fix_len, tokenize=t)
+            WORD.vocab = t.vocab
+        else:
+            WORD = Field('words', pad=PAD, unk=UNK, bos=BOS, lower=True)
+            if 'tag' in args.feat:
+                TAG = Field('tags', bos=BOS)
+            if 'char' in args.feat:
+                CHAR = SubwordField('chars', pad=PAD, unk=UNK, bos=BOS, fix_len=args.fix_len)
+            if 'lemma' in args.feat:
+                LEMMA = Field('lemmas', pad=PAD, unk=UNK, bos=BOS, lower=True)
+            if 'elmo' in args.feat:
+                from allennlp.modules.elmo import batch_to_ids
+                ELMO = RawField('elmo')
+                ELMO.compose = lambda x: batch_to_ids(x).to(WORD.device)
+            if 'bert' in args.feat:
+                t = TransformerTokenizer(args.bert)
+                BERT = SubwordField('bert', pad=t.pad, unk=t.unk, bos=t.bos, fix_len=args.fix_len, tokenize=t)
+                BERT.vocab = t.vocab
+        LABEL = ChartField('labels', fn=CoNLL.get_labels)
+        transform = CoNLL(FORM=(WORD, CHAR, ELMO, BERT), LEMMA=LEMMA, POS=TAG, PHEAD=LABEL)
+
+        train = Dataset(transform, args.train, **args)
+        if args.encoder != 'bert':
+            WORD.build(train, args.min_freq, (Embedding.load(args.embed) if args.embed else None), lambda x: x / torch.std(x))
+            if TAG is not None:
+                TAG.build(train)
+            if CHAR is not None:
+                CHAR.build(train)
+            if LEMMA is not None:
+                LEMMA.build(train)
+        LABEL.build(train)
+        args.update({
+            'n_words': len(WORD.vocab) if args.encoder == 'bert' else WORD.vocab.n_init,
+            'n_labels': len(LABEL.vocab),
+            'n_tags': len(TAG.vocab) if TAG is not None else None,
+            'n_chars': len(CHAR.vocab) if CHAR is not None else None,
+            'char_pad_index': CHAR.pad_index if CHAR is not None else None,
+            'n_lemmas': len(LEMMA.vocab) if LEMMA is not None else None,
+            'bert_pad_index': BERT.pad_index if BERT is not None else None,
+            'pad_index': WORD.pad_index,
+            'unk_index': WORD.unk_index,
+            'bos_index': WORD.bos_index
+        })
+        logger.info(f"{transform}")
+
+        logger.info("Building the model")
+        model = cls.MODEL(**args).load_pretrained(WORD.embed if hasattr(WORD, 'embed') else None)
+        logger.info(f"{model}\n")
+
+        parser = cls(args, model, transform)
+        parser.model.to(parser.device)
+        return parser
diff --git a/tania_scripts/supar/models/sdp/vi/__init__.py b/tania_scripts/supar/models/sdp/vi/__init__.py
new file mode 100644
index 0000000..2aae65d
--- /dev/null
+++ b/tania_scripts/supar/models/sdp/vi/__init__.py
@@ -0,0 +1,6 @@
+# -*- coding: utf-8 -*-
+
+from .model import VISemanticDependencyModel
+from .parser import VISemanticDependencyParser
+
+__all__ = ['VISemanticDependencyModel', 'VISemanticDependencyParser']
diff --git a/tania_scripts/supar/models/sdp/vi/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/models/sdp/vi/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6b7e00e74f70f0d965c505e8994b7e119a0dec34
GIT binary patch
literal 303
zcmd1j<>g{vU|`^9UzEOwfq~&Mh=Yuo7#J8F7#J9eRTvl;QW#Pga~N_NqZk=MY^EHh
zT;?cdMursT6qa<RD3%n~U<OULmy8Sy44RC$B*Q#|Q*#sZN-~pOQVUY^Qd0AhD}D1*
zQgbvJZ%JX33`i_0PAw_|*;&NQz`)?A$$E=57o-C$c8je5q5vd!i#<L*F()TJekDT@
zI|BoR_~ojfk)NBYUy@jonV6TTmz0y3l9^hhpPZjtkguCwP@)SqO~1IbAhAdv%r4e1
tPASkY%hZpL&&<m#iI3MSsJz8tlbfGXnv-e=@=7rq0|NsO6AvQ~697BGPiz1H

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/sdp/vi/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/models/sdp/vi/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e17f748d964d58b705b5a14d52e4f3758f8318e7
GIT binary patch
literal 372
zcmZ3^%ge>Uz`&q%Uo~S70|Ucj5C?{tpp4II3=9m@8B!Qh7;_kM8KW2(L2RZRrd;MI
zW=4h-<`kB6rYM#a)?fxrwwH_y3=Eo#w<N<ngHv-8^GY(4T~Z5D^HNgtk}G}lQ&Mv@
z8E;8plMF~KDo!mbVrF1qC}Lq?VDQsqy~Uaf(g7B`#Z~}O0Ft}K9v`2WlM^4mlHoJR
zmA``ZGxBp&^-B^<G86L>^^$TDQ!-PF^po>*3-WbKQY%VyQ_B)_^h*-+G85yAlZ!G7
zN{aQ1OA8W<^ubmX>lddK=$B>c$H!;pWtPOp>lIY~;;_lhPbtkwwJYLgU|;}wtk{Zy
tf#Cx)BO~JnHU>uB3k*8Q=mvw{1yuBaTkV2|%LOji26hlE;$&c8003|tY1se(

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/sdp/vi/__pycache__/model.cpython-310.pyc b/tania_scripts/supar/models/sdp/vi/__pycache__/model.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9cfb7bd073d93cc874641db0353d3cc92dcbf402
GIT binary patch
literal 19591
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/sdp/vi/__pycache__/model.cpython-311.pyc b/tania_scripts/supar/models/sdp/vi/__pycache__/model.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ac266759295a48ebd875a15b1b28e225c633c0b6
GIT binary patch
literal 24854
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
OEd2#SeZWS60|o$?Ob|-|

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/sdp/vi/__pycache__/parser.cpython-310.pyc b/tania_scripts/supar/models/sdp/vi/__pycache__/parser.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ceb658d3c6b5f0ceae68bdf73fc482f9763c6d5f
GIT binary patch
literal 4845
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/sdp/vi/__pycache__/parser.cpython-311.pyc b/tania_scripts/supar/models/sdp/vi/__pycache__/parser.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..3b28e31b2c498c355f12078f27de07f420d6c8a0
GIT binary patch
literal 8540
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/models/sdp/vi/model.py b/tania_scripts/supar/models/sdp/vi/model.py
new file mode 100644
index 0000000..12c20e1
--- /dev/null
+++ b/tania_scripts/supar/models/sdp/vi/model.py
@@ -0,0 +1,471 @@
+# -*- coding: utf-8 -*-
+
+import torch.nn as nn
+from supar.model import Model
+from supar.modules import MLP, Biaffine, Triaffine
+from supar.structs import SemanticDependencyLBP, SemanticDependencyMFVI
+from supar.utils import Config
+
+
+class BiaffineSemanticDependencyModel(Model):
+    r"""
+    The implementation of Biaffine Semantic Dependency Parser :cite:`dozat-manning-2018-simpler`.
+
+    Args:
+        n_words (int):
+            The size of the word vocabulary.
+        n_labels (int):
+            The number of labels in the treebank.
+        n_tags (int):
+            The number of POS tags, required if POS tag embeddings are used. Default: ``None``.
+        n_chars (int):
+            The number of characters, required if character-level representations are used. Default: ``None``.
+        n_lemmas (int):
+            The number of lemmas, required if lemma embeddings are used. Default: ``None``.
+        encoder (str):
+            Encoder to use.
+            ``'lstm'``: BiLSTM encoder.
+            ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``.
+            Default: ``'lstm'``.
+        feat (List[str]):
+            Additional features to use, required if ``encoder='lstm'``.
+            ``'tag'``: POS tag embeddings.
+            ``'char'``: Character-level representations extracted by CharLSTM.
+            ``'lemma'``: Lemma embeddings.
+            ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible.
+            Default: [ ``'tag'``, ``'char'``, ``'lemma'``].
+        n_embed (int):
+            The size of word embeddings. Default: 100.
+        n_pretrained (int):
+            The size of pretrained word representations. Default: 125.
+        n_feat_embed (int):
+            The size of feature representations. Default: 100.
+        n_char_embed (int):
+            The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50.
+        n_char_hidden (int):
+            The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100.
+        char_pad_index (int):
+            The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0.
+        elmo (str):
+            Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``.
+        elmo_bos_eos (Tuple[bool]):
+            A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs.
+            Default: ``(True, False)``.
+        bert (str):
+            Specifies which kind of language model to use, e.g., ``'bert-base-cased'``.
+            This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_.
+            Default: ``None``.
+        n_bert_layers (int):
+            Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features.
+            The final outputs would be weighted sum of the hidden states of these layers.
+            Default: 4.
+        mix_dropout (float):
+            The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0.
+        bert_pooling (str):
+            Pooling way to get token embeddings.
+            ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all.
+            Default: ``mean``.
+        bert_pad_index (int):
+            The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features.
+            Default: 0.
+        finetune (bool):
+            If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``.
+        n_plm_embed (int):
+            The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0.
+        embed_dropout (float):
+            The dropout ratio of input embeddings. Default: .2.
+        n_encoder_hidden (int):
+            The size of encoder hidden states. Default: 1200.
+        n_encoder_layers (int):
+            The number of encoder layers. Default: 3.
+        encoder_dropout (float):
+            The dropout ratio of encoder layer. Default: .33.
+        n_edge_mlp (int):
+            Edge MLP size. Default: 600.
+        n_label_mlp  (int):
+            Label MLP size. Default: 600.
+        edge_mlp_dropout (float):
+            The dropout ratio of edge MLP layers. Default: .25.
+        label_mlp_dropout (float):
+            The dropout ratio of label MLP layers. Default: .33.
+        interpolation (int):
+            Constant to even out the label/edge loss. Default: .1.
+        pad_index (int):
+            The index of the padding token in the word vocabulary. Default: 0.
+        unk_index (int):
+            The index of the unknown token in the word vocabulary. Default: 1.
+
+    .. _transformers:
+        https://github.com/huggingface/transformers
+    """
+
+    def __init__(self,
+                 n_words,
+                 n_labels,
+                 n_tags=None,
+                 n_chars=None,
+                 n_lemmas=None,
+                 encoder='lstm',
+                 feat=['tag', 'char', 'lemma'],
+                 n_embed=100,
+                 n_pretrained=125,
+                 n_feat_embed=100,
+                 n_char_embed=50,
+                 n_char_hidden=400,
+                 char_pad_index=0,
+                 char_dropout=0.33,
+                 elmo='original_5b',
+                 elmo_bos_eos=(True, False),
+                 bert=None,
+                 n_bert_layers=4,
+                 mix_dropout=.0,
+                 bert_pooling='mean',
+                 bert_pad_index=0,
+                 finetune=False,
+                 n_plm_embed=0,
+                 embed_dropout=.2,
+                 n_encoder_hidden=1200,
+                 n_encoder_layers=3,
+                 encoder_dropout=.33,
+                 n_edge_mlp=600,
+                 n_label_mlp=600,
+                 edge_mlp_dropout=.25,
+                 label_mlp_dropout=.33,
+                 interpolation=0.1,
+                 pad_index=0,
+                 unk_index=1,
+                 **kwargs):
+        super().__init__(**Config().update(locals()))
+
+        self.edge_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_edge_mlp, dropout=edge_mlp_dropout, activation=False)
+        self.edge_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_edge_mlp, dropout=edge_mlp_dropout, activation=False)
+        self.label_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=label_mlp_dropout, activation=False)
+        self.label_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=label_mlp_dropout, activation=False)
+
+        self.edge_attn = Biaffine(n_in=n_edge_mlp, n_out=2, bias_x=True, bias_y=True)
+        self.label_attn = Biaffine(n_in=n_label_mlp, n_out=n_labels, bias_x=True, bias_y=True)
+        self.criterion = nn.CrossEntropyLoss()
+
+    def load_pretrained(self, embed=None):
+        if embed is not None:
+            self.pretrained = nn.Embedding.from_pretrained(embed)
+            if embed.shape[1] != self.args.n_pretrained:
+                self.embed_proj = nn.Linear(embed.shape[1], self.args.n_pretrained)
+        return self
+
+    def forward(self, words, feats=None):
+        r"""
+        Args:
+            words (~torch.LongTensor): ``[batch_size, seq_len]``.
+                Word indices.
+            feats (List[~torch.LongTensor]):
+                A list of feat indices.
+                The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``,
+                or ``[batch_size, seq_len]`` otherwise.
+                Default: ``None``.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor:
+                The first tensor of shape ``[batch_size, seq_len, seq_len, 2]`` holds scores of all possible edges.
+                The second of shape ``[batch_size, seq_len, seq_len, n_labels]`` holds
+                scores of all possible labels on each edge.
+        """
+
+        x = self.encode(words, feats)
+
+        edge_d = self.edge_mlp_d(x)
+        edge_h = self.edge_mlp_h(x)
+        label_d = self.label_mlp_d(x)
+        label_h = self.label_mlp_h(x)
+
+        # [batch_size, seq_len, seq_len, 2]
+        s_edge = self.edge_attn(edge_d, edge_h).permute(0, 2, 3, 1)
+        # [batch_size, seq_len, seq_len, n_labels]
+        s_label = self.label_attn(label_d, label_h).permute(0, 2, 3, 1)
+
+        return s_edge, s_label
+
+    def loss(self, s_edge, s_label, labels, mask):
+        r"""
+        Args:
+            s_edge (~torch.Tensor): ``[batch_size, seq_len, seq_len, 2]``.
+                Scores of all possible edges.
+            s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``.
+                Scores of all possible labels on each edge.
+            labels (~torch.LongTensor): ``[batch_size, seq_len, seq_len]``.
+                The tensor of gold-standard labels.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens.
+
+        Returns:
+            ~torch.Tensor:
+                The training loss.
+        """
+
+        edge_mask = labels.ge(0) & mask
+        edge_loss = self.criterion(s_edge[mask], edge_mask[mask].long())
+        label_loss = self.criterion(s_label[edge_mask], labels[edge_mask])
+        return self.args.interpolation * label_loss + (1 - self.args.interpolation) * edge_loss
+
+    def decode(self, s_edge, s_label):
+        r"""
+        Args:
+            s_edge (~torch.Tensor): ``[batch_size, seq_len, seq_len, 2]``.
+                Scores of all possible edges.
+            s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``.
+                Scores of all possible labels on each edge.
+
+        Returns:
+            ~torch.LongTensor:
+                Predicted labels of shape ``[batch_size, seq_len, seq_len]``.
+        """
+
+        return s_label.argmax(-1).masked_fill_(s_edge.argmax(-1).lt(1), -1)
+
+
+class VISemanticDependencyModel(BiaffineSemanticDependencyModel):
+    r"""
+    The implementation of Semantic Dependency Parser using Variational Inference :cite:`wang-etal-2019-second`.
+
+    Args:
+        n_words (int):
+            The size of the word vocabulary.
+        n_labels (int):
+            The number of labels in the treebank.
+        n_tags (int):
+            The number of POS tags, required if POS tag embeddings are used. Default: ``None``.
+        n_chars (int):
+            The number of characters, required if character-level representations are used. Default: ``None``.
+        n_lemmas (int):
+            The number of lemmas, required if lemma embeddings are used. Default: ``None``.
+        encoder (str):
+            Encoder to use.
+            ``'lstm'``: BiLSTM encoder.
+            ``'bert'``: BERT-like pretrained language model (for finetuning), e.g., ``'bert-base-cased'``.
+            Default: ``'lstm'``.
+        feat (List[str]):
+            Additional features to use, required if ``encoder='lstm'``.
+            ``'tag'``: POS tag embeddings.
+            ``'char'``: Character-level representations extracted by CharLSTM.
+            ``'lemma'``: Lemma embeddings.
+            ``'bert'``: BERT representations, other pretrained language models like RoBERTa are also feasible.
+            Default: [ ``'tag'``, ``'char'``, ``'lemma'``].
+        n_embed (int):
+            The size of word embeddings. Default: 100.
+        n_pretrained (int):
+            The size of pretrained word embeddings. Default: 125.
+        n_feat_embed (int):
+            The size of feature representations. Default: 100.
+        n_char_embed (int):
+            The size of character embeddings serving as inputs of CharLSTM, required if using CharLSTM. Default: 50.
+        n_char_hidden (int):
+            The size of hidden states of CharLSTM, required if using CharLSTM. Default: 100.
+        char_pad_index (int):
+            The index of the padding token in the character vocabulary, required if using CharLSTM. Default: 0.
+        elmo (str):
+            Name of the pretrained ELMo registered in `ELMoEmbedding.OPTION`. Default: ``'original_5b'``.
+        elmo_bos_eos (Tuple[bool]):
+            A tuple of two boolean values indicating whether to keep start/end boundaries of elmo outputs.
+            Default: ``(True, False)``.
+        bert (str):
+            Specifies which kind of language model to use, e.g., ``'bert-base-cased'``.
+            This is required if ``encoder='bert'`` or using BERT features. The full list can be found in `transformers`_.
+            Default: ``None``.
+        n_bert_layers (int):
+            Specifies how many last layers to use, required if ``encoder='bert'`` or using BERT features.
+            The final outputs would be weighted sum of the hidden states of these layers.
+            Default: 4.
+        mix_dropout (float):
+            The dropout ratio of BERT layers, required if ``encoder='bert'`` or using BERT features. Default: .0.
+        bert_pooling (str):
+            Pooling way to get token embeddings.
+            ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all.
+            Default: ``mean``.
+        bert_pad_index (int):
+            The index of the padding token in BERT vocabulary, required if ``encoder='bert'`` or using BERT features.
+            Default: 0.
+        finetune (bool):
+            If ``False``, freezes all parameters, required if using pretrained layers. Default: ``False``.
+        n_plm_embed (int):
+            The size of PLM embeddings. If 0, uses the size of the pretrained embedding model. Default: 0.
+        embed_dropout (float):
+            The dropout ratio of input embeddings. Default: .2.
+        n_encoder_hidden (int):
+            The size of encoder hidden states. Default: 1200.
+        n_encoder_layers (int):
+            The number of encoder layers. Default: 3.
+        encoder_dropout (float):
+            The dropout ratio of encoder layer. Default: .33.
+        n_edge_mlp (int):
+            Unary factor MLP size. Default: 600.
+        n_pair_mlp (int):
+            Binary factor MLP size. Default: 150.
+        n_label_mlp  (int):
+            Label MLP size. Default: 600.
+        edge_mlp_dropout (float):
+            The dropout ratio of unary edge factor MLP layers. Default: .25.
+        pair_mlp_dropout (float):
+            The dropout ratio of binary factor MLP layers. Default: .25.
+        label_mlp_dropout (float):
+            The dropout ratio of label MLP layers. Default: .33.
+        inference (str):
+            Approximate inference methods. Default: ``mfvi``.
+        max_iter (int):
+            Max iteration times for inference. Default: 3.
+        interpolation (int):
+            Constant to even out the label/edge loss. Default: .1.
+        pad_index (int):
+            The index of the padding token in the word vocabulary. Default: 0.
+        unk_index (int):
+            The index of the unknown token in the word vocabulary. Default: 1.
+
+    .. _transformers:
+        https://github.com/huggingface/transformers
+    """
+
+    def __init__(self,
+                 n_words,
+                 n_labels,
+                 n_tags=None,
+                 n_chars=None,
+                 n_lemmas=None,
+                 encoder='lstm',
+                 feat=['tag', 'char', 'lemma'],
+                 n_embed=100,
+                 n_pretrained=125,
+                 n_feat_embed=100,
+                 n_char_embed=50,
+                 n_char_hidden=100,
+                 char_pad_index=0,
+                 char_dropout=0,
+                 elmo='original_5b',
+                 elmo_bos_eos=(True, False),
+                 bert=None,
+                 n_bert_layers=4,
+                 mix_dropout=.0,
+                 bert_pooling='mean',
+                 bert_pad_index=0,
+                 finetune=False,
+                 n_plm_embed=0,
+                 embed_dropout=.2,
+                 n_encoder_hidden=1200,
+                 n_encoder_layers=3,
+                 encoder_dropout=.33,
+                 n_edge_mlp=600,
+                 n_pair_mlp=150,
+                 n_label_mlp=600,
+                 edge_mlp_dropout=.25,
+                 pair_mlp_dropout=.25,
+                 label_mlp_dropout=.33,
+                 inference='mfvi',
+                 max_iter=3,
+                 interpolation=0.1,
+                 pad_index=0,
+                 unk_index=1,
+                 **kwargs):
+        super().__init__(**Config().update(locals()))
+
+        self.edge_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_edge_mlp, dropout=edge_mlp_dropout, activation=False)
+        self.edge_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_edge_mlp, dropout=edge_mlp_dropout, activation=False)
+        self.pair_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_pair_mlp, dropout=pair_mlp_dropout, activation=False)
+        self.pair_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_pair_mlp, dropout=pair_mlp_dropout, activation=False)
+        self.pair_mlp_g = MLP(n_in=self.args.n_encoder_hidden, n_out=n_pair_mlp, dropout=pair_mlp_dropout, activation=False)
+        self.label_mlp_d = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=label_mlp_dropout, activation=False)
+        self.label_mlp_h = MLP(n_in=self.args.n_encoder_hidden, n_out=n_label_mlp, dropout=label_mlp_dropout, activation=False)
+
+        self.edge_attn = Biaffine(n_in=n_edge_mlp, bias_x=True, bias_y=True)
+        self.sib_attn = Triaffine(n_in=n_pair_mlp, bias_x=True, bias_y=True)
+        self.cop_attn = Triaffine(n_in=n_pair_mlp, bias_x=True, bias_y=True)
+        self.grd_attn = Triaffine(n_in=n_pair_mlp, bias_x=True, bias_y=True)
+        self.label_attn = Biaffine(n_in=n_label_mlp, n_out=n_labels, bias_x=True, bias_y=True)
+        self.inference = (SemanticDependencyMFVI if inference == 'mfvi' else SemanticDependencyLBP)(max_iter)
+        self.criterion = nn.CrossEntropyLoss()
+
+    def forward(self, words, feats=None):
+        r"""
+        Args:
+            words (~torch.LongTensor): ``[batch_size, seq_len]``.
+                Word indices.
+            feats (List[~torch.LongTensor]):
+                A list of feat indices.
+                The size is either ``[batch_size, seq_len, fix_len]`` if ``feat`` is ``'char'`` or ``'bert'``,
+                or ``[batch_size, seq_len]`` otherwise.
+                Default: ``None``.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor, ~torch.Tensor, ~torch.Tensor, ~torch.Tensor:
+                The first and last are scores of all possible edges of shape ``[batch_size, seq_len, seq_len]``
+                and possible labels on each edge of shape ``[batch_size, seq_len, seq_len, n_labels]``.
+                Others are scores of second-order sibling, coparent and grandparent factors
+                (``[batch_size, seq_len, seq_len, seq_len]``).
+
+        """
+
+        x = self.encode(words, feats)
+
+        edge_d = self.edge_mlp_d(x)
+        edge_h = self.edge_mlp_h(x)
+        pair_d = self.pair_mlp_d(x)
+        pair_h = self.pair_mlp_h(x)
+        pair_g = self.pair_mlp_g(x)
+        label_d = self.label_mlp_d(x)
+        label_h = self.label_mlp_h(x)
+
+        # [batch_size, seq_len, seq_len]
+        s_edge = self.edge_attn(edge_d, edge_h)
+        # [batch_size, seq_len, seq_len, seq_len], (d->h->s)
+        s_sib = self.sib_attn(pair_d, pair_d, pair_h)
+        s_sib = (s_sib.triu() + s_sib.triu(1).transpose(-1, -2)).permute(0, 3, 1, 2)
+        # [batch_size, seq_len, seq_len, seq_len], (d->h->c)
+        s_cop = self.cop_attn(pair_h, pair_d, pair_h).permute(0, 3, 1, 2)
+        s_cop = s_cop.triu() + s_cop.triu(1).transpose(-1, -2)
+        # [batch_size, seq_len, seq_len, seq_len], (d->h->g)
+        s_grd = self.grd_attn(pair_g, pair_d, pair_h).permute(0, 3, 1, 2)
+        # [batch_size, seq_len, seq_len, n_labels]
+        s_label = self.label_attn(label_d, label_h).permute(0, 2, 3, 1)
+
+        return s_edge, s_sib, s_cop, s_grd, s_label
+
+    def loss(self, s_edge, s_sib, s_cop, s_grd, s_label, labels, mask):
+        r"""
+        Args:
+            s_edge (~torch.Tensor): ``[batch_size, seq_len, seq_len]``.
+                Scores of all possible edges.
+            s_sib (~torch.Tensor): ``[batch_size, seq_len, seq_len, seq_len]``.
+                Scores of all possible dependent-head-sibling triples.
+            s_cop (~torch.Tensor): ``[batch_size, seq_len, seq_len, seq_len]``.
+                Scores of all possible dependent-head-coparent triples.
+            s_grd (~torch.Tensor): ``[batch_size, seq_len, seq_len, seq_len]``.
+                Scores of all possible dependent-head-grandparent triples.
+            s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``.
+                Scores of all possible labels on each edge.
+            labels (~torch.LongTensor): ``[batch_size, seq_len, seq_len]``.
+                The tensor of gold-standard labels.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor:
+                The training loss and marginals of shape ``[batch_size, seq_len, seq_len]``.
+        """
+
+        edge_mask = labels.ge(0) & mask
+        edge_loss, marginals = self.inference((s_edge, s_sib, s_cop, s_grd), mask, edge_mask.long())
+        label_loss = self.criterion(s_label[edge_mask], labels[edge_mask])
+        loss = self.args.interpolation * label_loss + (1 - self.args.interpolation) * edge_loss
+        return loss, marginals
+
+    def decode(self, s_edge, s_label):
+        r"""
+        Args:
+            s_edge (~torch.Tensor): ``[batch_size, seq_len, seq_len]``.
+                Scores of all possible edges.
+            s_label (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_labels]``.
+                Scores of all possible labels on each edge.
+
+        Returns:
+            ~torch.LongTensor:
+                Predicted labels of shape ``[batch_size, seq_len, seq_len]``.
+        """
+
+        return s_label.argmax(-1).masked_fill_(s_edge.lt(0.5), -1)
diff --git a/tania_scripts/supar/models/sdp/vi/parser.py b/tania_scripts/supar/models/sdp/vi/parser.py
new file mode 100644
index 0000000..dbb85c8
--- /dev/null
+++ b/tania_scripts/supar/models/sdp/vi/parser.py
@@ -0,0 +1,114 @@
+# -*- coding: utf-8 -*-
+
+from typing import Iterable, Union
+
+import torch
+
+from supar.models.dep.biaffine.transform import CoNLL
+from supar.models.sdp.biaffine.parser import BiaffineSemanticDependencyParser
+from supar.models.sdp.vi.model import VISemanticDependencyModel
+from supar.utils import Config
+from supar.utils.logging import get_logger
+from supar.utils.metric import ChartMetric
+from supar.utils.transform import Batch
+
+logger = get_logger(__name__)
+
+
+class VISemanticDependencyParser(BiaffineSemanticDependencyParser):
+    r"""
+    The implementation of Semantic Dependency Parser using Variational Inference :cite:`wang-etal-2019-second`.
+    """
+
+    NAME = 'vi-semantic-dependency'
+    MODEL = VISemanticDependencyModel
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self.LEMMA = self.transform.LEMMA
+        self.TAG = self.transform.POS
+        self.LABEL = self.transform.PHEAD
+
+    def train(
+        self,
+        train: Union[str, Iterable],
+        dev: Union[str, Iterable],
+        test: Union[str, Iterable],
+        epochs: int = 1000,
+        patience: int = 100,
+        batch_size: int = 5000,
+        update_steps: int = 1,
+        buckets: int = 32,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().train(**Config().update(locals()))
+
+    def evaluate(
+        self,
+        data: Union[str, Iterable],
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().evaluate(**Config().update(locals()))
+
+    def predict(
+        self,
+        data: Union[str, Iterable],
+        pred: str = None,
+        lang: str = None,
+        prob: bool = False,
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        return super().predict(**Config().update(locals()))
+
+    def train_step(self, batch: Batch) -> torch.Tensor:
+        words, *feats, labels = batch
+        mask = batch.mask
+        mask = mask.unsqueeze(1) & mask.unsqueeze(2)
+        mask[:, 0] = 0
+        s_edge, s_sib, s_cop, s_grd, s_label = self.model(words, feats)
+        loss, s_edge = self.model.loss(s_edge, s_sib, s_cop, s_grd, s_label, labels, mask)
+        return loss
+
+    @torch.no_grad()
+    def eval_step(self, batch: Batch) -> ChartMetric:
+        words, *feats, labels = batch
+        mask = batch.mask
+        mask = mask.unsqueeze(1) & mask.unsqueeze(2)
+        mask[:, 0] = 0
+        s_edge, s_sib, s_cop, s_grd, s_label = self.model(words, feats)
+        loss, s_edge = self.model.loss(s_edge, s_sib, s_cop, s_grd, s_label, labels, mask)
+        label_preds = self.model.decode(s_edge, s_label)
+        return ChartMetric(loss, label_preds.masked_fill(~mask, -1), labels.masked_fill(~mask, -1))
+
+    @torch.no_grad()
+    def pred_step(self, batch: Batch) -> Batch:
+        words, *feats = batch
+        mask, lens = batch.mask, (batch.lens - 1).tolist()
+        mask = mask.unsqueeze(1) & mask.unsqueeze(2)
+        mask[:, 0] = 0
+        s_edge, s_sib, s_cop, s_grd, s_label = self.model(words, feats)
+        s_edge = self.model.inference((s_edge, s_sib, s_cop, s_grd), mask)
+        label_preds = self.model.decode(s_edge, s_label).masked_fill(~mask, -1)
+        batch.labels = [CoNLL.build_relations([[self.LABEL.vocab[i] if i >= 0 else None for i in row]
+                                               for row in chart[1:i, :i].tolist()])
+                        for i, chart in zip(lens, label_preds)]
+        if self.args.prob:
+            batch.probs = [prob[1:i, :i].cpu() for i, prob in zip(lens, s_edge.unbind())]
+        return batch
diff --git a/tania_scripts/supar/modules/__init__.py b/tania_scripts/supar/modules/__init__.py
new file mode 100644
index 0000000..981a6bf
--- /dev/null
+++ b/tania_scripts/supar/modules/__init__.py
@@ -0,0 +1,20 @@
+# -*- coding: utf-8 -*-
+
+from .affine import Biaffine, Triaffine
+from .dropout import IndependentDropout, SharedDropout, TokenDropout
+from .gnn import GraphConvolutionalNetwork
+from .lstm import CharLSTM, VariationalLSTM
+from .mlp import MLP
+from .decoder import DecoderLSTM
+from .pretrained import ELMoEmbedding, TransformerEmbedding
+from .transformer import (TransformerDecoder, TransformerEncoder,
+                          TransformerWordEmbedding)
+
+__all__ = ['Biaffine', 'Triaffine',
+           'IndependentDropout', 'SharedDropout', 'TokenDropout',
+           'GraphConvolutionalNetwork',
+           'CharLSTM', 'VariationalLSTM',
+           'MLP', 'DecoderLSTM',
+           'ELMoEmbedding', 'TransformerEmbedding',
+           'TransformerWordEmbedding',
+           'TransformerDecoder', 'TransformerEncoder']
diff --git a/tania_scripts/supar/modules/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/modules/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9c13e44da2a22e9ce2413ca58f980bfe9c2110b8
GIT binary patch
literal 795
zcmd1j<>g{vU|`^9UzBdh%)sy%#6iYP3=9ko3=9m#9SjT%DGVu$ISjdsQH;4vQA~^=
zK2r{JE=v?kE^8EPE?X2ESd2M`J(nYj1I%X0;mqZV;>zWY;s*0sb9i!jqj<q=wj91(
z{wRJhn>|M$S1?L2S13vd%;(4v&J~Fg$rX(f%@vChV`NBYNa0+>7$u&<70jT?{gRP^
zfkBh$7Kc-2Vp>{eUg|B*kRm8kllhjAXI@HbL26z~YF>#;QGP*wX~`|#;Ecqg)D#$(
zCnP^RH4n<uWV|KmUX)mn;hdjWmY-8vl9`{EnB$jPQl4Lw4YI~LBeBRQIK=lBe^_Es
zW+Fr$B%sN7i`myFK$Gznw@Yereo87>nI_XMURNLAeAnEh)RdIWy!2ZlAw`LK#cBCP
zxv52PQIJcK#GwY<5<(Jl%>x^HO9DwOJijOfVFrH@D2|Gl85kIfSU?0Th+qQ|>>z>z
zL~w!#P)rwbgIGKuf)_*xfCxSi!Oy_J;HN2ZiwzQ>2vcvdr$B-b&G;zh^t`+xkR7*J
za*9iGi{LgzG3VwK6oIU}#hwBQ6|lXxxC)9=ONtUR^HNia;BL6ZU4jUkBDh<MKu){G
z9v`2WlM^4mlA%Zf<Vq0n%U(YtKQ~psB(WqjF)vXsDJL-{Gqp%RIX|}`UpKv=L^n4-
zB{fICxU?X#NIy3}r8FnCSU)~KGcU6wK3=b&@)m~;MAQzHjEaRA7#IYYL>PG(1sHk2
JqzEGqGXTHg(EI=Z

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/modules/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/modules/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b8dc3d835d3ccc7fab896ae595885b0226ecebc2
GIT binary patch
literal 1028
zcmZ3^%ge>Uz`&q%Up2#!nStRkhy%k+P{!vj1_p-d3@HpLj5!Rsj8TlaOi@gXAU;zL
zb1q91OD<~^Yc5+98(54vhdq}giUZ7M$>Gf9isH)Uj^YOMS#x-Dd82s2Y_=S}T>dD2
zFq=I`AXhL-Fjpu_2+Zfm5zZBf63G>f63rEh5@TdYXGq~(#26)>!WGP*$^DX%fq_Aj
z=@y4mW@1`eW?t$o&X6J~Q<M3YkY`>>YC&pVN@`w-OHqD7erd@q-r$VHqSO=^mnS4Y
zJ2el=(`39Q>0Xprkl~!4SC*esT9TQcmzd+1T2h{0lnt`RIU}*iCpg6S7Jpb`QD!1U
z9wea2c#GNBCqR?&7Pm`ka(+rGSeYi%EnZh2-+b5Hq|}s@%)InlA|XYIdBth@MY*X(
za8Zy;k;I_}+!8_(bIk)AdP@RHEIhv`1z`q%5i<h=LlFyzU<DCuAc7r4aDWI-5CMwf
zB5n|i2So6K2tE)Y2qO4Fga88rgP*3vEjCDiB22x-o&pKNB2?pVF{kI{6@l!y#gbE8
zl3N6~=@xTtP661uTkI*2P$>f0dyA`}D7B<0F*7eUr3mhZTihjxuqlGOr3mD-TkP@i
zi8(p(@hcfVgVN$JU;T{y+*JLN#FEU!yhOdEoWzvO)FS=l{M>?k-ICOb65Z6Y#2o#S
z#JtSJ_~PWE%z~0){o>Ms#3KFN{FKt1)MEYk_{_Y_lK6PNg34bUHV{#}A~^;I22i3Z
ze#OAR@PV0;k?{i?1Ea<T26aqygTdtjZghh|>jEme!JvHs8@j<Dasd_HU{JV#if%Ai
hU%-YwFflTkd|)7jU}NVt|G)qv8rVUwNQQxd0RZ7AAYuRj

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/modules/__pycache__/affine.cpython-310.pyc b/tania_scripts/supar/modules/__pycache__/affine.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..39667f1870be23948663babfaa2080b05451c54f
GIT binary patch
literal 8011
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
T&BG+X#KFYF$ipbaELH^oF5vSb

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/modules/__pycache__/affine.cpython-311.pyc b/tania_scripts/supar/modules/__pycache__/affine.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c47fed9d260e0af01681cd36e39620f2209a26b3
GIT binary patch
literal 12963
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/modules/__pycache__/decoder.cpython-310.pyc b/tania_scripts/supar/modules/__pycache__/decoder.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..76a4b2187f9eabbe13f6151c3b2f5c962b577852
GIT binary patch
literal 1746
zcmd1j<>g{vU|<knUzG00#=!6x#6iX^3=9ko3=9m#W(*7rDGVu$ISjdsQH+crHd78$
zE^`z!n9Z2O62;=qkiwk8(!!9!lFFFH+RPlqmckg!pvn3YWTKxY<1J=ipMYc#2O0A~
zImICi3=F9ZQH&`JQA{a}smv)%smv+Nsmv)Xsmv*?sVpgMsjO){?F?y*DeNg6Ej&?d
zDV(Y7SsW=`ATo_5g*%0(g(ZqJg*Sz-g&~Tooq>fRiaVG=lm8aCOKNg{N@|f$aER|M
zuFSlG(vtY%%&OE|+!>iEDXDo-PJU?#T!t&JG&epcu`;!&_!fIgQGP*wX~`|Nl+?1!
z<kVz#sGC6)h|R&kz`zU&rU(WGh7yKmh6RiZ85kLA7;BiAm}(f}L72IQxrQO0rG}-3
zA)d8_EsGr_Tf>sVSi_pal)~K0R>Kg_QNmfnRKpAwVd({_<f;LQbEhzX0@BYdM3b!u
z6emTj3=9lKAggcjCS|5%7NsVaWaj53<`jXPa*I1Du_QSoJ}tATxI~lX7E4}yX5KB<
zy!iam5{Lq>#N?99vP6&`O`cn<#ia$QMYlNO<1_OzOXA~^tYCxN!<3hIiv=8jEIGv`
zxkXG23=FrJb8`xcI2jliG}&*l6sP8-Vbcn>60B+^<1Nnk_~e|#;^O%Dl?=b^^fU5v
zQ}s&{OEMGl67`aD5>ql$i}aK8a|`ly(+f&;bMsSDbM%W#3lfX;bMsS5b5e`-Qy_7v
zS5R3bz`(!&a$&Iq0|NsWBOenRBO4<J6AL2?Bga1u7A8iH|6EK}B1o~X2lL}C#)?~P
zMX4pFMR~~}uYjTwghBZMWTZ1FI_nr17-|@^7-E=fnQED9SxOieFx4<*G1q`dmW9j<
zSZf%v*cLM45@%wnWvykaVORi)Y}OjKG^T}2F-*1WwH!4J3pi@n7l5N%grSBZi)A6x
zLdIIo8cv8<4MP^!LgruwO~$HjE(IvCDo89!%vGqcQYgtUO3u&=NzE(HFH(qx#5O2F
z>nIeb7RKkK=IJOPQh6-G0EmZ+iP4Xg84w0&a^GSt&PXgsy~PT4!Y$US)S~=ia7qNH
z$y-b%`QWH75(cFl5l|vwFG>aLDFTJ7CRdRtNJa`I!-a79Eq18OZ!yN-V#+YM#guGt
zizy@T7E^NGEjEZ_ia^l}AtXWC+0*ii$`gxHKn51`F)%Rjuu3pXFtYs@VUl1LV5|~G
zj(DirWJXXdLotXA$}r%_Rsj`pj5Q2d46_+hKoQJ1n<0g{h9Qe-HbV*vDB5Q;%;f;*
z!zytklQj?_ZCk~sqkvST*jDlCC?E<Fur$Og;1b7HlLaZifO0b=h!`P3gyvh0`1qpK
zf};3%RZ!9drCAk5^t268pveQu%Xx{psqyi*xZ>j>IVV2;7EgS9VQFFxRE9Y-ujCeM
zT26jq$t~vMk|J<+Dv||-EE^<g6={N^N(&^y3(dF5sX00E@sLOWJ5UUy1QZ=bpb`*N
zE)|1<l!HNyQH)<e04%D>ev1Q~Ui9+viUdK%34-&q9>itEdZ1zi<Rhr<zTm75){0~k
b*gB9+w>WGd8tp(42)2%gfrpWUQH%)y8nLvR

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/modules/__pycache__/decoder.cpython-311.pyc b/tania_scripts/supar/modules/__pycache__/decoder.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6de6a887d7ce612ec0a7ef15992c489fb6b21aa7
GIT binary patch
literal 2997
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/modules/__pycache__/dropout.cpython-310.pyc b/tania_scripts/supar/modules/__pycache__/dropout.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c9431bcc12f190fe9a1715caba2b9b9b578ef7e8
GIT binary patch
literal 6173
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
W58PJbVd7!pVB%pEViwXCGXnrdC4;E|

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/modules/__pycache__/dropout.cpython-311.pyc b/tania_scripts/supar/modules/__pycache__/dropout.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..24e3f7b05eeb7b0809eb5b72992b12d9e5c160d4
GIT binary patch
literal 8710
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
G4iNyULAJ{P

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/modules/__pycache__/gnn.cpython-310.pyc b/tania_scripts/supar/modules/__pycache__/gnn.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..8c9899ee4c9fc3620942fc1768b69b489f133280
GIT binary patch
literal 5471
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/modules/__pycache__/gnn.cpython-311.pyc b/tania_scripts/supar/modules/__pycache__/gnn.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7471454ca9e111edcc54852b2bfeafb07ef79179
GIT binary patch
literal 7820
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
BS+@WH

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/modules/__pycache__/lstm.cpython-310.pyc b/tania_scripts/supar/modules/__pycache__/lstm.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b41ac7e996529a8790ae248cd831e01297c48eb3
GIT binary patch
literal 10155
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/modules/__pycache__/lstm.cpython-311.pyc b/tania_scripts/supar/modules/__pycache__/lstm.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..cbe023f8403b631f77886bc738ca050d7e7cf659
GIT binary patch
literal 16394
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
SNSc!Q5iIuwOk%172NnQIwNi8d

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/modules/__pycache__/mlp.cpython-310.pyc b/tania_scripts/supar/modules/__pycache__/mlp.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..856587590500e87d19034d97b32fba8d05cf1ddb
GIT binary patch
literal 2397
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/modules/__pycache__/mlp.cpython-311.pyc b/tania_scripts/supar/modules/__pycache__/mlp.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..69c92f7adbd0833ce5ccf154ad0997ff3e2cb672
GIT binary patch
literal 3517
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/modules/__pycache__/pretrained.cpython-310.pyc b/tania_scripts/supar/modules/__pycache__/pretrained.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fe5270597f6a76ea7e0866c0b20e3227024c7199
GIT binary patch
literal 10694
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
ZrDD(!JP(rq69*FyxUV6^EL18M3IGHrEQbI9

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/modules/__pycache__/pretrained.cpython-311.pyc b/tania_scripts/supar/modules/__pycache__/pretrained.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..75014d025196b5be3ee840b78c519e0d692f6c4c
GIT binary patch
literal 16517
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
UV4A}DkpU$41x$XxAi;4706db;N&o-=

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/modules/__pycache__/transformer.cpython-310.pyc b/tania_scripts/supar/modules/__pycache__/transformer.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0aa648d7943086a791868bfe31ccd2dac17e4d0e
GIT binary patch
literal 17309
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/modules/__pycache__/transformer.cpython-311.pyc b/tania_scripts/supar/modules/__pycache__/transformer.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..eb5927d047ca6f9c5b2983417896033e2322681e
GIT binary patch
literal 36701
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/modules/affine.py b/tania_scripts/supar/modules/affine.py
new file mode 100644
index 0000000..fe5defb
--- /dev/null
+++ b/tania_scripts/supar/modules/affine.py
@@ -0,0 +1,260 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+from typing import Callable, Optional
+
+import torch
+import torch.nn as nn
+from supar.modules.mlp import MLP
+
+
+class Biaffine(nn.Module):
+    r"""
+    Biaffine layer for first-order scoring :cite:`dozat-etal-2017-biaffine`.
+
+    This function has a tensor of weights :math:`W` and bias terms if needed.
+    The score :math:`s(x, y)` of the vector pair :math:`(x, y)` is computed as :math:`x^T W y / d^s`,
+    where `d` and `s` are vector dimension and scaling factor respectively.
+    :math:`x` and :math:`y` can be concatenated with bias terms.
+
+    Args:
+        n_in (int):
+            The size of the input feature.
+        n_out (int):
+            The number of output channels.
+        n_proj (Optional[int]):
+            If specified, applies MLP layers to reduce vector dimensions. Default: ``None``.
+        dropout (Optional[float]):
+            If specified, applies a :class:`SharedDropout` layer with the ratio on MLP outputs. Default: 0.
+        scale (float):
+            Factor to scale the scores. Default: 0.
+        bias_x (bool):
+            If ``True``, adds a bias term for tensor :math:`x`. Default: ``True``.
+        bias_y (bool):
+            If ``True``, adds a bias term for tensor :math:`y`. Default: ``True``.
+        decompose (bool):
+            If ``True``, represents the weight as the product of 2 independent matrices. Default: ``False``.
+        init (Callable):
+            Callable initialization method. Default: `nn.init.zeros_`.
+    """
+
+    def __init__(
+        self,
+        n_in: int,
+        n_out: int = 1,
+        n_proj: Optional[int] = None,
+        dropout: Optional[float] = 0,
+        scale: int = 0,
+        bias_x: bool = True,
+        bias_y: bool = True,
+        decompose: bool = False,
+        init: Callable = nn.init.zeros_
+    ) -> Biaffine:
+        super().__init__()
+
+        self.n_in = n_in
+        self.n_out = n_out
+        self.n_proj = n_proj
+        self.dropout = dropout
+        self.scale = scale
+        self.bias_x = bias_x
+        self.bias_y = bias_y
+        self.decompose = decompose
+        self.init = init
+
+        if n_proj is not None:
+            self.mlp_x, self.mlp_y = MLP(n_in, n_proj, dropout), MLP(n_in, n_proj, dropout)
+        self.n_model = n_proj or n_in
+        if not decompose:
+            self.weight = nn.Parameter(torch.Tensor(n_out, self.n_model + bias_x, self.n_model + bias_y))
+        else:
+            self.weight = nn.ParameterList((nn.Parameter(torch.Tensor(n_out, self.n_model + bias_x)),
+                                            nn.Parameter(torch.Tensor(n_out, self.n_model + bias_y))))
+
+        self.reset_parameters()
+
+    def __repr__(self):
+        s = f"n_in={self.n_in}"
+        if self.n_out > 1:
+            s += f", n_out={self.n_out}"
+        if self.n_proj is not None:
+            s += f", n_proj={self.n_proj}"
+        if self.dropout > 0:
+            s += f", dropout={self.dropout}"
+        if self.scale != 0:
+            s += f", scale={self.scale}"
+        if self.bias_x:
+            s += f", bias_x={self.bias_x}"
+        if self.bias_y:
+            s += f", bias_y={self.bias_y}"
+        if self.decompose:
+            s += f", decompose={self.decompose}"
+        return f"{self.__class__.__name__}({s})"
+
+    def reset_parameters(self):
+        if self.decompose:
+            for i in self.weight:
+                self.init(i)
+        else:
+            self.init(self.weight)
+
+    def forward(
+        self,
+        x: torch.Tensor,
+        y: torch.Tensor
+    ) -> torch.Tensor:
+        r"""
+        Args:
+            x (torch.Tensor): ``[batch_size, seq_len, n_in]``.
+            y (torch.Tensor): ``[batch_size, seq_len, n_in]``.
+
+        Returns:
+            ~torch.Tensor:
+                A scoring tensor of shape ``[batch_size, n_out, seq_len, seq_len]``.
+                If ``n_out=1``, the dimension for ``n_out`` will be squeezed automatically.
+        """
+
+        if hasattr(self, 'mlp_x'):
+            x, y = self.mlp_x(x), self.mlp_y(y)
+        if self.bias_x:
+            x = torch.cat((x, torch.ones_like(x[..., :1])), -1)
+        if self.bias_y:
+            y = torch.cat((y, torch.ones_like(y[..., :1])), -1)
+        # [batch_size, n_out, seq_len, seq_len]
+        if self.decompose:
+            wx = torch.einsum('bxi,oi->box', x, self.weight[0])
+            wy = torch.einsum('byj,oj->boy', y, self.weight[1])
+            s = torch.einsum('box,boy->boxy', wx, wy)
+        else:
+            s = torch.einsum('bxi,oij,byj->boxy', x, self.weight, y)
+        return s.squeeze(1) / self.n_in ** self.scale
+
+
+class Triaffine(nn.Module):
+    r"""
+    Triaffine layer for second-order scoring :cite:`zhang-etal-2020-efficient,wang-etal-2019-second`.
+
+    This function has a tensor of weights :math:`W` and bias terms if needed.
+    The score :math:`s(x, y, z)` of the vector triple :math:`(x, y, z)` is computed as :math:`x^T z^T W y / d^s`,
+    where `d` and `s` are vector dimension and scaling factor respectively.
+    :math:`x` and :math:`y` can be concatenated with bias terms.
+
+    Args:
+        n_in (int):
+            The size of the input feature.
+        n_out (int):
+            The number of output channels.
+        n_proj (Optional[int]):
+            If specified, applies MLP layers to reduce vector dimensions. Default: ``None``.
+        dropout (Optional[float]):
+            If specified, applies a :class:`SharedDropout` layer with the ratio on MLP outputs. Default: 0.
+        scale (float):
+            Factor to scale the scores. Default: 0.
+        bias_x (bool):
+            If ``True``, adds a bias term for tensor :math:`x`. Default: ``False``.
+        bias_y (bool):
+            If ``True``, adds a bias term for tensor :math:`y`. Default: ``False``.
+        decompose (bool):
+            If ``True``, represents the weight as the product of 3 independent matrices. Default: ``False``.
+        init (Callable):
+            Callable initialization method. Default: `nn.init.zeros_`.
+    """
+
+    def __init__(
+        self,
+        n_in: int,
+        n_out: int = 1,
+        n_proj: Optional[int] = None,
+        dropout: Optional[float] = 0,
+        scale: int = 0,
+        bias_x: bool = False,
+        bias_y: bool = False,
+        decompose: bool = False,
+        init: Callable = nn.init.zeros_
+    ) -> Triaffine:
+        super().__init__()
+
+        self.n_in = n_in
+        self.n_out = n_out
+        self.n_proj = n_proj
+        self.dropout = dropout
+        self.scale = scale
+        self.bias_x = bias_x
+        self.bias_y = bias_y
+        self.decompose = decompose
+        self.init = init
+
+        if n_proj is not None:
+            self.mlp_x = MLP(n_in, n_proj, dropout)
+            self.mlp_y = MLP(n_in, n_proj, dropout)
+            self.mlp_z = MLP(n_in, n_proj, dropout)
+        self.n_model = n_proj or n_in
+        if not decompose:
+            self.weight = nn.Parameter(torch.Tensor(n_out, self.n_model + bias_x, self.n_model, self.n_model + bias_y))
+        else:
+            self.weight = nn.ParameterList((nn.Parameter(torch.Tensor(n_out, self.n_model + bias_x)),
+                                            nn.Parameter(torch.Tensor(n_out, self.n_model)),
+                                            nn.Parameter(torch.Tensor(n_out, self.n_model + bias_y))))
+
+        self.reset_parameters()
+
+    def __repr__(self):
+        s = f"n_in={self.n_in}"
+        if self.n_out > 1:
+            s += f", n_out={self.n_out}"
+        if self.n_proj is not None:
+            s += f", n_proj={self.n_proj}"
+        if self.dropout > 0:
+            s += f", dropout={self.dropout}"
+        if self.scale != 0:
+            s += f", scale={self.scale}"
+        if self.bias_x:
+            s += f", bias_x={self.bias_x}"
+        if self.bias_y:
+            s += f", bias_y={self.bias_y}"
+        if self.decompose:
+            s += f", decompose={self.decompose}"
+        return f"{self.__class__.__name__}({s})"
+
+    def reset_parameters(self):
+        if self.decompose:
+            for i in self.weight:
+                self.init(i)
+        else:
+            self.init(self.weight)
+
+    def forward(
+        self,
+        x: torch.Tensor,
+        y: torch.Tensor,
+        z: torch.Tensor
+    ) -> torch.Tensor:
+        r"""
+        Args:
+            x (torch.Tensor): ``[batch_size, seq_len, n_in]``.
+            y (torch.Tensor): ``[batch_size, seq_len, n_in]``.
+            z (torch.Tensor): ``[batch_size, seq_len, n_in]``.
+
+        Returns:
+            ~torch.Tensor:
+                A scoring tensor of shape ``[batch_size, n_out, seq_len, seq_len, seq_len]``.
+                If ``n_out=1``, the dimension for ``n_out`` will be squeezed automatically.
+        """
+
+        if hasattr(self, 'mlp_x'):
+            x, y, z = self.mlp_x(x), self.mlp_y(y), self.mlp_z(y)
+        if self.bias_x:
+            x = torch.cat((x, torch.ones_like(x[..., :1])), -1)
+        if self.bias_y:
+            y = torch.cat((y, torch.ones_like(y[..., :1])), -1)
+        # [batch_size, n_out, seq_len, seq_len, seq_len]
+        if self.decompose:
+            wx = torch.einsum('bxi,oi->box', x, self.weight[0])
+            wz = torch.einsum('bzk,ok->boz', z, self.weight[1])
+            wy = torch.einsum('byj,oj->boy', y, self.weight[2])
+            s = torch.einsum('box,boz,boy->bozxy', wx, wz, wy)
+        else:
+            w = torch.einsum('bzk,oikj->bozij', z, self.weight)
+            s = torch.einsum('bxi,bozij,byj->bozxy', x, w, y)
+        return s.squeeze(1) / self.n_in ** self.scale
diff --git a/tania_scripts/supar/modules/decoder.py b/tania_scripts/supar/modules/decoder.py
new file mode 100644
index 0000000..2e9f97f
--- /dev/null
+++ b/tania_scripts/supar/modules/decoder.py
@@ -0,0 +1,38 @@
+import torch.nn as nn
+from supar.modules.mlp import MLP
+import torch
+
+class DecoderLSTM(nn.Module):
+    def __init__(self, input_size: int, hidden_size: int, output_size: int, num_layers: int, dropout: float, device: str):
+        super().__init__()
+
+        self.input_size, self.hidden_size = input_size, hidden_size
+        self.output_size = output_size
+        self.num_layers = num_layers
+
+        self.lstm = nn.LSTM(input_size=input_size, hidden_size=hidden_size,
+                            num_layers=num_layers, bidirectional=False,
+                            dropout=dropout, batch_first=True)
+
+        self.mlp = MLP(n_in=hidden_size, n_out=output_size, dropout=dropout,
+                       activation=True)
+        self.device = device
+
+    def forward(self, x: torch.Tensor) -> torch.Tensor:
+        r"""
+        :param x: torch.Tensor [batch_size, seq_len, input_size]
+        :returns torch.Tensor [batch_size, seq_len, output_size]
+        """
+        batch_size, seq_len, _ = x.shape
+
+        # LSTM forward pass
+        h0, c0 = torch.zeros(self.num_layers, batch_size, self.hidden_size).to(self.device), \
+                 torch.zeros(self.num_layers, batch_size, self.hidden_size).to(self.device)
+        hn, cn = self.lstm(x, (h0, c0))
+
+        # MLP forward pass
+        output = self.mlp(hn.reshape(batch_size*seq_len, self.hidden_size))
+        return output.reshape(batch_size, seq_len, self.output_size)
+
+    def __repr__(self):
+        return f'DecoderLSTM(input_size={self.input_size}, hidden_size={self.hidden_size}, num_layers={self.num_layers}, output_size={self.output_size}'
diff --git a/tania_scripts/supar/modules/dropout.py b/tania_scripts/supar/modules/dropout.py
new file mode 100644
index 0000000..1e3c947
--- /dev/null
+++ b/tania_scripts/supar/modules/dropout.py
@@ -0,0 +1,155 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+from typing import List
+
+import torch
+import torch.nn as nn
+
+
+class TokenDropout(nn.Module):
+    r"""
+    :class:`TokenDropout` seeks to randomly zero the vectors of some tokens with the probability of `p`.
+
+    Args:
+        p (float):
+            The probability of an element to be zeroed. Default: 0.5.
+
+    Examples:
+        >>> batch_size, seq_len, hidden_size = 1, 3, 5
+        >>> x = torch.ones(batch_size, seq_len, hidden_size)
+        >>> nn.Dropout()(x)
+        tensor([[[0., 2., 2., 0., 0.],
+                 [2., 2., 0., 2., 2.],
+                 [2., 2., 2., 2., 0.]]])
+        >>> TokenDropout()(x)
+        tensor([[[2., 2., 2., 2., 2.],
+                 [0., 0., 0., 0., 0.],
+                 [2., 2., 2., 2., 2.]]])
+    """
+
+    def __init__(self, p: float = 0.5) -> TokenDropout:
+        super().__init__()
+
+        self.p = p
+
+    def __repr__(self):
+        return f"{self.__class__.__name__}(p={self.p})"
+
+    def forward(self, x: torch.Tensor) -> torch.Tensor:
+        r"""
+        Args:
+            x (~torch.Tensor):
+                A tensor of any shape.
+        Returns:
+            A tensor with the same shape as `x`.
+        """
+
+        if not self.training:
+            return x
+        return x * (x.new_empty(x.shape[:2]).bernoulli_(1 - self.p) / (1 - self.p)).unsqueeze(-1)
+
+
+class SharedDropout(nn.Module):
+    r"""
+    :class:`SharedDropout` differs from the vanilla dropout strategy in that the dropout mask is shared across one dimension.
+
+    Args:
+        p (float):
+            The probability of an element to be zeroed. Default: 0.5.
+        batch_first (bool):
+            If ``True``, the input and output tensors are provided as ``[batch_size, seq_len, *]``.
+            Default: ``True``.
+
+    Examples:
+        >>> batch_size, seq_len, hidden_size = 1, 3, 5
+        >>> x = torch.ones(batch_size, seq_len, hidden_size)
+        >>> nn.Dropout()(x)
+        tensor([[[0., 2., 2., 0., 0.],
+                 [2., 2., 0., 2., 2.],
+                 [2., 2., 2., 2., 0.]]])
+        >>> SharedDropout()(x)
+        tensor([[[2., 0., 2., 0., 2.],
+                 [2., 0., 2., 0., 2.],
+                 [2., 0., 2., 0., 2.]]])
+    """
+
+    def __init__(self, p: float = 0.5, batch_first: bool = True) -> SharedDropout:
+        super().__init__()
+
+        self.p = p
+        self.batch_first = batch_first
+
+    def __repr__(self):
+        s = f"p={self.p}"
+        if self.batch_first:
+            s += f", batch_first={self.batch_first}"
+        return f"{self.__class__.__name__}({s})"
+
+    def forward(self, x: torch.Tensor) -> torch.Tensor:
+        r"""
+        Args:
+            x (~torch.Tensor):
+                A tensor of any shape.
+        Returns:
+            A tensor with the same shape as `x`.
+        """
+
+        if not self.training:
+            return x
+        return x * self.get_mask(x[:, 0], self.p).unsqueeze(1) if self.batch_first else self.get_mask(x[0], self.p)
+
+    @staticmethod
+    def get_mask(x: torch.Tensor, p: float) -> torch.FloatTensor:
+        return x.new_empty(x.shape).bernoulli_(1 - p) / (1 - p)
+
+
+class IndependentDropout(nn.Module):
+    r"""
+    For :math:`N` tensors, they use different dropout masks respectively.
+    When :math:`N-M` of them are dropped, the remaining :math:`M` ones are scaled by a factor of :math:`N/M` to compensate,
+    and when all of them are dropped together, zeros are returned.
+
+    Args:
+        p (float):
+            The probability of an element to be zeroed. Default: 0.5.
+
+    Examples:
+        >>> batch_size, seq_len, hidden_size = 1, 3, 5
+        >>> x, y = torch.ones(batch_size, seq_len, hidden_size), torch.ones(batch_size, seq_len, hidden_size)
+        >>> x, y = IndependentDropout()(x, y)
+        >>> x
+        tensor([[[1., 1., 1., 1., 1.],
+                 [0., 0., 0., 0., 0.],
+                 [2., 2., 2., 2., 2.]]])
+        >>> y
+        tensor([[[1., 1., 1., 1., 1.],
+                 [2., 2., 2., 2., 2.],
+                 [0., 0., 0., 0., 0.]]])
+    """
+
+    def __init__(self, p: float = 0.5) -> IndependentDropout:
+        super().__init__()
+
+        self.p = p
+
+    def __repr__(self):
+        return f"{self.__class__.__name__}(p={self.p})"
+
+    def forward(self, *items: List[torch.Tensor]) -> List[torch.Tensor]:
+        r"""
+        Args:
+            items (List[~torch.Tensor]):
+                A list of tensors that have the same shape except the last dimension.
+        Returns:
+            A tensors are of the same shape as `items`.
+        """
+
+        if not self.training:
+            return items
+        masks = [x.new_empty(x.shape[:2]).bernoulli_(1 - self.p) for x in items]
+        total = sum(masks)
+        scale = len(items) / total.max(torch.ones_like(total))
+        masks = [mask * scale for mask in masks]
+        return [item * mask.unsqueeze(-1) for item, mask in zip(items, masks)]
diff --git a/tania_scripts/supar/modules/gnn.py b/tania_scripts/supar/modules/gnn.py
new file mode 100644
index 0000000..8f2108c
--- /dev/null
+++ b/tania_scripts/supar/modules/gnn.py
@@ -0,0 +1,135 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+import torch
+import torch.nn as nn
+
+
+class GraphConvolutionalNetwork(nn.Module):
+    r"""
+    Multiple GCN layers with layer normalization and residual connections, each executing the operator
+    from the `"Semi-supervised Classification with Graph Convolutional Networks" <https://arxiv.org/abs/1609.02907>`_ paper
+
+    .. math::
+        \mathbf{X}^{\prime} = \mathbf{\hat{D}}^{-1/2} \mathbf{\hat{A}}
+        \mathbf{\hat{D}}^{-1/2} \mathbf{X} \mathbf{\Theta},
+
+    where :math:`\mathbf{\hat{A}} = \mathbf{A} + \mathbf{I}` denotes the adjacency matrix with inserted self-loops
+    and :math:`\hat{D}_{ii} = \sum_{j=0} \hat{A}_{ij}` its diagonal degree matrix.
+
+    Its node-wise formulation is given by:
+
+    .. math::
+        \mathbf{x}^{\prime}_i = \mathbf{\Theta}^{\top} \sum_{j \in
+        \mathcal{N}(v) \cup \{ i \}} \frac{e_{j,i}}{\sqrt{\hat{d}_j
+        \hat{d}_i}} \mathbf{x}_j
+
+    with :math:`\hat{d}_i = 1 + \sum_{j \in \mathcal{N}(i)} e_{j,i}`, where
+    :math:`e_{j,i}` denotes the edge weight from source node :obj:`j` to target
+    node :obj:`i` (default: :obj:`1.0`)
+
+    Args:
+        n_model (int):
+            The size of node feature vectors.
+        n_layers (int):
+            The number of GCN layers. Default: 1.
+        selfloop (bool):
+            If ``True``, adds self-loops to adjacent matrices. Default: ``True``.
+        dropout (float):
+            The probability of feature vector elements to be zeroed. Default: 0.
+        norm (bool):
+            If ``True``, adds a :class:`~torch.nn.LayerNorm` layer after each GCN layer. Default: ``True``.
+    """
+
+    def __init__(
+        self,
+        n_model: int,
+        n_layers: int = 1,
+        selfloop: bool = True,
+        dropout: float = 0.,
+        norm: bool = True
+    ) -> GraphConvolutionalNetwork:
+        super().__init__()
+
+        self.n_model = n_model
+        self.n_layers = n_layers
+        self.selfloop = selfloop
+        self.norm = norm
+
+        self.conv_layers = nn.ModuleList([
+            nn.Sequential(
+                GraphConv(n_model),
+                nn.LayerNorm([n_model]) if norm else nn.Identity()
+            )
+            for _ in range(n_layers)
+        ])
+        self.dropout = nn.Dropout(dropout)
+
+    def __repr__(self):
+        s = f"n_model={self.n_model}, n_layers={self.n_layers}"
+        if self.selfloop:
+            s += f", selfloop={self.selfloop}"
+        if self.dropout.p > 0:
+            s += f", dropout={self.dropout.p}"
+        if self.norm:
+            s += f", norm={self.norm}"
+        return f"{self.__class__.__name__}({s})"
+
+    def forward(self, x: torch.Tensor, adj: torch.Tensor, mask: torch.BoolTensor) -> torch.Tensor:
+        r"""
+        Args:
+            x (~torch.Tensor):
+                Node feature tensors of shape ``[batch_size, seq_len, n_model]``.
+            adj (~torch.Tensor):
+                Adjacent matrix of shape ``[batch_size, seq_len, seq_len]``.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask for covering the unpadded tokens in each chart.
+
+        Returns:
+            ~torch.Tensor:
+                Node feature tensors of shape ``[batch_size, seq_len, n_model]``.
+        """
+
+        if self.selfloop:
+            adj.diagonal(0, 1, 2).fill_(1.)
+        adj = adj.masked_fill(~(mask.unsqueeze(1) & mask.unsqueeze(2)), 0)
+        for conv, norm in self.conv_layers:
+            x = norm(x + self.dropout(conv(x, adj).relu()))
+        return x
+
+
+class GraphConv(nn.Module):
+
+    def __init__(self, n_model: int, bias: bool = True) -> GraphConv:
+        super().__init__()
+
+        self.n_model = n_model
+
+        self.linear = nn.Linear(n_model, n_model, bias=False)
+        self.bias = nn.Parameter(torch.zeros(n_model)) if bias else None
+
+    def __repr__(self):
+        s = f"n_model={self.n_model}"
+        if self.bias is not None:
+            s += ", bias=True"
+        return f"{self.__class__.__name__}({s})"
+
+    def forward(self, x: torch.Tensor, adj: torch.Tensor) -> torch.Tensor:
+        r"""
+        Args:
+            x (~torch.Tensor):
+                Node feature tensors of shape ``[batch_size, seq_len, n_model]``.
+            adj (~torch.Tensor):
+                Adjacent matrix of shape ``[batch_size, seq_len, seq_len]``.
+
+        Returns:
+            ~torch.Tensor:
+                Node feature tensors of shape ``[batch_size, seq_len, n_model]``.
+        """
+
+        x = self.linear(x)
+        x = torch.matmul(adj * (adj.sum(1, True) * adj.sum(2, True) + torch.finfo(adj.dtype).eps).pow(-0.5), x)
+        if self.bias is not None:
+            x = x + self.bias
+        return x
diff --git a/tania_scripts/supar/modules/lstm.py b/tania_scripts/supar/modules/lstm.py
new file mode 100644
index 0000000..759f9c1
--- /dev/null
+++ b/tania_scripts/supar/modules/lstm.py
@@ -0,0 +1,271 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+from typing import List, Optional, Tuple
+
+import torch
+import torch.nn as nn
+from supar.modules.dropout import SharedDropout
+from torch.nn.modules.rnn import apply_permutation
+from torch.nn.utils.rnn import PackedSequence, pack_padded_sequence
+
+
+class CharLSTM(nn.Module):
+    r"""
+    CharLSTM aims to generate character-level embeddings for tokens.
+    It summarizes the information of characters in each token to an embedding using a LSTM layer.
+
+    Args:
+        n_char (int):
+            The number of characters.
+        n_embed (int):
+            The size of each embedding vector as input to LSTM.
+        n_hidden (int):
+            The size of each LSTM hidden state.
+        n_out (int):
+            The size of each output vector. Default: 0.
+            If 0, equals to the size of hidden states.
+        pad_index (int):
+            The index of the padding token in the vocabulary. Default: 0.
+        dropout (float):
+            The dropout ratio of CharLSTM hidden states. Default: 0.
+    """
+
+    def __init__(
+        self,
+        n_chars: int,
+        n_embed: int,
+        n_hidden: int,
+        n_out: int = 0,
+        pad_index: int = 0,
+        dropout: float = 0
+    ) -> CharLSTM:
+        super().__init__()
+
+        self.n_chars = n_chars
+        self.n_embed = n_embed
+        self.n_hidden = n_hidden
+        self.n_out = n_out or n_hidden
+        self.pad_index = pad_index
+
+        self.embed = nn.Embedding(num_embeddings=n_chars, embedding_dim=n_embed)
+        self.lstm = nn.LSTM(input_size=n_embed, hidden_size=n_hidden//2, batch_first=True, bidirectional=True)
+        self.dropout = nn.Dropout(p=dropout)
+        self.projection = nn.Linear(in_features=n_hidden, out_features=self.n_out) if n_hidden != self.n_out else nn.Identity()
+
+    def __repr__(self):
+        s = f"{self.n_chars}, {self.n_embed}"
+        if self.n_hidden != self.n_out:
+            s += f", n_hidden={self.n_hidden}"
+        s += f", n_out={self.n_out}, pad_index={self.pad_index}"
+        if self.dropout.p != 0:
+            s += f", dropout={self.dropout.p}"
+        return f"{self.__class__.__name__}({s})"
+
+    def forward(self, x: torch.Tensor) -> torch.Tensor:
+        r"""
+        Args:
+            x (~torch.Tensor): ``[batch_size, seq_len, fix_len]``.
+                Characters of all tokens.
+                Each token holds no more than `fix_len` characters, and the excess is cut off directly.
+        Returns:
+            ~torch.Tensor:
+                The embeddings of shape ``[batch_size, seq_len, n_out]`` derived from the characters.
+        """
+
+        # [batch_size, seq_len, fix_len]
+        mask = x.ne(self.pad_index)
+        # [batch_size, seq_len]
+        lens = mask.sum(-1)
+        char_mask = lens.gt(0)
+
+        # [n, fix_len, n_embed]
+        x = self.embed(x[char_mask])
+        x = pack_padded_sequence(x, lens[char_mask].tolist(), True, False)
+        x, (h, _) = self.lstm(x)
+        # [n, fix_len, n_hidden]
+        h = self.dropout(torch.cat(torch.unbind(h), -1))
+        # [n, fix_len, n_out]
+        h = self.projection(h)
+        # [batch_size, seq_len, n_out]
+        return h.new_zeros(*lens.shape, self.n_out).masked_scatter_(char_mask.unsqueeze(-1), h)
+
+
+class VariationalLSTM(nn.Module):
+    r"""
+    VariationalLSTM :cite:`yarin-etal-2016-dropout` is an variant of the vanilla bidirectional LSTM
+    adopted by Biaffine Parser with the only difference of the dropout strategy.
+    It drops nodes in the LSTM layers (input and recurrent connections)
+    and applies the same dropout mask at every recurrent timesteps.
+
+    APIs are roughly the same as :class:`~torch.nn.LSTM` except that we only allows
+    :class:`~torch.nn.utils.rnn.PackedSequence` as input.
+
+    Args:
+        input_size (int):
+            The number of expected features in the input.
+        hidden_size (int):
+            The number of features in the hidden state `h`.
+        num_layers (int):
+            The number of recurrent layers. Default: 1.
+        bidirectional (bool):
+            If ``True``, becomes a bidirectional LSTM. Default: ``False``
+        dropout (float):
+            If non-zero, introduces a :class:`SharedDropout` layer on the outputs of each LSTM layer except the last layer.
+            Default: 0.
+    """
+
+    def __init__(
+        self,
+        input_size: int,
+        hidden_size: int,
+        num_layers: int = 1,
+        bidirectional: bool = False,
+        dropout: float = .0
+    ) -> VariationalLSTM:
+        super().__init__()
+
+        self.input_size = input_size
+        self.hidden_size = hidden_size
+        self.num_layers = num_layers
+        self.bidirectional = bidirectional
+        self.dropout = dropout
+        self.num_directions = 1 + self.bidirectional
+
+        self.f_cells = nn.ModuleList()
+        if bidirectional:
+            self.b_cells = nn.ModuleList()
+        for _ in range(self.num_layers):
+            self.f_cells.append(nn.LSTMCell(input_size=input_size, hidden_size=hidden_size))
+            if bidirectional:
+                self.b_cells.append(nn.LSTMCell(input_size=input_size, hidden_size=hidden_size))
+            input_size = hidden_size * self.num_directions
+
+        self.reset_parameters()
+
+    def __repr__(self):
+        s = f"{self.input_size}, {self.hidden_size}"
+        if self.num_layers > 1:
+            s += f", num_layers={self.num_layers}"
+        if self.bidirectional:
+            s += f", bidirectional={self.bidirectional}"
+        if self.dropout > 0:
+            s += f", dropout={self.dropout}"
+        return f"{self.__class__.__name__}({s})"
+
+    def reset_parameters(self):
+        for param in self.parameters():
+            # apply orthogonal_ to weight
+            if len(param.shape) > 1:
+                nn.init.orthogonal_(param)
+            # apply zeros_ to bias
+            else:
+                nn.init.zeros_(param)
+
+    def permute_hidden(
+        self,
+        hx: Tuple[torch.Tensor, torch.Tensor],
+        permutation: torch.LongTensor
+    ) -> Tuple[torch.Tensor, torch.Tensor]:
+        if permutation is None:
+            return hx
+        h = apply_permutation(hx[0], permutation)
+        c = apply_permutation(hx[1], permutation)
+
+        return h, c
+
+    def layer_forward(
+        self,
+        x: List[torch.Tensor],
+        hx: Tuple[torch.Tensor, torch.Tensor],
+        cell: nn.LSTMCell,
+        batch_sizes: List[int],
+        reverse: bool = False
+    ) -> Tuple[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]]:
+        hx_0 = hx_i = hx
+        hx_n, output = [], []
+        steps = reversed(range(len(x))) if reverse else range(len(x))
+        if self.training:
+            hid_mask = SharedDropout.get_mask(hx_0[0], self.dropout)
+
+        for t in steps:
+            last_batch_size, batch_size = len(hx_i[0]), batch_sizes[t]
+            if last_batch_size < batch_size:
+                hx_i = [torch.cat((h, ih[last_batch_size:batch_size])) for h, ih in zip(hx_i, hx_0)]
+            else:
+                hx_n.append([h[batch_size:] for h in hx_i])
+                hx_i = [h[:batch_size] for h in hx_i]
+            hx_i = [h for h in cell(x[t], hx_i)]
+            output.append(hx_i[0])
+            if self.training:
+                hx_i[0] = hx_i[0] * hid_mask[:batch_size]
+        if reverse:
+            hx_n = hx_i
+            output.reverse()
+        else:
+            hx_n.append(hx_i)
+            hx_n = [torch.cat(h) for h in zip(*reversed(hx_n))]
+        output = torch.cat(output)
+
+        return output, hx_n
+
+    def forward(
+        self,
+        sequence: PackedSequence,
+        hx: Optional[Tuple[torch.Tensor, torch.Tensor]] = None
+    ) -> Tuple[PackedSequence, Tuple[torch.Tensor, torch.Tensor]]:
+        r"""
+        Args:
+            sequence (~torch.nn.utils.rnn.PackedSequence):
+                A packed variable length sequence.
+            hx (~torch.Tensor, ~torch.Tensor):
+                A tuple composed of two tensors `h` and `c`.
+                `h` of shape ``[num_layers*num_directions, batch_size, hidden_size]`` holds the initial hidden state
+                for each element in the batch.
+                `c` of shape ``[num_layers*num_directions, batch_size, hidden_size]`` holds the initial cell state
+                for each element in the batch.
+                If `hx` is not provided, both `h` and `c` default to zero.
+                Default: ``None``.
+
+        Returns:
+            ~torch.nn.utils.rnn.PackedSequence, (~torch.Tensor, ~torch.Tensor):
+                The first is a packed variable length sequence.
+                The second is a tuple of tensors `h` and `c`.
+                `h` of shape ``[num_layers*num_directions, batch_size, hidden_size]`` holds the hidden state for `t=seq_len`.
+                Like output, the layers can be separated using ``h.view(num_layers, num_directions, batch_size, hidden_size)``
+                and similarly for c.
+                `c` of shape ``[num_layers*num_directions, batch_size, hidden_size]`` holds the cell state for `t=seq_len`.
+        """
+        x, batch_sizes = sequence.data, sequence.batch_sizes.tolist()
+        batch_size = batch_sizes[0]
+        h_n, c_n = [], []
+
+        if hx is None:
+            ih = x.new_zeros(self.num_layers * self.num_directions, batch_size, self.hidden_size)
+            h, c = ih, ih
+        else:
+            h, c = self.permute_hidden(hx, sequence.sorted_indices)
+        h = h.view(self.num_layers, self.num_directions, batch_size, self.hidden_size)
+        c = c.view(self.num_layers, self.num_directions, batch_size, self.hidden_size)
+
+        for i in range(self.num_layers):
+            x = torch.split(x, batch_sizes)
+            if self.training:
+                mask = SharedDropout.get_mask(x[0], self.dropout)
+                x = [i * mask[:len(i)] for i in x]
+            x_i, (h_i, c_i) = self.layer_forward(x, (h[i, 0], c[i, 0]), self.f_cells[i], batch_sizes)
+            if self.bidirectional:
+                x_b, (h_b, c_b) = self.layer_forward(x, (h[i, 1], c[i, 1]), self.b_cells[i], batch_sizes, True)
+                x_i = torch.cat((x_i, x_b), -1)
+                h_i = torch.stack((h_i, h_b))
+                c_i = torch.stack((c_i, c_b))
+            x = x_i
+            h_n.append(h_i)
+            c_n.append(c_i)
+
+        x = PackedSequence(x, sequence.batch_sizes, sequence.sorted_indices, sequence.unsorted_indices)
+        hx = torch.cat(h_n, 0), torch.cat(c_n, 0)
+        hx = self.permute_hidden(hx, sequence.unsorted_indices)
+
+        return x, hx
diff --git a/tania_scripts/supar/modules/mlp.py b/tania_scripts/supar/modules/mlp.py
new file mode 100644
index 0000000..f26cdd9
--- /dev/null
+++ b/tania_scripts/supar/modules/mlp.py
@@ -0,0 +1,62 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+import torch
+import torch.nn as nn
+from supar.modules.dropout import SharedDropout
+
+
+class MLP(nn.Module):
+    r"""
+    Applies a linear transformation together with a non-linear activation to the incoming tensor:
+    :math:`y = \mathrm{Activation}(x A^T + b)`
+
+    Args:
+        n_in (~torch.Tensor):
+            The size of each input feature.
+        n_out (~torch.Tensor):
+            The size of each output feature.
+        dropout (float):
+            If non-zero, introduces a :class:`SharedDropout` layer on the output with this dropout ratio. Default: 0.
+        activation (bool):
+            Whether to use activations. Default: True.
+    """
+
+    def __init__(self, n_in: int, n_out: int, dropout: float = .0, activation: bool = True) -> MLP:
+        super().__init__()
+
+        self.n_in = n_in
+        self.n_out = n_out
+        self.linear = nn.Linear(n_in, n_out)
+        self.activation = nn.LeakyReLU(negative_slope=0.1) if activation else nn.Identity()
+        self.dropout = SharedDropout(p=dropout)
+
+        self.reset_parameters()
+
+    def __repr__(self):
+        s = f"n_in={self.n_in}, n_out={self.n_out}"
+        if self.dropout.p > 0:
+            s += f", dropout={self.dropout.p}"
+
+        return f"{self.__class__.__name__}({s})"
+
+    def reset_parameters(self):
+        nn.init.orthogonal_(self.linear.weight)
+        nn.init.zeros_(self.linear.bias)
+
+    def forward(self, x: torch.Tensor) -> torch.Tensor:
+        r"""
+        Args:
+            x (~torch.Tensor):
+                The size of each input feature is `n_in`.
+
+        Returns:
+            A tensor with the size of each output feature `n_out`.
+        """
+
+        x = self.linear(x)
+        x = self.activation(x)
+        x = self.dropout(x)
+
+        return x
diff --git a/tania_scripts/supar/modules/pretrained.py b/tania_scripts/supar/modules/pretrained.py
new file mode 100644
index 0000000..4805c88
--- /dev/null
+++ b/tania_scripts/supar/modules/pretrained.py
@@ -0,0 +1,256 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+from typing import List, Tuple
+
+import torch
+import torch.nn as nn
+from supar.utils.fn import pad
+from supar.utils.tokenizer import TransformerTokenizer
+
+
+class TransformerEmbedding(nn.Module):
+    r"""
+    Bidirectional transformer embeddings of words from various transformer architectures :cite:`devlin-etal-2019-bert`.
+
+    Args:
+        name (str):
+            Path or name of the pretrained models registered in `transformers`_, e.g., ``'bert-base-cased'``.
+        n_layers (int):
+            The number of BERT layers to use. If 0, uses all layers.
+        n_out (int):
+            The requested size of the embeddings. If 0, uses the size of the pretrained embedding model. Default: 0.
+        stride (int):
+            A sequence longer than max length will be splitted into several small pieces
+            with a window size of ``stride``. Default: 10.
+        pooling (str):
+            Pooling way to get from token piece embeddings to token embedding.
+            ``first``: take the first subtoken. ``last``: take the last subtoken. ``mean``: take a mean over all.
+            Default: ``mean``.
+        pad_index (int):
+            The index of the padding token in BERT vocabulary. Default: 0.
+        mix_dropout (float):
+            The dropout ratio of BERT layers. This value will be passed into the :class:`ScalarMix` layer. Default: 0.
+        finetune (bool):
+            If ``True``, the model parameters will be updated together with the downstream task. Default: ``False``.
+
+    .. _transformers:
+        https://github.com/huggingface/transformers
+    """
+
+    def __init__(
+        self,
+        name: str,
+        n_layers: int,
+        n_out: int = 0,
+        stride: int = 256,
+        pooling: str = 'mean',
+        pad_index: int = 0,
+        mix_dropout: float = .0,
+        finetune: bool = False
+    ) -> TransformerEmbedding:
+        super().__init__()
+
+        from transformers import AutoModel
+        try:
+            self.model = AutoModel.from_pretrained(name, output_hidden_states=True, local_files_only=True)
+        except Exception:
+            self.model = AutoModel.from_pretrained(name, output_hidden_states=True, local_files_only=False)
+        self.model = self.model.requires_grad_(finetune)
+        self.tokenizer = TransformerTokenizer(name)
+
+        self.name = name
+        self.n_layers = n_layers or self.model.config.num_hidden_layers
+        self.hidden_size = self.model.config.hidden_size
+        self.n_out = n_out or self.hidden_size
+        self.pooling = pooling
+        self.pad_index = pad_index
+        self.mix_dropout = mix_dropout
+        self.finetune = finetune
+        try:
+            self.max_len = int(max(0, self.model.config.max_position_embeddings) or 1e12) - 2
+        except:
+            self.max_len = 512
+        self.stride = min(stride, self.max_len)
+
+        self.scalar_mix = ScalarMix(self.n_layers, mix_dropout)
+        self.projection = nn.Linear(self.hidden_size, self.n_out, False) if self.hidden_size != n_out else nn.Identity()
+
+    def __repr__(self):
+        s = f"{self.name}, n_layers={self.n_layers}, n_out={self.n_out}, "
+        s += f"stride={self.stride}, pooling={self.pooling}, pad_index={self.pad_index}"
+        if self.mix_dropout > 0:
+            s += f", mix_dropout={self.mix_dropout}"
+        if self.finetune:
+            s += f", finetune={self.finetune}"
+        return f"{self.__class__.__name__}({s})"
+
+    def forward(self, tokens: torch.Tensor) -> torch.Tensor:
+        r"""
+        Args:
+            tokens (~torch.Tensor): ``[batch_size, seq_len, fix_len]``.
+
+        Returns:
+            ~torch.Tensor:
+                Contextualized token embeddings of shape ``[batch_size, seq_len, n_out]``.
+        """
+
+        mask = tokens.ne(self.pad_index)
+        lens = mask.sum((1, 2))
+        # [batch_size, n_subwords]
+        tokens = pad(tokens[mask].split(lens.tolist()), self.pad_index, padding_side=self.tokenizer.padding_side)
+        token_mask = pad(mask[mask].split(lens.tolist()), 0, padding_side=self.tokenizer.padding_side)
+
+        # return the hidden states of all layers
+        x = self.model(tokens[:, :self.max_len], attention_mask=token_mask[:, :self.max_len].float())[-1]
+        # [batch_size, max_len, hidden_size]
+        x = self.scalar_mix(x[-self.n_layers:])
+        # [batch_size, n_subwords, hidden_size]
+        for i in range(self.stride, (tokens.shape[1]-self.max_len+self.stride-1)//self.stride*self.stride+1, self.stride):
+            part = self.model(tokens[:, i:i+self.max_len], attention_mask=token_mask[:, i:i+self.max_len].float())[-1]
+            x = torch.cat((x, self.scalar_mix(part[-self.n_layers:])[:, self.max_len-self.stride:]), 1)
+        # [batch_size, seq_len]
+        lens = mask.sum(-1)
+        lens = lens.masked_fill_(lens.eq(0), 1)
+        # [batch_size, seq_len, fix_len, hidden_size]
+        x = x.new_zeros(*mask.shape, self.hidden_size).masked_scatter_(mask.unsqueeze(-1), x[token_mask])
+        # [batch_size, seq_len, hidden_size]
+        if self.pooling == 'first':
+            x = x[:, :, 0]
+        elif self.pooling == 'last':
+            x = x.gather(2, (lens-1).unsqueeze(-1).repeat(1, 1, self.hidden_size).unsqueeze(2)).squeeze(2)
+        elif self.pooling == 'mean':
+            x = x.sum(2) / lens.unsqueeze(-1)
+        else:
+            raise RuntimeError(f'Unsupported pooling method "{self.pooling}"!')
+        return self.projection(x)
+
+
+class ELMoEmbedding(nn.Module):
+    r"""
+    Contextual word embeddings using word-level bidirectional LM :cite:`peters-etal-2018-deep`.
+
+    Args:
+        name (str):
+            The name of the pretrained ELMo registered in `OPTION` and `WEIGHT`. Default: ``'original_5b'``.
+        bos_eos (Tuple[bool]):
+            A tuple of two boolean values indicating whether to keep start/end boundaries of sentence outputs.
+            Default: ``(True, True)``.
+        n_out (int):
+            The requested size of the embeddings. If 0, uses the default size of ELMo outputs. Default: 0.
+        dropout (float):
+            The dropout ratio for the ELMo layer. Default: 0.
+        finetune (bool):
+            If ``True``, the model parameters will be updated together with the downstream task. Default: ``False``.
+    """
+
+    OPTION = {
+        'small': 'https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x1024_128_2048cnn_1xhighway/elmo_2x1024_128_2048cnn_1xhighway_options.json',  # noqa
+        'medium': 'https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x2048_256_2048cnn_1xhighway/elmo_2x2048_256_2048cnn_1xhighway_options.json',  # noqa
+        'original': 'https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x4096_512_2048cnn_2xhighway/elmo_2x4096_512_2048cnn_2xhighway_options.json',  # noqa
+        'original_5b': 'https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x4096_512_2048cnn_2xhighway_5.5B/elmo_2x4096_512_2048cnn_2xhighway_5.5B_options.json',  # noqa
+    }
+    WEIGHT = {
+        'small': 'https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x1024_128_2048cnn_1xhighway/elmo_2x1024_128_2048cnn_1xhighway_weights.hdf5',  # noqa
+        'medium': 'https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x2048_256_2048cnn_1xhighway/elmo_2x2048_256_2048cnn_1xhighway_weights.hdf5',  # noqa
+        'original': 'https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x4096_512_2048cnn_2xhighway/elmo_2x4096_512_2048cnn_2xhighway_weights.hdf5',  # noqa
+        'original_5b': 'https://s3-us-west-2.amazonaws.com/allennlp/models/elmo/2x4096_512_2048cnn_2xhighway_5.5B/elmo_2x4096_512_2048cnn_2xhighway_5.5B_weights.hdf5',  # noqa
+    }
+
+    def __init__(
+        self,
+        name: str = 'original_5b',
+        bos_eos: Tuple[bool, bool] = (True, True),
+        n_out: int = 0,
+        dropout: float = 0.5,
+        finetune: bool = False
+    ) -> ELMoEmbedding:
+        super().__init__()
+
+        from allennlp.modules import Elmo
+
+        self.elmo = Elmo(options_file=self.OPTION[name],
+                         weight_file=self.WEIGHT[name],
+                         num_output_representations=1,
+                         dropout=dropout,
+                         finetune=finetune,
+                         keep_sentence_boundaries=True)
+
+        self.name = name
+        self.bos_eos = bos_eos
+        self.hidden_size = self.elmo.get_output_dim()
+        self.n_out = n_out or self.hidden_size
+        self.dropout = dropout
+        self.finetune = finetune
+
+        self.projection = nn.Linear(self.hidden_size, self.n_out, False) if self.hidden_size != n_out else nn.Identity()
+
+    def __repr__(self):
+        s = f"{self.name}, n_out={self.n_out}"
+        if self.dropout > 0:
+            s += f", dropout={self.dropout}"
+        if self.finetune:
+            s += f", finetune={self.finetune}"
+        return f"{self.__class__.__name__}({s})"
+
+    def forward(self, chars: torch.LongTensor) -> torch.Tensor:
+        r"""
+        Args:
+            chars (~torch.LongTensor): ``[batch_size, seq_len, fix_len]``.
+
+        Returns:
+            ~torch.Tensor:
+                ELMo embeddings of shape ``[batch_size, seq_len, n_out]``.
+        """
+
+        x = self.projection(self.elmo(chars)['elmo_representations'][0])
+        if not self.bos_eos[0]:
+            x = x[:, 1:]
+        if not self.bos_eos[1]:
+            x = x[:, :-1]
+        return x
+
+
+class ScalarMix(nn.Module):
+    r"""
+    Computes a parameterized scalar mixture of :math:`N` tensors, :math:`mixture = \gamma * \sum_{k}(s_k * tensor_k)`
+    where :math:`s = \mathrm{softmax}(w)`, with :math:`w` and :math:`\gamma` scalar parameters.
+
+    Args:
+        n_layers (int):
+            The number of layers to be mixed, i.e., :math:`N`.
+        dropout (float):
+            The dropout ratio of the layer weights.
+            If dropout > 0, then for each scalar weight, adjusts its softmax weight mass to 0
+            with the dropout probability (i.e., setting the unnormalized weight to -inf).
+            This effectively redistributes the dropped probability mass to all other weights.
+            Default: 0.
+    """
+
+    def __init__(self, n_layers: int, dropout: float = .0) -> ScalarMix:
+        super().__init__()
+
+        self.n_layers = n_layers
+
+        self.weights = nn.Parameter(torch.zeros(n_layers))
+        self.gamma = nn.Parameter(torch.tensor([1.0]))
+        self.dropout = nn.Dropout(dropout)
+
+    def __repr__(self):
+        s = f"n_layers={self.n_layers}"
+        if self.dropout.p > 0:
+            s += f", dropout={self.dropout.p}"
+        return f"{self.__class__.__name__}({s})"
+
+    def forward(self, tensors: List[torch.Tensor]) -> torch.Tensor:
+        r"""
+        Args:
+            tensors (List[~torch.Tensor]):
+                :math:`N` tensors to be mixed.
+
+        Returns:
+            The mixture of :math:`N` tensors.
+        """
+
+        return self.gamma * sum(w * h for w, h in zip(self.dropout(self.weights.softmax(-1)), tensors))
diff --git a/tania_scripts/supar/modules/transformer.py b/tania_scripts/supar/modules/transformer.py
new file mode 100644
index 0000000..8e7c967
--- /dev/null
+++ b/tania_scripts/supar/modules/transformer.py
@@ -0,0 +1,585 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+import copy
+from typing import Optional
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+
+class TransformerWordEmbedding(nn.Module):
+
+    def __init__(
+        self,
+        n_vocab: int = None,
+        n_embed: int = None,
+        embed_scale: Optional[int] = None,
+        max_len: Optional[int] = 512,
+        pos: Optional[str] = None,
+        pad_index: Optional[int] = None,
+    ) -> TransformerWordEmbedding:
+        super(TransformerWordEmbedding, self).__init__()
+
+        self.embed = nn.Embedding(num_embeddings=n_vocab,
+                                  embedding_dim=n_embed)
+        if pos is None:
+            self.pos_embed = nn.Identity()
+        elif pos == 'sinusoid':
+            self.pos_embed = SinusoidPositionalEmbedding()
+        elif pos == 'sinusoid_relative':
+            self.pos_embed = SinusoidRelativePositionalEmbedding()
+        elif pos == 'learnable':
+            self.pos_embed = PositionalEmbedding(max_len=max_len)
+        elif pos == 'learnable_relative':
+            self.pos_embed = RelativePositionalEmbedding(max_len=max_len)
+        else:
+            raise ValueError(f'Unknown positional embedding type {pos}')
+
+        self.n_vocab = n_vocab
+        self.n_embed = n_embed
+        self.embed_scale = embed_scale or n_embed ** 0.5
+        self.max_len = max_len
+        self.pos = pos
+        self.pad_index = pad_index
+
+        self.reset_parameters()
+
+    def __repr__(self):
+        s = self.__class__.__name__ + '('
+        s += f"{self.n_vocab}, {self.n_embed}"
+        if self.embed_scale is not None:
+            s += f", embed_scale={self.embed_scale:.2f}"
+        if self.max_len is not None:
+            s += f", max_len={self.max_len}"
+        if self.pos is not None:
+            s += f", pos={self.pos}"
+        if self.pad_index is not None:
+            s += f", pad_index={self.pad_index}"
+        s += ')'
+        return s
+
+    def reset_parameters(self):
+        nn.init.normal_(self.embed.weight, 0, self.n_embed ** -0.5)
+        if self.pad_index is not None:
+            nn.init.zeros_(self.embed.weight[self.pad_index])
+
+    def forward(self, x: torch.Tensor) -> torch.Tensor:
+        x = self.embed(x)
+        if self.embed_scale:
+            x = x * self.embed_scale
+        if self.pos is not None:
+            x = x + self.pos_embed(x)
+        return x
+
+
+class TransformerEncoder(nn.Module):
+
+    def __init__(
+        self,
+        layer: nn.Module,
+        n_layers: int = 6,
+        n_model: int = 1024,
+        pre_norm: bool = False,
+    ) -> TransformerEncoder:
+        super(TransformerEncoder, self).__init__()
+
+        self.n_layers = n_layers
+        self.n_model = n_model
+        self.pre_norm = pre_norm
+
+        self.layers = nn.ModuleList([copy.deepcopy(layer) for _ in range(n_layers)])
+        self.norm = nn.LayerNorm(n_model) if self.pre_norm else None
+
+    def forward(self, x: torch.Tensor, mask: torch.BoolTensor) -> torch.Tensor:
+        x = x.transpose(0, 1)
+        for layer in self.layers:
+            x = layer(x, mask)
+        if self.pre_norm:
+            x = self.norm(x)
+        return x.transpose(0, 1)
+
+
+class TransformerDecoder(nn.Module):
+
+    def __init__(
+        self,
+        layer: nn.Module,
+        n_layers: int = 6,
+        n_model: int = 1024,
+        pre_norm: bool = False,
+    ) -> TransformerDecoder:
+        super(TransformerDecoder, self).__init__()
+
+        self.n_layers = n_layers
+        self.n_model = n_model
+        self.pre_norm = pre_norm
+
+        self.layers = nn.ModuleList([copy.deepcopy(layer) for _ in range(n_layers)])
+        self.norm = nn.LayerNorm(n_model) if self.pre_norm else None
+
+    def forward(
+        self,
+        x_tgt: torch.Tensor,
+        x_src: torch.Tensor,
+        tgt_mask: torch.BoolTensor,
+        src_mask: torch.BoolTensor,
+        attn_mask: Optional[torch.BoolTensor] = None
+    ) -> torch.Tensor:
+        x_tgt, x_src = x_tgt.transpose(0, 1), x_src.transpose(0, 1)
+        for layer in self.layers:
+            x_tgt = layer(x_tgt=x_tgt,
+                          x_src=x_src,
+                          tgt_mask=tgt_mask,
+                          src_mask=src_mask,
+                          attn_mask=attn_mask)
+        if self.pre_norm:
+            x_tgt = self.norm(x_tgt)
+        return x_tgt.transpose(0, 1)
+
+
+class TransformerEncoderLayer(nn.Module):
+
+    def __init__(
+        self,
+        n_heads: int = 8,
+        n_model: int = 1024,
+        n_inner: int = 2048,
+        activation: str = 'relu',
+        bias: bool = True,
+        pre_norm: bool = False,
+        attn_dropout: float = 0.1,
+        ffn_dropout: float = 0.1,
+        dropout: float = 0.1
+    ) -> TransformerEncoderLayer:
+        super(TransformerEncoderLayer, self).__init__()
+
+        self.attn = MultiHeadAttention(n_heads=n_heads,
+                                       n_model=n_model,
+                                       n_embed=n_model//n_heads,
+                                       dropout=attn_dropout,
+                                       bias=bias)
+        self.attn_norm = nn.LayerNorm(n_model)
+        self.ffn = PositionwiseFeedForward(n_model=n_model,
+                                           n_inner=n_inner,
+                                           activation=activation,
+                                           dropout=ffn_dropout)
+        self.ffn_norm = nn.LayerNorm(n_model)
+        self.dropout = nn.Dropout(dropout)
+
+        self.pre_norm = pre_norm
+
+    def forward(self, x: torch.Tensor, mask: torch.BoolTensor) -> torch.Tensor:
+        if self.pre_norm:
+            n = self.attn_norm(x)
+            x = x + self.dropout(self.attn(n, n, n, mask))
+            n = self.ffn_norm(x)
+            x = x + self.dropout(self.ffn(n))
+        else:
+            x = self.attn_norm(x + self.dropout(self.attn(x, x, x, mask)))
+            x = self.ffn_norm(x + self.dropout(self.ffn(x)))
+        return x
+
+
+class RelativePositionTransformerEncoderLayer(nn.Module):
+
+    def __init__(
+        self,
+        n_heads: int = 8,
+        n_model: int = 1024,
+        n_inner: int = 2048,
+        activation: str = 'relu',
+        pre_norm: bool = False,
+        attn_dropout: float = 0.1,
+        ffn_dropout: float = 0.1,
+        dropout: float = 0.1
+    ) -> RelativePositionTransformerEncoderLayer:
+        super(RelativePositionTransformerEncoderLayer, self).__init__()
+
+        self.attn = RelativePositionMultiHeadAttention(n_heads=n_heads,
+                                                       n_model=n_model,
+                                                       n_embed=n_model//n_heads,
+                                                       dropout=attn_dropout)
+        self.attn_norm = nn.LayerNorm(n_model)
+        self.ffn = PositionwiseFeedForward(n_model=n_model,
+                                           n_inner=n_inner,
+                                           activation=activation,
+                                           dropout=ffn_dropout)
+        self.ffn_norm = nn.LayerNorm(n_model)
+        self.dropout = nn.Dropout(dropout)
+
+        self.pre_norm = pre_norm
+
+    def forward(self, x: torch.Tensor, mask: torch.BoolTensor) -> torch.Tensor:
+        if self.pre_norm:
+            n = self.attn_norm(x)
+            x = x + self.dropout(self.attn(n, n, n, mask))
+            n = self.ffn_norm(x)
+            x = x + self.dropout(self.ffn(n))
+        else:
+            x = self.attn_norm(x + self.dropout(self.attn(x, x, x, mask)))
+            x = self.ffn_norm(x + self.dropout(self.ffn(x)))
+        return x
+
+
+class TransformerDecoderLayer(nn.Module):
+
+    def __init__(
+        self,
+        n_heads: int = 8,
+        n_model: int = 1024,
+        n_inner: int = 2048,
+        activation: str = 'relu',
+        bias: bool = True,
+        pre_norm: bool = False,
+        attn_dropout: float = 0.1,
+        ffn_dropout: float = 0.1,
+        dropout: float = 0.1
+    ) -> TransformerDecoderLayer:
+        super(TransformerDecoderLayer, self).__init__()
+
+        self.self_attn = MultiHeadAttention(n_heads=n_heads,
+                                            n_model=n_model,
+                                            n_embed=n_model//n_heads,
+                                            dropout=attn_dropout,
+                                            bias=bias)
+        self.self_attn_norm = nn.LayerNorm(n_model)
+        self.mha_attn = MultiHeadAttention(n_heads=n_heads,
+                                           n_model=n_model,
+                                           n_embed=n_model//n_heads,
+                                           dropout=attn_dropout,
+                                           bias=bias)
+        self.mha_attn_norm = nn.LayerNorm(n_model)
+        self.ffn = PositionwiseFeedForward(n_model=n_model,
+                                           n_inner=n_inner,
+                                           activation=activation,
+                                           dropout=ffn_dropout)
+        self.ffn_norm = nn.LayerNorm(n_model)
+        self.dropout = nn.Dropout(dropout)
+
+        self.pre_norm = pre_norm
+
+    def forward(
+        self,
+        x_tgt: torch.Tensor,
+        x_src: torch.Tensor,
+        tgt_mask: torch.BoolTensor,
+        src_mask: torch.BoolTensor,
+        attn_mask: Optional[torch.BoolTensor] = None
+    ) -> torch.Tensor:
+        if self.pre_norm:
+            n_tgt = self.self_attn_norm(x_tgt)
+            x_tgt = x_tgt + self.dropout(self.self_attn(n_tgt, n_tgt, n_tgt, tgt_mask, attn_mask))
+            n_tgt = self.mha_attn_norm(x_tgt)
+            x_tgt = x_tgt + self.dropout(self.mha_attn(n_tgt, x_src, x_src, src_mask))
+            n_tgt = self.ffn_norm(x_tgt)
+            x_tgt = x_tgt + self.dropout(self.ffn(x_tgt))
+        else:
+            x_tgt = self.self_attn_norm(x_tgt + self.dropout(self.self_attn(x_tgt, x_tgt, x_tgt, tgt_mask, attn_mask)))
+            x_tgt = self.mha_attn_norm(x_tgt + self.dropout(self.mha_attn(x_tgt, x_src, x_src, src_mask)))
+            x_tgt = self.ffn_norm(x_tgt + self.dropout(self.ffn(x_tgt)))
+        return x_tgt
+
+
+class RelativePositionTransformerDecoderLayer(nn.Module):
+
+    def __init__(
+        self,
+        n_heads: int = 8,
+        n_model: int = 1024,
+        n_inner: int = 2048,
+        activation: str = 'relu',
+        pre_norm: bool = False,
+        attn_dropout: float = 0.1,
+        ffn_dropout: float = 0.1,
+        dropout: float = 0.1
+    ) -> RelativePositionTransformerDecoderLayer:
+        super(RelativePositionTransformerDecoderLayer, self).__init__()
+
+        self.self_attn = RelativePositionMultiHeadAttention(n_heads=n_heads,
+                                                            n_model=n_model,
+                                                            n_embed=n_model//n_heads,
+                                                            dropout=attn_dropout)
+        self.self_attn_norm = nn.LayerNorm(n_model)
+        self.mha_attn = RelativePositionMultiHeadAttention(n_heads=n_heads,
+                                                           n_model=n_model,
+                                                           n_embed=n_model//n_heads,
+                                                           dropout=attn_dropout)
+        self.mha_attn_norm = nn.LayerNorm(n_model)
+        self.ffn = PositionwiseFeedForward(n_model=n_model,
+                                           n_inner=n_inner,
+                                           activation=activation,
+                                           dropout=ffn_dropout)
+        self.ffn_norm = nn.LayerNorm(n_model)
+        self.dropout = nn.Dropout(dropout)
+
+        self.pre_norm = pre_norm
+
+    def forward(
+        self,
+        x_tgt: torch.Tensor,
+        x_src: torch.Tensor,
+        tgt_mask: torch.BoolTensor,
+        src_mask: torch.BoolTensor,
+        attn_mask: Optional[torch.BoolTensor] = None
+    ) -> torch.Tensor:
+        if self.pre_norm:
+            n_tgt = self.self_attn_norm(x_tgt)
+            x_tgt = x_tgt + self.dropout(self.self_attn(n_tgt, n_tgt, n_tgt, tgt_mask, attn_mask))
+            n_tgt = self.mha_attn_norm(x_tgt)
+            x_tgt = x_tgt + self.dropout(self.mha_attn(n_tgt, x_src, x_src, src_mask))
+            n_tgt = self.ffn_norm(x_tgt)
+            x_tgt = x_tgt + self.dropout(self.ffn(x_tgt))
+        else:
+            x_tgt = self.self_attn_norm(x_tgt + self.dropout(self.self_attn(x_tgt, x_tgt, x_tgt, tgt_mask, attn_mask)))
+            x_tgt = self.mha_attn_norm(x_tgt + self.dropout(self.mha_attn(x_tgt, x_src, x_src, src_mask)))
+            x_tgt = self.ffn_norm(x_tgt + self.dropout(self.ffn(x_tgt)))
+        return x_tgt
+
+
+class MultiHeadAttention(nn.Module):
+
+    def __init__(
+        self,
+        n_heads: int = 8,
+        n_model: int = 1024,
+        n_embed: int = 128,
+        dropout: float = 0.1,
+        bias: bool = True,
+        attn: bool = False,
+    ) -> MultiHeadAttention:
+        super(MultiHeadAttention, self).__init__()
+
+        self.n_heads = n_heads
+        self.n_model = n_model
+        self.n_embed = n_embed
+        self.scale = n_embed**0.5
+
+        self.wq = nn.Linear(n_model, n_heads * n_embed, bias=bias)
+        self.wk = nn.Linear(n_model, n_heads * n_embed, bias=bias)
+        self.wv = nn.Linear(n_model, n_heads * n_embed, bias=bias)
+        self.wo = nn.Linear(n_heads * n_embed, n_model, bias=bias)
+        self.dropout = nn.Dropout(dropout)
+
+        self.bias = bias
+        self.attn = attn
+
+        self.reset_parameters()
+
+    def reset_parameters(self):
+        # borrowed from https://github.com/facebookresearch/fairseq/blob/main/fairseq/modules/multihead_attention.py
+        nn.init.xavier_uniform_(self.wq.weight, 2 ** -0.5)
+        nn.init.xavier_uniform_(self.wk.weight, 2 ** -0.5)
+        nn.init.xavier_uniform_(self.wv.weight, 2 ** -0.5)
+        nn.init.xavier_uniform_(self.wo.weight)
+
+    def forward(
+        self,
+        q: torch.Tensor,
+        k: torch.Tensor,
+        v: torch.Tensor,
+        mask: torch.BoolTensor,
+        attn_mask: Optional[torch.BoolTensor] = None
+    ) -> torch.Tensor:
+        batch_size, _ = mask.shape
+        # [seq_len, batch_size * n_heads, n_embed]
+        q = self.wq(q).view(-1, batch_size * self.n_heads, self.n_embed)
+        # [src_len, batch_size * n_heads, n_embed]
+        k = self.wk(k).view(-1, batch_size * self.n_heads, self.n_embed)
+        v = self.wv(v).view(-1, batch_size * self.n_heads, self.n_embed)
+
+        mask = mask.unsqueeze(1).repeat(1, self.n_heads, 1).view(-1, 1, *mask.shape[1:])
+        # [batch_size * n_heads, seq_len, src_len]
+        if attn_mask is not None:
+            mask = mask & attn_mask
+        # [batch_size * n_heads, seq_len, src_len]
+        attn = torch.bmm(q.transpose(0, 1) / self.scale, k.movedim((0, 1), (2, 0)))
+        attn = torch.softmax(attn + torch.where(mask, 0., float('-inf')), -1)
+        attn = self.dropout(attn)
+        # [seq_len, batch_size * n_heads, n_embed]
+        x = torch.bmm(attn, v.transpose(0, 1)).transpose(0, 1)
+        # [seq_len, batch_size, n_model]
+        x = self.wo(x.reshape(-1, batch_size, self.n_heads * self.n_embed))
+
+        return (x, attn.view(batch_size, self.n_heads, *attn.shape[1:])) if self.attn else x
+
+
+class RelativePositionMultiHeadAttention(nn.Module):
+
+    def __init__(
+        self,
+        n_heads: int = 8,
+        n_model: int = 1024,
+        n_embed: int = 128,
+        dropout: float = 0.1,
+        attn: bool = False
+    ) -> RelativePositionMultiHeadAttention:
+        super(RelativePositionMultiHeadAttention, self).__init__()
+
+        self.n_heads = n_heads
+        self.n_model = n_model
+        self.n_embed = n_embed
+        self.scale = n_embed**0.5
+
+        self.pos_embed = RelativePositionalEmbedding(n_model=n_embed)
+        self.wq = nn.Parameter(torch.zeros(n_model, n_heads * n_embed))
+        self.wk = nn.Parameter(torch.zeros(n_model, n_heads * n_embed))
+        self.wv = nn.Parameter(torch.zeros(n_model, n_heads * n_embed))
+        self.wo = nn.Parameter(torch.zeros(n_heads * n_embed, n_model))
+        self.bu = nn.Parameter(torch.zeros(n_heads, n_embed))
+        self.bv = nn.Parameter(torch.zeros(n_heads, n_embed))
+        self.dropout = nn.Dropout(dropout)
+
+        self.attn = attn
+
+        self.reset_parameters()
+
+    def reset_parameters(self):
+        # borrowed from https://github.com/facebookresearch/fairseq/blob/main/fairseq/modules/multihead_attention.py
+        nn.init.xavier_uniform_(self.wq, 2 ** -0.5)
+        nn.init.xavier_uniform_(self.wk, 2 ** -0.5)
+        nn.init.xavier_uniform_(self.wv, 2 ** -0.5)
+        nn.init.xavier_uniform_(self.wo)
+
+    def forward(
+        self,
+        q: torch.Tensor,
+        k: torch.Tensor,
+        v: torch.Tensor,
+        mask: torch.BoolTensor,
+        attn_mask: Optional[torch.BoolTensor] = None
+    ) -> torch.Tensor:
+        batch_size, _ = mask.shape
+        # [seq_len, batch_size, n_heads, n_embed]
+        q = F.linear(q, self.wq).view(-1, batch_size, self.n_heads, self.n_embed)
+        # [src_len, batch_size * n_heads, n_embed]
+        k = F.linear(k, self.wk).view(-1, batch_size * self.n_heads, self.n_embed)
+        v = F.linear(v, self.wv).view(-1, batch_size * self.n_heads, self.n_embed)
+        # [seq_len, src_len, n_embed]
+        p = self.pos_embed(q[:, 0, 0], k[:, 0])
+        # [seq_len, batch_size * n_heads, n_embed]
+        qu, qv = (q + self.bu).view(-1, *k.shape[1:]), (q + self.bv).view(-1, *k.shape[1:])
+
+        mask = mask.unsqueeze(1).repeat(1, self.n_heads, 1).view(-1, 1, *mask.shape[1:])
+        if attn_mask is not None:
+            mask = mask & attn_mask
+        # [batch_size * n_heads, seq_len, src_len]
+        attn = torch.bmm(qu.transpose(0, 1), k.movedim((0, 1), (2, 0)))
+        attn = attn + torch.matmul(qv.transpose(0, 1).unsqueeze(2), p.transpose(1, 2)).squeeze(2)
+        attn = torch.softmax(attn / self.scale + torch.where(mask, 0., float('-inf')), -1)
+        attn = self.dropout(attn)
+        # [seq_len, batch_size * n_heads, n_embed]
+        x = torch.bmm(attn, v.transpose(0, 1)).transpose(0, 1)
+        # [seq_len, batch_size, n_model]
+        x = F.linear(x.reshape(-1, batch_size, self.n_heads * self.n_embed), self.wo)
+
+        return (x, attn.view(batch_size, self.n_heads, *attn.shape[1:])) if self.attn else x
+
+
+class PositionwiseFeedForward(nn.Module):
+
+    def __init__(
+        self,
+        n_model: int = 1024,
+        n_inner: int = 2048,
+        activation: str = 'relu',
+        dropout: float = 0.1
+    ) -> PositionwiseFeedForward:
+        super(PositionwiseFeedForward, self).__init__()
+
+        self.w1 = nn.Linear(n_model, n_inner)
+        self.activation = nn.ReLU() if activation == 'relu' else nn.GELU()
+        self.dropout = nn.Dropout(dropout)
+        self.w2 = nn.Linear(n_inner, n_model)
+
+        self.reset_parameters()
+
+    def reset_parameters(self):
+        nn.init.xavier_uniform_(self.w1.weight)
+        nn.init.xavier_uniform_(self.w2.weight)
+        nn.init.zeros_(self.w1.bias)
+        nn.init.zeros_(self.w2.bias)
+
+    def forward(self, x):
+        x = self.w1(x)
+        x = self.activation(x)
+        x = self.dropout(x)
+        x = self.w2(x)
+
+        return x
+
+
+class PositionalEmbedding(nn.Module):
+
+    def __init__(
+        self,
+        n_model: int = 1024,
+        max_len: int = 1024
+    ) -> PositionalEmbedding:
+        super().__init__()
+
+        self.embed = nn.Embedding(max_len, n_model)
+
+        self.reset_parameters()
+
+    @torch.no_grad()
+    def reset_parameters(self):
+        w = self.embed.weight
+        max_len, n_model = w.shape
+        w = w.new_tensor(range(max_len)).unsqueeze(-1)
+        w = w / 10000 ** (w.new_tensor(range(n_model)).div(2, rounding_mode='floor') * 2 / n_model)
+        w[:, 0::2], w[:, 1::2] = w[:, 0::2].sin(), w[:, 1::2].cos()
+        self.embed.weight.copy_(w)
+
+    def forward(self, x: torch.Tensor) -> torch.Tensor:
+        return self.embed(x.new_tensor(range(x.shape[1])).long())
+
+
+class RelativePositionalEmbedding(nn.Module):
+
+    def __init__(
+        self,
+        n_model: int = 1024,
+        max_len: int = 1024
+    ) -> RelativePositionalEmbedding:
+        super().__init__()
+
+        self.embed = nn.Embedding(max_len, n_model)
+
+        self.reset_parameters()
+
+    @torch.no_grad()
+    def reset_parameters(self):
+        w = self.embed.weight
+        max_len, n_model = w.shape
+        pos = torch.cat((w.new_tensor(range(-max_len//2, 0)), w.new_tensor(range(max_len//2))))
+        w = pos.unsqueeze(-1) / 10000 ** (w.new_tensor(range(n_model)).div(2, rounding_mode='floor') * 2 / n_model)
+        w[:, 0::2], w[:, 1::2] = w[:, 0::2].sin(), w[:, 1::2].cos()
+        self.embed.weight.copy_(w)
+
+    def forward(self, q: torch.Tensor, k: torch.Tensor) -> torch.Tensor:
+        offset = sum(divmod(self.embed.weight.shape[0], 2))
+        return self.embed((k.new_tensor(range(k.shape[0])) - q.new_tensor(range(q.shape[0])).unsqueeze(-1)).long() + offset)
+
+
+class SinusoidPositionalEmbedding(nn.Module):
+
+    def forward(self, x: torch.Tensor) -> torch.Tensor:
+        seq_len, n_model = x[0].shape
+        pos = x.new_tensor(range(seq_len)).unsqueeze(-1)
+        pos = pos / 10000 ** (x.new_tensor(range(n_model)).div(2, rounding_mode='floor') * 2 / n_model)
+        pos[:, 0::2], pos[:, 1::2] = pos[:, 0::2].sin(), pos[:, 1::2].cos()
+        return pos
+
+
+class SinusoidRelativePositionalEmbedding(nn.Module):
+
+    def forward(self, x: torch.Tensor) -> torch.Tensor:
+        seq_len, n_model = x[0].shape
+        pos = x.new_tensor(range(seq_len))
+        pos = (pos - pos.unsqueeze(-1)).unsqueeze(-1)
+        pos = pos / 10000 ** (x.new_tensor(range(n_model)).div(2, rounding_mode='floor') * 2 / n_model)
+        pos[..., 0::2], pos[..., 1::2] = pos[..., 0::2].sin(), pos[..., 1::2].cos()
+        return pos
diff --git a/tania_scripts/supar/parser.py b/tania_scripts/supar/parser.py
new file mode 100644
index 0000000..f1c372e
--- /dev/null
+++ b/tania_scripts/supar/parser.py
@@ -0,0 +1,620 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+import contextlib
+import os
+import shutil
+import sys
+import tempfile
+import pickle
+from contextlib import contextmanager
+from datetime import datetime, timedelta
+from typing import Any, Iterable, Union
+
+import dill
+import torch
+import torch.distributed as dist
+import torch.nn as nn
+from torch.cuda.amp import GradScaler
+from torch.optim import Adam, Optimizer
+from torch.optim.lr_scheduler import ExponentialLR, _LRScheduler
+
+import supar
+from supar.utils import Config, Dataset
+from supar.utils.field import Field
+from supar.utils.fn import download, get_rng_state, set_rng_state
+from supar.utils.logging import get_logger, init_logger, progress_bar
+from supar.utils.metric import Metric
+from supar.utils.optim import InverseSquareRootLR, LinearLR
+from supar.utils.parallel import DistributedDataParallel as DDP
+from supar.utils.parallel import gather, is_dist, is_master, reduce
+from supar.utils.transform import Batch
+
+logger = get_logger(__name__)
+
+
+class Parser(object):
+
+    NAME = None
+    MODEL = None
+
+    def __init__(self, args, model, transform):
+        self.args = args
+        self.model = model
+        self.transform = transform
+
+    @property
+    def device(self):
+        return 'cuda' if torch.cuda.is_available() else 'cpu'
+
+    @property
+    def sync_grad(self):
+        return self.step % self.args.update_steps == 0 or self.step % self.n_batches == 0
+
+    @contextmanager
+    def sync(self):
+        context = getattr(contextlib, 'suppress' if sys.version < '3.7' else 'nullcontext')
+        if is_dist() and not self.sync_grad:
+            context = self.model.no_sync
+        with context():
+            yield
+
+    @contextmanager
+    def join(self):
+        context = getattr(contextlib, 'suppress' if sys.version < '3.7' else 'nullcontext')
+        if not is_dist():
+            with context():
+                yield
+        elif self.model.training:
+            with self.model.join():
+                yield
+        else:
+            try:
+                dist_model = self.model
+                # https://github.com/pytorch/pytorch/issues/54059
+                if hasattr(self.model, 'module'):
+                    self.model = self.model.module
+                yield
+            finally:
+                self.model = dist_model
+
+    def train(
+        self,
+        train: Union[str, Iterable],
+        dev: Union[str, Iterable],
+        test: Union[str, Iterable],
+        epochs: int,
+        patience: int,
+        batch_size: int = 5000,
+        update_steps: int = 1,
+        buckets: int = 32,
+        workers: int = 0,
+        clip: float = 5.0,
+        amp: bool = False,
+        cache: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ) -> None:
+        r"""
+        Args:
+            train/dev/test (Union[str, Iterable]):
+                Filenames of the train/dev/test datasets.
+            epochs (int):
+                The number of training iterations.
+            patience (int):
+                The number of consecutive iterations after which the training process would be early stopped if no improvement.
+            batch_size (int):
+                The number of tokens in each batch. Default: 5000.
+            update_steps (int):
+                Gradient accumulation steps. Default: 1.
+            buckets (int):
+                The number of buckets that sentences are assigned to. Default: 32.
+            workers (int):
+                The number of subprocesses used for data loading. 0 means only the main process. Default: 0.
+            clip (float):
+                Clips gradient of an iterable of parameters at specified value. Default: 5.0.
+            amp (bool):
+                Specifies whether to use automatic mixed precision. Default: ``False``.
+            cache (bool):
+                If ``True``, caches the data first, suggested for huge files (e.g., > 1M sentences). Default: ``False``.
+            verbose (bool):
+                If ``True``, increases the output verbosity. Default: ``True``.
+        """
+
+        args = self.args.update(locals())
+        init_logger(logger, verbose=args.verbose)
+
+        self.transform.train()
+        batch_size = batch_size // update_steps
+        eval_batch_size = args.get('eval_batch_size', batch_size)
+        if is_dist():
+            batch_size = batch_size // dist.get_world_size()
+            eval_batch_size = eval_batch_size // dist.get_world_size()
+        logger.info("Loading the data")
+        if args.cache:
+            args.bin = os.path.join(os.path.dirname(args.path), 'bin')
+        args.even = args.get('even', is_dist())
+        
+        train = Dataset(self.transform, args.train, **args).build(batch_size=batch_size,
+                                                                  n_buckets=buckets,
+                                                                  shuffle=True,
+                                                                  distributed=is_dist(),
+                                                                  even=args.even,
+                                                                  n_workers=workers)
+        dev = Dataset(self.transform, args.dev, **args).build(batch_size=eval_batch_size,
+                                                              n_buckets=buckets,
+                                                              shuffle=False,
+                                                              distributed=is_dist(),
+                                                              even=False,
+                                                              n_workers=workers)
+        logger.info(f"{'train:':6} {train}")
+        if not args.test:
+            logger.info(f"{'dev:':6} {dev}\n")
+        else:
+            test = Dataset(self.transform, args.test, **args).build(batch_size=eval_batch_size,
+                                                                    n_buckets=buckets,
+                                                                    shuffle=False,
+                                                                    distributed=is_dist(),
+                                                                    even=False,
+                                                                    n_workers=workers)
+            logger.info(f"{'dev:':6} {dev}")
+            logger.info(f"{'test:':6} {test}\n")
+        loader, sampler = train.loader, train.loader.batch_sampler
+        args.steps = len(loader) * epochs // args.update_steps
+        args.save(f"{args.path}.yaml")
+
+        self.optimizer = self.init_optimizer()
+        self.scheduler = self.init_scheduler()
+        self.scaler = GradScaler(enabled=args.amp)
+
+        if dist.is_initialized():
+            self.model = DDP(module=self.model,
+                             device_ids=[args.local_rank],
+                             find_unused_parameters=args.get('find_unused_parameters', True),
+                             static_graph=args.get('static_graph', False))
+            if args.amp:
+                from torch.distributed.algorithms.ddp_comm_hooks.default_hooks import fp16_compress_hook
+                self.model.register_comm_hook(dist.group.WORLD, fp16_compress_hook)
+        if args.wandb and is_master():
+            import wandb
+            # start a new wandb run to track this script
+            wandb.init(config=args.primitive_config,
+                       project=args.get('project', self.NAME),
+                       name=args.get('name', args.path),
+                       resume=self.args.checkpoint)
+        self.step, self.epoch, self.best_e, self.patience = 1, 1, 1, patience
+        # uneven batches are excluded
+        self.n_batches = min(gather(len(loader))) if is_dist() else len(loader)
+        self.best_metric, self.elapsed = Metric(), timedelta()
+        if args.checkpoint:
+            try:
+                self.optimizer.load_state_dict(self.checkpoint_state_dict.pop('optimizer_state_dict'))
+                self.scheduler.load_state_dict(self.checkpoint_state_dict.pop('scheduler_state_dict'))
+                self.scaler.load_state_dict(self.checkpoint_state_dict.pop('scaler_state_dict'))
+                set_rng_state(self.checkpoint_state_dict.pop('rng_state'))
+                for k, v in self.checkpoint_state_dict.items():
+                    setattr(self, k, v)
+                sampler.set_epoch(self.epoch)
+            except AttributeError:
+                logger.warning("No checkpoint found. Try re-launching the training procedure instead")
+
+        for epoch in range(self.epoch, args.epochs + 1):
+            start = datetime.now()
+            bar, metric = progress_bar(loader), Metric()
+
+            logger.info(f"Epoch {epoch} / {args.epochs}:")
+            self.model.train()
+            with self.join():
+                # we should reset `step` as the number of batches in different processes is not necessarily equal
+                self.step = 1
+                for batch in bar:
+                    with self.sync():
+                        with torch.autocast(self.device, enabled=args.amp):
+                            loss = self.train_step(batch)
+                        self.backward(loss)
+                    if self.sync_grad:
+                        self.clip_grad_norm_(self.model.parameters(), args.clip)
+                        self.scaler.step(self.optimizer)
+                        self.scaler.update()
+                        self.scheduler.step()
+                        self.optimizer.zero_grad(True)
+
+                    bar.set_postfix_str(f"lr: {self.scheduler.get_last_lr()[0]:.4e} - loss: {loss:.4f}")
+                    # log metrics to wandb
+                    if args.wandb and is_master():
+                        wandb.log({'lr': self.scheduler.get_last_lr()[0], 'loss': loss})
+                    self.step += 1
+                logger.info(f"{bar.postfix}")
+            self.model.eval()
+            with self.join(), torch.autocast(self.device, enabled=args.amp):
+                metric = self.reduce(sum([self.eval_step(i) for i in progress_bar(dev.loader)], Metric()))
+                logger.info(f"{'dev:':5} {metric}")
+                if args.wandb and is_master():
+                    wandb.log({'dev': metric.values, 'epochs': epoch})
+                if args.test:
+                    test_metric = sum([self.eval_step(i) for i in progress_bar(test.loader)], Metric())
+                    logger.info(f"{'test:':5} {self.reduce(test_metric)}")
+                    if args.wandb and is_master():
+                        wandb.log({'test': test_metric.values, 'epochs': epoch})
+
+            t = datetime.now() - start
+            self.epoch += 1
+            self.patience -= 1
+            self.elapsed += t
+
+            if metric > self.best_metric:
+                self.best_e, self.patience, self.best_metric = epoch, patience, metric
+                if is_master():
+                    self.save_checkpoint(args.path)
+                logger.info(f"{t}s elapsed (saved)\n")
+            else:
+                logger.info(f"{t}s elapsed\n")
+            if self.patience < 1:
+                break
+        if is_dist():
+            dist.barrier()
+
+        best = self.load(**args)
+        # only allow the master device to save models
+        if is_master():
+            best.save(args.path)
+
+        logger.info(f"Epoch {self.best_e} saved")
+        logger.info(f"{'dev:':5} {self.best_metric}")
+        if args.test:
+            best.model.eval()
+            with best.join():
+                test_metric = sum([best.eval_step(i) for i in progress_bar(test.loader)], Metric())
+                logger.info(f"{'test:':5} {best.reduce(test_metric)}")
+        logger.info(f"{self.elapsed}s elapsed, {self.elapsed / epoch}s/epoch")
+        if args.wandb and is_master():
+            wandb.finish()
+
+        self.evaluate(data=args.test, batch_size=batch_size)
+        self.predict(args.test, batch_size=batch_size, buckets=buckets, workers=workers)
+
+        with open(f'{self.args.folder}/status', 'w') as file:
+            file.write('finished')
+
+
+
+    def evaluate(
+        self,
+        data: Union[str, Iterable],
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        amp: bool = False,
+        cache: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        r"""
+        Args:
+            data (Union[str, Iterable]):
+                The data for evaluation. Both a filename and a list of instances are allowed.
+            batch_size (int):
+                The number of tokens in each batch. Default: 5000.
+            buckets (int):
+                The number of buckets that sentences are assigned to. Default: 8.
+            workers (int):
+                The number of subprocesses used for data loading. 0 means only the main process. Default: 0.
+            amp (bool):
+                Specifies whether to use automatic mixed precision. Default: ``False``.
+            cache (bool):
+                If ``True``, caches the data first, suggested for huge files (e.g., > 1M sentences). Default: ``False``.
+            verbose (bool):
+                If ``True``, increases the output verbosity. Default: ``True``.
+
+        Returns:
+            The evaluation results.
+        """
+
+        args = self.args.update(locals())
+        init_logger(logger, verbose=args.verbose)
+
+        self.transform.train()
+        logger.info("Loading the data")
+        if args.cache:
+            args.bin = os.path.join(os.path.dirname(args.path), 'bin')
+        if is_dist():
+            batch_size = batch_size // dist.get_world_size()
+        data = Dataset(self.transform, **args)
+        data.build(batch_size=batch_size,
+                   n_buckets=buckets,
+                   shuffle=False,
+                   distributed=is_dist(),
+                   even=False,
+                   n_workers=workers)
+        logger.info(f"\n{data}")
+
+        logger.info("Evaluating the data")
+        start = datetime.now()
+        self.model.eval()
+        with self.join():
+            bar, metric = progress_bar(data.loader), Metric()
+            for batch in bar:
+                metric += self.eval_step(batch)
+                bar.set_postfix_str(metric)
+            metric = self.reduce(metric)
+        elapsed = datetime.now() - start
+        logger.info(f"{metric}")
+        logger.info(f"{elapsed}s elapsed, "
+                    f"{sum(data.sizes)/elapsed.total_seconds():.2f} Tokens/s, "
+                    f"{len(data)/elapsed.total_seconds():.2f} Sents/s")
+        os.makedirs(os.path.dirname(self.args.folder + '/metrics.pickle'), exist_ok=True)
+        with open(f'{self.args.folder}/metrics.pickle', 'wb') as file:
+            pickle.dump(obj=metric, file=file)
+
+        return metric
+
+    def predict(
+        self,
+        data: Union[str, Iterable],
+        pred: str = None,
+        lang: str = None,
+        prob: bool = False,
+        batch_size: int = 5000,
+        buckets: int = 8,
+        workers: int = 0,
+        cache: bool = False,
+        verbose: bool = True,
+        **kwargs
+    ):
+        r"""
+        Args:
+            data (Union[str, Iterable]):
+                The data for prediction.
+                - a filename. If ends with `.txt`, the parser will seek to make predictions line by line from plain texts.
+                - a list of instances.
+            pred (str):
+                If specified, the predicted results will be saved to the file. Default: ``None``.
+            lang (str):
+                Language code (e.g., ``en``) or language name (e.g., ``English``) for the text to tokenize.
+                ``None`` if tokenization is not required.
+                Default: ``None``.
+            prob (bool):
+                If ``True``, outputs the probabilities. Default: ``False``.
+            batch_size (int):
+                The number of tokens in each batch. Default: 5000.
+            buckets (int):
+                The number of buckets that sentences are assigned to. Default: 8.
+            workers (int):
+                The number of subprocesses used for data loading. 0 means only the main process. Default: 0.
+            amp (bool):
+                Specifies whether to use automatic mixed precision. Default: ``False``.
+            cache (bool):
+                If ``True``, caches the data first, suggested for huge files (e.g., > 1M sentences). Default: ``False``.
+            verbose (bool):
+                If ``True``, increases the output verbosity. Default: ``True``.
+
+        Returns:
+            A :class:`~supar.utils.Dataset` object containing all predictions if ``cache=False``, otherwise ``None``.
+        """
+
+        args = self.args.update(locals())
+        init_logger(logger, verbose=args.verbose)
+
+        if self.args.use_vq:
+            self.model.passes_remaining = 0
+            self.model.vq.observe_steps_remaining = 0
+
+        self.transform.eval()
+        if args.prob:
+            self.transform.append(Field('probs'))
+
+        #logger.info("Loading the data")
+        if args.cache:
+            args.bin = os.path.join(os.path.dirname(args.path), 'bin')
+        if is_dist():
+            batch_size = batch_size // dist.get_world_size()
+        data = Dataset(self.transform, **args)
+        data.build(batch_size=batch_size,
+                   n_buckets=buckets,
+                   shuffle=False,
+                   distributed=is_dist(),
+                   even=False,
+                   n_workers=workers)
+
+        #logger.info(f"\n{data}")
+
+        #logger.info("Making predictions on the data")
+        start = datetime.now()
+        self.model.eval()
+        #with tempfile.TemporaryDirectory() as t:
+            # we have clustered the sentences by length here to speed up prediction,
+            # so the order of the yielded sentences can't be guaranteed
+        for batch in progress_bar(data.loader):
+            #batch, head_preds, deprel_preds, stack_list, buffer_list, actions_list, act_dict_list, deprel_preds_decoded, pos_preds_decoded, sent_text, act_dict = self.pred_step(batch)
+            *predicted_values, = self.pred_step(batch)
+            #print('429 supar/parser.py ', batch.sentences)
+            #print(head_preds, deprel_preds, stack_list, act_dict_list, deprel_preds_decoded, pos_preds_decoded, sent_text)
+            #logger.info(f"Saving predicted results to {pred}")
+           # with open(pred, 'w') as f:
+                    
+
+            elapsed = datetime.now() - start
+
+            #if is_dist():
+            #    dist.barrier()
+            #tdirs = gather(t) if is_dist() else (t,)
+            #if pred is not None and is_master():
+                #logger.info(f"Saving predicted results to {pred}")
+            """with open(pred, 'w') as f:
+                    # merge all predictions into one single file
+                    if is_dist() or args.cache:
+                        sentences = (os.path.join(i, s) for i in tdirs for s in os.listdir(i))
+                        for i in progress_bar(sorted(sentences, key=lambda x: int(os.path.basename(x)))):
+                            with open(i) as s:
+                                shutil.copyfileobj(s, f)
+                    else:
+                        for s in progress_bar(data):
+                            f.write(str(s) + '\n')"""
+            # exit util all files have been merged
+            if is_dist():
+                dist.barrier()
+        #logger.info(f"{elapsed}s elapsed, "
+        #            f"{sum(data.sizes)/elapsed.total_seconds():.2f} Tokens/s, "
+        #            f"{len(data)/elapsed.total_seconds():.2f} Sents/s")
+
+        if not cache:
+            #return data, head_preds, deprel_preds, stack_list, buffer_list, actions_list, act_dict_list, deprel_preds_decoded, pos_preds_decoded, sent_text, act_dict
+            return *predicted_values,
+
+    def backward(self, loss: torch.Tensor, **kwargs):
+        loss /= self.args.update_steps
+        if hasattr(self, 'scaler'):
+            self.scaler.scale(loss).backward(**kwargs)
+        else:
+            loss.backward(**kwargs)
+
+    def clip_grad_norm_(
+        self,
+        params: Union[Iterable[torch.Tensor], torch.Tensor],
+        max_norm: float,
+        norm_type: float = 2
+    ) -> torch.Tensor:
+        self.scaler.unscale_(self.optimizer)
+        return nn.utils.clip_grad_norm_(params, max_norm, norm_type)
+
+    def clip_grad_value_(
+        self,
+        params: Union[Iterable[torch.Tensor], torch.Tensor],
+        clip_value: float
+    ) -> None:
+        self.scaler.unscale_(self.optimizer)
+        return nn.utils.clip_grad_value_(params, clip_value)
+
+    def reduce(self, obj: Any) -> Any:
+        if not is_dist():
+            return obj
+        return reduce(obj)
+
+    def train_step(self, batch: Batch) -> torch.Tensor:
+        ...
+
+    @torch.no_grad()
+    def eval_step(self, batch: Batch) -> Metric:
+        ...
+
+    @torch.no_grad()
+    def pred_step(self, batch: Batch) -> Batch:
+        ...
+
+    def init_optimizer(self) -> Optimizer:
+        if self.args.encoder in ('lstm', 'transformer'):
+            optimizer = Adam(params=self.model.parameters(),
+                             lr=self.args.lr,
+                             betas=(self.args.get('mu', 0.9), self.args.get('nu', 0.999)),
+                             eps=self.args.get('eps', 1e-8),
+                             weight_decay=self.args.get('weight_decay', 0))
+        else:
+            # we found that Huggingface's AdamW is more robust and empirically better than the native implementation
+            from transformers import AdamW
+            optimizer = AdamW(params=[{'params': p, 'lr': self.args.lr * (1 if n.startswith('encoder') else self.args.lr_rate)}
+                                      for n, p in self.model.named_parameters()],
+                              lr=self.args.lr,
+                              betas=(self.args.get('mu', 0.9), self.args.get('nu', 0.999)),
+                              eps=self.args.get('eps', 1e-8),
+                              weight_decay=self.args.get('weight_decay', 0))
+        return optimizer
+
+    def init_scheduler(self) -> _LRScheduler:
+        if self.args.encoder == 'lstm':
+            scheduler = ExponentialLR(optimizer=self.optimizer,
+                                      gamma=self.args.decay**(1/self.args.decay_steps))
+        elif self.args.encoder == 'transformer':
+            scheduler = InverseSquareRootLR(optimizer=self.optimizer,
+                                            warmup_steps=self.args.warmup_steps)
+        else:
+            scheduler = LinearLR(optimizer=self.optimizer,
+                                 warmup_steps=self.args.get('warmup_steps', int(self.args.steps*self.args.get('warmup', 0))),
+                                 steps=self.args.steps)
+        return scheduler
+
+    @classmethod
+    def build(cls, path, **kwargs):
+        ...
+
+    @classmethod
+    def load(
+        cls,
+        path: str,
+        reload: bool = True,
+        src: str = 'github',
+        checkpoint: bool = False,
+        **kwargs
+    ) -> Parser:
+        r"""
+        Loads a parser with data fields and pretrained model parameters.
+
+        Args:
+            path (str):
+                - a string with the shortcut name of a pretrained model defined in ``supar.MODEL``
+                  to load from cache or download, e.g., ``'biaffine-dep-en'``.
+                - a local path to a pretrained model, e.g., ``./<path>/model``.
+            reload (bool):
+                Whether to discard the existing cache and force a fresh download. Default: ``False``.
+            src (str):
+                Specifies where to download the model.
+                ``'github'``: github release page.
+                ``'hlt'``: hlt homepage, only accessible from 9:00 to 18:00 (UTC+8).
+                Default: ``'github'``.
+            checkpoint (bool):
+                If ``True``, loads all checkpoint states to restore the training process. Default: ``False``.
+
+        Examples:
+            >>> from supar import Parser
+            >>> parser = Parser.load('biaffine-dep-en')
+            >>> parser = Parser.load('./ptb.biaffine.dep.lstm.char')
+        """
+
+        args = Config(**locals())
+        if not os.path.exists(path):
+            path = download(supar.MODEL[src].get(path, path), reload=reload)
+        state = torch.load(path, map_location='cpu', weights_only=False)
+        #torch.load(path, map_location='cpu')
+        cls = supar.PARSER[state['name']] if cls.NAME is None else cls
+        args = state['args'].update(args)
+        #print('ARGS', args)
+        model = cls.MODEL(**args)
+        model.load_pretrained(state['pretrained'])
+        model.load_state_dict(state['state_dict'], True)
+        transform = state['transform']
+        parser = cls(args, model, transform)
+        parser.checkpoint_state_dict = state.get('checkpoint_state_dict', None) if checkpoint else None
+        parser.model.to(parser.device)
+        return parser
+
+    def save(self, path: str) -> None:
+        model = self.model
+        if hasattr(model, 'module'):
+            model = self.model.module
+        state_dict = {k: v.cpu() for k, v in model.state_dict().items()}
+        pretrained = state_dict.pop('pretrained.weight', None)
+        state = {'name': self.NAME,
+                 'args': model.args,
+                 'state_dict': state_dict,
+                 'pretrained': pretrained,
+                 'transform': self.transform}
+        torch.save(state, path, pickle_module=dill)
+
+    def save_checkpoint(self, path: str) -> None:
+        model = self.model
+        if hasattr(model, 'module'):
+            model = self.model.module
+        checkpoint_state_dict = {k: getattr(self, k) for k in ['epoch', 'best_e', 'patience', 'best_metric', 'elapsed']}
+        checkpoint_state_dict.update({'optimizer_state_dict': self.optimizer.state_dict(),
+                                      'scheduler_state_dict': self.scheduler.state_dict(),
+                                      'scaler_state_dict': self.scaler.state_dict(),
+                                      'rng_state': get_rng_state()})
+        state_dict = {k: v.cpu() for k, v in model.state_dict().items()}
+        pretrained = state_dict.pop('pretrained.weight', None)
+        state = {'name': self.NAME,
+                 'args': model.args,
+                 'state_dict': state_dict,
+                 'pretrained': pretrained,
+                 'checkpoint_state_dict': checkpoint_state_dict,
+                 'transform': self.transform}
+        torch.save(state, path, pickle_module=dill)
diff --git a/tania_scripts/supar/structs/__init__.py b/tania_scripts/supar/structs/__init__.py
new file mode 100644
index 0000000..9afbd79
--- /dev/null
+++ b/tania_scripts/supar/structs/__init__.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+
+from .chain import LinearChainCRF, SemiMarkovCRF
+from .dist import StructuredDistribution
+from .tree import (BiLexicalizedConstituencyCRF, ConstituencyCRF,
+                   Dependency2oCRF, DependencyCRF, MatrixTree)
+from .vi import (ConstituencyLBP, ConstituencyMFVI, DependencyLBP,
+                 DependencyMFVI, SemanticDependencyLBP, SemanticDependencyMFVI)
+
+__all__ = ['StructuredDistribution',
+           'LinearChainCRF',
+           'SemiMarkovCRF',
+           'MatrixTree',
+           'DependencyCRF',
+           'Dependency2oCRF',
+           'ConstituencyCRF',
+           'BiLexicalizedConstituencyCRF',
+           'DependencyMFVI',
+           'DependencyLBP',
+           'ConstituencyMFVI',
+           'ConstituencyLBP',
+           'SemanticDependencyMFVI',
+           'SemanticDependencyLBP', ]
diff --git a/tania_scripts/supar/structs/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/structs/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ef548e93f5fe211cae6a010de99dbcb04c3710ad
GIT binary patch
literal 703
zcmd1j<>g{vU|<knUzG05%)sy%#6iYP3=9ko3=9m#DGUq@DGVu$ISjdsQH;4vQA~^=
zK2r{JE=v>(n9ZESn#&f&mdhT+p34!%k;@synadT$1(svU;m+lW;>qQW;?3oY;>+ca
z;?EU`637*d5@cjZXGmdP#26)%!WPV+$^Md&fq_Aj=@y?)W?pJyk#k03W}b79+b!PU
z)Z9$p#G>r{GUp&SO~zYd!6ikd$t9&lsVOd*#U(|VNu?#3`FWbGw`80$eNrnjlM{0?
zt5Q>(^Ye;JGD}KR^O7q;2JvGExTF@O=B0q-jq*V%co701E|+g&Nl|7+NKtC4Cfh9(
z?LJNcw*-*Q^K}dJyoID6q<{}$99UX3I5jshuOu@WAr4X|hA9kEuE|%#!oa{#1d56x
zW)O=LL~wuzb`Ze^B3MBLFNoj)5!@gG6tzYCAQm431B0KY@GaJ4P-r5Iy2X+L3OSJZ
zw^&MwQd5h-=73EEn+>)FWZx~Ovdki|fncM-mVm7T84b4N7JGbrVopwc{7Qx*QIMq|
z;+MUCMt*Lpeo10UW@28VUQ$kCN@i-2esX?pLB4K!L5Xf|eoAVNesO6*Vv&9^I6{l{
p<Kr{)GE3s)^$IF)aoFVMr<CTT+JTZqF~|i1OgxM-j0#LV%mCu)x=#QA

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/structs/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/structs/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d4517337ef5ef26d1d5c1d3e7001d4ea719d5120
GIT binary patch
literal 946
zcmZ3^%ge>Uz`&q%Up2#-nStRkhy%k+P{!vp1_p-d3@HpLj5!Rsj8TlaOi@gXAU;zL
zb1q913z*HE!<x$$#g@w+#h%L%#gWSy#hJ?$#RZmQ$>GlBiQ>uSjpEJai{i`WkK)f2
zh!V&Zj1pvINM}f4UBnnAl)@IwpvnG{k%56hlj#<pPi9_fVv%!3VrHImklQWZ;MCkq
z-^8Nq{4(btH%-P{V!<UvrO73wMX4z+nZ+eVnMtK3nfZB|thZ#GGJR4jGLsW?GOJQk
zob&UFOEODJQ}dE5K?d<-2)Lvcq~@i7<c;z{DtHkBATF10Vo6bEMMzO<swUel6zx7v
z0k;H@&GU5&^Sp(mAEbZ}VH{XmG&nUkF|Q;u86gf*CWa{tQm)BY#LB?HP{a%(SU?0Q
z!iqRSEDjLC4kFk<1Rsdt1ra<Tf*V8#fCzpD1_nP(;ajZ9pwL7Zb&Dkh6mlT*Z?TjV
zrKT2v%>kPTHXCdU$i7=lWtl}_1HndvEdg5xGP($4$u0Ky_{5x?`1q9!pF!#7m#=<C
zer~FMNn%N6VqT(NQchw@W@?dsa(-?>zHUisMTu@|Sz?ZUNn&1RVtjFOQD#9&v3_xB
zL1K}9F*s(6_2c6+^D;}~<Mj$Ee{tC4=BJeAq}mlpGB7ZJ5=rqJ1_p)?%#4hTAJ`Ze
z4KFYlV4@og8W&K}2PQ^F`wtA15-g020gNDHXhgE{a;tq{fDsMsAXp^Mz`y_imp1%4

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/structs/__pycache__/chain.cpython-310.pyc b/tania_scripts/supar/structs/__pycache__/chain.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e42d31e38ad624ca095da2a77618bca27d421e88
GIT binary patch
literal 9988
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/structs/__pycache__/chain.cpython-311.pyc b/tania_scripts/supar/structs/__pycache__/chain.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5f42a094bb248a728f5748ec2648f7828e587fdd
GIT binary patch
literal 17390
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
VZt8-F)<*`g^cM*A0UHI5G5~K|LgfGe

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/structs/__pycache__/dist.cpython-310.pyc b/tania_scripts/supar/structs/__pycache__/dist.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4fd9588165983a30bc91fedfe71a124d9e274b7a
GIT binary patch
literal 5710
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/structs/__pycache__/dist.cpython-311.pyc b/tania_scripts/supar/structs/__pycache__/dist.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..bde8b84641e2db640d4bc8b6077df3a2e1aae03a
GIT binary patch
literal 7995
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/structs/__pycache__/fn.cpython-310.pyc b/tania_scripts/supar/structs/__pycache__/fn.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..128838b69315f5cfbbab3bcd5933e1af0b4e9816
GIT binary patch
literal 11869
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
AzW@LL

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/structs/__pycache__/fn.cpython-311.pyc b/tania_scripts/supar/structs/__pycache__/fn.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..52542e3188bfcde5e56f78ad516e4e75e2da4552
GIT binary patch
literal 21496
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
SskAOI2txS{oDH1d>;eGpwdP^~

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/structs/__pycache__/semiring.cpython-310.pyc b/tania_scripts/supar/structs/__pycache__/semiring.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..eebbfcd87f3a9e230655a6f65e90217253551767
GIT binary patch
literal 17503
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/structs/__pycache__/semiring.cpython-311.pyc b/tania_scripts/supar/structs/__pycache__/semiring.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e9cfb3a935ad9c1fee1faac17b0a0e4317f6aa3d
GIT binary patch
literal 33629
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
X3f6(0oWcE(0VMMUOn$&1!PPhbRFa}C

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/structs/__pycache__/tree.cpython-310.pyc b/tania_scripts/supar/structs/__pycache__/tree.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9cfa02dffd8263f04ff8556087083f71ef8bccee
GIT binary patch
literal 26754
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
D%w81)

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/structs/__pycache__/tree.cpython-311.pyc b/tania_scripts/supar/structs/__pycache__/tree.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b42efb7cbe328a1db42ec469766abe4c93796ba5
GIT binary patch
literal 52834
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
DPbNQ0

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/structs/__pycache__/vi.cpython-310.pyc b/tania_scripts/supar/structs/__pycache__/vi.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0dc6ac96670b2c3dda14334e09a50e31c53a3ff5
GIT binary patch
literal 13833
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/structs/__pycache__/vi.cpython-311.pyc b/tania_scripts/supar/structs/__pycache__/vi.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4b5a62221a93d1af40f302d54c6da4bfff1818d4
GIT binary patch
literal 28892
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
WJ2}H?j^{@PklYtA`2m9j$2|Z;=Cxe_

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/structs/chain.py b/tania_scripts/supar/structs/chain.py
new file mode 100644
index 0000000..828caab
--- /dev/null
+++ b/tania_scripts/supar/structs/chain.py
@@ -0,0 +1,208 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+from typing import List, Optional
+
+import torch
+from supar.structs.dist import StructuredDistribution
+from supar.structs.semiring import LogSemiring, Semiring
+from torch.distributions.utils import lazy_property
+
+
+class LinearChainCRF(StructuredDistribution):
+    r"""
+        Linear-chain CRFs :cite:`lafferty-etal-2001-crf`.
+
+        Args:
+            scores (~torch.Tensor): ``[batch_size, seq_len, n_tags]``.
+                Log potentials.
+            trans (~torch.Tensor): ``[n_tags+1, n_tags+1]``.
+                Transition scores.
+                ``trans[-1, :-1]``/``trans[:-1, -1]`` represent oracle for start/end positions respectively.
+            lens (~torch.LongTensor): ``[batch_size]``.
+                Sentence lengths for masking. Default: ``None``.
+
+        Examples:
+            >>> from supar import LinearChainCRF
+            >>> batch_size, seq_len, n_tags = 2, 5, 4
+            >>> lens = torch.tensor([3, 4])
+            >>> value = torch.randint(n_tags, (batch_size, seq_len))
+            >>> s1 = LinearChainCRF(torch.randn(batch_size, seq_len, n_tags),
+                                    torch.randn(n_tags+1, n_tags+1),
+                                    lens)
+            >>> s2 = LinearChainCRF(torch.randn(batch_size, seq_len, n_tags),
+                                    torch.randn(n_tags+1, n_tags+1),
+                                    lens)
+            >>> s1.max
+            tensor([4.4120, 8.9672], grad_fn=<MaxBackward0>)
+            >>> s1.argmax
+            tensor([[2, 0, 3, 0, 0],
+                    [3, 3, 3, 2, 0]])
+            >>> s1.log_partition
+            tensor([ 6.3486, 10.9106], grad_fn=<LogsumexpBackward>)
+            >>> s1.log_prob(value)
+            tensor([ -8.1515, -10.5572], grad_fn=<SubBackward0>)
+            >>> s1.entropy
+            tensor([3.4150, 3.6549], grad_fn=<SelectBackward>)
+            >>> s1.kl(s2)
+            tensor([4.0333, 4.3807], grad_fn=<SelectBackward>)
+    """
+
+    def __init__(
+        self,
+        scores: torch.Tensor,
+        trans: Optional[torch.Tensor] = None,
+        lens: Optional[torch.LongTensor] = None
+    ) -> LinearChainCRF:
+        super().__init__(scores, lens=lens)
+
+        batch_size, seq_len, self.n_tags = scores.shape[:3]
+        self.lens = scores.new_full((batch_size,), seq_len).long() if lens is None else lens
+        self.mask = self.lens.unsqueeze(-1).gt(self.lens.new_tensor(range(seq_len)))
+
+        self.trans = self.scores.new_full((self.n_tags+1, self.n_tags+1), LogSemiring.one) if trans is None else trans
+
+    def __repr__(self):
+        return f"{self.__class__.__name__}(n_tags={self.n_tags})"
+
+    def __add__(self, other):
+        return LinearChainCRF(torch.stack((self.scores, other.scores), -1),
+                              torch.stack((self.trans, other.trans), -1),
+                              self.lens)
+
+    @lazy_property
+    def argmax(self):
+        return self.lens.new_zeros(self.mask.shape).masked_scatter_(self.mask, torch.where(self.backward(self.max.sum()))[2])
+
+    def topk(self, k: int) -> torch.LongTensor:
+        preds = torch.stack([torch.where(self.backward(i))[2] for i in self.kmax(k).sum(0)], -1)
+        return self.lens.new_zeros(*self.mask.shape, k).masked_scatter_(self.mask.unsqueeze(-1), preds)
+
+    def score(self, value: torch.LongTensor) -> torch.Tensor:
+        scores, mask, value = self.scores.transpose(0, 1), self.mask.t(), value.t()
+        prev, succ = torch.cat((torch.full_like(value[:1], -1), value[:-1]), 0), value
+        # [seq_len, batch_size]
+        alpha = scores.gather(-1, value.unsqueeze(-1)).squeeze(-1)
+        # [batch_size]
+        alpha = LogSemiring.prod(LogSemiring.one_mask(LogSemiring.mul(alpha, self.trans[prev, succ]), ~mask), 0)
+        alpha = alpha + self.trans[value.gather(0, self.lens.unsqueeze(0) - 1).squeeze(0), torch.full_like(value[0], -1)]
+        return alpha
+
+    def forward(self, semiring: Semiring) -> torch.Tensor:
+        # [seq_len, batch_size, n_tags, ...]
+        scores = semiring.convert(self.scores.transpose(0, 1))
+        trans = semiring.convert(self.trans)
+        mask = self.mask.t()
+
+        # [batch_size, n_tags]
+        alpha = semiring.mul(trans[-1, :-1], scores[0])
+        for i in range(1, len(mask)):
+            alpha[mask[i]] = semiring.mul(semiring.dot(alpha.unsqueeze(2), trans[:-1, :-1], 1), scores[i])[mask[i]]
+        alpha = semiring.dot(alpha, trans[:-1, -1], 1)
+        return semiring.unconvert(alpha)
+
+
+class SemiMarkovCRF(StructuredDistribution):
+    r"""
+        Semi-markov CRFs :cite:`sarawagi-cohen-2004-semicrf`.
+
+        Args:
+            scores (~torch.Tensor): ``[batch_size, seq_len, seq_len, n_tags]``.
+                Log potentials.
+            trans (~torch.Tensor): ``[n_tags, n_tags]``.
+                Transition scores.
+            lens (~torch.LongTensor): ``[batch_size]``.
+                Sentence lengths for masking. Default: ``None``.
+
+        Examples:
+            >>> from supar import SemiMarkovCRF
+            >>> batch_size, seq_len, n_tags = 2, 5, 4
+            >>> lens = torch.tensor([3, 4])
+            >>> value = torch.tensor([[[ 0, -1, -1, -1, -1],
+                                       [-1, -1,  2, -1, -1],
+                                       [-1, -1, -1, -1, -1],
+                                       [-1, -1, -1, -1, -1],
+                                       [-1, -1, -1, -1, -1]],
+                                      [[-1,  1, -1, -1, -1],
+                                       [-1, -1,  3, -1, -1],
+                                       [-1, -1, -1,  0, -1],
+                                       [-1, -1, -1, -1, -1],
+                                       [-1, -1, -1, -1, -1]]])
+            >>> s1 = SemiMarkovCRF(torch.randn(batch_size, seq_len, seq_len, n_tags),
+                                   torch.randn(n_tags, n_tags),
+                                   lens)
+            >>> s2 = SemiMarkovCRF(torch.randn(batch_size, seq_len, seq_len, n_tags),
+                                   torch.randn(n_tags, n_tags),
+                                   lens)
+            >>> s1.max
+            tensor([4.1971, 5.5746], grad_fn=<MaxBackward0>)
+            >>> s1.argmax
+            [[[0, 0, 1], [1, 1, 0], [2, 2, 1]], [[0, 0, 1], [1, 1, 3], [2, 2, 0], [3, 3, 1]]]
+            >>> s1.log_partition
+            tensor([6.3641, 8.4384], grad_fn=<LogsumexpBackward0>)
+            >>> s1.log_prob(value)
+            tensor([-5.7982, -7.4534], grad_fn=<SubBackward0>)
+            >>> s1.entropy
+            tensor([3.7520, 5.1609], grad_fn=<SelectBackward0>)
+            >>> s1.kl(s2)
+            tensor([3.5348, 2.2826], grad_fn=<SelectBackward0>)
+    """
+
+    def __init__(
+        self,
+        scores: torch.Tensor,
+        trans: Optional[torch.Tensor] = None,
+        lens: Optional[torch.LongTensor] = None
+    ) -> SemiMarkovCRF:
+        super().__init__(scores, lens=lens)
+
+        batch_size, seq_len, _, self.n_tags = scores.shape[:4]
+        self.lens = scores.new_full((batch_size,), seq_len).long() if lens is None else lens
+        self.mask = self.lens.unsqueeze(-1).gt(self.lens.new_tensor(range(seq_len)))
+        self.mask = self.mask.unsqueeze(1) & self.mask.unsqueeze(2)
+
+        self.trans = self.scores.new_full((self.n_tags, self.n_tags), LogSemiring.one) if trans is None else trans
+
+    def __repr__(self):
+        return f"{self.__class__.__name__}(n_tags={self.n_tags})"
+
+    def __add__(self, other):
+        return SemiMarkovCRF(torch.stack((self.scores, other.scores), -1),
+                             torch.stack((self.trans, other.trans), -1),
+                             self.lens)
+
+    @lazy_property
+    def argmax(self) -> List:
+        return [torch.nonzero(i).tolist() for i in self.backward(self.max.sum())]
+
+    def topk(self, k: int) -> List:
+        return list(zip(*[[torch.nonzero(j).tolist() for j in self.backward(i)] for i in self.kmax(k).sum(0)]))
+
+    def score(self, value: torch.LongTensor) -> torch.Tensor:
+        mask = self.mask & value.ge(0)
+        lens = mask.sum((1, 2))
+        indices = torch.where(mask)
+        batch_size, seq_len = lens.shape[0], lens.max()
+        span_mask = lens.unsqueeze(-1).gt(lens.new_tensor(range(seq_len)))
+        scores = self.scores.new_full((batch_size, seq_len), LogSemiring.one)
+        scores = scores.masked_scatter_(span_mask, self.scores[(*indices, value[indices])])
+        scores = LogSemiring.prod(LogSemiring.one_mask(scores, ~span_mask), -1)
+        value = value.new_zeros(batch_size, seq_len).masked_scatter_(span_mask, value[indices])
+        trans = LogSemiring.prod(LogSemiring.one_mask(self.trans[value[:, :-1], value[:, 1:]], ~span_mask[:, 1:]), -1)
+        return LogSemiring.mul(scores, trans)
+
+    def forward(self, semiring: Semiring) -> torch.Tensor:
+        # [seq_len, seq_len, batch_size, n_tags, ...]
+        scores = semiring.convert(self.scores.movedim((1, 2), (0, 1)))
+        trans = semiring.convert(self.trans)
+        # [seq_len, batch_size, n_tags, ...]
+        alpha = semiring.zeros_like(scores[0])
+
+        alpha[0] = scores[0, 0]
+        # [batch_size, n_tags]
+        for t in range(1, len(scores)):
+            # [batch_size, n_tags, ...]
+            s = semiring.dot(semiring.dot(alpha[:t].unsqueeze(3), trans, 2), scores[1:t+1, t], 0)
+            alpha[t] = semiring.sum(torch.stack((s, scores[0, t])), 0)
+        return semiring.unconvert(semiring.sum(alpha[self.lens - 1, range(len(self.lens))], 1))
diff --git a/tania_scripts/supar/structs/dist.py b/tania_scripts/supar/structs/dist.py
new file mode 100644
index 0000000..6ab594d
--- /dev/null
+++ b/tania_scripts/supar/structs/dist.py
@@ -0,0 +1,138 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+from typing import Iterable, Union
+
+import torch
+import torch.autograd as autograd
+from supar.structs.semiring import (CrossEntropySemiring, EntropySemiring,
+                                    KLDivergenceSemiring, KMaxSemiring,
+                                    LogSemiring, MaxSemiring, SampledSemiring,
+                                    Semiring)
+from torch.distributions.distribution import Distribution
+from torch.distributions.utils import lazy_property
+
+
+class StructuredDistribution(Distribution):
+    r"""
+    Base class for structured distribution :math:`p(y)` :cite:`eisner-2016-inside,goodman-1999-semiring,li-eisner-2009-first`.
+
+    Args:
+        scores (torch.Tensor):
+            Log potentials, also for high-order cases.
+
+    """
+
+    def __init__(self, scores: torch.Tensor, **kwargs) -> StructuredDistribution:
+        self.scores = scores.requires_grad_() if isinstance(scores, torch.Tensor) else [s.requires_grad_() for s in scores]
+        self.kwargs = kwargs
+
+    def __repr__(self):
+        return f"{self.__class__.__name__}()"
+
+    def __add__(self, other: 'StructuredDistribution') -> StructuredDistribution:
+        return self.__class__(torch.stack((self.scores, other.scores), -1), lens=self.lens)
+
+    @lazy_property
+    def log_partition(self):
+        r"""
+        Computes the log partition function of the distribution :math:`p(y)`.
+        """
+
+        return self.forward(LogSemiring)
+
+    @lazy_property
+    def marginals(self):
+        r"""
+        Computes marginal probabilities of the distribution :math:`p(y)`.
+        """
+
+        return self.backward(self.log_partition.sum())
+
+    @lazy_property
+    def max(self):
+        r"""
+        Computes the max score of the distribution :math:`p(y)`.
+        """
+
+        return self.forward(MaxSemiring)
+
+    @lazy_property
+    def argmax(self):
+        r"""
+        Computes :math:`\arg\max_y p(y)` of the distribution :math:`p(y)`.
+        """
+
+        return self.backward(self.max.sum())
+
+    @lazy_property
+    def mode(self):
+        return self.argmax
+
+    def kmax(self, k: int) -> torch.Tensor:
+        r"""
+        Computes the k-max of the distribution :math:`p(y)`.
+        """
+
+        return self.forward(KMaxSemiring(k))
+
+    def topk(self, k: int) -> Union[torch.Tensor, Iterable]:
+        r"""
+        Computes the k-argmax of the distribution :math:`p(y)`.
+        """
+        raise NotImplementedError
+
+    def sample(self):
+        r"""
+        Obtains a structured sample from the distribution :math:`y \sim p(y)`.
+        TODO: multi-sampling.
+        """
+
+        return self.backward(self.forward(SampledSemiring).sum()).detach()
+
+    @lazy_property
+    def entropy(self):
+        r"""
+        Computes entropy :math:`H[p]` of the distribution :math:`p(y)`.
+        """
+
+        return self.forward(EntropySemiring)
+
+    def cross_entropy(self, other: 'StructuredDistribution') -> torch.Tensor:
+        r"""
+        Computes cross-entropy :math:`H[p,q]` of self and another distribution.
+
+        Args:
+            other (~supar.structs.dist.StructuredDistribution): Comparison distribution.
+        """
+
+        return (self + other).forward(CrossEntropySemiring)
+
+    def kl(self, other: 'StructuredDistribution') -> torch.Tensor:
+        r"""
+        Computes KL-divergence :math:`KL[p \parallel q]=H[p,q]-H[p]` of self and another distribution.
+
+        Args:
+            other (~supar.structs.dist.StructuredDistribution): Comparison distribution.
+        """
+
+        return (self + other).forward(KLDivergenceSemiring)
+
+    def log_prob(self, value: torch.LongTensor, *args, **kwargs) -> torch.Tensor:
+        """
+        Computes log probability over values :math:`p(y)`.
+        """
+
+        return self.score(value, *args, **kwargs) - self.log_partition
+
+    def score(self, value: torch.LongTensor, *args, **kwargs) -> torch.Tensor:
+        raise NotImplementedError
+
+    @torch.enable_grad()
+    def forward(self, semiring: Semiring) -> torch.Tensor:
+        raise NotImplementedError
+
+    def backward(self, log_partition: torch.Tensor) -> Union[torch.Tensor, Iterable[torch.Tensor]]:
+        grads = autograd.grad(log_partition, self.scores, create_graph=True)
+        return grads[0] if isinstance(self.scores, torch.Tensor) else grads
diff --git a/tania_scripts/supar/structs/fn.py b/tania_scripts/supar/structs/fn.py
new file mode 100644
index 0000000..1a0af2a
--- /dev/null
+++ b/tania_scripts/supar/structs/fn.py
@@ -0,0 +1,379 @@
+# -*- coding: utf-8 -*-
+
+import operator
+from typing import Iterable, Tuple, Union
+
+import torch
+from supar.utils.common import INF, MIN
+from supar.utils.fn import pad
+from torch.autograd import Function
+
+
+def tarjan(sequence: Iterable[int]) -> Iterable[int]:
+    r"""
+    Tarjan algorithm for finding Strongly Connected Components (SCCs) of a graph.
+
+    Args:
+        sequence (list):
+            List of head indices.
+
+    Yields:
+        A list of indices making up a SCC. All self-loops are ignored.
+
+    Examples:
+        >>> next(tarjan([2, 5, 0, 3, 1]))  # (1 -> 5 -> 2 -> 1) is a cycle
+        [2, 5, 1]
+    """
+
+    sequence = [-1] + sequence
+    # record the search order, i.e., the timestep
+    dfn = [-1] * len(sequence)
+    # record the the smallest timestep in a SCC
+    low = [-1] * len(sequence)
+    # push the visited into the stack
+    stack, onstack = [], [False] * len(sequence)
+
+    def connect(i, timestep):
+        dfn[i] = low[i] = timestep[0]
+        timestep[0] += 1
+        stack.append(i)
+        onstack[i] = True
+
+        for j, head in enumerate(sequence):
+            if head != i:
+                continue
+            if dfn[j] == -1:
+                yield from connect(j, timestep)
+                low[i] = min(low[i], low[j])
+            elif onstack[j]:
+                low[i] = min(low[i], dfn[j])
+
+        # a SCC is completed
+        if low[i] == dfn[i]:
+            cycle = [stack.pop()]
+            while cycle[-1] != i:
+                onstack[cycle[-1]] = False
+                cycle.append(stack.pop())
+            onstack[i] = False
+            # ignore the self-loop
+            if len(cycle) > 1:
+                yield cycle
+
+    timestep = [0]
+    for i in range(len(sequence)):
+        if dfn[i] == -1:
+            yield from connect(i, timestep)
+
+
+def chuliu_edmonds(s: torch.Tensor) -> torch.Tensor:
+    r"""
+    ChuLiu/Edmonds algorithm for non-projective decoding :cite:`mcdonald-etal-2005-non`.
+
+    Some code is borrowed from `tdozat's implementation`_.
+    Descriptions of notations and formulas can be found in :cite:`mcdonald-etal-2005-non`.
+
+    Notes:
+        The algorithm does not guarantee to parse a single-root tree.
+
+    Args:
+        s (~torch.Tensor): ``[seq_len, seq_len]``.
+            Scores of all dependent-head pairs.
+
+    Returns:
+        ~torch.Tensor:
+            A tensor with shape ``[seq_len]`` for the resulting non-projective parse tree.
+
+    .. _tdozat's implementation:
+        https://github.com/tdozat/Parser-v3
+    """
+
+    s[0, 1:] = MIN
+    # prevent self-loops
+    s.diagonal()[1:].fill_(MIN)
+    # select heads with highest scores
+    tree = s.argmax(-1)
+    # return the cycle finded by tarjan algorithm lazily
+    cycle = next(tarjan(tree.tolist()[1:]), None)
+    # if the tree has no cycles, then it is a MST
+    if not cycle:
+        return tree
+    # indices of cycle in the original tree
+    cycle = torch.tensor(cycle)
+    # indices of noncycle in the original tree
+    noncycle = torch.ones(len(s)).index_fill_(0, cycle, 0)
+    noncycle = torch.where(noncycle.gt(0))[0]
+
+    def contract(s):
+        # heads of cycle in original tree
+        cycle_heads = tree[cycle]
+        # scores of cycle in original tree
+        s_cycle = s[cycle, cycle_heads]
+
+        # calculate the scores of cycle's potential dependents
+        # s(c->x) = max(s(x'->x)), x in noncycle and x' in cycle
+        s_dep = s[noncycle][:, cycle]
+        # find the best cycle head for each noncycle dependent
+        deps = s_dep.argmax(1)
+        # calculate the scores of cycle's potential heads
+        # s(x->c) = max(s(x'->x) - s(a(x')->x') + s(cycle)), x in noncycle and x' in cycle
+        #                                                    a(v) is the predecessor of v in cycle
+        #                                                    s(cycle) = sum(s(a(v)->v))
+        s_head = s[cycle][:, noncycle] - s_cycle.view(-1, 1) + s_cycle.sum()
+        # find the best noncycle head for each cycle dependent
+        heads = s_head.argmax(0)
+
+        contracted = torch.cat((noncycle, torch.tensor([-1])))
+        # calculate the scores of contracted graph
+        s = s[contracted][:, contracted]
+        # set the contracted graph scores of cycle's potential dependents
+        s[:-1, -1] = s_dep[range(len(deps)), deps]
+        # set the contracted graph scores of cycle's potential heads
+        s[-1, :-1] = s_head[heads, range(len(heads))]
+
+        return s, heads, deps
+
+    # keep track of the endpoints of the edges into and out of cycle for reconstruction later
+    s, heads, deps = contract(s)
+
+    # y is the contracted tree
+    y = chuliu_edmonds(s)
+    # exclude head of cycle from y
+    y, cycle_head = y[:-1], y[-1]
+
+    # fix the subtree with no heads coming from the cycle
+    # len(y) denotes heads coming from the cycle
+    subtree = y < len(y)
+    # add the nodes to the new tree
+    tree[noncycle[subtree]] = noncycle[y[subtree]]
+    # fix the subtree with heads coming from the cycle
+    subtree = ~subtree
+    # add the nodes to the tree
+    tree[noncycle[subtree]] = cycle[deps[subtree]]
+    # fix the root of the cycle
+    cycle_root = heads[cycle_head]
+    # break the cycle and add the root of the cycle to the tree
+    tree[cycle[cycle_root]] = noncycle[cycle_head]
+
+    return tree
+
+
+def mst(scores: torch.Tensor, mask: torch.BoolTensor, multiroot: bool = False) -> torch.Tensor:
+    r"""
+    MST algorithm for decoding non-projective trees.
+    This is a wrapper for ChuLiu/Edmonds algorithm.
+
+    The algorithm first runs ChuLiu/Edmonds to parse a tree and then have a check of multi-roots,
+    If ``multiroot=True`` and there indeed exist multi-roots, the algorithm seeks to find
+    best single-root trees by iterating all possible single-root trees parsed by ChuLiu/Edmonds.
+    Otherwise the resulting trees are directly taken as the final outputs.
+
+    Args:
+        scores (~torch.Tensor): ``[batch_size, seq_len, seq_len]``.
+            Scores of all dependent-head pairs.
+        mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+            The mask to avoid parsing over padding tokens.
+            The first column serving as pseudo words for roots should be ``False``.
+        multiroot (bool):
+            Ensures to parse a single-root tree If ``False``.
+
+    Returns:
+        ~torch.Tensor:
+            A tensor with shape ``[batch_size, seq_len]`` for the resulting non-projective parse trees.
+
+    Examples:
+        >>> scores = torch.tensor([[[-11.9436, -13.1464,  -6.4789, -13.8917],
+                                    [-60.6957, -60.2866, -48.6457, -63.8125],
+                                    [-38.1747, -49.9296, -45.2733, -49.5571],
+                                    [-19.7504, -23.9066,  -9.9139, -16.2088]]])
+        >>> scores[:, 0, 1:] = MIN
+        >>> scores.diagonal(0, 1, 2)[1:].fill_(MIN)
+        >>> mask = torch.tensor([[False,  True,  True,  True]])
+        >>> mst(scores, mask)
+        tensor([[0, 2, 0, 2]])
+    """
+
+    _, seq_len, _ = scores.shape
+    scores = scores.cpu().unbind()
+
+    preds = []
+    for i, length in enumerate(mask.sum(1).tolist()):
+        s = scores[i][:length+1, :length+1]
+        tree = chuliu_edmonds(s)
+        roots = torch.where(tree[1:].eq(0))[0] + 1
+        if not multiroot and len(roots) > 1:
+            s_root = s[:, 0]
+            s_best = MIN
+            s = s.index_fill(1, torch.tensor(0), MIN)
+            for root in roots:
+                s[:, 0] = MIN
+                s[root, 0] = s_root[root]
+                t = chuliu_edmonds(s)
+                s_tree = s[1:].gather(1, t[1:].unsqueeze(-1)).sum()
+                if s_tree > s_best:
+                    s_best, tree = s_tree, t
+        preds.append(tree)
+
+    return pad(preds, total_length=seq_len).to(mask.device)
+
+
+def levenshtein(x: Iterable, y: Iterable, align: bool = False) -> int:
+    """
+    Calculates the Levenshtein edit-distance between two sequences.
+    The edit distance is the number of characters that need to be
+    substituted, inserted, or deleted, to transform `x` into `y`.
+
+    For example, transforming "rain" to "shine" requires three steps,
+    consisting of two substitutions and one insertion:
+    "rain" -> "sain" -> "shin" -> "shine".
+    These operations could have been done in other orders, but at least three steps are needed.
+
+    Allows specifying the cost of substitution edits (e.g., "a" -> "b"),
+    because sometimes it makes sense to assign greater penalties to substitutions.
+
+    The code is revised from `nltk`_ and `wiki`_'s implementations.
+
+    Args:
+        x/y (Iterable):
+            The sequences to be analysed.
+        align (bool):
+            Whether to return the alignments based on the minimum Levenshtein edit-distance. Default: ``False``.
+
+    Examples:
+        >>> from supar.structs.utils.fn import levenshtein
+        >>> levenshtein('intention', 'execution', align=True)
+        (5, [(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6), (7, 7), (8, 8), (9, 9)])
+
+    .. _nltk:
+        https://github.com/nltk/nltk/blob/develop/nltk/metrics/distance.py
+    .. _wiki:
+        https://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance
+    """
+
+    # set up a 2-D array
+    len1, len2 = len(x), len(y)
+    lev = [list(range(len2 + 1))] + [[i] + [0] * len2 for i in range(1, len1 + 1)]
+
+    # iterate over the array
+    # i and j start from 1 and not 0 to stay close to the wikipedia pseudo-code
+    # see https://en.wikipedia.org/wiki/Damerau%E2%80%93Levenshtein_distance
+    for i in range(1, len1 + 1):
+        for j in range(1, len2 + 1):
+            # substitution
+            s = lev[i - 1][j - 1] + (x[i - 1] != y[j - 1])
+            # deletion
+            a = lev[i - 1][j] + 1
+            # insertion
+            b = lev[i][j - 1] + 1
+
+            lev[i][j] = min(s, a, b)
+    distance = lev[-1][-1]
+    if align:
+        i, j = len1, len2
+        alignments = [(i, j)]
+        while (i, j) != (0, 0):
+            directions = [
+                (i - 1, j - 1),  # substitution
+                (i - 1, j),  # deletion
+                (i, j - 1),  # insertion
+            ]
+            direction_costs = ((lev[i][j] if (i >= 0 and j >= 0) else INF, (i, j)) for i, j in directions)
+            _, (i, j) = min(direction_costs, key=operator.itemgetter(0))
+            alignments.append((i, j))
+        alignments = list(reversed(alignments))
+    return (distance, alignments) if align else distance
+
+
+class Logsumexp(Function):
+
+    r"""
+    Safer ``logsumexp`` to cure unnecessary NaN values that arise from inf arguments.
+    See discussions at http://github.com/pytorch/pytorch/issues/49724.
+    To be optimized with C++/Cuda extensions.
+    """
+
+    @staticmethod
+    @torch.cuda.amp.custom_fwd(cast_inputs=torch.float)
+    def forward(ctx, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        output = x.logsumexp(dim)
+        ctx.dim = dim
+        ctx.save_for_backward(x, output)
+        return output.clone()
+
+    @staticmethod
+    @torch.cuda.amp.custom_bwd
+    def backward(ctx, g: torch.Tensor) -> Union[torch.Tensor, None]:
+        x, output, dim = *ctx.saved_tensors, ctx.dim
+        g, output = g.unsqueeze(dim), output.unsqueeze(dim)
+        mask = g.eq(0).expand_as(x)
+        grad = g * (x - output).exp()
+        return torch.where(mask, x.new_tensor(0.), grad), None
+
+
+class Logaddexp(Function):
+
+    @staticmethod
+    @torch.cuda.amp.custom_fwd(cast_inputs=torch.float)
+    def forward(ctx, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
+        output = torch.logaddexp(x, y)
+        ctx.save_for_backward(x, y, output)
+        return output.clone()
+
+    @staticmethod
+    @torch.cuda.amp.custom_bwd
+    def backward(ctx, g: torch.Tensor) -> Union[torch.Tensor, torch.Tensor]:
+        x, y, output = ctx.saved_tensors
+        mask = g.eq(0)
+        grad_x, grad_y = (x - output).exp(), (y - output).exp()
+        grad_x = torch.where(mask, x.new_tensor(0.), grad_x)
+        grad_y = torch.where(mask, y.new_tensor(0.), grad_y)
+        return grad_x, grad_y
+
+
+class SampledLogsumexp(Function):
+
+    @staticmethod
+    @torch.cuda.amp.custom_fwd(cast_inputs=torch.float)
+    def forward(ctx, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        ctx.dim = dim
+        ctx.save_for_backward(x)
+        return x.logsumexp(dim=dim)
+
+    @staticmethod
+    @torch.cuda.amp.custom_bwd
+    def backward(ctx, g: torch.Tensor) -> Union[torch.Tensor, None]:
+        from torch.distributions import OneHotCategorical
+        (x, ), dim = ctx.saved_tensors, ctx.dim
+        return g.unsqueeze(dim).mul(OneHotCategorical(logits=x.movedim(dim, -1)).sample().movedim(-1, dim)), None
+
+
+class Sparsemax(Function):
+
+    @staticmethod
+    @torch.cuda.amp.custom_fwd(cast_inputs=torch.float)
+    def forward(ctx, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        ctx.dim = dim
+        sorted_x, _ = x.sort(dim, True)
+        z = sorted_x.cumsum(dim) - 1
+        k = x.new_tensor(range(1, sorted_x.size(dim) + 1)).view(-1, *[1] * (x.dim() - 1)).transpose(0, dim)
+        k = (k * sorted_x).gt(z).sum(dim, True)
+        tau = z.gather(dim, k - 1) / k
+        p = torch.clamp(x - tau, 0)
+        ctx.save_for_backward(k, p)
+        return p
+
+    @staticmethod
+    @torch.cuda.amp.custom_bwd
+    def backward(ctx, g: torch.Tensor) -> Tuple[torch.Tensor, None]:
+        k, p, dim = *ctx.saved_tensors, ctx.dim
+        grad = g.masked_fill(p.eq(0), 0)
+        grad = torch.where(p.ne(0), grad - grad.sum(dim, True) / k, grad)
+        return grad, None
+
+
+logsumexp = Logsumexp.apply
+
+logaddexp = Logaddexp.apply
+
+sampled_logsumexp = SampledLogsumexp.apply
+
+sparsemax = Sparsemax.apply
diff --git a/tania_scripts/supar/structs/semiring.py b/tania_scripts/supar/structs/semiring.py
new file mode 100644
index 0000000..9b66bee
--- /dev/null
+++ b/tania_scripts/supar/structs/semiring.py
@@ -0,0 +1,406 @@
+# -*- coding: utf-8 -*-
+
+import itertools
+from functools import reduce
+from typing import Iterable
+
+import torch
+from supar.structs.fn import sampled_logsumexp, sparsemax
+from supar.utils.common import MIN
+
+
+class Semiring(object):
+    r"""
+    Base semiring class :cite:`goodman-1999-semiring`.
+
+    A semiring is defined by a tuple :math:`<K, \oplus, \otimes, \mathbf{0}, \mathbf{1}>`.
+    :math:`K` is a set of values;
+    :math:`\oplus` is commutative, associative and has an identity element `0`;
+    :math:`\otimes` is associative, has an identity element `1` and distributes over `+`.
+    """
+
+    zero = 0
+    one = 1
+
+    @classmethod
+    def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
+        return x + y
+
+    @classmethod
+    def mul(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
+        return x * y
+
+    @classmethod
+    def sum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return x.sum(dim)
+
+    @classmethod
+    def prod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return x.prod(dim)
+
+    @classmethod
+    def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return x.cumsum(dim)
+
+    @classmethod
+    def cumprod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return x.cumprod(dim)
+
+    @classmethod
+    def dot(cls, x: torch.Tensor, y: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return cls.sum(cls.mul(x, y), dim)
+
+    @classmethod
+    def times(cls, *x: Iterable[torch.Tensor]) -> torch.Tensor:
+        return reduce(lambda i, j: cls.mul(i, j), x)
+
+    @classmethod
+    def zero_(cls, x: torch.Tensor) -> torch.Tensor:
+        return x.fill_(cls.zero)
+
+    @classmethod
+    def one_(cls, x: torch.Tensor) -> torch.Tensor:
+        return x.fill_(cls.one)
+
+    @classmethod
+    def zero_mask(cls, x: torch.Tensor, mask: torch.BoolTensor) -> torch.Tensor:
+        return x.masked_fill(mask, cls.zero)
+
+    @classmethod
+    def zero_mask_(cls, x: torch.Tensor, mask: torch.BoolTensor) -> torch.Tensor:
+        return x.masked_fill_(mask, cls.zero)
+
+    @classmethod
+    def one_mask(cls, x: torch.Tensor, mask: torch.BoolTensor) -> torch.Tensor:
+        return x.masked_fill(mask, cls.one)
+
+    @classmethod
+    def one_mask_(cls, x: torch.Tensor, mask: torch.BoolTensor) -> torch.Tensor:
+        return x.masked_fill_(mask, cls.one)
+
+    @classmethod
+    def zeros_like(cls, x: torch.Tensor) -> torch.Tensor:
+        return x.new_full(x.shape, cls.zero)
+
+    @classmethod
+    def ones_like(cls, x: torch.Tensor) -> torch.Tensor:
+        return x.new_full(x.shape, cls.one)
+
+    @classmethod
+    def convert(cls, x: torch.Tensor) -> torch.Tensor:
+        return x
+
+    @classmethod
+    def unconvert(cls, x: torch.Tensor) -> torch.Tensor:
+        return x
+
+
+class LogSemiring(Semiring):
+    r"""
+    Log-space semiring :math:`<\mathrm{logsumexp}, +, -\infty, 0>`.
+    """
+
+    zero = MIN
+    one = 0
+
+    @classmethod
+    def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
+        return x.logaddexp(y)
+
+    @classmethod
+    def mul(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
+        return x + y
+
+    @classmethod
+    def sum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return x.logsumexp(dim)
+
+    @classmethod
+    def prod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return x.sum(dim)
+
+    @classmethod
+    def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return x.logcumsumexp(dim)
+
+    @classmethod
+    def cumprod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return x.cumsum(dim)
+
+
+class MaxSemiring(LogSemiring):
+    r"""
+    Max semiring :math:`<\mathrm{max}, +, -\infty, 0>`.
+    """
+
+    @classmethod
+    def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
+        return x.max(y)
+
+    @classmethod
+    def sum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return x.max(dim)[0]
+
+    @classmethod
+    def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return x.cummax(dim)
+
+
+def KMaxSemiring(k):
+    r"""
+    k-max semiring :math:`<\mathrm{kmax}, +, [-\infty, -\infty, \dots], [0, -\infty, \dots]>`.
+    """
+
+    class KMaxSemiring(LogSemiring):
+
+        @classmethod
+        def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
+            return x.unsqueeze(-1).max(y.unsqueeze(-2)).flatten(-2).topk(k, -1)[0]
+
+        @classmethod
+        def mul(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
+            return (x.unsqueeze(-1) + y.unsqueeze(-2)).flatten(-2).topk(k, -1)[0]
+
+        @classmethod
+        def sum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+            return x.movedim(dim, -1).flatten(-2).topk(k, -1)[0]
+
+        @classmethod
+        def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+            return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.add(x, y))), dim)
+
+        @classmethod
+        def cumprod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+            return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.mul(x, y))), dim)
+
+        @classmethod
+        def one_(cls, x: torch.Tensor) -> torch.Tensor:
+            x[..., :1].fill_(cls.one)
+            x[..., 1:].fill_(cls.zero)
+            return x
+
+        @classmethod
+        def convert(cls, x: torch.Tensor) -> torch.Tensor:
+            return torch.cat((x.unsqueeze(-1), cls.zero_(x.new_empty(*x.shape, k - 1))), -1)
+
+    return KMaxSemiring
+
+
+class ExpectationSemiring(Semiring):
+    r"""
+    Expectation semiring :math:`<\oplus, +, [0, 0], [1, 0]>` :cite:`li-eisner-2009-first`.
+
+    Practical Applications: :math:`H(p) = \log Z - \frac{1}{Z}\sum_{d \in D} p(d) r(d)`.
+    """
+
+    @classmethod
+    def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
+        return x + y
+
+    @classmethod
+    def mul(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
+        return torch.stack((x[..., 0] * y[..., 0], x[..., 0] * y[..., 1] + x[..., 1] * y[..., 0]), -1)
+
+    @classmethod
+    def sum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return x.sum(dim)
+
+    @classmethod
+    def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.add(x, y))), dim)
+
+    @classmethod
+    def cumprod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.mul(x, y))), dim)
+
+    @classmethod
+    def zero_(cls, x: torch.Tensor) -> torch.Tensor:
+        return x.fill_(cls.zero)
+
+    @classmethod
+    def one_(cls, x: torch.Tensor) -> torch.Tensor:
+        x[..., 0].fill_(cls.one)
+        x[..., 1].fill_(cls.zero)
+        return x
+
+
+class EntropySemiring(LogSemiring):
+    r"""
+    Entropy expectation semiring :math:`<\oplus, +, [-\infty, 0], [0, 0]>`,
+    where :math:`\oplus` computes the log-values and the running distributional entropy :math:`H[p]`
+    :cite:`li-eisner-2009-first,hwa-2000-sample,kim-etal-2019-unsupervised`.
+    """
+
+    @classmethod
+    def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
+        return cls.sum(torch.stack((x, y)), 0)
+
+    @classmethod
+    def sum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        p = x[..., 0].logsumexp(dim)
+        r = x[..., 0] - p.unsqueeze(dim)
+        r = r.exp().mul((x[..., 1] - r)).sum(dim)
+        return torch.stack((p, r), -1)
+
+    @classmethod
+    def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.add(x, y))), dim)
+
+    @classmethod
+    def cumprod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.mul(x, y))), dim)
+
+    @classmethod
+    def zero_(cls, x: torch.Tensor) -> torch.Tensor:
+        x[..., 0].fill_(cls.zero)
+        x[..., 1].fill_(cls.one)
+        return x
+
+    @classmethod
+    def one_(cls, x: torch.Tensor) -> torch.Tensor:
+        return x.fill_(cls.one)
+
+    @classmethod
+    def convert(cls, x: torch.Tensor) -> torch.Tensor:
+        return torch.stack((x, cls.ones_like(x)), -1)
+
+    @classmethod
+    def unconvert(cls, x: torch.Tensor) -> torch.Tensor:
+        return x[..., 1]
+
+
+class CrossEntropySemiring(LogSemiring):
+    r"""
+    Cross Entropy expectation semiring :math:`<\oplus, +, [-\infty, -\infty, 0], [0, 0, 0]>`,
+    where :math:`\oplus` computes the log-values and the running distributional cross entropy :math:`H[p,q]`
+    of the two distributions :cite:`li-eisner-2009-first`.
+    """
+
+    @classmethod
+    def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
+        return cls.sum(torch.stack((x, y)), 0)
+
+    @classmethod
+    def sum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        p = x[..., :-1].logsumexp(dim)
+        r = x[..., :-1] - p.unsqueeze(dim)
+        r = r[..., 0].exp().mul((x[..., -1] - r[..., 1])).sum(dim)
+        return torch.cat((p, r.unsqueeze(-1)), -1)
+
+    @classmethod
+    def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.add(x, y))), dim)
+
+    @classmethod
+    def cumprod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.mul(x, y))), dim)
+
+    @classmethod
+    def zero_(cls, x: torch.Tensor) -> torch.Tensor:
+        x[..., :-1].fill_(cls.zero)
+        x[..., -1].fill_(cls.one)
+        return x
+
+    @classmethod
+    def one_(cls, x: torch.Tensor) -> torch.Tensor:
+        return x.fill_(cls.one)
+
+    @classmethod
+    def convert(cls, x: torch.Tensor) -> torch.Tensor:
+        return torch.cat((x, cls.one_(torch.empty_like(x[..., :1]))), -1)
+
+    @classmethod
+    def unconvert(cls, x: torch.Tensor) -> torch.Tensor:
+        return x[..., -1]
+
+
+class KLDivergenceSemiring(LogSemiring):
+    r"""
+    KL divergence expectation semiring :math:`<\oplus, +, [-\infty, -\infty, 0], [0, 0, 0]>`,
+    where :math:`\oplus` computes the log-values and the running distributional KL divergence :math:`KL[p \parallel q]`
+    of the two distributions :cite:`li-eisner-2009-first`.
+    """
+
+    @classmethod
+    def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
+        return cls.sum(torch.stack((x, y)), 0)
+
+    @classmethod
+    def sum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        p = x[..., :-1].logsumexp(dim)
+        r = x[..., :-1] - p.unsqueeze(dim)
+        r = r[..., 0].exp().mul((x[..., -1] - r[..., 1] + r[..., 0])).sum(dim)
+        return torch.cat((p, r.unsqueeze(-1)), -1)
+
+    @classmethod
+    def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.add(x, y))), dim)
+
+    @classmethod
+    def cumprod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.mul(x, y))), dim)
+
+    @classmethod
+    def zero_(cls, x: torch.Tensor) -> torch.Tensor:
+        x[..., :-1].fill_(cls.zero)
+        x[..., -1].fill_(cls.one)
+        return x
+
+    @classmethod
+    def one_(cls, x: torch.Tensor) -> torch.Tensor:
+        return x.fill_(cls.one)
+
+    @classmethod
+    def convert(cls, x: torch.Tensor) -> torch.Tensor:
+        return torch.cat((x, cls.one_(torch.empty_like(x[..., :1]))), -1)
+
+    @classmethod
+    def unconvert(cls, x: torch.Tensor) -> torch.Tensor:
+        return x[..., -1]
+
+
+class SampledSemiring(LogSemiring):
+    r"""
+    Sampling semiring :math:`<\mathrm{logsumexp}, +, -\infty, 0>`,
+    which is an exact forward-filtering, backward-sampling approach.
+    """
+
+    @classmethod
+    def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
+        return cls.sum(torch.stack((x, y)), 0)
+
+    @classmethod
+    def sum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return sampled_logsumexp(x, dim)
+
+    @classmethod
+    def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.add(x, y))), dim)
+
+    @classmethod
+    def cumprod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.mul(x, y))), dim)
+
+
+class SparsemaxSemiring(LogSemiring):
+    r"""
+    Sparsemax semiring :math:`<\mathrm{sparsemax}, +, -\infty, 0>`
+    :cite:`martins-etal-2016-sparsemax,mensch-etal-2018-dp,correia-etal-2020-efficient`.
+    """
+
+    @classmethod
+    def add(cls, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
+        return cls.sum(torch.stack((x, y)), 0)
+
+    @staticmethod
+    def sum(x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        p = sparsemax(x, dim)
+        return x.mul(p).sum(dim) - p.norm(p=2, dim=dim)
+
+    @classmethod
+    def cumsum(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.add(x, y))), dim)
+
+    @classmethod
+    def cumprod(cls, x: torch.Tensor, dim: int = -1) -> torch.Tensor:
+        return torch.stack(list(itertools.accumulate(x.unbind(dim), lambda x, y: cls.mul(x, y))), dim)
diff --git a/tania_scripts/supar/structs/tree.py b/tania_scripts/supar/structs/tree.py
new file mode 100644
index 0000000..e1cc555
--- /dev/null
+++ b/tania_scripts/supar/structs/tree.py
@@ -0,0 +1,635 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+from typing import List, Optional, Tuple, Union
+
+import torch
+import torch.nn as nn
+from supar.structs.dist import StructuredDistribution
+from supar.structs.fn import mst
+from supar.structs.semiring import LogSemiring, Semiring
+from supar.utils.fn import diagonal_stripe, expanded_stripe, stripe
+from torch.distributions.utils import lazy_property
+
+
+class MatrixTree(StructuredDistribution):
+    r"""
+    MatrixTree for calculating partitions and marginals of non-projective dependency trees in :math:`O(n^3)`
+    by an adaptation of Kirchhoff's MatrixTree Theorem :cite:`koo-etal-2007-structured`.
+
+    Args:
+        scores (~torch.Tensor): ``[batch_size, seq_len, seq_len]``.
+            Scores of all possible dependent-head pairs.
+        lens (~torch.LongTensor): ``[batch_size]``.
+            Sentence lengths for masking, regardless of root positions. Default: ``None``.
+        multiroot (bool):
+            If ``False``, requires the tree to contain only a single root. Default: ``True``.
+
+    Examples:
+        >>> from supar import MatrixTree
+        >>> batch_size, seq_len = 2, 5
+        >>> lens = torch.tensor([3, 4])
+        >>> arcs = torch.tensor([[0, 2, 0, 4, 2], [0, 3, 1, 0, 3]])
+        >>> s1 = MatrixTree(torch.randn(batch_size, seq_len, seq_len), lens)
+        >>> s2 = MatrixTree(torch.randn(batch_size, seq_len, seq_len), lens)
+        >>> s1.max
+        tensor([0.7174, 3.7910], grad_fn=<SumBackward1>)
+        >>> s1.argmax
+        tensor([[0, 0, 1, 1, 0],
+                [0, 4, 1, 0, 3]])
+        >>> s1.log_partition
+        tensor([2.0229, 6.0558], grad_fn=<CopyBackwards>)
+        >>> s1.log_prob(arcs)
+        tensor([-3.2209, -2.5756], grad_fn=<SubBackward0>)
+        >>> s1.entropy
+        tensor([1.9711, 3.4497], grad_fn=<SubBackward0>)
+        >>> s1.kl(s2)
+        tensor([1.3354, 2.6914], grad_fn=<AddBackward0>)
+    """
+
+    def __init__(
+        self,
+        scores: torch.Tensor,
+        lens: Optional[torch.LongTensor] = None,
+        multiroot: bool = False
+    ) -> MatrixTree:
+        super().__init__(scores)
+
+        batch_size, seq_len, *_ = scores.shape
+        self.lens = scores.new_full((batch_size,), seq_len-1).long() if lens is None else lens
+        self.mask = (self.lens.unsqueeze(-1) + 1).gt(self.lens.new_tensor(range(seq_len)))
+        self.mask = self.mask.index_fill(1, self.lens.new_tensor(0), 0)
+
+        self.multiroot = multiroot
+
+    def __repr__(self):
+        return f"{self.__class__.__name__}(multiroot={self.multiroot})"
+
+    def __add__(self, other):
+        return MatrixTree(torch.stack((self.scores, other.scores)), self.lens, self.multiroot)
+
+    @lazy_property
+    def max(self):
+        arcs = self.argmax
+        return LogSemiring.prod(LogSemiring.one_mask(self.scores.gather(-1, arcs.unsqueeze(-1)).squeeze(-1), ~self.mask), -1)
+
+    @lazy_property
+    def argmax(self):
+        with torch.no_grad():
+            return mst(self.scores, self.mask, self.multiroot)
+
+    def kmax(self, k: int) -> torch.Tensor:
+        # TODO: Camerini algorithm
+        raise NotImplementedError
+
+    def sample(self):
+        raise NotImplementedError
+
+    @lazy_property
+    def entropy(self):
+        return self.log_partition - (self.marginals * self.scores).sum((-1, -2))
+
+    def cross_entropy(self, other: MatrixTree) -> torch.Tensor:
+        return other.log_partition - (self.marginals * other.scores).sum((-1, -2))
+
+    def kl(self, other: MatrixTree) -> torch.Tensor:
+        return other.log_partition - self.log_partition + (self.marginals * (self.scores - other.scores)).sum((-1, -2))
+
+    def score(self, value: torch.LongTensor, partial: bool = False) -> torch.Tensor:
+        arcs = value
+        if partial:
+            mask, lens = self.mask, self.lens
+            mask = mask.index_fill(1, self.lens.new_tensor(0), 1)
+            mask = mask.unsqueeze(1) & mask.unsqueeze(2)
+            arcs = arcs.index_fill(1, lens.new_tensor(0), -1).unsqueeze(-1)
+            arcs = arcs.eq(lens.new_tensor(range(mask.shape[1]))) | arcs.lt(0)
+            scores = LogSemiring.zero_mask(self.scores, ~(arcs & mask))
+            return self.__class__(scores, lens, **self.kwargs).log_partition
+        return LogSemiring.prod(LogSemiring.one_mask(self.scores.gather(-1, arcs.unsqueeze(-1)).squeeze(-1), ~self.mask), -1)
+
+    @torch.enable_grad()
+    def forward(self, semiring: Semiring) -> torch.Tensor:
+        s_arc = self.scores
+        batch_size, *_ = s_arc.shape
+        mask, lens = self.mask.index_fill(1, self.lens.new_tensor(0), 1), self.lens
+        # double precision to prevent overflows
+        s_arc = semiring.zero_mask(s_arc, ~(mask.unsqueeze(-1) & mask.unsqueeze(-2))).double()
+
+        # A(i, j) = exp(s(i, j))
+        m = s_arc.view(batch_size, -1).max(-1)[0]
+        A = torch.exp(s_arc - m.view(-1, 1, 1))
+
+        # Weighted degree matrix
+        # D(i, j) = sum_j(A(i, j)), if h == m
+        #           0,              otherwise
+        D = torch.zeros_like(A)
+        D.diagonal(0, 1, 2).copy_(A.sum(-1))
+        # Laplacian matrix
+        # L(i, j) = D(i, j) - A(i, j)
+        L = D - A
+        if not self.multiroot:
+            L.diagonal(0, 1, 2).add_(-A[..., 0])
+            L[..., 1] = A[..., 0]
+        L = nn.init.eye_(torch.empty_like(A[0])).repeat(batch_size, 1, 1).masked_scatter_(mask.unsqueeze(-1), L[mask])
+        L = L + nn.init.eye_(torch.empty_like(A[0])) * torch.finfo().tiny
+        # Z = L^(0, 0), the minor of L w.r.t row 0 and column 0
+        return (L[:, 1:, 1:].logdet() + m * lens).float()
+
+
+class DependencyCRF(StructuredDistribution):
+    r"""
+    First-order TreeCRF for projective dependency trees :cite:`eisner-2000-bilexical,zhang-etal-2020-efficient`.
+
+    Args:
+        scores (~torch.Tensor): ``[batch_size, seq_len, seq_len]``.
+            Scores of all possible dependent-head pairs.
+        lens (~torch.LongTensor): ``[batch_size]``.
+            Sentence lengths for masking, regardless of root positions. Default: ``None``.
+        multiroot (bool):
+            If ``False``, requires the tree to contain only a single root. Default: ``True``.
+
+    Examples:
+        >>> from supar import DependencyCRF
+        >>> batch_size, seq_len = 2, 5
+        >>> lens = torch.tensor([3, 4])
+        >>> arcs = torch.tensor([[0, 2, 0, 4, 2], [0, 3, 1, 0, 3]])
+        >>> s1 = DependencyCRF(torch.randn(batch_size, seq_len, seq_len), lens)
+        >>> s2 = DependencyCRF(torch.randn(batch_size, seq_len, seq_len), lens)
+        >>> s1.max
+        tensor([3.6346, 1.7194], grad_fn=<IndexBackward>)
+        >>> s1.argmax
+        tensor([[0, 2, 3, 0, 0],
+                [0, 0, 3, 1, 1]])
+        >>> s1.log_partition
+        tensor([4.1007, 3.3383], grad_fn=<IndexBackward>)
+        >>> s1.log_prob(arcs)
+        tensor([-1.3866, -5.5352], grad_fn=<SubBackward0>)
+        >>> s1.entropy
+        tensor([0.9979, 2.6056], grad_fn=<IndexBackward>)
+        >>> s1.kl(s2)
+        tensor([1.6631, 2.6558], grad_fn=<IndexBackward>)
+    """
+
+    def __init__(
+        self,
+        scores: torch.Tensor,
+        lens: Optional[torch.LongTensor] = None,
+        multiroot: bool = False
+    ) -> DependencyCRF:
+        super().__init__(scores)
+
+        batch_size, seq_len, *_ = scores.shape
+        self.lens = scores.new_full((batch_size,), seq_len-1).long() if lens is None else lens
+        self.mask = (self.lens.unsqueeze(-1) + 1).gt(self.lens.new_tensor(range(seq_len)))
+        self.mask = self.mask.index_fill(1, self.lens.new_tensor(0), 0)
+
+        self.multiroot = multiroot
+
+    def __repr__(self):
+        return f"{self.__class__.__name__}(multiroot={self.multiroot})"
+
+    def __add__(self, other):
+        return DependencyCRF(torch.stack((self.scores, other.scores), -1), self.lens, self.multiroot)
+
+    @lazy_property
+    def argmax(self):
+        return self.lens.new_zeros(self.mask.shape).masked_scatter_(self.mask, torch.where(self.backward(self.max.sum()))[2])
+
+    def topk(self, k: int) -> torch.LongTensor:
+        preds = torch.stack([torch.where(self.backward(i))[2] for i in self.kmax(k).sum(0)], -1)
+        return self.lens.new_zeros(*self.mask.shape, k).masked_scatter_(self.mask.unsqueeze(-1), preds)
+
+    def score(self, value: torch.Tensor, partial: bool = False) -> torch.Tensor:
+        arcs = value
+        if partial:
+            mask, lens = self.mask, self.lens
+            mask = mask.index_fill(1, self.lens.new_tensor(0), 1)
+            mask = mask.unsqueeze(1) & mask.unsqueeze(2)
+            arcs = arcs.index_fill(1, lens.new_tensor(0), -1).unsqueeze(-1)
+            arcs = arcs.eq(lens.new_tensor(range(mask.shape[1]))) | arcs.lt(0)
+            scores = LogSemiring.zero_mask(self.scores, ~(arcs & mask))
+            return self.__class__(scores, lens, **self.kwargs).log_partition
+        return LogSemiring.prod(LogSemiring.one_mask(self.scores.gather(-1, arcs.unsqueeze(-1)).squeeze(-1), ~self.mask), -1)
+
+    def forward(self, semiring: Semiring) -> torch.Tensor:
+        s_arc = self.scores
+        batch_size, seq_len = s_arc.shape[:2]
+        # [seq_len, seq_len, batch_size, ...], (h->m)
+        s_arc = semiring.convert(s_arc.movedim((1, 2), (1, 0)))
+        s_i = semiring.zeros_like(s_arc)
+        s_c = semiring.zeros_like(s_arc)
+        semiring.one_(s_c.diagonal().movedim(-1, 1))
+
+        for w in range(1, seq_len):
+            n = seq_len - w
+
+            # [n, batch_size, ...]
+            il = ir = semiring.dot(stripe(s_c, n, w), stripe(s_c, n, w, (w, 1)), 1)
+            # INCOMPLETE-L: I(j->i) = <C(i->r), C(j->r+1)> * s(j->i), i <= r < j
+            # fill the w-th diagonal of the lower triangular part of s_i with I(j->i) of n spans
+            s_i.diagonal(-w).copy_(semiring.mul(il, s_arc.diagonal(-w).movedim(-1, 0)).movedim(0, -1))
+            # INCOMPLETE-R: I(i->j) = <C(i->r), C(j->r+1)> * s(i->j), i <= r < j
+            # fill the w-th diagonal of the upper triangular part of s_i with I(i->j) of n spans
+            s_i.diagonal(w).copy_(semiring.mul(ir, s_arc.diagonal(w).movedim(-1, 0)).movedim(0, -1))
+
+            # [n, batch_size, ...]
+            # COMPLETE-L: C(j->i) = <C(r->i), I(j->r)>, i <= r < j
+            cl = semiring.dot(stripe(s_c, n, w, (0, 0), 0), stripe(s_i, n, w, (w, 0)), 1)
+            s_c.diagonal(-w).copy_(cl.movedim(0, -1))
+            # COMPLETE-R: C(i->j) = <I(i->r), C(r->j)>, i < r <= j
+            cr = semiring.dot(stripe(s_i, n, w, (0, 1)), stripe(s_c, n, w, (1, w), 0), 1)
+            s_c.diagonal(w).copy_(cr.movedim(0, -1))
+            if not self.multiroot:
+                s_c[0, w][self.lens.ne(w)] = semiring.zero
+        return semiring.unconvert(s_c)[0][self.lens, range(batch_size)]
+
+
+class Dependency2oCRF(StructuredDistribution):
+    r"""
+    Second-order TreeCRF for projective dependency trees :cite:`mcdonald-pereira-2006-online,zhang-etal-2020-efficient`.
+
+    Args:
+        scores (tuple(~torch.Tensor, ~torch.Tensor)):
+            Scores of all possible dependent-head pairs (``[batch_size, seq_len, seq_len]``) and
+            dependent-head-sibling triples ``[batch_size, seq_len, seq_len, seq_len]``.
+        lens (~torch.LongTensor): ``[batch_size]``.
+            Sentence lengths for masking, regardless of root positions. Default: ``None``.
+        multiroot (bool):
+            If ``False``, requires the tree to contain only a single root. Default: ``True``.
+
+    Examples:
+        >>> from supar import Dependency2oCRF
+        >>> batch_size, seq_len = 2, 5
+        >>> lens = torch.tensor([3, 4])
+        >>> arcs = torch.tensor([[0, 2, 0, 4, 2], [0, 3, 1, 0, 3]])
+        >>> sibs = torch.tensor([CoNLL.get_sibs(i) for i in arcs[:, 1:].tolist()])
+        >>> s1 = Dependency2oCRF((torch.randn(batch_size, seq_len, seq_len),
+                                  torch.randn(batch_size, seq_len, seq_len, seq_len)),
+                                 lens)
+        >>> s2 = Dependency2oCRF((torch.randn(batch_size, seq_len, seq_len),
+                                  torch.randn(batch_size, seq_len, seq_len, seq_len)),
+                                 lens)
+        >>> s1.max
+        tensor([0.7574, 3.3634], grad_fn=<IndexBackward>)
+        >>> s1.argmax
+        tensor([[0, 3, 3, 0, 0],
+                [0, 4, 4, 4, 0]])
+        >>> s1.log_partition
+        tensor([1.9906, 4.3599], grad_fn=<IndexBackward>)
+        >>> s1.log_prob((arcs, sibs))
+        tensor([-0.6975, -6.2845], grad_fn=<SubBackward0>)
+        >>> s1.entropy
+        tensor([1.6436, 2.1717], grad_fn=<IndexBackward>)
+        >>> s1.kl(s2)
+        tensor([0.4929, 2.0759], grad_fn=<IndexBackward>)
+    """
+
+    def __init__(
+        self,
+        scores: Tuple[torch.Tensor, torch.Tensor],
+        lens: Optional[torch.LongTensor] = None,
+        multiroot: bool = False
+    ) -> Dependency2oCRF:
+        super().__init__(scores)
+
+        batch_size, seq_len, *_ = scores[0].shape
+        self.lens = scores[0].new_full((batch_size,), seq_len-1).long() if lens is None else lens
+        self.mask = (self.lens.unsqueeze(-1) + 1).gt(self.lens.new_tensor(range(seq_len)))
+        self.mask = self.mask.index_fill(1, self.lens.new_tensor(0), 0)
+
+        self.multiroot = multiroot
+
+    def __repr__(self):
+        return f"{self.__class__.__name__}(multiroot={self.multiroot})"
+
+    def __add__(self, other):
+        return Dependency2oCRF([torch.stack((i, j), -1) for i, j in zip(self.scores, other.scores)], self.lens, self.multiroot)
+
+    @lazy_property
+    def argmax(self):
+        return self.lens.new_zeros(self.mask.shape).masked_scatter_(self.mask,
+                                                                    torch.where(self.backward(self.max.sum())[0])[2])
+
+    def topk(self, k: int) -> torch.LongTensor:
+        preds = torch.stack([torch.where(self.backward(i)[0])[2] for i in self.kmax(k).sum(0)], -1)
+        return self.lens.new_zeros(*self.mask.shape, k).masked_scatter_(self.mask.unsqueeze(-1), preds)
+
+    def score(self, value: Tuple[torch.LongTensor, torch.LongTensor], partial: bool = False) -> torch.Tensor:
+        arcs, sibs = value
+        if partial:
+            mask, lens = self.mask, self.lens
+            mask = mask.index_fill(1, self.lens.new_tensor(0), 1)
+            mask = mask.unsqueeze(1) & mask.unsqueeze(2)
+            arcs = arcs.index_fill(1, lens.new_tensor(0), -1).unsqueeze(-1)
+            arcs = arcs.eq(lens.new_tensor(range(mask.shape[1]))) | arcs.lt(0)
+            s_arc, s_sib = LogSemiring.zero_mask(self.scores[0], ~(arcs & mask)), self.scores[1]
+            return self.__class__((s_arc, s_sib), lens, **self.kwargs).log_partition
+        s_arc = self.scores[0].gather(-1, arcs.unsqueeze(-1)).squeeze(-1)
+        s_arc = LogSemiring.prod(LogSemiring.one_mask(s_arc, ~self.mask), -1)
+        s_sib = self.scores[1].gather(-1, sibs.unsqueeze(-1)).squeeze(-1)
+        s_sib = LogSemiring.prod(LogSemiring.one_mask(s_sib, ~sibs.gt(0)), (-1, -2))
+        return LogSemiring.mul(s_arc, s_sib)
+
+    @torch.enable_grad()
+    def forward(self, semiring: Semiring) -> torch.Tensor:
+        s_arc, s_sib = self.scores
+        batch_size, seq_len = s_arc.shape[:2]
+        # [seq_len, seq_len, batch_size, ...], (h->m)
+        s_arc = semiring.convert(s_arc.movedim((1, 2), (1, 0)))
+        # [seq_len, seq_len, seq_len, batch_size, ...], (h->m->s)
+        s_sib = semiring.convert(s_sib.movedim((0, 2), (3, 0)))
+        s_i = semiring.zeros_like(s_arc)
+        s_s = semiring.zeros_like(s_arc)
+        s_c = semiring.zeros_like(s_arc)
+        semiring.one_(s_c.diagonal().movedim(-1, 1))
+
+        for w in range(1, seq_len):
+            n = seq_len - w
+
+            # INCOMPLETE-L: I(j->i) = <I(j->r), S(j->r, i)> * s(j->i), i < r < j
+            #                         <C(j->j), C(i->j-1)>  * s(j->i), otherwise
+            # [n, w, batch_size, ...]
+            il = semiring.times(stripe(s_i, n, w, (w, 1)),
+                                stripe(s_s, n, w, (1, 0), 0),
+                                stripe(s_sib[range(w, n+w), range(n), :], n, w, (0, 1)))
+            il[:, -1] = semiring.mul(stripe(s_c, n, 1, (w, w)), stripe(s_c, n, 1, (0, w - 1))).squeeze(1)
+            il = semiring.sum(il, 1)
+            s_i.diagonal(-w).copy_(semiring.mul(il, s_arc.diagonal(-w).movedim(-1, 0)).movedim(0, -1))
+            # INCOMPLETE-R: I(i->j) = <I(i->r), S(i->r, j)> * s(i->j), i < r < j
+            #                         <C(i->i), C(j->i+1)>  * s(i->j), otherwise
+            # [n, w, batch_size, ...]
+            ir = semiring.times(stripe(s_i, n, w),
+                                stripe(s_s, n, w, (0, w), 0),
+                                stripe(s_sib[range(n), range(w, n+w), :], n, w))
+            if not self.multiroot:
+                semiring.zero_(ir[0])
+            ir[:, 0] = semiring.mul(stripe(s_c, n, 1), stripe(s_c, n, 1, (w, 1))).squeeze(1)
+            ir = semiring.sum(ir, 1)
+            s_i.diagonal(w).copy_(semiring.mul(ir, s_arc.diagonal(w).movedim(-1, 0)).movedim(0, -1))
+
+            # [batch_size, ..., n]
+            sl = sr = semiring.dot(stripe(s_c, n, w), stripe(s_c, n, w, (w, 1)), 1).movedim(0, -1)
+            # SIB: S(j, i) = <C(i->r), C(j->r+1)>, i <= r < j
+            s_s.diagonal(-w).copy_(sl)
+            # SIB: S(i, j) = <C(i->r), C(j->r+1)>, i <= r < j
+            s_s.diagonal(w).copy_(sr)
+
+            # [n, batch_size, ...]
+            # COMPLETE-L: C(j->i) = <C(r->i), I(j->r)>, i <= r < j
+            cl = semiring.dot(stripe(s_c, n, w, (0, 0), 0), stripe(s_i, n, w, (w, 0)), 1)
+            s_c.diagonal(-w).copy_(cl.movedim(0, -1))
+            # COMPLETE-R: C(i->j) = <I(i->r), C(r->j)>, i < r <= j
+            cr = semiring.dot(stripe(s_i, n, w, (0, 1)), stripe(s_c, n, w, (1, w), 0), 1)
+            s_c.diagonal(w).copy_(cr.movedim(0, -1))
+        return semiring.unconvert(s_c)[0][self.lens, range(batch_size)]
+
+
+class ConstituencyCRF(StructuredDistribution):
+    r"""
+    Constituency TreeCRF :cite:`zhang-etal-2020-fast,stern-etal-2017-minimal`.
+
+    Args:
+        scores (~torch.Tensor): ``[batch_size, seq_len, seq_len]``.
+            Scores of all constituents.
+        lens (~torch.LongTensor): ``[batch_size]``.
+            Sentence lengths for masking.
+
+    Examples:
+        >>> from supar import ConstituencyCRF
+        >>> batch_size, seq_len, n_labels = 2, 5, 4
+        >>> lens = torch.tensor([3, 4])
+        >>> charts = torch.tensor([[[-1,  0, -1,  0, -1],
+                                    [-1, -1,  0,  0, -1],
+                                    [-1, -1, -1,  0, -1],
+                                    [-1, -1, -1, -1, -1],
+                                    [-1, -1, -1, -1, -1]],
+                                   [[-1,  0,  0, -1,  0],
+                                    [-1, -1,  0, -1, -1],
+                                    [-1, -1, -1,  0,  0],
+                                    [-1, -1, -1, -1,  0],
+                                    [-1, -1, -1, -1, -1]]])
+        >>> s1 = ConstituencyCRF(torch.randn(batch_size, seq_len, seq_len, n_labels), lens, True)
+        >>> s2 = ConstituencyCRF(torch.randn(batch_size, seq_len, seq_len, n_labels), lens, True)
+        >>> s1.max
+        tensor([3.7036, 7.2569], grad_fn=<IndexBackward0>)
+        >>> s1.argmax
+        [[[0, 1, 2], [0, 3, 0], [1, 2, 1], [1, 3, 0], [2, 3, 3]],
+         [[0, 1, 1], [0, 4, 2], [1, 2, 3], [1, 4, 1], [2, 3, 2], [2, 4, 3], [3, 4, 3]]]
+        >>> s1.log_partition
+        tensor([ 8.5394, 12.9940], grad_fn=<IndexBackward0>)
+        >>> s1.log_prob(charts)
+        tensor([ -8.5209, -14.1160], grad_fn=<SubBackward0>)
+        >>> s1.entropy
+        tensor([6.8868, 9.3996], grad_fn=<IndexBackward0>)
+        >>> s1.kl(s2)
+        tensor([4.0039, 4.1037], grad_fn=<IndexBackward0>)
+    """
+
+    def __init__(
+        self,
+        scores: torch.Tensor,
+        lens: Optional[torch.LongTensor] = None,
+        label: bool = False
+    ) -> ConstituencyCRF:
+        super().__init__(scores)
+
+        batch_size, seq_len, *_ = scores.shape
+        self.lens = scores.new_full((batch_size,), seq_len-1).long() if lens is None else lens
+        self.mask = (self.lens.unsqueeze(-1) + 1).gt(self.lens.new_tensor(range(seq_len)))
+        self.mask = self.mask.unsqueeze(1) & scores.new_ones(scores.shape[:3]).bool().triu_(1)
+        self.label = label
+
+    def __repr__(self):
+        return f"{self.__class__.__name__}(label={self.label})"
+
+    def __add__(self, other):
+        return ConstituencyCRF(torch.stack((self.scores, other.scores), -1), self.lens, self.label)
+
+    @lazy_property
+    def argmax(self):
+        return [torch.nonzero(i).tolist() for i in self.backward(self.max.sum())]
+
+    def topk(self, k: int) -> List[List[Tuple]]:
+        return list(zip(*[[torch.nonzero(j).tolist() for j in self.backward(i)] for i in self.kmax(k).sum(0)]))
+
+    def score(self, value: torch.LongTensor) -> torch.Tensor:
+        mask = self.mask & value.ge(0)
+        if self.label:
+            scores = self.scores[mask].gather(-1, value[mask].unsqueeze(-1)).squeeze(-1)
+            scores = torch.full_like(mask, LogSemiring.one, dtype=scores.dtype).masked_scatter_(mask, scores)
+        else:
+            scores = LogSemiring.one_mask(self.scores, ~mask)
+        return LogSemiring.prod(LogSemiring.prod(scores, -1), -1)
+
+    @torch.enable_grad()
+    def forward(self, semiring: Semiring) -> torch.Tensor:
+        batch_size, seq_len = self.scores.shape[:2]
+        # [seq_len, seq_len, batch_size, ...], (l->r)
+        scores = semiring.convert(self.scores.movedim((1, 2), (0, 1)))
+        scores = semiring.sum(scores, 3) if self.label else scores
+        s = semiring.zeros_like(scores)
+        s.diagonal(1).copy_(scores.diagonal(1))
+
+        for w in range(2, seq_len):
+            n = seq_len - w
+            # [n, batch_size, ...]
+            s_s = semiring.dot(stripe(s, n, w-1, (0, 1)), stripe(s, n, w-1, (1, w), False), 1)
+            s.diagonal(w).copy_(semiring.mul(s_s, scores.diagonal(w).movedim(-1, 0)).movedim(0, -1))
+        return semiring.unconvert(s)[0][self.lens, range(batch_size)]
+
+
+class BiLexicalizedConstituencyCRF(StructuredDistribution):
+    r"""
+    Grammarless Eisner-Satta Algorithm :cite:`eisner-satta-1999-efficient,yang-etal-2021-neural`.
+
+    Code is revised from `Songlin Yang's implementation <https://github.com/sustcsonglin/span-based-dependency-parsing>`_.
+
+    Args:
+        scores (~torch.Tensor): ``[2, batch_size, seq_len, seq_len]``.
+            Scores of dependencies and constituents.
+        lens (~torch.LongTensor): ``[batch_size]``.
+            Sentence lengths for masking.
+
+    Examples:
+        >>> from supar import BiLexicalizedConstituencyCRF
+        >>> batch_size, seq_len = 2, 5
+        >>> lens = torch.tensor([3, 4])
+        >>> deps = torch.tensor([[0, 0, 1, 1, 0], [0, 3, 1, 0, 3]])
+        >>> cons = torch.tensor([[[0, 1, 1, 1, 0],
+                                  [0, 0, 1, 0, 0],
+                                  [0, 0, 0, 1, 0],
+                                  [0, 0, 0, 0, 0],
+                                  [0, 0, 0, 0, 0]],
+                                 [[0, 1, 1, 1, 1],
+                                  [0, 0, 1, 0, 0],
+                                  [0, 0, 0, 1, 0],
+                                  [0, 0, 0, 0, 1],
+                                  [0, 0, 0, 0, 0]]]).bool()
+        >>> heads = torch.tensor([[[0, 1, 1, 1, 0],
+                                   [0, 0, 2, 0, 0],
+                                   [0, 0, 0, 3, 0],
+                                   [0, 0, 0, 0, 0],
+                                   [0, 0, 0, 0, 0]],
+                                  [[0, 1, 1, 3, 3],
+                                   [0, 0, 2, 0, 0],
+                                   [0, 0, 0, 3, 0],
+                                   [0, 0, 0, 0, 4],
+                                   [0, 0, 0, 0, 0]]])
+        >>> s1 = BiLexicalizedConstituencyCRF((torch.randn(batch_size, seq_len, seq_len),
+                                               torch.randn(batch_size, seq_len, seq_len),
+                                               torch.randn(batch_size, seq_len, seq_len, seq_len)),
+                                              lens)
+        >>> s2 = BiLexicalizedConstituencyCRF((torch.randn(batch_size, seq_len, seq_len),
+                                               torch.randn(batch_size, seq_len, seq_len),
+                                               torch.randn(batch_size, seq_len, seq_len, seq_len)),
+                                              lens)
+        >>> s1.max
+        tensor([0.5792, 2.1737], grad_fn=<MaxBackward0>)
+        >>> s1.argmax[0]
+        tensor([[0, 3, 1, 0, 0],
+                [0, 4, 1, 1, 0]])
+        >>> s1.argmax[1]
+        [[[0, 3], [0, 2], [0, 1], [1, 2], [2, 3]], [[0, 4], [0, 3], [0, 2], [0, 1], [1, 2], [2, 3], [3, 4]]]
+        >>> s1.log_partition
+        tensor([1.1923, 3.2343], grad_fn=<LogsumexpBackward>)
+        >>> s1.log_prob((deps, cons, heads))
+        tensor([-1.9123, -3.6127], grad_fn=<SubBackward0>)
+        >>> s1.entropy
+        tensor([1.3376, 2.2996], grad_fn=<SelectBackward>)
+        >>> s1.kl(s2)
+        tensor([1.0617, 2.7839], grad_fn=<SelectBackward>)
+    """
+
+    def __init__(
+        self,
+        scores: List[torch.Tensor],
+        lens: Optional[torch.LongTensor] = None
+    ) -> BiLexicalizedConstituencyCRF:
+        super().__init__(scores)
+
+        batch_size, seq_len, *_ = scores[1].shape
+        self.lens = scores[1].new_full((batch_size,), seq_len-1).long() if lens is None else lens
+        self.mask = (self.lens.unsqueeze(-1) + 1).gt(self.lens.new_tensor(range(seq_len)))
+        self.mask = self.mask.unsqueeze(1) & scores[1].new_ones(scores[1].shape[:3]).bool().triu_(1)
+
+    def __add__(self, other):
+        return BiLexicalizedConstituencyCRF([torch.stack((i, j), -1) for i, j in zip(self.scores, other.scores)], self.lens)
+
+    @lazy_property
+    def argmax(self):
+        marginals = self.backward(self.max.sum())
+        dep_mask = self.mask[:, 0]
+        dep = self.lens.new_zeros(dep_mask.shape).masked_scatter_(dep_mask, torch.where(marginals[0])[2])
+        con = [torch.nonzero(i).tolist() for i in marginals[1]]
+        return dep, con
+
+    def topk(self, k: int) -> Tuple[torch.LongTensor, List[List[Tuple]]]:
+        dep_mask = self.mask[:, 0]
+        marginals = [self.backward(i) for i in self.kmax(k).sum(0)]
+        dep_preds = torch.stack([torch.where(i)[2] for i in marginals[0]], -1)
+        dep_preds = self.lens.new_zeros(*dep_mask.shape, k).masked_scatter_(dep_mask.unsqueeze(-1), dep_preds)
+        con_preds = list(zip(*[[torch.nonzero(j).tolist() for j in i] for i in marginals[1]]))
+        return dep_preds, con_preds
+
+    def score(self, value: List[Union[torch.LongTensor, torch.BoolTensor]], partial: bool = False) -> torch.Tensor:
+        deps, cons, heads = value
+        s_dep, s_con, s_head = self.scores
+        mask, lens = self.mask, self.lens
+        dep_mask, con_mask = mask[:, 0], mask
+        if partial:
+            if deps is not None:
+                dep_mask = dep_mask.index_fill(1, self.lens.new_tensor(0), 1)
+                dep_mask = dep_mask.unsqueeze(1) & dep_mask.unsqueeze(2)
+                deps = deps.index_fill(1, lens.new_tensor(0), -1).unsqueeze(-1)
+                deps = deps.eq(lens.new_tensor(range(mask.shape[1]))) | deps.lt(0)
+                s_dep = LogSemiring.zero_mask(s_dep, ~(deps & dep_mask))
+            if cons is not None:
+                s_con = LogSemiring.zero_mask(s_con, ~(cons & con_mask))
+            if heads is not None:
+                head_mask = heads.unsqueeze(-1).eq(lens.new_tensor(range(mask.shape[1])))
+                head_mask = head_mask & con_mask.unsqueeze(-1)
+                s_head = LogSemiring.zero_mask(s_head, ~head_mask)
+            return self.__class__((s_dep, s_con, s_head), lens, **self.kwargs).log_partition
+        s_dep = LogSemiring.prod(LogSemiring.one_mask(s_dep.gather(-1, deps.unsqueeze(-1)).squeeze(-1), ~dep_mask), -1)
+        s_head = LogSemiring.mul(s_con, s_head.gather(-1, heads.unsqueeze(-1)).squeeze(-1))
+        s_head = LogSemiring.prod(LogSemiring.prod(LogSemiring.one_mask(s_head, ~(con_mask & cons)), -1), -1)
+        return LogSemiring.mul(s_dep, s_head)
+
+    def forward(self, semiring: Semiring) -> torch.Tensor:
+        s_dep, s_con, s_head = self.scores
+        batch_size, seq_len, *_ = s_con.shape
+        # [seq_len, seq_len, batch_size, ...], (m<-h)
+        s_dep = semiring.convert(s_dep.movedim(0, 2))
+        s_root, s_dep = s_dep[1:, 0], s_dep[1:, 1:]
+        # [seq_len, seq_len, batch_size, ...], (i, j)
+        s_con = semiring.convert(s_con.movedim(0, 2))
+        # [seq_len, seq_len, seq_len-1, batch_size, ...], (i, j, h)
+        s_head = semiring.mul(s_con.unsqueeze(2), semiring.convert(s_head.movedim(0, -1)[:, :, 1:]))
+        # [seq_len, seq_len, seq_len-1, batch_size, ...], (i, j, h)
+        s_span = semiring.zeros_like(s_head)
+        # [seq_len, seq_len, seq_len-1, batch_size, ...], (i, j<-h)
+        s_hook = semiring.zeros_like(s_head)
+        diagonal_stripe(s_span, 1).copy_(diagonal_stripe(s_head, 1))
+        s_hook.diagonal(1).copy_(semiring.mul(s_dep, diagonal_stripe(s_head, 1)).movedim(0, -1))
+
+        for w in range(2, seq_len):
+            n = seq_len - w
+            # COMPLETE-L: s_span_l(i, j, h) = <s_span(i, k, h), s_hook(h->k, j)>, i < k < j
+            # [n, w, batch_size, ...]
+            s_l = stripe(semiring.dot(stripe(s_span, n, w-1, (0, 1)), stripe(s_hook, n, w-1, (1, w), False), 1), n, w)
+            # COMPLETE-R: s_span_r(i, j, h) = <s_hook(i, k<-h), s_span(k, j, h)>, i < k < j
+            # [n, w, batch_size, ...]
+            s_r = stripe(semiring.dot(stripe(s_hook, n, w-1, (0, 1)), stripe(s_span, n, w-1, (1, w), False), 1), n, w)
+            # COMPLETE: s_span(i, j, h) = (s_span_l(i, j, h) + s_span_r(i, j, h)) * s(i, j, h)
+            # [n, w, batch_size, ...]
+            s = semiring.mul(semiring.sum(torch.stack((s_l, s_r)), 0), diagonal_stripe(s_head, w))
+            diagonal_stripe(s_span, w).copy_(s)
+
+            if w == seq_len - 1:
+                continue
+            # ATTACH: s_hook(h->i, j) = <s(h->m), s_span(i, j, m)>, i <= m < j
+            # [n, seq_len, batch_size, ...]
+            s = semiring.dot(expanded_stripe(s_dep, n, w), diagonal_stripe(s_span, w).unsqueeze(2), 1)
+            s_hook.diagonal(w).copy_(s.movedim(0, -1))
+        return semiring.unconvert(semiring.dot(s_span[0][self.lens, :, range(batch_size)].transpose(0, 1), s_root, 0))
diff --git a/tania_scripts/supar/structs/vi.py b/tania_scripts/supar/structs/vi.py
new file mode 100644
index 0000000..b848825
--- /dev/null
+++ b/tania_scripts/supar/structs/vi.py
@@ -0,0 +1,499 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+from typing import List, Optional, Tuple
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from supar.structs import DependencyCRF
+from supar.utils.common import MIN
+
+
+class DependencyMFVI(nn.Module):
+    r"""
+    Mean Field Variational Inference for approximately calculating marginals
+    of dependency trees :cite:`wang-tu-2020-second`.
+    """
+
+    def __init__(self, max_iter: int = 3) -> DependencyMFVI:
+        super().__init__()
+
+        self.max_iter = max_iter
+
+    def __repr__(self):
+        return f"{self.__class__.__name__}(max_iter={self.max_iter})"
+
+    @torch.enable_grad()
+    def forward(
+        self,
+        scores: List[torch.Tensor],
+        mask: torch.BoolTensor,
+        target: Optional[torch.LongTensor] = None
+    ) -> Tuple[torch.Tensor, torch.Tensor]:
+        r"""
+        Args:
+            scores (~torch.Tensor, ~torch.Tensor):
+                Tuple of three tensors `s_arc` and `s_sib`.
+                `s_arc` (``[batch_size, seq_len, seq_len]``) holds scores of all possible dependent-head pairs.
+                `s_sib` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of dependent-head-sibling triples.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask to avoid aggregation on padding tokens.
+            target (~torch.LongTensor): ``[batch_size, seq_len]``.
+                A Tensor of gold-standard dependent-head pairs. Default: ``None``.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor:
+                The first is the training loss averaged by the number of tokens, which won't be returned if ``target=None``.
+                The second is a tensor for marginals of shape ``[batch_size, seq_len, seq_len]``.
+        """
+
+        logits = self.mfvi(*scores, mask)
+        marginals = logits.softmax(-1)
+
+        if target is None:
+            return marginals
+        loss = F.cross_entropy(logits[mask], target[mask])
+
+        return loss, marginals
+
+    def mfvi(self, s_arc, s_sib, mask):
+        batch_size, seq_len = mask.shape
+        ls, rs = torch.stack(torch.where(mask.new_ones(seq_len, seq_len))).view(-1, seq_len, seq_len).sort(0)[0]
+        mask = mask.index_fill(1, ls.new_tensor(0), 1)
+        # [seq_len, seq_len, batch_size], (h->m)
+        mask = (mask.unsqueeze(-1) & mask.unsqueeze(-2)).permute(2, 1, 0)
+        # [seq_len, seq_len, seq_len, batch_size], (h->m->s)
+        mask2o = mask.unsqueeze(1) & mask.unsqueeze(2)
+        mask2o = mask2o & ls.unsqueeze(-1).ne(ls.new_tensor(range(seq_len))).unsqueeze(-1)
+        mask2o = mask2o & rs.unsqueeze(-1).ne(rs.new_tensor(range(seq_len))).unsqueeze(-1)
+        # [seq_len, seq_len, batch_size], (h->m)
+        s_arc = s_arc.permute(2, 1, 0)
+        # [seq_len, seq_len, seq_len, batch_size], (h->m->s)
+        s_sib = s_sib.permute(2, 1, 3, 0) * mask2o
+
+        # posterior distributions
+        # [seq_len, seq_len, batch_size], (h->m)
+        q = s_arc
+
+        for _ in range(self.max_iter):
+            q = q.softmax(0)
+            # q(ij) = s(ij) + sum(q(ik)s^sib(ij,ik)), k != i,j
+            q = s_arc + (q.unsqueeze(1) * s_sib).sum(2)
+
+        return q.permute(2, 1, 0)
+
+
+class DependencyLBP(nn.Module):
+    r"""
+    Loopy Belief Propagation for approximately calculating marginals
+    of dependency trees :cite:`smith-eisner-2008-dependency`.
+    """
+
+    def __init__(self, max_iter: int = 3) -> DependencyLBP:
+        super().__init__()
+
+        self.max_iter = max_iter
+
+    def __repr__(self):
+        return f"{self.__class__.__name__}(max_iter={self.max_iter})"
+
+    @torch.enable_grad()
+    def forward(
+        self,
+        scores: List[torch.Tensor],
+        mask: torch.BoolTensor,
+        target: Optional[torch.LongTensor] = None
+    ) -> Tuple[torch.Tensor, torch.Tensor]:
+        r"""
+        Args:
+            scores (~torch.Tensor, ~torch.Tensor):
+                Tuple of three tensors `s_arc` and `s_sib`.
+                `s_arc` (``[batch_size, seq_len, seq_len]``) holds scores of all possible dependent-head pairs.
+                `s_sib` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of dependent-head-sibling triples.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len]``.
+                The mask to avoid aggregation on padding tokens.
+            target (~torch.LongTensor): ``[batch_size, seq_len]``.
+                A Tensor of gold-standard dependent-head pairs. Default: ``None``.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor:
+                The first is the training loss averaged by the number of tokens, which won't be returned if ``target=None``.
+                The second is a tensor for marginals of shape ``[batch_size, seq_len, seq_len]``.
+        """
+
+        logits = self.lbp(*scores, mask)
+        marginals = logits.softmax(-1)
+
+        if target is None:
+            return marginals
+        loss = F.cross_entropy(logits[mask], target[mask])
+
+        return loss, marginals
+
+    def lbp(self, s_arc, s_sib, mask):
+        batch_size, seq_len = mask.shape
+        ls, rs = torch.stack(torch.where(mask.new_ones(seq_len, seq_len))).view(-1, seq_len, seq_len).sort(0)[0]
+        mask = mask.index_fill(1, ls.new_tensor(0), 1)
+        # [seq_len, seq_len, batch_size], (h->m)
+        mask = (mask.unsqueeze(-1) & mask.unsqueeze(-2)).permute(2, 1, 0)
+        # [seq_len, seq_len, seq_len, batch_size], (h->m->s)
+        mask2o = mask.unsqueeze(1) & mask.unsqueeze(2)
+        mask2o = mask2o & ls.unsqueeze(-1).ne(ls.new_tensor(range(seq_len))).unsqueeze(-1)
+        mask2o = mask2o & rs.unsqueeze(-1).ne(rs.new_tensor(range(seq_len))).unsqueeze(-1)
+        # [seq_len, seq_len, batch_size], (h->m)
+        s_arc = s_arc.permute(2, 1, 0)
+        # [seq_len, seq_len, seq_len, batch_size], (h->m->s)
+        s_sib = s_sib.permute(2, 1, 3, 0).masked_fill_(~mask2o, MIN)
+
+        # log beliefs
+        # [seq_len, seq_len, batch_size], (h->m)
+        q = s_arc
+        # [seq_len, seq_len, seq_len, batch_size], (h->m->s)
+        m_sib = s_sib.new_zeros(seq_len, seq_len, seq_len, batch_size)
+
+        for _ in range(self.max_iter):
+            q = q.log_softmax(0)
+            # m(ik->ij) = logsumexp(q(ik) - m(ij->ik) + s(ij->ik))
+            m = q.unsqueeze(2) - m_sib
+            # TODO: better solution for OOM
+            m_sib = torch.logaddexp(m.logsumexp(0), m + s_sib).transpose(1, 2).log_softmax(0)
+            # q(ij) = s(ij) + sum(m(ik->ij)), k != i,j
+            q = s_arc + (m_sib * mask2o).sum(2)
+
+        return q.permute(2, 1, 0)
+
+
+class ConstituencyMFVI(nn.Module):
+    r"""
+    Mean Field Variational Inference for approximately calculating marginals of constituent trees.
+    """
+
+    def __init__(self, max_iter: int = 3) -> ConstituencyMFVI:
+        super().__init__()
+
+        self.max_iter = max_iter
+
+    def __repr__(self):
+        return f"{self.__class__.__name__}(max_iter={self.max_iter})"
+
+    @torch.enable_grad()
+    def forward(
+        self,
+        scores: List[torch.Tensor],
+        mask: torch.BoolTensor,
+        target: Optional[torch.LongTensor] = None
+    ) -> Tuple[torch.Tensor, torch.Tensor]:
+        r"""
+        Args:
+            scores (~torch.Tensor, ~torch.Tensor):
+                Tuple of two tensors `s_span` and `s_pair`.
+                `s_span` (``[batch_size, seq_len, seq_len]``) holds scores of all possible spans.
+                `s_pair` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of second-order triples.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``.
+                The mask to avoid aggregation on padding tokens.
+            target (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``.
+                A Tensor of gold-standard dependent-head pairs. Default: ``None``.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor:
+                The first is the training loss averaged by the number of tokens, which won't be returned if ``target=None``.
+                The second is a tensor for marginals of shape ``[batch_size, seq_len, seq_len]``.
+        """
+
+        logits = self.mfvi(*scores, mask)
+        marginals = logits.sigmoid()
+
+        if target is None:
+            return marginals
+        loss = F.binary_cross_entropy_with_logits(logits[mask], target[mask].float())
+
+        return loss, marginals
+
+    def mfvi(self, s_span, s_pair, mask):
+        batch_size, seq_len, _ = mask.shape
+        ls, rs = torch.stack(torch.where(torch.ones_like(mask[0]))).view(-1, seq_len, seq_len).sort(0)[0]
+        # [seq_len, seq_len, batch_size], (l->r)
+        mask = mask.movedim(0, 2)
+        # [seq_len, seq_len, seq_len, batch_size], (l->r->b)
+        mask2o = mask.unsqueeze(2).repeat(1, 1, seq_len, 1)
+        mask2o = mask2o & ls.unsqueeze(-1).ne(ls.new_tensor(range(seq_len))).unsqueeze(-1)
+        mask2o = mask2o & rs.unsqueeze(-1).ne(rs.new_tensor(range(seq_len))).unsqueeze(-1)
+        # [seq_len, seq_len, batch_size], (l->r)
+        s_span = s_span.movedim(0, 2)
+        # [seq_len, seq_len, seq_len, batch_size], (l->r->b)
+        s_pair = s_pair.permute(1, 2, 3, 0) * mask2o
+
+        # posterior distributions
+        # [seq_len, seq_len, batch_size], (l->r)
+        q = s_span
+
+        for _ in range(self.max_iter):
+            q = q.sigmoid()
+            # q(ij) = s(ij) + sum(q(jk)*s^pair(ij,jk), k != i,j
+            q = s_span + (q.unsqueeze(1) * s_pair).sum(2)
+
+        return q.permute(2, 0, 1)
+
+
+class ConstituencyLBP(nn.Module):
+    r"""
+    Loopy Belief Propagation for approximately calculating marginals of constituent trees.
+    """
+
+    def __init__(self, max_iter: int = 3) -> ConstituencyLBP:
+        super().__init__()
+
+        self.max_iter = max_iter
+
+    def __repr__(self):
+        return f"{self.__class__.__name__}(max_iter={self.max_iter})"
+
+    @torch.enable_grad()
+    def forward(
+        self,
+        scores: List[torch.Tensor],
+        mask: torch.BoolTensor,
+        target: Optional[torch.LongTensor] = None
+    ) -> Tuple[torch.Tensor, torch.Tensor]:
+        r"""
+        Args:
+            scores (~torch.Tensor, ~torch.Tensor):
+                Tuple of four tensors `s_edge`, `s_sib`, `s_cop` and `s_grd`.
+                `s_span` (``[batch_size, seq_len, seq_len]``) holds scores of all possible spans.
+                `s_pair` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of second-order triples.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``.
+                The mask to avoid aggregation on padding tokens.
+            target (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``.
+                A Tensor of gold-standard dependent-head pairs. Default: ``None``.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor:
+                The first is the training loss averaged by the number of tokens, which won't be returned if ``target=None``.
+                The second is a tensor for marginals of shape ``[batch_size, seq_len, seq_len]``.
+        """
+
+        logits = self.lbp(*scores, mask)
+        marginals = logits.softmax(-1)[..., 1]
+
+        if target is None:
+            return marginals
+        loss = F.cross_entropy(logits[mask], target[mask].long())
+
+        return loss, marginals
+
+    def lbp(self, s_span, s_pair, mask):
+        batch_size, seq_len, _ = mask.shape
+        ls, rs = torch.stack(torch.where(torch.ones_like(mask[0]))).view(-1, seq_len, seq_len).sort(0)[0]
+        # [seq_len, seq_len, batch_size], (l->r)
+        mask = mask.movedim(0, 2)
+        # [seq_len, seq_len, seq_len, batch_size], (l->r->b)
+        mask2o = mask.unsqueeze(2).repeat(1, 1, seq_len, 1)
+        mask2o = mask2o & ls.unsqueeze(-1).ne(ls.new_tensor(range(seq_len))).unsqueeze(-1)
+        mask2o = mask2o & rs.unsqueeze(-1).ne(rs.new_tensor(range(seq_len))).unsqueeze(-1)
+        # [2, seq_len, seq_len, batch_size], (l->r)
+        s_span = torch.stack((torch.zeros_like(s_span), s_span)).permute(0, 3, 2, 1)
+        # [seq_len, seq_len, seq_len, batch_size], (l->r->p)
+        s_pair = s_pair.permute(2, 1, 3, 0)
+
+        # log beliefs
+        # [2, seq_len, seq_len, batch_size], (h->m)
+        q = s_span
+        # [2, seq_len, seq_len, seq_len, batch_size], (h->m->s)
+        m_pair = s_pair.new_zeros(2, seq_len, seq_len, seq_len, batch_size)
+
+        for _ in range(self.max_iter):
+            q = q.log_softmax(0)
+            # m(ik->ij) = logsumexp(q(ik) - m(ij->ik) + s(ij->ik))
+            m = q.unsqueeze(3) - m_pair
+            m_pair = torch.stack((m.logsumexp(0), torch.stack((m[0], m[1] + s_pair)).logsumexp(0))).log_softmax(0)
+            # q(ij) = s(ij) + sum(m(ik->ij)), k != i,j
+            q = s_span + (m_pair.transpose(2, 3) * mask2o).sum(3)
+
+        return q.permute(3, 2, 1, 0)
+
+
+class SemanticDependencyMFVI(nn.Module):
+    r"""
+    Mean Field Variational Inference for approximately calculating marginals
+    of semantic dependency trees :cite:`wang-etal-2019-second`.
+    """
+
+    def __init__(self, max_iter: int = 3) -> SemanticDependencyMFVI:
+        super().__init__()
+
+        self.max_iter = max_iter
+
+    def __repr__(self):
+        return f"{self.__class__.__name__}(max_iter={self.max_iter})"
+
+    @torch.enable_grad()
+    def forward(
+        self,
+        scores: List[torch.Tensor],
+        mask: torch.BoolTensor,
+        target: Optional[torch.LongTensor] = None
+    ) -> Tuple[torch.Tensor, torch.Tensor]:
+        r"""
+        Args:
+            scores (~torch.Tensor, ~torch.Tensor):
+                Tuple of four tensors `s_edge`, `s_sib`, `s_cop` and `s_grd`.
+                `s_edge` (``[batch_size, seq_len, seq_len]``) holds scores of all possible dependent-head pairs.
+                `s_sib` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of dependent-head-sibling triples.
+                `s_cop` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of dependent-head-coparent triples.
+                `s_grd` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of dependent-head-grandparent triples.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``.
+                The mask to avoid aggregation on padding tokens.
+            target (~torch.LongTensor): ``[batch_size, seq_len, seq_len]``.
+                A Tensor of gold-standard dependent-head pairs. Default: ``None``.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor:
+                The first is the training loss averaged by the number of tokens, which won't be returned if ``target=None``.
+                The second is a tensor for marginals of shape ``[batch_size, seq_len, seq_len]``.
+        """
+
+        logits = self.mfvi(*scores, mask)
+        marginals = logits.sigmoid()
+
+        if target is None:
+            return marginals
+        loss = F.binary_cross_entropy_with_logits(logits[mask], target[mask].float())
+
+        return loss, marginals
+
+    def mfvi(self, s_edge, s_sib, s_cop, s_grd, mask):
+        _, seq_len, _ = mask.shape
+        hs, ms = torch.stack(torch.where(torch.ones_like(mask[0]))).view(-1, seq_len, seq_len)
+        # [seq_len, seq_len, batch_size], (h->m)
+        mask = mask.permute(2, 1, 0)
+        # [seq_len, seq_len, seq_len, batch_size], (h->m->s)
+        mask2o = mask.unsqueeze(1) & mask.unsqueeze(2)
+        mask2o = mask2o & hs.unsqueeze(-1).ne(hs.new_tensor(range(seq_len))).unsqueeze(-1)
+        mask2o = mask2o & ms.unsqueeze(-1).ne(ms.new_tensor(range(seq_len))).unsqueeze(-1)
+        mask2o.diagonal().fill_(0)
+        # [seq_len, seq_len, batch_size], (h->m)
+        s_edge = s_edge.permute(2, 1, 0)
+        # [seq_len, seq_len, seq_len, batch_size], (h->m->s)
+        s_sib = s_sib.permute(2, 1, 3, 0) * mask2o
+        # [seq_len, seq_len, seq_len, batch_size], (h->m->c)
+        s_cop = s_cop.permute(2, 1, 3, 0) * mask2o
+        # [seq_len, seq_len, seq_len, batch_size], (h->m->g)
+        s_grd = s_grd.permute(2, 1, 3, 0) * mask2o
+
+        # posterior distributions
+        # [seq_len, seq_len, batch_size], (h->m)
+        q = s_edge
+
+        for _ in range(self.max_iter):
+            q = q.sigmoid()
+            # q(ij) = s(ij) + sum(q(ik)s^sib(ij,ik) + q(kj)s^cop(ij,kj) + q(jk)s^grd(ij,jk)), k != i,j
+            q = s_edge + (q.unsqueeze(1) * s_sib + q.transpose(0, 1).unsqueeze(0) * s_cop + q.unsqueeze(0) * s_grd).sum(2)
+
+        return q.permute(2, 1, 0)
+
+
+class SemanticDependencyLBP(nn.Module):
+    r"""
+    Loopy Belief Propagation for approximately calculating marginals
+    of semantic dependency trees :cite:`wang-etal-2019-second`.
+    """
+
+    def __init__(self, max_iter: int = 3) -> SemanticDependencyLBP:
+        super().__init__()
+
+        self.max_iter = max_iter
+
+    def __repr__(self):
+        return f"{self.__class__.__name__}(max_iter={self.max_iter})"
+
+    @torch.enable_grad()
+    def forward(
+        self,
+        scores: List[torch.Tensor],
+        mask: torch.BoolTensor,
+        target: Optional[torch.LongTensor] = None
+    ) -> Tuple[torch.Tensor, torch.Tensor]:
+        r"""
+        Args:
+            scores (~torch.Tensor, ~torch.Tensor):
+                Tuple of four tensors `s_edge`, `s_sib`, `s_cop` and `s_grd`.
+                `s_edge` (``[batch_size, seq_len, seq_len]``) holds scores of all possible dependent-head pairs.
+                `s_sib` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of dependent-head-sibling triples.
+                `s_cop` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of dependent-head-coparent triples.
+                `s_grd` (``[batch_size, seq_len, seq_len, seq_len]``) holds the scores of dependent-head-grandparent triples.
+            mask (~torch.BoolTensor): ``[batch_size, seq_len, seq_len]``.
+                The mask to avoid aggregation on padding tokens.
+            target (~torch.LongTensor): ``[batch_size, seq_len, seq_len]``.
+                A Tensor of gold-standard dependent-head pairs. Default: ``None``.
+
+        Returns:
+            ~torch.Tensor, ~torch.Tensor:
+                The first is the training loss averaged by the number of tokens, which won't be returned if ``target=None``.
+                The second is a tensor for marginals of shape ``[batch_size, seq_len, seq_len]``.
+        """
+
+        logits = self.lbp(*scores, mask)
+        marginals = logits.softmax(-1)[..., 1]
+
+        if target is None:
+            return marginals
+        loss = F.cross_entropy(logits[mask], target[mask])
+
+        return loss, marginals
+
+    def lbp(self, s_edge, s_sib, s_cop, s_grd, mask):
+        lens = mask[..., 0].sum(1)
+        _, seq_len, _ = mask.shape
+        hs, ms = torch.stack(torch.where(torch.ones_like(mask[0]))).view(-1, seq_len, seq_len)
+        # [seq_len, seq_len, batch_size], (h->m)
+        mask = mask.permute(2, 1, 0)
+        # [seq_len, seq_len, seq_len, batch_size], (h->m->s)
+        mask2o = mask.unsqueeze(1) & mask.unsqueeze(2)
+        mask2o = mask2o & hs.unsqueeze(-1).ne(hs.new_tensor(range(seq_len))).unsqueeze(-1)
+        mask2o = mask2o & ms.unsqueeze(-1).ne(ms.new_tensor(range(seq_len))).unsqueeze(-1)
+        mask2o.diagonal().fill_(0)
+        # [2, seq_len, seq_len, batch_size], (h->m)
+        s_edge = torch.stack((torch.zeros_like(s_edge), s_edge)).permute(0, 3, 2, 1)
+        # [seq_len, seq_len, seq_len, batch_size], (h->m->s)
+        s_sib = s_sib.permute(2, 1, 3, 0)
+        # [seq_len, seq_len, seq_len, batch_size], (h->m->c)
+        s_cop = s_cop.permute(2, 1, 3, 0)
+        # [seq_len, seq_len, seq_len, batch_size], (h->m->g)
+        s_grd = s_grd.permute(2, 1, 3, 0)
+
+        # log beliefs
+        # [2, seq_len, seq_len, batch_size], (h->m)
+        q = s_edge
+        # sibling factor
+        # [2, seq_len, seq_len, seq_len, batch_size], (h->m->s)
+        m_sib = s_sib.new_zeros(2, *mask2o.shape)
+        # coparent factor
+        # [2, seq_len, seq_len, seq_len, batch_size], (h->m->c)
+        m_cop = s_cop.new_zeros(2, *mask2o.shape)
+        # grandparent factor
+        # [2, seq_len, seq_len, seq_len, batch_size], (h->m->g)
+        m_grd = s_grd.new_zeros(2, *mask2o.shape)
+        # tree factor
+        # [2, seq_len, seq_len, batch_size], (h->m)
+        m_tree = torch.zeros_like(s_edge)
+
+        for _ in range(self.max_iter):
+            # sibling factor
+            v_sib = q.unsqueeze(2) - m_sib
+            m_sib = torch.stack((v_sib.logsumexp(0), torch.stack((v_sib[0], v_sib[1] + s_sib)).logsumexp(0))).log_softmax(0)
+            # coparent factor
+            v_cop = q.transpose(1, 2).unsqueeze(1) - m_cop
+            m_cop = torch.stack((v_cop.logsumexp(0), torch.stack((v_cop[0], v_cop[1] + s_cop)).logsumexp(0))).log_softmax(0)
+            # grandparent factor
+            v_grd = q.unsqueeze(1) - m_grd
+            m_grd = torch.stack((v_grd.logsumexp(0), torch.stack((v_grd[0], v_grd[1] + s_grd)).logsumexp(0))).log_softmax(0)
+            # tree factor
+            v_tree = q - m_tree
+            b_tree = DependencyCRF((v_tree[1] - v_tree[0]).permute(2, 1, 0), lens).marginals.permute(2, 1, 0)
+            b_tree = torch.stack((1 - b_tree, b_tree))
+            m_tree = (b_tree.clamp(torch.finfo().eps).log() - v_tree).log_softmax(0)
+            # q(ij) = s(ij) + sum(m(ik->ij)), k != i,j
+            q = s_edge + ((m_sib + m_cop + m_grd).transpose(2, 3) * mask2o).sum(3) + m_tree
+
+        return q.permute(3, 2, 1, 0)
diff --git a/tania_scripts/supar/utils/__init__.py b/tania_scripts/supar/utils/__init__.py
new file mode 100644
index 0000000..279bb3f
--- /dev/null
+++ b/tania_scripts/supar/utils/__init__.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+
+from . import field, fn, metric, transform
+from .config import Config
+from .data import Dataset
+from .embed import Embedding
+from .field import ChartField, Field, RawField, SubwordField
+from .transform import Transform
+from .vocab import Vocab
+
+__all__ = ['Config',
+           'Dataset',
+           'Embedding',
+           'RawField', 'Field', 'SubwordField', 'ChartField',
+           'Transform',
+           'Vocab',
+           'field', 'fn', 'metric', 'transform']
diff --git a/tania_scripts/supar/utils/__pycache__/__init__.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/__init__.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d7085981158edde053f2e613913ae5104f375bc5
GIT binary patch
literal 590
zcmd1j<>g{vU|<knUzGlak%8ech=Yuo7#J8F7#J9eD;O9UQW#Pga~N_NqZo6UqL^}-
zqnLA9qF5L~;!HWLxolBvU^a6OdoD*52bj&0!<ow!#RX=w<}l`RM{(!!MDgVEM)BtI
zMe%{f*>YHN`J?#3Z1x<1T)`+oMuv2T6plrVQ9>!4!3>&QFBusa7&KXKv8H9F=A_(W
zO3S;&mYZ5ql$m^sv!p07uQ)BgC|8s57MpW^URq|lCgUx3m&B69;?xpN##@}Oxk;%h
zDVcfcnk=`toHG)OO5DK4utF$~pu}<rizm1=sXV_Z1<V8K3_&uRH7q|lF-eoRh>d}P
zp@<zsaDWJI5CICsA|4Qn6GZTW2tE)23cw;}5Q_ywure?(_-P8?Vkp8Qaf>Y(?0m2d
zw^&jVOA^8M++s}y`Jf1F9oT%ZbzqCZc7m*nVl4x?uLxx8E%x~M#GIV?_>~MrA|Pu)
z#4lU@jQreG{gT9z%*4Dzy`-GPl+4s3{p9@If_&Zdf)d@_{FKxj{o>Ms#3KFDlFXc9
s{rLFIyv&mLc)fzkTO2mI`6;D2sdk{aC>CH~V31(qVFW=5Fv-IN0MJ{BYybcN

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/__init__.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/__init__.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ea9d342a076da2ffb2ad39c0137168c37c8ba0a9
GIT binary patch
literal 781
zcmZ3^%ge>Uz`&q%Up3<mBLl-@5C?{tpp4H|3=9m@8B!Qh7;_kM8KW3;nWC6-nWLC<
zS)y1NLE=m~thsDaY+yEX4tp*~6bG2ilEazH6~zT+v*s}7az}CJ@<j3E@<#FI@<s81
z#o2OLa`~h9!EE*%fn32TK}Lpjh7^uPj8Q@<oWTs5TrU|J7#K8JZn36irskyFVoJ-q
z#g>~|Qk0o|i?gICF|Rl+zbIFe@fMqNeqLH;x+dc-c9+DG#NyNvO~zZCuDMC6DJhwG
z>6$FJxSTT*i%Q(U#;`&tj-bSH2#Y7UG^sqlC<V*|=?p<Kn>8#yIWb9-w}_pAfuV>4
zL~w!#9uUC|B6vXrC^U=sKrDU`!3-i;Km;p@U}Iol@Y58&#ZZJr;uc#n*!f@^Zn2~!
zmL!7hxy70a@<9>UI<Wa*>%bO+?F3nOi?s~oz9NvVx7g$36LWIn<5x0#21Vg7Z~ct?
z+*JLN#FEU!yhOdEoWzvO)FS=l{M>?k-ICOb65Z6Y#2o#S#JtSJ_~PWE%z~0){o>Ms
z#3KFDlFXc9{rLFIyv&mLc)fzkUmP~M`6;D2sdhz@3=9mQm?_@Jz`*c<nURt40~-UQ
z_5}tl{OAUQ)CE*@gF*5FD!RcSa{(3IV6eGB2;E>%xPXdoFi2cLMITt$xD7urz=#HR
L5G)dBU|;|M)oIM#

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/common.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/common.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1d3aa81c201d0bcf97afeb8657a7fbfda08ae766
GIT binary patch
literal 358
zcmd1j<>g{vU|<knUzEOsfq~&Mh=Yuo85kHG7#J9eEf^RWQW#Pga~Pr+QkbF`Q<$Te
zQdpvxQ&^)|QrMzcQ`n=}QrS~Dni-=wQW>&17jUI;E@X`2PGJmY(BygvGSjb$)utdZ
z#jc9grZg`bL?z`HgQ!#pl~<Z$moA>ix^?T0$;WOnXXd3<@zv?;B_}3lr0N%!79<vF
z^4wy|FOFgkaCC`c4)ybnVs`Qmj$(H855C3h7wU71+1JzW7He8geqzZjW=}u2TPy{M
zB^kH4QY#7)^HNHSQ;Tk~Iy*XhxUOU<;$~og5WlSTGxBp&^-B^<G86L>^^$TDQ!-PF
z^po>*3-Wc-3rciz^HWlDATH1^Ey>I&2Fc~-=jjzx-r}&y%}*)KNws4Hg^~~h0|N&W
P3lj??6f$uz3NQfxK^R}e

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/common.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/common.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4a95bf475fc0c1b5ed5fbe397eed664cc93daf29
GIT binary patch
literal 496
zcmZ3^%ge>Uz`&q%Uo~R~0|Ucj5C?{tp^VQ33=9m@8B!Qh7;_k+7*d#`7*m*|m{M4x
zm{VAzSW?)cSX0=e*q9hn*;6={F)}c$W`ycwh~h|P$l`?Y7J%)7@nCccCz>Aa6vki%
zO|F+91%6emHU)_(c2%r4rFq#PDk;AhM5RKgywV)Ibn!gaty_0YK6Z;aGcT=*uTEbt
zIWajSRlm5jAhAf3=N40b@h#>6N0(d7p?==Cn4SECZ!x=q2)|IDTg<+mez#cDa`F>P
zZZUiMx!qzZNG!>?#g$r7keHWJTAW&Ri`CiD*~4`u!)K6-etGI=<maa9mn4>CCgvsT
zCFLZhWTqDBC+FuD<m;BCR+Q+bmL=xsmn7z8CdL;h7iAWd6hoY%Us{rxQw&m>o1dpw
zQ2C3)CO1E&G$+-rNSJ|v0TgP*p$rTRAD9^#89%TwFmg3;g5U!--Uj9yScnH~+#m_=
rhSUz%#+;U%2IdDGTs`d9IixOeNL`TDzR00-g+r%-6$Fa}85kG<fB1zj

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/config.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/config.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9ca40a0457ad92a8c30fc0f85221363889e017cd
GIT binary patch
literal 4218
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
Jm_W1$GXTwohEo6l

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/config.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/config.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c702557431115d22e5cd81b51b3e043b2e3df185
GIT binary patch
literal 7268
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
IssaZD0KUHYN&o-=

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/data.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/data.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..86c2665f120944e63bad5a419675ff4d4c8cdfdc
GIT binary patch
literal 15054
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/data.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/data.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f6e9fad9bc068980a106abf82b540436629543ca
GIT binary patch
literal 25699
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
INq|cO07RSj_W%F@

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/embed.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/embed.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..06e59dca4554b13420c432192952564973ebd013
GIT binary patch
literal 13204
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
GJWl~b1v`BJ

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/embed.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/embed.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..50a582efc082811b6496eeb81a30e62f80b7f484
GIT binary patch
literal 19798
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
E0ISx{od5s;

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/field.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/field.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..67521b6cccf3e5ff86e13752f33222767dc10c66
GIT binary patch
literal 16475
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
R$ODA}%mVTZ^#W-kF#zWj;Vu9G

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/field.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/field.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..448dcecae208170106c7fee557c7e348e4ae066f
GIT binary patch
literal 24575
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
W(c%LGCNV+uBS`cMh(MDECu0Dg{q<o0

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/fn.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/fn.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9d4582deab9dc73c2dbc769f06c95e6ab6002084
GIT binary patch
literal 13456
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/fn.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/fn.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b894334d6aceb12d3be2fb5c1afb8363709ba8d3
GIT binary patch
literal 26506
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
W8LeiBd|+T^v|6A7rf?GA(iQ+l((*9?

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/logging.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/logging.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d47f1e45e93b38ad9f76e9acb3bef318cf82085f
GIT binary patch
literal 3238
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
Cq2iSQ

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/logging.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/logging.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f52d49b3cbff680cb6322a30b5b1986941d883a6
GIT binary patch
literal 5351
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
L$TYBlAUN&;ZHk}Y

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/metric.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/metric.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1eb49a374e350bfdb86f44ddc9bb384ce41fe121
GIT binary patch
literal 10873
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/metric.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/metric.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..8d685d90d287c335bc5300af1b9cb989c3df9b65
GIT binary patch
literal 20588
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
a#2m^9auIfNg4#z0kjxh_`2m9j#~lD?=~$!y

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/optim.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/optim.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..cf0d056ae56044d19b2e5e290f45058425bc2af3
GIT binary patch
literal 2798
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/optim.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/optim.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f34b83e7bcd94eda11b8b415630ab6d562cf1c79
GIT binary patch
literal 4195
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/parallel.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/parallel.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d12400edeb441199d157172e73705a9fc94003fb
GIT binary patch
literal 2976
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
a4kjK(9!3#nE*>sk9ySg>4i*j;9!>yoz<{X$

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/parallel.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/parallel.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..20c67aea66c324dbdeb02c9220e11cd0318b49f8
GIT binary patch
literal 5035
zcmZ3^%ge>Uz`&q%Up1qOoq^#ohy%l{5C-GtJq!#C(-~42QW$d>av7r-89{8O9HuCy
z6owS09OfuyFwGLhlERR}oWq*S7R8p!9>oq-#}UN=mgmgnisFWf@#OMG@iH<nF}O3N
zu(U9wu%_~6@j>ikV94T!v6eA2Fsx>V@uK)sL{d0fSfT_{L{qq1SfT_|#8Sjl_*+<`
zgi-`r7@~wz1X~!QL{fxW7@|Z|gj*P*#8Q}o88jtcf{f5)yv3cEmzQ6XSdy8aSL~<B
zbc@+Buksd$XGv;NVp2|OGDsB+GeH=PpEVd57}^=8Go&&^F{Us?F?BGcF{UuKa6~bK
zSxhY)Q7jz{6^v1=!3>(rx5QmCi%W_!lS)fcQ(O{D5(5&85_57=bCRJ3f{g_QEjI%L
z<7XQN28OAO(;1i;N*KX1U}6~q1H)=C3q)kWWoj7H7&94an3gd1fg>T9VI?ET8?42p
z1*t{1IO5|o^D;}~<26}su@tA~q}^i6%}*)KNxj9EU7lE!UVMu)K0Y}ovA8%szL<r9
zfk8n*q2ZUeenx(7sy--G67v%El5!GLGE<B6lk;;6@^wp6D@t@z%Mx?+OA_-k6XT1M
zi!uvJiuH?23lfX;OG`3yiuDViKGZ9yEaGNhV5m~S5d?ZL_X#pEFcgEr^+yB44GxK3
z)=u^w_A49`GsG@%XkFmYT3`mD;pAsfIG}_e$ob5m5Ig}5LEPcD03LoIQ(!oSaTy~6
z!)mx(EmH|7R-n=~Of`(lm>3vV!(**TpoASN$-uyXDIbg{2C=)K2F(S*44O=SMZ63Q
z44N!Oplo@IJ3c-=wIs2mq$ocA7JEiwF^GAK9V({DQpCf+z;KHtFEKau7JGS7VnIP_
zN)agYz+<;afPsObNEj3=%D7_%YG8c42q<Dg7#J9SG%(y15}&9(Mg6*v>Lnr71sNBG
z^sfl%cd*~(7Mfr_!{s8k;uUVi4-AZ)T6cw|W|%K<xhSl8MOgC!kLF!|k<Rj-^6UIc
zm-v+ym|W!7xWcb-fkUGR6z!U9pkxYiaeVwOuK0LJ0*#Nq#S<T2SelpvkpZV8u(NOR
zLX&KAYEDjkye1>Wf1qe{fOrlRD@7mz?D0T|;~N+t@B<4YtM&&5ECd@1tL6s=;s~(I
z!FJqYD@rXXEy^nbrN3m5D`05?R7!ypq#LxnKu(Z|EZoU}n(V-32xAKeYL>5MtYHKv
z2b3ZSls@G_X?_Vb&8INbG9g=oYDf_W6GJC+4MQeF4I`+;sAVbvITGq%G_@MYsXq&@
z4pkK+LkTBTJ2(%ZdL@NX5-wTGRKpa^u#(BI2$X>|S#NP>7RTo%7MG+J-D1xyj!(%f
zF1f`5CfSn`i;6N+i*B){CzfQS7J&*cP+?UBst<0lmL=wtrru&o%R^1mu=HM3C0d@C
zS)yl?lb@WJQ*5UP$p%F-NGbV&fJg`HU2c(1>mF-Riq*IwA~wNk2FnEz^#yDfMAR>c
zsCT&D<reC+?6Lg7z{II~mq(z-r_-;;ufy-Ih|~<ziM~^O7bsp4QR#5K!7tLm15OW`
zOt(1GO7oIS^7C_wZ?S^xE!JczQU_%?P}x=t@_B*+IFa6B0Xecrn}LBr8ssnwNGiR{
z%GVM<A?PBj#1&SF4@~T=q8}Jgh>y$+Y?5#}0R|r720yUnx0v&jvVQTxYOZL<yvkUV
z<OoWi;N%zwt-RA2ky8pHL88WR6)OWnEvib8H^A{)!&t+BS|&0wfRbquC{1WG7b!6?
zFx=uxPc4Zr&o9bJi7(EqO1&kRn3EF^iP-r3q^#8B5>2Ke9gs?v{G_a6a3Co_0;xy^
z6m%d09DMo=3=9nnH+Td(%%-|r5mCP=qIpF`^CGuqgUekOjw>uuGfWl;Uu03e!lHVC
zMfC<Ze}gwPXo^d7Z*dl-rj#awD*9W@#U(}9>kbV@P{Rf}Tx!s=XDw3=V+vz7I1Gx!
zkn>L#SPT>}DNHR4HB6`>6U<P<n8FOzr-nlx3#LBQItDd=RdF*gfX!uvn#+$bH-c5N
z!Bv7PW{_jC<lA6|5>TZBl}%x<VVun{mkHJGCPqyTzak?B1_qRn1ciYxs6+x)MAI2+
z7-|@+7(lKBr-_veE17OFR@`E&M2_ZP95y+Lxk)LBc2yGKNJ>RyUYLv_0|UcnP!-s~
zup)4S;L6Yj21wkp<fbO(k>G?Pb5NQBWjACe6j_5RM4Yx8gY<w}W)M4>b2Ia9G3O>$
zREdS=6_*wi<QJ8srYL~j4oYAOn(UCIs|iZhY+&)!Tg*ABc}4ahlN><8!hZQBp1B1%
zsky0nC8;T{MMe2Vn#|ywPz1IQ<mF;exvK!n4vrwrAVLpRWGn<{hr8T@6O=*aScA(A
zc7X}5m)IpQuuI<Mm$<?&e?h_Mf`ZWomy7(CSNJV2a9G~p6q=BBiBskRrwld~dz}xk
z?DX8@d6D1s0*5O|aq1;b=?k3Fclm`Tm~>Y5R9@haz#;sUPw|41+YZYMN^TdF+%EFD
zU*U7Vz~K%KFqAqAltRGekRP}lLe6Wr%AkB96jdM-z-be;qzYyLr!iQ$!;@JYpIDZd
znFDIb-{Q+G1~-K>6LT`FQd1zQ0Mz^dm&QekppXR-phzy3hlVWw6>gb}+;UgA<t}hr
zEH$~JY<5xE;)=4x1r`gE{DtaH9)<!O<p!!cSSb_CPy}+2CNsp9;6jxHRHzmu=4GRM
zL;>Ux5CKYK#c~jj@QZ=suEX{Mx4~SOIleRf=lHKEyd-0AfyDsRAMkqO8aRGZ7*iN>
z7-|`67#4uT9GyUQGpLz@y=|L<R(>!tAh$1S7#Dz2I=bNusHUedBia+Fr4gu9UI21A
z0TUP*K&=o>7HBJk=@tXHIr0+JZqsDF#a5i3oSj;7izO*DFQv!?lufzQQ%gXipl0YT
z*5sW0;#5uMA|H?xWAQB(P}WDuq_=oMQIl4bni>z1D+*#@U~mCt*I;m5++Y!G@CCse
z9DMz}UA&$AJ^T%hH&|HP-J0Aw%p3h%{2To5a`SZ*_SbgRcGmaQ&nUdYuXvGL=?b?}
zg9}KZdy{*kXNzZpC!&T!$zY(CFF1qkgGOKpQlKERSQ$f+5ponDS2S7hpiE)Ht{b^&
zhg#90Moch638>VDx*&@U%3xRkawUudr%|ID)O+^3CE^_F;us(18SLrg;~MYc8s_Qj
z8eGL3lcKH3af>Ox_!fI=URh>QeqNCiC{mb;Qg5-RW#*+M=H%RBEy*uR&bY;rT$+-2
zizg+uEHgPZJ~_WMuLLdM+!6rA8j6A#1_lOSP{g@HB92{lsn8Os3+&n#*tPHS3r#he
zVl^XeY0{Fc3x@7j)I2T<dtMRtyvXl$h2QG}hu2+hfgY>t+)9_Yl`e9tT;W!^z@h@q
zYnn{pmMFNppveL$?m?jq5!D6t^%%j`swNwfB)CEVrALS|kOob0P;V)%w4}5sH9o!w
zlzoao^-WPIs0auLg#}wlWkF_MI@qovP+y@a5+p1L4i!C6TN^qoaf=&?18KH#KosTW
z-D1kiyTt+P(u4av;AShNh6B|`ka7uB=zvpu5h&!)!uJ=4O)hxg!LBHUfq?;(-HOc_
z85lk=Gcq!MU}IoZzQCY_j2<uuT!5h)44e&Mh{RC1z<>okVBl#0!y6c~HyA`OprQ|K
zoQ#?u7%+($NprHV$T@xlNqqqk5JeJPjKUunPzfn!Mu86us00r;qX**$1{|aeBctU9
e1~|dN$Y==SLJ1Bwka=)Ih?!9pWIQ?nPDuda$Q>a7

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/tokenizer.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/tokenizer.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..cb268708f3777028bfa8541824a2616c07fc8b52
GIT binary patch
literal 9291
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/tokenizer.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/tokenizer.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..37128ac854fdfde72e08c626b1a6cda83b86d673
GIT binary patch
literal 15768
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
U1csaX$N-l60--)&qri~?02)QaGXMYp

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/transform.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/transform.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..aa125d981767ec90dad382896177289419f0d04a
GIT binary patch
literal 9574
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
Rj66&Nj2uh?%mNM~jsSB0r<VW#

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/transform.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/transform.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fd491045274e55fd2e1572e2fcbdf56acaec5e61
GIT binary patch
literal 15399
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/vocab.cpython-310.pyc b/tania_scripts/supar/utils/__pycache__/vocab.cpython-310.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..89fc3d6b458d28f39f20492fa93b0fd4981e51fd
GIT binary patch
literal 4122
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
F834(3r5gYM

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/__pycache__/vocab.cpython-311.pyc b/tania_scripts/supar/utils/__pycache__/vocab.cpython-311.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..37a8843712eaa44afd7d45ac81dfeef4e4038e50
GIT binary patch
literal 6223
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

literal 0
HcmV?d00001

diff --git a/tania_scripts/supar/utils/common.py b/tania_scripts/supar/utils/common.py
new file mode 100644
index 0000000..f320d29
--- /dev/null
+++ b/tania_scripts/supar/utils/common.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+
+import os
+
+PAD = '<pad>'
+UNK = '<unk>'
+BOS = '<bos>'
+EOS = '<eos>'
+NUL = '<nul>'
+
+MIN = -1e32
+INF = float('inf')
+
+CACHE = os.path.expanduser('~/.cache/supar')
diff --git a/tania_scripts/supar/utils/config.py b/tania_scripts/supar/utils/config.py
new file mode 100644
index 0000000..28b18ad
--- /dev/null
+++ b/tania_scripts/supar/utils/config.py
@@ -0,0 +1,85 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+import argparse
+import yaml
+import os
+from ast import literal_eval
+from configparser import ConfigParser
+from typing import Any, Dict, Optional, Sequence
+
+import supar
+from omegaconf import OmegaConf
+from supar.utils.fn import download
+
+
+class Config(object):
+
+    def __init__(self, **kwargs: Any) -> None:
+        super(Config, self).__init__()
+
+        self.update(kwargs)
+
+    def __repr__(self) -> str:
+        return yaml.dump(self.__dict__)
+
+    def __getitem__(self, key: str) -> Any:
+        return getattr(self, key)
+
+    def __contains__(self, key: str) -> bool:
+        return hasattr(self, key)
+
+    def __getstate__(self) -> Dict[str, Any]:
+        return self.__dict__
+
+    def __setstate__(self, state: Dict[str, Any]) -> None:
+        self.__dict__.update(state)
+
+    @property
+    def primitive_config(self) -> Dict[str, Any]:
+        from enum import Enum
+        from pathlib import Path
+        primitive_types = (int, float, bool, str, bytes, Enum, Path)
+        return {name: value for name, value in self.__dict__.items() if type(value) in primitive_types}
+
+    def keys(self) -> Any:
+        return self.__dict__.keys()
+
+    def items(self) -> Any:
+        return self.__dict__.items()
+
+    def update(self, kwargs: Dict[str, Any]) -> Config:
+        for key in ('self', 'cls', '__class__'):
+            kwargs.pop(key, None)
+        kwargs.update(kwargs.pop('kwargs', dict()))
+        for name, value in kwargs.items():
+            setattr(self, name, value)
+        return self
+
+    def get(self, key: str, default: Optional[Any] = None) -> Any:
+        return getattr(self, key, default)
+
+    def pop(self, key: str, default: Optional[Any] = None) -> Any:
+        return self.__dict__.pop(key, default)
+
+    def save(self, path):
+        with open(path, 'w') as f:
+            f.write(str(self))
+
+    @classmethod
+    def load(cls, conf: str = '', unknown: Optional[Sequence[str]] = None, **kwargs: Any) -> Config:
+        if conf and not os.path.exists(conf):
+            conf = download(supar.CONFIG['github'].get(conf, conf))
+        if conf.endswith(('.yml', '.yaml')):
+            config = OmegaConf.load(conf)
+        else:
+            config = ConfigParser()
+            config.read(conf)
+            config = dict((name, literal_eval(value)) for s in config.sections() for name, value in config.items(s))
+        if unknown is not None:
+            parser = argparse.ArgumentParser()
+            for name, value in config.items():
+                parser.add_argument('--'+name.replace('_', '-'), type=type(value), default=value)
+            config.update(vars(parser.parse_args(unknown)))
+        return cls(**config).update(kwargs)
diff --git a/tania_scripts/supar/utils/data.py b/tania_scripts/supar/utils/data.py
new file mode 100644
index 0000000..587b32d
--- /dev/null
+++ b/tania_scripts/supar/utils/data.py
@@ -0,0 +1,344 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+import itertools
+import os
+import queue
+import shutil
+import tempfile
+import threading
+from contextlib import contextmanager
+from typing import Dict, Iterable, List, Union
+
+import pathos.multiprocessing as mp
+import torch
+import torch.distributed as dist
+from supar.utils.common import INF
+from supar.utils.fn import binarize, debinarize, kmeans
+from supar.utils.logging import get_logger, progress_bar
+from supar.utils.parallel import is_dist, is_master
+from supar.utils.transform import Batch, Transform
+from torch.distributions.utils import lazy_property
+
+logger = get_logger(__name__)
+
+
+class Dataset(torch.utils.data.Dataset):
+    r"""
+    Dataset that is compatible with :class:`torch.utils.data.Dataset`, serving as a wrapper for manipulating all data fields
+    with the operating behaviours defined in :class:`~supar.utils.transform.Transform`.
+    The data fields of all the instantiated sentences can be accessed as an attribute of the dataset.
+
+    Args:
+        transform (Transform):
+            An instance of :class:`~supar.utils.transform.Transform` or its derivations.
+            The instance holds a series of loading and processing behaviours with regard to the specific data format.
+        data (Union[str, Iterable]):
+            A filename or a list of instances that will be passed into :meth:`transform.load`.
+        cache (bool):
+            If ``True``, tries to use the previously cached binarized data for fast loading.
+            In this way, sentences are loaded on-the-fly according to the meta data.
+            If ``False``, all sentences will be directly loaded into the memory.
+            Default: ``False``.
+        binarize (bool):
+            If ``True``, binarizes the dataset once building it. Only works if ``cache=True``. Default: ``False``.
+        bin (str):
+            Path for saving binarized files, required if ``cache=True``. Default: ``None``.
+        max_len (int):
+            Sentences exceeding the length will be discarded. Default: ``None``.
+        kwargs (Dict):
+            Together with `data`, kwargs will be passed into :meth:`transform.load` to control the loading behaviour.
+
+    Attributes:
+        transform (Transform):
+            An instance of :class:`~supar.utils.transform.Transform`.
+        sentences (List[Sentence]):
+            A list of sentences loaded from the data.
+            Each sentence includes fields obeying the data format defined in ``transform``.
+            If ``cache=True``, each is a pointer to the sentence stored in the cache file.
+    """
+
+    def __init__(
+        self,
+        transform: Transform,
+        data: Union[str, Iterable],
+        cache: bool = False,
+        binarize: bool = False,
+        bin: str = None,
+        max_len: int = None,
+        **kwargs
+    ) -> Dataset:
+        super(Dataset, self).__init__()
+
+        self.transform = transform
+        self.data = data
+        self.cache = cache
+        self.binarize = binarize
+        self.bin = bin
+        self.max_len = max_len or INF
+        self.kwargs = kwargs
+
+        if cache:
+            if not isinstance(data, str) or not os.path.exists(data):
+                raise FileNotFoundError("Only files are allowed for binarization, but not found")
+            if self.bin is None:
+                self.fbin = data + '.pt'
+            else:
+                os.makedirs(self.bin, exist_ok=True)
+                self.fbin = os.path.join(self.bin, os.path.split(data)[1]) + '.pt'
+            if not self.binarize and os.path.exists(self.fbin):
+                try:
+                    self.sentences = debinarize(self.fbin, meta=True)['sentences']
+                except Exception:
+                    raise RuntimeError(f"Error found while debinarizing {self.fbin}, which may have been corrupted. "
+                                       "Try re-binarizing it first!")
+        else:
+            self.sentences = list(transform.load(data, **kwargs))
+
+
+    def __repr__(self):
+        s = f"{self.__class__.__name__}("
+        s += f"n_sentences={len(self.sentences)}"
+        if hasattr(self, 'loader'):
+            s += f", n_batches={len(self.loader)}"
+        if hasattr(self, 'buckets'):
+            s += f", n_buckets={len(self.buckets)}"
+        if self.cache:
+            s += f", cache={self.cache}"
+        if self.binarize:
+            s += f", binarize={self.binarize}"
+        if self.max_len < INF:
+            s += f", max_len={self.max_len}"
+        s += ")"
+        return s
+
+    def __len__(self):
+        return len(self.sentences)
+
+    def __getitem__(self, index):
+        return debinarize(self.fbin, self.sentences[index]) if self.cache else self.sentences[index]
+
+    def __getattr__(self, name):
+        if name not in {f.name for f in self.transform.flattened_fields}:
+            raise AttributeError
+        if self.cache:
+            if os.path.exists(self.fbin) and not self.binarize:
+                sentences = self
+            else:
+                sentences = self.transform.load(self.data, **self.kwargs)
+            return (getattr(sentence, name) for sentence in sentences)
+        return [getattr(sentence, name) for sentence in self.sentences]
+
+    def __getstate__(self):
+        return self.__dict__
+
+    def __setstate__(self, state):
+        self.__dict__.update(state)
+
+    @lazy_property
+    def sizes(self):
+        if not self.cache:
+            return [s.size for s in self.sentences]
+        return debinarize(self.fbin, 'sizes')
+
+    def build(
+        self,
+        batch_size: int,
+        n_buckets: int = 1,
+        shuffle: bool = False,
+        distributed: bool = False,
+        even: bool = True,
+        n_workers: int = 0,
+        pin_memory: bool = True,
+        chunk_size: int = 1000,
+    ) -> Dataset:
+        # numericalize all fields
+        if not self.cache:
+            self.sentences = [i for i in self.transform(self.sentences) if len(i) < self.max_len]
+        else:
+            # if not forced to do binarization and the binarized file already exists, directly load the meta file
+            if os.path.exists(self.fbin) and not self.binarize:
+                self.sentences = debinarize(self.fbin, meta=True)['sentences']
+            else:
+                @contextmanager
+                def cache(sentences):
+                    ftemp = tempfile.mkdtemp()
+                    fs = os.path.join(ftemp, 'sentences')
+                    fb = os.path.join(ftemp, os.path.basename(self.fbin))
+                    global global_transform
+                    global_transform = self.transform
+                    sentences = binarize({'sentences': progress_bar(sentences)}, fs)[1]['sentences']
+                    try:
+                        yield ((sentences[s:s+chunk_size], fs, f"{fb}.{i}", self.max_len)
+                               for i, s in enumerate(range(0, len(sentences), chunk_size)))
+                    finally:
+                        del global_transform
+                        shutil.rmtree(ftemp)
+
+                def numericalize(sentences, fs, fb, max_len):
+                    sentences = global_transform((debinarize(fs, sentence) for sentence in sentences))
+                    sentences = [i for i in sentences if len(i) < max_len]
+                    return binarize({'sentences': sentences, 'sizes': [sentence.size for sentence in sentences]}, fb)[0]
+
+                logger.info(f"Seeking to cache the data to {self.fbin} first")
+                # numericalize the fields of each sentence
+                if is_master():
+                    with cache(self.transform.load(self.data, **self.kwargs)) as chunks, mp.Pool(32) as pool:
+                        results = [pool.apply_async(numericalize, chunk) for chunk in chunks]
+                        self.sentences = binarize((r.get() for r in results), self.fbin, merge=True)[1]['sentences']
+                if is_dist():
+                    dist.barrier()
+                if not is_master():
+                    self.sentences = debinarize(self.fbin, meta=True)['sentences']
+        # NOTE: the final bucket count is roughly equal to n_buckets
+        self.buckets = dict(zip(*kmeans(self.sizes, n_buckets)))
+        self.loader = DataLoader(transform=self.transform,
+                                 dataset=self,
+                                 batch_sampler=Sampler(self.buckets, batch_size, shuffle, distributed, even),
+                                 num_workers=n_workers,
+                                 collate_fn=collate_fn,
+                                 pin_memory=pin_memory)
+        return self
+
+
+class Sampler(torch.utils.data.Sampler):
+    r"""
+    Sampler that supports for bucketization and token-level batchification.
+
+    Args:
+        buckets (Dict):
+            A dict that maps each centroid to indices of clustered sentences.
+            The centroid corresponds to the average length of all sentences in the bucket.
+        batch_size (int):
+            Token-level batch size. The resulting batch contains roughly the same number of tokens as ``batch_size``.
+        shuffle (bool):
+            If ``True``, the sampler will shuffle both buckets and samples in each bucket. Default: ``False``.
+        distributed (bool):
+            If ``True``, the sampler will be used in conjunction with :class:`torch.nn.parallel.DistributedDataParallel`
+            that restricts data loading to a subset of the dataset.
+            Default: ``False``.
+        even (bool):
+            If ``True``, the sampler will add extra indices to make the data evenly divisible across the replicas.
+            Default: ``True``.
+    """
+
+    def __init__(
+        self,
+        buckets: Dict[float, List],
+        batch_size: int,
+        shuffle: bool = False,
+        distributed: bool = False,
+        even: bool = True
+    ) -> Sampler:
+        self.batch_size = batch_size
+        self.shuffle = shuffle
+        self.distributed = distributed
+        self.even = even
+        #print("237 utils data buckets items", buckets.items()) 
+        self.sizes, self.buckets = zip(*[(size, bucket) for size, bucket in buckets.items()])
+        # number of batches in each bucket, clipped by range [1, len(bucket)]
+        self.n_batches = [min(len(bucket), max(round(size * len(bucket) / batch_size), 1))
+                          for size, bucket in zip(self.sizes, self.buckets)]
+        self.rank, self.n_replicas, self.n_samples = 0, 1, self.n_total_samples
+
+        if distributed:
+            self.rank = dist.get_rank()
+            self.n_replicas = dist.get_world_size()
+            self.n_samples = self.n_total_samples // self.n_replicas
+            if self.n_total_samples % self.n_replicas != 0:
+                self.n_samples += 1 if even else int(self.rank < self.n_total_samples % self.n_replicas)
+        self.epoch = 1
+
+    def __iter__(self):
+        g = torch.Generator()
+        g.manual_seed(self.epoch)
+        self.epoch += 1
+
+        total, batches = 0, []
+        # if `shuffle=True`, shuffle both the buckets and samples in each bucket
+        # for distributed training, make sure each process generates the same random sequence at each epoch
+        range_fn = torch.arange if not self.shuffle else lambda x: torch.randperm(x, generator=g)
+        for i in itertools.cycle(range(len(self.buckets))):
+            bucket = self.buckets[i]
+            split_sizes = [(len(bucket) - j - 1) // self.n_batches[i] + 1 for j in range(self.n_batches[i])]
+            # DON'T use `torch.chunk` which may return wrong number of batches
+            for batch in range_fn(len(bucket)).split(split_sizes):
+                #print('supar utils 270', batch)
+                if total % self.n_replicas == self.rank:
+                    batches.append([bucket[j] for j in batch.tolist()])
+                if len(batches) == self.n_samples:
+                    return iter(batches[i] for i in range_fn(self.n_samples).tolist())
+                total += 1
+
+    def __len__(self):
+        return self.n_samples
+
+    @property
+    def n_total_samples(self):
+        return sum(self.n_batches)
+
+    def set_epoch(self, epoch: int) -> None:
+        self.epoch = epoch
+
+
+class DataLoader(torch.utils.data.DataLoader):
+
+    r"""
+    A wrapper for native :class:`torch.utils.data.DataLoader` enhanced with a data prefetcher.
+    See http://stackoverflow.com/questions/7323664/python-generator-pre-fetch and
+    https://github.com/NVIDIA/apex/issues/304.
+    """
+
+    def __init__(self, transform, **kwargs):
+        super().__init__(**kwargs)
+
+        self.transform = transform
+
+    def __iter__(self):
+        return PrefetchGenerator(self.transform, super().__iter__())
+
+
+class PrefetchGenerator(threading.Thread):
+
+    def __init__(self, transform, loader, prefetch=1):
+        threading.Thread.__init__(self)
+
+        self.transform = transform
+
+        self.queue = queue.Queue(prefetch)
+        self.loader = loader
+        self.daemon = True
+        if torch.cuda.is_available():
+            self.stream = torch.cuda.Stream()
+
+        self.start()
+
+    def __iter__(self):
+        return self
+
+    def __next__(self):
+        if hasattr(self, 'stream'):
+            torch.cuda.current_stream().wait_stream(self.stream)
+        batch = self.queue.get()
+        if batch is None:
+            raise StopIteration
+        return batch
+
+    def run(self):
+        # `torch.cuda.current_device` is thread local
+        # see https://github.com/pytorch/pytorch/issues/56588
+        if is_dist() and torch.cuda.is_available():
+            torch.cuda.set_device(dist.get_rank())
+        if hasattr(self, 'stream'):
+            with torch.cuda.stream(self.stream):
+                for batch in self.loader:
+                    self.queue.put(batch.compose(self.transform))
+        else:
+            for batch in self.loader:
+                self.queue.put(batch.compose(self.transform))
+        self.queue.put(None)
+
+
+def collate_fn(x):
+    return Batch(x)
diff --git a/tania_scripts/supar/utils/embed.py b/tania_scripts/supar/utils/embed.py
new file mode 100644
index 0000000..c132b4d
--- /dev/null
+++ b/tania_scripts/supar/utils/embed.py
@@ -0,0 +1,334 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+import os
+from typing import Iterable, Optional, Union
+
+import torch
+from supar.utils.common import CACHE
+from supar.utils.fn import download
+from supar.utils.logging import progress_bar
+from torch.distributions.utils import lazy_property
+
+
+class Embedding(object):
+    r"""
+    Defines a container object for holding pretrained embeddings.
+    This object is callable and behaves like :class:`torch.nn.Embedding`.
+    For huge files, this object supports lazy loading, seeking to retrieve vectors from the disk on the fly if necessary.
+
+    Currently available embeddings:
+        - `GloVe`_
+        - `Fasttext`_
+        - `Giga`_
+        - `Tencent`_
+
+    Args:
+        path (str):
+            Path to the embedding file or short name registered in ``supar.utils.embed.PRETRAINED``.
+        unk (Optional[str]):
+            The string token used to represent OOV tokens. Default: ``None``.
+        skip_first (bool)
+            If ``True``, skips the first line of the embedding file. Default: ``False``.
+        cache (bool):
+            If ``True``, instead of loading entire embeddings into memory, seeks to load vectors from the disk once called.
+            Default: ``True``.
+        sep (str):
+            Separator used by embedding file. Default: ``' '``.
+
+    Examples:
+        >>> import torch.nn as nn
+        >>> from supar.utils.embed import Embedding
+        >>> glove = Embedding.load('glove-6b-100')
+        >>> glove
+        GloVeEmbedding(n_tokens=400000, dim=100, unk=unk, cache=True)
+        >>> fasttext = Embedding.load('fasttext-en')
+        >>> fasttext
+        FasttextEmbedding(n_tokens=2000000, dim=300, skip_first=True, cache=True)
+        >>> giga = Embedding.load('giga-100')
+        >>> giga
+        GigaEmbedding(n_tokens=372846, dim=100, cache=True)
+        >>> indices = torch.tensor([glove.vocab[i.lower()] for i in ['She', 'enjoys', 'playing', 'tennis', '.']])
+        >>> indices
+        tensor([  67, 8371,  697, 2140,    2])
+        >>> glove(indices).shape
+        torch.Size([5, 100])
+        >>> glove(indices).equal(nn.Embedding.from_pretrained(glove.vectors)(indices))
+        True
+
+    .. _GloVe:
+        https://nlp.stanford.edu/projects/glove/
+    .. _Fasttext:
+        https://fasttext.cc/docs/en/crawl-vectors.html
+    .. _Giga:
+        https://github.com/yzhangcs/parser/releases/download/v1.1.0/giga.100.zip
+    .. _Tencent:
+        https://ai.tencent.com/ailab/nlp/zh/download.html
+    """
+
+    CACHE = os.path.join(CACHE, 'data/embeds')
+
+    def __init__(
+        self,
+        path: str,
+        unk: Optional[str] = None,
+        skip_first: bool = False,
+        cache: bool = True,
+        sep: str = ' ',
+        **kwargs
+    ) -> Embedding:
+        super().__init__()
+
+        self.path = path
+        self.unk = unk
+        self.skip_first = skip_first
+        self.cache = cache
+        self.sep = sep
+        self.kwargs = kwargs
+
+        self.vocab = {token: i for i, token in enumerate(self.tokens)}
+
+    def __len__(self):
+        return len(self.vocab)
+
+    def __repr__(self):
+        s = f"{self.__class__.__name__}("
+        s += f"n_tokens={len(self)}, dim={self.dim}"
+        if self.unk is not None:
+            s += f", unk={self.unk}"
+        if self.skip_first:
+            s += f", skip_first={self.skip_first}"
+        if self.cache:
+            s += f", cache={self.cache}"
+        s += ")"
+        return s
+
+    def __contains__(self, token):
+        return token in self.vocab
+
+    def __getitem__(self, key: Union[int, Iterable[int], torch.Tensor]) -> torch.Tensor:
+        indices = key
+        if not isinstance(indices, torch.Tensor):
+            indices = torch.tensor(key)
+        if self.cache:
+            elems, indices = indices.unique(return_inverse=True)
+            with open(self.path) as f:
+                vectors = []
+                for index in elems.tolist():
+                    f.seek(self.positions[index])
+                    vectors.append(list(map(float, f.readline().strip().split(self.sep)[1:])))
+                vectors = torch.tensor(vectors)
+        else:
+            vectors = self.vectors
+        return torch.embedding(vectors, indices)
+
+    def __call__(self, key: Union[int, Iterable[int], torch.Tensor]) -> torch.Tensor:
+        return self[key]
+
+    @lazy_property
+    def dim(self):
+        return len(self[0])
+
+    @lazy_property
+    def unk_index(self):
+        if self.unk is not None:
+            return self.vocab[self.unk]
+        raise AttributeError
+
+    @lazy_property
+    def tokens(self):
+        with open(self.path) as f:
+            if self.skip_first:
+                f.readline()
+            return [line.strip().split(self.sep)[0] for line in progress_bar(f)]
+
+    @lazy_property
+    def vectors(self):
+        with open(self.path) as f:
+            if self.skip_first:
+                f.readline()
+            return torch.tensor([list(map(float, line.strip().split(self.sep)[1:])) for line in progress_bar(f)])
+
+    @lazy_property
+    def positions(self):
+        with open(self.path) as f:
+            if self.skip_first:
+                f.readline()
+            positions = [f.tell()]
+            while True:
+                line = f.readline()
+                if line:
+                    positions.append(f.tell())
+                else:
+                    break
+            return positions
+
+    @classmethod
+    def load(cls, path: str, unk: Optional[str] = None, **kwargs) -> Embedding:
+        if path in PRETRAINED:
+            cfg = dict(**PRETRAINED[path])
+            embed = cfg.pop('_target_')
+            return embed(**cfg, **kwargs)
+        return cls(path, unk, **kwargs)
+
+
+class GloVeEmbedding(Embedding):
+
+    r"""
+    `GloVe`_: Global Vectors for Word Representation.
+    Training is performed on aggregated global word-word co-occurrence statistics from a corpus,
+    and the resulting representations showcase interesting linear substructures of the word vector space.
+
+    Args:
+        src (str):
+            Size of the source data for training. Default: ``6B``.
+        dim (int):
+            Which dimension of the embeddings to use. Default: 100.
+        reload (bool):
+                If ``True``, forces a fresh download. Default: ``False``.
+
+    Examples:
+        >>> from supar.utils.embed import Embedding
+        >>> Embedding.load('glove-6b-100')
+        GloVeEmbedding(n_tokens=400000, dim=100, unk=unk, cache=True)
+
+    .. _GloVe:
+        https://nlp.stanford.edu/projects/glove/
+    """
+
+    def __init__(self, src: str = '6B', dim: int = 100, reload=False, *args, **kwargs) -> GloVeEmbedding:
+        if src == '6B' or src == 'twitter.27B':
+            url = f'https://nlp.stanford.edu/data/glove.{src}.zip'
+        else:
+            url = f'https://nlp.stanford.edu/data/glove.{src}.{dim}d.zip'
+        path = os.path.join(os.path.join(self.CACHE, 'glove'), f'glove.{src}.{dim}d.txt')
+        if not os.path.exists(path) or reload:
+            download(url, os.path.join(self.CACHE, 'glove'), clean=True)
+
+        super().__init__(path=path, unk='unk', *args, **kwargs, )
+
+
+class FasttextEmbedding(Embedding):
+
+    r"""
+    `Fasttext`_ word embeddings for 157 languages, trained using CBOW, in dimension 300,
+    with character n-grams of length 5, a window of size 5 and 10 negatives.
+
+    Args:
+        lang (str):
+            Language code. Default: ``en``.
+        reload (bool):
+                If ``True``, forces a fresh download. Default: ``False``.
+
+    Examples:
+        >>> from supar.utils.embed import Embedding
+        >>> Embedding.load('fasttext-en')
+        FasttextEmbedding(n_tokens=2000000, dim=300, skip_first=True, cache=True)
+
+    .. _Fasttext:
+        https://fasttext.cc/docs/en/crawl-vectors.html
+    """
+
+    def __init__(self, lang: str = 'en', reload=False, *args, **kwargs) -> FasttextEmbedding:
+        url = f'https://dl.fbaipublicfiles.com/fasttext/vectors-crawl/cc.{lang}.300.vec.gz'
+        path = os.path.join(self.CACHE, 'fasttext', f'cc.{lang}.300.vec')
+        if not os.path.exists(path) or reload:
+            download(url, os.path.join(self.CACHE, 'fasttext'), clean=True)
+
+        super().__init__(path=path, skip_first=True, *args, **kwargs)
+
+
+class GigaEmbedding(Embedding):
+
+    r"""
+    `Giga`_ word embeddings, trained on Chinese Gigaword Third Edition for Chinese using word2vec,
+    used by :cite:`zhang-etal-2020-efficient` and :cite:`zhang-etal-2020-fast`.
+
+    Args:
+        reload (bool):
+            If ``True``, forces a fresh download. Default: ``False``.
+
+    Examples:
+        >>> from supar.utils.embed import Embedding
+        >>> Embedding.load('giga-100')
+        GigaEmbedding(n_tokens=372846, dim=100, cache=True)
+
+    .. _Giga:
+        https://github.com/yzhangcs/parser/releases/download/v1.1.0/giga.100.zip
+    """
+
+    def __init__(self, reload=False, *args, **kwargs) -> GigaEmbedding:
+        url = 'https://github.com/yzhangcs/parser/releases/download/v1.1.0/giga.100.zip'
+        path = os.path.join(self.CACHE, 'giga', 'giga.100.txt')
+        if not os.path.exists(path) or reload:
+            download(url, os.path.join(self.CACHE, 'giga'), clean=True)
+
+        super().__init__(path=path, *args, **kwargs)
+
+
+class TencentEmbedding(Embedding):
+
+    r"""
+    `Tencent`_ word embeddings.
+    The embeddings are trained on large-scale text collected from news, webpages, and novels with Directional Skip-Gram.
+    100-dimension and 200-dimension embeddings for over 12 million Chinese words are provided.
+
+    Args:
+        dim (int):
+            Which dimension of the embeddings to use. Currently 100 and 200 are available. Default: 100.
+        large (bool):
+            If ``True``, uses large version with larger vocab size (12,287,933); 2,000,000 otherwise. Default: ``False``.
+        reload (bool):
+            If ``True``, forces a fresh download. Default: ``False``.
+
+    Examples:
+        >>> from supar.utils.embed import Embedding
+        >>> Embedding.load('tencent-100')
+        TencentEmbedding(n_tokens=2000000, dim=100, skip_first=True, cache=True)
+        >>> Embedding.load('tencent-100-large')
+        TencentEmbedding(n_tokens=12287933, dim=100, skip_first=True, cache=True)
+
+    .. _Tencent:
+        https://ai.tencent.com/ailab/nlp/zh/download.html
+    """
+
+    def __init__(self, dim: int = 100, large: bool = False, reload=False, *args, **kwargs) -> TencentEmbedding:
+        url = f'https://ai.tencent.com/ailab/nlp/zh/data/tencent-ailab-embedding-zh-d{dim}-v0.2.0{"" if large else "-s"}.tar.gz'  # noqa
+        name = f'tencent-ailab-embedding-zh-d{dim}-v0.2.0{"" if large else "-s"}'
+        path = os.path.join(os.path.join(self.CACHE, 'tencent'), name, f'{name}.txt')
+        if not os.path.exists(path) or reload:
+            download(url, os.path.join(self.CACHE, 'tencent'), clean=True)
+
+        super().__init__(path=path, skip_first=True, *args, **kwargs)
+
+
+PRETRAINED = {
+    'glove-6b-50': {'_target_': GloVeEmbedding, 'src': '6B', 'dim': 50},
+    'glove-6b-100': {'_target_': GloVeEmbedding, 'src': '6B', 'dim': 100},
+    'glove-6b-200': {'_target_': GloVeEmbedding, 'src': '6B', 'dim': 200},
+    'glove-6b-300': {'_target_': GloVeEmbedding, 'src': '6B', 'dim': 300},
+    'glove-42b-300': {'_target_': GloVeEmbedding, 'src': '42B', 'dim': 300},
+    'glove-840b-300': {'_target_': GloVeEmbedding, 'src': '84B', 'dim': 300},
+    'glove-twitter-27b-25': {'_target_': GloVeEmbedding, 'src': 'twitter.27B', 'dim': 25},
+    'glove-twitter-27b-50': {'_target_': GloVeEmbedding, 'src': 'twitter.27B', 'dim': 50},
+    'glove-twitter-27b-100': {'_target_': GloVeEmbedding, 'src': 'twitter.27B', 'dim': 100},
+    'glove-twitter-27b-200': {'_target_': GloVeEmbedding, 'src': 'twitter.27B', 'dim': 200},
+    'fasttext-bg': {'_target_': FasttextEmbedding, 'lang': 'bg'},
+    'fasttext-ca': {'_target_': FasttextEmbedding, 'lang': 'ca'},
+    'fasttext-cs': {'_target_': FasttextEmbedding, 'lang': 'cs'},
+    'fasttext-de': {'_target_': FasttextEmbedding, 'lang': 'de'},
+    'fasttext-en': {'_target_': FasttextEmbedding, 'lang': 'en'},
+    'fasttext-es': {'_target_': FasttextEmbedding, 'lang': 'es'},
+    'fasttext-fr': {'_target_': FasttextEmbedding, 'lang': 'fr'},
+    'fasttext-it': {'_target_': FasttextEmbedding, 'lang': 'it'},
+    'fasttext-nl': {'_target_': FasttextEmbedding, 'lang': 'nl'},
+    'fasttext-no': {'_target_': FasttextEmbedding, 'lang': 'no'},
+    'fasttext-ro': {'_target_': FasttextEmbedding, 'lang': 'ro'},
+    'fasttext-ru': {'_target_': FasttextEmbedding, 'lang': 'ru'},
+    'giga-100': {'_target_': GigaEmbedding},
+    'tencent-100': {'_target_': TencentEmbedding, 'dim': 100},
+    'tencent-100-large': {'_target_': TencentEmbedding, 'dim': 100, 'large': True},
+    'tencent-200': {'_target_': TencentEmbedding, 'dim': 200},
+    'tencent-200-large': {'_target_': TencentEmbedding, 'dim': 200, 'large': True},
+}
diff --git a/tania_scripts/supar/utils/field.py b/tania_scripts/supar/utils/field.py
new file mode 100644
index 0000000..dd14bc7
--- /dev/null
+++ b/tania_scripts/supar/utils/field.py
@@ -0,0 +1,415 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+from collections import Counter
+from typing import Callable, Iterable, List, Optional, Union
+
+import torch
+from supar.utils.data import Dataset
+from supar.utils.embed import Embedding
+from supar.utils.fn import pad
+from supar.utils.logging import progress_bar
+from supar.utils.parallel import wait
+from supar.utils.vocab import Vocab
+
+
+class RawField(object):
+    r"""
+    Defines a general datatype.
+
+    A :class:`RawField` object does not assume any property of the datatype and
+    it holds parameters relating to how a datatype should be processed.
+
+    Args:
+        name (str):
+            The name of the field.
+        fn (function):
+            The function used for preprocessing the examples. Default: ``None``.
+    """
+
+    def __init__(self, name: str, fn: Optional[Callable] = None) -> RawField:
+        self.name = name
+        self.fn = fn
+
+    def __repr__(self):
+        return f"({self.name}): {self.__class__.__name__}()"
+
+    def preprocess(self, sequence: Iterable) -> Iterable:
+        return self.fn(sequence) if self.fn is not None else sequence
+
+    def transform(self, sequences: Iterable[List]) -> Iterable[List]:
+        return (self.preprocess(seq) for seq in sequences)
+
+    def compose(self, sequences: Iterable[List]) -> Iterable[List]:
+        return sequences
+
+
+class Field(RawField):
+    r"""
+    Defines a datatype together with instructions for converting to :class:`~torch.Tensor`.
+    :class:`Field` models common text processing datatypes that can be represented by tensors.
+    It holds a :class:`~supar.utils.vocab.Vocab` object that defines the set of possible values
+    for elements of the field and their corresponding numerical representations.
+    The :class:`Field` object also holds other parameters relating to how a datatype
+    should be numericalized, such as a tokenization method.
+
+    Args:
+        name (str):
+            The name of the field.
+        pad_token (str):
+            The string token used as padding. Default: ``None``.
+        unk_token (str):
+            The string token used to represent OOV words. Default: ``None``.
+        bos_token (str):
+            A token that will be prepended to every example using this field, or ``None`` for no `bos_token`.
+            Default: ``None``.
+        eos_token (str):
+            A token that will be appended to every example using this field, or ``None`` for no `eos_token`.
+        lower (bool):
+            Whether to lowercase the text in this field. Default: ``False``.
+        use_vocab (bool):
+            Whether to use a :class:`~supar.utils.vocab.Vocab` object.
+            If ``False``, the data in this field should already be numerical.
+            Default: ``True``.
+        tokenize (function):
+            The function used to tokenize strings using this field into sequential examples. Default: ``None``.
+        fn (function):
+            The function used for preprocessing the examples. Default: ``None``.
+    """
+
+    def __init__(
+        self,
+        name: str,
+        pad: Optional[str] = None,
+        unk: Optional[str] = None,
+        bos: Optional[str] = None,
+        eos: Optional[str] = None,
+        lower: bool = False,
+        use_vocab: bool = True,
+        tokenize: Optional[Callable] = None,
+        fn: Optional[Callable] = None,
+        delay: Optional[int] = 0
+    ) -> Field:
+        self.name = name
+        self.pad = pad
+        self.unk = unk
+        self.bos = bos
+        self.eos = eos
+        self.lower = lower
+        self.use_vocab = use_vocab
+        self.tokenize = tokenize
+        self.fn = fn
+        self.delay = delay
+
+        self.specials = [token for token in [pad, unk, bos, eos] if token is not None]
+
+    def __repr__(self):
+        s, params = f"({self.name}): {self.__class__.__name__}(", []
+        if hasattr(self, 'vocab'):
+            params.append(f"vocab_size={len(self.vocab)}")
+        if self.pad is not None:
+            params.append(f"pad={self.pad}")
+        if self.unk is not None:
+            params.append(f"unk={self.unk}")
+        if self.bos is not None:
+            params.append(f"bos={self.bos}")
+        if self.eos is not None:
+            params.append(f"eos={self.eos}")
+        if self.lower:
+            params.append(f"lower={self.lower}")
+        if not self.use_vocab:
+            params.append(f"use_vocab={self.use_vocab}")
+        if self.delay > 0:
+            params.append(f'delay={self.delay}')
+        return s + ', '.join(params) + ')'
+
+    @property
+    def pad_index(self):
+        if self.pad is None:
+            return 0
+        if hasattr(self, 'vocab'):
+            return self.vocab[self.pad]
+        return self.specials.index(self.pad)
+
+    @property
+    def unk_index(self):
+        if self.unk is None:
+            return 0
+        if hasattr(self, 'vocab'):
+            return self.vocab[self.unk]
+        return self.specials.index(self.unk)
+
+    @property
+    def bos_index(self):
+        if hasattr(self, 'vocab'):
+            return self.vocab[self.bos]
+        return self.specials.index(self.bos)
+
+    @property
+    def eos_index(self):
+        if hasattr(self, 'vocab'):
+            return self.vocab[self.eos]
+        return self.specials.index(self.eos)
+
+    @property
+    def device(self):
+        return 'cuda' if torch.cuda.is_available() else 'cpu'
+
+    def preprocess(self, data: Union[str, Iterable]) -> Iterable:
+        r"""
+        Loads a single example and tokenize it if necessary.
+        The sequence will be first passed to ``fn`` if available.
+        If ``tokenize`` is not None, the input will be tokenized.
+        Then the input will be lowercased optionally.
+
+        Args:
+            data (Union[str, Iterable]):
+                The data to be preprocessed.
+
+        Returns:
+            A list of preprocessed sequence.
+        """
+
+        if self.fn is not None:
+            data = self.fn(data)
+        if self.tokenize is not None:
+            data = self.tokenize(data)
+        if self.lower:
+            data = [str.lower(token) for token in data]
+        return data
+
+    def build(
+        self,
+        dataset: Dataset,
+        min_freq: int = 1,
+        embed: Optional[Embedding] = None,
+        norm: Callable = None
+    ) -> Field:
+        r"""
+        Constructs a :class:`~supar.utils.vocab.Vocab` object for this field from the dataset.
+        If the vocabulary has already existed, this function will have no effect.
+
+        Args:
+            dataset (Dataset):
+                A :class:`~supar.utils.data.Dataset` object.
+                One of the attributes should be named after the name of this field.
+            min_freq (int):
+                The minimum frequency needed to include a token in the vocabulary. Default: 1.
+            embed (Embedding):
+                An Embedding object, words in which will be extended to the vocabulary. Default: ``None``.
+            norm (Callable):
+                Callable function used for normalizing embedding weights. Default: ``None``.
+        """
+
+        if hasattr(self, 'vocab'):
+            return
+
+        @wait
+        def build_vocab(dataset):
+            return Vocab(counter=Counter(token
+                                         for seq in progress_bar(getattr(dataset, self.name))
+                                         for token in self.preprocess(seq)),
+                         min_freq=min_freq,
+                         specials=self.specials,
+                         unk_index=self.unk_index)
+        self.vocab = build_vocab(dataset)
+
+        if not embed:
+            self.embed = None
+        else:
+            tokens = self.preprocess(embed.tokens)
+            # replace the `unk` token in the pretrained with a self-defined one if existed
+            if embed.unk:
+                tokens[embed.unk_index] = self.unk
+
+            self.vocab.update(tokens)
+            self.embed = torch.zeros(len(self.vocab), embed.dim)
+            self.embed[self.vocab[tokens]] = embed.vectors
+            if norm is not None:
+                self.embed = norm(self.embed)
+        return self
+
+    def transform(self, sequences: Iterable[List[str]]) -> Iterable[torch.Tensor]:
+        r"""
+        Turns a list of sequences that use this field into tensors.
+
+        Each sequence is first preprocessed and then numericalized if needed.
+
+        Args:
+            sequences (Iterable[List[str]]):
+                A list of sequences.
+
+        Returns:
+            A list of tensors transformed from the input sequences.
+        """
+
+        for seq in sequences:
+            seq = self.preprocess(seq)
+            if self.use_vocab:
+                try:
+                    seq = [self.vocab[token] for token in seq]
+                except:
+                    raise AssertionError
+            if self.bos:
+                seq = [self.bos_index] + seq
+            if self.delay > 0:
+                seq = seq + [self.pad_index for _ in range(self.delay)]
+            if self.eos:
+                seq = seq + [self.eos_index]
+            yield torch.tensor(seq, dtype=torch.long)
+
+    def compose(self, batch: Iterable[torch.Tensor]) -> torch.Tensor:
+        r"""
+        Composes a batch of sequences into a padded tensor.
+
+        Args:
+            batch (Iterable[~torch.Tensor]):
+                A list of tensors.
+
+        Returns:
+            A padded tensor converted to proper device.
+        """
+
+        return pad(batch, self.pad_index).to(self.device, non_blocking=True)
+
+
+class SubwordField(Field):
+    r"""
+    A field that conducts tokenization and numericalization over each token rather the sequence.
+
+    This is customized for models requiring character/subword-level inputs, e.g., CharLSTM and BERT.
+
+    Args:
+        fix_len (int):
+            A fixed length that all subword pieces will be padded to.
+            This is used for truncating the subword pieces exceeding the length.
+            To save the memory, the final length will be the smaller value
+            between the max length of subword pieces in a batch and `fix_len`.
+
+    Examples:
+        >>> from supar.utils.tokenizer import TransformerTokenizer
+        >>> tokenizer = TransformerTokenizer('bert-base-cased')
+        >>> field = SubwordField('bert',
+                                 pad=tokenizer.pad,
+                                 unk=tokenizer.unk,
+                                 bos=tokenizer.bos,
+                                 eos=tokenizer.eos,
+                                 fix_len=20,
+                                 tokenize=tokenizer)
+        >>> field.vocab = tokenizer.vocab  # no need to re-build the vocab
+        >>> next(field.transform([['This', 'field', 'performs', 'token-level', 'tokenization']]))
+        tensor([[  101,     0,     0],
+                [ 1188,     0,     0],
+                [ 1768,     0,     0],
+                [10383,     0,     0],
+                [22559,   118,  1634],
+                [22559,  2734,     0],
+                [  102,     0,     0]])
+    """
+
+    def __init__(self, *args, **kwargs):
+        self.fix_len = kwargs.pop('fix_len') if 'fix_len' in kwargs else 0
+        super().__init__(*args, **kwargs)
+
+    def build(
+        self,
+        dataset: Dataset,
+        min_freq: int = 1,
+        embed: Optional[Embedding] = None,
+        norm: Callable = None
+    ) -> SubwordField:
+        if hasattr(self, 'vocab'):
+            return
+
+        @wait
+        def build_vocab(dataset):
+            return Vocab(counter=Counter(piece
+                                         for seq in progress_bar(getattr(dataset, self.name))
+                                         for token in seq
+                                         for piece in self.preprocess(token)),
+                         min_freq=min_freq,
+                         specials=self.specials,
+                         unk_index=self.unk_index)
+        self.vocab = build_vocab(dataset)
+
+        if not embed:
+            self.embed = None
+        else:
+            tokens = self.preprocess(embed.tokens)
+            # if the `unk` token has existed in the pretrained,
+            # then replace it with a self-defined one
+            if embed.unk:
+                tokens[embed.unk_index] = self.unk
+
+            self.vocab.update(tokens)
+            self.embed = torch.zeros(len(self.vocab), embed.dim)
+            self.embed[self.vocab[tokens]] = embed.vectors
+            if norm is not None:
+                self.embed = norm(self.embed)
+        return self
+
+    def transform(self, sequences: Iterable[List[str]]) -> Iterable[torch.Tensor]:
+        for seq in sequences:
+            seq = [self.preprocess(token) for token in seq]
+            if self.use_vocab:
+                seq = [[self.vocab[i] if i in self.vocab else self.unk_index for i in token] if token else [self.unk_index]
+                       for token in seq]
+            if self.bos:
+                seq = [[self.bos_index]] + seq
+            if self.delay > 0:
+                seq = seq + [[self.pad_index] for _ in range(self.delay)]
+            if self.eos:
+                seq = seq + [[self.eos_index]]
+            if self.fix_len > 0:
+                seq = [ids[:self.fix_len] for ids in seq]
+            yield pad([torch.tensor(ids, dtype=torch.long) for ids in seq], self.pad_index)
+
+
+class ChartField(Field):
+    r"""
+    Field dealing with chart inputs.
+
+    Examples:
+        >>> chart = [[    None,    'NP',    None,    None,    'S*',     'S'],
+                     [    None,    None,   'VP*',    None,    'VP',    None],
+                     [    None,    None,    None,   'VP*', 'S::VP',    None],
+                     [    None,    None,    None,    None,    'NP',    None],
+                     [    None,    None,    None,    None,    None,    'S*'],
+                     [    None,    None,    None,    None,    None,    None]]
+        >>> next(field.transform([chart]))
+        tensor([[ -1,  37,  -1,  -1, 107,  79],
+                [ -1,  -1, 120,  -1, 112,  -1],
+                [ -1,  -1,  -1, 120,  86,  -1],
+                [ -1,  -1,  -1,  -1,  37,  -1],
+                [ -1,  -1,  -1,  -1,  -1, 107],
+                [ -1,  -1,  -1,  -1,  -1,  -1]])
+    """
+
+    def build(
+        self,
+        dataset: Dataset,
+        min_freq: int = 1
+    ) -> ChartField:
+        @wait
+        def build_vocab(dataset):
+            return Vocab(counter=Counter(i
+                                         for chart in progress_bar(getattr(dataset, self.name))
+                                         for row in self.preprocess(chart)
+                                         for i in row if i is not None),
+                         min_freq=min_freq,
+                         specials=self.specials,
+                         unk_index=self.unk_index)
+        self.vocab = build_vocab(dataset)
+        return self
+
+    def transform(self, charts: Iterable[List[List]]) -> Iterable[torch.Tensor]:
+        for chart in charts:
+            chart = self.preprocess(chart)
+            if self.use_vocab:
+                chart = [[self.vocab[i] if i is not None else -1 for i in row] for row in chart]
+            if self.bos:
+                chart = [[self.bos_index]*len(chart[0])] + chart
+            if self.eos:
+                chart = chart + [[self.eos_index]*len(chart[0])]
+            yield torch.tensor(chart, dtype=torch.long)
diff --git a/tania_scripts/supar/utils/fn.py b/tania_scripts/supar/utils/fn.py
new file mode 100644
index 0000000..95d826a
--- /dev/null
+++ b/tania_scripts/supar/utils/fn.py
@@ -0,0 +1,383 @@
+# -*- coding: utf-8 -*-
+
+import gzip
+import mmap
+import os
+import pickle
+import shutil
+import struct
+import sys
+import tarfile
+import unicodedata
+import urllib
+import zipfile
+from collections import defaultdict
+from typing import Any, Dict, Iterable, List, Optional, Tuple, Union
+
+import torch
+from omegaconf import DictConfig, OmegaConf
+from supar.utils.common import CACHE
+from supar.utils.parallel import wait
+
+
+def ispunct(token: str) -> bool:
+    return all(unicodedata.category(char).startswith('P') for char in token)
+
+
+def isfullwidth(token: str) -> bool:
+    return all(unicodedata.east_asian_width(char) in ['W', 'F', 'A'] for char in token)
+
+
+def islatin(token: str) -> bool:
+    return all('LATIN' in unicodedata.name(char) for char in token)
+
+
+def isdigit(token: str) -> bool:
+    return all('DIGIT' in unicodedata.name(char) for char in token)
+
+
+def tohalfwidth(token: str) -> str:
+    return unicodedata.normalize('NFKC', token)
+
+
+def kmeans(x: List[int], k: int, max_it: int = 32) -> Tuple[List[float], List[List[int]]]:
+    r"""
+    KMeans algorithm for clustering the sentences by length.
+
+    Args:
+        x (List[int]):
+            The list of sentence lengths.
+        k (int):
+            The number of clusters, which is an approximate value.
+            The final number of clusters can be less or equal to `k`.
+        max_it (int):
+            Maximum number of iterations.
+            If centroids does not converge after several iterations, the algorithm will be early stopped.
+
+    Returns:
+        List[float], List[List[int]]:
+            The first list contains average lengths of sentences in each cluster.
+            The second is the list of clusters holding indices of data points.
+
+    Examples:
+        >>> x = torch.randint(10, 20, (10,)).tolist()
+        >>> x
+        [15, 10, 17, 11, 18, 13, 17, 19, 18, 14]
+        >>> centroids, clusters = kmeans(x, 3)
+        >>> centroids
+        [10.5, 14.0, 17.799999237060547]
+        >>> clusters
+        [[1, 3], [0, 5, 9], [2, 4, 6, 7, 8]]
+    """
+
+    x = torch.tensor(x, dtype=torch.float)
+    # collect unique datapoints
+    datapoints, indices, freqs = x.unique(return_inverse=True, return_counts=True)
+    # the number of clusters must not be greater than the number of datapoints
+    k = min(len(datapoints), k)
+    # initialize k centroids randomly
+    centroids = datapoints[torch.randperm(len(datapoints))[:k]]
+    # assign each datapoint to the cluster with the closest centroid
+    dists, y = torch.abs_(datapoints.unsqueeze(-1) - centroids).min(-1)
+
+    for _ in range(max_it):
+        # if an empty cluster is encountered,
+        # choose the farthest datapoint from the biggest cluster and move that the empty one
+        mask = torch.arange(k).unsqueeze(-1).eq(y)
+        none = torch.where(~mask.any(-1))[0].tolist()
+        for i in none:
+            # the biggest cluster
+            biggest = torch.where(mask[mask.sum(-1).argmax()])[0]
+            # the datapoint farthest from the centroid of the biggest cluster
+            farthest = dists[biggest].argmax()
+            # update the assigned cluster of the farthest datapoint
+            y[biggest[farthest]] = i
+            # re-calculate the mask
+            mask = torch.arange(k).unsqueeze(-1).eq(y)
+        # update the centroids
+        centroids, old = (datapoints * freqs * mask).sum(-1) / (freqs * mask).sum(-1), centroids
+        # re-assign all datapoints to clusters
+        dists, y = torch.abs_(datapoints.unsqueeze(-1) - centroids).min(-1)
+        # stop iteration early if the centroids converge
+        if centroids.equal(old):
+            break
+    # assign all datapoints to the new-generated clusters
+    # the empty ones are discarded
+    assigned = y.unique().tolist()
+    # get the centroids of the assigned clusters
+    centroids = centroids[assigned].tolist()
+    # map all values of datapoints to buckets
+    clusters = [torch.where(indices.unsqueeze(-1).eq(torch.where(y.eq(i))[0]).any(-1))[0].tolist() for i in assigned]
+
+    return centroids, clusters
+
+
+def stripe(x: torch.Tensor, n: int, w: int, offset: Tuple = (0, 0), horizontal: bool = True) -> torch.Tensor:
+    r"""
+    Returns a parallelogram stripe of the tensor.
+
+    Args:
+        x (~torch.Tensor): the input tensor with 2 or more dims.
+        n (int): the length of the stripe.
+        w (int): the width of the stripe.
+        offset (tuple): the offset of the first two dims.
+        horizontal (bool): `True` if returns a horizontal stripe; `False` otherwise.
+
+    Returns:
+        A parallelogram stripe of the tensor.
+
+    Examples:
+        >>> x = torch.arange(25).view(5, 5)
+        >>> x
+        tensor([[ 0,  1,  2,  3,  4],
+                [ 5,  6,  7,  8,  9],
+                [10, 11, 12, 13, 14],
+                [15, 16, 17, 18, 19],
+                [20, 21, 22, 23, 24]])
+        >>> stripe(x, 2, 3)
+        tensor([[0, 1, 2],
+                [6, 7, 8]])
+        >>> stripe(x, 2, 3, (1, 1))
+        tensor([[ 6,  7,  8],
+                [12, 13, 14]])
+        >>> stripe(x, 2, 3, (1, 1), 0)
+        tensor([[ 6, 11, 16],
+                [12, 17, 22]])
+    """
+
+    x = x.contiguous()
+    seq_len, stride = x.size(1), list(x.stride())
+    numel = stride[1]
+    return x.as_strided(size=(n, w, *x.shape[2:]),
+                        stride=[(seq_len + 1) * numel, (1 if horizontal else seq_len) * numel] + stride[2:],
+                        storage_offset=(offset[0]*seq_len+offset[1])*numel)
+
+
+def diagonal_stripe(x: torch.Tensor, offset: int = 1) -> torch.Tensor:
+    r"""
+    Returns a diagonal parallelogram stripe of the tensor.
+
+    Args:
+        x (~torch.Tensor): the input tensor with 3 or more dims.
+        offset (int): which diagonal to consider. Default: 1.
+
+    Returns:
+        A diagonal parallelogram stripe of the tensor.
+
+    Examples:
+        >>> x = torch.arange(125).view(5, 5, 5)
+        >>> diagonal_stripe(x)
+        tensor([[ 5],
+                [36],
+                [67],
+                [98]])
+        >>> diagonal_stripe(x, 2)
+        tensor([[10, 11],
+                [41, 42],
+                [72, 73]])
+        >>> diagonal_stripe(x, -2)
+        tensor([[ 50,  51],
+                [ 81,  82],
+                [112, 113]])
+    """
+
+    x = x.contiguous()
+    seq_len, stride = x.size(1), list(x.stride())
+    n, w, numel = seq_len - abs(offset), abs(offset), stride[2]
+    return x.as_strided(size=(n, w, *x.shape[3:]),
+                        stride=[((seq_len + 1) * x.size(2) + 1) * numel] + stride[2:],
+                        storage_offset=offset*stride[1] if offset > 0 else abs(offset)*stride[0])
+
+
+def expanded_stripe(x: torch.Tensor, n: int, w: int, offset: Tuple = (0, 0)) -> torch.Tensor:
+    r"""
+    Returns an expanded parallelogram stripe of the tensor.
+
+    Args:
+        x (~torch.Tensor): the input tensor with 2 or more dims.
+        n (int): the length of the stripe.
+        w (int): the width of the stripe.
+        offset (tuple): the offset of the first two dims.
+
+    Returns:
+        An expanded parallelogram stripe of the tensor.
+
+    Examples:
+        >>> x = torch.arange(25).view(5, 5)
+        >>> x
+        tensor([[ 0,  1,  2,  3,  4],
+                [ 5,  6,  7,  8,  9],
+                [10, 11, 12, 13, 14],
+                [15, 16, 17, 18, 19],
+                [20, 21, 22, 23, 24]])
+        >>> expanded_stripe(x, 2, 3)
+        tensor([[[ 0,  1,  2,  3,  4],
+                 [ 5,  6,  7,  8,  9],
+                 [10, 11, 12, 13, 14]],
+
+                [[ 5,  6,  7,  8,  9],
+                 [10, 11, 12, 13, 14],
+                 [15, 16, 17, 18, 19]]])
+        >>> expanded_stripe(x, 2, 3, (1, 1))
+        tensor([[[ 5,  6,  7,  8,  9],
+                 [10, 11, 12, 13, 14],
+                 [15, 16, 17, 18, 19]],
+
+                [[10, 11, 12, 13, 14],
+                 [15, 16, 17, 18, 19],
+                 [20, 21, 22, 23, 24]]])
+
+    """
+    x = x.contiguous()
+    stride = list(x.stride())
+    return x.as_strided(size=(n, w, *list(x.shape[1:])),
+                        stride=stride[:1] + [stride[0]] + stride[1:],
+                        storage_offset=(offset[1])*stride[0])
+
+
+def pad(
+    tensors: List[torch.Tensor],
+    padding_value: int = 0,
+    total_length: int = None,
+    padding_side: str = 'right'
+) -> torch.Tensor:
+    size = [len(tensors)] + [max(tensor.size(i) for tensor in tensors)
+                             for i in range(len(tensors[0].size()))]
+    if total_length is not None:
+        assert total_length >= size[1]
+        size[1] = total_length
+    out_tensor = tensors[0].data.new(*size).fill_(padding_value)
+    for i, tensor in enumerate(tensors):
+        out_tensor[i][[slice(-i, None) if padding_side == 'left' else slice(0, i) for i in tensor.size()]] = tensor
+    return out_tensor
+
+
+@wait
+def download(url: str, path: Optional[str] = None, reload: bool = False, clean: bool = False) -> str:
+    filename = os.path.basename(urllib.parse.urlparse(url).path)
+    if path is None:
+        path = CACHE
+    os.makedirs(path, exist_ok=True)
+    path = os.path.join(path, filename)
+    if reload and os.path.exists(path):
+        os.remove(path)
+    if not os.path.exists(path):
+        sys.stderr.write(f"Downloading {url} to {path}\n")
+        try:
+            torch.hub.download_url_to_file(url, path, progress=True)
+        except (ValueError, urllib.error.URLError):
+            raise RuntimeError(f"File {url} unavailable. Please try other sources.")
+    return extract(path, reload, clean)
+
+
+def extract(path: str, reload: bool = False, clean: bool = False) -> str:
+    extracted = path
+    if zipfile.is_zipfile(path):
+        with zipfile.ZipFile(path) as f:
+            extracted = os.path.join(os.path.dirname(path), f.infolist()[0].filename)
+            if reload or not os.path.exists(extracted):
+                f.extractall(os.path.dirname(path))
+    elif tarfile.is_tarfile(path):
+        with tarfile.open(path) as f:
+            extracted = os.path.join(os.path.dirname(path), f.getnames()[0])
+            if reload or not os.path.exists(extracted):
+                f.extractall(os.path.dirname(path))
+    elif path.endswith('.gz'):
+        extracted = path[:-3]
+        with gzip.open(path) as fgz:
+            with open(extracted, 'wb') as f:
+                shutil.copyfileobj(fgz, f)
+    if clean:
+        os.remove(path)
+    return extracted
+
+
+def binarize(
+    data: Union[List[str], Dict[str, Iterable]],
+    fbin: str = None,
+    merge: bool = False
+) -> Tuple[str, torch.Tensor]:
+    start, meta = 0, defaultdict(list)
+    # the binarized file is organized as:
+    # `data`: pickled objects
+    # `meta`: a dict containing the pointers of each kind of data
+    # `index`: fixed size integers representing the storage positions of the meta data
+    with open(fbin, 'wb') as f:
+        # in this case, data should be a list of binarized files
+        if merge:
+            for file in data:
+                if not os.path.exists(file):
+                    raise RuntimeError("Some files are missing. Please check the paths")
+                mi = debinarize(file, meta=True)
+                for key, val in mi.items():
+                    val[:, 0] += start
+                    meta[key].append(val)
+                with open(file, 'rb') as fi:
+                    length = int(sum(val[:, 1].sum() for val in mi.values()))
+                    f.write(fi.read(length))
+                start = start + length
+            meta = {key: torch.cat(val) for key, val in meta.items()}
+        else:
+            for key, val in data.items():
+                for i in val:
+                    bytes = pickle.dumps(i)
+                    f.write(bytes)
+                    meta[key].append((start, len(bytes)))
+                    start = start + len(bytes)
+            meta = {key: torch.tensor(val) for key, val in meta.items()}
+        pickled = pickle.dumps(meta)
+        # append the meta data to the end of the bin file
+        f.write(pickled)
+        # record the positions of the meta data
+        f.write(struct.pack('LL', start, len(pickled)))
+    return fbin, meta
+
+
+def debinarize(
+    fbin: str,
+    pos_or_key: Optional[Union[Tuple[int, int], str]] = (0, 0),
+    meta: bool = False
+) -> Union[Any, Iterable[Any]]:
+    with open(fbin, 'rb') as f, mmap.mmap(f.fileno(), 0, access=mmap.ACCESS_READ) as mm:
+        if meta or isinstance(pos_or_key, str):
+            length = len(struct.pack('LL', 0, 0))
+            mm.seek(-length, os.SEEK_END)
+            offset, length = struct.unpack('LL', mm.read(length))
+            mm.seek(offset)
+            if meta:
+                return pickle.loads(mm.read(length))
+            # fetch by key
+            objs, meta = [], pickle.loads(mm.read(length))[pos_or_key]
+            for offset, length in meta.tolist():
+                mm.seek(offset)
+                objs.append(pickle.loads(mm.read(length)))
+            return objs
+        # fetch by positions
+        offset, length = pos_or_key
+        mm.seek(offset)
+        return pickle.loads(mm.read(length))
+
+
+def resolve_config(args: Union[Dict, DictConfig]) -> DictConfig:
+    OmegaConf.register_new_resolver("eval", eval)
+    return DictConfig(OmegaConf.to_container(args, resolve=True))
+
+
+def collect_args(args: Union[Dict, DictConfig]) -> DictConfig:
+    for key in ('self', 'cls', '__class__'):
+        args.pop(key, None)
+    args.update(args.pop('kwargs', dict()))
+    return DictConfig(args)
+
+
+def get_rng_state() -> Dict[str, torch.Tensor]:
+    state = {'rng_state': torch.get_rng_state()}
+    if torch.cuda.is_available():
+        state['cuda_rng_state'] = torch.cuda.get_rng_state()
+    return state
+
+
+def set_rng_state(state: Dict) -> None:
+    torch.set_rng_state(state['rng_state'])
+    if torch.cuda.is_available():
+        torch.cuda.set_rng_state(state['cuda_rng_state'])
diff --git a/tania_scripts/supar/utils/logging.py b/tania_scripts/supar/utils/logging.py
new file mode 100644
index 0000000..73e4a77
--- /dev/null
+++ b/tania_scripts/supar/utils/logging.py
@@ -0,0 +1,100 @@
+# -*- coding: utf-8 -*-
+
+import logging
+import os
+from logging import FileHandler, Formatter, Handler, Logger, StreamHandler
+from typing import Iterable, Optional
+
+from supar.utils.parallel import is_master
+from tqdm import tqdm
+
+
+def get_logger(name: Optional[str] = None) -> Logger:
+    logger = logging.getLogger(name)
+    # init the root logger
+    if name is None:
+        logging.basicConfig(format='[%(asctime)s %(levelname)s] %(message)s',
+                            datefmt='%Y-%m-%d %H:%M:%S',
+                            handlers=[TqdmHandler()])
+    return logger
+
+
+class TqdmHandler(StreamHandler):
+
+    def __init__(self, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+    def emit(self, record):
+        try:
+            msg = self.format(record)
+            tqdm.write(msg)
+            self.flush()
+        except (KeyboardInterrupt, SystemExit):
+            raise
+        except Exception:
+            self.handleError(record)
+
+
+def init_logger(
+    logger: Logger,
+    path: Optional[str] = None,
+    mode: str = 'w',
+    handlers: Optional[Iterable[Handler]] = None,
+    verbose: bool = True
+) -> Logger:
+    if not handlers:
+        if path:
+            os.makedirs(os.path.dirname(path) or './', exist_ok=True)
+            logger.addHandler(FileHandler(path, mode))
+    for handler in logger.handlers:
+        handler.setFormatter(ColoredFormatter(colored=not isinstance(handler, FileHandler)))
+    logger.setLevel(logging.INFO if is_master() and verbose else logging.WARNING)
+    return logger
+
+
+def progress_bar(
+    iterator: Iterable,
+    ncols: Optional[int] = None,
+    bar_format: str = '{l_bar}{bar:20}| {n_fmt}/{total_fmt} {elapsed}<{remaining}, {rate_fmt}{postfix}',
+    leave: bool = False,
+    **kwargs
+) -> tqdm:
+    return tqdm(iterator,
+                ncols=ncols,
+                bar_format=bar_format,
+                ascii=True,
+                disable=(not (logger.level == logging.INFO and is_master())),
+                leave=leave,
+                **kwargs)
+
+
+class ColoredFormatter(Formatter):
+
+    BLACK = '\033[30m'
+    RED = '\033[31m'
+    GREEN = '\033[32m'
+    GREY = '\033[37m'
+    RESET = '\033[0m'
+
+    COLORS = {
+        logging.ERROR: RED,
+        logging.WARNING: RED,
+        logging.INFO: GREEN,
+        logging.DEBUG: BLACK,
+        logging.NOTSET: BLACK
+    }
+
+    def __init__(self, colored=True, *args, **kwargs):
+        super().__init__(*args, **kwargs)
+
+        self.colored = colored
+
+    def format(self, record):
+        fmt = '[%(asctime)s %(levelname)s] %(message)s'
+        if self.colored:
+            fmt = f'{self.COLORS[record.levelno]}[%(asctime)s %(levelname)s]{self.RESET} %(message)s'
+        datefmt = '%Y-%m-%d %H:%M:%S'
+        return Formatter(fmt=fmt, datefmt=datefmt).format(record)
+
+
+logger = get_logger()
diff --git a/tania_scripts/supar/utils/metric.py b/tania_scripts/supar/utils/metric.py
new file mode 100644
index 0000000..f64940c
--- /dev/null
+++ b/tania_scripts/supar/utils/metric.py
@@ -0,0 +1,346 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+from collections import Counter
+from typing import Dict, List, Optional, Tuple
+
+import torch
+
+
+class Metric(object):
+
+    def __init__(self, reverse: Optional[bool] = None, eps: float = 1e-12) -> Metric:
+        super().__init__()
+
+        self.n = 0.0
+        self.count = 0.0
+        self.total_loss = 0.0
+        self.reverse = reverse
+        self.eps = eps
+
+    def __repr__(self):
+        return f"loss: {self.loss:.4f} - " + ' '.join([f"{key}: {val:6.2%}" for key, val in self.values.items()])
+
+    def __lt__(self, other: Metric) -> bool:
+        if not hasattr(self, 'score'):
+            return True
+        if not hasattr(other, 'score'):
+            return False
+        return (self.score < other.score) if not self.reverse else (self.score > other.score)
+
+    def __le__(self, other: Metric) -> bool:
+        if not hasattr(self, 'score'):
+            return True
+        if not hasattr(other, 'score'):
+            return False
+        return (self.score <= other.score) if not self.reverse else (self.score >= other.score)
+
+    def __gt__(self, other: Metric) -> bool:
+        if not hasattr(self, 'score'):
+            return False
+        if not hasattr(other, 'score'):
+            return True
+        return (self.score > other.score) if not self.reverse else (self.score < other.score)
+
+    def __ge__(self, other: Metric) -> bool:
+        if not hasattr(self, 'score'):
+            return False
+        if not hasattr(other, 'score'):
+            return True
+        return (self.score >= other.score) if not self.reverse else (self.score <= other.score)
+
+    def __add__(self, other: Metric) -> Metric:
+        return other
+
+    @property
+    def score(self):
+        raise AttributeError
+
+    @property
+    def loss(self):
+        return self.total_loss / (self.count + self.eps)
+
+    @property
+    def values(self):
+        raise AttributeError
+
+
+class AttachmentMetric(Metric):
+
+    def __init__(
+        self,
+        loss: Optional[float] = None,
+        preds: Optional[Tuple[torch.Tensor, torch.Tensor]] = None,
+        golds: Optional[Tuple[torch.Tensor, torch.Tensor]] = None,
+        mask: Optional[torch.BoolTensor] = None,
+        reverse: bool = False,
+        eps: float = 1e-12
+    ) -> AttachmentMetric:
+        super().__init__(reverse=reverse, eps=eps)
+
+        self.n_ucm = 0.0
+        self.n_lcm = 0.0
+        self.total = 0.0
+        self.correct_arcs = 0.0
+        self.correct_rels = 0.0
+
+        if loss is not None:
+            self(loss, preds, golds, mask)
+
+    def __call__(
+        self,
+        loss: float,
+        preds: Tuple[torch.Tensor, torch.Tensor],
+        golds: Tuple[torch.Tensor, torch.Tensor],
+        mask: torch.BoolTensor
+    ) -> AttachmentMetric:
+        lens = mask.sum(1)
+        arc_preds, rel_preds, arc_golds, rel_golds = *preds, *golds
+        arc_mask = arc_preds.eq(arc_golds) & mask
+        rel_mask = rel_preds.eq(rel_golds) & arc_mask
+        arc_mask_seq, rel_mask_seq = arc_mask[mask], rel_mask[mask]
+
+        self.n += len(mask)
+        self.count += 1
+        self.total_loss += float(loss)
+        self.n_ucm += arc_mask.sum(1).eq(lens).sum().item()
+        self.n_lcm += rel_mask.sum(1).eq(lens).sum().item()
+
+        self.total += len(arc_mask_seq)
+        self.correct_arcs += arc_mask_seq.sum().item()
+        self.correct_rels += rel_mask_seq.sum().item()
+        return self
+
+    def __add__(self, other: AttachmentMetric) -> AttachmentMetric:
+        metric = AttachmentMetric(eps=self.eps)
+        metric.n = self.n + other.n
+        metric.count = self.count + other.count
+        metric.total_loss = self.total_loss + other.total_loss
+        metric.n_ucm = self.n_ucm + other.n_ucm
+        metric.n_lcm = self.n_lcm + other.n_lcm
+        metric.total = self.total + other.total
+        metric.correct_arcs = self.correct_arcs + other.correct_arcs
+        metric.correct_rels = self.correct_rels + other.correct_rels
+        metric.reverse = self.reverse or other.reverse
+        return metric
+
+    @property
+    def score(self):
+        return self.las
+
+    @property
+    def ucm(self):
+        return self.n_ucm / (self.n + self.eps)
+
+    @property
+    def lcm(self):
+        return self.n_lcm / (self.n + self.eps)
+
+    @property
+    def uas(self):
+        return self.correct_arcs / (self.total + self.eps)
+
+    @property
+    def las(self):
+        return self.correct_rels / (self.total + self.eps)
+
+    @property
+    def values(self) -> Dict:
+        return {'UCM': self.ucm,
+                'LCM': self.lcm,
+                'UAS': self.uas,
+                'LAS': self.las}
+
+
+class SpanMetric(Metric):
+
+    def __init__(
+        self,
+        loss: Optional[float] = None,
+        preds: Optional[List[List[Tuple]]] = None,
+        golds: Optional[List[List[Tuple]]] = None,
+        reverse: bool = False,
+        eps: float = 1e-12
+    ) -> SpanMetric:
+        super().__init__(reverse=reverse, eps=eps)
+
+        self.n_ucm = 0.0
+        self.n_lcm = 0.0
+        self.utp = 0.0
+        self.ltp = 0.0
+        self.pred = 0.0
+        self.gold = 0.0
+
+        if loss is not None:
+            self(loss, preds, golds)
+
+    def __call__(
+        self,
+        loss: float,
+        preds: List[List[Tuple]],
+        golds: List[List[Tuple]]
+    ) -> SpanMetric:
+        self.n += len(preds)
+        self.count += 1
+        self.total_loss += float(loss)
+        for pred, gold in zip(preds, golds):
+            upred, ugold = Counter([tuple(span[:-1]) for span in pred]), Counter([tuple(span[:-1]) for span in gold])
+            lpred, lgold = Counter([tuple(span) for span in pred]), Counter([tuple(span) for span in gold])
+            utp, ltp = list((upred & ugold).elements()), list((lpred & lgold).elements())
+            self.n_ucm += len(utp) == len(pred) == len(gold)
+            self.n_lcm += len(ltp) == len(pred) == len(gold)
+            self.utp += len(utp)
+            self.ltp += len(ltp)
+            self.pred += len(pred)
+            self.gold += len(gold)
+        return self
+
+    def __add__(self, other: SpanMetric) -> SpanMetric:
+        metric = SpanMetric(eps=self.eps)
+        metric.n = self.n + other.n
+        metric.count = self.count + other.count
+        metric.total_loss = self.total_loss + other.total_loss
+        metric.n_ucm = self.n_ucm + other.n_ucm
+        metric.n_lcm = self.n_lcm + other.n_lcm
+        metric.utp = self.utp + other.utp
+        metric.ltp = self.ltp + other.ltp
+        metric.pred = self.pred + other.pred
+        metric.gold = self.gold + other.gold
+        metric.reverse = self.reverse or other.reverse
+        return metric
+
+    @property
+    def score(self):
+        return self.lf
+
+    @property
+    def ucm(self):
+        return self.n_ucm / (self.n + self.eps)
+
+    @property
+    def lcm(self):
+        return self.n_lcm / (self.n + self.eps)
+
+    @property
+    def up(self):
+        return self.utp / (self.pred + self.eps)
+
+    @property
+    def ur(self):
+        return self.utp / (self.gold + self.eps)
+
+    @property
+    def uf(self):
+        return 2 * self.utp / (self.pred + self.gold + self.eps)
+
+    @property
+    def lp(self):
+        return self.ltp / (self.pred + self.eps)
+
+    @property
+    def lr(self):
+        return self.ltp / (self.gold + self.eps)
+
+    @property
+    def lf(self):
+        return 2 * self.ltp / (self.pred + self.gold + self.eps)
+
+    @property
+    def values(self) -> Dict:
+        return {'UCM': self.ucm,
+                'LCM': self.lcm,
+                'UP': self.up,
+                'UR': self.ur,
+                'UF': self.uf,
+                'LP': self.lp,
+                'LR': self.lr,
+                'LF': self.lf}
+
+
+class ChartMetric(Metric):
+
+    def __init__(
+        self,
+        loss: Optional[float] = None,
+        preds: Optional[torch.Tensor] = None,
+        golds: Optional[torch.Tensor] = None,
+        reverse: bool = False,
+        eps: float = 1e-12
+    ) -> ChartMetric:
+        super().__init__(reverse=reverse, eps=eps)
+
+        self.tp = 0.0
+        self.utp = 0.0
+        self.pred = 0.0
+        self.gold = 0.0
+
+        if loss is not None:
+            self(loss, preds, golds)
+
+    def __call__(
+        self,
+        loss: float,
+        preds: torch.Tensor,
+        golds: torch.Tensor
+    ) -> ChartMetric:
+        self.n += len(preds)
+        self.count += 1
+        self.total_loss += float(loss)
+        pred_mask = preds.ge(0)
+        gold_mask = golds.ge(0)
+        span_mask = pred_mask & gold_mask
+        self.pred += pred_mask.sum().item()
+        self.gold += gold_mask.sum().item()
+        self.tp += (preds.eq(golds) & span_mask).sum().item()
+        self.utp += span_mask.sum().item()
+        return self
+
+    def __add__(self, other: ChartMetric) -> ChartMetric:
+        metric = ChartMetric(eps=self.eps)
+        metric.n = self.n + other.n
+        metric.count = self.count + other.count
+        metric.total_loss = self.total_loss + other.total_loss
+        metric.tp = self.tp + other.tp
+        metric.utp = self.utp + other.utp
+        metric.pred = self.pred + other.pred
+        metric.gold = self.gold + other.gold
+        metric.reverse = self.reverse or other.reverse
+        return metric
+
+    @property
+    def score(self):
+        return self.f
+
+    @property
+    def up(self):
+        return self.utp / (self.pred + self.eps)
+
+    @property
+    def ur(self):
+        return self.utp / (self.gold + self.eps)
+
+    @property
+    def uf(self):
+        return 2 * self.utp / (self.pred + self.gold + self.eps)
+
+    @property
+    def p(self):
+        return self.tp / (self.pred + self.eps)
+
+    @property
+    def r(self):
+        return self.tp / (self.gold + self.eps)
+
+    @property
+    def f(self):
+        return 2 * self.tp / (self.pred + self.gold + self.eps)
+
+    @property
+    def values(self) -> Dict:
+        return {'UP': self.up,
+                'UR': self.ur,
+                'UF': self.uf,
+                'P': self.p,
+                'R': self.r,
+                'F': self.f}
diff --git a/tania_scripts/supar/utils/optim.py b/tania_scripts/supar/utils/optim.py
new file mode 100644
index 0000000..e67730b
--- /dev/null
+++ b/tania_scripts/supar/utils/optim.py
@@ -0,0 +1,55 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+from torch.optim import Optimizer
+from torch.optim.lr_scheduler import _LRScheduler
+
+
+class InverseSquareRootLR(_LRScheduler):
+
+    def __init__(
+        self,
+        optimizer: Optimizer,
+        warmup_steps: int,
+        last_epoch: int = -1
+    ) -> InverseSquareRootLR:
+        self.warmup_steps = warmup_steps
+        self.factor = warmup_steps ** 0.5
+        super(InverseSquareRootLR, self).__init__(optimizer, last_epoch)
+
+    def get_lr(self):
+        epoch = max(self.last_epoch, 1)
+        scale = min(epoch ** -0.5, epoch * self.warmup_steps ** -1.5) * self.factor
+        return [scale * lr for lr in self.base_lrs]
+
+
+class PolynomialLR(_LRScheduler):
+    r"""
+    Set the learning rate for each parameter group using a polynomial defined as: `lr = base_lr * (1 - t / T) ^ (power)`,
+    where `t` is the current epoch and `T` is the maximum number of epochs.
+    """
+
+    def __init__(
+        self,
+        optimizer: Optimizer,
+        warmup_steps: int = 0,
+        steps: int = 100000,
+        power: float = 1.,
+        last_epoch: int = -1
+    ) -> PolynomialLR:
+        self.warmup_steps = warmup_steps
+        self.steps = steps
+        self.power = power
+        super(PolynomialLR, self).__init__(optimizer, last_epoch)
+
+    def get_lr(self):
+        epoch = max(self.last_epoch, 1)
+        if epoch <= self.warmup_steps:
+            return [epoch / self.warmup_steps * lr for lr in self.base_lrs]
+        t, T = (epoch - self.warmup_steps), (self.steps - self.warmup_steps)
+        return [lr * (1 - t / T) ** self.power for lr in self.base_lrs]
+
+
+def LinearLR(optimizer: Optimizer, warmup_steps: int = 0, steps: int = 100000, last_epoch: int = -1) -> PolynomialLR:
+    return PolynomialLR(optimizer, warmup_steps, steps, 1, last_epoch)
diff --git a/tania_scripts/supar/utils/parallel.py b/tania_scripts/supar/utils/parallel.py
new file mode 100644
index 0000000..f6f1e0b
--- /dev/null
+++ b/tania_scripts/supar/utils/parallel.py
@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+import functools
+import os
+import re
+from typing import Any, Iterable
+
+import torch
+import torch.distributed as dist
+import torch.nn as nn
+
+
+class DistributedDataParallel(nn.parallel.DistributedDataParallel):
+
+    def __init__(self, module, **kwargs):
+        super().__init__(module, **kwargs)
+
+    def __getattr__(self, name):
+        wrapped = super().__getattr__('module')
+        if hasattr(wrapped, name):
+            return getattr(wrapped, name)
+        return super().__getattr__(name)
+
+
+def wait(fn) -> Any:
+    @functools.wraps(fn)
+    def wrapper(*args, **kwargs):
+        value = None
+        if is_master():
+            value = fn(*args, **kwargs)
+        if is_dist():
+            dist.barrier()
+            value = gather(value)[0]
+        return value
+    return wrapper
+
+
+def gather(obj: Any) -> Iterable[Any]:
+    objs = [None] * dist.get_world_size()
+    dist.all_gather_object(objs, obj)
+    return objs
+
+
+def reduce(obj: Any, reduction: str = 'sum') -> Any:
+    objs = gather(obj)
+    if reduction == 'sum':
+        return functools.reduce(lambda x, y: x + y, objs)
+    elif reduction == 'mean':
+        return functools.reduce(lambda x, y: x + y, objs) / len(objs)
+    elif reduction == 'min':
+        return min(objs)
+    elif reduction == 'max':
+        return max(objs)
+    else:
+        raise NotImplementedError(f"Unsupported reduction {reduction}")
+
+
+def is_dist():
+    return dist.is_available() and dist.is_initialized()
+
+
+def is_master():
+    return not is_dist() or dist.get_rank() == 0
+
+
+def get_free_port():
+    import socket
+    s = socket.socket()
+    s.bind(('', 0))
+    port = str(s.getsockname()[1])
+    s.close()
+    return port
+
+
+def get_device_count():
+    if 'CUDA_VISIBLE_DEVICES' in os.environ:
+        return len(re.findall(r'\d+', os.environ['CUDA_VISIBLE_DEVICES']))
+    return torch.cuda.device_count()
diff --git a/tania_scripts/supar/utils/tokenizer.py b/tania_scripts/supar/utils/tokenizer.py
new file mode 100644
index 0000000..35920b6
--- /dev/null
+++ b/tania_scripts/supar/utils/tokenizer.py
@@ -0,0 +1,220 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+import os
+import re
+import tempfile
+from collections import Counter, defaultdict
+from typing import Any, Dict, List, Optional, Union
+
+import torch.distributed as dist
+from supar.utils.parallel import is_dist, is_master
+from supar.utils.vocab import Vocab
+from torch.distributions.utils import lazy_property
+
+
+class Tokenizer:
+
+    def __init__(self, lang: str = 'en') -> Tokenizer:
+        import stanza
+        try:
+            self.pipeline = stanza.Pipeline(lang=lang, processors='tokenize', verbose=False, tokenize_no_ssplit=True)
+        except Exception:
+            stanza.download(lang=lang, resources_url='stanford')
+            self.pipeline = stanza.Pipeline(lang=lang, processors='tokenize', verbose=False, tokenize_no_ssplit=True)
+
+    def __call__(self, text: str) -> List[str]:
+        return [i.text for i in self.pipeline(text).sentences[0].tokens]
+
+
+class TransformerTokenizer:
+
+    def __init__(self, name) -> TransformerTokenizer:
+        from transformers import AutoTokenizer
+        self.name = name
+        try:
+            self.tokenizer = AutoTokenizer.from_pretrained(name, local_files_only=True)
+        except Exception:
+            self.tokenizer = AutoTokenizer.from_pretrained(name, local_files_only=False)
+
+    def __repr__(self) -> str:
+        return f"{self.__class__.__name__}({self.name})"
+
+    def __len__(self) -> int:
+        return self.vocab_size
+
+    def __call__(self, text: str) -> List[str]:
+        from tokenizers.pre_tokenizers import ByteLevel
+        if isinstance(self.tokenizer.backend_tokenizer.pre_tokenizer, ByteLevel):
+            text = ' ' + text
+        return self.tokenizer.tokenize(text)
+
+    def __getattr__(self, name: str) -> Any:
+        return getattr(self.tokenizer, name)
+
+    def __getstate__(self) -> Dict:
+        return self.__dict__
+
+    def __setstate__(self, state: Dict):
+        self.__dict__.update(state)
+
+    @lazy_property
+    def vocab(self):
+        return defaultdict(lambda: self.tokenizer.vocab[self.unk], self.tokenizer.get_vocab())
+
+    @lazy_property
+    def tokens(self):
+        return sorted(self.vocab, key=lambda x: self.vocab[x])
+
+    @property
+    def vocab_size(self):
+        return len(self.vocab)
+
+    @property
+    def pad(self):
+        return self.tokenizer.pad_token
+
+    @property
+    def unk(self):
+        return self.tokenizer.unk_token
+
+    @property
+    def bos(self):
+        return self.tokenizer.bos_token or self.tokenizer.cls_token
+
+    @property
+    def eos(self):
+        return self.tokenizer.eos_token or self.tokenizer.sep_token
+
+    def decode(self, text: List) -> str:
+        return self.tokenizer.decode(text, skip_special_tokens=True, clean_up_tokenization_spaces=False)
+
+
+class BPETokenizer:
+
+    def __init__(
+        self,
+        path: str = None,
+        files: Optional[List[str]] = None,
+        vocab_size: Optional[int] = 32000,
+        min_freq: Optional[int] = 2,
+        dropout: float = None,
+        backend: str = 'huggingface',
+        pad: Optional[str] = None,
+        unk: Optional[str] = None,
+        bos: Optional[str] = None,
+        eos: Optional[str] = None,
+    ) -> BPETokenizer:
+
+        self.path = path
+        self.files = files
+        self.min_freq = min_freq
+        self.dropout = dropout or .0
+        self.backend = backend
+        self.pad = pad
+        self.unk = unk
+        self.bos = bos
+        self.eos = eos
+        self.special_tokens = [i for i in [pad, unk, bos, eos] if i is not None]
+
+        if backend == 'huggingface':
+            from tokenizers import Tokenizer
+            from tokenizers.decoders import BPEDecoder
+            from tokenizers.models import BPE
+            from tokenizers.pre_tokenizers import WhitespaceSplit
+            from tokenizers.trainers import BpeTrainer
+            path = os.path.join(path, 'tokenizer.json')
+            if is_master() and not os.path.exists(path):
+                # start to train a tokenizer from scratch
+                self.tokenizer = Tokenizer(BPE(dropout=dropout, unk_token=unk))
+                self.tokenizer.pre_tokenizer = WhitespaceSplit()
+                self.tokenizer.decoder = BPEDecoder()
+                self.tokenizer.train(files=files,
+                                     trainer=BpeTrainer(vocab_size=vocab_size,
+                                                        min_frequency=min_freq,
+                                                        special_tokens=self.special_tokens,
+                                                        end_of_word_suffix='</w>'))
+                self.tokenizer.save(path)
+            if is_dist():
+                dist.barrier()
+            self.tokenizer = Tokenizer.from_file(path)
+            self.vocab = self.tokenizer.get_vocab()
+
+        elif backend == 'subword-nmt':
+            import argparse
+            from argparse import Namespace
+
+            from subword_nmt.apply_bpe import BPE, read_vocabulary
+            from subword_nmt.learn_joint_bpe_and_vocab import learn_joint_bpe_and_vocab
+            fmerge = os.path.join(path, 'merge.txt')
+            fvocab = os.path.join(path, 'vocab.txt')
+            separator = '@@'
+            if is_master() and (not os.path.exists(fmerge) or not os.path.exists(fvocab)):
+                with tempfile.TemporaryDirectory() as ftemp:
+                    fall = os.path.join(ftemp, 'fall')
+                    with open(fall, 'w') as f:
+                        for file in files:
+                            with open(file) as fi:
+                                f.write(fi.read())
+                    learn_joint_bpe_and_vocab(Namespace(input=[argparse.FileType()(fall)],
+                                                        output=argparse.FileType('w')(fmerge),
+                                                        symbols=vocab_size,
+                                                        separator=separator,
+                                                        vocab=[argparse.FileType('w')(fvocab)],
+                                                        min_frequency=min_freq,
+                                                        total_symbols=False,
+                                                        verbose=False,
+                                                        num_workers=32))
+            if is_dist():
+                dist.barrier()
+            self.tokenizer = BPE(codes=open(fmerge), separator=separator, vocab=read_vocabulary(open(fvocab), None))
+            self.vocab = Vocab(counter=Counter(self.tokenizer.vocab),
+                               specials=self.special_tokens,
+                               unk_index=self.special_tokens.index(unk))
+        else:
+            raise ValueError(f'Unsupported backend: {backend} not in (huggingface, subword-nmt)')
+
+    def __repr__(self) -> str:
+        s = self.__class__.__name__ + f'({self.vocab_size}, min_freq={self.min_freq}'
+        if self.dropout > 0:
+            s += f", dropout={self.dropout}"
+        s += f", backend={self.backend}"
+        if self.pad is not None:
+            s += f", pad={self.pad}"
+        if self.unk is not None:
+            s += f", unk={self.unk}"
+        if self.bos is not None:
+            s += f", bos={self.bos}"
+        if self.eos is not None:
+            s += f", eos={self.eos}"
+        s += ')'
+        return s
+
+    def __len__(self) -> int:
+        return self.vocab_size
+
+    def __call__(self, text: Union[str, List]) -> List[str]:
+        is_pretokenized = isinstance(text, list)
+        if self.backend == 'huggingface':
+            return self.tokenizer.encode(text, is_pretokenized=is_pretokenized).tokens
+        else:
+            if not is_pretokenized:
+                text = text.split()
+            return self.tokenizer.segment_tokens(text, dropout=self.dropout)
+
+    @lazy_property
+    def tokens(self):
+        return sorted(self.vocab, key=lambda x: self.vocab[x])
+
+    @property
+    def vocab_size(self):
+        return len(self.vocab)
+
+    def decode(self, text: List) -> str:
+        if self.backend == 'huggingface':
+            return self.tokenizer.decode(text)
+        else:
+            text = self.vocab[text]
+            text = ' '.join([i for i in text if i not in self.special_tokens])
+            return re.sub(f'({self.tokenizer.separator} )|({self.tokenizer.separator} ?$)', '', text)
diff --git a/tania_scripts/supar/utils/transform.py b/tania_scripts/supar/utils/transform.py
new file mode 100644
index 0000000..f8d070c
--- /dev/null
+++ b/tania_scripts/supar/utils/transform.py
@@ -0,0 +1,219 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+from typing import Any, Iterable, Optional, Tuple
+
+import torch
+from torch.distributions.utils import lazy_property
+
+from supar.utils.fn import debinarize
+from supar.utils.logging import get_logger, progress_bar
+
+logger = get_logger(__name__)
+
+
+class Transform(object):
+    r"""
+    A :class:`Transform` object corresponds to a specific data format, which holds several instances of data fields
+    that provide instructions for preprocessing and numericalization, etc.
+
+    Attributes:
+        training (bool):
+            Sets the object in training mode.
+            If ``False``, some data fields not required for predictions won't be returned.
+            Default: ``True``.
+    """
+
+    fields = []
+
+    def __init__(self):
+        self.training = True
+
+    def __len__(self):
+        return len(self.fields)
+
+    def __repr__(self):
+        s = '\n' + '\n'.join([f" {f}" for f in self.flattened_fields]) + '\n'
+        return f"{self.__class__.__name__}({s})"
+
+    def __call__(self, sentences: Iterable[Sentence]) -> Iterable[Sentence]:
+        return [sentence.numericalize(self.flattened_fields) for sentence in progress_bar(sentences)]
+
+    def __getitem__(self, index):
+        return getattr(self, self.fields[index])
+
+    @property
+    def flattened_fields(self):
+        flattened = []
+        for field in self:
+            if field not in self.src and field not in self.tgt:
+                continue
+            if not self.training and field in self.tgt:
+                continue
+            if not isinstance(field, Iterable):
+                field = [field]
+            for f in field:
+                if f is not None:
+                    flattened.append(f)
+        return flattened
+
+    def train(self, training=True):
+        self.training = training
+
+    def eval(self):
+        self.train(False)
+
+    def append(self, field):
+        self.fields.append(field.name)
+        setattr(self, field.name, field)
+
+    @property
+    def src(self):
+        raise AttributeError
+
+    @property
+    def tgt(self):
+        raise AttributeError
+
+
+class Batch(object):
+
+    def __init__(self, sentences: Iterable[Sentence]) -> Batch:
+        self.sentences = sentences
+
+        self.names, self.fields = [], {}
+
+    def __repr__(self):
+        return f'{self.__class__.__name__}({", ".join([f"{name}" for name in self.names])})'
+
+    def __len__(self):
+        return len(self.sentences)
+
+    def __getitem__(self, index):
+        return self.fields[self.names[index]]
+
+    def __getattr__(self, name):
+        return [s.fields[name] for s in self.sentences]
+
+    def __setattr__(self, name: str, value: Iterable[Any]):
+        if name not in ('sentences', 'fields', 'names'):
+            for s, v in zip(self.sentences, value):
+                setattr(s, name, v)
+        else:
+            self.__dict__[name] = value
+
+    def __getstate__(self):
+        return self.__dict__
+
+    def __setstate__(self, state):
+        self.__dict__.update(state)
+
+    @property
+    def device(self):
+        return 'cuda' if torch.cuda.is_available() else 'cpu'
+
+    @lazy_property
+    def lens(self):
+        return torch.tensor([len(i) for i in self.sentences]).to(self.device, non_blocking=True)
+
+    @lazy_property
+    def mask(self):
+        return self.lens.unsqueeze(-1).gt(self.lens.new_tensor(range(self.lens.max())))
+
+    def compose(self, transform: Transform) -> Batch:
+        for f in transform.flattened_fields:
+            self.names.append(f.name)
+            self.fields[f.name] = f.compose([s.fields[f.name] for s in self.sentences])
+        return self
+
+    def shrink(self, batch_size: Optional[int] = None) -> Batch:
+        if batch_size is None:
+            batch_size = len(self) // 2
+        if batch_size <= 0:
+            raise RuntimeError(f"The batch has only {len(self)} sentences and can't be shrinked!")
+        return Batch([self.sentences[i] for i in torch.randperm(len(self))[:batch_size].tolist()])
+
+    def pin_memory(self):
+        for s in self.sentences:
+            for i in s.fields.values():
+                if isinstance(i, torch.Tensor):
+                    i.pin_memory()
+        return self
+
+
+class Sentence(object):
+
+    def __init__(self, transform, index: Optional[int] = None) -> Sentence:
+        self.index = index
+        # mapping from each nested field to their proper position
+        self.maps = dict()
+        # original values and numericalized values of each position
+        self.values, self.fields = [], {}
+        for i, field in enumerate(transform):
+
+            if not isinstance(field, Iterable):
+                field = [field]
+            for f in field:
+                if f is not None:
+                    self.maps[f.name] = i
+                    self.fields[f.name] = None
+
+    def __contains__(self, name):
+        return name in self.fields
+
+    def __getattr__(self, name):
+        if name in self.fields:
+            return self.values[self.maps[name]]
+        raise AttributeError(f"`{name}` not found")
+
+    def __setattr__(self, name, value):
+        if 'fields' in self.__dict__ and name in self:
+            index = self.maps[name]
+            if index >= len(self.values):
+                self.__dict__[name] = value
+            else:
+                self.values[index] = value
+        else:
+            self.__dict__[name] = value
+
+    def __getstate__(self):
+        state = vars(self)
+        if 'fields' in state:
+            state['fields'] = {
+                name: ((value.dtype, value.tolist())
+                       if isinstance(value, torch.Tensor)
+                       else value)
+                for name, value in state['fields'].items()
+            }
+        return state
+
+    def __setstate__(self, state):
+        if 'fields' in state:
+            state['fields'] = {
+                name: (torch.tensor(value[1], dtype=value[0])
+                       if isinstance(value, tuple) and isinstance(value[0], torch.dtype)
+                       else value)
+                for name, value in state['fields'].items()
+            }
+            self.__dict__.update(state)
+
+    def __len__(self):
+        try:
+            return len(next(iter(self.fields.values())))
+        except Exception:
+            raise AttributeError("Cannot get size of a sentence with no fields")
+
+    @lazy_property
+    def size(self):
+        return len(self)
+
+    def numericalize(self, fields):
+        for f in fields:
+             self.fields[f.name] = next(f.transform([getattr(self, f.name)]))
+        self.pad_index = fields[0].pad_index
+        return self
+
+    @classmethod
+    def from_cache(cls, fbin: str, pos: Tuple[int, int]) -> Sentence:
+        return debinarize(fbin, pos)
diff --git a/tania_scripts/supar/utils/vocab.py b/tania_scripts/supar/utils/vocab.py
new file mode 100644
index 0000000..ee9cae0
--- /dev/null
+++ b/tania_scripts/supar/utils/vocab.py
@@ -0,0 +1,77 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+from collections import Counter, defaultdict
+from typing import Iterable, Tuple, Union
+
+
+class Vocab(object):
+    r"""
+    Defines a vocabulary object that will be used to numericalize a field.
+
+    Args:
+        counter (~collections.Counter):
+            :class:`~collections.Counter` object holding the frequencies of each value found in the data.
+        min_freq (int):
+            The minimum frequency needed to include a token in the vocabulary. Default: 1.
+        specials (Tuple[str]):
+            The list of special tokens (e.g., pad, unk, bos and eos) that will be prepended to the vocabulary. Default: ``[]``.
+        unk_index (int):
+            The index of unk token. Default: 0.
+
+    Attributes:
+        itos:
+            A list of token strings indexed by their numerical identifiers.
+        stoi:
+            A :class:`~collections.defaultdict` object mapping token strings to numerical identifiers.
+    """
+
+    def __init__(self, counter: Counter, min_freq: int = 1, specials: Tuple = tuple(), unk_index: int = 0) -> Vocab:
+        self.itos = list(specials)
+        self.stoi = defaultdict(lambda: unk_index)
+        self.stoi.update({token: i for i, token in enumerate(self.itos)})
+        self.update([token for token, freq in counter.items() if freq >= min_freq])
+        self.unk_index = unk_index
+        self.n_init = len(self)
+
+    def __len__(self):
+        return len(self.itos)
+
+    def __getitem__(self, key: Union[int, str, Iterable]) -> Union[str, int, Iterable]:
+        if isinstance(key, str):
+            return self.stoi[key]
+        elif not isinstance(key, Iterable):
+            return self.itos[key]
+        elif isinstance(key[0], str):
+            return [self.stoi[i] for i in key]
+        else:
+            return [self.itos[i] for i in key]
+
+    def __contains__(self, token):
+        return token in self.stoi
+
+    def __getstate__(self):
+        # avoid picking defaultdict
+        attrs = dict(self.__dict__)
+        # cast to regular dict
+        attrs['stoi'] = dict(self.stoi)
+        return attrs
+
+    def __setstate__(self, state):
+        stoi = defaultdict(lambda: self.unk_index)
+        stoi.update(state['stoi'])
+        state['stoi'] = stoi
+        self.__dict__.update(state)
+
+    def items(self):
+        return self.stoi.items()
+
+    def update(self, vocab: Union[Iterable[str], Vocab, Counter]) -> Vocab:
+        if isinstance(vocab, Vocab):
+            vocab = vocab.itos
+        # NOTE: PAY CAREFUL ATTENTION TO DICT ORDER UNDER DISTRIBUTED TRAINING!
+        vocab = sorted(set(vocab).difference(self.stoi))
+        self.itos.extend(vocab)
+        self.stoi.update({token: i for i, token in enumerate(vocab, len(self.stoi))})
+        return self
diff --git a/tania_scripts/supar/vector_quantize.py b/tania_scripts/supar/vector_quantize.py
new file mode 100644
index 0000000..7e9a6ac
--- /dev/null
+++ b/tania_scripts/supar/vector_quantize.py
@@ -0,0 +1,130 @@
+import numpy as np
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+from clusopt_core.cluster import Streamkm
+
+
+def ema_inplace(moving_avg, new, decay):
+    moving_avg.data.mul_(decay).add_(new, alpha=(1 - decay))
+
+
+def laplace_smoothing(x, n_categories, eps=1e-5):
+    return (x + eps) / (x.sum() + n_categories * eps)
+
+
+class VectorQuantize(nn.Module):
+    # Based on: https://github.com/lucidrains/vector-quantize-pytorch
+    def __init__(
+        self,
+        dim,
+        n_embed,
+        decay=0.8,
+        commitment=1.0,
+        eps=1e-5,
+        wait_steps=0,
+        observe_steps=1245,
+        coreset_size_multiplier=10,
+    ):
+        super().__init__()
+
+        self.dim = dim
+        self.n_embed = n_embed
+        self.decay = decay
+        self.eps = eps
+        self.commitment = commitment
+
+        embed = torch.randn(dim, n_embed)
+        self.register_buffer("embed", nn.Parameter(embed))
+        self.register_buffer("cluster_size", torch.zeros(n_embed))
+        self.register_buffer("embed_avg", nn.Parameter(embed.clone()))
+
+        self.wait_steps_remaining = wait_steps
+        self.observe_steps_remaining = observe_steps
+        self.clustering_model = Streamkm(
+            coresetsize=n_embed * coreset_size_multiplier,
+            length=1500000,
+            seed=42,
+        )
+        self.data_chunks = []
+
+    def stream_cluster(self, input, expected_num_tokens=None):
+        input = input.reshape(-1, self.dim)
+        input_np = input.detach().cpu().numpy()
+        assert len(input.shape) == 2
+        self.data_chunks.append(input_np)
+        if (
+            expected_num_tokens is not None
+            and sum([chunk.shape[0] for chunk in self.data_chunks])
+            < expected_num_tokens
+        ):
+            return  # This is not the last sub-batch.
+        if self.wait_steps_remaining > 0:
+            self.wait_steps_remaining -= 1
+            self.data_chunks.clear()
+            return
+
+        self.observe_steps_remaining -= 1
+        input_np = np.concatenate(self.data_chunks, axis=0)
+        self.data_chunks.clear()
+        self.clustering_model.partial_fit(input_np)
+        if self.observe_steps_remaining == 0:
+            print("\nInitializing vq clusters (this may take a while)...")
+            clusters, _ = self.clustering_model.get_final_clusters(
+                self.n_embed, seed=42
+            )
+            new_embed = torch.tensor(
+                clusters.T, dtype=self.embed.dtype, device=self.embed.device
+            )
+            self.embed.copy_(new_embed)
+            # Don't set initial cluster sizes to zero! If a cluster is rare,
+            # embed_avg will be undergoing exponential decay until it's seen for
+            # the first time. If cluster_size is zero, this will lead to *embed*
+            # also undergoing exponential decay towards the origin before the
+            # cluster is ever encountered. Initializing to 1.0 will instead will
+            # instead leave embed in place for many iterations, up until
+            # cluster_size finally decays to near-zero.
+            self.cluster_size.fill_(1.0)
+            self.embed_avg.copy_(new_embed)
+
+    def forward(self, input, expected_num_tokens=None):
+        if self.observe_steps_remaining > 0:
+            if self.training:
+                self.stream_cluster(input, expected_num_tokens)
+            return (
+                input,
+                torch.zeros(input.shape[0],
+                            dtype=torch.long, device=input.device),
+                torch.tensor(0.0, dtype=input.dtype, device=input.device),
+                None
+            )
+
+        dtype = input.dtype
+        flatten = input.reshape(-1, self.dim)
+        dist = (
+            flatten.pow(2).sum(1, keepdim=True)
+            - 2 * flatten @ self.embed
+            + self.embed.pow(2).sum(0, keepdim=True)
+        )
+        _, embed_ind = (-dist).max(1)
+        embed_onehot = F.one_hot(embed_ind, self.n_embed).type(dtype)
+        embed_ind = embed_ind.view(*input.shape[:-1])
+        quantize = F.embedding(embed_ind, self.embed.transpose(0, 1))
+
+        if self.training:
+            ema_inplace(self.cluster_size, embed_onehot.sum(0), self.decay)
+            embed_sum = flatten.transpose(0, 1) @ embed_onehot
+            ema_inplace(self.embed_avg, embed_sum, self.decay)
+            cluster_size = (
+                laplace_smoothing(self.cluster_size, self.n_embed, self.eps)
+                * self.cluster_size.sum()
+            )
+            embed_normalized = self.embed_avg / cluster_size.unsqueeze(0)
+            self.embed.data.copy_(embed_normalized)
+
+        loss = F.mse_loss(quantize.detach(), input) * self.commitment
+        quantize = input + (quantize - input).detach()
+        quantize = torch.reshape(quantize, input.size())
+        return quantize, embed_ind, loss, dist
diff --git a/tania_scripts/tania-some-other-metrics.ipynb b/tania_scripts/tania-some-other-metrics.ipynb
index e23180b..ceb6052 100644
--- a/tania_scripts/tania-some-other-metrics.ipynb
+++ b/tania_scripts/tania-some-other-metrics.ipynb
@@ -88,7 +88,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": 4,
    "id": "2a882cc9-8f9d-4457-becb-d2e26ab3f14f",
    "metadata": {},
    "outputs": [
@@ -107,7 +107,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 6,
+   "execution_count": 5,
    "id": "8897dcc3-4218-4ee5-9984-17b9a6d8dce2",
    "metadata": {},
    "outputs": [],
@@ -163,7 +163,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 7,
+   "execution_count": 6,
    "id": "1363f307-fa4b-43ba-93d5-2d1c11ceb9e4",
    "metadata": {},
    "outputs": [
@@ -184,7 +184,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 8,
+   "execution_count": 7,
    "id": "1362e192-514a-4a77-a8cb-5c012026e2bb",
    "metadata": {},
    "outputs": [],
@@ -238,7 +238,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 9,
+   "execution_count": 8,
    "id": "544ff6aa-4104-4580-a01f-97429ffcc228",
    "metadata": {},
    "outputs": [
@@ -328,7 +328,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 10,
+   "execution_count": 9,
    "id": "b9052dc2-ce45-4af4-a0a0-46c60a13da12",
    "metadata": {},
    "outputs": [],
@@ -388,7 +388,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 11,
+   "execution_count": 10,
    "id": "1e9dd0fb-db6a-47d1-8bfb-1015845f6d3e",
    "metadata": {},
    "outputs": [
@@ -398,7 +398,7 @@
        "{'Flesch-Douma': 88.68, 'LIX': 11.55, 'Kandel-Moles': 5.86}"
       ]
      },
-     "execution_count": 11,
+     "execution_count": 10,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -421,7 +421,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 12,
+   "execution_count": 11,
    "id": "24bc84a5-b2df-4194-838a-8f24302599bd",
    "metadata": {},
    "outputs": [],
@@ -467,7 +467,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 13,
+   "execution_count": 12,
    "id": "0cdb972f-31b6-4e7e-82a8-371eda344f2c",
    "metadata": {},
    "outputs": [
@@ -477,7 +477,7 @@
        "{'Average Word Length': 3.79, 'Average Sentence Length': 7.0}"
       ]
      },
-     "execution_count": 13,
+     "execution_count": 12,
      "metadata": {},
      "output_type": "execute_result"
     }
@@ -521,7 +521,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 14,
+   "execution_count": 13,
    "id": "56af520c-d56b-404a-aebf-ad7c2a9ca503",
    "metadata": {},
    "outputs": [],
@@ -567,7 +567,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 15,
+   "execution_count": 14,
    "id": "f7c8b125-4651-4b21-bcc4-93ef78a4239b",
    "metadata": {},
    "outputs": [
@@ -603,7 +603,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 23,
+   "execution_count": 15,
    "id": "daa17c33-adca-4695-90eb-741579382939",
    "metadata": {},
    "outputs": [],
@@ -622,7 +622,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 25,
+   "execution_count": 16,
    "id": "80d8fa08-6b7d-4ab7-85cd-987823639277",
    "metadata": {},
    "outputs": [
@@ -665,7 +665,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 22,
+   "execution_count": 18,
    "id": "3f9c7dc7-6820-4013-a85c-2af4f846d4f5",
    "metadata": {},
    "outputs": [
@@ -693,7 +693,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 18,
+   "execution_count": 19,
    "id": "65e1a630-c46e-4b18-9831-b97864de53ee",
    "metadata": {},
    "outputs": [],
@@ -713,7 +713,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 21,
+   "execution_count": 20,
    "id": "1612e911-12a8-47c9-b811-b2d6885c3647",
    "metadata": {},
    "outputs": [
@@ -742,7 +742,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 19,
+   "execution_count": 21,
    "id": "925a3a75-aaaa-4851-b77b-b42cb1e21e11",
    "metadata": {},
    "outputs": [],
@@ -757,7 +757,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 20,
+   "execution_count": 22,
    "id": "6fa60897-ad26-43b4-b8de-861290ca6bd3",
    "metadata": {},
    "outputs": [
@@ -783,25 +783,10 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 4,
+   "execution_count": 23,
    "id": "f3678462-e572-4ce5-8d3d-a5389b2356c8",
    "metadata": {},
-   "outputs": [
-    {
-     "name": "stdout",
-     "output_type": "stream",
-     "text": [
-      "Defaulting to user installation because normal site-packages is not writeable\n",
-      "Collecting scipy\n",
-      "  Downloading scipy-1.15.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (61 kB)\n",
-      "Requirement already satisfied: numpy<2.5,>=1.23.5 in /public/conda/Miniconda/envs/pytorch-2.6/lib/python3.11/site-packages (from scipy) (2.2.4)\n",
-      "Downloading scipy-1.15.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (37.7 MB)\n",
-      "\u001b[2K   \u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\u001b[0m \u001b[32m37.7/37.7 MB\u001b[0m \u001b[31m75.5 MB/s\u001b[0m eta \u001b[36m0:00:00\u001b[0ma \u001b[36m0:00:01\u001b[0m\n",
-      "\u001b[?25hInstalling collected packages: scipy\n",
-      "Successfully installed scipy-1.15.3\n"
-     ]
-    }
-   ],
+   "outputs": [],
    "source": [
     "#!pip3 install seaborn\n",
     "#!pip3 install scipy"
@@ -809,7 +794,7 @@
   },
   {
    "cell_type": "code",
-   "execution_count": 5,
+   "execution_count": 24,
    "id": "b621b2a8-488f-44db-b085-fe156f453943",
    "metadata": {},
    "outputs": [
@@ -830,7 +815,7 @@
     "import matplotlib.pyplot as plt\n",
     "from scipy.stats import spearmanr\n",
     "\n",
-    "# Sample data (replace with your real values)\n",
+    "# Sample data (to be replaces with real values)\n",
     "data = {\n",
     "    \"perplexity\": [32.5, 45.2, 28.1, 39.0, 50.3],\n",
     "    \"avg_word_length\": [4.1, 4.3, 4.0, 4.2, 4.5],\n",
@@ -853,10 +838,123 @@
     "plt.show()"
    ]
   },
+  {
+   "cell_type": "markdown",
+   "id": "45ee04fc-acab-4bba-ba06-e4cf4bca9fe5",
+   "metadata": {},
+   "source": [
+    "## Tree depth"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 25,
+   "id": "79f99787-c220-4f1d-93a9-59230363ec3f",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "def parse_sentence_block(text):\n",
+    "    lines = text.strip().split('\\n')\n",
+    "    result = []\n",
+    "    tokenlist = []\n",
+    "    for line in lines:\n",
+    "        # Split the line by tab and strip whitespace\n",
+    "        parts = tuple(line.strip().split('\\t'))\n",
+    "        # Only include lines that have exactly 4 parts\n",
+    "        if len(parts) == 4:\n",
+    "            parentidx =  int(parts[3])\n",
+    "            if '@@' in parts[2]:\n",
+    "                nonterm1 = parts[2].split('@@')[0]\n",
+    "                nonterm2 = parts[2].split('@@')[1]\n",
+    "            else:\n",
+    "                nonterm1 = parts[2]\n",
+    "                nonterm2 = '<nul>'\n",
+    "            postag = parts[1]\n",
+    "            token = parts[0]\n",
+    "            result.append((parentidx, nonterm1, nonterm2, postag))\n",
+    "            tokenlist.append(token)\n",
+    "    return result, tokenlist\n",
+    "    "
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 26,
+   "id": "f567efb0-8b0b-4782-9345-052cf1785776",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "example_sentence = \"\"\"\n",
+    "<s>\t<s>\t<s>\t1\n",
+    "--\tponct\t<nul>@@<nul>\t1\n",
+    "Eh\tnpp\t<nul>@@<nul>\t1\n",
+    "bien?\tadv\tAP@@<nul>\t1\n",
+    "fit\tv\tVN@@<nul>\t2\n",
+    "-il\tcls-suj\tVN@@VPinf-OBJ\t3\n",
+    ".\tponct\t<nul>@@<nul>\t4\n",
+    "</s>\t</s>\t</s>\t4\n",
+    "\"\"\""
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 29,
+   "id": "8d4ecba9-89b8-4000-a061-aa16aa68a404",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "from transform import *\n",
+    "\n",
+    "def visualize_const_prediction(example_sent):\n",
+    "    parsed, tokenlist = parse_sentence_block(example_sent)\n",
+    "    tree = AttachJuxtaposeTree.totree(tokenlist, 'SENT')\n",
+    "    AttachJuxtaposeTree.action2tree(tree, parsed).pretty_print()\n",
+    "    nltk_tree = AttachJuxtaposeTree.action2tree(tree, parsed)\n",
+    "    #print(\"NLTK TREE\", nltk_tree)\n",
+    "    depth = nltk_tree.height() - 1  # NLTK includes the leaf level as height 1, so subtract 1 for tree depth \n",
+    "    print(\"Tree depth:\", depth)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 30,
+   "id": "bfd3abf3-b83a-4817-85ad-654daf72be88",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "               SENT                                 \n",
+      "                |                                    \n",
+      "               <s>                                  \n",
+      "                |                                    \n",
+      "               <s>                                  \n",
+      "  ______________|__________                          \n",
+      " |    |    |               AP                       \n",
+      " |    |    |     __________|________                 \n",
+      " |    |    |    |               VPinf-OBJ           \n",
+      " |    |    |    |     ______________|_______         \n",
+      " |    |    |    |    |                      VN      \n",
+      " |    |    |    |    |      ________________|____    \n",
+      " |    |    |    |    VN    |                |   </s>\n",
+      " |    |    |    |    |     |                |    |   \n",
+      " |  ponct npp  adv   v  cls-suj           ponct </s>\n",
+      " |    |    |    |    |     |                |    |   \n",
+      "<s>   --   Eh bien? fit   -il               .   </s>\n",
+      "\n",
+      "Tree depth: 8\n"
+     ]
+    }
+   ],
+   "source": [
+    "visualize_const_prediction(example_sentence)"
+   ]
+  },
   {
    "cell_type": "code",
    "execution_count": null,
-   "id": "3a6e3b53-7104-45ef-a4b5-e831bdd6ca6f",
+   "id": "bc51ab44-6885-45cc-bad2-6a43a7791fdb",
    "metadata": {},
    "outputs": [],
    "source": []
diff --git a/tania_scripts/transform.py b/tania_scripts/transform.py
new file mode 100644
index 0000000..56e0f51
--- /dev/null
+++ b/tania_scripts/transform.py
@@ -0,0 +1,459 @@
+# -*- coding: utf-8 -*-
+
+from __future__ import annotations
+
+import os
+from typing import TYPE_CHECKING, Iterable, List, Optional, Tuple, Union
+
+import nltk
+import torch
+
+from supar.models.const.crf.transform import Tree
+from supar.utils.common import NUL
+from supar.utils.logging import get_logger
+from supar.utils.tokenizer import Tokenizer
+from supar.utils.transform import Sentence
+
+if TYPE_CHECKING:
+    from supar.utils import Field
+
+logger = get_logger(__name__)
+
+
+class AttachJuxtaposeTree(Tree):
+    r"""
+    :class:`AttachJuxtaposeTree` is derived from the :class:`Tree` class,
+    supporting back-and-forth transformations between trees and AttachJuxtapose actions :cite:`yang-deng-2020-aj`.
+
+    Attributes:
+        WORD:
+            Words in the sentence.
+        POS:
+            Part-of-speech tags, or underscores if not available.
+        TREE:
+            The raw constituency tree in :class:`nltk.tree.Tree` format.
+        NODE:
+            The target node on each rightmost chain.
+        PARENT:
+            The label of the parent node of each terminal.
+        NEW:
+            The label of each newly inserted non-terminal with a target node and a terminal as juxtaposed children.
+            ``NUL`` represents the `Attach` action.
+    """
+
+    fields = ['WORD', 'POS', 'TREE', 'NODE', 'PARENT', 'NEW']
+
+    def __init__(
+        self,
+        WORD: Optional[Union[Field, Iterable[Field]]] = None,
+        POS: Optional[Union[Field, Iterable[Field]]] = None,
+        TREE: Optional[Union[Field, Iterable[Field]]] = None,
+        NODE: Optional[Union[Field, Iterable[Field]]] = None,
+        PARENT: Optional[Union[Field, Iterable[Field]]] = None,
+        NEW: Optional[Union[Field, Iterable[Field]]] = None
+    ) -> Tree:
+        super().__init__()
+
+        self.WORD = WORD
+        self.POS = POS
+        self.TREE = TREE
+        self.NODE = NODE
+        self.PARENT = PARENT
+        self.NEW = NEW
+
+    @property
+    def src(self):
+        return self.WORD, self.POS, self.TREE
+
+    @property
+    def tgt(self):
+        return self.NODE, self.PARENT, self.NEW
+
+    @classmethod
+    def tree2action(cls, tree: nltk.Tree):
+        r"""
+        Converts a constituency tree into AttachJuxtapose actions.
+
+        Args:
+            tree (nltk.tree.Tree):
+                A constituency tree in :class:`nltk.tree.Tree` format.
+
+        Returns:
+            A sequence of AttachJuxtapose actions.
+
+        Examples:
+            >>> from supar.models.const.aj.transform import AttachJuxtaposeTree
+            >>> tree = nltk.Tree.fromstring('''
+                                            (TOP
+                                              (S
+                                                (NP (_ Arthur))
+                                                (VP
+                                                  (_ is)
+                                                  (NP (NP (_ King)) (PP (_ of) (NP (_ the) (_ Britons)))))
+                                                (_ .)))
+                                            ''')
+            >>> tree.pretty_print()
+                            TOP
+                             |
+                             S
+               ______________|_______________________
+              |              VP                      |
+              |      ________|___                    |
+              |     |            NP                  |
+              |     |    ________|___                |
+              |     |   |            PP              |
+              |     |   |     _______|___            |
+              NP    |   NP   |           NP          |
+              |     |   |    |        ___|_____      |
+              _     _   _    _       _         _     _
+              |     |   |    |       |         |     |
+            Arthur  is King  of     the     Britons  .
+            >>> AttachJuxtaposeTree.tree2action(tree)
+            [(0, 'NP', '<nul>'), (0, 'VP', 'S'), (1, 'NP', '<nul>'),
+             (2, 'PP', 'NP'), (3, 'NP', '<nul>'), (4, '<nul>', '<nul>'),
+             (0, '<nul>', '<nul>')]
+        """
+
+        def isroot(node):
+            return node == tree[0]
+
+        def isterminal(node):
+            return len(node) == 1 and not isinstance(node[0], nltk.Tree)
+
+        def last_leaf(node):
+            pos = ()
+            while True:
+                pos += (len(node) - 1,)
+                node = node[-1]
+                if isterminal(node):
+                    return node, pos
+
+        def parent(position):
+            return tree[position[:-1]]
+
+        def grand(position):
+            return tree[position[:-2]]
+
+        def detach(tree):
+            last, last_pos = last_leaf(tree)
+            siblings = parent(last_pos)[:-1]
+
+            if len(siblings) > 0:
+                last_subtree = last
+                last_subtree_siblings = siblings
+                parent_label = NUL
+            else:
+                last_subtree, last_pos = parent(last_pos), last_pos[:-1]
+                last_subtree_siblings = [] if isroot(last_subtree) else parent(last_pos)[:-1]
+                parent_label = last_subtree.label()
+
+            target_pos, new_label, last_tree = 0, NUL, tree
+            if isroot(last_subtree):
+                last_tree = None
+            
+            elif len(last_subtree_siblings) == 1 and not isterminal(last_subtree_siblings[0]):
+                new_label = parent(last_pos).label()
+                new_label = new_label
+                target = last_subtree_siblings[0]
+                last_grand = grand(last_pos)
+                if last_grand is None:
+                    last_tree = targetistermina
+                else:
+                    last_grand[-1] = target
+                target_pos = len(last_pos) - 2
+            else:
+                target = parent(last_pos)
+                target.pop()
+                target_pos = len(last_pos) - 2
+            action = target_pos, parent_label, new_label
+            return action, last_tree
+        if tree is None:
+            return []
+        action, last_tree = detach(tree)
+        return cls.tree2action(last_tree) + [action]
+
+    @classmethod
+    def action2tree(
+        cls,
+        tree: nltk.Tree,
+        actions: List[Tuple[int, str, str]],
+        join: str = '::',
+    ) -> nltk.Tree:
+        r"""
+        Recovers a constituency tree from a sequence of AttachJuxtapose actions.
+
+        Args:
+            tree (nltk.tree.Tree):
+                An empty tree that provides a base for building a result tree.
+            actions (List[Tuple[int, str, str]]):
+                A sequence of AttachJuxtapose actions.
+            join (str):
+                A string used to connect collapsed node labels. Non-terminals containing this will be expanded to unary chains.
+                Default: ``'::'``.
+
+        Returns:
+            A result constituency tree.
+
+        Examples:
+            >>> from supar.models.const.aj.transform import AttachJuxtaposeTree
+            >>> tree = AttachJuxtaposeTree.totree(['Arthur', 'is', 'King', 'of', 'the', 'Britons', '.'], 'TOP')
+            >>> AttachJuxtaposeTree.action2tree(tree,
+                                                [(0, 'NP', '<nul>'), (0, 'VP', 'S'), (1, 'NP', '<nul>'),
+                                                 (2, 'PP', 'NP'), (3, 'NP', '<nul>'), (4, '<nul>', '<nul>'),
+                                                 (0, '<nul>', '<nul>')]).pretty_print()
+                            TOP
+                             |
+                             S
+               ______________|_______________________
+              |              VP                      |
+              |      ________|___                    |
+              |     |            NP                  |
+              |     |    ________|___                |
+              |     |   |            PP              |
+              |     |   |     _______|___            |
+              NP    |   NP   |           NP          |
+              |     |   |    |        ___|_____      |
+              _     _   _    _       _         _     _
+              |     |   |    |       |         |     |
+            Arthur  is King  of     the     Britons  .
+        """
+
+        def target(node, depth):
+            node_pos = ()
+            for _ in range(depth):
+                node_pos += (len(node) - 1,)
+                node = node[-1]
+            return node, node_pos
+
+        def parent(tree, position):
+            return tree[position[:-1]]
+
+        def execute(tree: nltk.Tree, terminal: Tuple(str, str), action: Tuple[int, str, str]) -> nltk.Tree:
+            target_pos, parent_label, new_label, post = action
+            #print(target_pos, parent_label, new_label)
+            new_leaf = nltk.Tree(post, [terminal[0]])
+
+            # create the subtree to be inserted
+            new_subtree = new_leaf if parent_label == NUL else nltk.Tree(parent_label, [new_leaf])
+            # find the target position at which to insert the new subtree
+            target_node = tree
+            if target_node is not None:
+                target_node, target_pos = target(target_node, target_pos)
+
+            # Attach
+            if new_label == NUL:
+                # attach the first token
+                if target_node is None:
+                    return new_subtree
+                target_node.append(new_subtree)
+            # Juxtapose
+            else:
+                new_subtree = nltk.Tree(new_label, [target_node, new_subtree])
+                if len(target_pos) > 0:
+                    parent_node = parent(tree, target_pos)
+                    parent_node[-1] = new_subtree
+                else:
+                    tree = new_subtree
+            return tree
+
+        tree, root, terminals = None, tree.label(), tree.pos()
+        for terminal, action in zip(terminals, actions):
+            tree = execute(tree, terminal, action)
+        # recover unary chains
+        nodes = [tree]
+        while nodes:
+            node = nodes.pop()
+            if isinstance(node, nltk.Tree):
+                nodes.extend(node)
+                if join in node.label():
+                    labels = node.label().split(join)
+                    node.set_label(labels[0])
+                    subtree = nltk.Tree(labels[-1], node)
+                    for label in reversed(labels[1:-1]):
+                        subtree = nltk.Tree(label, [subtree])
+                    node[:] = [subtree]
+        return nltk.Tree(root, [tree])
+
+    @classmethod
+    def action2span(
+        cls,
+        action: torch.Tensor,
+        spans: torch.Tensor = None,
+        nul_index: int = -1,
+        mask: torch.BoolTensor = None
+    ) -> torch.Tensor:
+        r"""
+        Converts a batch of the tensorized action at a given step into spans.
+
+        Args:
+            action (~torch.Tensor): ``[3, batch_size]``.
+                A batch of the tensorized action at a given step, containing indices of target nodes, parent and new labels.
+            spans (~torch.Tensor):
+                Spans generated at previous steps, ``None`` at the first step. Default: ``None``.
+            nul_index (int):
+                The index for the obj:`NUL` token, representing the Attach action. Default: -1.
+            mask (~torch.BoolTensor): ``[batch_size]``.
+                The mask for covering the unpadded tokens.
+
+        Returns:
+            A tensor representing a batch of spans for the given step.
+
+        Examples:
+            >>> from collections import Counter
+            >>> from supar.models.const.aj.transform import AttachJuxtaposeTree, Vocab
+            >>> from supar.utils.common import NUL
+            >>> nodes, parents, news = zip(*[(0, 'NP', NUL), (0, 'VP', 'S'), (1, 'NP', NUL),
+                                             (2, 'PP', 'NP'), (3, 'NP', NUL), (4, NUL, NUL),
+                                             (0, NUL, NUL)])
+            >>> vocab = Vocab(Counter(sorted(set([*parents, *news]))))
+            >>> actions = torch.tensor([nodes, vocab[parents], vocab[news]]).unsqueeze(1)
+            >>> spans = None
+            >>> for action in actions.unbind(-1):
+            ...     spans = AttachJuxtaposeTree.action2span(action, spans, vocab[NUL])
+            ...
+            >>> spans
+            tensor([[[-1,  1, -1, -1, -1, -1, -1,  3],
+                     [-1, -1, -1, -1, -1, -1,  4, -1],
+                     [-1, -1, -1,  1, -1, -1,  1, -1],
+                     [-1, -1, -1, -1, -1, -1,  2, -1],
+                     [-1, -1, -1, -1, -1, -1,  1, -1],
+                     [-1, -1, -1, -1, -1, -1, -1, -1],
+                     [-1, -1, -1, -1, -1, -1, -1, -1],
+                     [-1, -1, -1, -1, -1, -1, -1, -1]]])
+            >>> sequence = torch.where(spans.ge(0))
+            >>> sequence = list(zip(sequence[1].tolist(), sequence[2].tolist(), vocab[spans[sequence]]))
+            >>> sequence
+            [(0, 1, 'NP'), (0, 7, 'S'), (1, 6, 'VP'), (2, 3, 'NP'), (2, 6, 'NP'), (3, 6, 'PP'), (4, 6, 'NP')]
+            >>> tree = AttachJuxtaposeTree.totree(['Arthur', 'is', 'King', 'of', 'the', 'Britons', '.'], 'TOP')
+            >>> AttachJuxtaposeTree.build(tree, sequence).pretty_print()
+                            TOP
+                             |
+                             S
+               ______________|_______________________
+              |              VP                      |
+              |      ________|___                    |
+              |     |            NP                  |
+              |     |    ________|___                |
+              |     |   |            PP              |
+              |     |   |     _______|___            |
+              NP    |   NP   |           NP          |
+              |     |   |    |        ___|_____      |
+              _     _   _    _       _         _     _
+              |     |   |    |       |         |     |
+            Arthur  is King  of     the     Britons  .
+
+        """
+
+        # [batch_size]
+        target, parent, new = action
+        if spans is None:
+            spans = action.new_full((action.shape[1], 2, 2), -1)
+            spans[:, 0, 1] = parent
+            return spans
+        if mask is None:
+            mask = torch.ones_like(target, dtype=bool)
+        juxtapose_mask = new.ne(nul_index) & mask
+        # ancestor nodes are those on the rightmost chain and higher than the target node
+        # [batch_size, seq_len]
+        rightmost_mask = spans[..., -1].ge(0)
+        ancestors = rightmost_mask.cumsum(-1).masked_fill_(~rightmost_mask, -1) - 1
+        # should not include the target node for the Juxtapose action
+        ancestor_mask = mask.unsqueeze(-1) & ancestors.ge(0) & ancestors.le((target - juxtapose_mask.long()).unsqueeze(-1))
+        target_pos = torch.where(ancestors.eq(target.unsqueeze(-1))[juxtapose_mask])[-1]
+        # the right boundaries of ancestor nodes should be aligned with the new generated terminals
+        spans = torch.cat((spans, torch.where(ancestor_mask, spans[..., -1], -1).unsqueeze(-1)), -1)
+        spans[..., -2].masked_fill_(ancestor_mask, -1)
+        spans[juxtapose_mask, target_pos, -1] = new.masked_fill(new.eq(nul_index), -1)[juxtapose_mask]
+        spans[mask, -1, -1] = parent.masked_fill(parent.eq(nul_index), -1)[mask]
+        # [batch_size, seq_len+1, seq_len+1]
+        spans = torch.cat((spans, torch.full_like(spans[:, :1], -1)), 1)
+        return spans
+
+    def load(
+        self,
+        data: Union[str, Iterable],
+        lang: Optional[str] = None,
+        **kwargs
+    ) -> List[AttachJuxtaposeTreeSentence]:
+        r"""
+        Args:
+            data (Union[str, Iterable]):
+                A filename or a list of instances.
+            lang (str):
+                Language code (e.g., ``en``) or language name (e.g., ``English``) for the text to tokenize.
+                ``None`` if tokenization is not required.
+                Default: ``None``.
+
+        Returns:
+            A list of :class:`AttachJuxtaposeTreeSentence` instances.
+        """
+
+        if lang is not None:
+            tokenizer = Tokenizer(lang)
+        if isinstance(data, str) and os.path.exists(data):
+            if data.endswith('.txt'):
+                data = (s.split() if lang is None else tokenizer(s) for s in open(data) if len(s) > 1)
+            else:
+                data = open(data)
+        else:
+            if lang is not None:
+                data = [tokenizer(i) for i in ([data] if isinstance(data, str) else data)]
+            else:
+                data = [data] if isinstance(data[0], str) else data
+
+        index = 0
+        for s in data:
+
+            try:
+                tree = nltk.Tree.fromstring(s) if isinstance(s, str) else self.totree(s, self.root)
+                sentence = AttachJuxtaposeTreeSentence(self, tree, index)
+            except ValueError:
+                logger.warning(f"Error found while converting Sentence {index} to a tree:\n{s}\nDiscarding it!")
+                continue
+            except IndexError:
+                tree = nltk.Tree.fromstring('(S ' + s + ')')
+                sentence = AttachJuxtaposeTreeSentence(self, tree, index)
+            else:
+                yield sentence
+                index += 1
+        self.root = tree.label()
+
+
+class AttachJuxtaposeTreeSentence(Sentence):
+    r"""
+    Args:
+        transform (AttachJuxtaposeTree):
+            A :class:`AttachJuxtaposeTree` object.
+        tree (nltk.tree.Tree):
+            A :class:`nltk.tree.Tree` object.
+        index (Optional[int]):
+            Index of the sentence in the corpus. Default: ``None``.
+    """
+
+    def __init__(
+        self,
+        transform: AttachJuxtaposeTree,
+        tree: nltk.Tree,
+        index: Optional[int] = None
+    ) -> AttachJuxtaposeTreeSentence:
+        super().__init__(transform, index)
+
+        words, tags = zip(*tree.pos())
+        nodes, parents, news = None, None, None
+        if transform.training:
+            oracle_tree = tree.copy(True)
+            # the root node must have a unary chain
+            if len(oracle_tree) > 1:
+                oracle_tree[:] = [nltk.Tree('*', oracle_tree)]
+            oracle_tree.collapse_unary(joinChar='::')
+            if len(oracle_tree) == 1 and not isinstance(oracle_tree[0][0], nltk.Tree):
+                oracle_tree[0] = nltk.Tree('*', [oracle_tree[0]])
+            nodes, parents, news = zip(*transform.tree2action(oracle_tree))
+        tags = [x.split("##")[0] for x in tags]
+        self.values = [words, tags, tree, nodes, parents, news]
+
+    def __repr__(self):
+        return self.values[-4].pformat(1000000)
+
+    def pretty_print(self):
+        self.values[-4].pretty_print()
-- 
GitLab