Przeskocz do treści

Delta mi!

Równania napisów

Artur Jeż

o artykule ...

  • Publikacja w Delcie: kwiecień 2020
  • Publikacja elektroniczna: 1 kwietnia 2020
  • Autor: Artur Jeż
    Afiliacja: Wydział Matematyki i Informatyki, Uniwersytet Wrocławski
  • Wersja do druku [application/pdf]: (347 KB)

Przyjrzyjmy się problemowi równań napisów: dla ustalonego alfabetu, np. |a;b;c;::: ; piszemy równania używające liter z tegoż alfabetu oraz zmiennych, które będziemy oznaczać przez |X;Y; Z;::: Dla uproszczenia pomyślmy o jednym równaniu, np. aXXXX = XaY Y: Rozwiązaniem będą takie napisy, złożone z liter alfabetu, że po podstawieniu pod zmienne uzyskamy takie same napisy....

W naszym przykładzie podstawienie =aa,Y=aaa X jest rozwiązaniem. Innym przykładem jest równanie baYb=baaababbab, X którego rozwiązaniem jest np. =baaa,Y=bba. |X Równania tego typu rozważane były od lat 60. XX wieku, z jednej strony ze względu na związki z 10. problemem Hilberta, z drugiej ze względu na związki z teorią grup… Ale obie te historie to tematy na osobne artykuły.

Pierwszy sposób rozwiązywania tego typu równań podał G. Makanin w 1977 roku, w roku 1999 inne, dużo prostsze podejście zaproponował W. Plandowski. My przyjrzymy się dziś rozwiązaniu upraszczającemu drugie z nich, na podstawie mojego artykułu Recompression: A Simple and Powerful Technique for Word Equations, (Journal of the ACM, 2016 63:1, art. 4).

Zanim przystąpimy do prezentacji sposobu rozwiązywania takich równań, należałoby ustalić, do czego będziemy dążyć: chcemy podać algorytm, czyli systematyczny przepis pokazujący, jak uzyskać rozwiązanie (lub stwierdzić, że go nie ma). Przykładem algorytmu dla układu równań liniowych jest: "Powtarzaj: weź pierwsze równanie, jeśli jest niesprzeczne i zawiera zmienną, to wylicz jedną zmienną w oparciu o inne i podstaw do pozostałych równań, usuń równanie". Przykładem algorytmu dla równania kwadratowego |ax2 + bx + c = 0 jest: "Wylicz  √ -------- |∆ = b2 − 4ac, jeśli ∆ < 0, to nie ma rozwiązań, w przeciwnym przypadku rozwiązania to |(−b ± √∆-) /2a". Podamy tego typu algorytm, choć dłuższy i bardziej skomplikowany, dla równań napisów.

Nasz algorytm będzie wielokrotnie sprawdzał niezależnie kilka możliwości, np. osobno sprawdzi możliwości, że pierwsza litera podstawienia pod |X to a lub b, a potem osobno, czy poza tą jedną literą coś jeszcze w podstawieniu jest, czy nie, itd. Jeśli istnieje rozwiązanie, to algorytm znajdzie je dla którejś sekwencji możliwości, dla innych być może nie znajdzie. Nie brzmi to jak dobry pomysł - w takim razie algorytm mógłby po prostu przejrzeć wszystkie możliwe podstawienia, litera po literze… Dlatego też zagwarantujemy coś jeszcze - algorytm będzie przekształcał równanie w taki sposób, że dla którejś z możliwości wiodących do rozwiązania rozważane równanie zawsze będzie miało najwyżej  2 8n liter i n zmiennych, gdzie n to długość równania wejściowego. W szczególności dla niektórych możliwości nie znajdziemy rozwiązania (trudno!), a inne doprowadzą nas do równania dłuższego niż 8n2 +n - wtedy algorytm przestaje dalej liczyć. Takie podejście można też zrealizować inaczej, bez odwoływania się do sprawdzania wszystkich możliwości: możemy wypisać wszystkie równania długości najwyżej 8n2 +n, zaznaczyć, które równania możemy przekształcić w które, i sprawdzić, czy potrafimy przekształcić wejściowe równanie w jakieś bardzo proste niesprzeczne równanie, np. a = a albo =X.X

Od teraz skupimy się na wykazaniu, że algorytm zawsze ma "dobry wybór", tj. potrafi przekształcić niesprzeczne równanie długości nie większej niż |8n2 + n w niesprzeczne równanie długości również nie większej niż |8n2 + n. Ważne jest też, że niezależnie od wyboru nie przekształcimy równania sprzecznego w niesprzeczne.

Równanie napisów może mieć wiele rozwiązań i algorytm jest w stanie podać reprezentację wszystkich; dla uproszczenia będziemy wymagać jedynie, o ile istnieje, aby podał dowolne. W szczególności: jeśli istnieje rozwiązanie, to istnieje też takie, które używa tylko liter występujących w równaniu, choć sam alfabet może być większy - wszystkie inne litery w rozwiązaniu można zastąpić przez ustaloną literę; nowe podstawienie dalej jest rozwiązaniem. Będziemy też zakładać, że podstawienie pod zmienną jest niepuste, tj. w podstawieniu =w |X słowo w | ma dodatnią długość.

Aby rozwiązać równanie napisów, będziemy skracać jego krótkie fragmenty: popatrzmy jeszcze raz na równanie baYb=baaababbab X | (które ma rozwiązanie =baaa,Y=bba X ): jeśli zastąpimy ba przez "świeżą", tj. nieużywaną w równaniu, literę |c, to otrzymane równanie cYb=caacbcbX ma rozwiązanie =caa,Y=bc. X Łatwo też sprawdzić, że jeśli nowe równanie ma rozwiązanie, to stare też ma - wystarczy zamienić w podstawieniu każde c przez ba. Niestety, ten pomysł nie działa, jeśli w oryginalnym równaniu spróbujemy zastąpić ab przez |d: po lewej stronie równania nie ma żadnego |ab, w podstawieniu =baaa,Y=bbaX również nie ma, jest za to po prawej stronie równania. Problemem jest to, że |ab jest częściowo w podstawieniu i częściowo poza. Parę ab, gdzie a ≠b, nazwiemy złą (dla ustalonego rozwiązania), jeśli |b jest pierwszą literą podstawienia pod X oraz |aX występuje w równaniu lub a jest ostatnią literą podstawienia pod Y oraz Yb występuje w równaniu (lub dla powyższych założeń Y X występuje w równaniu). Parę, która nie jest zła, nazwiemy dobrą. Jeśli para |ab, gdzie a ≠ b, jest dobra, to skrócenie |ab daje równanie, które ma odpowiadające, krótsze rozwiązanie. Jednocześnie, jeśli nowe równanie ma rozwiązanie, to stare też miało: wystarczy każde c zastąpić przez ab.

Co do złych par, to łatwo zauważyć, że jeśli równanie ma n wystąpień zmiennych, to jest najwyżej 2n różnych złych par: po jednej na każdą stronę zmiennej. Co więcej, ustaloną złą parę łatwo udobruchać (czyli uczynić dobrą): jeśli ab jest zła, to dla każdej zmiennej sprawdzamy: jeśli jej podstawienie zaczyna się na |b, czyli =bw, X to zastępujemy X przez bX (a podstawienie przez =w X ), analogicznie, jeśli podstawienie kończy się na |a, to zastępujemy X przez a. |X Jeśli w ten sposób podstawienie za |X stało się puste, to usuwamy X z równania. Łatwo sprawdzić, że nowe równanie ma rozwiązanie oraz para ab jest dobra; jeśli zaś nowe równanie ma rozwiązanie, to miało je też stare równanie: wystarczy dokleić litery, które "wypchnęliśmy" ze zmiennych. W nowym równaniu możemy skrócić |ab.

Złe pary to nie jedyny problem: skoro zakładamy, że w parze ab litery |a i b są różne, to nie potrafimy skrócić długich powtórzeń jednej litery, np. nie wiemy, co zrobić z równaniem XXX=XaYY |aX z pierwszego przykładu. Zamiast skracać pary, będziemy skracać maksymalne powtórzenia: |aℓ jest maksymalnym powtórzeniem a, jeśli na lewo i prawo nie ma litery |a. Podobnie jak w przypadku par, możemy zdefiniować, co to znaczy, że litera |a jest zła (jest zmienna X zaczynająca się na a i aX występuje w równaniu lub…) i dobra. Jeśli a jest dobre, to możemy równocześnie zastąpić wszystkie maksymalne wystąpienia a, powiedzmy dla każdego |ℓ zastępujemy maksymalne  ℓ a przez |aℓ ; przy czym aℓ to tylko wygodna nazwa dla nas, algorytm nie musi potem pamiętać, że ta litera powstała z |aℓ. Jeśli a jest zła, to chcemy ją "udobruchać", ale zastąpienie X przez |aX może nie wystarczyć, gdyż podstawienie pod X może dalej zaczynać się na a. Zamiast tego, jeśli ℓr =awa, X gdzie w nie zaczyna się ani nie kończy na a, to zastępujemy X przez ar, aℓX odpowiednio zmieniając podstawienie pod X (teraz =w |X ). Wszystkie możliwe , ℓ r chcemy sprawdzić osobno i tu pojawia się problem: |ℓ i |r mogą być dowolnie duże. Wiadomo jednak, że jeśli istnieje rozwiązanie równania, to istnieje też rozwiązanie, w którym wszystkie takie |ℓ,r mają najwyżej wykładniczą długość. To wciąż dużo, ale zamiast pisać ℓ razy |a, możemy zapisać |(a,ℓ), a zapis pozycyjny ℓ ma wielomianowo wiele cyfr. I tak zaraz skrócimy wszystkie maksymalne powtórzenia a. Tak samo jak dla par możemy wykazać, że jest najwyżej |2n złych liter, a jeśli rozpatrzymy jednocześnie złe pary i litery, to podobnie stwierdzamy, że w sumie złych par i liter jest najwyżej |2n.

Teraz możemy już podać wybory algorytmu, które prowadzą do rozwiązania, a równanie ma niezmiennie co najwyżej 8n2 liter (i najwyżej |n zmiennych): dla danego równania, jeśli istnieje dobra para lub litera, to skracamy ją. Jeśli są tylko złe pary i litery, to wybieramy taką, że po jej udobruchaniu oraz skróceniu otrzymane równanie jest najkrótsze.

Przeanalizujmy algorytm dla tych możliwości: zauważmy najpierw, że jeśli równanie nie ma rozwiązania, to nieważne, co zrobimy, nowe równanie również nie będzie miało rozwiązania. Twierdzimy też, że przy właściwych wyborach równanie nigdy nie będzie miało więcej niż 8n2 liter, gdzie |n to długość równania danego na wejściu: Jeśli istnieje dobra para lub litera, to po jej skróceniu nowe równanie jest krótsze niż stare. A co, jeśli są tylko złe pary i litery? Niech równanie ma |m liter, nie licząc zmiennych. Różnych złych par i liter jest w sumie najwyżej |2n. Dla każdej litery rozpatrzmy literę na prawo (lub lewo, dla ostatniej); ta sąsiednia litera może pochodzić z podstawienia pod zmienną. Razem tworzą parę albo są częścią maksymalnego bloku. Czyli dla każdego wystąpienia litery a w równaniu istnieje zła para lub litera, której wystąpienie zawiera to ustalone wystąpienie a. Skrócenie tej pary/litery usunie to ustalone wystąpienie a. Jako że jest 2n złych par i liter, "średnio" skrócenie usunie przynajmniej |m2n liter oraz wprowadzi co najwyżej połowę z tej liczby (skrócenie pary usuwa dwie litery i dodaje jedną, a skrócenie bloku liter usuwa wiele liter i dodaje jedną). Tak więc istnieje takie skrócenie, które w sumie skróci równanie o przynajmniej |m4n liter. Musimy też wykonać jedno udobruchanie, które wprowadza do równania najwyżej |2n liter: udobruchanie litery wprowadza długie powtórzenia tej litery, ale zaraz każde takie powtórzenie zostanie zastąpione przez jedną literę. Tak więc nowe równanie ma najwyżej |m (stare litery) |−m/4n (usunięte przez skrócenie) + | 2n (udobruchanie) liter. Oszacujmy:

m

jedyna nierówność wynika z ograniczenia m I to jest koniec: dla podanych wyżej wyborów równanie znajdzie rozwiązanie i równania, które rozważa, mają najwyżej 8n2 liter (i najwyżej n zmiennych).

A czego nie wiemy o równaniach napisów? Dokładniejsza analiza algorytmu pokazuje, że jeśli istnieje rozwiązanie, to istnieje też rozwiązanie podwójnie wykładnicze. Nie jest jednak znane równanie, którego najkrótsze rozwiązanie jest ponad wykładnicze; popularna jest hipoteza, że jeśli istnieje rozwiązanie, to istnieje też rozwiązanie wykładnicze. Do równań napisów można też dodać dodatkowe warunki na rozwiązanie, np. żądać, by suma długości podstawień pod |X i Y była równa długości podstawienia pod Z. Nie wiadomo, czy równania napisów z liniowymi warunkami na długości podstawień można rozwiązać.