Po , zmieniłem moją relację Fixpoint
do wzajemnej relacji Inductive
, która "buduje" różne porównania między grami, zamiast "wiercić w dół".Dlaczego cewki indukcyjne muszą mieć te same parametry?
Ale teraz jestem otrzymaniu całkowicie nowy komunikat o błędzie:
Error: Parameters should be syntactically the same for each inductive type.
Myślę, że komunikat o błędzie mówiąc, że muszę te same dokładne parametry dla wszystkich tych wspólnych definicji indukcyjnych.
Zdaję sobie sprawę, że istnieją proste sposoby na obejście tego problemu (nieużywane zmienne typu dummy, długie typy funkcjonalne ze wszystkim wewnątrz forall
), ale nie rozumiem, dlaczego powinienem.
Czy ktoś może wyjaśnić logikę tego ograniczenia wzajemnych typów indukcyjnych? Czy istnieje bardziej elegancki sposób na napisanie tego? Czy to ograniczenie implikuje również, że indukcyjne wywołania do siebie muszą używać tych samych parametrów (w którym to przypadku nie znam żadnych hacków oprócz ohydnych ilości powielania kodu)?
(Definicje wszystkich rodzajach i kategoriach, takich jak compare_quest, gry, g1side itp pozostają niezmienione od tego, co było w moim first question.
Inductive gameCompare (c : compare_quest) : game -> game -> Prop :=
| igc : forall g1 g2 : game,
innerGCompare (nextCompare c) (compareCombiner c) (g1side c) (g2side c) g1 g2 ->
gameCompare c g1 g2
with innerGCompare (next_c : compare_quest) (cbn : combiner) (g1s g2s : side)
: game -> game -> Prop :=
| compBoth : forall g1 g2 : game,
cbn (listGameCompare next_c cbn (g1s g1) g2)
(gameListCompare next_c cbn g1 (g2s g2)) ->
innerGCompare next_c cbn g1s g2s g1 g2
with listGameCompare (c : compare_quest) (cbn : combiner) : gamelist -> game -> Prop :=
| emptylgCompare : cbn_init cbn -> forall g2 : game, listGameCompare c cbn emptylist g2
| otlgCompare : forall (g1_cdr : gamelist) (g1_car g2 : game),
(cbn (listGameCompare c cbn g1_cdr g2) (gameCompare c g1_car g2)) ->
listGameCompare c cbn (listCons g1_car g1_cdr) g2
with gameListCompare (c : compare_quest) (cbn : combiner) : game -> gamelist -> Prop :=
| emptyglCompare : cbn_init cbn -> forall g1 : game, gameListCompare c cbn g1 emptylist
| otglCompare : forall (g1 g2_car : game) (g2_cdr : gamelist),
(cbn (gameListCompare c cbn g1 g2_cdr) (gameCompare c g1 g2_car)) ->
gameListCompare c cbn g1 (listCons g2_car g2_cdr).
W CGT, zazwyczaj dwóch graczy (o nazwie Left
i Right
) na zmianę gry, w której gracz wygrywa ostatni ruch Każda gra (czyli każda pozycja w grze) może być odczytana jako zestaw opcji Left
i zestaw Right
opcji zapisanych jako {G_L | G_R}
. porównując dwie gry, można je porównać na cztery różne sposoby: <
, >
, =
lub ||
.
Gra jest A < B
, jeśli B
jest ściśle lepsza niż A
dla Left
, niezależnie od tego, kto pierwszy. A > B
, jeśli A
jest lepsze niż B
dla Left
. A = B
, jeśli dwie gry są równoważne (w tym sensie, że suma gier A + -B
jest grą zero, tak że gracz, który jako pierwszy przegrywa). I, A || B
, która gra jest lepsza dla Left
, zależy od tego, kto pierwszy.
Jednym ze sposobów, aby sprawdzić porównanie dwóch gier jest następujący:
A <= B
jeśli wszystkieA
„sLeft
dzieci są<| B
iA <|
wszystkichB
” Prawo dzieci s.A <| B
jeśliA
ma prawo dziecka, które jest<= B
czyA <=
któregokolwiek z lewych dzieciB
„s.I podobnie dla
>=
i>|
.
Tak więc widząc, która para tych stosunków zastosowanie do dwóch gier A
i B
, jest to możliwe do ustalenia, czy A < B
(A<=B
i A<|B
), A=B
(A<=B
i A>=B
) A > B
(A>=B
i A>|B
) lub A || B
(A<|B
i A>|B
).
Oto wiki article on CGT.
Dziękuję, to dobrze wiedzieć. Widzę problem i wiem, jak się go pozbyć (choć nie bez powielania kodu). Dodałem opis tego, co to znaczy porównać dwie gry CGT. na wypadek, gdybyś miał z tego jakieś inne pomysły. Jeszcze raz dziękuję – dspyz
Wow, to CGT jest naprawdę fajne! Dziękuję za wyjaśnienie nieco bardziej szczegółowo. Opublikowalem [gist] (https://gist.github.com/arthuraa/5882759) rozwijanie tego w Coq, może to ci pomoże! –