more on ee

This commit is contained in:
lingdocs 2021-10-22 15:14:55 -04:00
parent a97b85863e
commit 45955a997e
9 changed files with 181 additions and 34 deletions

View File

@ -1,9 +1,12 @@
import {
VerbTable,
defaultTextOptions as opts,
ButtonSelect,
Types as T,
} from "@lingdocs/pashto-inflector";
import {
ExplorerState,
ExplorerReducerAction,
} from "./explorer-types";
import {
makeBlockWPronouns,
@ -15,12 +18,13 @@ import {
} from "../../lib/equative-machine";
import { isNoun, isPluralEntry, isUnisexNoun } from "../../lib/type-predicates";
function EquativeDisplay({ state }: { state: ExplorerState }) {
export function chooseLength<O>(o: T.SingleOrLengthOpts<O>, length: "short" | "long"): O {
return ("long" in o) ? o[length] : o;
}
function SingleItemDisplay({ state }: { state: ExplorerState }) {
if (state.subjectType === "pronouns") {
return <VerbTable
textOptions={opts}
block={makeBlockWPronouns(state.predicatesSelected[state.predicateType])}
/>
return <div>ERROR: Wrong display being used</div>;
}
const entry = state.subjectsSelected[state.subjectType];
// @ts-ignore - TODO: safer and for use with unisex nouns
@ -32,13 +36,40 @@ function EquativeDisplay({ state }: { state: ExplorerState }) {
} : {},
} : entry;
const eq = assembleEquativeOutput(
equativeMachine(subjInput, state.predicatesSelected[state.predicateType])
const block = assembleEquativeOutput(
equativeMachine(subjInput, state.predicatesSelected[state.predicateType], state.tense)
);
if ("short" in eq) return <div>length options not supported yet</div>;
return <div>
<VerbTable textOptions={opts} block={eq} />
<VerbTable textOptions={opts} block={chooseLength(block, state.length)} />
</div>;
}
function PronounBlockDisplay({ state }: { state: ExplorerState }) {
const block = makeBlockWPronouns(state.predicatesSelected[state.predicateType], state.tense);
return <VerbTable
textOptions={opts}
block={chooseLength(block, state.length)}
/>;
}
function EquativeDisplay({ state, dispatch }: { state: ExplorerState, dispatch: (action: ExplorerReducerAction) => void }) {
return <>
{state.tense === "past" && <div className="text-center">
<ButtonSelect
small
options={[
{ label: "Long", value: "long" },
{ label: "Short", value: "short" },
]}
value={state.length}
handleChange={(p) => dispatch({ type: "setLength", payload: p as "long" | "short" })}
/>
</div>}
{state.subjectType === "pronouns"
? <PronounBlockDisplay state={state} />
: <SingleItemDisplay state={state} />
}
</>;
}
export default EquativeDisplay;

View File

@ -5,6 +5,7 @@ import {
import {
PredicateSelector,
SubjectSelector,
TenseSelector,
} from "./explorer-selectors";
import {
ExplorerState,
@ -18,9 +19,9 @@ import {
} from "./explorer-inputs";
import EquativeDisplay from "./EquativeDisplay";
// TODO: Plural nouns like shoode
const defaultState: ExplorerState = {
tense: "present",
length: "short",
predicatesSelected: {
adjective: defaultAdjective,
unisexNoun: defaultUnisexNoun,
@ -45,11 +46,12 @@ function EquativeExplorer() {
unsafeSetState(newState);
}
return <>
<div className="d-flex flex-row justify-content-between align-items-center">
<TenseSelector state={state} dispatch={dispatch} />
<div className="d-flex flex-row justify-content-between align-items-center mt-2">
<SubjectSelector state={state} dispatch={dispatch} />
<PredicateSelector state={state} dispatch={dispatch} />
</div>
<EquativeDisplay state={state} />
<EquativeDisplay state={state} dispatch={dispatch} />
</>;
}

View File

@ -9,16 +9,27 @@ import {
ParticipleInput,
isParticipleInput,
getEnglishParticiple,
TenseInput,
} from "../../lib/equative-machine";
export function sort<T extends (Adjective | Noun | ParticipleInput)>(arr: Readonly<T[]>): T[] {
return [...arr].sort((a, b) => a.p.localeCompare(b.p));
}
export function makeBlockWPronouns(e: Adjective | UnisexNoun): T.VerbBlock {
export function makeBlockWPronouns(e: Adjective | UnisexNoun, tense: TenseInput, length?: "short" | "long"): T.SingleOrLengthOpts<T.VerbBlock> {
if (tense === "past" && !length) {
return {
short: makeBlockWPronouns(e, tense, "short") as T.VerbBlock,
long: makeBlockWPronouns(e, tense, "long") as 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>;
const b = assembleEquativeOutput(equativeMachine(p, e, tense));
if ("long" in b) {
if (!length) throw new Error("bad length processing");
return b[length];
}
return b;
};
return [
[makeP(0), makeP(6)],

View File

@ -53,6 +53,7 @@ export function reducer(state: ExplorerState, action: ExplorerReducerAction): Ex
},
};
}
if (action.type === "setSubjectGender") {
return {
...state,
subjectsSelected: {
@ -64,3 +65,14 @@ export function reducer(state: ExplorerState, action: ExplorerReducerAction): Ex
},
};
}
if (action.type === "setTense") {
return {
...state,
tense: action.payload,
};
}
return {
...state,
length: action.payload,
};
}

View File

@ -204,3 +204,27 @@ export function PredicateSelector({ state, dispatch }: {
</div>;
}
export function TenseSelector({ state, dispatch }: {
state: ExplorerState,
dispatch: (action: ExplorerReducerAction) => void,
}) {
const options = [
{ value: "present", label: "Present" },
{ value: "past", label: "Past" },
];
function onTenseSelect({ value }: any) {
dispatch({ type: "setTense", payload: value });
}
return <div>
<h5>Tense:</h5>
<Select
value={state.tense}
onChange={onTenseSelect}
className="mb-2"
// @ts-ignore
options={options}
placeholder={options.find(o => o.value === state.tense)?.label}
{...zIndexProps}
/>
</div>
}

View File

@ -1,10 +1,12 @@
import { Types as T } from "@lingdocs/pashto-inflector";
import { ParticipleInput } from "../../lib/equative-machine";
import { ParticipleInput, TenseInput } from "../../lib/equative-machine";
export type PredicateType = keyof PredicatesSelected;
export type SubjectType = "noun" | "pronouns" | "participle" | "unisexNoun";
export type ExplorerState = {
tense: TenseInput,
length: "short" | "long",
subjectType: SubjectType,
subjectsSelected: SubjectSelected,
predicateType: PredicateType,
@ -36,4 +38,8 @@ export type ExplorerReducerAction = {
type: "setSubjectPlural", payload: boolean,
} | {
type: "setSubjectGender", payload: T.Gender,
} | {
type: "setTense", payload: TenseInput,
} | {
type: "setLength", payload: "short" | "long",
};

View File

@ -3,8 +3,5 @@ title: Equative Explorer 🌎
---
import EquativeExplorer from "../../components/equative-explorer/EquativeExplorer";
import Link from "../../components/Link";
This currently only works with <Link to="/equatives/present-equative/">present equatives</Link>. More coming soon... 👷‍♂️
<EquativeExplorer />

View File

@ -5,6 +5,7 @@ import {
PredicateInput,
ParticipleInput,
assembleEquativeOutput,
TenseInput,
} from "./equative-machine";
import {
Types as T,
@ -45,6 +46,7 @@ const abilities: {
in: {
subject: SubjectInput,
predicate: PredicateInput,
tense: TenseInput,
},
out: EquativeMachineOutput,
}[],
@ -57,6 +59,7 @@ const abilities: {
in: {
subject: T.Person.FirstSingMale,
predicate: {"ts":1527815306,"i":7530,"p":"ستړی","f":"stúRey","g":"stuRey","e":"tired","c":"adj."} as Adjective,
tense: "present",
},
out: {
subject: [{ p: "زه", f: "zu", e: "I (m.)" }],
@ -68,6 +71,7 @@ const abilities: {
in: {
subject: T.Person.SecondPlurFemale,
predicate: {"ts":1527815306,"i":7530,"p":"ستړی","f":"stúRey","g":"stuRey","e":"tired","c":"adj."} as Adjective,
tense: "present",
},
out: {
subject: [{ p: "تاسو", f: "táaso", e: "You (f. pl.)" }, { p: "تاسې", f: "táase", e: "You (f. pl.)"}],
@ -80,6 +84,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 Adjective,
tense: "present",
},
out: {
subject: [{ p: "هغه", f: "haghá", e: "She/it (f.)" }],
@ -96,6 +101,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. anim. unisex"} as UnisexNoun,
tense: "present",
},
out: {
subject: [{ p: "زه", f: "zu", e: "I (f.)" }],
@ -107,6 +113,7 @@ const abilities: {
in: {
subject: T.Person.FirstPlurFemale,
predicate: {"ts":1591872915426,"i":696,"p":"افغانی","f":"afghaanéy","g":"afghaaney","e":"Afghan (person)","c":"n. m. anim. unisex"} as UnisexNoun,
tense: "present",
},
out: {
subject: [{ p: "مونږ", f: "moonG", e: "We (f. pl.)" }, { p: "موږ", f: "mooG", e: "We (f. pl.)" }],
@ -121,6 +128,7 @@ 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 UnisexNoun,
tense: "present",
},
out: {
subject: [{ p: "مونږ", f: "moonG", e: "We (f. pl.)" }, { p: "موږ", f: "mooG", e: "We (f. pl.)" }],
@ -132,6 +140,7 @@ const abilities: {
in: {
subject: T.Person.SecondSingFemale,
predicate: {"ts":1527814779,"i":935,"p":"انسان","f":"insaan","g":"insaan","e":"human, person","c":"n. m. anim. unisex"} as UnisexNoun,
tense: "present",
},
out: {
subject: [{ p: "ته", f: "tu", e: "You (f.)" }],
@ -151,6 +160,7 @@ const abilities: {
plural: false,
},
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as Adjective,
tense: "present",
},
out: {
subject: [{ p: "کتاب", f: "kitáab", e: "(A/The) book" }],
@ -165,6 +175,7 @@ const abilities: {
plural: true,
},
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as Adjective,
tense: "present",
},
out: {
subject: [{ p: "کتابونه", f: "kitaabóona", e: "(The) books" }],
@ -179,6 +190,7 @@ const abilities: {
plural: false,
},
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as Adjective,
tense: "present",
},
out: {
subject: [{ p: "ښځه", f: "xúdza", e: "(A/The) woman" }],
@ -193,6 +205,7 @@ const abilities: {
plural: true,
},
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as Adjective,
tense: "present",
},
out: {
subject: [{ p: "ښځې", f: "xúdze", e: "(The) women" }],
@ -208,6 +221,7 @@ const abilities: {
plural: true,
},
predicate: {"ts":1527812798,"i":5595,"p":"خفه","f":"khufa","g":"khufa","e":"sad, upset, angry; choked, suffocated","c":"adj."} as Adjective,
tense: "present",
},
out: {
subject: [{ p: "ښځې", f: "xúdze", e: "(The) women" }],
@ -227,6 +241,7 @@ const abilities: {
plural: true,
},
predicate: {"ts":1527812796,"i":8578,"p":"ښه","f":"xu","g":"xu","e":"good","c":"adj."} as Adjective,
tense: "present",
},
out: {
subject: [{ p: "شودې", f: "shoodé", e: "(The) milk" }],
@ -241,6 +256,7 @@ const abilities: {
plural: true,
},
predicate: {"ts":1527815451,"i":7192,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as Adjective,
tense: "present",
},
out: {
subject: [{ p: "غنم", f: "ghanúm", e: "(The) wheat" }],
@ -257,6 +273,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 Adjective,
tense: "present",
},
out: {
subject: [{ p: "خوړل", f: "khoRul", e: "eating" }],
@ -268,6 +285,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 Adjective,
tense: "present",
},
out: {
subject: [{ p: "اخیستل", f: "akheestul", e: "taking" }],
@ -279,6 +297,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 Adjective,
tense: "present",
},
out: {
subject: [{ p: "جګېدل", f: "jugedul", e: "getting up" }],
@ -295,6 +314,7 @@ const abilities: {
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,
tense: "present",
},
out: {
subject: [{ p: "ته", f: "tu", e: "You (m.)" }],
@ -317,6 +337,7 @@ const abilities: {
entry: {"ts":1527812788,"i":5729,"p":"خوراک","f":"khoráak, khwaráak","g":"khoraak,khwaraak","e":"food","c":"n. m."} as SingularEntry<Noun>,
plural: false,
},
tense: "present",
},
out: {
subject: [{ p: "خوشحالي", f: "khosh`haalee", e: "(A/The) happiness" }],
@ -336,6 +357,7 @@ const abilities: {
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,
tense: "present",
},
out: {
subject: [{ p: "وروروالی", f: "wrorwaaley", e: "(A/The) brotherhood" }],
@ -355,6 +377,7 @@ const abilities: {
entry: {"ts":1527813477,"i":5790,"p":"خوشحالي","f":"khosh`haalee","g":"khoshhaalee","e":"happiness, joy","c":"n. f."} as SingularEntry<Noun>,
plural: false,
},
tense: "present",
},
out: {
subject: [{ p: "لیکل", f: "leekul", e: "writing" }],
@ -371,6 +394,7 @@ const abilities: {
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,
tense: "present",
},
out: {
subject: [{ p: "لیکل", f: "leekul", e: "writing" }],
@ -394,6 +418,7 @@ const abilities: {
plural: false,
gender: "fem",
},
tense: "present",
},
out: {
subject: [{ p: "کتابونه", f: "kitaabóona", e: "(The) books" }],
@ -414,6 +439,7 @@ const abilities: {
gender: "fem",
},
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as Adjective,
tense: "present",
},
out: {
subject: [
@ -440,6 +466,7 @@ const abilities: {
entry: {"ts":1527812817,"i":9921,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m."} as SingularEntry<Noun>,
plural: true,
},
tense: "present",
},
out: {
subject: [{ p: "نرسه", f: "narsa", e: "(A/The) nurse" }],
@ -460,6 +487,7 @@ const abilities: {
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,
tense: "present",
},
out: {
subject: [{ p: "نرسه", f: "narsa", e: "(A/The) nurse" }],
@ -480,6 +508,7 @@ const abilities: {
plural: false,
gender: "fem",
},
tense: "present",
},
out: {
subject: [{ p: "لیکل", f: "leekul", e: "writing" }],
@ -489,13 +518,36 @@ const abilities: {
},
],
},
{
label: "Past tense",
tests: [
{
in: {
subject: {
entry: { "ts":1527812817,"i":9921,"p":"کتاب","f":"kitáab","g":"kitaab","e":"book","c":"n. m." } as SingularEntry<Noun>,
plural: false,
},
predicate: {"ts":1527815451,"i":7193,"p":"زوړ","f":"zoR","g":"zoR","e":"old","c":"adj. irreg.","infap":"زاړه","infaf":"zaaRu","infbp":"زړ","infbf":"zaR"} as Adjective,
tense: "past",
},
out: {
subject: [{ p: "کتاب", f: "kitáab", e: "(A/The) book" }],
predicate: [{ p: "زوړ", f: "zoR", e: "old" }],
equative: {
short: [{ p: "و", f: "wo", e: "was" }],
long: [{ p: "ولو", f: "wulo", e: "was" }],
},
},
},
],
},
];
describe("equativeMachine", () => {
abilities.forEach((a) => {
test(a.label, () => {
a.tests.forEach((t) => {
expect(equativeMachine(t.in.subject, t.in.predicate)).toEqual(t.out);
expect(equativeMachine(t.in.subject, t.in.predicate, t.in.tense)).toEqual(t.out);
});
});
});
@ -520,4 +572,15 @@ test("assembleEquativeOutput", () => {
{ 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" },
]);
expect(assembleEquativeOutput({
subject: [{ p: "کتاب", f: "kitáab", e: "(A/The) book" }],
predicate: [{ p: "زوړ", f: "zoR", e: "old" }],
equative: {
short: [{ p: "و", f: "wo", e: "was" }],
long: [{ p: "ولو", f: "wulo", e: "was" }],
},
})).toEqual({
short: [{ p: "کتاب زوړ و", f: "kitáab zoR wo", e: "(A/The) book was old" }],
long: [{ p: "کتاب زوړ ولو", f: "kitáab zoR wulo", e: "(A/The) book was old" }],
});
});

View File

@ -38,8 +38,9 @@ export type PersonInput = T.Person;
export type EntityInput = SubjectInput | PredicateInput;
export type SubjectInput = PersonInput | NounInput | ParticipleInput | SpecifiedUnisexNounInput;
export type PredicateInput = PersonInput | NounInput | Adjective | SpecifiedUnisexNounInput | UnisexNoun | ParticipleInput;
export type TenseInput = "present" | "past";
export function equativeMachine(sub: SubjectInput, pred: PredicateInput): EquativeMachineOutput {
export function equativeMachine(sub: SubjectInput, pred: PredicateInput, tense: TenseInput = "present"): 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
@ -47,7 +48,7 @@ export function equativeMachine(sub: SubjectInput, pred: PredicateInput): Equati
const predPerson = getInputPerson(pred, "predicate") || subjPerson;
const subject = makeEntity(sub);
const predicate = makeEntity(pred, subjPerson);
const equative = makeEquative(subjPerson, predPerson, sub);
const equative = makeEquative(subjPerson, predPerson, sub, tense);
return {
subject,
predicate,
@ -120,7 +121,7 @@ function makeEntity(e: EntityInput, subjPerson?: T.Person): T.PsString[] {
throw new Error(`invalid entity in ${subjPerson ? "predicate" : "subject"}`);
}
function makeEquative(subj: T.Person, pred: T.Person, subjectInput: SubjectInput): T.SentenceForm {
function makeEquative(subj: T.Person, pred: T.Person, subjectInput: SubjectInput, tense: TenseInput): T.SentenceForm {
const isPluralNoun = isNounInput(subjectInput) && isPluralEntry(subjectInput.entry);
// The subject's person information, for the English equative
const [eeRow, eeCol] = getVerbBlockPosFromPerson(
@ -129,9 +130,9 @@ function makeEquative(subj: T.Person, pred: T.Person, subjectInput: SubjectInput
: subj
);
return addEnglish(
grammarUnits.englishEquative.present[eeRow][eeCol],
grammarUnits.englishEquative[tense][eeRow][eeCol],
// pashto agrees with predicate (if possible)
getPersonFromVerbForm(grammarUnits.equativeEndings.present, pred),
getPersonFromVerbForm(grammarUnits.equativeEndings[tense], pred),
);
}