المرجع: صوتيات القرآن وأحكام التجويد

كيف ينبغي أن تكون التلاوة صوتًا صوتًا وحكمًا حكمًا: محرّك quran-g2p ومجموعة بيانات quran-tajweed-phonetics، وكيف يرتبطان بالوحدات المتوقَّعة من النموذج، وأين نصّ أهل العلم على كل حكم في كتبهم.

النموذج يسمع. أما كيف ينبغي أن تكون التلاوة صوتًا صوتًا وحكمًا حكمًا، فذلك هو مرجع Quran Lab لصوتيات القرآن وأحكام تجويده، برواية حفص عن عاصم من طريق الشاطبية. تُكتب فيه كل آية أصواتًا (phones)، ويحمل كل صوت الأحكام التي جعلته على ما هو عليه. وهو الأساس الذي أُخذت منه تسميات النموذج والوحدات المتوقَّعة منه (model.reference). وهو منشور في موضعين: المحرّك quran-g2p، ومجموعة البيانات المصنوعة به quran-tajweed-phonetics.

من الحكم إلى الكتاب والصفحة

يذكر كل صوت في مجموعة البيانات، في الحقل rules، معرّفات الأحكام التي أنتجته، مثل R185_MUTTASIL. ويُحال كل معرّف في الملف rulings.jsonl من مجموعة البيانات إلى اسم الحكم بالعربية والإنجليزية، ومرحلته، وإحالته إلى المصادر الكلاسيكية كما يوردها الملف: الكتاب، مع الجزء والصفحة أو رقم البيت. فإذا وجد المُقيِّم الخاص بتطبيقك، مما سمعه النموذج، أن المتعلّم لم يقرأ موضعًا كما يقرّره المرجع، أمكن التطبيقَ أن يُري المتعلّم الحكمَ الذي ينطبق هناك وأين نصّ عليه العلماء. ويعرض المثال التطبيقي أدناه السلسلة كاملة على بيانات حقيقية.

تدلّ الإحالة على الموضع الذي نصّت فيه الكتب الكلاسيكية على الحكم الذي يطبّقه المحرّك. ولا تعني أن المتعلّم أخطأ. فذلك حكم يصدره تطبيقك بناءً على مخرجات النموذج (ابنِ ملاحظاتك بنفسك)، ولا يقول الـ SDK ولا Quran Lab لأي متعلّم أبدًا إنه خالف حكمًا.

ما تغطّيه الملفات المنشورة، كما عُدَّ لهذه الصفحة:

  • تحمل الأصوات 45 معرّفًا مختلفًا في rules. يُحال 44 منها في rulings.jsonl. أما المعرّف رقم 45، EMIT، فليس حكمًا: إنه يسجّل أن الصوت قُرئ من النص المكتوب، فتجاوزه.
  • في rulings.jsonl 62 حكمًا، كلٌّ منها مطابق لسجلّ أحكام المحرّك حقلًا بحقل. وفي السجلّ اليوم 63 حكمًا: الحكم الذي ينقص الملف، R162_NAKHLUQKUM_NAQIS (الوجه الثاني في 77:20)، أُضيف إلى المحرّك بعد آخر إصدار لمجموعة البيانات، ولا يحمله أي صوت فيها. ولا يزال README المحرّك وبطاقة مجموعة البيانات يذكران 62؛ أما ملف السجلّ فيذكر 63، و63 هو العدد اليوم.
  • تذكر 53 إحالة من الـ 62 موضعًا في الكتاب: الجزء والصفحة، أو الصفحة، أو رقم البيت. وتذكر 9 منها المصنَّف دون موضع: R134_LAM_JALALA_ALIF وR180_TABEEI وR189_AARED وR212_LAM_JALALA تقتبس بيت المنظومة المُحال إليها، وR112_STRIP_INITIAL_SHADDA وR121_MADD_EWAD وR130_WASL_ELISION وR221_IMALA وR222_TASHEEL تذكر المصنَّف وحده.
  • لكل حكم صفوف مراجَعة في register_reviewed.jsonl: آية شاهدة عليه، وصياغة الحكم في تلك الآية، وقرار المراجِع (صحيح أو فيه وجهان). وتحمل هذه الصفوف معرّفات المراجعة الخاصة بها (فالحكم R185_MUTTASIL في المحرّك رُوجع باسم R182_MUTTASIL)، لذا فالطريق من معرّف المحرّك إلى صفوفه يمرّ بسجلّ أحكام المحرّك: يذكر عمود المراجعة فيه صفوف الاختبار المرجعية (golden) في tests/goldens/ التي عُرض بها الحكم على المراجعين، ويذكر كل صف منها آيته. وبهذا الطريق يصل كلٌّ من الأحكام الـ 63 إلى صفّ مراجَع واحد على الأقل.

المحرّك ومجموعة البيانات

quran-g2p هو المحرّك: يدخله النص وتخرج منه أصوات منسوبة إلى أحكام التجويد، مكتوب بلغة Python دون اعتماديات. وما يستعمله المطوّر منه:

  • src/quran_g2p/: المحرّك نفسه. تعطي phonemize أصوات الآية، وتحوّل tokenlayer_tj3 الأصواتَ إلى رموز النموذج.
  • docs/RULINGS-REGISTER.md: سجلّ الأحكام، مولَّد من شيفرة المحرّك. كل حكم بمعرّفه واسمه بالعربية والإنجليزية ومصادره وصفوف مراجعته.
  • artifacts/tokenizer_tj3/: مفردات النموذج، tokens.txt وبيانه.
  • artifacts/spans/: الأحكام على هيئة مواضع أحرف في الآيات كلها (6,236 آية)، لمشروع لا يستطيع تشغيل Python.

quran-tajweed-phonetics هي مجموعة البيانات: 6,236 آية و522,475 صوتًا، صُنعت بالمحرّك.

الملف (config) ما فيه
quran_phonetics.jsonl (phonetics) صفّ لكل آية: surah وayah وtext وphones. ولكل صوت base وkind وgeminated وword_index وtafkheem، وحيث تنطبق tafkheem_rank وghunna وqalqalah وlength وsakt_after وrules، وsifat على الحرف الصامت
rulings.jsonl (rulings) صفّ لكل حكم: rule_id وphase وname_ar وname_en وspec وcitation
register_reviewed.jsonl (register_reviewed) الصفوف المراجَعة الـ 208: row وsurah وayah وrule_id وruling_ar وcitation وreview_verdict وreviewed_by وarbitration
rule_index.jsonl (rule_index) لكل آية، كل صوت يحمل حكمًا: رقمه i بين أصوات الآية، وspan (أحرف text التي قُرئ منها)، وأحكامه ومقادير مدّه؛ وevents، وهي الأحكام التي أثرها أن صوتًا لا يُنطق
quran_labels_v1.jsonl (labels) وayah_tokens.jsonl (tokens) وtokens.txt وvocab_manifest.json تسميات وسلاسل رموز بمفردات أقدم من 234 رمزًا، لا برموز النموذج الـ 38

يعدّ word_index الكلمات الصوتية في الآية: كلمة لكل كلمة مكتوبة، إلا في 27 آية تُهجّى فيها الحروف المقطّعة (R011_MUQATTAAT)، فيكون اسم كل حرف كلمة مستقلة.

والترخيص بنصّ بطاقة مجموعة البيانات: «Quran-Lab No-Profit License 1.2 (انظر LICENSE): حرّ الاستعمال والتعديل وإعادة التوزيع، بالترخيص نفسه. والعمل نفسه ليس للبيع أبدًا، فلا يجوز لك أن تتقاضى أجرًا عليه، ولا على الوصول إليه، ولا على ميزة يشغّلها، والأمر نفسه ينطبق على ما يُشتقّ منه، ومن ذلك النماذج المدرَّبة به.»

كيف جرى التحقق منه

من بطاقة مجموعة البيانات وREADME المحرّك. يحمل كل حكم إحالته إلى المصادر الكلاسيكية، وقد رُوجعت كل إحالة على الكتب المطبوعة. وفي سجلّ الأحكام الذي قرأه المراجعون 208 مدخلًا. حكم حافظ مُجاز، هو Shaikh Sami Almadani كما تسمّيه البطاقة، على المداخل الـ 208 كلها من تلقّيه هو: أكّد 191، وأكّد 17 مع توثيق وجه ثانٍ منقول، ولم يحكم بخطأ أيٍّ منها. ثم خضع السجلّ كاملًا لتحكيم علمي رسمي (تحكيم علمي) من أستاذين عاملين في القراءات بجامعة أم القرى في مكة المكرمة، كلٌّ منهما كُلِّف على حدة ودون علم بغيره من المراجعين: أكّد الأول السجلّ، ولم تنقض أيٌّ من ملاحظات الثاني حكمًا صوتيًا. وعلى المدوّنة كلها، تعطي طبعتا المصحف المثبَّتتان (Tanzil وKFGQPC) أصواتًا متطابقة في الآيات كلها (6,236 آية)؛ وتوافق الأصوات ضبط المصحف نفسه في نحو 8,900 موضع للتنوين؛ وقد فُحصت في الاتجاهين مقابل مجموعة بيانات مواضع الأحكام quran-tajweed (60,057 تعليقًا توضيحيًا)، وكلمةً كلمةً مقابل مصحف المدينة الملوّن الصادر عن مجمع الملك فهد (77,429 كلمة)؛ وتسرد البطاقة مواضع الاختلاف.

النموذج والمرجع

الرموز الـ 38 هي رموز المحرّك. model.tokens في TajweedFormer V4 هي مفردات tj3 في المحرّك: الملف tokens.txt لنموذج 4.0.0 مطابق بايتًا ببايت للملف artifacts/tokenizer_tj3/tokens.txt (SHA-256 66fe6eb81b15506270f9e3c6efb0724cda757cd54326f26ca4bcd6be4f3b2aa4). رمز واحد لكل صوت: الحركة الطويلة رمز واحد (الحركة وحرف المدّ)، والحرف المشدّد رمز واحد. أما عدد حركات المدّ، والتشديد، ومقدار الغنّة، والرَّوم، والسكت، فليست رموزًا، وكذلك التفخيم والقلقلة ونوع الغنّة: يعطيها النموذج في رؤوس الإخراج (heads) (timing_log_probs وgem وattr_tafkheem وattr_qalqalah وattr_ghunna؛ ابنِ ملاحظاتك بنفسك). فهناك موضع الشدّة والغنّة والإدغام: رؤوس في النموذج، وgeminated وghunna ومعرّفات الأحكام في المرجع.

model.reference مصنوع من مجموعة البيانات. يحوّل مسار الإصدار في Quran Lab كل صفّ من quran_phonetics.jsonl بالدالة tokenlayer_tj3.phones_to_tj3_units من المحرّك: وحدات الآية مقروءة من أولها إلى آخرها مع الوقف هناك، وبين الكلمات حدّ الكلمة |، مع الكلمة التي تنتمي إليها كل وحدة. وقد فُحص ذلك لهذه الصفحة في الآيات كلها (6,236 آية): الجدول الذي صدر مع 4.0.0 يطابق ما ينتجه quran-g2p في التزامه العلني الحالي (7eeba12)، وأصوات مجموعة البيانات تطابق أصوات المحرّك.

الربط. تعيد phones_to_tj3_units([[p] for p in row["phones"]]) وحدات الآية، ولكل صوت رقم الوحدة التي صار إليها. وهذه الوحدات هي نفسها التي يعطيها model.reference للآية، فالوحدة i في البيانات المرجعية مكوّنة من الأصوات التي رقمها i: الحركة الطويلة هي حركتها وحرف مدّها، وكل وحدة أخرى صوت واحد. والجدول الذي يأتي مع الـ SDK لا يحمل إلا معرّفات الوحدات وكلماتها. أما الأصوات وعلاماتها وأحكامها فتأتي من مجموعة البيانات عبر هذا الربط. وللأحرف، يعطي rule_index.jsonl كل صوت يحمل حكمًا أحرف text التي قُرئ منها (span)، ويعطي المحرّك الشيء نفسه لكل صوت (src_span).

مثال تطبيقي

انسخ مستودع المحرّك وضع بجانبه ثلاثة ملفات من مجموعة البيانات: quran_phonetics.jsonl (نحو 150 ميغابايت) وrulings.jsonl وregister_reviewed.jsonl.

git clone https://github.com/Quran-Lab/quran-g2p

احفظ ما يلي باسم reference_example.py في المجلد نفسه:

# reference_example.py: the reference for one ayah, joined to the model's expected units.
#   python reference_example.py 1 1             each unit with its phones, their rules, and the rules' sources
#   python reference_example.py R185_MUTTASIL   one ruling: its row of rulings.jsonl and its reviewed rows
# Beside this file: a clone of quran-g2p, and rulings.jsonl, quran_phonetics.jsonl and register_reviewed.jsonl
# from the dataset. The ruling mode also needs pyyaml (pip install pyyaml).
import glob, json, sys
sys.path.insert(0, "quran-g2p/src")
from quran_g2p import tokenlayer_tj3 as tj3

def rows(name):
    with open(name, encoding="utf-8") as f:
        yield from map(json.loads, f)

rulings = {r["rule_id"]: r for r in rows("rulings.jsonl")}

def ayah(surah, number):
    row = next(r for r in rows("quran_phonetics.jsonl") if (r["surah"], r["ayah"]) == (surah, number))
    phones = row["phones"]
    units, first = tj3.phones_to_tj3_units([[p] for p in phones])  # first[k]: the unit phone k became
    print(row["text"])
    print("ids", [tj3.INDEX[u] for u in units])                      # what model.reference gives for the ayah
    named = []
    for i, u in enumerate(units):
        mine = [p for k, p in enumerate(phones) if first[k] == i]
        if not mine:                                                  # "|", the word boundary
            continue
        rules = list(dict.fromkeys(r for p in mine for r in p.get("rules", []) if r != "EMIT"))
        marks = ["geminated" for p in mine if p["geminated"]]
        marks += [f"{k} {p[k]}" for p in mine for k in ("ghunna", "qalqalah") if k in p]
        marks += [f"length {p['length']['allowed']}" for p in mine if "length" in p]
        print(f"{i:3} {tj3.INDEX[u]:2} {u:3} word {mine[0]['word_index']}", "+".join(p["base"] for p in mine), *marks, *rules)
        named += [r for r in rules if r not in named]
    for r in named:
        print(r, "|", rulings[r]["name_ar"], "|", rulings[r]["name_en"], "|", rulings[r]["citation"])

def ruling(rule_id):
    import yaml
    from quran_g2p.rules.registry import COVERAGE                     # the golden rows put before the reviewers
    print(json.dumps(rulings[rule_id], ensure_ascii=False))
    golden = {g["id"]: g for f in glob.glob("quran-g2p/tests/goldens/*.yaml")
              for g in yaml.safe_load(open(f, encoding="utf-8")) or []}
    sites = {(golden[g]["surah"], golden[g]["ayah"], golden[g]["rule"]) for g in COVERAGE[rule_id]}
    for r in rows("register_reviewed.jsonl"):
        if (r["surah"], r["ayah"], r["rule_id"]) in sites:
            print("row", r["row"], f"{r['surah']}:{r['ayah']}", r["rule_id"], "|", r["ruling_ar"], "|", r["review_verdict"])

if sys.argv[1].startswith("R"):
    ruling(sys.argv[1])
else:
    ayah(int(sys.argv[1]), int(sys.argv[2]))

python reference_example.py 1 1، الفاتحة 1:1. يُقرأ كل سطر هكذا: رقم الوحدة في model.reference للآية، ومعرّفها في model.tokens، والرمز، وكلمته، والأصوات التي صُنع منها مع علاماتها، ومعرّفات أحكامها. والأرقام التي تتخطّاها القائمة (5، 10، 18) هي حدود الكلمات. وتسمّي الأسطر الأخيرة كل حكم من rulings.jsonl مع إحالته كما وردت في الملف تمامًا.

بِسْمِ ٱللَّهِ ٱلرَّحْمَٰنِ ٱلرَّحِيمِ
ids [3, 32, 13, 25, 32, 1, 24, 34, 27, 32, 1, 11, 31, 7, 25, 34, 26, 32, 1, 11, 31, 7, 35, 25]
  0  3 ب   word 0 beh
  1 32 i   word 0 kasra
  2 13 س   word 0 seen
  3 25 م   word 0 meem
  4 32 i   word 0 kasra
  6 24 ل   word 1 lam geminated R133_R160_IDGHAM_KAMIL
  7 34 aa  word 1 fatha+alef_madd length [2] R134_LAM_JALALA_ALIF R180_TABEEI
  8 27 ه   word 1 heh
  9 32 i   word 1 kasra
 11 11 ر   word 2 reh geminated R133_R160_IDGHAM_KAMIL R211_REH
 12 31 a   word 2 fatha
 13  7 ح   word 2 hah
 14 25 م   word 2 meem
 15 34 aa  word 2 fatha+alef_madd length [2] R180_TABEEI
 16 26 ن   word 2 noon
 17 32 i   word 2 kasra
 19 11 ر   word 3 reh geminated R133_R160_IDGHAM_KAMIL R211_REH
 20 31 a   word 3 fatha
 21  7 ح   word 3 hah
 22 35 ii  word 3 kasra+yeh_madd length [2, 4, 6] R189_AARED
 23 25 م   word 3 meem
R133_R160_IDGHAM_KAMIL | الإدغام الكامل (اللام الشمسية والمثلان المتصلان) | complete idgham: lam shamsiyya and adjacent mithlayn | تحفة الأطفال «للام أل حالان قبل الأحرف»؛ النشر 2:18-19
R134_LAM_JALALA_ALIF | ألف لفظ الجلالة المحذوفة رسمًا | the dagger alif of the jalala | الجزرية «وفخم اللام من اسم الله عن فتح أو ضم»
R180_TABEEI | المد الطبيعي | madd tabee'i (2) | تحفة الأطفال «والمد أصلي وفرعي له»
R211_REH | أحكام الراء تفخيمًا وترقيقًا | the raa decision table | الجزرية باب الراءات «ورقق الراء إذا ما كسرت»؛ هداية القاري 1:130
R189_AARED | المد العارض للسكون | madd 'aared lil-sukun (2/4/6) | تحفة الأطفال «ومثل ذا إن عرض السكون»

python reference_example.py 2 5، آية فيها مدّ متّصل (الوحدتان 3 و35) وإدغام بغنّة (الوحدة 19). وحيث يُقتطع الناتج يظهر سطر فيه ....

أُو۟لَٰٓئِكَ عَلَىٰ هُدًى مِّن رَّبِّهِمْ وَأُو۟لَٰٓئِكَ هُمُ ٱلْمُفْلِحُونَ
ids [2, 33, 24, 34, 2, 32, 23, 31, 1, 19, 31, 24, 34, 1, 27, 33, 9, 31, 1, 25, 32, 1, 11, 31, 3, 32, 27, 32, 25, 1, 28, 31, 2, 33, 24, 34, 2, 32, 23, 31, 1, 27, 33, 25, 33, 1, 24, 25, 33, 21, 24, 32, 7, 36, 26]
  0  2 ء   word 0 hamza
  1 33 u   word 0 damma
  2 24 ل   word 0 lam
  3 34 aa  word 0 fatha+alef_madd length [4, 5] R185_MUTTASIL
  4  2 ء   word 0 hamza
  5 32 i   word 0 kasra
  6 23 ك   word 0 kaf
  7 31 a   word 0 fatha
...
 14 27 ه   word 2 heh
 15 33 u   word 2 damma
 16  9 د   word 2 dal
 17 31 a   word 2 fatha
 19 25 م   word 3 meem geminated ghunna idgham length [2] R141_IDGHAM_GHUNNA
 20 32 i   word 3 kasra
 22 11 ر   word 4 reh geminated R133_R160_IDGHAM_KAMIL R211_REH
 23 31 a   word 4 fatha
 24  3 ب   word 4 beh geminated
 25 32 i   word 4 kasra
 26 27 ه   word 4 heh
 27 32 i   word 4 kasra
 28 25 م   word 4 meem
...
 53 36 uu  word 7 damma+waw_madd length [2, 4, 6] R189_AARED
 54 26 ن   word 7 noon
R185_MUTTASIL | المد الواجب المتصل | madd muttasil (4-5) | الشاطبية باب المد؛ النشر 1:315 «فوجب أن لا يعتقد أن قصر المتصل جائز عند أحد من القراء»
R180_TABEEI | المد الطبيعي | madd tabee'i (2) | تحفة الأطفال «والمد أصلي وفرعي له»
R141_IDGHAM_GHUNNA | الإدغام بغنة الكامل (ن، م) | complete idgham with ghunna | تحفة الأطفال «في يرملون»؛ النشر 2:22
R133_R160_IDGHAM_KAMIL | الإدغام الكامل (اللام الشمسية والمثلان المتصلان) | complete idgham: lam shamsiyya and adjacent mithlayn | تحفة الأطفال «للام أل حالان قبل الأحرف»؛ النشر 2:18-19
R211_REH | أحكام الراء تفخيمًا وترقيقًا | the raa decision table | الجزرية باب الراءات «ورقق الراء إذا ما كسرت»؛ هداية القاري 1:130
R189_AARED | المد العارض للسكون | madd 'aared lil-sukun (2/4/6) | تحفة الأطفال «ومثل ذا إن عرض السكون»

الباء في رَّبِّهِمْ (الوحدة 24) مشدّدة بلا حكم: فالشدّة التي هي من رسم الكلمة نفسها ليست حكمًا. وثمة موضع واحد لا يكون فيه معرّف الحكم على الصوت هو المعرّف الذي راجعه السجلّ: حين تنتهي كلمة بنون ساكنة وتبدأ التالية بالراء أو اللام، كما في مِّن رَّبِّهِمْ (الوحدة 22)، يحمل الحرف المشدّد R133_R160_IDGHAM_KAMIL، بينما الصفّ المراجَع لهذه الآية تحت R142_IDGHAM_BILA_GHUNNA، الذي لا تحمله الأصوات إلا بعد التنوين. وهذه المواضع 338 موضعًا. والأصوات والوحدات فيها كما هو مقرَّر؛ إنما معرّف الحكم هو العامّ.

python reference_example.py 112 1، قلقلة كبرى عند الوقف (الوحدة 18):

قُلْ هُوَ ٱللَّهُ أَحَدٌ
ids [22, 33, 24, 1, 27, 33, 28, 31, 1, 24, 34, 27, 33, 1, 2, 31, 7, 31, 9]
  0 22 ق   word 0 qaf R210_ISTILA
  1 33 u   word 0 damma
  2 24 ل   word 0 lam
  4 27 ه   word 1 heh
  5 33 u   word 1 damma
  6 28 و   word 1 waw
  7 31 a   word 1 fatha
  9 24 ل   word 2 lam geminated R133_R160_IDGHAM_KAMIL R212_LAM_JALALA
 10 34 aa  word 2 fatha+alef_madd length [2] R134_LAM_JALALA_ALIF R180_TABEEI
 11 27 ه   word 2 heh
 12 33 u   word 2 damma
 14  2 ء   word 3 hamza
 15 31 a   word 3 fatha
 16  7 ح   word 3 hah
 17 31 a   word 3 fatha
 18  9 د   word 3 dal qalqalah kubra R201_QALQALAH_KUBRA
R210_ISTILA | تفخيم حروف الاستعلاء ومراتبه | isti'la tafkheem and its maraatib | المقدمة الجزرية (باب صفات الحروف)؛ النويري 1:237-238
R133_R160_IDGHAM_KAMIL | الإدغام الكامل (اللام الشمسية والمثلان المتصلان) | complete idgham: lam shamsiyya and adjacent mithlayn | تحفة الأطفال «للام أل حالان قبل الأحرف»؛ النشر 2:18-19
R212_LAM_JALALA | تفخيم لام الجلالة وترقيقها | lam al-jalala tafkheem/tarqeeq | الجزرية «وفخم اللام من اسم الله عن فتح أو ضم»
R134_LAM_JALALA_ALIF | ألف لفظ الجلالة المحذوفة رسمًا | the dagger alif of the jalala | الجزرية «وفخم اللام من اسم الله عن فتح أو ضم»
R180_TABEEI | المد الطبيعي | madd tabee'i (2) | تحفة الأطفال «والمد أصلي وفرعي له»
R201_QALQALAH_KUBRA | القلقلة الكبرى | qalqalah kubra (waqf) | الجزرية «وبينن مقلقلًا إن سكنا وإن يكن في الوقف كان أبينا»؛ هداية القاري 1:84-87

من الموضع إلى الكتاب: الحكم في كلٍّ من تلك المواضع، مع صفّه في rulings.jsonl مطبوعًا كاملًا، وصفوفه المراجَعة. python reference_example.py R185_MUTTASIL (المدّ في الوحدة 3 من 2:5):

{"rule_id": "R185_MUTTASIL", "phase": "P10", "name_ar": "المد الواجب المتصل", "name_en": "madd muttasil (4-5)", "spec": "SPEC-185", "citation": "الشاطبية باب المد؛ النشر 1:315 «فوجب أن لا يعتقد أن قصر المتصل جائز عند أحد من القراء»"}
row 44 4:43 R182_MUTTASIL | مد واجب متصل (جَآءَ) | صحيح
row 45 2:19 R182_MUTTASIL | مد متصل (ٱلسَّمَآءِ) | صحيح

python reference_example.py R141_IDGHAM_GHUNNA (الوحدة 19 من 2:5):

{"rule_id": "R141_IDGHAM_GHUNNA", "phase": "P6", "name_ar": "الإدغام بغنة الكامل (ن، م)", "name_en": "complete idgham with ghunna", "spec": "SPEC-141", "citation": "تحفة الأطفال «في يرملون»؛ النشر 2:22"}
row 115 2:61 R141_IDGHAM_GHUNNA | إدغام كامل بغنة في النون (لَن نَّصْبِرَ) | صحيح
row 116 86:6 R141_IDGHAM_GHUNNA | إدغام كامل بغنة في الميم (مِن مَّآءٍ دَافِقٍ) | صحيح
row 127 2:26 R141_IDGHAM_GHUNNA | إدغام تنوين (مَثَلًا) في ميم (مَّا) | صحيح
row 176 12:32 R141_IDGHAM_GHUNNA | نون التوكيد الخفيفة تدغم في الميم وصلًا (وَلَيَكُونًا مِّنَ ٱلصَّٰغِرِينَ)؛ والوقف عليها بالألف | صحيح

python reference_example.py R201_QALQALAH_KUBRA (الوحدة 18 من 112:1؛ والصفّ الطويل مقتطَع):

{"rule_id": "R201_QALQALAH_KUBRA", "phase": "P11", "name_ar": "القلقلة الكبرى", "name_en": "qalqalah kubra (waqf)", "spec": "SPEC-200", "citation": "الجزرية «وبينن مقلقلًا إن سكنا وإن يكن في الوقف كان أبينا»؛ هداية القاري 1:84-87"}
row 18 113:1 R201_QALQALAH_KUBRA | قلقلة كبرى وقفًا (ٱلْفَلَقِ) | صحيح
row 20 112:1 R201_QALQALAH_KUBRA | قلقلة كبرى وقفًا (أَحَدٌ ...
row 21 85:20 R201_QALQALAH_KUBRA | قلقلة كبرى وقفًا للطاء (مُّحِيطُۢ) | صحيح
row 22 22:5 R201_QALQALAH_KUBRA | قلقلة كبرى وقفًا للجيم (بَهِيجٍ) | صحيح

موضع كل حكم في البيانات

الحكم في كل صوت معرّفات الأحكام
الشدّة (التشديد) geminated: true على الحرف الصامت؛ وحدة واحدة ممسَكة (رأس gem) لا حكم خاصًا بالشدّة التي هي من رسم الكلمة؛ وإن جاءت من إدغام فحكم ذلك الإدغام (أدناه)؛ وR170_GHUNNA_MUSHADDADAH على النون أو الميم المشدّدة
الغنّة ghunna: asl أو mushaddadah أو ikhfa أو idgham؛ ومقدارها في length على الحرف الصامت R170_GHUNNA_MUSHADDADAH وR144_IKHFA وR214_IKHFA_TAFKHEEM وR143_IQLAB وR150_IKHFA_SHAFAWI وR141_IDGHAM_GHUNNA وR141_IDGHAM_GHUNNA_NAQIS؛ والإظهار: R140_IZHAR وR140_IZHAR_HALQI وR141_IZHAR_MUTLAQ
الإدغام على الحرف الذي يُدغَم فيه الأول R141_IDGHAM_GHUNNA وR141_IDGHAM_GHUNNA_NAQIS وR142_IDGHAM_BILA_GHUNNA وR133_R160_IDGHAM_KAMIL وR160_MUTAMATHILAYN
المدّ length على صوت المدّ (alef_madd وwaw_madd وyeh_madd): kind (fixed أو free) وallowed وcanonical وscoring. وهو مع حركته وحدة واحدة: aa أو ii أو uu R180_TABEEI وR181_BADAL وR185_MUTTASIL وR185_MUTTASIL_WAQF وR186_MUNFASIL وR184_SILAH_KUBRA وR187_LAZIM_MUTHAQQAL وR187_R188_LAZIM وR189_AARED وR121_MADD_EWAD وR134_LAM_JALALA_ALIF وR180_PAUSAL_GLIDE
اللين length على الواو أو الياء الساكنة R190_LEEN وR188_AIN_LEEN_LAZIM
القلقلة qalqalah: sughra أو kubra أو akbar R200_QALQALAH_SUGHRA وR201_QALQALAH_KUBRA وR202_QALQALAH_AKBAR
التفخيم tafkheem: moraqaq أو mofakham أو low_mofakham، وtafkheem_rank R210_ISTILA وR211_REH وR211_WAQF_KHILAF وR212_LAM_JALALA وR214_IKHFA_TAFKHEEM
السكت sakt_after: true على الصوت الذي يسبق السكتة R132_SAKT
الصفات sifat على كل حرف صامت، في 12 مفتاحًا: hams_or_jahr وshidda_or_rakhawa وtafkheem_or_taqeeq وitbaq وsafeer وqalqla وtikraar وtafashie وistitala وinhiraf وidhlaq وghonna لا شيء: فهي صفات الحرف نفسه

أسماء كل معرّف وإحالاته في rulings.jsonl؛ أما السجلّ كاملًا، بما فيه الأحكام التي لا يحملها أي صوت، فهو docs/RULINGS-REGISTER.md.

ما ليس هو

  • المقادير تقرير لا رصد. بنصّ البطاقة: «حيث يمنح النقلُ القارئَ اختيارًا (المنفصل، والعارض، واللين)، فالقيمة التي تتحقق فعلًا في تسجيلٍ ما قياسٌ لا تستطيع هذه الطبقة النصية أن توفّره. فلا تعامل القيم الافتراضية على أنها الحقيقة المرجعية في مواضع الاختيار.» فالمتعلّم الذي يمدّ المنفصل 4 حركات أو 5 هو ضمن allowed.
  • قراءة واحدة لكل آية. حُوِّلت الصفوف إلى أصوات على أنها مقروءة من أول الآية إلى آخرها مع الوقف هناك، وكذلك model.reference. أما الوقف داخل الآية، والرَّوم والإشمام، وقراءة آيتين دون وقف بينهما، فكلها يمكن توليدها بالمحرّك، ومجموعة البيانات لا تحملها.
  • رواية واحدة. حفص عن عاصم من طريق الشاطبية، لا غير.
  • ليس حكمًا على أحد. بنصّ البطاقة: «تقرّر مجموعة البيانات هذه ما تنصّ عليه الرواية؛ أما إجازة القرّاء فتبقى عمل السند.»

بناء الملاحظات عليه

يقارن المُقيِّم ما سمعه النموذج بما تقرّره الآية. يعطي الـ SDK الأول (رؤوس الإخراج والتوقيت والمعايرة: ابنِ ملاحظاتك بنفسك)، ويعطي model.reference الوحدات المتوقَّعة؛ ويعطي هذا المرجع لكل وحدة أصواتها وأحكامها ومصادر تلك الأحكام. استعمل المرجع لما هو متوقَّع، ومخرجات النموذج لما سُمع، وصُغ كل ما يعرضه تطبيقك على أنه قراءة تطبيقك لمخرجات النموذج، لا على أنه حكم شرعي أبدًا. ولا تكتب أبدًا نص القرآن ولا الأصوات ولا إسناد الأحكام من الذاكرة: خذها من المرجع.