Module:User:Φρύδια/logic

local Composer = { }

local function split(str, sep) if not sep then sep = '%s' end local parts = { } for s in str:gmatch('([^'..sep..']+)') do		table.insert(parts, s)	end return parts end

function Composer:new(init_members) local obj = init_members or { } setmetatable(obj, self) self.__index = self return obj end

local function get_morph(fts_id, data, morph) local m_id, fts_id = fts_id:match '^(%l*)_?(.*)' local fts_S, fts_P = split(fts_id, '_'), { } local function fts_powerset(n, n_set, pos, fts) if n_set < n then fts_powerset(n, n_set+1, pos+1, (fts and fts..'_' or '')..fts_S[pos]) if #fts_S - pos >= n - n_set then fts_powerset(n, n_set, pos+1, fts) end else table.insert(fts_P, fts or '') end if pos == 1 and n > 0 then fts_powerset(n-1, 0, 1) end end fts_powerset(#fts_S, 0, 1) for _, fts in ipairs(fts_P) do		local entry = data[m_id..(m_id ~=  and fts ~=  and '_' or '')..fts] if entry then morph = entry:gsub('([^&]+)', function(c)				return c:sub(1, 1) == '@' and get_morph(c:sub(2), data) or c end) :gsub('&', )..(morph or ) if entry:sub(1, 1) ~= '&' then return morph end end end end

local function union(tbs) local i_max = table.maxn(tbs) local function _union(i, t)		if tbs[i+1] then setmetatable(tbs[i+1], { __index = tbs[t] }) return _union(i+1, i+1) else if i < i_max then return _union(i+1, t)			else return tbs[t] end end end return _union(1, 1) end

function Composer:conjugate(lemma) local data = union(self:make_tables(lemma)) local deferred = { } local function get_form(pdgm, ref, ending) local form_id = pdgm..(ref ==  and  or '_'..ref) local form = data[form_id] if form then if form:sub(1, 1) == '@' then deferred[form_id] = form:sub(2, -1) return nil end return self.prefix..form end local stm = get_morph('stm_'..form_id, data) local vwl = get_morph('vwl_'..form_id, data) local affx = get_morph('affx_'..form_id, data) local endg = get_morph('end_'..form_id, data) or ending return self:assemble_form(stm, vwl, affx, endg, pdgm, ref) end local function make_ids(pdgm) local tb = { } local function _make_ids(dp, ad, id) local function is_valid(name) local c_data = self.constraints[name] if c_data then for _, v in ipairs(c_data[2]) do						if (id:find(v) ~= nil) == c_data[1] then return true end end return false else return true end end if ad < #pdgm[dp] then _make_ids(dp, ad+1, id) end local add = pdgm[dp][ad] if is_valid(add) then id = id..(id ==  and  or '_')..add if dp < #pdgm then _make_ids(dp+1, 1, id) else table.insert(tb, id) end end end _make_ids(1, 1, '') return tb	end local cnjg = { } for i, tb_pdgms in ipairs(self.paradigms) do		for _, pdgm in ipairs(make_ids(tb_pdgms)) do			local endings_info = get_morph(pdgm, self.endings_map) local function make_f(ref, en) local form = get_form(pdgm, ref, en) if form then local form_id = pdgm..(ref ==  and  or '_'..ref) cnjg[form_id] = form end end if endings_info ==  then make_f(, '') else local ref_id = tonumber(endings_info:sub(1, 1)) for n, ref in ipairs(self.endings_refs[ref_id]) do					local en, make = '', true for j = 3, endings_info:len do						local m = tonumber(endings_info:sub(j, j)) local en_part = self.endings[m][n] if en_part then en = en..en_part else make = false break end end if make then make_f(ref, en) end end end end end for copied_form, source_form in pairs(deferred) do		cnjg[copied_form] = cnjg[source_form] end return cnjg end

return Composer