refactor np and add negative in equative clause
This commit is contained in:
parent
1d9ff2b9e1
commit
440a9decb7
|
@ -10,18 +10,13 @@ import {
|
|||
ExplorerState,
|
||||
ExplorerReducerAction,
|
||||
} from "./explorer-types";
|
||||
// import {
|
||||
// makeBlockWPronouns,
|
||||
// } from "./explorer-helpers";
|
||||
import {
|
||||
equativeMachine,
|
||||
assembleEquativeOutput,
|
||||
} from "../../lib/equative-machine";
|
||||
import {
|
||||
isPluralNounEntry,
|
||||
isUnisexNounEntry,
|
||||
isAdjectiveEntry,
|
||||
isSingularEntry,
|
||||
isVerbEntry,
|
||||
isLocativeAdverbEntry,
|
||||
isNounEntry,
|
||||
|
@ -47,6 +42,7 @@ function SingleItemDisplay({ state }: { state: ExplorerState }) {
|
|||
subject,
|
||||
predicate,
|
||||
tense: state.tense,
|
||||
negative: state.negative,
|
||||
})
|
||||
);
|
||||
return <div>
|
||||
|
@ -72,56 +68,27 @@ function makeNounPhrase(entry: NounEntry | UnisexNounEntry | VerbEntry, state: E
|
|||
entry,
|
||||
};
|
||||
}
|
||||
const isUnisex = isUnisexNounEntry(entry);
|
||||
if (isUnisex && isSingularEntry(entry)) {
|
||||
return {
|
||||
type: "unisex noun",
|
||||
number: state[entity].info.number,
|
||||
gender: state[entity].info.gender,
|
||||
entry,
|
||||
};
|
||||
}
|
||||
if (isUnisex && isPluralNounEntry(entry)) {
|
||||
return {
|
||||
type: "unisex noun",
|
||||
number: state[entity].info.number,
|
||||
gender: state[entity].info.gender,
|
||||
entry,
|
||||
};
|
||||
}
|
||||
if (isUnisex) {
|
||||
throw new Error("improper unisex noun");
|
||||
}
|
||||
if (isPluralNounEntry(entry)) {
|
||||
const e = entry as PluralNounEntry<MascNounEntry | FemNounEntry>;
|
||||
return {
|
||||
type: "plural noun",
|
||||
entry: e,
|
||||
};
|
||||
}
|
||||
if (isSingularEntry(entry)) {
|
||||
const e = entry as SingularEntry<MascNounEntry | FemNounEntry>;
|
||||
return {
|
||||
type: "singular noun",
|
||||
entry: e,
|
||||
number: state[entity].info.number,
|
||||
};
|
||||
}
|
||||
throw new Error("unable to make subject input from entry");
|
||||
return {
|
||||
type: "noun",
|
||||
number: state[entity].info.number,
|
||||
gender: state[entity].info.gender,
|
||||
entry,
|
||||
};
|
||||
}
|
||||
|
||||
export function makeBlockWPronouns(e: AdjectiveEntry | UnisexNounEntry | LocativeAdverbEntry, tense: EquativeTense, length?: "short" | "long"): T.SingleOrLengthOpts<T.VerbBlock> {
|
||||
export function makeBlockWPronouns(e: AdjectiveEntry | UnisexNounEntry | LocativeAdverbEntry, tense: EquativeTense, negative: boolean, length?: "short" | "long"): T.SingleOrLengthOpts<T.VerbBlock> {
|
||||
// if the output's gonna have long / short forms (if it's past or wouldBe) then recursive call to make the long and short versions
|
||||
if (!length && "long" in assembleEquativeOutput(equativeMachine({
|
||||
subject: { type: "pronoun", pronounType: "near", person: 0 },
|
||||
predicate: (isAdjectiveEntry(e) || isLocativeAdverbEntry(e))
|
||||
? { type: "compliment", entry: e }
|
||||
: { type: "unisex noun", gender: "masc", number: "singular", entry: e },
|
||||
: { type: "noun", gender: "masc", number: "singular", entry: e },
|
||||
tense,
|
||||
negative,
|
||||
}))) {
|
||||
return {
|
||||
short: makeBlockWPronouns(e, tense, "short") as T.VerbBlock,
|
||||
long: makeBlockWPronouns(e, tense, "long") as T.VerbBlock,
|
||||
short: makeBlockWPronouns(e, tense, negative, "short") as T.VerbBlock,
|
||||
long: makeBlockWPronouns(e, tense, negative, "long") as T.VerbBlock,
|
||||
};
|
||||
}
|
||||
const makeP = (p: T.Person): T.ArrayOneOrMore<T.PsString> => {
|
||||
|
@ -129,8 +96,9 @@ export function makeBlockWPronouns(e: AdjectiveEntry | UnisexNounEntry | Locativ
|
|||
subject: { type: "pronoun", pronounType: "far", person: p },
|
||||
predicate: (isAdjectiveEntry(e) || isLocativeAdverbEntry(e))
|
||||
? { type: "compliment", entry: e }
|
||||
: { type: "unisex noun", gender: personGender(p), number: personIsPlural(p) ? "plural" : "singular", entry: e },
|
||||
: { type: "noun", gender: personGender(p), number: personIsPlural(p) ? "plural" : "singular", entry: e },
|
||||
tense,
|
||||
negative,
|
||||
}));
|
||||
if ("long" in b) {
|
||||
if (!length) throw new Error("bad length processing");
|
||||
|
@ -151,7 +119,7 @@ export function makeBlockWPronouns(e: AdjectiveEntry | UnisexNounEntry | Locativ
|
|||
function PronounBlockDisplay({ state }: { state: ExplorerState }) {
|
||||
const pred = state.predicate[state.predicate.type];
|
||||
if (!isVerbEntry(pred) && (isAdjectiveEntry(pred) || isLocativeAdverbEntry(pred) || (isNounEntry(pred) && isUnisexNounEntry(pred)))) {
|
||||
const block = makeBlockWPronouns(pred, state.tense);
|
||||
const block = makeBlockWPronouns(pred, state.tense, state.negative);
|
||||
return <VerbTable
|
||||
textOptions={opts}
|
||||
block={chooseLength(block, state.length)}
|
||||
|
|
|
@ -22,6 +22,7 @@ import EquativeDisplay from "./EquativeDisplay";
|
|||
const defaultState: ExplorerState = {
|
||||
tense: "present",
|
||||
length: "short",
|
||||
negative: false,
|
||||
predicate: {
|
||||
type: "adjective",
|
||||
adjective: defaultAdjective,
|
||||
|
|
|
@ -94,6 +94,12 @@ export function reducer(state: ExplorerState, action: ExplorerReducerAction): Ex
|
|||
// },
|
||||
// };
|
||||
// }
|
||||
if (action.type === "setNegative") {
|
||||
return {
|
||||
...state,
|
||||
negative: action.payload,
|
||||
};
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
length: action.payload,
|
||||
|
|
|
@ -209,5 +209,16 @@ export function TenseSelector({ state, dispatch }: {
|
|||
placeholder={options.find(o => o.value === state.tense)?.label}
|
||||
{...zIndexProps}
|
||||
/>
|
||||
<div className="text-center mb-2">
|
||||
<ButtonSelect
|
||||
small
|
||||
options={[
|
||||
{ label: "Pos.", value: "pos" },
|
||||
{ label: "Neg.", value: "neg" },
|
||||
]}
|
||||
value={state.negative ? "neg" : "pos"}
|
||||
handleChange={(p) => dispatch({ type: "setNegative", payload: p === "neg" })}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ export type ExplorerState = {
|
|||
length: "short" | "long",
|
||||
subject: SubjectEntityInfo,
|
||||
predicate: PredicateEntityInfo,
|
||||
negative: boolean,
|
||||
};
|
||||
|
||||
export type SubjectEntityInfo = EntitiyInfo & { type: SubjectType };
|
||||
|
@ -46,4 +47,6 @@ export type ExplorerReducerAction = {
|
|||
type: "setTense", payload: EquativeTense,
|
||||
} | {
|
||||
type: "setLength", payload: "short" | "long",
|
||||
} | {
|
||||
type: "setNegative", payload: boolean,
|
||||
};
|
|
@ -4,6 +4,7 @@ import {
|
|||
getVerbBlockPosFromPerson,
|
||||
getPersonFromVerbForm,
|
||||
concatPsString,
|
||||
removeAccents,
|
||||
} from "@lingdocs/pashto-inflector";
|
||||
import {
|
||||
personFromNP,
|
||||
|
@ -12,6 +13,7 @@ import {
|
|||
import {
|
||||
evaluateCompliment,
|
||||
} from "./compliment-tools";
|
||||
import { isPluralNounEntry } from "./type-predicates";
|
||||
|
||||
// Equative Rules
|
||||
// - An equative equates a SUBJECT: Noun Phrase and a PREDICATE: Noun Phrase | Compliment
|
||||
|
@ -27,11 +29,13 @@ export function equativeMachine(e: EquativeClause): EquativeClauseOutput {
|
|||
? evaluateCompliment(e.predicate, personFromNP(e.subject))
|
||||
: evaluateNP(e.predicate);
|
||||
const equative = makeEquative(e);
|
||||
const negative = !!e?.negative;
|
||||
return {
|
||||
ba,
|
||||
subject,
|
||||
predicate,
|
||||
equative,
|
||||
negative,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -47,10 +51,19 @@ export function assembleEquativeOutput(o: EquativeClauseOutput): T.SingleOrLengt
|
|||
const equatives = o.equative.ps;
|
||||
const predicates = o.predicate.ps;
|
||||
const ba = o.ba ? { p: " به", f: " ba" } : "";
|
||||
const neg = o.negative ? { p: "نه ", f: "nú " } : "";
|
||||
const ps = o.subject.ps.flatMap(subj => (
|
||||
predicates.flatMap(pred => (
|
||||
equatives.map(eq => (
|
||||
concatPsString(subj, ba, " ", pred, " ", eq))
|
||||
concatPsString(
|
||||
subj,
|
||||
ba,
|
||||
" ",
|
||||
pred,
|
||||
" ",
|
||||
neg,
|
||||
o.negative ? removeAccents(eq) : eq,
|
||||
))
|
||||
)
|
||||
))
|
||||
));
|
||||
|
@ -71,7 +84,7 @@ function makeEquative(e: EquativeClause) {
|
|||
? "past"
|
||||
: e.tense;
|
||||
const subjP = personFromNP(e.subject);
|
||||
const englishPerson = (e.subject.type === "plural noun" || e.subject.type === "participle")
|
||||
const englishPerson = (e.subject.type === "participle" || (e.subject.type === "noun" && isPluralNounEntry(e.subject.entry)))
|
||||
? T.Person.ThirdSingMale
|
||||
: subjP
|
||||
const pashtoPerson = (e.subject.type === "pronoun")
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { isMascNounEntry } from "./type-predicates";
|
||||
import { isMascNounEntry, isPluralNounEntry, isUnisexNounEntry } from "./type-predicates";
|
||||
import {
|
||||
Types as T,
|
||||
getEnglishWord,
|
||||
|
@ -18,14 +18,8 @@ export function personFromNP(np: NounPhrase): T.Person {
|
|||
if (np.type === "pronoun") {
|
||||
return np.person;
|
||||
}
|
||||
const gender: T.Gender = "gender" in np
|
||||
? np.gender
|
||||
: isMascNounEntry(np.entry)
|
||||
? "masc"
|
||||
: "fem";
|
||||
const number: NounNumber = np.type === "plural noun"
|
||||
? "plural"
|
||||
: np.number;
|
||||
const gender = nounGender(np);
|
||||
const number = nounNumber(np);
|
||||
return number === "plural"
|
||||
? (gender === "masc" ? T.Person.ThirdPlurMale : T.Person.ThirdPlurFemale)
|
||||
: (gender === "masc" ? T.Person.ThirdSingMale : T.Person.ThirdSingFemale);
|
||||
|
@ -41,6 +35,30 @@ export function evaluateNP(np: NounPhrase): { ps: T.PsString[], e: string } {
|
|||
return evaluateNoun(np);
|
||||
}
|
||||
|
||||
function nounGender(n: Noun): T.Gender {
|
||||
const nGender = isUnisexNounEntry(n.entry)
|
||||
? "unisex"
|
||||
: isMascNounEntry(n.entry)
|
||||
? "masc"
|
||||
: "fem";
|
||||
return (nGender === "unisex" && n.gender)
|
||||
? n.gender
|
||||
: (nGender === "unisex")
|
||||
? "masc"
|
||||
: nGender;
|
||||
}
|
||||
|
||||
function nounNumber(n: Noun): NounNumber {
|
||||
const nNumber = isPluralNounEntry(n.entry)
|
||||
? "plural"
|
||||
: "singular";
|
||||
return nNumber === "plural"
|
||||
? "plural"
|
||||
: n.number
|
||||
? n.number
|
||||
: nNumber;
|
||||
}
|
||||
|
||||
function evaluatePronoun(p: Pronoun): { ps: T.PsString[], e: string } {
|
||||
// TODO: Will need to handle inflecting and inflecting english pronouns etc.
|
||||
const [row, col] = getVerbBlockPosFromPerson(p.person);
|
||||
|
@ -51,12 +69,11 @@ function evaluatePronoun(p: Pronoun): { ps: T.PsString[], e: string } {
|
|||
}
|
||||
|
||||
function evaluateNoun(n: Noun): { ps: T.PsString[], e: string } {
|
||||
const number: NounNumber = "number" in n ? n.number : "plural";
|
||||
const number = nounNumber(n);
|
||||
const english = getEnglishFromNoun(n.entry, number);
|
||||
const pashto = ((): T.PsString[] => {
|
||||
const infs = inflectWord(n.entry);
|
||||
const gender: T.Gender = "gender" in n ? n.gender :
|
||||
(isMascNounEntry(n.entry) ? "masc" : "fem");
|
||||
const gender = nounGender(n);
|
||||
const ps = number === "singular"
|
||||
? getInf(infs, "inflections", gender, false)
|
||||
: [
|
||||
|
|
|
@ -5,6 +5,7 @@ type EquativeClause = {
|
|||
subject: NounPhrase,
|
||||
predicate: NounPhrase | Compliment,
|
||||
tense: EquativeTense,
|
||||
negative?: boolean,
|
||||
};
|
||||
|
||||
type EquativeClauseOutput = {
|
||||
|
@ -17,6 +18,7 @@ type EquativeClauseOutput = {
|
|||
e: string,
|
||||
},
|
||||
ba: boolean,
|
||||
negative: boolean,
|
||||
equative: {
|
||||
ps: import("@lingdocs/pashto-inflector").Types.SentenceForm,
|
||||
e: string[],
|
||||
|
@ -25,23 +27,12 @@ type EquativeClauseOutput = {
|
|||
|
||||
type NounPhrase = Pronoun | Noun | Participle;
|
||||
|
||||
// TODO: better, simpler type here
|
||||
// The gender and number can be added, if it conflicts with the noun it will be ignored
|
||||
type Noun = {
|
||||
type: "unisex noun",
|
||||
number: NounNumber,
|
||||
gender: import("@lingdocs/pashto-inflector").Types.Gender,
|
||||
entry: UnisexNounEntry,
|
||||
possesor?: Noun,
|
||||
adjectives?: AdjectiveEntry[],
|
||||
} | {
|
||||
type: "plural noun",
|
||||
entry: PluralNounEntry<MascNounEntry | FemNounEntry>,
|
||||
possesor?: Noun,
|
||||
adjectives?: AdjectiveEntry[],
|
||||
} | {
|
||||
type: "singular noun",
|
||||
number: NounNumber,
|
||||
entry: SingularEntry<MascNounEntry | FemNounEntry>,
|
||||
type: "noun",
|
||||
entry: NounEntry,
|
||||
number?: NounNumber,
|
||||
gender?: import("@lingdocs/pashto-inflector").Types.Gender,
|
||||
possesor?: Noun,
|
||||
adjectives?: AdjectiveEntry[],
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue