Module:ltc-pron/predict

Hello, you have come here looking for the meaning of the word Module:ltc-pron/predict. In DICTIOUS you will not only get to know all the dictionary meanings for the word Module:ltc-pron/predict, but we will also tell you about its etymology, its characteristics and you will know how to say Module:ltc-pron/predict in singular and plural. Everything you need to know about the word Module:ltc-pron/predict you have here. The definition of the word Module:ltc-pron/predict will help you to be more precise and correct when speaking or writing your texts. Knowing the definition ofModule:ltc-pron/predict, as well as those of other words, enriches your vocabulary and provides you with more and better linguistic resources.

This module calculates the expected Mandarin and Cantonese reflexes of Middle Chinese pronunciations.


local export = {}

local fully_voiced_initial = {
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
}

local partially_voiced_initial = {
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
}

local fricativisation_inducing = {
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
}

local m_lenition_inducing = {
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
}

local devoicing_outcomes = {
	 = "p",
	 = "t",
	 = "c",
	 = "k",
	 = "ch",
	 = "ch",
}

local function has(str, index, ...)
	if index ~= 0 then
		str = mw.ustring.sub(str, index, index)
	end
	for i, v in ipairs{...} do
		if str == v then
			return true
		end
	end
	return false
end

local initial_outcomes_cmn = {
	 = "b",  = "p",  = "b",  = "m",
	 = "d",  = "t",  = "d",  = "n",
	 = "zh",  = "ch",  = "zh",  = "n",
	 = "z",  = "c",  = "z",  = "s",  = "s",
	 = "zh",  = "ch",  = "zh",  = "sh",  = "sh",
	 = "zh",  = "ch",  = "sh",  = "sh",  = "sh",
	 = "g",  = "k",  = "g",  = "h",  = "h",
	 = "",  = "",  = "",  = "",
	 = "l",  = "r",
}

local devoicing_initial_cmn = {
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
}

local palatalisation_outcomes_cmn = {
	 = "j",
	 = "q",
	 = "x",
	 = "j",
	 = "q",
	 = "x",
}

local final_simplification_outcomes_cmn = {
	 = "iu",
	 = "ui",
	 = "un",
	 = "ong",
}

local rhyme_outcomes_cmn = {
	 = "ueng",
	 = { "ueng", 3, "iong" },
	 = "u",
	 = { "u", 3, "ü" },
	 = "ueng",
	 = "u",
	 = { "ueng", 3, "iong" },
	 = { "u", 3, "ü" },
	 = { "uang", 3, "iang" },
	 = { "uo", 3, "üe" },
	 = { "er", 3, "i" },
	 = { "uei", 2, "uai" },
	 = { "er", 3, "i" },
	 = { "uei", 2, "uai" },
	 = { "er", 3, "i" },
	 = { "uei", 2, "uai" },
	 = { "er", 3, "i" },
	 = { "uei", 2, "uai" },
	 = { "er", 3, "i" },
	 = { "er", 3, "i" },
	 = { "uei", 2, "uai" },
	 = "ü",
	 = "u",
	 = "ü",
	 = "ai",
	 = "uei",
	 = "i",
	 = "uei",
	 = { "ai", 3, "ie" },
	 = "uai",
	 = { "ai", 3, "ia" },
	 = { "uai", 3, "ua" },
	 = { "ai", 3, "ie" },
	 = "uai",
	 = "i",
	 = { "uei", 2, "uai" },
	 = "i",
	 = { "uei", 2, "uai" },
	 = "i",
	 = "uei",
	 = "ai",
	 = "uei",
	 = "in",
	 = "in",
	 = "ün",
	 = "en",
	 = "ün",
	 = "i",
	 = "i",
	 = { "ü", 2, "uai" },
	 = "e",
	 = { "ü", 2, "uai" },
	 = { "uen", 3, "en" },
	 = "e",
	 = "uen",
	 = { "u", 1, "o" },
	 = "in",
	 = "i",
	 = { "uen", 3, "ün" },
	 = "ü",
	 = "an",
	 = "uan",
	 = { "a", 3, "e" },
	 = "uo",
	 = "ian",
	 = "üan",
	 = "ie",
	 = { "a", 3, "üe" },
	 = { "an", 3, "ian" },
	 = "uan",
	 = { "a", 3, "ia" },
	 = "ua",
	 = { "an", 3, "ian" },
	 = "uan",
	 = { "a", 3, "ia" },
	 = "ua",
	 = "ian",
	 = "üan",
	 = "ian",
	 = "üan",
	 = "ie",
	 = "üe",
	 = "ie",
	 = "üe",
	 = "ian",
	 = "üan",
	 = "ie",
	 = "üe",
	 = "ao",
	 = { "ao", 3, "iao" },
	 = "iao",
	 = "iao",
	 = "iao",
	 = { "uo", 3, "e" },
	 = "uo",
	 = "ie",
	 = "üe",
	 = { "a", 3, "ia" },
	 = "ua",
	 = "ie",
	 = "ang",
	 = "uang",
	 = { "uo", 3, "e" },
	 = "uo",
	 = { "iang", 2, "uang" },
	 = "uang",
	 = { "üe", 1, "o" },
	 = { "üe", 1, "o" },
	 = "eng",
	 = "ueng",
	 = "ing",
	 = "iong",
	 = "e",
	 = "uo",
	 = "i",
	 = "ü",
	 = "eng",
	 = "ueng",
	 = "e",
	 = "uo",
	 = "ing",
	 = "iong",
	 = "i",
	 = "ü",
	 = "ing",
	 = "iong",
	 = "i",
	 = "ü",
	 = "eng",
	 = "ueng",
	 = "e",
	 = "uo",
	 = "ing",
	 = { "i", 2, "e" },
	 = "ü",
	 = { "iou", 1, "ou" },
	 = "ou",
	 = { "iou", 1, "iao" },
	 = "in",
	 = "in",
	 = { "i", 2, "e" },
	 = { "i", 2, "e" },
	 = "an",
	 = { "a", 3, "e" },
	 = { "an", 3, "ian" },
	 = "uan",
	 = "ie",
	 = { "a", 3, "ia" },
	 = { "an", 3, "ian" },
	 = { "a", 3, "ia" },
	 = { "an", 3, "ian" },
	 = { "a", 3, "ia" },
	 = "ian",
	 = "ian",
	 = "ie",
	 = "ie",
	 = "ian",
	 = "ie",
	 = "an",
	 = { "a", 3, "e" },
}

local labial_openness_normalisation_cmn = {
	 = 11,
	 = 13,
	 = 15,
	 = 17,
	 = 20,
	 = 26,
	 = 27,
	 = 35,
	 = 37,
	 = 39,
	 = 64,
	 = 68,
	 = 106,
	 = 111,
	 = 114,
	 = 120,
	 = 121,
	 = 125,
	 = 132,
}

function export.predict_cmn(initial, final, tone)
	local initial_result = initial_outcomes_cmn

	if fricativisation_inducing and initial <= 3 then
		initial_result = "f"

	elseif m_lenition_inducing and initial == 4 then
		initial_result = "w"

	elseif tone == 1 and devoicing_initial_cmn then
		initial_result = devoicing_outcomes
	end

	if initial <= 4 then
		final = labial_openness_normalisation_cmn or final
	end
	local final_result = rhyme_outcomes_cmn

	if type(final_result) == "table" then
		if final_result == 1 and initial <= 4
		or final_result == 2 and initial >= 18 and initial <= 22
		or final_result == 3 and initial >= 28 and initial <= 36 then
			final_result = final_result
		else
			final_result = final_result
		end
	end

	if has(final_result, 1, "i", "ü") then
		initial_result = palatalisation_outcomes_cmn or initial_result
	end

	if final_result == "er" then
		if initial_result == "r" then
			initial_result = ""
		else
			final_result = "i"
		end
	end

	if has(initial_result, 0, "zh", "ch", "sh", "r") then
		final_result = mw.ustring.gsub(final_result, "^in", "en")
		final_result = mw.ustring.gsub(final_result, "^i(.)", "%1")
		final_result = mw.ustring.gsub(final_result, "^üe$", "uo")
	end

	if initial <= 4 then
		final_result = mw.ustring.gsub(final_result, "^u(.)", "%1")
		if has(initial_result, 0, "f", "w") then
			final_result = mw.ustring.gsub(final_result, "^(.)", "%1")
			final_result = mw.ustring.gsub(final_result, "^i$", "ei")
		else
			final_result = mw.ustring.gsub(final_result, "^ü", "i")
		end
	end

	if has(initial_result, 0, "n", "l") and has(final_result, 0, "ua", "uai", "uang", "uei") then
		final_result = mw.ustring.gsub(final_result, "^u", "")
	end
	if has(final_result, 1, "ü") and
		not (has(initial_result, 0, "n", "l") and has(final_result, 0, "ü", "üe")) then
		if initial_result == "" then
			initial_result = "y"
		end
		final_result = mw.ustring.gsub(final_result, "^ü", "u")
	end

	if initial_result == "" then
		if has(final_result, 1, "i") then
			initial_result = "y"
		end
		if has(final_result, 1, "u") then
			initial_result = "w"
		end
		if initial_result ~= "" then
			final_result = mw.ustring.gsub(final_result, "^.()", "%1")
		end
	end

	final_result = final_simplification_outcomes_cmn or final_result
	
	local tone_result
	if tone == 1 then
		if fully_voiced_initial or partially_voiced_initial then
			tone_result = 2
		else
			tone_result = 1
		end
	elseif tone == 2 then
		if fully_voiced_initial then
			tone_result = 4
		else
			tone_result = 3
		end
	elseif tone == 3 then
		tone_result = 4
	else
		if fully_voiced_initial then
			tone_result = 2
		elseif partially_voiced_initial then
			tone_result = 4
		else
			tone_result = ""
		end
	end

	return initial_result .. final_result .. tone_result
end

local initial_outcomes_yue = {
	 = "b",  = "p",  = "b",  = "m",
	 = "d",  = "t",  = "d",  = "n",
	 = "z",  = "c",  = "z",  = "n",
	 = "z",  = "c",  = "z",  = "s",  = "z",
	 = "z",  = "c",  = "z",  = "s",  = "z",
	 = "z",  = "c",  = "s",  = "s",  = "s",
	 = "g",  = "k",  = "g",  = "ng",  = "h",
	 = "h",  = "",  = "",  = "",
	 = "l",  = "j",
}

local devoicing_initial_yue = {
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
}

local initial_class_yue = {
	 = 1,
	 = 1,
	 = 1,
	 = 1,
	 = 2,
	 = 2,
	 = 2,
	 = 2,
	 = 3,
	 = 3,
	 = 3,
	 = 2,
	 = 4,
	 = 4,
	 = 4,
	 = 4,
	 = 4,
	 = 5,
	 = 5,
	 = 5,
	 = 5,
	 = 5,
	 = 6,
	 = 6,
	 = 6,
	 = 6,
	 = 6,
	 = 7,
	 = 7,
	 = 7,
	 = 8,
	 = 7,
	 = 7,
	 = 8,
	 = 8,
	 = 8,
	 = 2,
	 = 6,
}

local final_class_yue = {
	 = 20,
	 = 20,
	 = 20,
	 = 20,
	 = 20,
	 = 20,
	 = 20,
	 = 20,
	 = 34,
	 = 34,
	 = 35,
	 = 21,
	 = 35,
	 = 21,
	 = 35,
	 = 21,
	 = 35,
	 = 21,
	 = 35,
	 = 35,
	 = 21,
	 = 36,
	 = 24,
	 = 36,
	 = 39,
	 = 28,
	 = 6,
	 = 6,
	 = 2,
	 = 33,
	 = 2,
	 = 33,
	 = 2,
	 = 33,
	 = 6,
	 = 21,
	 = 6,
	 = 21,
	 = 6,
	 = 6,
	 = 17,
	 = 25,
	 = 8,
	 = 8,
	 = 22,
	 = 8,
	 = 22,
	 = 8,
	 = 8,
	 = 22,
	 = 8,
	 = 22,
	 = 8,
	 = 8,
	 = 38,
	 = 38,
	 = 8,
	 = 8,
	 = 8,
	 = 8,
	 = 31,
	 = 32,
	 = 31,
	 = 32,
	 = 26,
	 = 27,
	 = 26,
	 = 27,
	 = 4,
	 = 4,
	 = 4,
	 = 4,
	 = 4,
	 = 4,
	 = 4,
	 = 4,
	 = 13,
	 = 30,
	 = 13,
	 = 30,
	 = 13,
	 = 30,
	 = 13,
	 = 30,
	 = 13,
	 = 30,
	 = 13,
	 = 30,
	 = 19,
	 = 5,
	 = 15,
	 = 15,
	 = 15,
	 = 16,
	 = 16,
	 = 11,
	 = 29,
	 = 1,
	 = 1,
	 = 11,
	 = 18,
	 = 18,
	 = 18,
	 = 18,
	 = 37,
	 = 18,
	 = 37,
	 = 18,
	 = 9,
	 = 9,
	 = 40,
	 = 40,
	 = 9,
	 = 9,
	 = 14,
	 = 14,
	 = 9,
	 = 9,
	 = 9,
	 = 9,
	 = 14,
	 = 14,
	 = 14,
	 = 14,
	 = 14,
	 = 14,
	 = 14,
	 = 14,
	 = 9,
	 = 9,
	 = 9,
	 = 9,
	 = 14,
	 = 14,
	 = 14,
	 = 10,
	 = 10,
	 = 10,
	 = 7,
	 = 7,
	 = 7,
	 = 7,
	 = 23,
	 = 23,
	 = 12,
	 = 3,
	 = 12,
	 = 3,
	 = 3,
	 = 3,
	 = 3,
	 = 3,
	 = 12,
	 = 12,
	 = 12,
	 = 12,
	 = 12,
	 = 12,
	 = 23,
	 = 23,
}

local rhyme_outcomes_yue = {
	 = "A",
	 = "Ai",
	 = "Am",
	 = "An",
	 = "Au",
	 = "ai",
	 = "am",
	 = "an",
	 = "aN",
	 = "au",
	 = "e",
	 = "im",
	 = "in",
	 = "IN",
	 = "iu",
	 = "o",
	 = "oi",
	 = "oN",
	 = "ou",
	 = "UN",
	 = { "ei", "Ei", "ai" },
	 = { "En", "En", "an" },
	 = { "Am", "Am", "om" },
	 = { "ou", "ou", "u" },
	 = { "ui", "Ei", "ui" },
	 = { "An", "in", "in" },
	 = { "An", "Yn", "Yn" },
	 = { "ai", "Ei", "ui" },
	 = { "e", "O", "O" },
	 = { "in", "Yn", "Yn" },
	 = { "un", "An", "on" },
	 = { "un", "Yn", "un" },
	 = { "Ai", "Ei", "Ai" },
	 = { "oN", "oN", "oN" },
	 = { "ei", "ei", "i", "i", "i", "i", "ei", "i" },
	 = { "u", "Ei", "Y", "Ei", "o", "Y", "Ei", "Y" },
	 = { "oN", "ON", "ON", "ON", "oN", "ON", "ON", "ON" },
	 = { "un", "En", "En", "Yn", "Yn", "Yn", "an", "an" },
	 = { "ui", "Ai", "Ai", "oi", "Ai", "Ai", "oi", "oi" },
	 = { "IN", "IN", "IN", "IN", "aN", "IN", "IN", "IN" },
}

local palatalisation_inducing_yue = {
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
}

local labialisation_inducing_yue = {
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
}

local glide_inducing_yue = {
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
	 = true,
}

local debuccalisation_inducing_yue = {
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
     = true,
}

function export.predict_yue(initial, final, tone)
	local initial_result = initial_outcomes_yue

	if fricativisation_inducing and initial <= 3 then
		initial_result = "f"

	elseif tone == 1 and devoicing_initial_yue then
		initial_result = devoicing_outcomes

	elseif initial == 17 and labialisation_inducing_yue then
		initial_result = "s"
	end

	if initial == 29 and debuccalisation_inducing_yue then
		initial_result = "h"

	elseif initial == 29 and (final == 136 or final >= 139 and final <= 142)
		or initial == 32 and (final == 136 or final == 57)
		or initial == 33 and (labialisation_inducing_yue or glide_inducing_yue)
		or initial_result == "" and palatalisation_inducing_yue then
		initial_result = "j"
	end
	
	local final_result
	if (final == 36 or final == 38) and initial == 36 then
		final_result = "Ei"

	elseif (final == 26 or final == 42) and initial == 31 then
		final_result = "oi"

	elseif final == 23 and initial == 31 then
		final_result = ""

	elseif (final == 22 or final == 24) and initial == 4 then
		final_result = "ou"

	else
		local final_class = final_class_yue
		final_result = rhyme_outcomes_yue
		if final_class >= 35 then
			final_result = final_result]
		elseif final_class >= 21 then
			final_result = final_result + 8) / 5)]
		end
	end

	if initial == 31 and mw.ustring.find(final_result, "^") ~= nil then
		initial_result = "j"
	end

	if labialisation_inducing_yue and mw.ustring.find(final_result, "^") == nil then
		if initial_result == "h" and mw.ustring.find(final_result, "^") == nil then
			initial_result = "f"
		elseif initial_result == "j" or initial_result == "" then
			initial_result = "w"
		elseif initial_result == "g" and mw.ustring.find(final_result, "^") == nil then
			initial_result = "gw"
		elseif initial_result == "k" and mw.ustring.find(final_result, "^") == nil then
			initial_result = "kw"
		end
	end
	
	local tone_result
	if tone == 4 then
		if fully_voiced_initial or partially_voiced_initial then
			tone_result = 6
		elseif mw.ustring.find(final_result, "^") ~= nil then
			tone_result = 3
		else
			tone_result = 1
		end
	elseif tone == 2 and fully_voiced_initial then
		tone_result = 6
	elseif fully_voiced_initial or partially_voiced_initial then
		tone_result = 3 + tone
	else
		tone_result = tone
	end

	final_result = mw.ustring.gsub(final_result, "om", "am")

	if initial <= 4 then
		final_result = mw.ustring.gsub(final_result, "m$", "n")
	end

	if tone == 4 then
		final_result = mw.ustring.gsub(final_result, "m$", "p")
		final_result = mw.ustring.gsub(final_result, "n$", "t")
		final_result = mw.ustring.gsub(final_result, "N$", "k")
	end

	final_result = mw.ustring.gsub(final_result, "A", "aa")
	final_result = mw.ustring.gsub(final_result, "I", "i")
	final_result = mw.ustring.gsub(final_result, "U", "u")
	final_result = mw.ustring.gsub(final_result, "O", "oe")
	final_result = mw.ustring.gsub(final_result, "E", "eo")
	final_result = mw.ustring.gsub(final_result, "Y", "yu")

	final_result = mw.ustring.gsub(final_result, "N", "ng")

	return initial_result .. final_result .. "<sup>" .. tone_result .. "</sup>"
end

return export