ACE Grammar Engine
Master arrays and analyzer test data.
<?php
/**
* Split a UTF-8 string into Unicode characters.
*
* @return list<string>
*/
//function ace_chars
/**
* ------------------------------------------------------------
* Extract structural positions from the marked stem.
* ------------------------------------------------------------
*
* Input:
* تَسْتَقْبِلَ
*
* Output:
* [
* 'vn' => '',
* 'vm' => '',
* 'fs' => '',
* 'r0' => '',
* 'v1' => '',
* 'r1' => '',
* 'v2' => '',
* 'r2' => '',
* 'r1_repeat' => false,
* 'r2_repeat' => false,
* 'r0_marks' => '',
* 'r1_marks' => '',
* 'r2_marks' => '',
* 'clusters' => [],
* ]
*/
/**
* Normalize a radical for root reporting and database comparison.
*/
$master_suffixes = [
/*
* --------------------------------------------------------
* Six-unit suffixes.
* --------------------------------------------------------
*/
[
'suffix' => 'ْتُمَا',
'families' => ['perfect'],
'persons' => ['2md', '2fd'],
'moods' => [],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'ْتُمْ',
'families' => ['perfect'],
'persons' => ['2mp'],
'moods' => [],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'ْتُنَّ',
'families' => ['perfect'],
'persons' => ['2fp'],
'moods' => [],
'declensions' => [],
'pos' => ['verb'],
],
/*
* --------------------------------------------------------
* Five-unit suffixes.
* --------------------------------------------------------
*/
[
'suffix' => 'ُونَ',
'families' => ['imperfect'],
'persons' => ['3mp', '2mp'],
'moods' => ['indicative'],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'ِينَ',
'families' => ['imperfect'],
'persons' => ['2fs'],
'moods' => ['indicative'],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'َانِ',
'families' => ['imperfect'],
'persons' => ['3md', '2md'],
'moods' => ['indicative'],
'declensions' => [],
'pos' => ['verb'],
],
/*
* --------------------------------------------------------
* Four-unit suffixes.
* --------------------------------------------------------
*/
[
'suffix' => 'َتَا',
'families' => ['perfect'],
'persons' => ['3fd'],
'moods' => [],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'ةُ',
'families' => ['declension'],
'persons' => [],
'moods' => [],
'declensions' => ['nominative'],
'pos' => ['noun'],
],
[
'suffix' => 'ةً',
'families' => ['declension'],
'persons' => [],
'moods' => [],
'declensions' => ['accusative'],
'pos' => ['noun'],
],
[
'suffix' => 'ةٍ',
'families' => ['declension'],
'persons' => [],
'moods' => [],
'declensions' => ['genitive'],
'pos' => ['noun'],
],
/*
* --------------------------------------------------------
* Three-unit suffixes.
* --------------------------------------------------------
*/
[
'suffix' => 'ْتَ',
'families' => ['perfect'],
'persons' => ['2ms'],
'moods' => [],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'ْتِ',
'families' => ['perfect'],
'persons' => ['2fs'],
'moods' => [],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'ْتُ',
'families' => ['perfect'],
'persons' => ['1s'],
'moods' => [],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'ْنَا',
'families' => ['perfect'],
'persons' => ['1p'],
'moods' => [],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'ْنَ',
'families' => ['perfect'],
'persons' => ['3fp'],
'moods' => [],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'َتْ',
'families' => ['perfect'],
'persons' => ['3fs'],
'moods' => [],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'ُوا',
'families' => ['subjunctive', 'jussive', 'imperative'],
'persons' => ['3mp', '2mp'],
'moods' => ['subjunctive', 'jussive', 'imperative'],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'نَّ',
'families' => ['heavy_emphatic'],
'persons' => ['3ms','3fs','2ms','2mp','2fs','1s','1p'],
'moods' => ['heavy_emphatic'],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'نْ',
'families' => ['light_emphatic'],
'persons' => ['3ms','3fs','2ms','2mp','2fs','1s','1p'],
'moods' => ['light_emphatic'],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'ٌ',
'families' => ['declension'],
'persons' => [],
'moods' => [],
'declensions' => ['nominative'],
'pos' => ['noun'],
],
[
'suffix' => 'ًا',
'families' => ['declension'],
'persons' => [],
'moods' => [],
'declensions' => ['accusative'],
'pos' => ['noun'],
],
[
'suffix' => 'ٍ',
'families' => ['declension'],
'persons' => [],
'moods' => [],
'declensions' => ['genitive'],
'pos' => ['noun'],
],
/*
* --------------------------------------------------------
* Two-unit suffixes.
* --------------------------------------------------------
*/
[
'suffix' => 'ا',
'families' => ['perfect'],
'persons' => ['3md'],
'moods' => [],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'ا',
'families' => ['subjunctive'],
'persons' => ['3md', '2md'],
'moods' => ['subjunctive'],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'ي',
'families' => ['subjunctive', 'imperative'],
'persons' => ['2fs'],
'moods' => ['subjunctive', 'imperative'],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'وا',
'families' => ['perfect'],
'persons' => ['3mp'],
'moods' => [],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'ينِ',
'families' => ['declension'],
'persons' => [],
'moods' => [],
'declensions' => ['accusative', 'genitive', 'dual'],
'pos' => ['noun'],
],
/*
* --------------------------------------------------------
* One-unit suffixes.
* --------------------------------------------------------
*/
[
'suffix' => 'ُ',
'families' => ['imperfect'],
'persons' => ['3ms','3fs','2ms','1s'],
'moods' => ['indicative'],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'َ',
'families' => ['subjunctive', 'imperative'],
'persons' => ['3ms','3fs','2ms','1s'],
'moods' => ['subjunctive', 'imperative'],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => 'ْ',
'families' => ['jussive', 'imperative'],
'persons' => ['3ms','3fs','2ms','1s'],
'moods' => ['jussive', 'imperative'],
'declensions' => [],
'pos' => ['verb'],
],
[
'suffix' => '',
'families' => [],
'persons' => [],
'moods' => [],
'declensions' => [],
'pos' => [],
],
];
$master_pronouns = [
/*
* --------------------------------------------------------
* Third Person
* --------------------------------------------------------
*/
[
'id' => 1,
'person' => '3ms',
'english' => 'he',
'arabic' => 'هُوَ',
],
[
'id' => 2,
'person' => '3md',
'english' => 'they two (m)',
'arabic' => 'هُمَا',
],
[
'id' => 3,
'person' => '3mp',
'english' => 'they (m)',
'arabic' => 'هُمْ',
],
[
'id' => 4,
'person' => '3fs',
'english' => 'she',
'arabic' => 'هِيَ',
],
[
'id' => 5,
'person' => '3fd',
'english' => 'they two (f)',
'arabic' => 'هُمَا',
],
[
'id' => 6,
'person' => '3fp',
'english' => 'they (f)',
'arabic' => 'هُنَّ',
],
/*
* --------------------------------------------------------
* Second Person
* --------------------------------------------------------
*/
[
'id' => 7,
'person' => '2ms',
'english' => 'you (m)',
'arabic' => 'أَنْتَ',
],
[
'id' => 8,
'person' => '2md',
'english' => 'you two (m)',
'arabic' => 'أَنْتُمَا',
],
[
'id' => 9,
'person' => '2mp',
'english' => 'you (m plural)',
'arabic' => 'أَنْتُمْ',
],
[
'id' => 10,
'person' => '2fs',
'english' => 'you (f)',
'arabic' => 'أَنْتِ',
],
[
'id' => 11,
'person' => '2fd',
'english' => 'you two (f)',
'arabic' => 'أَنْتُمَا',
],
[
'id' => 12,
'person' => '2fp',
'english' => 'you (f plural)',
'arabic' => 'أَنْتُنَّ',
],
/*
* --------------------------------------------------------
* First Person
* --------------------------------------------------------
*/
[
'id' => 13,
'person' => '1s',
'english' => 'I',
'arabic' => 'أَنَا',
],
[
'id' => 14,
'person' => '1p',
'english' => 'we',
'arabic' => 'نَحْنُ',
],
];
/*
* --------------------------------------------------------
* Master prefixes
* (longest first)
* --------------------------------------------------------
*
* NOTE
* ----
* These are used only for reference and optional analysis.
* They are NOT removed from the token before dissection.
*
* Fields
* ------
* prefix
* length
* family
* tense
* voice
*/
$master_prefixes = [
/*
* ========================================================
* FORM X
* ========================================================
*
* The prefix is evidence for Form X.
* Mood is normally refined by the suffix.
*/
/*
* Perfect active:
* اِسْتَفْعَلَ
*/
[
'prefix' => 'اِسْتَ',
'length' => 5,
'forms' => [10],
'family' => 'form10',
'tense' => ['perfect'],
'voice' => ['active'],
'moods' => ['perfect', 'imperative'],
],
/*
* Perfect passive:
* اُسْتُفْعِلَ
*/
[
'prefix' => 'اُسْتُ',
'length' => 5,
'forms' => [10],
'family' => 'form10',
'tense' => ['perfect'],
'voice' => ['passive'],
'moods' => ['perfect'],
],
/*
* Imperative:
* اِسْتَفْعِلْ
*
* It has the same opening as the perfect active.
* The suffix and internal vowels must distinguish them.
*/
[
'prefix' => 'اِسْتَ',
'length' => 5,
'forms' => [10],
'family' => 'form10',
'tense' => ['imperative'],
'voice' => ['active'],
'moods' => ['imperative'],
],
/*
* Declension-related Form X sequence requested by the
* project rules:
* اِسْتِـ
*/
[
'prefix' => 'اِسْتِ',
'length' => 5,
'forms' => [10],
'family' => 'form10',
'tense' => ['declension'],
'voice' => ['active'],
'moods' => ['declension'],
],
/*
* --------------------------------------------------------
* Form X imperfect active
* --------------------------------------------------------
*/
[
'prefix' => 'يَسْتَ',
'length' => 5,
'forms' => [10],
'family' => 'form10',
'tense' => ['imperfect'],
'voice' => ['active'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
[
'prefix' => 'تَسْتَ',
'length' => 5,
'forms' => [10],
'family' => 'form10',
'tense' => ['imperfect'],
'voice' => ['active'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
[
'prefix' => 'أَسْتَ',
'length' => 5,
'forms' => [10],
'family' => 'form10',
'tense' => ['imperfect'],
'voice' => ['active'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
[
'prefix' => 'نَسْتَ',
'length' => 5,
'forms' => [10],
'family' => 'form10',
'tense' => ['imperfect'],
'voice' => ['active'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
/*
* --------------------------------------------------------
* Form X imperfect passive
* --------------------------------------------------------
*/
[
'prefix' => 'يُسْتَ',
'length' => 5,
'forms' => [10],
'family' => 'form10',
'tense' => ['imperfect'],
'voice' => ['passive'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
[
'prefix' => 'تُسْتَ',
'length' => 5,
'forms' => [10],
'family' => 'form10',
'tense' => ['imperfect'],
'voice' => ['passive'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
[
'prefix' => 'أُسْتَ',
'length' => 5,
'forms' => [10],
'family' => 'form10',
'tense' => ['imperfect'],
'voice' => ['passive'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
[
'prefix' => 'نُسْتَ',
'length' => 5,
'forms' => [10],
'family' => 'form10',
'tense' => ['imperfect'],
'voice' => ['passive'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
/*
* ========================================================
* FORM VII
* ========================================================
*/
/*
* Perfect and imperative opening:
* اِنْـ
*/
[
'prefix' => 'اِنْ',
'length' => 3,
'forms' => [7],
'family' => 'form7',
'tense' => [
'perfect',
'imperative',
],
'voice' => ['active'],
'moods' => [
'perfect',
'imperative',
],
],
/*
* Imperfect active Form VII:
* يَنْـ / تَنْـ / أَنْـ / نَنْـ
*/
[
'prefix' => 'يَنْ',
'length' => 3,
'forms' => [7],
'family' => 'form7',
'tense' => ['imperfect'],
'voice' => ['active'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
[
'prefix' => 'تَنْ',
'length' => 3,
'forms' => [7],
'family' => 'form7',
'tense' => ['imperfect'],
'voice' => ['active'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
[
'prefix' => 'أَنْ',
'length' => 3,
'forms' => [7],
'family' => 'form7',
'tense' => ['imperfect'],
'voice' => ['active'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
[
'prefix' => 'نَنْ',
'length' => 3,
'forms' => [7],
'family' => 'form7',
'tense' => ['imperfect'],
'voice' => ['active'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
/*
* ========================================================
* FORMS VIII AND IX
* ========================================================
*
* اِ alone does not distinguish Form VIII from Form IX.
* Internal structure must refine the result:
*
* Form VIII: infixed ت or an assimilated replacement.
* Form IX: final radical duplication/shadda.
*/
[
'prefix' => 'اِ',
'length' => 2,
'forms' => [8, 9],
'family' => 'form8_9',
'tense' => [
'perfect',
'imperative',
],
'voice' => ['active'],
'moods' => [
'perfect',
'imperative',
],
],
[
'prefix' => 'اُ',
'length' => 2,
'forms' => [8],
'family' => 'form8',
'tense' => ['perfect'],
'voice' => ['passive'],
'moods' => ['perfect'],
],
/*
* ========================================================
* FORM IV
* ========================================================
*/
[
'prefix' => 'أَ',
'length' => 2,
'forms' => [4],
'family' => 'form4',
'tense' => [
'perfect',
'imperative',
],
'voice' => ['active'],
'moods' => [
'perfect',
'imperative',
],
],
[
'prefix' => 'أُ',
'length' => 2,
'forms' => [4],
'family' => 'form4',
'tense' => ['perfect'],
'voice' => ['passive'],
'moods' => ['perfect'],
],
/*
* ========================================================
* FORMS V AND VI
* ========================================================
*
* تَ alone gives a Form V/VI candidate.
* Internal shadda or long alif distinguishes them.
*/
[
'prefix' => 'تَ',
'length' => 2,
'forms' => [5, 6],
'family' => 'form5_6',
'tense' => ['perfect'],
'voice' => ['active'],
'moods' => ['perfect'],
],
[
'prefix' => 'تُ',
'length' => 2,
'forms' => [5, 6],
'family' => 'form5_6',
'tense' => ['perfect'],
'voice' => ['passive'],
'moods' => ['perfect'],
],
/*
* ========================================================
* GENERAL IMPERFECT PREFIXES
* ========================================================
*
* These are deliberately placed after the longer,
* form-specific prefixes.
*/
[
'prefix' => 'يَ',
'length' => 2,
'forms' => [1, 5, 6, 7, 8, 9, 10],
'family' => 'imperfect',
'tense' => ['imperfect'],
'voice' => ['active'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
[
'prefix' => 'تَ',
'length' => 2,
'forms' => [1, 5, 6, 7, 8, 9, 10],
'family' => 'imperfect',
'tense' => ['imperfect'],
'voice' => ['active'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
[
'prefix' => 'أَ',
'length' => 2,
'forms' => [1, 5, 6, 7, 8, 9, 10],
'family' => 'imperfect',
'tense' => ['imperfect'],
'voice' => ['active'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
[
'prefix' => 'نَ',
'length' => 2,
'forms' => [1, 5, 6, 7, 8, 9, 10],
'family' => 'imperfect',
'tense' => ['imperfect'],
'voice' => ['active'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
[
'prefix' => 'يُ',
'length' => 2,
'forms' => [1, 2, 3, 4, 5, 6, 8, 10],
'family' => 'imperfect',
'tense' => ['imperfect'],
'voice' => ['passive'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
[
'prefix' => 'تُ',
'length' => 2,
'forms' => [1, 2, 3, 4, 5, 6, 8, 10],
'family' => 'imperfect',
'tense' => ['imperfect'],
'voice' => ['passive'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
[
'prefix' => 'أُ',
'length' => 2,
'forms' => [1, 2, 3, 4, 5, 6, 8, 10],
'family' => 'imperfect',
'tense' => ['imperfect'],
'voice' => ['passive'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
[
'prefix' => 'نُ',
'length' => 2,
'forms' => [1, 2, 3, 4, 5, 6, 8, 10],
'family' => 'imperfect',
'tense' => ['imperfect'],
'voice' => ['passive'],
'moods' => [
'indicative',
'subjunctive',
'jussive',
],
],
/*
* ========================================================
* ZERO PREFIX
* ========================================================
*/
[
'prefix' => '',
'length' => 0,
'forms' => [],
'family' => '',
'tense' => [],
'voice' => [],
'moods' => [],
],
];
$master_suffix_moods = [
'ا' => [
'perfect',
'subjunctive',
'jussive',
'imperative',
],
'َ' => [
'perfect',
'subjunctive',
'declension',
],
'ُ' => [
'indicative',
'declension',
],
'ِ' => [
'declension',
],
'نَا' => [
'perfect',
'indicative',
'subjunctive',
'jussive',
'imperative',
],
'ً' => [
'declension',
'light_emphatic',
],
'ٌ' => [
'declension',
'light_emphatic',
],
'ٍ' => [
'declension',
'light_emphatic',
],
'ْ' => [
'jussive',
'imperative',
],
];