Commit Graph

126 Commits

Author SHA1 Message Date
imaqtkatt
4b4b398139 Refactor String/Map functions 2024-03-22 13:23:43 -03:00
imaqtkatt
78fc259958 some fixes and add BMap data structure 2024-03-20 15:33:17 -03:00
imaqtkatt
56ec0f7951 add more List and Nat functions 2024-03-20 12:47:25 -03:00
imaqtkatt
22c3cf42ff refactor IO and HVM 2024-03-20 10:01:34 -03:00
imaqtkatt
af0ed6bb8d refactor BBT to new syntax 2024-03-20 09:28:46 -03:00
Victor Taelin
de14d56d3d Merge branch 'master' of github.com:HigherOrderCO/kind2 2024-03-18 17:02:39 -03:00
Victor Taelin
29d8338f4a unification fine polishments - see notes
1. Previously, the following term wouldn't type-check:

      match x = term {
        true: ct
        false: cf
      }

When `term` isn't a variable.

The reason is that the `match` syntax was desugared to:

    (~term _ ct cf)

Which, in general, results in the following check:

    true : ∀(P: Bool -> *) ∀(t: P true) ∀(f: P false) (P term)

    check _  :: Bool -> *
    check ct :: (_ true)
    check cf :: (_ false)
    check () :: (_ term)

    unify (_ term) == (P term)

This should generate the solution:

    _ = λx(P x)

But, when `term` isn't a variable (it could be a function call, or a ref, for
example), this fails to satisfy the pattern unification criteria. To fix that,
we just use a `let` to always create a variable before unifying, so that the
`match` syntax is desugared to:

      let x = term
      (~x _ ct cf)

Which solves the issue.

2. Previously, the following term wouldn't type-check:

    equal (a: Nat) (b: Nat) : Bool =
      match a with (b: Nat) {
        succ: match b {
          succ: (equal a.pred b.pred)
          zero: false
        }
        zero: match b {
          succ: false
          zero: true
        }
      }

After inspecting the type-checker output, I noticed the reason is due to how the
outer hole interacts with the inner hole. Specifically, after some computations
we eventually get to the following unification problem:

    unify _2 == (_3 b)

Here, there are two ways to solve this:

    _2 = (_3 b)

    or

    _3 = λx (_2)

Initially, it seems like both solutions are equivalent. Yet, by choosing the
first, we, later on, face the following problem:

    - (_3 (succ x))
    - Bool

Which violates the pattern unification requisites (for the same reason: `succ`
is a constructor, rather than a variable). A way to solve this problem would be
to simply invert the order, and use `_3 = λx (_2)` instead (done in the last
commit). That way, we'd have `(_3 (succ x))` reduce to just `_2`, which would
solve `_2 = Bool` and type-check fine. This is a quickfix though. I wonder if
there is a more principled approach that would let us avoid `(succ x)` to be
there at all.

Debug log: https://gist.github.com/VictorTaelin/6dd1a7167d5b7c8d5626c0f5b88c75a0
2024-03-18 16:59:21 -03:00
Victor Taelin
8c8c68cce9 fix repeated meta uids across refs 2024-03-18 14:53:47 -03:00
Victor Taelin
5571be7715
Update README.md 2024-03-15 23:38:31 -03:00
Victor Taelin
c7c4a0345a
Update README.md 2024-03-15 23:38:02 -03:00
Victor Taelin
9201bebc01 first kind2-hvm2 program run! sum-tree via fold 2024-03-15 23:06:44 -03:00
Victor Taelin
70288ef011 diff savida 2024-03-15 22:07:01 -03:00
Victor Taelin
0647ea9bc7 implicits args and stuff 2024-03-15 18:51:25 -03:00
Victor Taelin
dd6706a7d5 refactored CLI - by Claude3 2024-03-14 19:33:21 -03:00
Victor Taelin
6726b552b3 Merge branch 'LunaAmora-kind2-hvm2' 2024-03-14 18:32:10 -03:00
Victor Taelin
d98da0863e Merge branch 'kind2-hvm2' of https://github.com/LunaAmora/kind2 into LunaAmora-kind2-hvm2 2024-03-14 18:32:03 -03:00
Victor Taelin
f8ab510b1e Merge branch 'master' of github.com:HigherOrderCO/kind2 2024-03-14 18:27:06 -03:00
Victor Taelin
b061e8f3a3 HVM2 compiler WIP 2024-03-14 18:26:59 -03:00
Victor Taelin
f96624ddcb rename to_hs to to_hs_checker, to differentiate between compiling to hoas checker file, and the compiler to actually run 2024-03-14 17:34:38 -03:00
Victor Taelin
c918ee680e
Merge pull request #6 from Derenash/master
Updated BBT and other functions to fit new syntax
2024-03-14 17:14:47 -03:00
Derenash
867602746d
Merge branch 'HigherOrderCO:master' into master 2024-03-14 17:11:00 -03:00
Derenash
74ee9a3c97 fix Vector.concat using switch instead of match 2024-03-14 17:08:08 -03:00
Derenash
144c3210df Fix some syntaxes uses of switch +: to _: 2024-03-14 17:07:40 -03:00
Victor Taelin
4d421106bd update the README 2024-03-14 17:01:55 -03:00
Derenash
3ce20b7003 Merge branch 'master' of https://github.com/Derenash/kind2.0 2024-03-14 16:34:44 -03:00
Derenash
f4be6b5e45 Merge branch 'master' of https://github.com/Derenash/kind2.0 2024-03-14 16:31:59 -03:00
Derenash
357cc111a6 Fix typing in BBT.has.linear.kind2 2024-03-14 16:31:30 -03:00
Victor Taelin
65d9b7c6c4 fix long-switch 2024-03-14 16:28:56 -03:00
Victor Taelin
4639202430 long-switch notation, remove unused files 2024-03-14 16:19:00 -03:00
Victor Taelin
2666e5de0e U60 syntax without hashtag; numeric match now called switch 2024-03-14 13:35:03 -03:00
Victor Taelin
9cbaf6c4d5 prevent recursive holes (check condition 3) 2024-03-14 12:10:05 -03:00
Victor Taelin
057c8d51de fix equalSimilar not following described algo 2024-03-14 10:31:04 -03:00
LunaAmora
69bbdfc382 Update kind2.hvm2 to the latest changes 2024-03-14 09:05:21 -03:00
LunaAmora
f1615e4a6b Add Kind2.hvm2 and cli for choosing the runtime 2024-03-14 08:35:22 -03:00
Victor Taelin
981b8afe90 fix unchecked let 2024-03-14 00:21:21 -03:00
Victor Taelin
b489c148bf equal / refl syntax and stuff 2024-03-13 22:32:30 -03:00
Victor Taelin
3f1cdd2996 cleanup ai interactions 2024-03-13 16:21:24 -03:00
Victor Taelin
d059c82c1f ADTs & match - complete
ADTs can be defined with the syntax:

data Vector T (len: Nat)
| cons (len: Nat) (head: T) (tail: (Vector T len)) : (Vector T (Nat.succ len))
| nil : (Vector T Nat.zero)

Which will convert to the equivalent inductive λ-encoding (via self).

Pattern-matching has the syntax:

match x = expr with (a: A) (b: B) ... {
  ctr0: ret0
  ctr1: ret1
}: motive

The 'with' syntax is used to explicitly move values down the cases,
crating lambdas for them. This linearizes them (which avoids cloning)
and specializes their type w.r.t. the matched value, for proving.

We also allow a shorthand for top-level definitions, as:

foo (a: A) (b: B) ... : R =
  body

This will auto-add lambdas before 'body'. If 'body' is a pattern-match,
the lambdas will be automatically moved down, so this has the effect of
linearizing top-level args, without needing explicit 'with' annotations.
2024-03-13 15:05:52 -03:00
Victor Taelin
0c34404c0b use-declarations with shadowing 2024-03-12 18:01:12 -03:00
Victor Taelin
dc993b5de0 pattern-match syntax 2024-03-12 13:44:49 -03:00
Victor Taelin
24b83350c6 ADT syntax continuation 2024-03-12 11:55:09 -03:00
Victor Taelin
29de8994d2 progress on ADT parsing 2024-03-11 22:45:46 -03:00
Victor Taelin
76320ddb7f initial ADT formatter 2024-03-09 19:16:24 -03:00
Victor Taelin
dc5997bde8 list/nat syntax sugars, reorganizations 2024-03-09 17:59:39 -03:00
Victor Taelin
d617aeac49 cleanup 2024-03-08 19:10:37 -03:00
Victor Taelin
85ad65b026 use-notation
Now, there are two local binders:

let x = ...
use x = ...

The 'let' binder will create a local definition, type-check it, and
assign a name to it. When compiled, it will create 'dup' nodes.

The 'use' binder is just an alias. It will not bind a new variable, and,
when compiled, will create inline copies. Also, for type-checking, it
allows creating aliases that are definitionaly equal for the checker.
2024-03-08 17:39:37 -03:00
Victor Taelin
97015e9390 missing files? 2024-03-07 18:08:04 -03:00
Victor Taelin
f9a5bdb963 mixed checking order for better unification
on the `infer` function, we usually have something like this:

    infer (App f x) ctx =
      infer <- infer f ctx
      case infer of
        All a b -> do
          check x a ctx
          return $ out arg
        otherwise ->
          fail

this causes `x : a` to be happen before `infer (f x)` returns `b x`.
this is generally fine, but, in situations such as dependent
eliminations:

    λx (bool-elim ?A x t f) : (P x)

we really want `(elim ...)` to return `P x` BEFORE we check `t : ?A
true` and `t : ?A false`. that would allow the unification problem `?A x
== P x` to generate the solution `?A = λx (P x)` **before** the `t : ?A
true` check possibly fails.

being able to fill that metavar is very important for Kind2, since that
would allow us to omit motives in pattern-matches. because of that, I
think that the more sensible order is for infer to return its result
first, and then its inner checks occur. this is via a very lightweight
mechanism that consists of a list of suspended checks (`susp`), which we
push to inside `infer`, and fully consume inside `check`.

this is a middle-ground between checking in order (from left-to-right)
and a more complex suspension mechanism (involving dependency graphs).
with this simple solution, we're able to use metavars inside the motive
of dependent eliminations, greatly reducing the need for annotations in
practical code.
2024-03-06 22:29:33 -03:00
Victor Taelin
edbaf3048d simplified unification algorithm 2024-03-06 20:01:32 -03:00
Victor Taelin
c8bf072145 working hs 2024-03-06 11:35:17 -03:00