The reference: phonetics and tajweed rulings
What a recitation should be, sound by sound and rule by rule: the quran-g2p engine and the quran-tajweed-phonetics dataset, how they join to the model's expected units, and where each ruling is stated in the books.
The model hears. What a recitation should be, sound by sound and rule by rule, is Quran Lab's reference for the phonetics and tajweed rulings of the Quran, in the riwaya of Hafs 'an 'Asim via tariq al-Shatibiyyah. Every ayah is written out as phones, and every phone carries the rulings that made it what it is. It is the ground truth the model's labels and its expected units (model.reference) come from. It is public in two places: the engine, quran-g2p, and the dataset made with it, quran-tajweed-phonetics.
From a rule to the book and the page
Every phone of the dataset lists in rules the ids of the rulings that produced it, such as R185_MUTTASIL. Each id resolves in the dataset's rulings.jsonl to the ruling's name in Arabic and in English, its phase, and its classical citation as the file gives it: the book, with the volume and page or the bayt. So when your app's own judge finds, from what the model heard, that a learner did not recite a place as the reference prescribes, the app can show the learner which ruling applies there and where the scholars state it. The worked example below shows the whole chain on real data.
The citation says where the classical works state the ruling that the engine implements. It does not say that the learner erred. That judgement is your app's, made on the model's output (Build your own feedback); neither the SDK nor Quran Lab ever tells a learner that they broke a rule.
What the published files cover, counted for this page:
- The phones carry 45 distinct ids in
rules. 44 of them resolve inrulings.jsonl. The 45th,EMIT, is not a ruling: it records that the phone was read from the written text. Skip it. rulings.jsonlhas 62 rulings, each equal field by field to the engine's register. The register has 63 today: the one the file lacks,R162_NAKHLUQKUM_NAQIS(the second wajh at 77:20), was added to the engine after the dataset was last made, and no phone of the dataset carries it. The engine's README and the dataset's card still say 62; the register file says 63, and 63 is the count today.- 53 of the 62 citations give a place in the book: a volume and page, a page, or a bayt number. 9 give the work without a place:
R134_LAM_JALALA_ALIF,R180_TABEEI,R189_AAREDandR212_LAM_JALALAquote the line of the poem they cite, andR112_STRIP_INITIAL_SHADDA,R121_MADD_EWAD,R130_WASL_ELISION,R221_IMALAandR222_TASHEELname the work only. - Each ruling has reviewed rows in
register_reviewed.jsonl: an ayah that witnesses it, the ruling's wording for that ayah, and the reviewer's decision (صحيحorفيه وجهان). Those rows carry the review's own ids (the engine'sR185_MUTTASILis reviewed asR182_MUTTASIL), so the way from an engine id to its rows is the engine's register: its review column names the golden rows (tests/goldens/) that put the ruling before the reviewers, and each golden row names its ayah. All 63 rulings reach at least one reviewed row that way.
The engine and the dataset
quran-g2p is the engine: text in, tajweed-attributed phones out, in Python with no dependencies. What a developer uses in it:
src/quran_g2p/: the engine.phonemizegives the phones of an ayah, andtokenlayer_tj3turns phones into the model's tokens.docs/RULINGS-REGISTER.md: the register, generated from the engine's code. Each ruling with its id, its Arabic and English name, its sources and its review rows.artifacts/tokenizer_tj3/: the model's vocabulary,tokens.txtand its manifest.artifacts/spans/: the rulings as character offsets over all 6,236 ayat, for a project that cannot run Python.
quran-tajweed-phonetics is the dataset: 6,236 ayat and 522,475 phones, made with the engine.
| File (config) | What it holds |
|---|---|
quran_phonetics.jsonl (phonetics) |
One row per ayah: surah, ayah, text and phones. Each phone has base, kind, geminated, word_index, tafkheem, and where they apply tafkheem_rank, ghunna, qalqalah, length, sakt_after, rules, and on a consonant sifat |
rulings.jsonl (rulings) |
One row per ruling: rule_id, phase, name_ar, name_en, spec, citation |
register_reviewed.jsonl (register_reviewed) |
The 208 reviewed rows: row, surah, ayah, rule_id, ruling_ar, citation, review_verdict, reviewed_by, arbitration |
rule_index.jsonl (rule_index) |
Per ayah, each phone that carries a rule: its index i among the ayah's phones, its span (the characters of text it was read from), its rules and lengths; and events, the rulings whose effect is that a phone is not there |
quran_labels_v1.jsonl (labels), ayah_tokens.jsonl (tokens), tokens.txt, vocab_manifest.json |
Labels and token sequences in an older vocabulary of 234 tokens, not the model's 38 |
word_index counts the phonetic words of the ayah: one per written word, except in the 27 ayat whose opening letters are spelled out (R011_MUQATTAAT), where each letter's name is a word of its own.
The licence, in the card's own words: "Quran-Lab No-Profit License 1.2 (see LICENSE): free to use, adapt and redistribute, share-alike. The work itself is never for sale, so you may not charge for it, for access to it, or for a feature it powers, and the same holds for derivatives including models trained with it."
How it was verified
From the dataset's card and the engine's README. Every ruling carries its classical citation, and each citation was checked against the printed books. The rulings register the reviewers read has 208 entries. An ijazah-holding hafiz, Shaikh Sami Almadani, ruled on all 208 from his own talaqqi: 191 confirmed, 17 confirmed while documenting a second transmitted wajh, and none judged wrong. The complete register then underwent formal scholarly arbitration (تحكيم علمي) by two serving professors of Qira'at at Umm al-Qura University in Makkah, each engaged separately and blind to every other reviewer: the first confirmed the register, and none of the second's notes overturned a phonetic ruling. Over the whole corpus, the two pinned mushaf editions (Tanzil and KFGQPC) give identical phones for all 6,236 ayat; the phones agree with the mushaf's own dabt at about 8,900 tanween sites; they were checked in both directions against the quran-tajweed rule-span dataset (60,057 annotations) and word by word against the colour-coded Madinah mushaf of the King Fahd Complex (77,429 words); the card lists the differences.
The model and the reference
The 38 tokens are the engine's. model.tokens of TajweedFormer V4 is the engine's tj3 vocabulary: the tokens.txt of the 4.0.0 model is byte for byte artifacts/tokenizer_tj3/tokens.txt (SHA-256 66fe6eb81b15506270f9e3c6efb0724cda757cd54326f26ca4bcd6be4f3b2aa4). One token per sound: a long vowel is one token (the vowel and its madd letter), and a geminate consonant is one token. Madd counts, gemination, ghunna length, rawm and sakt are not tokens, and neither are tafkheem, qalqalah and the class of a ghunna: the model gives them as heads (timing_log_probs, gem, attr_tafkheem, attr_qalqalah, attr_ghunna; Build your own feedback). That is where shadda, ghunna and idgham are: heads in the model, and geminated, ghunna and the rule ids in the reference.
model.reference is made from the dataset. Quran Lab's release pipeline renders each row of quran_phonetics.jsonl with the engine's tokenlayer_tj3.phones_to_tj3_units: the units of the ayah read from its start to its end with a stop, with the word boundary | between words, and the word of each unit. Checked for this page on all 6,236 ayat: the table that ships with 4.0.0 equals what quran-g2p at its current public commit (7eeba12) produces, and the dataset's phones equal the engine's.
The join. phones_to_tj3_units([[p] for p in row["phones"]]) returns the ayah's units and, for each phone, the index of the unit it became. Those units are exactly the ones model.reference gives for the ayah, so unit i of the reference is made of the phones whose index is i: a long vowel is its vowel and its madd letter, and every other unit is one phone. The table the SDK ships holds unit ids and words only. The phones, their marks and their rules come from the dataset through this join. For the letters, rule_index.jsonl gives each phone that carries a rule the characters of text it was read from (span), and the engine gives every phone the same (src_span).
A worked example
Clone the engine and put three files of the dataset beside it: quran_phonetics.jsonl (about 150 MB), rulings.jsonl and register_reviewed.jsonl.
git clone https://github.com/Quran-Lab/quran-g2pSave this as reference_example.py in the same folder:
# 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, Al-Fatihah 1:1. A line reads: the unit's index in model.reference for the ayah, its id in model.tokens, the token, its word, the phones it was made from with their marks, and their rule ids. The indexes the list skips (5, 10, 18) are the word boundaries. The last lines name each ruling from rulings.jsonl, with its citation exactly as the file has it.
بِسْمِ ٱللَّهِ ٱلرَّحْمَٰنِ ٱلرَّحِيمِ
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, an ayah with a muttasil madd (units 3 and 35) and an idgham with ghunna (unit 19). Where the output is cut, a line shows ....
أُو۟لَٰٓئِكَ عَلَىٰ هُدًى مِّن رَّبِّهِمْ وَأُو۟لَٰٓئِكَ هُمُ ٱلْمُفْلِحُونَ
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) | تحفة الأطفال «ومثل ذا إن عرض السكون»The ب of رَّبِّهِمْ (unit 24) is geminated with no rule: a shadda of the word's own spelling is not a ruling. One place where the rule id on a phone is not the one the register reviews: where a noon sakinah ends a word and ر or ل begins the next, as in مِّن رَّبِّهِمْ (unit 22), the geminated letter carries R133_R160_IDGHAM_KAMIL, while the reviewed row for this ayah is under R142_IDGHAM_BILA_GHUNNA, which the phones carry only after a tanween. There are 338 such places. The phones and the units there are as prescribed; only the rule id is the general one.
python reference_example.py 112 1, a qalqalah kubra at the stop (unit 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-87From a place to the book: the ruling at each of those places, with its row of rulings.jsonl printed whole and its reviewed rows. python reference_example.py R185_MUTTASIL (the madd at unit 3 of 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 (unit 19 of 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 (unit 18 of 112:1; the long row is cut):
{"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 | قلقلة كبرى وقفًا للجيم (بَهِيجٍ) | صحيحWhere each rule is in the data
| What | In each phone | Rule ids |
|---|---|---|
| Shadda (gemination) | geminated: true on the consonant; one unit, held (the gem head) |
None of its own for a shadda of the word's spelling; from an idgham, that idgham's rule (below); R170_GHUNNA_MUSHADDADAH on a geminate noon or meem |
| Ghunna | ghunna: asl, mushaddadah, ikhfa or idgham; its length in length on the consonant |
R170_GHUNNA_MUSHADDADAH, R144_IKHFA, R214_IKHFA_TAFKHEEM, R143_IQLAB, R150_IKHFA_SHAFAWI, R141_IDGHAM_GHUNNA, R141_IDGHAM_GHUNNA_NAQIS; izhar: R140_IZHAR, R140_IZHAR_HALQI, R141_IZHAR_MUTLAQ |
| Idgham | On the letter the first one merges into | R141_IDGHAM_GHUNNA, R141_IDGHAM_GHUNNA_NAQIS, R142_IDGHAM_BILA_GHUNNA, R133_R160_IDGHAM_KAMIL, R160_MUTAMATHILAYN |
| Madd | length on the madd phone (alef_madd, waw_madd, yeh_madd): kind (fixed or free), allowed, canonical, scoring. With its vowel it is one unit, aa, ii or 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 |
| Leen | length on the waw or yeh consonant |
R190_LEEN, R188_AIN_LEEN_LAZIM |
| Qalqalah | qalqalah: sughra, kubra or akbar |
R200_QALQALAH_SUGHRA, R201_QALQALAH_KUBRA, R202_QALQALAH_AKBAR |
| Tafkheem | tafkheem: moraqaq, mofakham or low_mofakham, and tafkheem_rank |
R210_ISTILA, R211_REH, R211_WAQF_KHILAF, R212_LAM_JALALA, R214_IKHFA_TAFKHEEM |
| Sakt | sakt_after: true on the phone before the pause |
R132_SAKT |
| Sifat | sifat on every consonant, in 12 keys: hams_or_jahr, shidda_or_rakhawa, tafkheem_or_taqeeq, itbaq, safeer, qalqla, tikraar, tafashie, istitala, inhiraf, idhlaq, ghonna |
None: they belong to the letter |
The names and citations of every id are in rulings.jsonl; the whole register, with the rulings that no phone carries, is docs/RULINGS-REGISTER.md.
What it is not
- Lengths are prescriptions, not observations. In the card's words: "Where the tradition gives the reciter a choice (munfasil, 'aared, leen), the value actually realized in a recording is a measurement this text layer cannot supply. Do not treat canonical values as ground truth at free-choice positions." A learner who recites a munfasil at 4 or at 5 is within
allowed. - One reading of each ayah. The rows are phonemized as read from the start of the ayah to its end, with a stop there, and so is
model.reference. A stop inside the ayah, rawm and ishmam, and two ayat read without a stop between them can all be generated with the engine; the dataset does not hold them. - One riwaya. Hafs 'an 'Asim via tariq al-Shatibiyyah, and no other.
- Not a judgement of anyone. In the card's words: "This dataset states the prescription of the riwaya; certifying reciters remains the sanad's work."
Building feedback with it
A judge compares what the model heard with what the ayah prescribes. The SDK gives the first (the heads, the timing, the calibration: Build your own feedback) and model.reference the expected units; this reference gives, for each unit, its phones, its rules and their sources. Use the reference for what is expected and the model's output for what was heard, and phrase whatever your app shows as your app's reading of the model, never as a ruling. Never write Quran text, phones or rule assignments from memory: take them from the reference.