possesive mini pronouns

This commit is contained in:
adueck 2024-02-08 22:33:24 +01:00
parent 5f356fdb63
commit db3bc8303b
4 changed files with 417 additions and 73 deletions

View File

@ -13,7 +13,7 @@ import { lookup, wordQuery } from "./lookup";
import { parseVP } from "./parse-vp"; import { parseVP } from "./parse-vp";
import { tokenizer } from "./tokenizer"; import { tokenizer } from "./tokenizer";
import { tlul } from "./irreg-verbs"; import { tlul } from "./irreg-verbs";
import { getPeople, removeKeys } from "./utils"; import { addShrunkenPossesor, getPeople, removeKeys } from "./utils";
const sarey = wordQuery("سړی", "noun"); const sarey = wordQuery("سړی", "noun");
const rasedul = wordQuery("رسېدل", "verb"); const rasedul = wordQuery("رسېدل", "verb");
@ -890,47 +890,95 @@ const tests: {
], ],
}, },
{ {
input: "سړی یې وویني", input: "سړی یې ووهي",
output: getPeople(3, "both").map((person) => ({ output: [
blocks: [ ...getPeople(3, "both").map<T.VPSelectionComplete>((person) => ({
{ blocks: [
key: 1, {
block: makeSubjectSelectionComplete({ key: 1,
type: "NP", block: makeSubjectSelectionComplete({
selection: makeNounSelection(sarey, undefined), type: "NP",
}), selection: makeNounSelection(sarey, undefined),
}),
},
{
key: 1,
block: makeObjectSelectionComplete({
type: "NP",
selection: makePronounSelection(person),
}),
},
],
verb: {
type: "verb",
verb: wahul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "subjunctiveVerb",
canChangeVoice: true,
isCompound: false,
voice: "active",
}, },
{ externalComplement: undefined,
key: 1, form: {
block: makeObjectSelectionComplete({ removeKing: false,
type: "NP", shrinkServant: true,
selection: makePronounSelection(person),
}),
}, },
], })),
verb: { ...getPeople(3, "both").flatMap<T.VPSelectionComplete>((person) =>
type: "verb", getPeople(3, "both").map<T.VPSelectionComplete>((person2) => ({
verb: leedul, blocks: [
transitivity: "transitive", {
canChangeTransitivity: false, key: 1,
canChangeStatDyn: false, block: makeSubjectSelectionComplete({
negative: false, type: "NP",
tense: "subjunctiveVerb", selection: makePronounSelection(person),
canChangeVoice: true, }),
isCompound: false, },
voice: "active", {
}, key: 1,
externalComplement: undefined, block: makeObjectSelectionComplete(
form: { addShrunkenPossesor(
removeKing: false, {
shrinkServant: true, type: "NP",
}, selection: makeNounSelection(sarey, undefined),
})), },
person2
)
),
},
],
verb: {
type: "verb",
verb: wahul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "subjunctiveVerb",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: true,
shrinkServant: false,
},
}))
),
],
}, },
{ {
input: "سړی مو ویني", input: "سړی مو ویني",
output: [...getPeople(1, "pl"), ...getPeople(2, "pl")].map( output: [
(person) => ({ // the man sees you/us
...[
...getPeople(1, "pl"),
...getPeople(2, "pl"),
].map<T.VPSelectionComplete>((person) => ({
blocks: [ blocks: [
{ {
key: 1, key: 1,
@ -964,13 +1012,98 @@ const tests: {
removeKing: false, removeKing: false,
shrinkServant: true, shrinkServant: true,
}, },
}) })),
), // your/our man sees
}, ...[
{ ...getPeople(1, "pl"),
input: "سړي مې واهه", ...getPeople(2, "pl"),
output: [], ].map<T.VPSelectionComplete>((person) => ({
error: true, blocks: [
{
key: 1,
block: makeSubjectSelectionComplete(
addShrunkenPossesor(
{
type: "NP",
selection: makeNounSelection(sarey, undefined),
},
person
)
),
},
{
key: 1,
block: {
type: "objectSelection",
selection: T.Person.ThirdPlurMale,
},
},
],
verb: {
type: "verb",
verb: leedul,
transitivity: "grammatically transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "presentVerb",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: false,
shrinkServant: false,
},
})),
// they/he sees your/our man
...[
...getPeople(1, "pl"),
...getPeople(2, "pl"),
].flatMap<T.VPSelectionComplete>((possPers) =>
getPeople(3, "both").map<T.VPSelectionComplete>((subjPers) => ({
blocks: [
{
key: 1,
block: makeSubjectSelectionComplete({
type: "NP",
selection: makePronounSelection(subjPers),
}),
},
{
key: 1,
block: makeObjectSelectionComplete(
addShrunkenPossesor(
{
type: "NP",
selection: makeNounSelection(sarey, undefined),
},
possPers
)
),
},
],
verb: {
type: "verb",
verb: leedul,
transitivity: "transitive",
canChangeTransitivity: false,
canChangeStatDyn: false,
negative: false,
tense: "presentVerb",
canChangeVoice: true,
isCompound: false,
voice: "active",
},
externalComplement: undefined,
form: {
removeKing: true,
shrinkServant: false,
},
}))
),
],
}, },
], ],
}, },

View File

@ -1,6 +1,8 @@
import * as T from "../../../types"; import * as T from "../../../types";
import { import {
addShrunkenPossesor,
bindParseResult, bindParseResult,
canTakeShrunkenPossesor,
isNeg, isNeg,
isNonOoPh, isNonOoPh,
isPH, isPH,
@ -27,6 +29,11 @@ import { isSecondPerson, personToGenNum } from "../misc-helpers";
import { equals, zip } from "rambda"; import { equals, zip } from "rambda";
import { isImperativeTense } from "../type-predicates"; import { isImperativeTense } from "../type-predicates";
// to hide equatives type-doubling issue // to hide equatives type-doubling issue
// TODO: THESE SHOULD ERROR!!
// ماشومانې لاړل
// ماشومان لاړلې
// TODO: problem with 3rd pers seng verb endings اواز مې دې واورېده
// TODO: word query for kawul/kedul/stat/dyn // TODO: word query for kawul/kedul/stat/dyn
@ -43,33 +50,39 @@ export function parseVP(
return []; return [];
} }
const blocks = parseBlocks(tokens, lookup, [], []); const blocks = parseBlocks(tokens, lookup, [], []);
return bindParseResult(blocks, (tokens, { blocks, kids }) => { const blocksWPossPossibilities = createPossesivePossibilities(blocks);
const ba = kids.some((k) => k === "ba"); return bindParseResult(
const miniPronouns = getMiniPronouns(kids); blocksWPossPossibilities,
const npsAndAps = blocks.filter( (tokens, { blocks, kids }) => {
(x): x is T.ParsedNP | T.APSelection => x.type === "NP" || x.type === "AP" const ba = kids.some((k) => k === "ba");
); const miniPronouns = getMiniPronouns(kids);
const verbSection = blocks.findIndex(startsVerbSection); const npsAndAps = blocks.filter(
// TODO: would be nice if this could pass error messages about the (x): x is T.ParsedNP | T.APSelection =>
// negative being out of place etc x.type === "NP" || x.type === "AP"
if (!verbSectionOK(blocks.slice(verbSection))) { );
return []; const verbSection = blocks.findIndex(startsVerbSection);
// TODO: would be nice if this could pass error messages about the
// negative being out of place etc
if (!verbSectionOK(blocks.slice(verbSection))) {
return [];
}
const tenses = getTenses(blocks, ba);
// TODO get errors from the get tenses (perfect verbs not agreeing)
return tenses.flatMap(
({ tense, person, transitivities, negative, verb }) =>
finishPossibleVPSs({
tense,
transitivities,
npsAndAps,
miniPronouns,
tokens,
negative,
verb,
person,
})
);
} }
const tenses = getTenses(blocks, ba); );
// TODO get errors from the get tenses (perfect verbs not agreeing)
return tenses.flatMap(({ tense, person, transitivities, negative, verb }) =>
finishPossibleVPSs({
tense,
transitivities,
npsAndAps,
miniPronouns,
tokens,
negative,
verb,
person,
})
);
});
} }
function getTenses( function getTenses(
@ -487,6 +500,9 @@ function finishTransitive({
} }
} }
} else { } else {
if (miniPronouns.length > 1) {
errors.push({ message: "unknown mini-pronoun" });
}
if (np.inflected) { if (np.inflected) {
errors.push({ errors.push({
message: !isPast message: !isPast
@ -553,6 +569,9 @@ function finishTransitive({
})); }));
}); });
} else { } else {
const miniPronErrors: T.ParseError[] = miniPronouns.length
? [{ message: "unknown mini-pronoun" }]
: [];
if (isPast) { if (isPast) {
return ( return (
[ [
@ -598,7 +617,7 @@ function finishTransitive({
shrinkServant: false, shrinkServant: false,
}, },
} as T.VPSelectionComplete, } as T.VPSelectionComplete,
errors [...miniPronErrors, ...errors]
); );
}); });
} else { } else {
@ -657,7 +676,7 @@ function finishTransitive({
shrinkServant: false, shrinkServant: false,
}, },
} as T.VPSelectionComplete, } as T.VPSelectionComplete,
errors [...miniPronErrors, ...errors]
); );
}); });
} }
@ -1033,3 +1052,137 @@ function mapOutnpsAndAps(
} }
}); });
} }
function createPossesivePossibilities(
blocks: T.ParseResult<{
kids: T.ParsedKid[];
blocks: T.ParsedBlock[];
}>[]
): T.ParseResult<{
kids: T.ParsedKid[];
blocks: T.ParsedBlock[];
}>[] {
// Case 1: no mini pronouns
// Case 2: 1 mini pronoun
// - don't use any as possesive
// Case 3: 2 mini pronouns
// - don't use any as possesive
// - use first as possesive
// - use second as possesive
// - use both as possesive
function pullOutMiniPronoun(
body: {
kids: T.ParsedKid[];
blocks: T.ParsedBlock[];
},
pos: 0 | 1
): {
adjusted: {
kids: T.ParsedKid[];
blocks: T.ParsedBlock[];
};
miniPronoun: T.ParsedMiniPronoun;
} {
const miniPronoun = getMiniPronouns(body.kids)[pos];
if (!miniPronoun) {
throw new Error("tried to pull out non-existent mini-pronoun");
}
return {
miniPronoun,
adjusted: {
kids: body.kids.filter((x) => x !== miniPronoun),
blocks: body.blocks,
},
};
}
function spreadOutPoss(
body: {
kids: T.ParsedKid[];
blocks: T.ParsedBlock[];
},
pos: 0 | 1
): {
kids: T.ParsedKid[];
blocks: T.ParsedBlock[];
}[] {
const { miniPronoun, adjusted } = pullOutMiniPronoun(body, pos);
const people = getPeopleFromMiniPronouns([miniPronoun]);
// TODO: turn into reduce?
// TODO: allow possesives for sandwiches
return adjusted.blocks
.flatMap((x, i) => {
if (
(x.type === "NP" && canTakeShrunkenPossesor(x.selection)) ||
(x.type === "AP" && canTakeShrunkenPossesor(x))
) {
return addPossesiveAtIndex(people, adjusted.blocks, i);
} else {
return [];
}
})
.map((xb) => ({
kids: adjusted.kids,
blocks: xb,
}));
}
function addPossesiveAtIndex(
people: T.Person[],
blocks: T.ParsedBlock[],
i: number
): T.ParsedBlock[][] {
return people.map((person) => {
return blocks.map((x, j) => {
if (i !== j) return x;
// TODO: this is redundant ?
if (x.type === "NP" && canTakeShrunkenPossesor(x.selection)) {
return {
...x,
selection: addShrunkenPossesor(x.selection, person),
};
} else if (x.type === "AP" && canTakeShrunkenPossesor(x)) {
return addShrunkenPossesor(x, person);
} else {
throw new Error(
"improper index for adding possesor - addPossesiveAtIndex"
);
}
});
});
}
return blocks.flatMap((b) => {
const miniPronouns = getMiniPronouns(b.body.kids);
if (miniPronouns.length === 0) {
return [
{
tokens: b.tokens,
body: b.body,
errors: b.errors,
},
];
} else if (miniPronouns.length === 1) {
const withFirstMiniAsPossesive = spreadOutPoss(b.body, 0);
return [b.body, ...withFirstMiniAsPossesive].map((x) => ({
tokens: b.tokens,
body: x,
errors: b.errors,
}));
} else {
const withFirstMiniAsPossesive = spreadOutPoss(b.body, 0);
const withSecondMiniAsPossesive = spreadOutPoss(b.body, 1);
return [
// using none of the mini-pronouns as possesives
b.body,
// using the first mini-pronoun as a possesive
...withFirstMiniAsPossesive,
// using the second mini-pronoun as a prossesive
...withSecondMiniAsPossesive,
// using both mini pronouns as possesives
...withFirstMiniAsPossesive.flatMap((x) => spreadOutPoss(x, 0)),
].map((x) => ({
tokens: b.tokens,
body: x,
errors: b.errors,
}));
}
});
}

View File

@ -174,3 +174,61 @@ export function startsVerbSection(b: T.ParsedBlock): boolean {
b.type === "negative" b.type === "negative"
); );
} }
export function canTakeShrunkenPossesor(
block: T.NPSelection | T.APSelection
): boolean {
if (block.type === "NP") {
return block.selection.type !== "pronoun" && !block.selection.possesor;
}
if (block.selection.type === "sandwich") {
return canTakeShrunkenPossesor(block.selection.inside);
}
return false;
}
export function addShrunkenPossesor(
b: T.NPSelection,
person: T.Person
): T.NPSelection;
export function addShrunkenPossesor(
b: T.APSelection,
person: T.Person
): T.APSelection;
export function addShrunkenPossesor(
b: T.NPSelection | T.APSelection,
person: T.Person
): T.NPSelection | T.APSelection {
if (b.selection.type === "adverb" || b.selection.type === "pronoun") {
throw new Error("cannot add shrunken possesor");
}
if (b.type === "AP") {
return {
...b,
selection: {
...b.selection,
inside: addShrunkenPossesor(b.selection.inside, person),
},
};
}
if (b.selection.possesor) {
throw new Error("cannot add another possesor");
}
return {
...b,
selection: {
...b.selection,
possesor: {
shrunken: true,
np: {
type: "NP",
selection: {
type: "pronoun",
distance: "far",
person,
},
},
},
},
};
}

View File

@ -252,7 +252,7 @@ function pronounPossEng(p: T.Person): string {
if (p === T.Person.ThirdSingFemale) { if (p === T.Person.ThirdSingFemale) {
return "her/its"; return "her/its";
} }
return `their ${gend(p)}`; return `their (${gend(p)})`;
} }
export function getEnglishFromRendered( export function getEnglishFromRendered(