basic start on the equative machine

This commit is contained in:
lingdocs 2021-10-09 11:47:03 -04:00
parent 1911e3c1af
commit 4aa3568c72
3 changed files with 524 additions and 151 deletions

View File

@ -1,30 +1,63 @@
import {
equativeMachine,
EquativeMachineOutput,
EquativeNounInput,
SubjectInput,
PredicateInput,
AdjectiveInput,
UnisexNounInput,
ParticipleInput,
assembleEquativeOutput,
} from "./equative-machine";
import {
Types as T,
} from "@lingdocs/pashto-inflector";
// INPUTS
// Person (pronoun) - subject only
// Noun - subject/predicate
// Unisex Noun - subject/predicate
// Adjective - predicate only
// Participle - subject/predicate
// COMBINATIONS
// Subject | Predicate
// ---------------------------
// Person | Noun
// Person | Unisex Noun ✔
// Person | Adjective ✔
// Person | Participle ✔
// Noun | Noun ✔
// Noun | Adjective ✔
// Noun | Participle ✔
// Noun | Specified Unisex Noun ✔
// Specified Unisex Noun | Noun ✔
// Specified Unisex Noun | Adjective ✔
// Specified Unisex Noun | Participle ✔
// Participle | Noun ✔
// Participle | Adjective ✔
// Participle | Participle ✔
// Participle | Specified Unisex noun ✔
// TODO: allow unisex subject inputs male or female!
const abilities: {
label: string,
tests: {
in: {
subject: T.Person | EquativeNounInput | T.DictionaryEntry,
predicate: T.DictionaryEntry,
subject: SubjectInput,
predicate: PredicateInput,
},
out: EquativeMachineOutput,
}[],
}[] = [
{
label: "handle person subjects with adjective predicates",
label: "SUBJECT: Person PREDICATE: Adjective",
tests: [
// -- inflecting adjectives
{
in: {
subject: T.Person.FirstSingMale,
predicate: {"ts":1527815306,"i":7530,"p":"ستړی","f":"stúRey","g":"stuRey","e":"tired","c":"adj."},
predicate: {"ts":1527815306,"i":7530,"p":"ستړی","f":"stúRey","g":"stuRey","e":"tired","c":"adj."} as AdjectiveInput,
},
out: {
subject: [{ p: "زه", f: "zu", e: "I (m.)" }],
@ -35,7 +68,7 @@ const abilities: {
{
in: {
subject: T.Person.SecondPlurFemale,
predicate: {"ts":1527815306,"i":7530,"p":"ستړی","f":"stúRey","g":"stuRey","e":"tired","c":"adj."},
predicate: {"ts":1527815306,"i":7530,"p":"ستړی","f":"stúRey","g":"stuRey","e":"tired","c":"adj."} as AdjectiveInput,
},
out: {
subject: [{ p: "تاسو", f: "táaso", e: "You (f. pl.)" }, { p: "تاسې", f: "táase", e: "You (f. pl.)"}],
@ -47,7 +80,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."},
predicate: {"ts":1527812798,"i":5595,"p":"خفه","f":"khufa","g":"khufa","e":"sad, upset, angry; choked, suffocated","c":"adj."} as AdjectiveInput,
},
out: {
subject: [{ p: "هغه", f: "haghá", e: "She/it (f.)" }],
@ -58,45 +91,45 @@ const abilities: {
],
},
{
label: "handle person subjects with unisex noun predicate",
label: "SUBJECT: Person PREDICATE: Unisex Noun",
tests: [
{
in: {
subject: T.Person.FirstSingFemale,
predicate: {"ts":1591872915426,"i":696,"p":"افغانی","f":"afghaanéy","g":"afghaaney","e":"Afghan (person)","c":"n. m. unisex"},
predicate: {"ts":1591872915426,"i":696,"p":"افغانی","f":"afghaanéy","g":"afghaaney","e":"Afghan (person)","c":"n. m. unisex"} as UnisexNounInput,
},
out: {
subject: [{ p: "زه", f: "zu", e: "I (f.)" }],
predicate: [{ p: "افغانۍ", f: "afghaanúy", e: "Afghan" }],
predicate: [{ p: "افغانۍ", f: "afghaanúy", e: "(a/the) Afghan" }],
equative: [{ p: "یم", f: "yum", e: "am" }],
}
},
{
in: {
subject: T.Person.FirstPlurFemale,
predicate: {"ts":1527814779,"i":935,"p":"انسان","f":"insaan","g":"insaan","e":"human, person","c":"n. m. anim. unisex"},
predicate: {"ts":1527814779,"i":935,"p":"انسان","f":"insaan","g":"insaan","e":"human, person","c":"n. m. anim. unisex"} as UnisexNounInput,
},
out: {
subject: [{ p: "مونږ", f: "moonG", e: "We (f. pl.)" }, { p: "موږ", f: "mooG", e: "We (f. pl.)" }],
predicate: [{ p: "انسانانې", f: "insaanáane", e: "humans" }],
predicate: [{ p: "انسانانې", f: "insaanáane", 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"},
predicate: {"ts":1527814779,"i":935,"p":"انسان","f":"insaan","g":"insaan","e":"human, person","c":"n. m. anim. unisex"} as UnisexNounInput,
},
out: {
subject: [{ p: "ته", f: "tu", e: "You (f.)" }],
predicate: [{ p: "انسانه", f: "insaana", e: "human" }],
predicate: [{ p: "انسانه", f: "insaana", e: "(a/the) human" }],
equative: [{ p: "یې", f: "ye", e: "are" }],
},
},
],
},
{
label: "Handle noun subjects with adjective predicates",
label: "SUBJECT: Noun PREDICATE: Adjective",
tests: [
{
in: {
@ -104,7 +137,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"},
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as AdjectiveInput,
},
out: {
subject: [{ p: "کتاب", f: "kitáab", e: "(A/The) book" }],
@ -118,7 +151,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"},
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as AdjectiveInput,
},
out: {
subject: [{ p: "کتابونه", f: "kitaabóona", e: "(The) books" }],
@ -132,7 +165,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"},
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as AdjectiveInput,
},
out: {
subject: [{ p: "ښځه", f: "xúdza", e: "(A/The) woman" }],
@ -146,7 +179,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"},
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as AdjectiveInput,
},
out: {
subject: [{ p: "ښځې", f: "xúdze", e: "(The) women" }],
@ -161,7 +194,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."},
predicate: {"ts":1527812798,"i":5595,"p":"خفه","f":"khufa","g":"khufa","e":"sad, upset, angry; choked, suffocated","c":"adj."} as AdjectiveInput,
},
out: {
subject: [{ p: "ښځې", f: "xúdze", e: "(The) women" }],
@ -172,12 +205,12 @@ const abilities: {
],
},
{
label: "handle participle subjects with adjective predicates",
label: "SUBJECT: Participle PREDICATE: Adjective",
tests: [
{
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"},
predicate: {"ts":1527812796,"i":8578,"p":"ښه","f":"xu","g":"xu","e":"good","c":"adj."},
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,
},
out: {
subject: [{ p: "خوړل", f: "khoRul", e: "eating" }],
@ -187,15 +220,225 @@ 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"},
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"},
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,
},
out: {
subject: [{ p: "اخیستل", f: "akheestul", e: "taking" }],
predicate: [{ p: "زاړه", f: "zaaRu", e: "old" }],
equative: [{ p: "دي", f: "dee", e: "is" }],
},
}
},
{
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,
},
out: {
subject: [{ p: "جګېدل", f: "jugedul", e: "getting up" }],
predicate: [{ p: "سخت", f: "sakht", e: "hard" }],
equative: [{ p: "دي", f: "dee", e: "is" }],
},
},
],
},
{
label: "SUBJECT: Person PREDICATE: Participle",
tests: [
{
in: {
subject: T.Person.SecondSingMale,
predicate: {"ts":1527812856,"i":11521,"p":"لیکل","f":"leekul","g":"leekul","e":"to write","c":"v. trans.","ec":"write,writes,writing,wrote,wrote"} as ParticipleInput,
},
out: {
subject: [{ p: "ته", f: "tu", e: "You (m.)" }],
predicate: [{ p: "لیکل", f: "leekul", e: "writing" }],
equative: [{ p: "دي", f: "dee", e: "are" }],
}
},
],
},
{
label: "SUBJECT: Noun PREDICATE: Noun",
tests: [
{
in: {
subject: {
entry: {"ts":1527813477,"i":5790,"p":"خوشحالي","f":"khosh`haalee","g":"khoshhaalee","e":"happiness, joy","c":"n. f."},
plural: false,
},
predicate: {
entry: {"ts":1527812788,"i":5729,"p":"خوراک","f":"khoráak, khwaráak","g":"khoraak,khwaraak","e":"food","c":"n. m."},
plural: false,
},
},
out: {
subject: [{ p: "خوشحالي", f: "khosh`haalee", e: "(A/The) happiness" }],
predicate: [{ p: "خوراک", f: "khoráak", e: "(a/the) food" }],
equative: [{ p: "دی", f: "dey", e: "is" }],
},
},
],
},
{
label: "SUBJECT: Noun PREDICATE: Participle",
tests: [
{
in: {
subject: {
entry: {"ts":1527822878,"i":14157,"p":"وروروالی","f":"wrorwaaley","g":"wrorwaaley","e":"brotherhood, comradery, tight and good friendship","c":"n. m."},
plural: false,
},
predicate: {"ts":1527816064,"i":7097,"p":"زغمل","f":"zghamul","g":"zghamul","e":"to endure, bear, tolerate, take on, digest","c":"v. trans.","tppp":"زغامه","tppf":"zghaamu","ec":"endure"} as ParticipleInput,
},
out: {
subject: [{ p: "وروروالی", f: "wrorwaaley", e: "(A/The) brotherhood" }],
predicate: [{ p: "زغمل", f: "zghamul", e: "enduring" }],
equative: [{ p: "دي", f: "dee", e: "is" }],
},
},
],
},
{
label: "SUBJECT: Participle PREDICATE: Noun",
tests: [
{
in: {
subject: {"ts":1527812856,"i":11521,"p":"لیکل","f":"leekul","g":"leekul","e":"to write","c":"v. trans.","ec":"write,writes,writing,wrote,wrote"} as ParticipleInput,
predicate: {
entry: {"ts":1527813477,"i":5790,"p":"خوشحالي","f":"khosh`haalee","g":"khoshhaalee","e":"happiness, joy","c":"n. f."},
plural: false,
},
},
out: {
subject: [{ p: "لیکل", f: "leekul", e: "writing" }],
predicate: [{ p: "خوشحالي", f: "khosh`haalee", e: "(a/the) happiness" }],
equative: [{ p: "ده", f: "da", e: "is" }],
},
},
],
},
{
label: "SUBJECT: Participle PREDICATE: Participle",
tests: [
{
in: {
subject: {"ts":1527812856,"i":11521,"p":"لیکل","f":"leekul","g":"leekul","e":"to write","c":"v. trans.","ec":"write,writes,writing,wrote,wrote"} as ParticipleInput,
predicate: {"ts":1577394057681,"i":2784,"p":"پوهېدل","f":"pohedul","g":"pohedul","e":"to understand (to come to a state of understanding)","c":"v. stat. comp. intrans.","l":1527811469,"ec":"understand,understand,understanding,understood"} as ParticipleInput,
},
out: {
subject: [{ p: "لیکل", f: "leekul", e: "writing" }],
predicate: [{ p: "پوهېدل", f: "pohedul", e: "understanding" }],
equative: [{ p: "دي", f: "dee", e: "is" }],
},
},
],
},
{
label: "SUBJECT: Noun PREDICATE: Specified Unisex Noun",
tests: [
{
in: {
subject: {
entry: {"ts":1527812817,"i":9921,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."},
plural: true,
},
predicate: {
entry: {"ts":1527815127,"i":13259,"p":"نرس","f":"nars, nursa","g":"nars,nursa","e":"nurse","c":"n. m. anim. unisex"},
plural: false,
gender: "fem",
},
},
out: {
subject: [{ p: "کتابونه", f: "kitaabóona", e: "(The) books" }],
predicate: [{ p: "نرسه", f: "narsa", e: "(a/the) nurse" }],
equative: [{ p: "ده", f: "da", e: "are" }],
},
},
],
},
{
label: "SUBJECT: Specified Unisex Noun PREDICATE: Adjective",
tests: [
{
in: {
subject: {
entry: {"ts":1527815127,"i":13259,"p":"نرس","f":"nars, nursa","g":"nars,nursa","e":"nurse","c":"n. m. anim. unisex"},
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,
},
out: {
// TODO: should also use نرسې ?
subject: [{ p: "نرسانې", f: "narsáane", e: "(The) nurses" }],
predicate: [{ p: "زړې", f: "zaRe", e: "old" }],
equative: [{ p: "دي", f: "dee", e: "are" }],
},
},
],
},
{
label: "SUBJECT: Specified Unisex Noun PREDICATE: Predicate",
tests: [
{
in: {
subject: {
entry: {"ts":1527815127,"i":13259,"p":"نرس","f":"nars, nursa","g":"nars,nursa","e":"nurse","c":"n. m. anim. unisex"},
plural: false,
gender: "fem",
},
predicate: {
entry: {"ts":1527812817,"i":9921,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."},
plural: true,
},
},
out: {
subject: [{ p: "نرسه", f: "narsa", e: "(A/The) nurse" }],
predicate: [{ p: "کتابونه", f: "kitaabóona", e: "(the) books" }],
equative: [{ p: "دي", f: "dee", e: "is" }],
},
},
],
},
{
label: "SUBJECT: Specified Unisex Noun PREDICATE: Participle",
tests: [
{
in: {
subject: {
entry: {"ts":1527815127,"i":13259,"p":"نرس","f":"nars, nursa","g":"nars,nursa","e":"nurse","c":"n. m. anim. unisex"},
plural: false,
gender: "fem",
},
predicate: {"ts":1527813680,"i":9131,"p":"غږېدل","f":"ghuGedul, ghaGedul","g":"ghugedul,ghagedul","e":"to converse, speak, talk, sing","c":"v. intrans.","ec":"speak,speaks,speaking,spoke"} as ParticipleInput,
},
out: {
subject: [{ p: "نرسه", f: "narsa", e: "(A/The) nurse" }],
predicate: [{ p: "غږېدل", f: "ghuGedul", e: "speaking" }],
equative: [{ p: "دي", f: "dee", e: "is" }],
},
},
],
},
{
label: "SUBJECT: Participle PREDICATE: Specified Unisex Noun",
tests: [
{
in: {
subject: {"ts":1527812856,"i":11521,"p":"لیکل","f":"leekul","g":"leekul","e":"to write","c":"v. trans.","ec":"write,writes,writing,wrote,wrote"} as ParticipleInput,
predicate: {
entry: {"ts":1527815127,"i":13259,"p":"نرس","f":"nars, nursa","g":"nars,nursa","e":"nurse","c":"n. m. anim. unisex"},
plural: false,
gender: "fem",
},
},
out: {
subject: [{ p: "لیکل", f: "leekul", e: "writing" }],
predicate: [{ p: "نرسه", f: "narsa", e: "(a/the) nurse" }],
equative: [{ p: "ده", f: "da", e: "is" }],
},
},
],
},
];
@ -208,4 +451,12 @@ describe("equativeMachine", () => {
});
});
});
});
test("assembleEquativeOutput", () => {
expect(assembleEquativeOutput({
subject: [{ p: "کتابونه", f: "kitaabóona", e: "(The) books" }],
predicate: [{ p: "زاړه", f: "zaaRu", e: "old" }],
equative: [{ p: "دي", f: "dee", e: "are" }],
})).toEqual([{ p: "کتابونه زاړه دي", f: "kitaabóona zaaRu dee", e: "(The) books are old" }]);
});

View File

@ -10,7 +10,10 @@ import {
personGender,
getVerbBlockPosFromPerson,
addEnglish,
parseEc,
concatPsString,
} from "@lingdocs/pashto-inflector";
import { SingleOrLengthOpts } from "@lingdocs/pashto-inflector/dist/types";
export type EquativeMachineOutput = {
subject: T.PsString[],
@ -18,25 +21,30 @@ export type EquativeMachineOutput = {
equative: T.SingleOrLengthOpts<T.ArrayOneOrMore<T.PsString>>,
};
export type EquativeNounInput = {
export type NounInput = {
entry: T.DictionaryEntry,
plural: boolean,
};
export function equativeMachine(sub: T.Person | EquativeNounInput | T.DictionaryEntry, pred: T.DictionaryEntry): EquativeMachineOutput {
const subjPerson = getSubPerson(sub);
const isParticiple = !!(typeof sub !== "number" && "ts" in sub && sub.c?.startsWith("v."));
if (!isParticiple && (typeof sub !== "number" && "ts" in sub)) {
throw new Error("non participle subject should be in this form: { entry: T.Dictionary, plural: boolean }");
}
const subject = typeof sub === "number"
? makePronounSubject(sub)
: "entry" in sub
? makeNounSubject(sub)
: makeParticipleSub(sub);
const predicate = makePredicate(pred, subjPerson);
const equative = makeEquative(subjPerson, isParticiple);
export type AdjectiveInput = T.DictionaryEntry & { __brand: "an adjective" };
export type ParticipleInput = T.DictionaryEntry & { __brand: "a participle" };
export type UnisexNounInput = T.DictionaryEntry & { __brand: "a unisex noun" };
export type SpecifiedUnisexNounInput = NounInput & { gender: T.Gender };
export type PersonInput = T.Person;
export type EntityInput = SubjectInput | PredicateInput;
export type SubjectInput = PersonInput | NounInput | ParticipleInput | SpecifiedUnisexNounInput;
export type PredicateInput = PersonInput | NounInput | AdjectiveInput | SpecifiedUnisexNounInput | UnisexNounInput | ParticipleInput;
export function equativeMachine(sub: SubjectInput, pred: PredicateInput): EquativeMachineOutput {
// - english equative always agrees with subject
// - pashto equative agrees with predicate, unless it's an adjective, in which case the
// agreement reverts to the subject
const subjPerson = getInputPerson(sub, "subject");
const predPerson = getInputPerson(pred, "predicate") || subjPerson;
const subject = makeEntity(sub);
const predicate = makeEntity(pred, subjPerson);
const equative = makeEquative(subjPerson, predPerson, isParticipleInput(sub));
return {
subject,
predicate,
@ -44,7 +52,75 @@ export function equativeMachine(sub: T.Person | EquativeNounInput | T.Dictionary
};
}
function makePronounSubject(sub: T.Person): T.PsString[] {
export function assembleEquativeOutput(o: EquativeMachineOutput): 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]);
const e = `${o.subject[0].e} ${o.equative[0].e} ${o.predicate[0].e}`;
return [{ ...ps, e }];
}
// LEVEL 2 FUNCTIONS
function getInputPerson(e: SubjectInput, part: "subject"): T.Person;
function getInputPerson(e: PredicateInput, part: "predicate"): T.Person | undefined;
function getInputPerson(e: EntityInput, part: "subject" | "predicate"): T.Person | undefined {
function nounPerson(gender: T.Gender, plural: boolean): T.Person {
return plural
? ((gender === "masc") ? T.Person.ThirdPlurMale : T.Person.ThirdPlurFemale)
: ((gender === "masc") ? T.Person.ThirdSingMale : T.Person.ThirdSingFemale);
}
if (isPersonInput(e)) return e;
if (isNounInput(e)) {
const gender = e.entry.c?.includes("n. m.") ? "masc" : "fem"
return nounPerson(gender, e.plural);
}
if (isSpecifiedUnisexNounInput(e)) {
return nounPerson(e.gender, e.plural);
}
if (isParticipleInput(e)) return T.Person.ThirdPlurMale;
if (isUnisexNounInput(e)) return undefined;
if (isAdjectiveInput(e)) return undefined;
}
function makeEntity(e: EntityInput, subjPerson?: T.Person): T.PsString[] {
const isSubject = subjPerson === undefined;
if (typeof e === "number") return makePronoun(e);
if ("entry" in e) {
return makeNoun(e, isSubject ? "subject" : "predicate");
}
if (isAdjectiveInput(e) && subjPerson !== undefined) {
return makeAdjective(e, subjPerson);
}
if (isUnisexNounInput(e)) {
return makeUnisexNoun(e, subjPerson);
}
if (isParticipleInput(e)) {
return makeParticiple(e);
}
throw new Error(`invalid entity in ${subjPerson ? "predicate" : "subject"}`);
}
function makeEquative(subj: T.Person, pred: T.Person, subjIsParticipleInput: boolean): T.SentenceForm {
// The subject's person information, for the English equative
const [sRow, sCol] = getVerbBlockPosFromPerson(subjIsParticipleInput ? T.Person.ThirdSingMale : subj);
return addEnglish(
// english agrees with subject
grammarUnits.englishEquative.present[sRow][sCol],
// pashto agrees with predicate (if possible)
getPersonFromVerbForm(grammarUnits.equativeEndings.present, pred),
);
}
// LEVEL 3 FUNCTIONS
function makePronoun(sub: T.Person): T.PsString[] {
const [row, col] = getVerbBlockPosFromPerson(sub);
return addEnglish(
grammarUnits.persons[sub].label.subject,
@ -52,127 +128,124 @@ function makePronounSubject(sub: T.Person): T.PsString[] {
);
}
function makeNounSubject(sub: EquativeNounInput): T.PsString[] {
function makeEnglish(): string {
const e = getEnglishWord(sub.entry);
if (!e) {
throw new Error(`unable to get english from subject ${sub.entry.f} - ${sub.entry.ts}`);
function makeUnisexNoun(e: UnisexNounInput, subjPerson: T.Person | undefined): T.PsString[] {
// reuse english from make noun - do the a / an sensitivity
// if it's the predicate - get the inflection according to the subjPerson
const isPredicate = !!subjPerson;
if (isPredicate) {
const inf = inflectWord(e);
// TODO: Use if no inflections // FIX THIS
// BETTER CHECKING / GUARDING HERE
// @ts-ignore - TODO: REMOVE THIS
if (!inf || (!inf.inflections && !("plural" in inf)) || !isUnisexSet(inf.inflections)) {
throw Error("improper unisex noun");
}
if (typeof e === "string") return `(A/The) ${e}`;
if (sub.plural) {
return `(The) ${e.plural}`;
}
if (!e.singular) {
throw new Error(`unable to get english from subject ${sub.entry.f} - ${sub.entry.ts}`);
}
return `(A/The) ${e.singular}`;
}
function getPashto(): T.ArrayOneOrMore<T.PsString> {
const infs = inflectWord(sub.entry);
const gender = sub.entry.c?.includes("n. f.") ? "fem" : "masc";
try {
if (!infs || !sub.plural) {
return [psStringFromEntry(sub.entry, english)];
}
if (!("plural" in infs)) {
// @ts-ignore
return infs.inflections[gender][sub.plural ? 1 : 0];
}
// if plural // anim // chose that
// otherwise just chose inflection (or add both)
const pashto = ("plural" in inf && personIsPlural(subjPerson))
// @ts-ignore
return infs.plural[gender][0]
} catch (e) {
throw new Error(`error making noun subject for ${sub.entry.f} ${sub.entry.ts}`);
}
? inf.plural[personGender(subjPerson)][0] as T.ArrayOneOrMore<T.PsString>
: chooseInflection(inf.inflections, subjPerson);
const english = getEnglishFromNoun(e, personIsPlural(subjPerson), "predicate");
return addEnglish(english, pashto);
}
const english = makeEnglish();
// if it's the subject - TO BE IMPLEMENTED
throw new Error("unisex noun as subject not implemented yet");
}
function makeNoun(n: NounInput | SpecifiedUnisexNounInput, entity: "subject" | "predicate"): T.PsString[] {
const english = getEnglishFromNoun(n.entry, n.plural, entity);
const pashto = ((): T.ArrayOneOrMore<T.PsString> => {
const infs = inflectWord(n.entry);
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);
}
})();
return addEnglish(english, pashto);
}
function makeAdjective(e: AdjectiveInput, pers: T.Person): T.PsString[] {
const inf = inflectWord(e);
const english = getEnglishWord(e);
if (!english) throw new Error("no english available for adjective");
if (typeof english !== "string") throw new Error("error getting english for adjective, looks like a noun");
// non-inflecting adjective
if (!inf) return [psStringFromEntry(e, english)];
if (!inf.inflections) throw new Error("error getting inflections, looks like a noun")
if (!isUnisexSet(inf.inflections)) throw new Error("inflections for adjective were not unisex, looks like a noun");
// inflecting adjective - inflected based on the subject person
return addEnglish(
english,
getPashto(),
chooseInflection(inf.inflections, pers),
);
}
function makeParticipleSub(sub: T.DictionaryEntry): T.PsString[] {
return [
psStringFromEntry(sub, getEnglishParticiple(sub)),
];
function makeParticiple(e: T.DictionaryEntry): T.PsString[] {
return [psStringFromEntry(e, getEnglishParticiple(e))];
}
function makeEquative(pers: T.Person, isParticiple: boolean): T.SentenceForm {
const [row, col] = getVerbBlockPosFromPerson(pers);
return addEnglish(
isParticiple
? grammarUnits.englishEquative.present[4][0]
: grammarUnits.englishEquative.present[row][col],
getPersonFromVerbForm(grammarUnits.equativeEndings.present, pers),
);
}
function getSubPerson(sub: T.Person | EquativeNounInput | T.DictionaryEntry): T.Person {
if (typeof sub === "number") {
return sub;
}
if ("entry" in sub) {
const gender = sub.entry.c?.includes("n. f.") ? "fem" : "masc";
if (gender === "masc" && !sub.plural) {
return T.Person.ThirdSingMale;
}
if (gender === "masc" && sub.plural) {
return T.Person.ThirdPlurMale;
}
if (gender === "fem" && !sub.plural) {
return T.Person.ThirdSingFemale;
}
//if (gender === "fem" && sub.plural) {
return T.Person.ThirdPlurFemale;
// }
}
if (!sub.c || !sub.c.startsWith("v.")) {
throw new Error("subject should be a participle/verb");
}
return T.Person.ThirdPlurMale;
}
// LEVEL 4 FUNCTIONS
function makePredicate(pred: T.DictionaryEntry, pers: T.Person): T.PsString[] {
const infs = inflectWord(pred);
const e = retrieveEnglishPredicate(pred, pers);
if (!e) {
throw new Error(`unable to get english from predicate ${pred.f} - ${pred.ts}`);
}
const plural = personIsPlural(pers);
const gender = personGender(pers);
const makePlainPred = () => ([psStringFromEntry(pred, e)]);
if (!infs || !infs.inflections || !isUnisexSet(infs.inflections)) {
return makePlainPred();
}
if (plural && "plural" in infs && infs.plural) {
const ps = gender in infs.plural
// @ts-ignore
? infs.plural[gender][0] as T.PsString[]
: makePlainPred();
return ps.map((p) => ({ ...p, e }));
}
// if (infs.inflections) {
const inflection = chooseInflection(infs.inflections, pers);
return inflection.map((i) => ({ ...i, e }));
// }
}
function chooseInflection(inflections: T.UnisexSet<T.InflectionSet>, pers: T.Person): T.PsString[] {
function chooseInflection(inflections: T.UnisexSet<T.InflectionSet>, pers: T.Person): T.ArrayOneOrMore<T.PsString> {
return inflections[personGender(pers)][personIsPlural(pers) ? 1 : 0];
}
function retrieveEnglishPredicate(pred: T.DictionaryEntry, pers: T.Person): string | undefined {
const english = getEnglishWord(pred);
const plurSing = personIsPlural(pers) ? "plural" : "singular";
return typeof english === "string"
? english
: english === undefined
? undefined
: english[plurSing]
? english[plurSing]
: undefined;
function getEnglishFromNoun(entry: T.DictionaryEntry, plural: boolean, entity: "subject" | "predicate"): string {
const articles = {
singular: "(A/The)",
plural: "(The)",
};
const article = articles[plural ? "plural" : "singular"];
function addArticle(s: string) {
return `${entity === "subject" ? article : article.toLowerCase()} ${s}`;
}
const e = getEnglishWord(entry);
if (!e) throw new Error(`unable to get english from subject ${entry.f} - ${entry.ts}`);
if (typeof e === "string") return ` ${e}`;
if (plural) return addArticle(e.plural);
if (!e.singular || e.singular === undefined) {
throw new Error(`unable to get english from subject ${entry.f} - ${entry.ts}`);
}
return addArticle(e.singular);
}
// function getEnglishForUnisexNoun(pred: UnisexNounInput, pers: T.Person): string | undefined {
// const english = getEnglishWord(pred);
// const plurSing = personIsPlural(pers) ? "plural" : "singular";
// return typeof english === "string"
// ? english
// : english === undefined
// ? undefined
// : english[plurSing]
// ? english[plurSing]
// : undefined;
// }
function psStringFromEntry(entry: T.DictionaryEntry, e: string): T.PsString {
return {
p: entry.p,
@ -182,5 +255,54 @@ function psStringFromEntry(entry: T.DictionaryEntry, e: string): T.PsString {
}
function getEnglishParticiple(entry: T.DictionaryEntry): string {
return "doing";
}
if (!entry.ec) throw new Error("no english information for participle");
const ec = parseEc(entry.ec);
const participle = ec[2];
return (entry.ep)
? `${participle} ${entry.ep}`
: participle;
}
function isPersonInput(e: EntityInput): e is PersonInput {
return typeof e === "number";
}
function isNounInput(e: EntityInput): e is NounInput {
if (isPersonInput(e)) return false;
if ("entry" in e && !("gender" in e)) {
// e
return true;
}
return false;
}
function isParticipleInput(e: EntityInput): e is ParticipleInput {
if (isPersonInput(e)) return false;
if ("entry" in e) return false;
return !!e.c?.startsWith("v.");
}
function isSpecifiedUnisexNounInput(e: EntityInput): e is SpecifiedUnisexNounInput {
if (isPersonInput(e)) return false;
if ("entry" in e && "gender" in e) {
// e
return true;
}
return false;
}
function isUnisexNounInput(e: EntityInput): e is UnisexNounInput {
if (isPersonInput(e)) return false;
if ("entry" in e) return false;
return !!e.c?.includes("unisex");
}
function isAdjectiveInput(e: EntityInput): e is AdjectiveInput {
if (isPersonInput(e)) return false;
if ("entry" in e) return false;
if (isNounInput(e)) return false;
if (isUnisexNounInput(e)) return false;
if (isSpecifiedUnisexNounInput(e)) return false;
return !!e.c?.includes("adj.");
}

View File

@ -1583,10 +1583,10 @@
passport-google-oauth "^2.0.0"
passport-twitter "^1.0.4"
"@lingdocs/pashto-inflector@^1.1.3":
version "1.1.3"
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-1.1.3.tgz#e908b1933bd9dd3962d9757ad9eb270184d9914c"
integrity sha512-kez2oSZOK1RQm4VssyRBeGehtfT8iS3ROqiOjxgFZj0S8gGw4/A8TsfACGuqh1D0/3EaCI7JjBlj/O5tsHZ2DQ==
"@lingdocs/pashto-inflector@^1.1.4":
version "1.1.4"
resolved "https://npm.lingdocs.com/@lingdocs%2fpashto-inflector/-/pashto-inflector-1.1.4.tgz#1c1373fca53ef27705366663eb4519d51009dbe9"
integrity sha512-2TWXBV/Xnlot0kVz9016TiXMe/liRfghrZDJBdOSq29VMI//23UEuOWpxlkeIyw9XVY+MsYYC2k6dHsRoak7NQ==
dependencies:
classnames "^2.2.6"
pbf "^3.2.1"