#include #include #include #include #include using namespace std; class MorphEncap{ public: size_t minim; vector morph; MorphEncap *firstmorph; vector Sh; vector > > > factors; map preimages; vector > borders; size_t computedUntil; MorphEncap(vector& m):morph(m),firstmorph(this),factors(5000){ minim =10000; for(size_t i=0; im[i].size()) minim=m[i].size(); initfact(6); initSh(); initBorders(); preimages[""]=""; } MorphEncap(vector& m, MorphEncap* m1):morph(m),firstmorph(m1),factors(5000){ minim =10000; for(size_t i=0;im[i].size()) minim=m[i].size(); computedUntil=0; initSh(); initBorders(); preimages[""]=""; } friend ostream& operator<<(ostream& out, const MorphEncap& m){ for(size_t i=0;i "<< m.morph[i]<("",0)); cout<<"****************"<(s,j)); s[0]++; } for(auto it=factors[1].begin(),ie=factors[1].end(); it!=ie; it++){ string res; image(it->first,res); if(preimages.find(res) == preimages.end()) preimages[res] = it->first; else{cout<< "The morphism is not injective!!!"< listtemp; cout<<"computing from factors of size "<first); size_t ll=0; while(ll < listtemp.size()){ string res; image(listtemp[ll],res); cout<(listtemp[ll],j)); if(k==i && factors[k][res.substr(j,k)].size()==1) listtemp.push_back(res.substr(j,k)); } ll++; } for(auto it=factors[i].begin(),ie=factors[i].end(); it!=ie; it++){ string res; image(it->first,res); if(preimages.find(res) == preimages.end()) preimages[res] = it->first; else{cout<< "The morphism is not injective!!!"<increasecomp(i); for(auto it = firstmorph->factors[i].begin(),ie = firstmorph->factors[i].end(); it!=ie; it++){ string res; image(it->first, res); for(size_t j=0;jfirst[0]-'0'].size();j++) for(size_t k= max((int)(res.size()-j-morph[it->first[it->first.size()-1]-'0'].size()+1),0);k<=res.size()-j;k++) factors[k][res.substr(j,k)].push_back(pair(it->first,j)); } for(auto it = firstmorph->factors[i].begin(),ie = firstmorph->factors[i].end();it!=ie;it++){ string res; image(it->first,res); if(preimages.find(res) == preimages.end()) preimages[res] = it->first; else{cout<< "The morphism is not injective!!!"< synch(i+1,0); for(size_t j=0;jsecond.size();j++){ int v=-(it->second[j].second); for(size_t k=0;ksecond[j].first.size();k++){ if (v>=0 && v<=i) synch[v]++; v+= morph[it->second[j].first[k]-'0'].size(); } if (v>=0 && v<=i) synch[v]++; } int synchpoint=0; for(int j=0; jsecond.size()) synchpoint++; if(synchpoint<2){ done = false; Sh.push_back(it->first); cout<first<<" "; } } i++; if(i>1000){ cout<<"The morphisme is not circular (or for i >1000?)"< beg, end; beg.insert(""); end.insert(""); for(size_t i=0;i(*it,*eit)); } for(size_t i=0; i c; string pat; Patern(const string& pat, int par= -1) : c(pat.size()+1,""), pat(pat){ } Patern(const Patern & P) : c(P.c), pat(P.pat){ } string getpat()const{ string s; for(size_t i=0; i P.pat) return false; if(c.size()P.c.size()) return false; for(size_t i =0; i P.c[i]) return false; } return false; } inline bool operator == (const Patern &P) const{ if(pat != P.pat) return false; if(c.size()!=P.c.size()) return false; for(size_t i =0; i& replacedby, MorphEncap& morph, set& seen, vector& list, bool secondmorph){ if(nextVar == P.pat.size()){ if(NP.pat.back()=='.'){ char tc= NP.pat.back(); string temp= NP.c.back(); NP.pat.pop_back(); NP.c.pop_back(); if(secondmorph || seen.insert(NP).second) list.push_back(NP); NP.pat+=tc; NP.c.push_back(temp); }else{ if(secondmorph || seen.insert(NP).second) list.push_back(NP); } }else{ if(P.pat[nextVar] == '.'){ if(NP.pat.size()!=0 && NP.pat.back()!='.'){ NP.pat += '.'; NP.c.push_back(P.c[nextVar+1]); recReplace(P, NP, nextVar+1, replacedby, morph, seen, list, secondmorph); NP.pat.pop_back(); NP.c.pop_back(); }else{ string temp = NP.c.back(); NP.c.back() = P.c[nextVar+1]; recReplace(P, NP, nextVar+1, replacedby, morph, seen, list, secondmorph); NP.c.back() = temp; } }else if(replacedby[P.pat[nextVar]-'A'] == -2){ for(replacedby[P.pat[nextVar]-'A']= -1; replacedby[P.pat[nextVar]-'A']<(int)(morph.Sh.size()); replacedby[P.pat[nextVar]-'A']++){ recReplace(P, NP, nextVar, replacedby, morph, seen, list, secondmorph); } replacedby[P.pat[nextVar]-'A']=-2; }else if(replacedby[P.pat[nextVar]-'A'] == -1){ NP.pat+=P.pat[nextVar]; NP.c.push_back(P.c[nextVar+1]); recReplace(P, NP, nextVar+1, replacedby, morph, seen, list, secondmorph); NP.pat.pop_back(); NP.c.pop_back(); }else{ string temp = NP.c.back(); NP.c.back() += morph.Sh[replacedby[P.pat[nextVar]-'A']]+ P.c[nextVar+1]; if(NP.c.back().size() == 0 || morph.isafactor(NP.c.back())) recReplace(P, NP, nextVar+1, replacedby, morph, seen, list, secondmorph); NP.c.back()=temp; } } } void replace(const Patern & P, MorphEncap& morph, set& seen, vector& list, int nbVars, bool secondmorph){ Patern NP(""); vector replacedby(nbVars,-2); NP.c[0]=P.c[0]; recReplace(P, NP, 0, replacedby, morph, seen, list, secondmorph); } void recfind(const Patern& P, Patern& NP, vector& select, int nextVar, const string &fromLeft, MorphEncap& morph, set& seen, vector& list, const Patern& todiv){ if(nextVar == P.pat.size()){ for(size_t i=0; i& seen, int nbVars){ vector todo(1, P); replace(P, morph, seen, todo, nbVars,false); vector list; for(size_t i=0; i select(nbVars, -1); Patern NP(todo[i].pat, 0); for(size_t fl =0; fl "<& seen, int nbVars){ vector todo(1, P); replace(P, morph2, seen, todo, nbVars, true); vector list; for(size_t i=0; i select(nbVars, -1); Patern NP(todo[i].pat, 0); for(size_t fl =0; fl sentto(26,-1); int nbVars = 0; for(size_t i=0; i> formula; int nbVars = normalize(formula); Patern P(formula); int sizeA; cin >> sizeA; vector m(sizeA); for(int i=0; i>m[i]; MorphEncap morph(m); vector m2(sizeA); for(int i=0; i>m2[i]; MorphEncap morph2(m2, &morph); set seen; if(findancestors(P, morph2, morph, seen, nbVars)) cout<< "The formula "<