progress

[?]
Oct 23, 2023, 12:39 AM
75TM37DMPXA7YQPWZ4672OA3CUJNHYVIE5UFM2H6FHZMPGVMQS2AC

Dependencies

Change contents

  • edit in hwk1.typ at line 1
    [3.90545]
    [2.27]
    #set document(title: "Homework 1", author: "Michael Zhang <zhan4854@umn.edu>")
  • edit in hwk1.typ at line 4
    [3.90585]
    [3.90585]
    = Homework 1
    Michael Zhang \<zhan4854\@umn.edu\>
  • edit in hwk1.typ at line 9
    [3.90586]
    [2.51]
  • replacement in hwk1.typ at line 15
    [3.90635][3.90635:90647]()
    = Problem 1
    [3.90635]
    [3.90647]
    $#math.op("f")\(x)$
    == Problem 1
    $top : "Set"$
    $"case"_top$
  • replacement in hwk1.typ at line 25
    [3.90688][3.90688:90737]()
    $ "funsplit"(f, d) &equiv d("apply"(f, (x) x)) $
    [3.90688]
    [3.90737]
    $ "funsplit"(f, d) &equiv d((x) "apply"(f, x)) $
  • replacement in hwk1.typ at line 29
    [3.90802][3.90802:90888]()
    $ "funsplit"(lambda b, d) &equiv d( "apply"(lambda b, (x) x)) \
    &equiv d(((x)x)(b)) \
    [3.90802]
    [3.90888]
    $ "funsplit"(lambda b, d) &equiv d((x) "apply"(lambda b, x)) \
    &equiv d((x) (b(x))) \
  • edit in hwk1.typ at line 32
    [3.90902][2.139:267]()
    NOTE: Is it "cheating" in some sense, to use the identity abstraction $(x) x$ in the place of the last parameter to $"apply"$?
  • replacement in hwk1.typ at line 33
    [3.90903][3.90903:90915]()
    = Problem 2
    [3.90903]
    [3.90915]
    == Problem 2
  • replacement in hwk1.typ at line 104
    [2.2377][2.2377:2496]()
    axi[$x = y in NN [x in NN, y in NN]$],
    uni(right_label: "(3, 6)")[$"suc"(x) = "suc"(y) in NN [x in NN, y in NN]$],
    [2.2377]
    [2.2496]
    axi[$x in NN$],
    axi[$y in "Eq"(NN, "natrec"(x, 0, (u, v) "suc"(v)), x)$],
    bin(right_label: "(5)")[$"natrec"(x, 0, (u, v) "suc"(v)) = x in NN$],
    uni(right_label: "(3)")[$"suc"("natrec"(x, 0, (u, v) "suc"(v))) = "suc"(x) in NN$],
    uni(right_label: "natrec")[$"natrec"("suc"(x), 0, (u, v) "suc"(v))) = "suc"(x) in NN$],
  • replacement in hwk1.typ at line 111
    [2.2503][2.2503:2512]()
    $ #tree(
    [2.2503]
    [2.2512]
    $ #pad(left: -4em, tree(
  • replacement in hwk1.typ at line 118
    [2.2844][2.2844:2940]()
    uni[$"natrec"(x, "eq"_"0", "eq"_"suc") in "Eq"(NN, "natrec"(x, 0, (u, v) "suc"(v)), x)$],
    ) $
    [2.2844]
    [2.2940]
    uni(right_label: "(7, 9, 10)")[$"natrec"(x, "eq"_"0", "eq"_"suc") in "Eq"(NN, "natrec"(x, 0, (u, v) "suc"(v)), x)$],
    )) $
  • replacement in hwk1.typ at line 123
    [2.3050][2.3050:3132]()
    uni(right_label: "(5)")[$"natrec"(x, 0, (u, v) "suc"(v)) = x in NN [x in NN]$],
    [2.3050]
    [2.3132]
    uni(right_label: "(5, 11)")[$"natrec"(x, 0, (u, v) "suc"(v)) = x in NN [x in NN]$],
  • replacement in hwk1.typ at line 127
    [2.3216][2.3216:3229]()
    #pagebreak()
    [2.3216]
    [2.3229]
    // #pagebreak()
  • replacement in hwk1.typ at line 129
    [2.3230][2.3230:3253]()
    Then, we can use this:
    [2.3230]
    [2.3253]
    // Then, we can use this:
  • replacement in hwk1.typ at line 131
    [2.3254][2.3254:3290]()
    #set math.equation(numbering: none)
    [2.3254]
    [2.3290]
    // #set math.equation(numbering: none)
  • replacement in hwk1.typ at line 133
    [2.3291][2.3291:3415]()
    #tree(
    axi[$0 in NN$],
    uni(right_label: "(1)")[$0 = 0 in NN$],
    uni(right_label: "(3)")[$"eq"_0 in "Eq"(NN, 0, 0)$],
    )
    [2.3291]
    [2.3415]
    // #tree(
    // axi[$0 in NN$],
    // uni(right_label: "(1)")[$0 = 0 in NN$],
    // uni(right_label: "(3)")[$"eq"_0 in "Eq"(NN, 0, 0)$],
    // )
  • replacement in hwk1.typ at line 139
    [2.3416][2.3416:3525]()
    Using $C(x) = NN$ and the substitution-in-elements rule, we can prove that suc distributes over equivalence:
    [2.3416]
    [2.3525]
    // Using $C(x) = NN$ and the substitution-in-elements rule, we can prove that suc distributes over equivalence:
  • replacement in hwk1.typ at line 141
    [2.3526][2.3526:3630]()
    #tree(
    axi[$"suc"(x) in C(x) [x in NN]$],
    axi[$x = y in NN$],
    bin[$"suc"(x) = "suc"(y) in NN$],
    )
    [2.3526]
    [2.3630]
    // #tree(
    // axi[$"suc"(x) in C(x) [x in NN]$],
    // axi[$x = y in NN$],
    // bin[$"suc"(x) = "suc"(y) in NN$],
    // )
  • replacement in hwk1.typ at line 147
    [2.3631][2.3631:3657]()
    Then, convert this to Eq:
    [2.3631]
    [2.3657]
    // Then, convert this to Eq:
  • replacement in hwk1.typ at line 149
    [2.3658][2.3658:3781]()
    #tree(
    axi[$"suc"(x) = "suc"(y) in NN$],
    axi[$x = y in NN$],
    bin[$"eq"_"xy-suc" in "Eq"(NN, "suc"(x), "suc"(y))$],
    )
    [2.3658]
    [2.3781]
    // #tree(
    // axi[$"suc"(x) = "suc"(y) in NN$],
    // axi[$x = y in NN$],
    // bin[$"eq"_"xy-suc" in "Eq"(NN, "suc"(x), "suc"(y))$],
    // )
  • replacement in hwk1.typ at line 155
    [2.3782][2.3782:3853]()
    We can form a lambda term over eq objects using $lambda$-introduction:
    [2.3782]
    [2.3853]
    // We can form a lambda term over eq objects using $lambda$-introduction:
  • replacement in hwk1.typ at line 157
    [2.3854][2.3854:4066]()
    #tree(
    axi[$"eq"_"xy-suc" in "Eq"(NN, "suc"(x), "suc"(y)) ["eq"_"xy" in "Eq"(NN, x, y), x in NN, y in NN]$],
    uni[$lambda(("eq"_"xy") "eq"_"xy-suc") in "Eq"(NN, x, y) arrow.r "Eq"(NN, "suc"(x), "suc"(y))$],
    )
    [2.3854]
    [2.4066]
    // #tree(
    // axi[$"eq"_"xy-suc" in "Eq"(NN, "suc"(x), "suc"(y)) ["eq"_"xy" in "Eq"(NN, x, y), x in NN, y in NN]$],
    // uni[$lambda(("eq"_"xy") "eq"_"xy-suc") in "Eq"(NN, x, y) arrow.r "Eq"(NN, "suc"(x), "suc"(y))$],
    // )
  • replacement in hwk1.typ at line 162
    [2.4067][2.4067:4126]()
    This gives us what we need to perform induction over nats:
    [2.4067]
    [2.4126]
    // This gives us what we need to perform induction over nats:
  • replacement in hwk1.typ at line 164
    [2.4127][2.4127:4238]()
    #tree(
    axi[$"natrec"(x, "eq"_0, (u, v) "apply"(lambda(("eq"_"xy") "eq"_"xy-suc"), v)) [x in NN]$],
    uni[]
    )
    [2.4127]
    [2.4238]
    // #tree(
    // axi[$"natrec"(x, "eq"_0, (u, v) "apply"(lambda(("eq"_"xy") "eq"_"xy-suc"), v)) [x in NN]$],
    // uni[]
    // )
  • replacement in hwk1.typ at line 169
    [2.4239][2.4239:4330]()
    #tree(
    axi[$"i'm fucking stupid" equiv (x) "natrec"(x, 0, (u, v) "suc"(v))$],
    uni[],
    )
    [2.4239]
    [2.4330]
    // #tree(
    // axi[$"i'm fucking stupid" equiv (x) "natrec"(x, 0, (u, v) "suc"(v))$],
    // uni[],
    // )
  • replacement in hwk1.typ at line 174
    [2.4331][2.4331:4545]()
    #tree(
    axi[$"eq" in "Eq"(NN, "natrec"(x, 0, (u, v) "suc"(v)), x) [x in NN]$],
    uni[$"natrec"(x, 0, (u, v) "suc"(v)) = x in NN [x in NN]$],
    uni(right_label: "macro")[$plus.circle(x, 0) = x in NN [x in NN]$],
    )
    [2.4331]
    [3.91570]
    // #tree(
    // axi[$"eq" in "Eq"(NN, "natrec"(x, 0, (u, v) "suc"(v)), x) [x in NN]$],
    // uni[$"natrec"(x, 0, (u, v) "suc"(v)) = x in NN [x in NN]$],
    // uni(right_label: "macro")[$plus.circle(x, 0) = x in NN [x in NN]$],
    // )
  • replacement in hwk1.typ at line 180
    [3.91571][2.4546:4563]()
    ---
    #pagebreak()
    [3.91571]
    [2.4563]
    // ---
    // #pagebreak()
  • replacement in hwk1.typ at line 183
    [2.4564][3.91571:91574](),[3.91571][3.91571:91574](),[3.91574][2.4565:4617]()
    #{
    let split1 = [$"natrec" (x, 0, (u, v) "suc"(v))$]
    [2.4564]
    [2.4617]
    // #{
    // let split1 = [$"natrec" (x, 0, (u, v) "suc"(v))$]
  • replacement in hwk1.typ at line 186
    [2.4618][2.4618:4732]()
    tree(
    axi[$"natrec"(x, "refl", (u, v) ("ap" v)) [x in NN]$],
    uni[$split1 equiv x in NN [x in NN]$],
    )
    [2.4618]
    [2.4732]
    // tree(
    // axi[$"natrec"(x, "refl", (u, v) ("ap" v)) [x in NN]$],
    // uni[$split1 equiv x in NN [x in NN]$],
    // )
  • replacement in hwk1.typ at line 191
    [2.4733][2.4733:4908]()
    tree(
    // axi[$c in "Eq"(NN, split1, 0), x)$],
    axi[$split1 equiv x in NN [x in NN]$],
    uni(right_label: "macro")[$plus.circle(x, 0) equiv x in NN [x in NN]$],
    )
    [2.4733]
    [2.4908]
    // tree(
    // // axi[$c in "Eq"(NN, split1, 0), x)$],
    // axi[$split1 equiv x in NN [x in NN]$],
    // uni(right_label: "macro")[$plus.circle(x, 0) equiv x in NN [x in NN]$],
    // )
  • replacement in hwk1.typ at line 197
    [2.4909][2.4909:5023]()
    tree(
    axi[$c in "Eq"(NN, plus.circle(x, 0), x)$],
    uni[$plus.circle(x, 0) equiv x in NN [x in NN]$],
    )
    [2.4909]
    [2.5023]
    // tree(
    // axi[$c in "Eq"(NN, plus.circle(x, 0), x)$],
    // uni[$plus.circle(x, 0) equiv x in NN [x in NN]$],
    // )
  • replacement in hwk1.typ at line 202
    [2.5024][2.5024:5089]()
    tree(
    axi[$plus.circle(x, 0) equiv split1 [x in NN]$],
    )
    [2.5024]
    [3.91780]
    // tree(
    // axi[$plus.circle(x, 0) equiv split1 [x in NN]$],
    // )
  • replacement in hwk1.typ at line 206
    [3.91781][2.5090:5139]()
    tree(
    axi[$split1 equiv x [x in NN]$],
    )
    [3.91781]
    [2.5139]
    // tree(
    // axi[$split1 equiv x [x in NN]$],
    // )
  • replacement in hwk1.typ at line 210
    [2.5140][2.5140:5318](),[2.5318][3.92058:92059](),[3.92058][3.92058:92059]()
    tree(
    axi[$plus.circle(x, 0) equiv split1 [x in NN]$],
    axi[$split1 equiv x [x in NN]$],
    bin(right_label: "trans")[$plus.circle(x, 0) equiv x in NN [x in NN]$],
    )
    }
    [2.5140]
    // tree(
    // axi[$plus.circle(x, 0) equiv split1 [x in NN]$],
    // axi[$split1 equiv x [x in NN]$],
    // bin(right_label: "trans")[$plus.circle(x, 0) equiv x in NN [x in NN]$],
    // )
    // }
  • file addition: extraexercises.agda (----------)
    [3.2]
    module extraexercises where
    open import Data.Nat
    open import Relation.Binary.PropositionalEquality as Eq
    open Eq.≡-Reasoning
  • file addition: bidir (d--r------)
    [3.2]
  • file addition: data.ts (----------)
    [0.3429]
    /**
    * Terms e ::= x | () | λx. e | e e | (e : A)
    * Types A, B, C ::= 1 | α | ^α | ∀α. A | A → B
    * Monotypes τ, σ ::= 1 | α | ^α | τ → σ
    * Contexts Γ, ∆, Θ ::= · | Γ, α | Γ, x : A
    * | Γ, ^α | Γ, ^α = τ | Γ, I^α
    * Complete Contexts Ω ::= · | Ω, α | Ω, x : A
    * | Ω, ^α = τ | Ω, I^
    */
    export type Term =
    | { kind: "var"; name: string }
    | { kind: "unit" }
    | { kind: "lambda"; name: string; body: Term }
    | { kind: "app"; func: Term; arg: Term }
    | { kind: "annot"; term: Term; type: Type };
    export type Type =
    | { kind: "unit" }
    | { kind: "var"; name: string }
    | { kind: "existential"; name: string }
    | { kind: "poly"; name: string; type: Type }
    | { kind: "arrow"; input: Type; output: Type };
    export type Monotype =
    | { kind: "unit" }
    | { kind: "var"; name: string }
    | { kind: "existential"; name: string }
    | { kind: "arrow"; input: Monotype; output: Monotype };
    export type ContextEntry =
    | { kind: "typeVar"; name: string }
    | { kind: "termAnnot"; name: string; type: Type }
    | { kind: "existentialVar"; name: string }
    | { kind: "existentialSolved"; name: string; type: Monotype }
    | { kind: "marker"; name: string };
    export type CompleteContextEntry =
    | { kind: "typeVar"; name: string }
    | { kind: "termAnnot"; name: string; type: Type }
    | { kind: "existentialSolved"; name: string; type: Monotype }
    | { kind: "marker"; name: string };
  • file addition: contexts.ts (----------)
    [0.3429]
    // Helper functions for dealing with contexts
    import { ContextEntry, Type } from "./data";
    import { isEqual } from "lodash";
    /** Γ |- A (is the given type in this context?) */
    export function isTypeInContext(type: Type, ctx: ContextEntry[]): boolean {
    for (const entry of ctx) {
    switch (entry.kind) {
    case "termAnnot":
    if (isEqual(entry.type, type)) return true;
    break;
    default:
    continue;
    }
    }
    return false;
    }
  • file addition: bidir.ts (----------)
    [0.3429]
    import { isTypeInContext } from "./contexts";
    import { ContextEntry, Term, Type } from "./data";
    function check(
    ctx: ContextEntry[],
    term: Term,
    type: Type
    ): [boolean, ContextEntry[]] {
    switch (term.kind) {
    case "var":
    break;
    case "unit":
    return [type.kind === "unit", ctx];
    case "lambda": {
    // Get A and B first
    if (type.kind !== "arrow") return [false, ctx];
    const { input: A, output: B } = type;
    }
    case "app":
    break;
    case "annot":
    break;
    }
    }
    function synthesize(ctx: ContextEntry[], term: Term): [Type, ContextEntry[]] {
    switch (term.kind) {
    case "var": {
    const res = lookupTypeVariable(ctx, term.name);
    if (!res) throw new Error("wtf?");
    return [res, ctx];
    }
    case "unit":
    return [{ kind: "unit" }, ctx];
    case "lambda": {
    }
    case "app":
    break;
    case "annot": {
    // Require that the type exists
    if (!isTypeInContext(term.type, ctx))
    throw new Error("type doesn't exist");
    // Require that the term checks against the type
    const [result, outputCtx] = check(ctx, term.term, term.type);
    if (!result) throw new Error("invalid annotation: term doesn't check");
    return [term.type, outputCtx];
    }
    }
    }
    function synthesizeApp(
    ctx: ContextEntry[],
    funcType: Type,
    term: Term
    ): [Type, ContextEntry[]] {}