Skip to content

Commit

Permalink
Imagine that incorporated objects move to end up under V
Browse files Browse the repository at this point in the history
That is, in the deep structure they start in the usual object position, then they move under V and follow V all the way to the start of the TP to produce the surface structure.
  • Loading branch information
robintown committed May 23, 2024
1 parent 7192824 commit 4d22fd3
Show file tree
Hide file tree
Showing 5 changed files with 108 additions and 56 deletions.
53 changes: 29 additions & 24 deletions src/grammar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -173,27 +173,33 @@ const grammar: Grammar = {
{"name": "AspP_main", "symbols": ["Aspcon", "vP_main"], "postprocess": makeBranch('AspP')},
{"name": "AspP_sub", "symbols": ["Aspcon", "vP_sub"], "postprocess": makeBranch('AspP')},
{"name": "AspPdet", "symbols": ["Aspcon", "vPdet"], "postprocess": makeBranch('AspP')},
{"name": "vP_main$ebnf$1", "symbols": []},
{"name": "vP_main$ebnf$1", "symbols": ["vP_main$ebnf$1", "AdjunctPcon"], "postprocess": (d) => d[0].concat([d[1]])},
{"name": "vP_main$ebnf$2$subexpression$1$ebnf$1", "symbols": ["VocArgument"]},
{"name": "vP_main$ebnf$2$subexpression$1$ebnf$1", "symbols": ["vP_main$ebnf$2$subexpression$1$ebnf$1", "VocArgument"], "postprocess": (d) => d[0].concat([d[1]])},
{"name": "vP_main$ebnf$2$subexpression$1$ebnf$2", "symbols": []},
{"name": "vP_main$ebnf$2$subexpression$1$ebnf$2", "symbols": ["vP_main$ebnf$2$subexpression$1$ebnf$2", "AdjunctPcon"], "postprocess": (d) => d[0].concat([d[1]])},
{"name": "vP_main$ebnf$2$subexpression$1", "symbols": ["vP_main$ebnf$2$subexpression$1$ebnf$1", "vP_main$ebnf$2$subexpression$1$ebnf$2"]},
{"name": "vP_main$ebnf$2", "symbols": ["vP_main$ebnf$2$subexpression$1"], "postprocess": id},
{"name": "vP_main$ebnf$2", "symbols": [], "postprocess": () => null},
{"name": "vP_main", "symbols": ["Serial", "vP_main$ebnf$1", "vP_main$ebnf$2"], "postprocess": makevP_main},
{"name": "vP_sub$ebnf$1", "symbols": []},
{"name": "vP_sub$ebnf$1", "symbols": ["vP_sub$ebnf$1", "AdjunctPcon"], "postprocess": (d) => d[0].concat([d[1]])},
{"name": "vP_sub$ebnf$2$subexpression$1$ebnf$1", "symbols": ["VocArgument"]},
{"name": "vP_sub$ebnf$2$subexpression$1$ebnf$1", "symbols": ["vP_sub$ebnf$2$subexpression$1$ebnf$1", "VocArgument"], "postprocess": (d) => d[0].concat([d[1]])},
{"name": "vP_sub$ebnf$2$subexpression$1$ebnf$2", "symbols": []},
{"name": "vP_sub$ebnf$2$subexpression$1$ebnf$2", "symbols": ["vP_sub$ebnf$2$subexpression$1$ebnf$2", "AdjunctPcon"], "postprocess": (d) => d[0].concat([d[1]])},
{"name": "vP_sub$ebnf$2$subexpression$1", "symbols": ["vP_sub$ebnf$2$subexpression$1$ebnf$1", "vP_sub$ebnf$2$subexpression$1$ebnf$2"]},
{"name": "vP_sub$ebnf$2", "symbols": ["vP_sub$ebnf$2$subexpression$1"], "postprocess": id},
{"name": "vP_sub$ebnf$2", "symbols": [], "postprocess": () => null},
{"name": "vP_sub", "symbols": ["Serial", "vP_sub$ebnf$1", "vP_sub$ebnf$2"], "postprocess": makevP_sub},
{"name": "vPdet", "symbols": ["Serialdet"], "postprocess": makevPdet},
{"name": "vP_main$ebnf$1", "symbols": ["Argincorp"], "postprocess": id},
{"name": "vP_main$ebnf$1", "symbols": [], "postprocess": () => null},
{"name": "vP_main$ebnf$2", "symbols": []},
{"name": "vP_main$ebnf$2", "symbols": ["vP_main$ebnf$2", "AdjunctPcon"], "postprocess": (d) => d[0].concat([d[1]])},
{"name": "vP_main$ebnf$3$subexpression$1$ebnf$1", "symbols": ["VocArgument"]},
{"name": "vP_main$ebnf$3$subexpression$1$ebnf$1", "symbols": ["vP_main$ebnf$3$subexpression$1$ebnf$1", "VocArgument"], "postprocess": (d) => d[0].concat([d[1]])},
{"name": "vP_main$ebnf$3$subexpression$1$ebnf$2", "symbols": []},
{"name": "vP_main$ebnf$3$subexpression$1$ebnf$2", "symbols": ["vP_main$ebnf$3$subexpression$1$ebnf$2", "AdjunctPcon"], "postprocess": (d) => d[0].concat([d[1]])},
{"name": "vP_main$ebnf$3$subexpression$1", "symbols": ["vP_main$ebnf$3$subexpression$1$ebnf$1", "vP_main$ebnf$3$subexpression$1$ebnf$2"]},
{"name": "vP_main$ebnf$3", "symbols": ["vP_main$ebnf$3$subexpression$1"], "postprocess": id},
{"name": "vP_main$ebnf$3", "symbols": [], "postprocess": () => null},
{"name": "vP_main", "symbols": ["Serial", "vP_main$ebnf$1", "vP_main$ebnf$2", "vP_main$ebnf$3"], "postprocess": makevP_main},
{"name": "vP_sub$ebnf$1", "symbols": ["Argincorp"], "postprocess": id},
{"name": "vP_sub$ebnf$1", "symbols": [], "postprocess": () => null},
{"name": "vP_sub$ebnf$2", "symbols": []},
{"name": "vP_sub$ebnf$2", "symbols": ["vP_sub$ebnf$2", "AdjunctPcon"], "postprocess": (d) => d[0].concat([d[1]])},
{"name": "vP_sub$ebnf$3$subexpression$1$ebnf$1", "symbols": ["VocArgument"]},
{"name": "vP_sub$ebnf$3$subexpression$1$ebnf$1", "symbols": ["vP_sub$ebnf$3$subexpression$1$ebnf$1", "VocArgument"], "postprocess": (d) => d[0].concat([d[1]])},
{"name": "vP_sub$ebnf$3$subexpression$1$ebnf$2", "symbols": []},
{"name": "vP_sub$ebnf$3$subexpression$1$ebnf$2", "symbols": ["vP_sub$ebnf$3$subexpression$1$ebnf$2", "AdjunctPcon"], "postprocess": (d) => d[0].concat([d[1]])},
{"name": "vP_sub$ebnf$3$subexpression$1", "symbols": ["vP_sub$ebnf$3$subexpression$1$ebnf$1", "vP_sub$ebnf$3$subexpression$1$ebnf$2"]},
{"name": "vP_sub$ebnf$3", "symbols": ["vP_sub$ebnf$3$subexpression$1"], "postprocess": id},
{"name": "vP_sub$ebnf$3", "symbols": [], "postprocess": () => null},
{"name": "vP_sub", "symbols": ["Serial", "vP_sub$ebnf$1", "vP_sub$ebnf$2", "vP_sub$ebnf$3"], "postprocess": makevP_sub},
{"name": "vPdet$ebnf$1", "symbols": ["Argincorp"], "postprocess": id},
{"name": "vPdet$ebnf$1", "symbols": [], "postprocess": () => null},
{"name": "vPdet", "symbols": ["Serialdet", "vPdet$ebnf$1"], "postprocess": makevPdet},
{"name": "AdjunctP", "symbols": ["Adjunct", "Serial", "Argument"], "postprocess": makeAdjunctPT},
{"name": "AdjunctP", "symbols": ["Adjunct", "Serial"], "postprocess": makeAdjunctPI},
{"name": "Serial$ebnf$1", "symbols": []},
Expand All @@ -203,8 +209,6 @@ const grammar: Grammar = {
{"name": "V1orKi", "symbols": ["Ki"], "postprocess": id},
{"name": "Serialdet", "symbols": ["Serial"], "postprocess": id},
{"name": "Serialdet", "symbols": [], "postprocess": makeEmptySerial()},
{"name": "VPincorp", "symbols": ["V", "DPincorp"], "postprocess": makeBranch('VP')},
{"name": "VPincorp", "symbols": ["V", "CPincorp"], "postprocess": makeBranch('VP')},
{"name": "DPincorp$ebnf$1", "symbols": []},
{"name": "DPincorp$ebnf$1", "symbols": ["DPincorp$ebnf$1", "Free"], "postprocess": (d) => d[0].concat([d[1]])},
{"name": "DPincorp", "symbols": [(lexer.has("incorporated_pronoun") ? {type: "incorporated_pronoun"} : incorporated_pronoun), "DPincorp$ebnf$1"], "postprocess": makeLeaf('DP')},
Expand All @@ -213,6 +217,8 @@ const grammar: Grammar = {
{"name": "VPoiv", "symbols": ["Voiv", "DPcon"], "postprocess": makeBranch('VP')},
{"name": "Argument", "symbols": ["DPcon"], "postprocess": id},
{"name": "Argument", "symbols": ["CPargcon"], "postprocess": id},
{"name": "Argincorp", "symbols": ["DPincorp"], "postprocess": id},
{"name": "Argincorp", "symbols": ["CPincorp"], "postprocess": id},
{"name": "DPcon", "symbols": ["DProi"], "postprocess": id},
{"name": "DPcon", "symbols": ["DProi", "Conjunction", "DPcon"], "postprocess": makeConn},
{"name": "DPcon", "symbols": ["DProi", "ConjunctionT1", "CPargcon"], "postprocess": makeConn},
Expand Down Expand Up @@ -242,7 +248,6 @@ const grammar: Grammar = {
{"name": "AdjunctPcon", "symbols": ["AdjunctPfoc", "Conjunction", "AdjunctPcon"], "postprocess": makeConn},
{"name": "AdjunctPfoc", "symbols": ["AdjunctP"], "postprocess": id},
{"name": "AdjunctPfoc", "symbols": ["Focus", "AdjunctP"], "postprocess": makeBranch('FocusP')},
{"name": "Vlast", "symbols": ["VPincorp"], "postprocess": id},
{"name": "Vlast", "symbols": ["VPoiv"], "postprocess": id},
{"name": "Vlast", "symbols": ["Verb", "ConjunctionT1", "Vlast"], "postprocess": makeConn},
{"name": "Vlast", "symbols": ["Verb"], "postprocess": id},
Expand Down
10 changes: 9 additions & 1 deletion src/semantics/denote.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { test, expect } from 'vitest';
import { parse } from '../modes/parse';
import { recover } from '../syntax/recover';
import { denote } from './denote';
import { Expr } from './model';
import { toPlainText } from './render';
import { Impossible } from '../core/error';
import { freeVariableUsages } from './operations';
Expand Down Expand Up @@ -415,3 +414,12 @@ test('subclauses open a new scope', () => {
"\"ASSERT(λ𝘸. (∃𝘦. τ(𝘦) ⊆ t'''' ∧ gaı.𝘸(b, a)(𝘦) | (∃𝘦. τ(𝘦) ⊆ t''' ∧ poq.𝘸(b)(𝘦)) ∧ ∀.SING 𝘹 : ∃𝘦. τ(𝘦) ⊆ t' ∧ rua.𝘸(𝘹)(𝘦). (∃𝘦. τ(𝘦) ⊆ t'' ∧ cho.𝘸(b, 𝘹)(𝘦) | inanimate(𝘹)) | ∃𝘦. τ(𝘦) ⊆ t ∧ rua.𝘸(a)(𝘦))) | animate(b) | inanimate(a)\"",
);
});

test('incorporated object scopes under other arguments', () => {
expect(d('Joe tû raı sía poq')).toMatchInlineSnapshot(
"\"ASSERT(λ𝘸. ¬∃𝘹 : ∃𝘦. τ(𝘦) ⊆ t' ∧ poq.𝘸(𝘹)(𝘦). (∀.SING 𝘺 : ∃𝘦. τ(𝘦) ⊆ t ∧ raı.𝘸(𝘺)(𝘦). ∃𝘦. τ(𝘦) ⊆ t'' ∧ joe.𝘸(𝘹, 𝘺)(𝘦) | animate(𝘹)))\"",
);
expect(d('Do sâ kue sá poq jí')).toMatchInlineSnapshot(
"\"ASSERT(λ𝘸. ∃𝘹 : ∃𝘦. τ(𝘦) ⊆ t' ∧ poq.𝘸(𝘹)(𝘦). (∃𝘺 : ∃𝘦. τ(𝘦) ⊆ t ∧ kue.𝘸(𝘺)(𝘦). (∃𝘦. τ(𝘦) ⊆ t'' ∧ AGENT(𝘦)(𝘸) = 𝘹 ∧ do.𝘸(jí, 𝘺)(𝘦) | inanimate(𝘺)) | animate(𝘹)))\"",
);
});
44 changes: 35 additions & 9 deletions src/syntax/serial.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Impossible, Ungrammatical, Unimplemented } from '../core/error';
import { splitNonEmpty } from '../core/misc';
import { Tone } from '../morphology/tone';
import {
Branch,
Label,
Expand Down Expand Up @@ -302,6 +303,29 @@ function attachAdjective(VP: Tree, kivP: KivP): Tree {
};
}

/**
* Determines whether an argument is an incorporated object.
*/
function isArgIncorp(dp: Tree): boolean {
let head: Leaf;
if ('word' in dp) {
head = dp;
} else {
assertBranch(dp);
assertLeaf(dp.left);
if (dp.left.word.covert) {
const cp = dp.right;
assertBranch(cp);
assertLeaf(cp.left);
head = cp.left;
} else {
head = dp.left;
}
}

return !head.word.covert && head.word.tone === Tone.T4;
}

/**
* Turn the given *Serial and terms into a proper 𝘷P, by:
*
Expand Down Expand Up @@ -348,19 +372,21 @@ export function fixSerial(
}
if (0 !== end) segments.unshift(children.slice(0, end));

let earlyAdjuncts = [];
let args = [];
let lateAdjuncts = [];
let earlyAdjuncts: Tree[] = [];
let args: Tree[] = [];
let argIncorp: Tree | null = null;
let lateAdjuncts: Tree[] = [];
for (const term of terms) {
const label = effectiveLabel(term);
if (label === 'DP' || label === 'CP') {
args.push(term);
} else if (args.length) {
lateAdjuncts.push(term);
if (term.label === 'DP' && isArgIncorp(term)) {
argIncorp = term;
} else {
earlyAdjuncts.push(term);
const label = effectiveLabel(term);
if (label === 'DP') args.push(term);
else if (args.length) lateAdjuncts.push(term);
else earlyAdjuncts.push(term);
}
}
if (argIncorp !== null) args.push(argIncorp);

// Now the first segment is the serial verb and everything after it is serial adjectives.
let { ki, vP } = segmentToKivP(segments[0], args, newCoindex);
Expand Down
13 changes: 5 additions & 8 deletions src/toaq.kuna.ne
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,10 @@ AspP<S> -> Aspcon vP<S> {% makeBranch('AspP') %}
AspPdet -> Aspcon vPdet {% makeBranch('AspP') %}

# tua hao tî kúe jí súq râo níchaq
vP<S> -> Serial AdjunctPcon:* (VocArgument:+ AdjunctPcon:*):? {% makevP<S> %}
vP<S> -> Serial Argincorp:? AdjunctPcon:* (VocArgument:+ AdjunctPcon:*):? {% makevP<S> %}

# (sá) tua hao
vPdet -> Serialdet {% makevPdet %}
# (sá) leo hamla lô raı
vPdet -> Serialdet Argincorp:? {% makevPdet %}

# ^ tı kúe
AdjunctP -> Adjunct Serial Argument {% makeAdjunctPT %}
Expand All @@ -168,10 +168,6 @@ Serialdet -> Serial {% id %}
# (sá) ∅
Serialdet -> null {% makeEmptySerial() %}

# hao sâ ...
VPincorp -> V DPincorp {% makeBranch('VP') %}
# hao ꝡâ ...
VPincorp -> V CPincorp {% makeBranch('VP') %}
# jî
DPincorp -> %incorporated_pronoun Free:* {% makeLeaf('DP') %}
# hụ̂ꝡa
Expand All @@ -183,6 +179,8 @@ VPoiv -> Voiv DPcon {% makeBranch('VP') %}

Argument -> DPcon {% id %}
Argument -> CPargcon {% id %}
Argincorp -> DPincorp {% id %}
Argincorp -> CPincorp {% id %}

DPcon -> DProi {% id %}
DPcon -> DProi Conjunction DPcon {% makeConn %}
Expand Down Expand Up @@ -213,7 +211,6 @@ AdjunctPcon -> AdjunctPfoc {% id %}
AdjunctPcon -> AdjunctPfoc Conjunction AdjunctPcon {% makeConn %}
AdjunctPfoc -> AdjunctP {% id %}
AdjunctPfoc -> Focus AdjunctP {% makeBranch('FocusP') %}
Vlast -> VPincorp {% id %}
Vlast -> VPoiv {% id %}
Vlast -> Verb ConjunctionT1 Vlast {% makeConn %}
Vlast -> Verb {% id %}
Expand Down
44 changes: 30 additions & 14 deletions src/tree/productions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,14 +166,20 @@ export function makeSerial(
}

export function makevP(
[serial, adjpsL, rest]: [Tree, Tree[], [Tree[], Tree[]] | null],
[serial, argIncorp, adjpsL, rest]: [
Tree,
Tree | null,
Tree[],
[Tree[], Tree[]] | null,
],
location: number,
reject: Object,
depth: 'main' | 'sub',
) {
rest ??= [[], []];
let [args, adjpsR] = rest;
args = args.filter(x => x.label !== 'VocativeP');
const argsL = argIncorp === null ? [] : [argIncorp];
let [argsR, adjpsR] = rest ?? [[], []];
argsR = argsR.filter(x => x.label !== 'VocativeP');
const args = [...argsL, ...argsR];

const arity = (serial as any).arity;
if (arity !== undefined) {
Expand All @@ -191,42 +197,52 @@ export function makevP(
// Disallow adjuncts that could have gone in a subclause:
if (
adjpsR.length &&
args.length &&
endsInClauseBoundary(args[args.length - 1])
argsR.length &&
endsInClauseBoundary(argsR[argsR.length - 1])
) {
return reject;
}
if (adjpsL.length && argIncorp !== null && endsInClauseBoundary(argIncorp)) {
return reject;
}

return {
label: '*𝘷P',
children: [serial, ...adjpsL, ...args, ...adjpsR],
children: [serial, ...argsL, ...adjpsL, ...argsR, ...adjpsR],
};
}

export function makevP_main(
args: [Tree, Tree[], [Tree[], Tree[]] | null],
args: [Tree, Tree | null, Tree[], [Tree[], Tree[]] | null],
location: number,
reject: Object,
) {
return makevP(args, location, reject, 'main');
}

export function makevP_sub(
args: [Tree, Tree[], [Tree[], Tree[]] | null],
args: [Tree, Tree | null, Tree[], [Tree[], Tree[]] | null],
location: number,
reject: Object,
) {
return makevP(args, location, reject, 'sub');
}

export function makevPdet([serial]: [Tree], location: number, reject: Object) {
export function makevPdet(
[serial, argIncorp]: [Tree, Tree | null],
location: number,
reject: Object,
) {
const arity = (serial as any).arity;
if (arity === 0) {
return reject;
}
if (arity < (argIncorp === null ? 1 : 2)) return reject;

return {
label: '*𝘷P',
children: [serial, { label: 'DP', word: { covert: true, value: 'PRO' } }],
children: [
serial,
...(argIncorp === null ? [] : [argIncorp]),
{ label: 'DP', word: { covert: true, value: 'PRO' } },
],
};
}

Expand Down

0 comments on commit 4d22fd3

Please sign in to comment.