Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pretty-printing checked output is not equal to pretty-printing unchecked output #344

Open
timsueberkrueb opened this issue Nov 6, 2024 · 1 comment
Labels
bug Something isn't working

Comments

@timsueberkrueb
Copy link
Collaborator

Consider the following example:

-- | The Martin-Löf equality type.
data Eq(implicit a: Type, x y: a) {
    -- | The reflexivity constructor.
    Refl(implicit a: Type, x: a): Eq(a:=a, x, x)
}

-- | Proof of symmetry of equality.
def Eq(x, y).sym(implicit a: Type, x y: a): Eq(a:=a, y, x) {
    Refl(a, x) => Refl(a:=a, x)
}

Our dependent pattern matching substitutes the unification not only on the rhs's expected type but also on the rhs expression. This means that the AST changes during typechecking.
Therefore, it makes a difference whether we pretty-print the checked vs. the unchecked output:

cargo run -- fmt examples/foo.pol

-- | The Martin-Löf equality type.
data Eq(implicit a: Type, x y: a) {
    -- | The reflexivity constructor.
    Refl(implicit a: Type, x: a): Eq(a:=a, x, x)
}

-- | Proof of symmetry of equality.
def Eq(x, y).sym(implicit a: Type, x y: a): Eq(a:=a, y, x) { Refl(a, x) => Refl(a:=a, x) }

cargo run -- fmt --checked examples/foo.pol

-- | The Martin-Löf equality type.
data Eq(implicit a: Type, x y: a) {
    -- | The reflexivity constructor.
    Refl(implicit a: Type, x: a): Eq(a:=a, x, x)
}

-- | Proof of symmetry of equality.
def Eq(x, y).sym(implicit a: Type, x y: a): Eq(a:=a, y, x) { Refl(a, x) => Refl(a:=<a>, y) }
@timsueberkrueb timsueberkrueb added the bug Something isn't working label Nov 6, 2024
@BinderDavid
Copy link
Collaborator

Here is one idea I had about how to solve this: First, observe that substitution only changes variables. So we could change the AST node for variables to add an extra field:

struct Variable {
    ...,
    /// Elaborated due to dependent. pattern matching.
    elaborated: Option<Exp>
 }

And then we define an operation elaborate which is just like substitution, but fills in this elaboration instead of replacing the variable. We could also avoid code duplication by reusing the substitution code appropriately.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants