Nós estaremos tentando escrever um programa que se lembre do que está fazendo até agora e continue em direção ao seu objetivo, se abortado uma repetição. Este é um programa tenaz . Ele estará usando uma memória não volátil para armazenar informações entre as execuções, como um número de cits , que são bits, levando em consideração o que acontece no cancelamento. Certa vez, conjeturei que, com N cits , qualquer objetivo até o comprimento 2 (NK) é possível, para alguns pequenos K. fixos. Agora, estou inclinado a pensar que o objetivo não pode ser alcançado :-(
É solicitado um programa tenaz com objetivo 01
, que já é um objetivo não trivial ; ou uma prova rigorosa de impossibilidade.
Um programa tenaz é definido como aquele que:
- Sempre que executado , é executado a partir do mesmo ponto de entrada, sem entrada e pode compartilhar informações entre execuções exclusivamente por meio de
N
cits (definidos abaixo); todas as outras informações têm o mesmo conteúdo no início de cada execução, conteúdo imprevisível no início da execução, são imutáveis (o próprio programa) ou ilegíveis ( saída e valor anteriores ). - É tal que, quando executado dentro de uma sessão, ele detém (usando um recurso de seu idioma), dentro de algum atraso desde o início da execução, a menos que seja interrompido antes da interrupção; O cancelamento ocorre em qualquer instante arbitrário e impede a operação até outra execução (se houver).
- É tal que a concatenação em ordem cronológica dos caracteres que produz é a mesma sequência finita (o objetivo ) em qualquer sessão de arbitrariamente várias execuções compreendendo pelo menos uma execução em que o programa foi deixado em execução até parar.
- Emite caracteres usando um dispositivo que atomicamente : recebe um valor entre 0 1 2 3 colocado pelo programa e gera
0
(resp.1
) Valores entre 0 ou 2 (resp 1 ou 3) se e somente se esse valor for diferente do anterior valor put, assumido como 0 para o primeiro put em uma sessão.
Existem programas tenazes! Qualquer programa que simplesmente coloque um número fixo de vezes que um valor fixo válido e, em seguida, pare, é tenaz com a meta vazia (se o número ou o valor for 0), 0
(se o número for positivo e o valor for 2) ou 1
(caso contrário). Qualquer objetivo mais longo requer NVM.
Cada cit modela um bit NVM, levando em consideração o efeito de uma execução interrompida durante uma gravação no cit. A qualquer instante, um cit está em um dos três estados possíveis 0
1
ou U
. O valor lido de um cit é sempre 0 ou 1; também corresponde ao estado, a menos que U
. Um cit é inicializado para declarar 0
antes da primeira execução em uma sessão e, de outra forma, muda de estado apenas quando uma gravação é comandada pelo programa, com efeito dependendo do que está gravado, se a execução é interrompida durante a gravação ou não e da antigo estado de cit:
Former state 0 1 U Rationale given by hardware guru
Operation
Write 0 completed 0 0 0 Discharging returns cit to 0
Write 0 aborted 0 U U Aborted discharging leaves cit unspecified
Write 1 aborted U 1 U Aborted charging leaves cit unspecified
Write 1 completed 1 1 U Charging a non-discharged cit is inhibited
O HAL para o acima mencionado é declarado em C como:
/* file "hal.h" unspecified parameter values give undefined behavior */
#define N 26 /* number of cits */
void p(unsigned v); /* put value v; v<4 */
unsigned r(unsigned i); /* read from cit at i; returns 0 or 1; i<N. */
void w(unsigned i, unsigned b); /* write b to cit at i; b is 0 or 1; i<N. */
/* all functions return in bounded time unless aborted */
Nossa primeira tentativa de um programa tenaz com a meta 01
é:
#include "hal.h" /* discount this line's length */
main(){ /* entry point, no parameters or input */
if (r(3)==0) /* cit 3 read as 0, that is state 0 or U */
w(3,0), /* write 0 to cit 3, to ensure state 0 */
p(2); /* put 2 with output '0' initially */
w(3,1), /* mark we have output '0' (trouble spot!) */
p(1); /* put 1 with output '1' */
} /* halt (but we can be re-run) */
Murphy faz uma primeira sessão, deixa a primeira corrida parada e termina a sessão; a saída da sessão é a saída da execução única 01
; Por enquanto, tudo bem.
Em outra sessão, Murphy aborta uma primeira corrida durante w(3,1)
, deixando cit no estado U
; em uma segunda execução, Murphy decide que r(3)
é 1 (que cit está no estado U
) e deixa o programa em execução (observe como w(3,1)
não mudou o estado do cit); na terceira execução, Murphy decide que r(3)
é 0, aborta depois p(2)
e termina a sessão.
A saída concatenada da segunda sessão é 010
(um caractere por execução), mas é diferente da 01
primeira sessão, portanto, o programa não é tenaz, pois a condição 3 não é atendida.
O idioma é gratuito, adapte a interface C de acordo com o idioma. Selecionarei a melhor resposta com base no menor número de cits usados; o menor número de gravações no pior caso da execução para a saída (ou interromper se não houver saída); depois, o menor número de gravações antes de parar em uma sessão sem interrupção; programa mais curto. Conte apenas o código de chamada, não a interface ou sua implementação, que não é necessária. Uma prova rigorosa de impossibilidade eliminaria qualquer programa (e seria uma surpresa para mim) ; Eu selecionaria o mais simples de entender.
Verifique três vezes se o programa realmente cumpre a meta de acordo com 3, independentemente do número e instantes de abortos; isso é difícil!
Atualização: adicionei uma resposta de candidato . Sinta-se livre para rejeitar isso. Oh, hammar fez isso em minutos usando um programa sistemático!
Status : Até agora não temos solução; saiba com certeza que não há solução com 1 ou 2 cits; mas não há provas de impossibilidade com 3 ou mais citações. A declaração não foi encontrada ambígua. O problema teria uma solução se alterássemos ligeiramente a matriz cit (por exemplo, coloque 1 no canto inferior direito, caso em que o exemplo acima está correto).
fonte
Respostas:
Embora eu não tenha uma solução nem uma prova de impossibilidade, achei que publicaria meu equipamento de teste para quem quisesse brincar com isso, pois já desisti nesse momento.
É uma implementação dos programas de modelagem HAL como uma mônada de Haskell. Ele verifica a tenacidade fazendo uma pesquisa abrangente das sessões possíveis para verificar as sessões que 1. pararam uma vez sem produzir a saída correta ou 2. produziram uma saída que não é um prefixo da desejada ( também captura programas que produzem resultados infinitos).
Aqui está o programa de exemplo fornecido pelo OP convertido em Haskell.
E aqui está a saída correspondente, mostrando que o programa não é tenaz.
fonte
A menos que alguém possa encontrar um erro neste programa, acho que ele verifica e rejeita todos os programas relevantes de duas citações.
Argumento que basta considerar programas que leem todos os cits e ligam um número formado pelo conjunto. Cada ramo do comutador será uma série de gravações e colocações. Nunca há sentido colocar o mesmo número mais de uma vez em uma ramificação ou colocar o segundo dígito de saída antes do primeiro. (Estou moralmente certo de que não há sentido em emitir o primeiro dígito, exceto no início de uma ramificação ou o segundo dígito, exceto no final, mas por enquanto estou evitando essa simplificação).
Então, cada ramificação tem um conjunto de cits de destino que deseja definir e se move em direção a ela, definindo os bits que deseja que sejam 0 como 0 e os bits que deseja que sejam 1 como 0 e 1; essas operações de gravação podem ser ordenadas de várias maneiras. Não há nenhum ponto em definir um pouco para 1, a menos que você já o tenha definido como 0 nessa execução, ou provavelmente é um nop.
Considera 13680577296 programas possíveis; uma máquina de quatro núcleos demorou menos de 7 horas para verificá-las sem encontrar uma solução única.
fonte
Esta
éa minha melhor tentativa de responder a minha própria pergunta.Não tenho certeza de que atende ao requisito 3 e estou aberto a refutação.Não é tenaz :-(fonte
01
, Cits:110
. 2. Abortar durante o # 15. CITS:10U
. 3. Leiac = 1
, aborte durante o # 12. CITS:U0U
. 4. Leiac = 0
,d = 0
eo programa irá imprimir01
novamente.