-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstav.pm
132 lines (114 loc) · 4.47 KB
/
stav.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package stav;
use utf8;
use zakaz;
#------------------------------------------------------------------------------
# Přidá do stromu závislost a aktualizuje stromové globální proměnné.
#------------------------------------------------------------------------------
sub pridat_zavislost
{
my $anot = shift; # odkaz na pole hashů
my $stav = shift; # odkaz na hash
my $kandidat = shift; # odkaz na hash s položkami r, z, c a p
# Tahle část se dříve prováděla už na konci funkce generovat_stavy(), proto
# ji provést nejdříve.
# Pokud se přidává část koordinace, zajistit návaznost v příštích kolech.
if($kandidat->{priste} ne "" && $stav->{coord}[$kandidat->{r}]!=1)
{
$stav->{coord}[$kandidat->{r}] = 1;
# Pokud budujeme koordinaci, musíme zajistit, aby šla celá někam
# pověsit. Její kořen tedy musí vědět, jakého druhu jsou členové.
# Zapamatovat si, po kom má kořen koordinace "zdědit" slovní druh a pád.
$stav->{dedic}[$kandidat->{r}] = $kandidat->{z};
$stav->{uznck}[$kandidat->{r}] = $stav->{uznck}[$kandidat->{z}];
}
$stav->{priste} = $kandidat->{priste};
# Kvůli ladění si zapamatovat seznam povolených závislostí, ze kterého byla vybrána ta naše.
$stav->{vyber}[$kandidat->{z}] = join(",", $stav->{povol});
$stav->{rodic}[$kandidat->{z}] = $kandidat->{r};
$stav->{ndeti}[$kandidat->{r}]++;
$stav->{zbyva}--;
$stav->{nprid}++;
$stav->{maxc}[$kandidat->{z}] = $kandidat->{c};
$stav->{maxp}[$kandidat->{z}] = $kandidat->{p};
$stav->{pord}[$kandidat->{z}] = $stav->{nprid}; # Pořadí, kolikátý byl zvolen.
# Zapamatovat si, kdo byl přidán jako poslední, aby se to nemuselo hledat procházením {pord}.
$stav->{poslz} = $kandidat->{z};
zakaz::prehodnotit_zakazy($anot, $stav, $kandidat->{r}, $kandidat->{z});
}
#------------------------------------------------------------------------------
# Odstraní ze stromu závislost a aktualizuje stromové globální proměnné.
#------------------------------------------------------------------------------
sub zrusit_zavislost
{
my $stav = shift; # odkaz na hash
my $z = shift; # index závislého uzlu přidávané závislosti
my $r = $stav->{rodic}[$z];
return -1 if($r==-1);
# Kvůli ladění jsme si pamatovali seznam povolených závislostí, ze kterého byla vybrána ta naše.
$stav->{vyber}[$z] = "";
$stav->{rodic}[$z] = -1;
$stav->{ndeti}[$r]--;
$stav->{zbyva}++;
$stav->{nprid}--;
$stav->{poslz} = -1 if($stav->{poslz}==$z);
}
#------------------------------------------------------------------------------
# Uloží rozpracovaný strom i se všemi doplňujícími informacemi, aby se k němu
# bylo možné kdykoliv vrátit. Vrátí odkaz na uloženou kopii stavu analýzy.
#------------------------------------------------------------------------------
sub zduplikovat
{
my $stav = shift; # odkaz na stav analýzy
# Zkopírovat hodnoty stavu, aby nebyly dotčeny dalšími změnami stavu u volajícího.
# Kopírovat se musí hloubkově, tj. ne odkazy na pole uvnitř stavu, ale celé kopie polí!
return zduplikovat_hash($stav);
}
#------------------------------------------------------------------------------
# Vytvoří hloubkovou kopii pole.
#------------------------------------------------------------------------------
sub zduplikovat_pole
{
my $pole = shift;
my @duplikat;
for(my $i = 0; $i<=$#{$pole}; $i++)
{
if(ref($pole->[$i]) eq "ARRAY")
{
$duplikat[$i] = zduplikovat_pole($pole->[$i]);
}
elsif(ref($pole->[$i]) eq "HASH")
{
$duplikat[$i] = zduplikovat_hash($pole->[$i]);
}
else
{
$duplikat[$i] = $pole->[$i];
}
}
return \@duplikat;
}
#------------------------------------------------------------------------------
# Vytvoří hloubkovou kopii hashe.
#------------------------------------------------------------------------------
sub zduplikovat_hash
{
my $hash = shift;
my %duplikat;
while(my ($klic, $hodnota) = each(%{$hash}))
{
if(ref($hodnota) eq "ARRAY")
{
$duplikat{$klic} = zduplikovat_pole($hodnota);
}
elsif(ref($hodnota) eq "HASH")
{
$duplikat{$klic} = zduplikovat_hash($hodnota);
}
else
{
$duplikat{$klic} = $hodnota;
}
}
return \%duplikat;
}
1;