Sharp SAT — различия между версиями
| SVKazakov (обсуждение | вклад) | SVKazakov (обсуждение | вклад)  | ||
| Строка 7: | Строка 7: | ||
| == Доказательство == | == Доказательство == | ||
| − | Для доказательства будем строить вероятностную программу Verifier, которая хочет проверить, верно ли, что заданная формула  | + | Для доказательства будем строить вероятностную программу <tex>Verifier</tex>, которая хочет проверить, верно ли, что заданная формула <tex>\varphi</tex> имеет ровно <tex>k</tex> удовлетворяющих наборов. Программа <tex>Verifier</tex> может совершить не больше полинома от длины входа действий, а также может обращаться к программе <tex>Prover</tex>, которая пытается любым возможным способом убедить <tex>Verifier</tex> в верности рассматриваемого утверждения. | 
| − | Далее в программе Verifier будем писать "проверим ...", что означает проверку соответствующего условия, и, при ложности,  | + | Далее в программе <tex>Verifier</tex> будем писать "проверим ...", что означает проверку соответствующего условия, и, при ложности, <tex>Verifier</tex> будет сразу завершаться и возвращать <tex>false</tex>, т.к. <tex>Prover</tex> её обманывает, а значит, нет правильного доказательства проверяемого утверждения. | 
| − | + | <tex>Verifier</tex> будет выполнять следующие шаги. | |
| Шаг 0. | Шаг 0. | ||
| − | Пусть формула <tex>\varphi</tex> каким либо образом записана. Пусть формула  | + | Пусть формула <tex>\varphi</tex> каким либо образом записана. Пусть формула <tex>\varphi</tex> имеет <tex>n</tex> переменных и степень <tex>d</tex>. Сделаем следующие замены и получим формулу <tex>A(x_1, x_2, ..., x_n)</tex>: | 
| # <tex>x \land y \to x \cdot y</tex> | # <tex>x \land y \to x \cdot y</tex> | ||
| # <tex> \lnot x \to 1 - x</tex> | # <tex> \lnot x \to 1 - x</tex> | ||
| Строка 23: | Строка 23: | ||
| Итак, надо проверить следующее арифметическое уравнение: <tex>\sum_{x_1 = 0}^{1}\sum_{x_2 = 0}^{1}...\sum_{x_n = 0}^{1} A(x_1, x_2, ..., x_n) = k</tex>. | Итак, надо проверить следующее арифметическое уравнение: <tex>\sum_{x_1 = 0}^{1}\sum_{x_2 = 0}^{1}...\sum_{x_n = 0}^{1} A(x_1, x_2, ..., x_n) = k</tex>. | ||
| − | + | Попросим <tex>Prover</tex> прислать <tex>Verifier</tex>'у простое число <tex>p > max(2^n, k_p)</tex> и сертификат о его простоте.  | |
| + | Проверим простоту <tex>p</tex> по сертификату, и условие <tex>p > max(2^n, k_p)</tex>. Константу <tex>k_p</tex> определим позднее. | ||
| − | + | Будем проверять уравнение по модулю <tex>p</tex>. | |
| − | |||
| − | |||
| − | Будем проверять уравнение по модулю p. | ||
| Пусть <tex>A_0(x_1) = \sum_{x_2 = 0}^{1}\sum_{x_3 = 0}^{1}...\sum_{x_n = 0}^{1} A(x_1, x_2, ..., x_n)</tex>. | Пусть <tex>A_0(x_1) = \sum_{x_2 = 0}^{1}\sum_{x_3 = 0}^{1}...\sum_{x_n = 0}^{1} A(x_1, x_2, ..., x_n)</tex>. | ||
| − | Попросим  | + | Попросим <tex>Prover</tex> прислать <tex>Verifier</tex>'у формулу <tex>A_0(x_1)</tex>. Её размер???. | 
| − | Проверим следующее утверждение:  | + | Проверим следующее утверждение: <tex>A_0(0) + A_0(1) = k</tex>. | 
| Шаг 1. | Шаг 1. | ||
| − | Пусть r_1 = random(p). Отправим r_1 программе Prover. | + | Пусть <tex>r_1 = random(p)</tex>. Отправим <tex>r_1</tex> программе <tex>Prover</tex>. | 
| Пусть <tex>A_1(x_2) = \sum_{x_3 = 0}^{1}\sum_{x_4 = 0}^{1}...\sum_{x_n = 0}^{1} A(r_1, x_2, ..., x_n)</tex>. | Пусть <tex>A_1(x_2) = \sum_{x_3 = 0}^{1}\sum_{x_4 = 0}^{1}...\sum_{x_n = 0}^{1} A(r_1, x_2, ..., x_n)</tex>. | ||
| − | Попросим  | + | Попросим <tex>Prover</tex> прислать <tex>Verifier</tex>'у формулу <tex>A_1(x_2)</tex>. | 
| − | Проверим следующее утверждение: A_1(0) + A_1(1) = A_0(r_1). | + | Проверим следующее утверждение: <tex>A_1(0) + A_1(1) = A_0(r_1)</tex>. | 
| Шаг 2. | Шаг 2. | ||
| Строка 48: | Строка 46: | ||
| ... | ... | ||
| − | Шаг n. | + | Шаг <tex>n</tex>. | 
| − | Пусть r_n = random(p). Отправим r_n программе Prover. | + | Пусть <tex>r_n = random(p)</tex>. Отправим <tex>r_n</tex> программе <tex>Prover</tex>. | 
| Пусть <tex>A_n() = A(r_1, r_2, ..., r_n)</tex>. | Пусть <tex>A_n() = A(r_1, r_2, ..., r_n)</tex>. | ||
| − | Попросим программу Prover прислать  | + | Попросим программу Prover прислать <tex>Verifier</tex>'у значение <tex>A_n()</tex>. | 
| − | Проверим следующее утверждение: A_n() =  | + | Проверим следующее утверждение: <tex>A_n() = A_{n-1}(r_n)</tex>. | 
| − | А также сами подставим r_1, r_2, ..., r_n в  | + | А также сами подставим <tex>r_1, r_2, ..., r_n</tex> в <tex>A(x_1, x_2, ..., x_n)</tex> и проверим правильность присланного значения <tex>A_n()</tex>. | 
| − | Возвращаем true. | + | Возвращаем <tex>true</tex>. | 
| − | Итак, остается доказать, что написанный Verifier - корректный Verifier для языка #SAT. То есть, нужно доказать: | + | Итак, остается доказать, что написанный <tex>Verifier</tex> - корректный <tex>Verifier</tex> для языка <tex>\#SAT</tex>. То есть, нужно доказать: | 
| − | # Построенный Verifier - вероятностная машина Тьюринга, совершающая не более полинома от длинны входа действий. | + | # Построенный <tex>Verifier</tex> - вероятностная машина Тьюринга, совершающая не более полинома от длинны входа действий. | 
| # <tex><\varphi, k> \in \#SAT \Rightarrow \exists P : P(VP(x)) \ge 2/3</tex>. | # <tex><\varphi, k> \in \#SAT \Rightarrow \exists P : P(VP(x)) \ge 2/3</tex>. | ||
| # <tex><\varphi, k> \notin \#SAT \Rightarrow \forall P : P(VP(x)) \le 1/3</tex>. | # <tex><\varphi, k> \notin \#SAT \Rightarrow \forall P : P(VP(x)) \le 1/3</tex>. | ||
| Доказательство: | Доказательство: | ||
| − | # Из программы Verifier видно, что она работает за O(n  | + | # Из программы <tex>Verifier</tex> видно, что она работает за <tex>O(n \cdot |input|) = O(poly(|input|))</tex>. | 
| − | # Если  | + | # Если <tex>\varphi</tex> имеет ровно <tex>k</tex> удовлетворяющих наборов, то существует программа <tex>Prover</tex>, такая что <tex>P(VP(x)) = 1</tex>. Такая программа: | 
| − | ## Присылает, например, первое простое число большее 2^n и сертификат. | + | ## Присылает, например, первое простое число большее <tex>max(2^n, k_p)</tex> и сертификат. | 
| − | ## Считает сумму A_0(x_1) и присылает формулу. | + | ## Считает сумму <tex>A_0(x_1)</tex> и присылает формулу. | 
| − | ## Получает r_1. | + | ## Получает <tex>r_1</tex>. | 
| − | ## Считает сумму A_1(x_2) и присылает формулу. | + | ## Считает сумму <tex>A_1(x_2)</tex> и присылает формулу. | 
| ## ... | ## ... | ||
| − | Ввиду того, что Prover все делает хорошо и нигде не ошибается, то Verifier дойдет до конца программы и вернет true. | + | Ввиду того, что <tex>Prover</tex> все делает хорошо и нигде не ошибается, то <tex>Verifier</tex> дойдет до конца программы и вернет <tex>true</tex>. | 
| − | # Пусть  | + | # Пусть <tex>\varphi</tex> имеет не <tex>k</tex> удовлетворяющих наборов. Тогда для того, что бы <tex>Verifier</tex> вернул <tex>true</tex>, необходимо <tex>Prover</tex>'у посылать такие <tex>A_i</tex>, чтобы выполнялись все проверяемые условия. Посмотрим на то, что он может послать: | 
| Шаг 0. | Шаг 0. | ||
| − | Так как  | + | Так как <tex>\varphi</tex> имеет не <tex>k</tex> удовлетворяющих наборов, то <tex>Prover</tex> не может послать правильное <tex>A_0</tex> – не выполнится условие <tex>A_0(0) + A_0(1) = k</tex>. Поэтому он посылает не <tex>A_0</tex>, а некое <tex>\tilde{A}_0</tex>. | 
| Шаг 1. | Шаг 1. | ||
| − | Во первых, отметим, что ситуация  | + | Во первых, отметим, что ситуация <tex>A_0(r_1) = \tilde{A}_0(r_1)</tex> происходит с вероятностью меньшей либо равной <tex>d / p</tex> для некоторого случайно выбранного <tex>r_1</tex>, что следует из [[Лемма_Шварца-Зиппеля|леммы Шварца-Зиппеля]]. То есть, с вероятностью большей либо равной <tex>1 - d / p : A_0(r_1) != \tilde{A}_0(r_1)</tex> и, ввиду того, что должно выполняться условие <tex>A_1(0) + A_1(1) = A_0(r_1)</tex>, получаем, что <tex>A_1</tex> тоже будет не правильное, т.е. некоторое <tex>\tilde{A}_1</tex>. | 
| ... | ... | ||
| − | Шаг n. | + | Шаг <tex>n</tex>. | 
| − | С вероятностью 1 - d / p  | + | С вероятностью <tex>1 - d / p : A_{n-1}(r_n) != \tilde{A}_{n-1}(r_n)</tex> и потому <tex>Verifier</tex> получит не <tex>A_n</tex>, а <tex>\tilde{A}_n</tex>. | 
| − | Из этого процесса заметим, что с вероятностью большей либо равной (1 - d / p) ^ n мы дойдем до последнего шага и будем имееть  | + | Из этого процесса заметим, что с вероятностью большей либо равной <tex>(1 - d / p) ^ n</tex> мы дойдем до последнего шага и будем имееть <tex>\tilde{A}_n</tex> вместо <tex>A_n</tex>. Так как на шаге <tex>n</tex> <tex>Verifier</tex> вычисляет <tex>A_n</tex> и проверяет значение, то <tex>Verifier</tex> вернет <tex>false</tex>.   | 
| − | Так как мы хотим сделать вероятность возврата false большую либо равную 2/3, то выберем k_p так, чтобы (1 - d / k_p) ^ n  | + | Так как мы хотим сделать вероятность возврата <tex>false</tex> большую либо равную <tex>2/3</tex>, то выберем <tex>k_p</tex> так, чтобы <tex>(1 - d / k_p) ^ n \ge 2/3</tex>.   | 
| Утверждение доказано. | Утверждение доказано. | ||
Версия 18:45, 22 апреля 2010
Определение
имеет удовлетворяющих наборов
Утверждение
Доказательство
Для доказательства будем строить вероятностную программу , которая хочет проверить, верно ли, что заданная формула имеет ровно удовлетворяющих наборов. Программа может совершить не больше полинома от длины входа действий, а также может обращаться к программе , которая пытается любым возможным способом убедить в верности рассматриваемого утверждения.
Далее в программе будем писать "проверим ...", что означает проверку соответствующего условия, и, при ложности, будет сразу завершаться и возвращать , т.к. её обманывает, а значит, нет правильного доказательства проверяемого утверждения.
будет выполнять следующие шаги.
Шаг 0.
Пусть формула каким либо образом записана. Пусть формула имеет переменных и степень . Сделаем следующие замены и получим формулу :
Заметим, что длина формулы возрастет не больше, чем в константу раз.
Итак, надо проверить следующее арифметическое уравнение: .
Попросим прислать 'у простое число и сертификат о его простоте. Проверим простоту по сертификату, и условие . Константу определим позднее.
Будем проверять уравнение по модулю .
Пусть .
Попросим прислать 'у формулу . Её размер???. Проверим следующее утверждение: .
Шаг 1.
Пусть . Отправим программе .
Пусть .
Попросим прислать 'у формулу . Проверим следующее утверждение: .
Шаг 2.
...
Шаг .
Пусть . Отправим программе .
Пусть .
Попросим программу Prover прислать 'у значение . Проверим следующее утверждение: . А также сами подставим в и проверим правильность присланного значения .
Возвращаем .
Итак, остается доказать, что написанный  - корректный  для языка . То есть, нужно доказать:
- Построенный - вероятностная машина Тьюринга, совершающая не более полинома от длинны входа действий.
- .
- .
Доказательство:
- Из программы видно, что она работает за .
-  Если  имеет ровно  удовлетворяющих наборов, то существует программа , такая что . Такая программа:
- Присылает, например, первое простое число большее и сертификат.
- Считает сумму и присылает формулу.
- Получает .
- Считает сумму и присылает формулу.
- ...
 
Ввиду того, что все делает хорошо и нигде не ошибается, то дойдет до конца программы и вернет .
- Пусть имеет не удовлетворяющих наборов. Тогда для того, что бы вернул , необходимо 'у посылать такие , чтобы выполнялись все проверяемые условия. Посмотрим на то, что он может послать:
Шаг 0.
Так как имеет не удовлетворяющих наборов, то не может послать правильное – не выполнится условие . Поэтому он посылает не , а некое .
Шаг 1.
Во первых, отметим, что ситуация происходит с вероятностью меньшей либо равной для некоторого случайно выбранного , что следует из леммы Шварца-Зиппеля. То есть, с вероятностью большей либо равной и, ввиду того, что должно выполняться условие , получаем, что тоже будет не правильное, т.е. некоторое .
...
Шаг .
С вероятностью и потому получит не , а .
Из этого процесса заметим, что с вероятностью большей либо равной мы дойдем до последнего шага и будем имееть вместо . Так как на шаге вычисляет и проверяет значение, то вернет .
Так как мы хотим сделать вероятность возврата большую либо равную , то выберем так, чтобы .
Утверждение доказано.
