Índice
Dividirei minha explicação do pseudocódigo de Tarjan nas seguintes seções:
- Os blocos If-else de Tarjan (os operadores
->
& |
)
- Testes de atribuição e igualdade (
:=
e =
)
- Existe
else if
, mas nenhuma else
construção
- Operador de atribuição condicional de Tarjan
:= if
Exemplos adicionais de Tarjan if
e:= if
5.5.
Matrizes Tarjan (ou listas)
Resumo dos Operadores
- Operador de flecha dupla de Tarjan (
⟷
)
- Os loops de Tarjan são como loops de C / Java
- Operador de atribuição condicional de Tarjan com todas as condições falsas
(1) Os blocos If-else de Tarjan
(os operadores →
e |
)
O if-else
construto é talvez a estrutura de controle mais fundamental na linguagem de Tarjan. Além dos blocos if-like C, o comportamento if-else está quase embutido nas atribuições de Tarjan e nos loops while de Tarjan. O operador de seta do Tarjan ->
(ou →) é um delimitador entre a condição de uma instrução if e o bloco de execução de uma instrução if.
Por exemplo, no idioma de Tarjan, podemos ter:
# Example One
if a = 4 → x := 9 fi
Se traduzirmos parcialmente a linha do código Tarjan acima em C ou Java, obteremos o seguinte:
if (a = 4)
x := 9
fi
Em vez de chaves entre chaves (como em C e Java), Tarjan encerra um if
-block com uma ortografia semelhante à ALGOL da palavra-chave:fi
Se continuarmos traduzindo nosso exemplo acima, obtemos:
if (a = 4) {
x := 9
}
(2) Testes de atribuição e igualdade ( :=
e =
)
Tarjan pega esses operadores da ALGOL (posteriormente vistos também em Pascal).
O Tarjan usa =
para testes de igualdade, não atribuições (portanto, funciona como Java ==
).
Para atribuição, o Tarjan usa :=
, que funciona como Java =
.
Assim, se continuarmos traduzindo nosso exemplo, teremos:
if (a == 4) {
x = 9
}
Uma barra vertical (ou "pipe" ou |
) na linguagem do Tarjan é equivalente à else if
palavra - chave em C ou Java.
Por exemplo, no idioma de Tarjan, podemos ter:
# Example Two
if a = 4 → x := 9 | a > 4 → y := 11 fi
O código Tarjan acima se traduz em:
if (a == 4) {
x = 9
}
else if (a > 4) {
y = 11
}
(3) else if
único e nenhum else
construto
Anteriormente, eu cobri o básico das if
declarações sem descrever as nuances. No entanto, não discutiremos um pequeno detalhe. A última cláusula em um if-else
bloco Tarjan-ian deve sempre conter um →
operador arrow ( ). Como tal, não existe apenas else
na língua de Tarjan else if
. A coisa mais próxima de um else
bloco na linguagem do Tarjan é fazer a condição de teste mais à direita true
.
if a = 4 → x := 9 | a > 4 → y := 11 | true → z := 99 fi
Em C / Java, teríamos:
if (a == 4) {
x = 9
}
else if (a > 4) {
y = 11
}
else { // else if (true)
z = 99
}
Exemplos são mais fáceis de entender do que descrições gerais. No entanto, agora que temos alguns exemplos em mente, saiba que o formal geral da construção if-else de Tarjan é o seguinte:
if condition
→ stuff to do
| condition
→ stuff to do
[...]
| condition
→ stuff to do
fi
O personagem |
é comoif else
O caractere →
separa a condição de teste das coisas a fazer.
(4) Operador de atribuição condicional da Tarjan := if
O Tarjan if
pode ser usado de duas maneiras muito diferentes. Até agora, descrevemos apenas um dos usos do Tarjaniano if
. Um tanto confuso, Tarjan ainda usa a notação / sintaxe if
para o segundo tipo de if
construção. Qual if
está sendo usado é baseado no contexto. Analisar o contexto é realmente muito fácil de fazer, pois o segundo tipo de Tarjan- if
é sempre pré-fixado por um operador de atribuição.
Por exemplo, podemos ter o seguinte código Tarjan:
# Example Three
x := if a = 4 → 9 fi
Iniciar digressão
Depois de trabalhar com o código Tarjan por um tempo, você se acostuma à ordem das operações. Se colocarmos parênteses na condição de teste no exemplo acima, obteremos:
x := if (a = 4) → 9 fi
a = 4
não é uma operação de atribuição. a = 4
é como a == 4
- retorna verdadeiro ou falso.
Digressão final
Pode ajudar a pensar := if
na sintaxe de um único operador, distinto :=
e if
Na verdade, vamos nos referir ao := if
operador como o operador de "atribuição condicional".
Para if
nós listamos (condition → action)
. Para := if
listamos (condition → value)
onde value
é teh valor mão do lado direito podemos atribuir à mão do lado esquerdolhs
# Tarjan Example Four
lhs := if (a = 4) → rhs fi
em C ou Java pode se parecer com:
# Example Four
if (a == 4) {
lhs = rhs
}
Considere o seguinte exemplo de "atribuição condicional" no código tarjaniano:
Instanciação Tarjan do Exemplo Cinco x: = a = 4 → 9 | a> 4 → 11 | verdadeiro → 99 fi
Em C / Java, teríamos:
// C/Java Instantiation of Example Five
if (a == 4) {
x = 9
}
else if (a > 4) {
x = 11
}
else if (true) { // else
x = 99
}
(5) Resumo dos operadores:
Até agora, temos:
:=
...... Operador de atribuição (C / Java =
)
=
...... Teste de igualdade (C / Java ==
)
→
...... Delimitador entre a condição de teste de um bloco if e o corpo de um bloco if
|
..... C / Java else-if
if ... fi
..... bloco if-else
:= if... fi
..... Atribuição condicional baseada em um bloco if-else
(5.5) Tarjan listas / matrizes:
O Tarjan's Language possui contêineres do tipo array embutidos. A sintaxe para matrizes Tarjan é muito mais intuitiva que a notação para if else
instruções Tarjan .
list1 := ['lion', 'witch', 'wardrobe'];
list2a := [1, 2, 3, 4, 5];
list2b := [1, 2];
list3 := ["a", "b", "c", "d"];
list4 := [ ]; # an empty array
Os elementos da matriz Tarjan são acessados com parênteses ()
, não entre colchetes[]
A indexação começa em 1
. Portanto,
list3 := ["a", "b", "c", "d"]
# list3(1) == "a" returns true
# list3(2) == "b" return true
Abaixo mostra como criar uma nova matriz contendo os 1º e 5º elementos de [1, 2, 3, 4, 5, 6, 7]
nums := [1, 2, 3, 4, 5, 6, 7]
new_arr := [nums(1), nums(5)]
O operador de igualdade é definido para matrizes. O código a seguir é impressotrue
x := false
if [1, 2] = [1, 2, 3, 4, 5] --> x := true
print(x)
A maneira de Tarjan testar se uma matriz está vazia é compará-la com uma matriz vazia
arr := [1, 2]
print(arr = [ ])
# `=` is equality test, not assignment
Pode-se criar uma visão (não copiar) de uma sub-matriz, fornecendo múltiplos índices ao operador ()
combinados com..
list3 := ["a", "b", "c", "d"]
beg := list3(.. 2)
# beg == ["a", "b"]
# beg(1) == "a"
end := list3(3..)
# end == ["c", "d"]
# end(1) == "c"
mid := list3(2..3)
# mid == ["b", "c"]
# mid(2) == "c"
# `list3(4)` is valid, but `mid(4)` is not
(6) Exemplos adicionais de Tarjan if
e:= if
A seguir, outros exemplos de uma atribuição condicional do Tarjan ( := if
):
# Tarjan Example Six
a := (false --> a | true --> b | false --> c1 + c2 | (2 + 3 < 99) --> d)
(true --> b)
é a (cond --> action)
cláusula mais à esquerda com uma condição verdadeira. Assim, o Exemplo Seis da atribuição original tem o mesmo comportamento de atribuição quea := b
Abaixo está o nosso exemplo mais complicado de código Tarjan até agora:
# Tarjan Example -- merge two sorted lists
list function merge (list s, t);
return if s =[] --> t
| t = [ ] --> s
| s != [ ] and t != [] and s(l) <= t(1) -->
[s(1)]& merge(s[2..], t)
| s != [ ]and t != [ ] and s(1) > r(l) -->
[t(1)] & merge (s,t(2..))
fi
end merge;
A seguir, uma tradução do código de Tarjan para mesclar duas listas classificadas. O seguinte não é exatamente C ou Java, mas é muito mais próximo do C / Java do que a versão Tarjan.
list merge (list s, list t) {
if (s is empty) {
return t;
}
else if (t is empty){
return s;
}
else if (s[1] <= t[1]) {
return CONCATENATE([s[1]], merge(s[2...], t));
else { // else if (s[1] > t[1])
return CONCATENATE ([t[1]], merge(s,t[2..]);
}
}
Abaixo está outro exemplo de código Tarjan e uma tradução em algo semelhante a C ou Java:
heap function meld (heap h1, h2);
return if h1 = null --> h2
| h2 = null --> h1
| h1 not null and h2 not null --> mesh (h1, h2)
fi
end meld;
Abaixo está a tradução C / Java:
HeapNode meld (HeapNode h1, HeapNode h2) {
if (h1 == null) {
return h2;
}
else if (h2 == null) {
return h1;
} else {
mesh(h1, h2)
}
} // end function
(7) Operador de flecha dupla de Tarjan ( <-->
)
Abaixo está um exemplo de código Tarjan:
x <--> y
O que um ⟷
operador de seta dupla ( ) faz no idioma do Tarjan?
Bem, quase todas as variáveis na linguagem do Tarjan são ponteiros.
<-->
é uma operação de troca. As seguintes impressõestrue
x_old := x
y_old := y
x <--> y
print(x == y_old) # prints true
print(y == x_old) # prints true
Após a execução x <--> y
, x
aponta para o objeto que y
costumava apontar e y
aponta para o objeto que x
costumava apontar.
Abaixo está uma instrução Tarjan usando o <-->
operador:
x := [1, 2, 3]
y := [4, 5, 6]
x <--> y
Abaixo está uma tradução do código Tarjan acima para o pseudocódigo alternativo:
Pointer X = address of array [1, 2, 3];
Pointer Y = address of array [4, 5, 6];
Pointer X_OLD = address of whatever X points to;
X = address of whatever Y points to;
Y = address of whatever X_OLD points to;
Como alternativa, poderíamos ter:
void operator_double_arrow(Array** lhs, Array** rhs) {
// swap lhs and rhs
int** old_lhs = 0;
old_lhs = lhs;
*lhs = *rhs;
*rhs = *old_lhs;
return;
}
int main() {
Array* lhs = new Array<int>(1, 2, 3);
Array* rhs = new Array<int>(4, 5, 6);
operator_double_arrow(&lhs, &rhs);
delete lhs;
delete rhs;
return 0;
}
Abaixo está um exemplo de uma das funções do Tarjan usando o ⟷
operador:
heap function mesh (heap nodes h1, h2);
if key(h1) > key(h2) → h1 ⟷ h2 fi;
right (h1) := if right(h1) = null → h2
|right(h1) ≠ null → mesh (right(h1), h2)
fi;
if rank (left (h1)) < rank (right (h1))
→ left(h1) ⟷ right(h1)
fi;
rank (h1) := rank(right(h1)) + 1;
return h1;
end mesh;
Abaixo está uma tradução da mesh
função de Tarjan em pseudo-código que não é C, mas parece mais com C (relativamente falando). O objetivo disso é ilustrar como o ⟷
operador do Tarjan funciona.
node pointer function mesh(node pointers h1, h2) {
if (h1.key) > h2.key) {
// swap h1 and h2
node pointer temp;
temp = h1;
h1 = h2;
h2 = temp;
}
// Now, h2.key <= h1.key
if (h1.right == null) {
h1.right = h2;
} else // h1.key != null {
h1.right = mesh(h1.right, h2);
}
if (h1.left.rank < h1.right.rank ) {
// swap h1.left and h1.right
node pointer temp;
temp = h1;
h1 = h2;
h2 = temp;
}
h1.rank = h1.right.rank + 1;
return h1;
}
(8) Os loops de Tarjan são como loops de C / Java
A linguagem if
e as for
construções de Tarjan são familiares para programadores de C / Java. No entanto, a palavra-chave Tarjan para um loop while é do
. Todos os do
loops terminam com a palavra-chave od
, que é a grafia inversa de do
. Abaixo está um exemplo:
sum := 0
do sum < 50 → sum := sum + 1
No pseudocódigo no estilo C, temos:
sum = 0;
while(sum < 50) {
sum = sum + 1;
}
O exposto acima não é exatamente correto. Um loop do Tarjan é realmente um C / Java while(true)
com um bloco if-else aninhado dentro. Uma tradução mais literal do código Tarjan é a seguinte:
sum = 0;
while(true) {
if (sum < 50) {
sum = sum + 1;
continue;
// This `continue` statement is questionable
}
break;
}
Abaixo, temos um Tarjan- do
loop mais complicado :
sum := 0
do sum < 50 → sum := sum + 1 | sum < 99 → sum := sum + 5
O pseudocódigo no estilo C / Java para o complicado Tarjan- do
loop é o seguinte:
sum = 0;
while(true) {
if (sum < 50) {
sum = sum + 1;
continue;
}
else if (sum < 99) {
sum = sum + 5;
continue;
}
break;
}
(9) Operador de atribuição condicional da Tarjan com todas as condições falsas
Embora a longa explicação acima cubra a maioria das coisas, algumas questões ainda não foram resolvidas. Espero que alguém mais algum dia escreva uma resposta nova e melhorada, com base na minha, que responda a esses dilemas.
Notavelmente, quando o operador de atribuição condicional := if
é usado e nenhuma condição é verdadeira, não sou o valor atribuído à variável.
x := if (False --> 1| False --> 2 | (99 < 2) --> 3) fi
Não tenho certeza, mas é possível que nenhuma atribuição seja feita para x
:
x = 0;
if (false) {
x = 1;
}
else if (false) {
x = 2;
}
else if (99 < 2) {
x = 3;
}
// At this point (x == 0)
Você pode exigir que a variável do lado esquerdo vista em uma := if
declaração seja declarada anteriormente. Nesse caso, mesmo que todas as condições sejam falsas, a variável ainda terá um valor.
Como alternativa, talvez todas as condições falsas representem um erro de tempo de execução. Outra alternativa é retornar um null
valor especial e armazenar null
no argumento esquerdo da atribuição.