13. Динамично оптимиране

Разпознаване на контекстно свободен език [8.3.8]

Хедонийски език [8.3.9]

Програма за втоматична проверка на синтактичната коректност според следните правила:
0. Единствените символи в езика са p,q,r,s,t,u,v,w,x,y,z и N,C,D,E,I.
1. Всеки символ измежду p, q, r, s, t, u, v, w, x, y, z, взет отделно, представлява правилно изречение
на хедонийски език.
2. Ако S е правилно изречение, то NS също е.
3. Ако S и T са правилни изречения, то такива са и CST, DST, EST и IST.
4. Няма други правилни изречения, освен тези, получени по правила 0, 1, 2 и 3.

Реализация на 3:
F(i, j)  връща истина, ако частта от входното изречение (низа) si, si+1,..., sj е правилно изречение.
1. F(i, j) = 1, ако i = j и sj е { p, q, r, s, t, u, v, w, x, y, z }
2. F(i, j) = 1, ако si = N и F(i+1, j) = 1.
3. F(i, j) = 1, ако si е {C,D,E,I} съществува k, такова че F(i+1, k) = 1 и F(k+1, j) = 1
4. иначе F(i, j) = 0

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX 100
#define NOT_CALCULATED 2

unsigned char F[MAX][MAX]; /* Целева функция */
const char *s = "NNNNNNNNECINNxqpCDNNNNNwNNNtNNNNs"; /* За проверка */ unsigned n; /* Дължина на изречението */

void init(void)
{ unsigned i, j;

  n = strlen(s);
  for (i = 0; i < n; i++)
    for (j = 0; j < n; j++) F[i][j] = NOT_CALCULATED;
}

unsigned char check(unsigned st, unsigned en)
{ unsigned k;

  if (NOT_CALCULATED != F[st][en]) return F[st][en];
  else
  {

/**/
    if (st == en)

      F[st][en] = (s[st] >= 'p' && s[st] <= 'z');
    else if ('N' == s[st])

      F[st][en] = check(st + 1, en);
    else if('C' == s[st] || 'D' == s[st] || 'E' == s[st] || 'I' == s[st])
    {

      k = st + 1;
      while (k < en && !(check(st + 1, k) && check(k + 1, en))) k++;
      F[st][en] = (k != en);
    }
    else
F[st][en] = 0;
    return F[st][en];

  }
}

int main(void)
{ init();

  printf("\n %s", check(0,n-1) ? "correct!" : "incorrect!");
  return 0;
}


Формални системи

Даден е низът MI. От него, с прилагане на няколко правила, получаваме други низове, състоящи се от буквите M, I и U.
Правилата са:
1. Ако последната буква на низа е I, може да получим нов низ, като прибавим в края му U.
2. От низа Mx може да получим Mxx, където x е низ, състоящ се от трите букви.
3. Ако низ съдържа III, може да получим нов низ, като на мястото на III поставим U.
Въпросът е може ли да получим низа MU ?
Дъглас Хофстатър. Гьодел,  Ешер, Бах - една гирлянда към безкрайността, Изток-Запад, 2011.

Пример:
MI
MIU (1),  MII (2)
MIUIU (2), MIIU (1), MIIII (2)
MIUIUIUIU (2), MIIUIIU (2), MIIIIU (1), MIIIIIIII (2), MUI (3), MIU (3)
...