mirror of
https://github.com/Z3Prover/z3
synced 2026-03-17 18:43:45 +00:00
Another attempt to fix powers
This commit is contained in:
parent
51e245a245
commit
2f46c8893e
3 changed files with 742 additions and 122 deletions
|
|
@ -598,75 +598,83 @@ static void test_zipt_parikh() {
|
|||
static void test_tricky_str_equations() {
|
||||
std::cout << "test_tricky_str_equations\n";
|
||||
|
||||
// --- SAT: commutativity / rotation / symmetry ---
|
||||
// ---------------------------------------------------------------
|
||||
// SAT — Conjugacy equations: Xw₂ = w₁X
|
||||
// SAT iff w₂ is a rotation of w₁. In that case w₁ = qp, w₂ = pq
|
||||
// and X = (qp)^n · q is a family of solutions (n ≥ 0).
|
||||
// All of these are UNSAT for X = ε (the ground parts don't match),
|
||||
// so the solver must find a non-trivial witness.
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// XY = YX (classic commutativity; witness: X="ab", Y="abab")
|
||||
VERIFY(eq_sat("XY", "YX"));
|
||||
// "ba" is a rotation of "ab" (p="b", q="a"). X = "a".
|
||||
VERIFY(eq_sat("Xba", "abX"));
|
||||
|
||||
// Xab = abX (X commutes with the word "ab"; witness: X="ab")
|
||||
VERIFY(eq_sat("Xab", "abX"));
|
||||
// "cb" is a rotation of "bc" (p="c", q="b"). X = "b".
|
||||
VERIFY(eq_sat("Xcb", "bcX"));
|
||||
|
||||
// XaY = YaX (swap-symmetric; witness: X=Y=any, e.g. X=Y="b")
|
||||
VERIFY(eq_sat("XaY", "YaX"));
|
||||
// "bca" is a rotation of "abc" (p="bc", q="a"). X = "a".
|
||||
VERIFY(eq_sat("Xbca", "abcX"));
|
||||
|
||||
// XYX = YXY (Markov-type; witness: X=Y)
|
||||
VERIFY(eq_sat("XYX", "YXY"));
|
||||
// "cab" is a rotation of "abc" (p="c", q="ab"). X = "ab".
|
||||
VERIFY(eq_sat("Xcab", "abcX"));
|
||||
|
||||
// XYZ = ZYX (reverse-palindrome; witness: X="a",Y="b",Z="a")
|
||||
VERIFY(eq_sat("XYZ", "ZYX"));
|
||||
// ---------------------------------------------------------------
|
||||
// SAT — Power decomposition (ε NOT a solution)
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// XabY = YabX (rotation-like; witness: X="",Y="ab")
|
||||
VERIFY(eq_sat("XabY", "YabX"));
|
||||
// XX = aa ⇒ X = "a". (ε gives "" ≠ "aa")
|
||||
VERIFY(eq_sat("XX", "aa"));
|
||||
|
||||
// aXYa = aYXa (cancel outer 'a'; reduces to XY=YX; witness: X=Y="")
|
||||
VERIFY(eq_sat("aXYa", "aYXa"));
|
||||
// XbX = aba ⇒ 2|X| + 1 = 3 forces |X| = 1; X = "a".
|
||||
// (ε gives "b" ≠ "aba")
|
||||
VERIFY(eq_sat("XbX", "aba"));
|
||||
|
||||
// XaXb = YaYb (both halves share variable; witness: X=Y)
|
||||
VERIFY(eq_sat("XaXb", "YaYb"));
|
||||
// ---------------------------------------------------------------
|
||||
// SAT — Multi-variable (ε NOT a solution)
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// abXba = Xabba (witness: X="" gives "abba"="abba")
|
||||
VERIFY(eq_sat("abXba", "Xabba"));
|
||||
// X = "b", Y = "a" gives "baab" = "baab". (ε gives "ab" ≠ "ba")
|
||||
VERIFY(eq_sat("XaYb", "bYaX"));
|
||||
|
||||
// --- UNSAT: first-character mismatch ---
|
||||
// X = "b", Y = "a" gives "abba" = "abba". (ε gives "ab" ≠ "ba")
|
||||
VERIFY(eq_sat("abXY", "YXba"));
|
||||
|
||||
// abXba = baXab (LHS starts 'a', RHS starts 'b')
|
||||
VERIFY(eq_unsat("abXba", "baXab"));
|
||||
// ---------------------------------------------------------------
|
||||
// UNSAT — Non-conjugate rotation
|
||||
// Xw₂ = w₁X where w₂ is NOT a rotation of w₁.
|
||||
// Heads are variable vs char, so never a trivial first-char clash.
|
||||
// GPowerIntr introduces periodicity, then the period boundaries
|
||||
// give a character mismatch.
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// XabX = XbaX (cancel X prefix/suffix → "ab"="ba"; 'a'≠'b')
|
||||
VERIFY(eq_unsat("XabX", "XbaX"));
|
||||
// "cba" is the reverse of "abc", NOT a rotation.
|
||||
// Rotations of "abc" are: abc, bca, cab.
|
||||
VERIFY(eq_unsat("Xcba", "abcX"));
|
||||
|
||||
// --- UNSAT: mismatch exposed after cancellation ---
|
||||
// "acb" is a transposition of "abc", NOT a rotation.
|
||||
VERIFY(eq_unsat("Xacb", "abcX"));
|
||||
|
||||
// XaYb = XbYa (cancel X prefix → aYb=bYa; first char 'a'≠'b')
|
||||
VERIFY(eq_unsat("XaYb", "XbYa"));
|
||||
// ---------------------------------------------------------------
|
||||
// UNSAT — Induction via GPowerIntr
|
||||
// One side starts with a variable that also appears on the other
|
||||
// side behind a ground prefix → self-cycle. GPowerIntr forces
|
||||
// periodicity; all period branches yield character mismatches.
|
||||
// None of these has a trivial first-char or last-char clash.
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// XaYbX = XbYaX (cancel X prefix+suffix → aYb=bYa; first char 'a'≠'b')
|
||||
VERIFY(eq_unsat("XaYbX", "XbYaX"));
|
||||
// Xa = bX: LHS head = X. Scan RHS: [b], X → self-cycle, base "b".
|
||||
// X = b^n ⇒ b^n·a = b^{n+1} ⇒ last chars a ≠ b ⊥.
|
||||
VERIFY(eq_unsat("Xa", "bX"));
|
||||
|
||||
// XaXbX = XbXaX (cancel X prefix+suffix → aXb=bXa; first char 'a'≠'b')
|
||||
VERIFY(eq_unsat("XaXbX", "XbXaX"));
|
||||
// acX = Xbc: RHS head = X. Scan LHS: [a,c], X → self-cycle, base "ac".
|
||||
// X = (ac)^n ⇒ ac = bc ⊥ (a ≠ b).
|
||||
// X = (ac)^n·a ⇒ aca = abc ⊥ (c ≠ b).
|
||||
VERIFY(eq_unsat("acX", "Xbc"));
|
||||
|
||||
// --- UNSAT: induction ---
|
||||
|
||||
// aXb = Xba (forces X=a^n; final step requires a=b)
|
||||
VERIFY(eq_unsat("aXb", "Xba"));
|
||||
|
||||
// XaY = YbX (a≠b; recursive unrolling forces a=b)
|
||||
VERIFY(eq_unsat("XaY", "YbX"));
|
||||
|
||||
// --- UNSAT: length parity ---
|
||||
|
||||
// XaX = YY (|XaX|=2|X|+1 is odd; |YY|=2|Y| is even)
|
||||
VERIFY(eq_unsat("XaX", "YY"));
|
||||
|
||||
// XaaX = YbY (|XaaX|=2|X|+2 is even; |YbY|=2|Y|+1 is odd)
|
||||
VERIFY(eq_unsat("XaaX", "YbY"));
|
||||
|
||||
// --- UNSAT: midpoint argument ---
|
||||
|
||||
// XaX = YbY (equal length forces |X|=|Y|; midpoint position |X|
|
||||
// holds 'a' in LHS and 'b' in RHS, but 'a'≠'b')
|
||||
VERIFY(eq_unsat("XaX", "YbY"));
|
||||
// bcX = Xab: RHS head = X. Scan LHS: [b,c], X → self-cycle, base "bc".
|
||||
// X = (bc)^n ⇒ bc = ab ⊥ (b ≠ a).
|
||||
// X = (bc)^n·b ⇒ bcb = bab ⊥ (c ≠ a).
|
||||
VERIFY(eq_unsat("bcX", "Xab"));
|
||||
|
||||
std::cout << " ok\n";
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue