wohoo properly working basic equative sentences!

This commit is contained in:
lingdocs 2021-10-18 22:08:43 -04:00
parent 0e1b776f1a
commit c7bd9e0665
4 changed files with 136 additions and 107 deletions

View File

@ -12,15 +12,13 @@ import {
import {
equativeMachine,
assembleEquativeOutput,
PredicateInput,
} from "../lib/equative-machine";
import words from "../words/words";
import { nouns, adjectives } from "../words/words";
function uniqueSort(arr: Adjective[]): Adjective[];
function uniqueSort(arr: UnisexNoun[]): UnisexNoun[];
function uniqueSort(arr: (Adjective | UnisexNoun)[]): (Adjective | UnisexNoun)[] {
return arr
.filter((v, i, a) => a.findIndex((e) => e.ts === v.ts) === i)
.filter((e) => {
try {
for (let p = 0; p < 12; p++) {
@ -36,13 +34,15 @@ function uniqueSort(arr: (Adjective | UnisexNoun)[]): (Adjective | UnisexNoun)[]
.sort((a, b) => a.p.localeCompare(b.p));
}
const unisexNouns = nouns.filter(x => isUnisexNoun(x)) as UnisexNoun[];
const inputs = {
// TODO: instead - have them unique and sorted in the words.ts file
adjectives: uniqueSort(words.adjectives),
unisexNouns: uniqueSort(words.nouns.filter(x => isUnisexNoun(x)) as UnisexNoun[]),
adjectives: uniqueSort(adjectives),
unisexNouns: unisexNouns.sort((a, b) => a.p.localeCompare(b.p)),
};
function makeBlock(e: PredicateInput): T.VerbBlock {
function makeBlock(e: Adjective | UnisexNoun): T.VerbBlock {
const makeP = (p: T.Person): T.ArrayOneOrMore<T.PsString> => {
const b = assembleEquativeOutput(equativeMachine(p, e));
return ("long" in b ? b.long : b) as T.ArrayOneOrMore<T.PsString>;
@ -62,7 +62,7 @@ type PredicateType = "adjectives" | "unisexNouns";
// TODO: Plural nouns like shoode
const defaultTs = 1527815306;
const defaultPe = inputs.adjectives.find(a => a.ts === defaultTs) || inputs.adjectives[0];
// const defaultPe = inputs.adjectives.find(a => a.ts === defaultTs) || inputs.adjectives[0];
function EquativeExplorer() {
// TODO: Use sticky state
@ -74,7 +74,6 @@ function EquativeExplorer() {
function makeOptionLabel(e: T.DictionaryEntry): string {
const eng = getEnglishWord(e);
// @ts-ignore - with dumb old typescript
const english = typeof eng === "string" ? eng : eng?.singular;
return `${e.p} - ${removeFVarients(e.f)} (${english})`;
}
@ -91,22 +90,12 @@ function EquativeExplorer() {
// setSubjectType(st);
// // setPredicate(inputs[pt][0].ts);
// }
// @ts-ignore
const pe = (inputs[predicateType].find((a: AdjectiveInput | UnisexNounInput) => (
a.ts === predicate
))) as PredicateInput;
const block = (() => {
try {
return makeBlock(pe);
} catch (e) {
console.error("error making equative");
console.error(e);
setPredicate(defaultTs);
setPredicateType("adjectives");
return makeBlock(defaultPe);
}
})();
const predicatePile = inputs[predicateType] as T.DictionaryEntry[];
const pe = predicatePile.find(p => p.ts === predicate) as UnisexNoun | Adjective;
if (!pe) return <>
ERROR!
</>
console.log("predicate in use", pe);
return <>
<div className="d-flex flex-row">
{/* <div className="form-group">
@ -183,10 +172,7 @@ function EquativeExplorer() {
</select>
</div>
</div>
{/*
// @ts-ignore */}
{pe.ts}
<VerbTable textOptions={opts} block={block} />
<VerbTable textOptions={opts} block={makeBlock(pe)} />
</>;
}

View File

@ -3,8 +3,6 @@ import {
EquativeMachineOutput,
SubjectInput,
PredicateInput,
AdjectiveInput,
UnisexNounInput,
ParticipleInput,
assembleEquativeOutput,
} from "./equative-machine";
@ -57,7 +55,7 @@ const abilities: {
{
in: {
subject: T.Person.FirstSingMale,
predicate: {"ts":1527815306,"i":7530,"p":"ستړی","f":"stúRey","g":"stuRey","e":"tired","c":"adj."} as AdjectiveInput,
predicate: {"ts":1527815306,"i":7530,"p":"ستړی","f":"stúRey","g":"stuRey","e":"tired","c":"adj."} as Adjective,
},
out: {
subject: [{ p: "زه", f: "zu", e: "I (m.)" }],
@ -68,7 +66,7 @@ const abilities: {
{
in: {
subject: T.Person.SecondPlurFemale,
predicate: {"ts":1527815306,"i":7530,"p":"ستړی","f":"stúRey","g":"stuRey","e":"tired","c":"adj."} as AdjectiveInput,
predicate: {"ts":1527815306,"i":7530,"p":"ستړی","f":"stúRey","g":"stuRey","e":"tired","c":"adj."} as Adjective,
},
out: {
subject: [{ p: "تاسو", f: "táaso", e: "You (f. pl.)" }, { p: "تاسې", f: "táase", e: "You (f. pl.)"}],
@ -80,7 +78,7 @@ const abilities: {
{
in: {
subject: T.Person.ThirdSingFemale,
predicate: {"ts":1527812798,"i":5595,"p":"خفه","f":"khufa","g":"khufa","e":"sad, upset, angry; choked, suffocated","c":"adj."} as AdjectiveInput,
predicate: {"ts":1527812798,"i":5595,"p":"خفه","f":"khufa","g":"khufa","e":"sad, upset, angry; choked, suffocated","c":"adj."} as Adjective,
},
out: {
subject: [{ p: "هغه", f: "haghá", e: "She/it (f.)" }],
@ -96,7 +94,7 @@ const abilities: {
{
in: {
subject: T.Person.FirstSingFemale,
predicate: {"ts":1591872915426,"i":696,"p":"افغانی","f":"afghaanéy","g":"afghaaney","e":"Afghan (person)","c":"n. m. unisex"} as UnisexNounInput,
predicate: {"ts":1591872915426,"i":696,"p":"افغانی","f":"afghaanéy","g":"afghaaney","e":"Afghan (person)","c":"n. m. anim. unisex"} as UnisexNoun,
},
out: {
subject: [{ p: "زه", f: "zu", e: "I (f.)" }],
@ -107,18 +105,32 @@ const abilities: {
{
in: {
subject: T.Person.FirstPlurFemale,
predicate: {"ts":1527814779,"i":935,"p":"انسان","f":"insaan","g":"insaan","e":"human, person","c":"n. m. anim. unisex"} as UnisexNounInput,
predicate: {"ts":1591872915426,"i":696,"p":"افغانی","f":"afghaanéy","g":"afghaaney","e":"Afghan (person)","c":"n. m. anim. unisex"} as UnisexNoun,
},
out: {
subject: [{ p: "مونږ", f: "moonG", e: "We (f. pl.)" }, { p: "موږ", f: "mooG", e: "We (f. pl.)" }],
predicate: [{ p: "انسانانې", f: "insaanáane", e: "(the) humans" }],
predicate: [
{ p: "افغانیانې", f: "afghaaniyáane", e: "(the) Afghans" },
{ p: "افغانۍ", f: "afghaanúy", e: "(the) Afghans" },
],
equative: [{ p: "یو", f: "yoo", e: "are" }],
},
},
{
in: {
subject: T.Person.FirstPlurFemale,
predicate: {"ts":1527814779,"i":935,"p":"انسان","f":"insaan","g":"insaan","e":"human, person","c":"n. m. anim. unisex"} as UnisexNoun,
},
out: {
subject: [{ p: "مونږ", f: "moonG", e: "We (f. pl.)" }, { p: "موږ", f: "mooG", e: "We (f. pl.)" }],
predicate: [{ p: "انسانانې", f: "insaanáane", e: "(the) humans" }, { p: "انسانې", f: "insaane", e: "(the) humans" }],
equative: [{ p: "یو", f: "yoo", e: "are" }],
},
},
{
in: {
subject: T.Person.SecondSingFemale,
predicate: {"ts":1527814779,"i":935,"p":"انسان","f":"insaan","g":"insaan","e":"human, person","c":"n. m. anim. unisex"} as UnisexNounInput,
predicate: {"ts":1527814779,"i":935,"p":"انسان","f":"insaan","g":"insaan","e":"human, person","c":"n. m. anim. unisex"} as UnisexNoun,
},
out: {
subject: [{ p: "ته", f: "tu", e: "You (f.)" }],
@ -137,7 +149,7 @@ const abilities: {
entry: { "ts":1527812817,"i":9921,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m." },
plural: false,
},
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as AdjectiveInput,
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as Adjective,
},
out: {
subject: [{ p: "کتاب", f: "kitáab", e: "(A/The) book" }],
@ -151,7 +163,7 @@ const abilities: {
entry: { "ts":1527812817,"i":9921,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m." },
plural: true,
},
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as AdjectiveInput,
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as Adjective,
},
out: {
subject: [{ p: "کتابونه", f: "kitaabóona", e: "(The) books" }],
@ -165,7 +177,7 @@ const abilities: {
entry: {"ts":1527812797,"i":8542,"p":"ښځه","f":"xúdza","g":"xudza","e":"woman, wife","c":"n. f. anim.","ec":"woman","ep":"women"},
plural: false,
},
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as AdjectiveInput,
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as Adjective,
},
out: {
subject: [{ p: "ښځه", f: "xúdza", e: "(A/The) woman" }],
@ -179,7 +191,7 @@ const abilities: {
entry: {"ts":1527812797,"i":8542,"p":"ښځه","f":"xúdza","g":"xudza","e":"woman, wife","c":"n. f. anim.","ec":"woman","ep":"women"},
plural: true,
},
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as AdjectiveInput,
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as Adjective,
},
out: {
subject: [{ p: "ښځې", f: "xúdze", e: "(The) women" }],
@ -194,7 +206,7 @@ const abilities: {
entry: {"ts":1527812797,"i":8542,"p":"ښځه","f":"xúdza","g":"xudza","e":"woman, wife","c":"n. f. anim.","ec":"woman","ep":"women"},
plural: true,
},
predicate: {"ts":1527812798,"i":5595,"p":"خفه","f":"khufa","g":"khufa","e":"sad, upset, angry; choked, suffocated","c":"adj."} as AdjectiveInput,
predicate: {"ts":1527812798,"i":5595,"p":"خفه","f":"khufa","g":"khufa","e":"sad, upset, angry; choked, suffocated","c":"adj."} as Adjective,
},
out: {
subject: [{ p: "ښځې", f: "xúdze", e: "(The) women" }],
@ -210,7 +222,7 @@ const abilities: {
{
in: {
subject: {"ts":1527812790,"i":5747,"p":"خوړل","f":"khoRul","g":"khoRul","e":"to eat, to bite","c":"v. trans.","psp":"خور","psf":"khor","tppp":"خوړ","tppf":"khoR","ec":"eat"} as ParticipleInput,
predicate: {"ts":1527812796,"i":8578,"p":"ښه","f":"xu","g":"xu","e":"good","c":"adj."} as AdjectiveInput,
predicate: {"ts":1527812796,"i":8578,"p":"ښه","f":"xu","g":"xu","e":"good","c":"adj."} as Adjective,
},
out: {
subject: [{ p: "خوړل", f: "khoRul", e: "eating" }],
@ -221,7 +233,7 @@ const abilities: {
{
in: {
subject: {"ts":1527817298,"i":310,"p":"اخیستل","f":"akheestul","g":"akheestul","e":"to take, buy, purchase, receive; to shave, cut with scissors","c":"v. trans.","psp":"اخل","psf":"akhl","ec":"take,takes,taking,took,taken"} as ParticipleInput,
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as AdjectiveInput,
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as Adjective,
},
out: {
subject: [{ p: "اخیستل", f: "akheestul", e: "taking" }],
@ -232,7 +244,7 @@ const abilities: {
{
in: {
subject: {"ts":1527816854,"i":4365,"p":"جګېدل","f":"jugedul, jigedul","g":"jugedul,jigedul","e":"to get up, be raised up","c":"v. stat. comp. intrans.","l":1527812707,"ec":"get, gets, getting, got, gotten","ep":"up"} as ParticipleInput,
predicate: {"ts":1527815246,"i":7591,"p":"سخت","f":"sakht","g":"sakht","e":"hard, difficult","c":"adj."} as AdjectiveInput,
predicate: {"ts":1527815246,"i":7591,"p":"سخت","f":"sakht","g":"sakht","e":"hard, difficult","c":"adj."} as Adjective,
},
out: {
subject: [{ p: "جګېدل", f: "jugedul", e: "getting up" }],
@ -367,11 +379,13 @@ const abilities: {
plural: true,
gender: "fem",
},
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as AdjectiveInput,
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as Adjective,
},
out: {
// TODO: should also use نرسې ?
subject: [{ p: "نرسانې", f: "narsáane", e: "(The) nurses" }],
subject: [
{ p: "نرسانې", f: "narsáane", e: "(The) nurses" },
{ p: "نرسې", f: "narse", e: "(The) nurses" },
],
predicate: [{ p: "زړې", f: "zaRe", e: "old" }],
equative: [{ p: "دي", f: "dee", e: "are" }],
},
@ -459,4 +473,17 @@ test("assembleEquativeOutput", () => {
predicate: [{ p: "زاړه", f: "zaaRu", e: "old" }],
equative: [{ p: "دي", f: "dee", e: "are" }],
})).toEqual([{ p: "کتابونه زاړه دي", f: "kitaabóona zaaRu dee", e: "(The) books are old" }]);
expect(assembleEquativeOutput({
subject: [{ p: "مونږ", f: "moonG", e: "We (f. pl.)" }, { p: "موږ", f: "mooG", e: "We (f. pl.)" }],
predicate: [
{ p: "افغانیانې", f: "afghaaniyáane", e: "(the) Afghans" },
{ p: "افغانۍ", f: "afghaanúy", e: "(the) Afghans" },
],
equative: [{ p: "یو", f: "yoo", e: "are" }],
})).toEqual([
{ p: "مونږ افغانیانې یو", f: "moonG afghaaniyáane yoo", e: "We (f. pl.) are (the) Afghans" },
{ p: "مونږ افغانۍ یو", f: "moonG afghaanúy yoo", e: "We (f. pl.) are (the) Afghans" },
{ p: "موږ افغانیانې یو", f: "mooG afghaaniyáane yoo", e: "We (f. pl.) are (the) Afghans" },
{ p: "موږ افغانۍ یو", f: "mooG afghaanúy yoo", e: "We (f. pl.) are (the) Afghans" },
]);
});

View File

@ -13,7 +13,9 @@ import {
parseEc,
concatPsString,
} from "@lingdocs/pashto-inflector";
import { SingleOrLengthOpts } from "@lingdocs/pashto-inflector/dist/types";
import {
isArrayOneOrMore,
} from "./type-predicates";
export type EquativeMachineOutput = {
subject: T.PsString[],
@ -50,17 +52,26 @@ export function equativeMachine(sub: SubjectInput, pred: PredicateInput): Equati
};
}
export function assembleEquativeOutput(o: EquativeMachineOutput): SingleOrLengthOpts<T.PsString[]> {
export function assembleEquativeOutput(o: EquativeMachineOutput): T.SingleOrLengthOpts<T.PsString[]> {
if ("long" in o.equative) {
return {
long: assembleEquativeOutput({ ...o, equative: o.equative.long }) as T.PsString[],
short: assembleEquativeOutput({ ...o, equative: o.equative.short }) as T.PsString[],
}
}
// TODO: make it use all the variations
const ps = concatPsString(o.subject[0], " ", o.predicate[0], " ", o.equative[0]);
// get all possible combinations of subject, predicate, and equative
// soooo cool how this works 🤓
const equatives = o.equative;
const predicates = o.predicate;
const ps = o.subject.flatMap(subj => (
predicates.flatMap(pred => (
equatives.map(eq => (
concatPsString(subj, " ", pred, " ", eq))
)
))
));
const e = `${o.subject[0].e} ${o.equative[0].e} ${o.predicate[0].e}`;
return [{ ...ps, e }];
return ps.map(x => ({ ...x, e }));
}
// LEVEL 2 FUNCTIONS
@ -97,6 +108,7 @@ function makeEntity(e: EntityInput, subjPerson?: T.Person): T.PsString[] {
return makeAdjective(e, subjPerson);
}
if (isUnisexNounInput(e)) {
if (subjPerson === undefined) throw new Error("unspecified unisex noun must be in the predicate");
return makeUnisexNoun(e, subjPerson);
}
if (isParticipleInput(e)) {
@ -126,41 +138,52 @@ function makePronoun(sub: T.Person): T.PsString[] {
);
}
function makeUnisexNoun(e: UnisexNoun, subjPerson: T.Person | undefined): T.PsString[] {
function makeUnisexNoun(e: UnisexNoun, subjPerson: T.Person): T.PsString[] {
// reuse english from make noun - do the a / an sensitivity
// if it's the predicate - get the inflection according to the subjPerson
if (subjPerson !== undefined) {
const inf = inflectWord(e);
const english = getEnglishFromNoun(e, personIsPlural(subjPerson), "predicate");
if (!inf) {
return [psStringFromEntry(e, english)];
}
if (!inf.inflections && (!("plural" in inf) || (!inf.inflections || !isUnisexSet(inf.inflections)))) {
throw Error("improper unisex noun");
}
// if plural // anim // chose that
// otherwise just chose inflection (or add both)
const pashto = ((): T.ArrayOneOrMore<T.PsString> => {
if ("plural" in inf && inf.plural !== undefined && personIsPlural(subjPerson)) {
const gender = personGender(subjPerson);
if (gender === "masc" && "masc" in inf.plural) {
return inf.plural.masc[0];
}
if (gender === "fem" && "fem" in inf.plural) {
return inf.plural.fem[0];
}
throw new Error("gender not available for plural");
}
if (isUnisexSet(inf.inflections)) {
return chooseInflection(inf.inflections, subjPerson);
} else {
return [psStringFromEntry(e, english)];
}
})();
return addEnglish(english, pashto);
const inf = inflectWord(e);
const english = getEnglishFromNoun(e, personIsPlural(subjPerson), "predicate");
const gender = personGender(subjPerson);
if (!inf) {
return [psStringFromEntry(e, english)];
}
// if it's the subject - TO BE IMPLEMENTED
throw new Error("unisex noun as subject not implemented yet");
// if (!inf.inflections && (!("plural" in inf) || (!inf.inflections || !isUnisexSet(inf.inflections)))) {
// throw Error("improper unisex noun");
// }
// if plural // anim // chose that
// otherwise just chose inflection (or add both)
const pashto = ((): T.ArrayOneOrMore<T.PsString> => {
const plural = personIsPlural(subjPerson);
function getPlural() {
const plural = getInf(inf, "plural", gender, true);
const arabicPlural = getInf(inf, "arabicPlural", gender, true);
const inflections = getInf(inf, "inflections", gender, true)
return [
...plural,
...arabicPlural,
// avoid useless non-inflecting masculine inflection "plural"
...(plural.length && inflections[0].p === e.p) ? [] : inflections,
];
}
const ps = plural
? getPlural()
: getInf(inf, "inflections", gender, plural);
return isArrayOneOrMore(ps)
? ps
: [psStringFromEntry(e, english)];
})();
return addEnglish(english, pashto);
}
function getInf(infs: T.InflectorOutput, t: "plural" | "arabicPlural" | "inflections", gender: T.Gender, plural: boolean): T.PsString[] {
// @ts-ignore
if (infs && t in infs && infs[t] !== undefined && gender in infs[t] && infs[t][gender] !== undefined) {
// @ts-ignore
const iset = infs[t][gender] as T.InflectionSet;
const ipick = iset[(t === "inflections" && plural) ? 1 : 0];
return ipick;
}
return [];
}
function makeNoun(n: NounInput | SpecifiedUnisexNounInput, entity: "subject" | "predicate"): T.PsString[] {
@ -171,28 +194,16 @@ function makeNoun(n: NounInput | SpecifiedUnisexNounInput, entity: "subject" | "
const gender = "gender" in n
? n.gender
: n.entry.c?.includes("n. f.") ? "fem" : "masc";
try {
if (n.plural && infs) {
if ("plural" in infs && infs.plural !== undefined) {
// ts-ignore used here because we know we can trust the gender to work
// @ts-ignore
return infs.plural[gender][0] as T.ArrayOneOrMore<T.PsString>;
}
// TODO: Add arabic plural?
if ("inflections" in infs && infs.inflections !== undefined) {
// @ts-ignore
return infs.inflections[gender][1] as T.ArrayOneOrMore<T.PsString>;
}
return [psStringFromEntry(n.entry, english)];
} else if (!n.plural && infs && "inflections" in infs && infs.inflections !== undefined) {
// @ts-ignore
return infs.inflections[gender][0] as T.ArrayOneOrMore<T.PsString>;
}
return [psStringFromEntry(n.entry, english)];
} catch(e) {
console.error(e);
throw new Error("error making noun " + n.entry.ts);
}
const ps = !n.plural
? getInf(infs, "inflections", gender, false)
: [
...getInf(infs, "plural", gender, true),
...getInf(infs, "arabicPlural", gender, true),
...getInf(infs, "inflections", gender, true),
];
return isArrayOneOrMore(ps)
? ps
: [psStringFromEntry(n.entry, english)];
})();
return addEnglish(english, pashto);
}

View File

@ -2,6 +2,7 @@ import {
pashtoConsonants,
endsWith,
countSyllables,
Types as T,
} from "@lingdocs/pashto-inflector";
export function isNoun(e: Word): e is Noun {
@ -132,3 +133,7 @@ export function isPattern6FemNoun(e: FemNoun): e is Pattern6FemNoun<FemNoun> {
if (e.c.includes("anim.")) return false;
return e.p.slice(-1) === "ي";
}
export function isArrayOneOrMore<U>(a: U[]): a is T.ArrayOneOrMore<U> {
return a.length > 0;
}