This commit is contained in:
rhiannon morris 2023-12-12 20:37:05 +01:00
parent b7f54594fb
commit aa36cbfd63
13 changed files with 615 additions and 42 deletions

55
day10.pl Normal file
View File

@ -0,0 +1,55 @@
:- use_module(library(dcg/basics)).
:- use_module(library(ugraphs)).
:- use_module(library(assoc)).
char(X, L, C0, L, C) -->
[X0], {X0 \= 0'\n, char_code(X, X0), C is C0 + 1}, !.
newline(L0, _, L, 0) --> "\n", {L is L0 + 1}.
empty(L, C0, L, C) --> char('.', L, C0, L, C).
pipe(Ds, L, C0, L, C) --> char(X, L, C0, L, C), {is_pipe(X, Ds)}.
start(L, C0, L, C) --> char('S', L, C0, L, C).
is_pipe('F', [down, right]).
is_pipe('L', [up, right]).
is_pipe('7', [down, left]).
is_pipe('J', [up, left]).
is_pipe('-', [left, right]).
is_pipe('|', [up, down]).
nonthing(L0, C0, L, C) --> empty(L0, C0, L, C).
nonthing(L0, C0, L, C) --> newline(L0, C0, L, C).
thing(s(L0, C0), L0, C0, L, C) --> start(L0, C0, L, C).
thing(p(P, L0, C0), L0, C0, L, C) --> pipe(P, L0, C0, L, C).
map([], L, C, L, C) --> [].
map(Xs, L0, C0, L, C) --> nonthing(L0, C0, L1, C1), map(Xs, L1, C1, L, C).
map([X|Xs], L0, C0, L, C) --> thing(X, L0, C0, L1, C1), map(Xs, L1, C1, L, C).
map(Xs) --> map(Xs, 0, 0, _, _).
insert(s(L, C), A0, A) :- put_assoc(L-C, A0, s, A).
insert(p(P, L, C), A0, A) :- put_assoc(L-C, A0, p(P), A).
make_assoc(Map, A) :-
empty_assoc(Start),
foldl(insert, Map, Start, A).
parse(File, A) :-
phrase_from_file(map(Map), File), !,
make_assoc(Map, A).
converse(up, down).
converse(down, up).
converse(left, right).
converse(right, left).
compat(p(Ds1), p(Ds2)) :- member(D1, Ds1), member(D2, Ds2), converse(D1, D2), !.
compat(s, p(_)).
compat(p(_), s).
% vim: set ft=prolog :

84
day12.pl Normal file
View File

@ -0,0 +1,84 @@
:- use_module(library(dcg/basics)).
:- use_module(library(dcg/high_order)).
ok([], [], []).
ok([T|Ts], Cs, [0'.|Rs]) :- can_empty(T), ok(Ts, Cs, Rs).
ok(Ts, [C|Cs], Rs) :- fill(Ts, C, Rs, Ts1, Rs1), ok(Ts1, Cs, Rs1).
fill([], 0, [], [], []).
fill([T|Ts], 0, [0'.|Rs], Ts, Rs) :- can_empty(T).
fill([T|Ts], C, [0'#|Rs], Ts1, Rs1) :-
C > 0, C1 is C - 1,
can_fill(T), fill(Ts, C1, Rs, Ts1, Rs1).
can_fill(0'#).
can_fill(0'?).
can_empty(0'.).
can_empty(0'?).
count(T, C, N) :- bagof(S, ok(T, C, S), Ss), length(Ss, N).
count(T-C, N) :- count(T, C, N).
examples1 :-
count(`???.###`, [1, 1, 3], 1),
count(`.??..??...?##.`, [1, 1, 3], 4),
count(`?#?#?#?#?#?#?#?`, [1, 3, 1, 6], 1),
count(`????.#...#...`, [4, 1, 1], 1),
count(`????.######..#####.`, [1, 6, 5], 4),
count(`?###????????`, [3, 2, 1], 10).
file(Lines) --> sequence(line, Lines).
line(T-C) --> template(T), " ", clues(C), blanks.
template(T) --> sequence(tchar, T).
tchar(T) --> [T], {member(T, `?#.`)}.
clues(C) --> sequence(number, ",", C).
part1(File) :-
phrase_from_file(file(TCs), File), !,
maplist(count, TCs, Ns),
foldl(plus, Ns, 0, N),
writeln(N).
/*
% oof ouch my stack
count_unfold(T-C, N) :-
unfold_template(T, T1),
unfold_clues(C, C1),
count(T1-C1, N).
unfold_template(T, R) :- unfold_template(5, T, R).
unfold_template(1, T, T) :- !.
unfold_template(N, T, R) :-
N > 1, N1 is N - 1,
unfold_template(N1, T, R1),
append(T, [0'?|R1], R).
unfold_clues(C, R) :- unfold_clues(5, C, R).
unfold_clues(1, C, C) :- !.
unfold_clues(N, C, R) :-
N > 1, N1 is N - 1,
unfold_clues(N1, C, R1),
append(C, R1, R).
examples2 :-
count_unfold(`???.###`-[1,1,3], 1),
count_unfold(`.??..??...?##.`-[1,1,3], 16384),
count_unfold(`?#?#?#?#?#?#?#?`-[1,3,1,6], 1),
count_unfold(`????.#...#...`-[4,1,1], 16),
count_unfold(`????.######..#####.`-[1,6,5], 2500),
count_unfold(`?###????????`-[3,2,1], 506250).
part2(File) :-
phrase_from_file(file(TCs), File), !,
maplist(count_unfold, TCs, Ns),
foldl(plus, Ns, 0, N),
writeln(N).
*/

View File

@ -77,3 +77,5 @@ part2(File) :-
bagof(R, gear(R), Rs),
sum(Rs, Total),
writeln(Total).
% vim: set ft=prolog :

24
day5.pl
View File

@ -20,8 +20,7 @@ part(p(From, To, Elems)) -->
header(From, To), blanks, blank_sep(map_line, Elems), blanks.
file1(Seeds, Parts) -->
seed_list(Seeds), blanks, many(part, Parts).
file1(Seeds, Parts) --> seed_list(Seeds), blanks, many(part, Parts).
parse1(Seeds, Parts, File) :- once(phrase_from_file(file1(Seeds, Parts), File)).
@ -65,4 +64,25 @@ part1(File) :-
writeln(L).
seed_ranges(Seeds) --> "seeds:", blanks, blank_sep(seed_range, Seeds).
seed_range(s(Lo, Len)) --> numbers([Lo, Len]).
file2(Seeds, Parts) --> seed_ranges(Seeds), blanks, many(part, Parts).
parse2(Seeds, Parts, File) :- once(phrase_from_file(file2(Seeds, Parts), File)).
min_range(To, Lo, Hi) :-
setof(r(Dest, Len),
From^Src^entry(From, To, Src, Dest, Len),
[r(Lo0, Len)|_]),
Hi0 is Lo0 + Len,
Hi1 is Lo0 - 1,
(Lo = Lo0, Hi = Hi0 ; Lo = 0, Hi = Hi1).
range_size(s(_, Len), Len).
seed_count(Seeds, N) :-
maplist(range_size, Seeds, Sizes),
foldl(plus, Sizes, 0, N).
% vim: set ft=prolog :

78
day9.quox Normal file
View File

@ -0,0 +1,78 @@
load "bool.quox"
load "list.quox"
load "maybe.quox"
load "int.quox"
def0 Int = scheme-int.Int
def zz = scheme-int.from- 0
def step : ω.(List Int) → List Int =
λ xs ⇒
list.zip-with-uneven Int Int Int (λ m n ⇒ scheme-int.minus n m)
xs (list.tail-or-nil Int xs)
def all-zero : ω.(List Int) → Bool =
list.foldlω Int Bool 'true (λ b n ⇒ bool.and b (scheme-int.eq n zz))
def last : 0.(A : ★) → ω.(List A) → Maybe A =
λ A ⇒ list.foldrω A (Maybe A) (Nothing A) (λ x y ⇒ maybe.or A y (Just A x))
def0 last-ok : last (4, 1, 4, 8, 5, 'nil) ≡ Just 5 : Maybe =
δ 𝑖 ⇒ Just 5
def last-or-0 : ω.(List Int) → Int =
λ xs ⇒ maybe.fold Int Int zz (λ x ⇒ x) (last Int xs)
def next-entry : ω.(List ) → Int =
λ xs ⇒
letω fuel = fst xs in
letω xs = list.map Int scheme-int.from- xs in
let result : Int =
caseω fuel return ω.(List Int) → Int of {
0 ⇒ λ _ ⇒ zz;
succ _, ω.rec ⇒ λ this ⇒
bool.if Int (all-zero this) zz
(letω next : List Int = step this in
letω diff : Int = rec next in
scheme-int.plus diff (last-or-0 this))
} xs in
result
def sumZ = list.foldr Int Int zz scheme-int.plus
{-
def0 ok-1 : next-entry (6, 0, 3, 6, 9, 12, 15, 'nil) ≡ 18 : = δ _ ⇒ 18
def0 ok-2 : next-entry (6, 1, 3, 6, 10, 15, 21, 'nil) ≡ 28 : = δ _ ⇒ 28
def0 ok-3 : next-entry (6, 10, 13, 16, 21, 30, 45, 'nil) ≡ 68 : = δ _ ⇒ 68
-}
load "io.quox"
load "string.quox"
def read-file : ω.String → IO [ω.List (List )] =
λ path ⇒
letω split-lines : ω.String → List String =
string.split (λ c ⇒ char.eq c char.newline);
split-numbers : ω.String → List = λ str ⇒
let words = string.split char.ws? str in
list.map String string.to--or-0 words;
split-file : ω.String → [ω. List (List )] = λ str ⇒
[list.mapω String (List ) split-numbers (split-lines str)] in
io.mapω String [ω.List (List )] split-file (io.read-fileω path)
def FILE : String = "in/day9"
#[main]
def part1 =
io.bindω (List (List )) True
(read-file FILE)
(λ lists ⇒ io.dump Int (sumZ (list.mapω (List ) Int next-entry lists)))
def part2 : IO True =
letω next-entry-r : ω.(List ) → Int = λ xs ⇒ next-entry (list.reverse xs) in
io.bindω (List (List )) True
(read-file FILE)
(λ lists ⇒ io.dump Int (sumZ (list.mapω (List ) Int next-entry-r lists)))

88
day9.tooslow.quox Normal file
View File

@ -0,0 +1,88 @@
load "bool.quox"
load "list.quox"
load "maybe.quox"
load "int.quox"
def zz = int.zero
def step : ω.(List ) → List =
λ xs ⇒
list.zip-with-uneven (λ m n ⇒ int.minus n m)
xs (list.tail-or-nil xs)
def all-zero : ω.(List ) → Bool =
list.foldlω Bool 'true (λ b n ⇒ bool.and b (int.eq n zz))
def last : 0.(A : ★) → ω.(List A) → Maybe A =
λ A ⇒ list.foldrω A (Maybe A) (Nothing A) (λ x y ⇒ maybe.or A y (Just A x))
def0 last-ok : last (4, 1, 4, 8, 5, 'nil) ≡ Just 5 : Maybe =
δ 𝑖 ⇒ Just 5
def last-or-0 : ω.(List ) → =
λ xs ⇒ maybe.fold zz (λ x ⇒ x) (last xs)
{-
def next-entries : ω.(List ) → List =
λ xs ⇒
letω fuel = fst xs in
caseω fuel return ω.(List ) → List of {
0 ⇒ λ _ ⇒ list.Nil ;
succ _, ω.rec ⇒ λ this ⇒
bool.if (List ) (all-zero this) (list.Nil )
(letω next : List = step this in
letω rest : List = rec next in
letω new : = nat.plus (last-or-0 this) (head-or-0 rest) in
list.Cons new rest)
} xs
-}
def next-entry : ω.(List ) → =
λ xs ⇒
letω fuel = fst xs in
letω xs = list.map int.from- xs in
let result : =
caseω fuel return ω.(List ) → of {
0 ⇒ λ _ ⇒ zz;
succ _, ω.rec ⇒ λ this ⇒
bool.if (all-zero this) zz
(letω next : List = step this in
letω diff : = rec next in
int.plus diff (last-or-0 this))
} xs in
int.abs result
def0 ok-1 : next-entry (6, 0, 3, 6, 9, 12, 15, 'nil) ≡ 18 : = δ _ ⇒ 18
def0 ok-2 : next-entry (6, 1, 3, 6, 10, 15, 21, 'nil) ≡ 28 : = δ _ ⇒ 28
def0 ok-3 : next-entry (6, 10, 13, 16, 21, 30, 45, 'nil) ≡ 68 : = δ _ ⇒ 68
load "io.quox"
load "string.quox"
def read-file : ω.String → IO [ω.List (List )] =
λ path ⇒
letω split-lines : ω.String → List String =
string.split (λ c ⇒ char.eq c char.newline);
split-numbers : ω.String → List = λ str ⇒
let words = string.split char.ws? str in
list.map String string.to--or-0 words;
split-file : ω.String → [ω. List (List )] = λ str ⇒
[list.mapω String (List ) split-numbers (split-lines str)] in
io.mapω String [ω.List (List )] split-file (io.read-fileω path)
def FILE : String = "in/day9"
-- #[main]
def doot =
io.bindω (List (List )) True
(read-file FILE)
(λ lists ⇒ io.dump (List (List )) lists)
#[main]
def part1 =
io.bindω (List (List )) True
(read-file FILE)
(λ lists ⇒ io.dump (list.sum (list.mapω (List ) next-entry lists)))

View File

@ -75,6 +75,9 @@ def0 Dec : ★ → ★ = λ A ⇒ Either [0.A] [0.Not A]
def Yes : 0.(A : ★) → 0.A → Dec A = λ A y ⇒ Left [0.A] [0.Not A] [y]
def No : 0.(A : ★) → 0.(Not A) → Dec A = λ A n ⇒ Right [0.A] [0.Not A] [n]
def yes-refl : 0.(A : ★) → 0.(x : A) → Dec (x ≡ x : A) =
λ A x ⇒ Yes (x ≡ x : A) (δ 𝑖 ⇒ x)
def0 DecEq : ★ → ★ =
λ A ⇒ ω.(x : A) → ω.(y : A) → Dec (x ≡ y : A)

149
lib/int.quox Normal file
View File

@ -0,0 +1,149 @@
load "nat.quox"
namespace int {
def0 Sign : ★ = {pos, neg-succ}
def0 : ★ = Sign ×
def from- : = λ n ⇒ ('pos, n)
def neg- : =
λ n ⇒ case n return of { 0 ⇒ ('pos, 0); succ n ⇒ ('neg-succ, n) }
def zero : = ('pos, 0)
def match : 0.(A : ★) → ω.(pos neg : → A) → → A =
λ A pos neg x ⇒
case x return A of { (s, x) ⇒
case s return A of { 'pos ⇒ pos x; 'neg-succ ⇒ neg x }
}
def negate : =
match neg- (λ x ⇒ from- (succ x))
def minus-- : =
λ m n ⇒
letω f : ω. → ω. = λ m n ⇒
bool.if (nat.ge m n) (from- (nat.minus m n))
(neg- (nat.minus n m)) in
getω (app2ω f (nat.dup m) (nat.dup n))
def plus- : =
match () (λ x n ⇒ from- (nat.plus x n))
(λ x n ⇒ minus-- n (succ x))
def minus- : =
match () minus-- (λ x n ⇒ ('neg-succ, nat.plus x n))
def plus : =
match () (λ x y ⇒ plus- y x) (λ x y ⇒ minus- y (succ x))
def minus : = λ x y ⇒ plus x (negate y)
def dup-sign : Sign → [ω. Sign] =
λ s ⇒ case s return [ω. Sign] of {
'pos ⇒ ['pos];
'neg-succ ⇒ ['neg-succ]
}
def0 dup-sign-ok : (s : Sign) → dup-sign s ≡ [s] : [ω. Sign] =
λ s ⇒ case s return s' ⇒ dup-sign s' ≡ [s'] : [ω. Sign] of {
'pos ⇒ δ 𝑖 ⇒ ['pos];
'neg-succ ⇒ δ 𝑖 ⇒ ['neg-succ]
}
def dup : → [ω.] =
λ x ⇒ case x return [ω.] of { (s, n) ⇒
app2ω Sign (λ s n ⇒ (s, n)) (dup-sign s) (nat.dup n)
}
def0 dup-ok : (x : ) → dup x ≡ [x] : [ω.] =
λ x ⇒
case x return x' ⇒ dup x' ≡ [x'] : [ω.] of { (s, n) ⇒ δ 𝑖
app2ω Sign (λ s n ⇒ (s, n)) (dup-sign-ok s @𝑖) (nat.dup-ok n @𝑖)
}
def times- : =
match ()
(λ m n ⇒ from- (nat.times m n))
(λ m' n ⇒ neg- (nat.times (succ m') n))
def times : =
match () (λ p x ⇒ times- x p) (λ n x ⇒ negate (times- x (succ n)))
def abs : = match (λ p ⇒ p) (λ n ⇒ succ n)
def pair-eq? : 0.(A B : ★) → ω.(DecEq A) → ω.(DecEq B) → DecEq (A × B) =
λ A B eqA? eqB? x y ⇒
let0 Ret : ★ = x ≡ y : (A × B) in
letω a0 = fst x; a1 = fst y;
b0 = snd x; b1 = snd y in
dec.elim (a0 ≡ a1 : A) (λ _ ⇒ Dec Ret)
(λ ya ⇒
dec.elim (b0 ≡ b1 : B) (λ _ ⇒ Dec Ret)
(λ yb ⇒ Yes Ret (δ 𝑖 ⇒ (ya @𝑖, yb @𝑖)))
(λ nb ⇒ No Ret (λ eq ⇒ nb (δ 𝑖 ⇒ snd (eq @𝑖))))
(eqB? b0 b1))
(λ na ⇒ No Ret (λ eq ⇒ na (δ 𝑖 ⇒ fst (eq @𝑖))))
(eqA? a0 a1)
def sign-eq? : DecEq Sign =
λ x y ⇒
let0 disc : Sign → ★ =
λ s ⇒ case s return ★ of { 'pos ⇒ True; 'neg-succ ⇒ False } in
case x return x' ⇒ Dec (x' ≡ y : Sign) of {
'pos ⇒
case y return y' ⇒ Dec ('pos ≡ y' : Sign) of {
'pos ⇒ dec.yes-refl Sign 'pos;
'neg-succ ⇒
No ('pos ≡ 'neg-succ : Sign)
(λ eq ⇒ coe (𝑖 ⇒ disc (eq @𝑖)) 'true)
};
'neg-succ ⇒
case y return y' ⇒ Dec ('neg-succ ≡ y' : Sign) of {
'neg-succ ⇒ dec.yes-refl Sign 'neg-succ;
'pos ⇒
No ('neg-succ ≡ 'pos : Sign)
(λ eq ⇒ coe (𝑖 ⇒ disc (eq @𝑖)) @1 @0 'true)
}
}
#[compile-scheme "(lambda% (x y) (if (equal? x y) Yes No))"]
def eq? : DecEq = pair-eq? Sign sign-eq? nat.eq?
def eq : ω. → ω. → Bool =
λ x y ⇒ dec.bool (x ≡ y : ) (eq? x y)
}
def0 = int.
namespace scheme-int {
postulate0 Int : ★
#[compile-scheme "(lambda (x) x)"]
postulate from- : → Int
#[compile-scheme "(lambda% (x y) (+ x y))"]
postulate plus : Int → Int → Int
#[compile-scheme "(lambda% (x y) (- x y))"]
postulate minus : Int → Int → Int
#[compile-scheme "(lambda% (x y) (* x y))"]
postulate times : Int → Int → Int
#[compile-scheme "(lambda% (x y) (if (= x y) 'true 'false))"]
postulate eq : Int → Int → Bool
#[compile-scheme "abs"]
postulate abs : Int →
}

View File

@ -23,6 +23,9 @@ def bindω : 0.(A B : ★) → IO [ω.A] → (ω.A → IO B) → IO B =
def map : 0.(A B : ★) → (A → B) → IO A → IO B =
λ A B f m ⇒ bind A B m (λ x ⇒ pure B (f x))
def mapω : 0.(A B : ★) → (ω.A → B) → IO [ω.A] → IO B =
λ A B f m ⇒ bindω A B m (λ x ⇒ pure B (f x))
def seq : 0.(B : ★) → IO True → IO B → IO B =
λ B x y ⇒ bind True B x (λ u ⇒ case u return IO B of { 'true ⇒ y })
@ -33,7 +36,7 @@ def pass : IO True = pure True 'true
#[compile-scheme "(lambda (str) (builtin-io (display str) 'true))"]
postulate print : String → IO True
#[compile-scheme "(lambda (str) (builtin-io (display str) (newline) 'true))"]
#[compile-scheme "(lambda (str) (builtin-io (write str) (newline) 'true))"]
postulate dump : 0.(A : ★) → A → IO True
def newline = print "\n"

View File

@ -111,6 +111,29 @@ def zip-withω : 0.(A B C : ★) → ω.(ω.A → ω.B → C) →
λ A B C f ⇒
elimω2 A B (λ n _ _ ⇒ Vec n C) 'nil (λ a b _ _ _ abs ⇒ (f a b, abs))
def0 ZipWithFailure : (m n : ) → (A B : ★) → Vec m A → Vec n B → ★ =
λ m n A B xs ys ⇒ Sing (Vec m A) xs × Sing (Vec n B) ys × [0. Not (m ≡ n : )]
def zip-with-het : 0.(A B C : ★) → ω.(A → B → C) →
ω.(m : ) → (xs : Vec m A) →
ω.(n : ) → (ys : Vec n B) →
Either (ZipWithFailure m n A B xs ys)
(Vec n C × [0. m ≡ n : ]) =
λ A B C f m xs n ys ⇒
let0 TNo : Vec m A → Vec n B → ★ = λ xs ys ⇒ ZipWithFailure m n A B xs ys;
TYes : ★ = Vec n C × [0. m ≡ n : ];
TRes : Vec m A → Vec n B → ★ = λ xs ys ⇒ Either (TNo xs ys) TYes in
dec.elim (m ≡ n : )
(λ _ ⇒ (xs : Vec m A) → (ys : Vec n B) → TRes xs ys)
(λ eq xs ys ⇒
let zs : Vec n C =
zip-with A B C f n (coe (𝑖 ⇒ Vec (eq @𝑖) A) xs) ys in
Right (TNo xs ys) TYes (zs, [eq]))
(λ neq xs ys ⇒ Left (TNo xs ys) TYes
(sing (Vec m A) xs, sing (Vec n B) ys, [neq]))
(nat.eq? m n) xs ys
#[compile-scheme "(lambda% (n xs) xs)"]
def up : 0.(A : ★) → (n : ) → Vec n A → Vec¹ n A =
λ A n ⇒
@ -311,11 +334,8 @@ def length : 0.(A : ★) → ω.(List A) → =
λ A xs ⇒ fst xs
def0 ZipWithFailureVec : (m n : ) → (A B : ★) → Vec m A → Vec n B → ★ =
λ m n A B xs ys ⇒ Sing (Vec m A) xs × Sing (Vec n B) ys × [0. Not (m ≡ n : )]
def0 ZipWithFailure : (A B : ★) → List A → List B → ★ =
λ A B xs ys ⇒ ZipWithFailureVec (fst xs) (fst ys) A B (snd xs) (snd ys)
λ A B xs ys ⇒ vec.ZipWithFailure (fst xs) (fst ys) A B (snd xs) (snd ys)
{-
-- unfinished
@ -376,6 +396,10 @@ def zip-with-uneven :
} xs ys
def sum : List = foldl 0 nat.plus
def product : List = foldl 1 nat.times
{-
-- unfinished
def zip-with : 0.(A B C : ★) → ω.(A → B → C) →
@ -422,11 +446,10 @@ postulate0 SchemeList : ★ → ★
postulate from-scheme : 0.(A : ★) → SchemeList A → List A
#[compile-scheme
"(lambda (list)
(let loop [(acc '()) (list (cdr list))]
(if (pair? list)
(loop (cons (car list) acc) (cdr list))
(reverse acc))))"]
"(lambda (lst)
(do [(lst (cdr lst) (cdr lst))
(acc '() (cons (car lst) acc))]
[(equal? lst 'nil) (reverse acc)]))"]
postulate to-scheme : 0.(A : ★) → List A → SchemeList A
}

View File

@ -87,6 +87,29 @@ def0 Sing : (A : ★) → A → ★ =
def sing : 0.(A : ★) → (x : A) → Sing A x =
λ A x ⇒ (x, [δ _ ⇒ x])
def0 Dup : (A : ★) → A → ★ =
λ A x ⇒ [ω. Sing A x]
def dup-from-parts :
0.(A : ★) →
(dup : A → [ω.A]) →
0.(prf : (x : A) → dup x ≡ [x] : [ω.A]) →
(x : A) → Dup A x =
λ A dup prf x ⇒
case dup x return x! ⇒ 0.(x! ≡ dup x : [ω.A]) → [ω. Sing A x] of {
[x'] ⇒ λ eq ⇒
let0 prf'-ω : [x'] ≡ [x] : [ω.A] =
trans [ω.A] [x'] (dup x) [x] eq (prf x);
prf' : x' ≡ x : A =
δ 𝑖 ⇒ getω A (prf'-ω @𝑖) in
[(x', [prf'])]
} (δ 𝑖 ⇒ dup x)
def drop-from-dup :
0.(A : ★) → (A → [ω.A]) → 0.(B : ★) → A → B → B =
λ A dup B x y ⇒ case dup x return B of { [_] ⇒ y }
namespace sing {
def val : 0.(A : ★) → 0.(x : A) → Sing A x → A =
@ -107,4 +130,6 @@ def app : 0.(A B : ★) → 0.(x : A) →
case sg return Sing B (f x) of { (x_, eq) ⇒
case eq return Sing B (f x) of { [eq] ⇒ (f x_, [δ 𝑖 ⇒ f (eq @𝑖)]) }
}
}

View File

@ -57,22 +57,31 @@ def elim-pairω :
}
}
#[compile-scheme "(lambda (n) (cons n 'erased))"]
def dup! : (n : ) → [ω. Sing n] =
λ n ⇒
case n return n' ⇒ [ω. Sing n'] of {
zero ⇒ [(zero, [δ _ ⇒ zero])];
succ n, d ⇒
appω (Sing n) (Sing (succ n))
(λ n' ⇒ sing.app n (λ n ⇒ succ n) n') d
};
def succ-boxω : [ω.] → [ω.] =
λ n ⇒ case n return [ω.] of { [n] ⇒ [succ n] }
#[compile-scheme "(lambda (n) n)"]
def dup : → [ω.] =
λ n ⇒ appω (Sing n) (λ n' ⇒ sing.val n n') (dup! n);
λ n ⇒ case n return [ω.] of {
0 ⇒ [0];
succ _, n! ⇒ succ-boxω n!
}
def0 dup-ok : (n : ) → dup n ≡ [n] : [ω.] =
λ n ⇒
case n return n' ⇒ dup n' ≡ [n'] : [ω.] of {
0 ⇒ δ 𝑖 ⇒ [0];
succ _, ih ⇒ δ 𝑖 ⇒ succ-boxω (ih @𝑖)
}
def dup! : (n : ) → [ω. Sing n] =
dup-from-parts dup dup-ok
#[compile-scheme "(lambda% (n x) x)"]
def drop : 0.(A : ★) → → A → A =
λ A n x ⇒ case n return A of { 0 ⇒ x; succ _, ih ⇒ ih }
drop-from-dup dup
#[compile-scheme "(lambda% (m n) (+ m n))"]
def plus : =

View File

@ -40,20 +40,16 @@ def eq? : DecEq Char =
(nat.eq? (to- c) (to- d))
def ws? : ω.Char → Bool =
λ c ⇒
case dup c return Bool of { [c] ⇒
bool.or (bool.or (eq c space) (eq c tab)) (eq c newline)
}
λ c ⇒ bool.or (bool.or (eq c space) (eq c tab)) (eq c newline)
def digit? : ω.Char → Bool =
λ c ⇒ case dup c return Bool of { [c] ⇒
bool.and (ge c (from- 0x30)) (le c (from- 0x39))
}
λ c ⇒ bool.and (ge c (from- 0x30)) (le c (from- 0x39))
def digit-val : Char → =
λ c ⇒
case dup c return of { [c] ⇒
bool.if (digit? c) (nat.minus (to- c) 0x30) 0
def digit-val : Char → Maybe =
λ c ⇒ case dup c return Maybe of { [c] ⇒
bool.if (Maybe ) (digit? c)
(Just (nat.minus (to- c) 0x30))
(Nothing )
}
}
@ -77,13 +73,6 @@ def from-list : List Char → String =
def foldl : 0.(A : ★) → A → ω.(A → Char → A) → String → A =
λ A z f str ⇒ list.foldl Char A z f (to-list str)
#[compile-scheme
"(lambda% (fail ok str) (cond [(string->number str) => ok] [else fail]))"]
postulate to-' : 0.(B : ★) → ω.B → ω.( → B) → String → B
def to- : String → Maybe =
to-' (Maybe ) (Nothing ) (Just )
def split : ω.(ω.Char → Bool) → ω.String → List String =
λ p str ⇒
list.map (List Char) String from-list
@ -103,4 +92,49 @@ postulate eq : ω.String → ω.String → Bool
def null : ω.String → Bool = eq ""
def not-null : ω.String → Bool = λ s ⇒ bool.not (null s)
#[compile-scheme "(lambda (str) str)"]
postulate dup : String → [ω.String]
postulate0 dup-ok : (str : String) → dup str ≡ [str] : [ω.String]
def dup! : (str : String) → Dup String str =
dup-from-parts String dup dup-ok
def to- : String → Maybe =
letω add-digit : Maybe → Maybe =
maybe.fold ( → Maybe ) (λ d ⇒ Just d)
(λ n d ⇒ Just (nat.plus (nat.times 10 n) d)) in
letω drop : Maybe → Maybe =
maybe.fold (Maybe ) (Nothing )
(λ n ⇒ nat.drop (Maybe ) n (Nothing )) in
letω add-digit-c : Maybe → Char → Maybe =
λ acc c ⇒
maybe.fold (Maybe → Maybe ) drop (λ n acc ⇒ add-digit acc n)
(char.digit-val c) acc in
λ str ⇒
case dup str return Maybe of { [str] ⇒
bool.if (Maybe ) (not-null str)
(foldl (Maybe ) (Just 0) add-digit-c str)
(Nothing )
}
def to--or-0 : String → =
λ str ⇒ maybe.fold 0 (λ x ⇒ x) (to- str)
#[compile-scheme
"(lambda% (yes no str)
(let [(len (string-length str))]
(if (= len 0)
no
(let [(first (string-ref str 0))
(rest (substring str 1 len))]
(% yes first rest)))))"]
postulate uncons' : 0.(A : ★) → ω.A → ω.(Char → String → A) → String → A
def uncons : String → Maybe (Char × String) =
let0 Ret : ★ = Char × String in
uncons' (Maybe Ret) (Nothing Ret) (λ c s ⇒ Just Ret (c, s))
}