add support for multiple epochs with dependencies

This commit is contained in:
Sorrel Bri 2020-02-21 15:17:59 -08:00
parent 471759a7cf
commit 31fab0ea57
2 changed files with 84 additions and 20 deletions

View file

@ -204,8 +204,10 @@ const transformPhoneme = (phoneme, newFeatures, features) => {
const transformLexemeInitial = (newLexeme, pre, post, position, phoneme, index, lexemeBundle, newFeatures, features) => { const transformLexemeInitial = (newLexeme, pre, post, position, phoneme, index, lexemeBundle, newFeatures, features) => {
if (index !== pre.length - 1) return [...newLexeme, phoneme]; if (index !== pre.length - 1) return [...newLexeme, phoneme];
if (!isEnvironmentBoundByRule([phoneme], position)) return [...newLexeme, phoneme]; if (!isEnvironmentBoundByRule([phoneme], position)) return [...newLexeme, phoneme];
if (!isEnvironmentBoundByRule(lexemeBundle.slice(index, index + post.length), post)) return [...newLexeme, phoneme]; if (!isEnvironmentBoundByRule(lexemeBundle.slice(index + position.length, index + post.length + position.length), post)) return [...newLexeme, phoneme];
const newPhoneme = transformPhoneme(phoneme, newFeatures[0], features); const newPhoneme = transformPhoneme(phoneme, newFeatures[0], features);
// if deletion occurs
if (!newPhoneme.grapheme) return [ ...newLexeme] ;
return [...newLexeme, newPhoneme]; return [...newLexeme, newPhoneme];
} }
@ -214,6 +216,8 @@ const transformLexemeCoda = (newLexeme, pre, post, position, phoneme, index, lex
if (!isEnvironmentBoundByRule(lexemeBundle.slice(index - pre.length, index), pre)) return [...newLexeme, phoneme]; if (!isEnvironmentBoundByRule(lexemeBundle.slice(index - pre.length, index), pre)) return [...newLexeme, phoneme];
if (!isEnvironmentBoundByRule([phoneme], position)) return [...newLexeme, phoneme]; if (!isEnvironmentBoundByRule([phoneme], position)) return [...newLexeme, phoneme];
const newPhoneme = transformPhoneme(phoneme, newFeatures[0], features); const newPhoneme = transformPhoneme(phoneme, newFeatures[0], features);
// if deletion occurs
if (!newPhoneme.grapheme) return [ ...newLexeme] ;
return [...newLexeme, newPhoneme]; return [...newLexeme, newPhoneme];
} }
@ -245,26 +249,33 @@ const transformLexicon = lexiconBundle =>
)) ))
const getGraphemeFromEntry = ([_, phoneme]) => phoneme.grapheme const getGraphemeFromEntry = ([_, phoneme]) => phoneme.grapheme
const stringifyResults = lexemeBundle => Object.entries(lexemeBundle).map(getGraphemeFromEntry).join('') const stringifyResults = passResults => {
const lexicon = passResults.lexicon.map(lexeme => lexeme.map(phoneme => phoneme.grapheme).join(''))
return {...passResults, lexicon }
}
export const run = (state: stateType, action: resultsAction): stateType => { export const run = (state: stateType, action: resultsAction): stateType => {
// TODO iterate through each epoch // TODO iterate through each epoch
try { try {
const epoch = state.epochs[0]; const passResults = state.epochs.reduce((results, epoch, _) => {
const { phones, lexicon, features } = state;
const { phones, features } = state;
const lexicon = epoch.parent ? results.find(result => result.pass === epoch.parent).lexicon : state.lexicon
const ruleBundle = decomposeRules(epoch, phones); const ruleBundle = decomposeRules(epoch, phones);
const lexiconBundle = formBundleFromLexicon(lexicon)(phones); const lexiconBundle = epoch.parent ? lexicon : formBundleFromLexicon(lexicon)(phones);
const passResults = transformLexicon(lexiconBundle)(ruleBundle)(features); const passResults = transformLexicon(lexiconBundle)(ruleBundle)(features)
const stringifiedPassResults = passResults.map(stringifyResults);
const pass = { const pass = {
pass: epoch.name, pass: epoch.name,
lexicon: stringifiedPassResults lexicon: passResults
} }
if ( epoch.parent ) pass.parent = epoch.parent;
return {...state, results: [pass] } return [...results, pass];
}, []);
const results = passResults.map(stringifyResults);
return {...state, results }
} catch (err) { } catch (err) {
console.log(err)
return err; return err;
} }
} }

View file

@ -134,20 +134,73 @@ describe('Results', () => {
]); ]);
}); });
// it('results returned through sixth sound change rule (multi-phoneme target)', () => {
// const action = {type: 'RUN'};
// state = initState(6)
// expect(stateReducer(state, action).results).toEqual([
// {
// pass: 'epoch 1',
// lexicon: [
// 'annu', 'anta', 'ant', 'annu', 'tʰan', 'nnu'
// ]
// }
// ]);
// });
it('results returned through sixth sound change rule (multi-phoneme target)', () => { it('results returned for multiple epochs without parent epoch', () => {
const action = {type: 'RUN'}; const action = {type: 'RUN'};
state = initState(5) state = initState(5);
const newEpoch = {
name: 'epoch 2',
changes: [
'[+ sonorant ]>0/#_.',
'n>0/#_n'
]
}
state.epochs = [ ...state.epochs, newEpoch ]
expect(stateReducer(state, action).results).toEqual([ expect(stateReducer(state, action).results).toEqual([
{ {
pass: 'epoch 1', pass: 'epoch 1',
lexicon: [ lexicon: [
'annu', 'anta', 'ant', 'annu', 'tʰan', 'nnu' 'annu', 'anat', 'ant', 'annu', 'tʰan', 'nnu'
]
},
{
pass: 'epoch 2',
lexicon: [
'nta', 'nat', 'nət', 'na', 'tan', 'nta'
] ]
} }
]); ])
}); })
it('results returned for multiple epochs with parent epoch', () => {
const action = {type: 'RUN'};
state = initState(5);
const newEpoch = {
name: 'epoch 2',
parent: 'epoch 1',
changes: [
'[+ sonorant ]>0/#_.'
]
}
state.epochs = [ ...state.epochs, newEpoch ]
expect(stateReducer(state, action).results).toEqual([
{
pass: 'epoch 1',
lexicon: [
'annu', 'anat', 'ant', 'annu', 'tʰan', 'nnu'
]
},
{
pass: 'epoch 2',
parent: 'epoch 1',
lexicon: [
'nnu', 'nat', 'nt', 'nnu', 'tʰan', 'nu'
]
}
])
})
}); });