From a07fed3794c0f91b4c2c7cd2332163b8cf031a72 Mon Sep 17 00:00:00 2001 From: Melody Horn Date: Fri, 12 Mar 2021 18:55:07 -0700 Subject: a first attempt at heresy --- src/main.chalk | 336 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 364 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 700 insertions(+) create mode 100644 src/main.chalk create mode 100644 src/main.rs (limited to 'src') diff --git a/src/main.chalk b/src/main.chalk new file mode 100644 index 0000000..4837512 --- /dev/null +++ b/src/main.chalk @@ -0,0 +1,336 @@ +struct Nil {} +struct Cons {} + +trait First { + type X; +} + +impl First for Nil { + type X = Nil; +} + +impl First for Cons { + type X = X; +} + +trait ListConcat { + type C; +} + +impl ListConcat for (Nil, X) { + type C = X; +} + +impl ListConcat for (Cons, Bs) where (As, Bs): ListConcat { + type C = Cons::C>; +} + +trait ListConcatAll { + type L; +} + +impl ListConcatAll for Nil { + type L = Nil; +} + +impl ListConcatAll for Cons where Rest: ListConcatAll, (Chunk, ::L): ListConcat { + type L = <(Chunk, ::L) as ListConcat>::C; +} + +struct True {} +struct False {} + +trait Not { + type B; +} + +impl Not for True { + type B = False; +} + +impl Not for False { + type B = True; +} + +trait Or { + type B; +} + +impl Or for (True, True) { + type B = True; +} + +impl Or for (True, False) { + type B = True; +} + +impl Or for (False, True) { + type B = True; +} + +impl Or for (False, False) { + type B = False; +} + +trait AnyTrue { + type T; +} + +impl AnyTrue for Nil { + type T = False; +} + +impl AnyTrue for Cons { + type T = True; +} + +impl AnyTrue for Cons where List: AnyTrue { + type T = ::T; +} + +struct Z {} +struct S {} + +trait PeanoEqual { + type T; +} + +impl PeanoEqual for (Z, Z) { + type T = True; +} + +impl PeanoEqual for (S, Z) { + type T = False; +} + +impl PeanoEqual for (Z, S) { + type T = False; +} + +impl PeanoEqual for (S, S) where (A, B): PeanoEqual { + type T = <(A, B) as PeanoEqual>::T; +} + +trait PeanoLT { + type T; +} + +impl PeanoLT for (Z, Z) { + type T = False; +} + +impl PeanoLT for (S, Z) { + type T = False; +} + +impl PeanoLT for (Z, S) { + type T = True; +} + +impl PeanoLT for (S, S) where (A, B): PeanoLT { + type T = <(A, B) as PeanoLT>::T; +} + +trait PeanoAbsDiff { + type C; +} + +impl PeanoAbsDiff for (Z, Z) { + type C = Z; +} + +impl PeanoAbsDiff for (Z, S) { + type C = S; +} + +impl PeanoAbsDiff for (S, Z) { + type C = S; +} + +impl PeanoAbsDiff for (S, S) where (A, B): PeanoAbsDiff { + type C = <(A, B) as PeanoAbsDiff>::C; +} + +trait Range { + type Xs; +} + +impl Range for Z { + type Xs = Nil; +} + +impl Range for S where N: Range { + type Xs = Cons::Xs>; +} + +trait Apply { + type R; +} + +struct Conj1 {} + +impl Apply for (Conj1, X) { + type R = Cons; +} + +trait Map { + type Ys; +} + +impl Map for (F, Nil) { + type Ys = Nil; +} + +impl Map for (F, Cons) where (F, X): Apply, (F, Xs): Map { + type Ys = Cons<<(F, X) as Apply>::R, <(F, Xs) as Map>::Ys>; +} + +trait MapCat { + type Zs; +} + +impl MapCat for (F, Nil) { + type Zs = Nil; +} + +impl MapCat for (F, Xs) where (F, Xs): Map, <(F, Xs) as Map>::Ys: ListConcatAll { + type Zs = <<(F, Xs) as Map>::Ys as ListConcatAll>::L; +} + +trait AppendIf { + type Zs; +} + +impl AppendIf for (True, X, Ys) { + type Zs = Cons; +} + +impl AppendIf for (False, X, Ys) { + type Zs = Ys; +} + +trait Filter { + type Ys; +} + +impl Filter for (F, Nil) { + type Ys = Nil; +} + +impl Filter for (F, Cons) where (F, X): Apply, (F, Xs): Filter, (<(F, X) as Apply>::R, X, <(F, Xs) as Filter>::Ys): AppendIf { + type Ys = <(<(F, X) as Apply>::R, X, <(F, Xs) as Filter>::Ys) as AppendIf>::Zs; +} + +struct Queen {} +struct Queen1 {} + +impl Apply for (Queen1, Y) { + type R = Queen; +} + +trait QueensInRow { + type Queens; +} + +impl QueensInRow for (N, X) where N: Range, (Queen1, ::Xs): Map { + type Queens = <(Queen1, ::Xs) as Map>::Ys; +} + +trait Threatens { + type T; +} + +impl Threatens for (Queen, Queen) + where (Ax, Bx): PeanoEqual, (Ax, Bx): PeanoAbsDiff, (Ay, By): PeanoEqual, (Ay, By): PeanoAbsDiff, + (<(Ax, Bx) as PeanoEqual>::T, <(Ay, By) as PeanoEqual>::T): Or, + (<(Ax, Bx) as PeanoAbsDiff>::C, <(Ay, By) as PeanoAbsDiff>::C): PeanoEqual, + (<(<(Ax, Bx) as PeanoEqual>::T, <(Ay, By) as PeanoEqual>::T) as Or>::B, + <(<(Ax, Bx) as PeanoAbsDiff>::C, <(Ay, By) as PeanoAbsDiff>::C) as PeanoEqual>::T, + ): Or { + type T = <( + <(<(Ax, Bx) as PeanoEqual>::T, <(Ay, By) as PeanoEqual>::T) as Or>::B, + <(<(Ax, Bx) as PeanoAbsDiff>::C, <(Ay, By) as PeanoAbsDiff>::C) as PeanoEqual>::T, + ) as Or>::B; +} + +struct Threatens1 {} + +impl Apply for (Threatens1, B) where (A, B): Threatens { + type R = <(A, B) as Threatens>::T; +} + +trait Safe { + type T; +} + +impl Safe for (Config, Queen) + where (Threatens1, Config): Map, + <(Threatens1, Config) as Map>::Ys: AnyTrue, + <<(Threatens1, Config) as Map>::Ys as AnyTrue>::T: Not { + type T = <<<(Threatens1, Config) as Map>::Ys as AnyTrue>::T as Not>::B; +} + +struct Safe1 {} + +impl Apply for (Safe1, Queen) where (Config, Queen): Safe { + type R = <(Config, Queen) as Safe>::T; +} + +trait AddQueen { + type Cs; +} + +impl AddQueen for (N, X, C) + where (N, X): QueensInRow, + (Safe1, <(N, X) as QueensInRow>::Queens): Filter, + <(Conj1, (Safe1, <(N, X) as QueensInRow>::Queens)) as Filter>::Ys: Map { + type Cs = <<(Conj1, (Safe1, <(N, X) as QueensInRow>::Queens)) as Filter>::Ys as Map>::Ys; +} + +struct AddQueen2 {} + +impl Apply for (AddQueen2, C) where (N, X, C): AddQueen { + type R = <(N, X, C) as AddQueen>::Cs; +} + +trait AddQueenToAll { + type CsPrime; +} + +impl AddQueenToAll for (N, X, Cs) where (AddQueen2, Cs): MapCat { + type CsPrime = <(AddQueen2, Cs) as MapCat>::Zs; +} + +trait AddQueensIf { + type CsPrime; +} + +impl AddQueensIf for (False, N, X, Cs) { + type CsPrime = Cs; +} + +impl AddQueensIf for (True, N, X, Cs) + where (N, X, Cs): AddQueenToAll, + (N, S, <(N, X, Cs) as AddQueenToAll>::CsPrime): AddQueens { + type CsPrime = <(N, S, <(N, X, Cs) as AddQueenToAll>::CsPrime) as AddQueens>::CsPrime; +} + +trait AddQueens { + type CsPrime; +} + +impl AddQueens for (N, X, Cs) + where (X, N): PeanoLT, + (<(X, N) as PeanoLT>::T, N, X, Cs): AddQueensIf { + type CsPrime = <(<(X, N) as PeanoLT>::T, N, X, Cs) as AddQueensIf>::CsPrime; +} + +trait Solution { + type C; +} + +impl Solution for N where (N, Z, Cons): AddQueens, <(N, Z, Cons) as AddQueens>::CsPrime: First { + type C = <<(N, Z, Cons) as AddQueens>::CsPrime as First>::X; +} + +// ::C diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..0c96e4e --- /dev/null +++ b/src/main.rs @@ -0,0 +1,364 @@ +#![recursion_limit="100000"] + +//! [source 1](https://aphyr.com/posts/342-typing-the-technical-interview) +//! [source 2](https://sdleffler.github.io/RustTypeSystemTuringComplete/) +use std::marker::PhantomData; + +struct Nil; +struct Cons(PhantomData, PhantomData); + +trait First { + type X; +} + +impl First for Nil { + type X = Nil; +} + +impl First for Cons { + type X = X; +} + +trait ListConcat { + type C; +} + +impl ListConcat for (Nil, X) { + type C = X; +} + +impl ListConcat for (Cons, Bs) where (As, Bs): ListConcat { + type C = Cons::C>; +} + +trait ListConcatAll { + type L; +} + +impl ListConcatAll for Nil { + type L = Nil; +} + +impl ListConcatAll for Cons where Rest: ListConcatAll, (Chunk, ::L): ListConcat { + type L = <(Chunk, ::L) as ListConcat>::C; +} + +struct True; +struct False; + +trait Not { + type B; +} + +impl Not for True { + type B = False; +} + +impl Not for False { + type B = True; +} + +trait Or { + type B; +} + +impl Or for (True, True) { + type B = True; +} + +impl Or for (True, False) { + type B = True; +} + +impl Or for (False, True) { + type B = True; +} + +impl Or for (False, False) { + type B = False; +} + +trait AnyTrue { + type T; +} + +impl AnyTrue for Nil { + type T = False; +} + +impl AnyTrue for Cons { + type T = True; +} + +impl AnyTrue for Cons where List: AnyTrue { + type T = ::T; +} + +struct Z; +struct S(PhantomData); + +type N0 = Z; +type N1 = S; +type N2 = S; +type N3 = S; +type N4 = S; +type N5 = S; +type N6 = S; +type N7 = S; +type N8 = S; + +trait PeanoEqual { + type T; +} + +impl PeanoEqual for (Z, Z) { + type T = True; +} + +impl PeanoEqual for (S, Z) { + type T = False; +} + +impl PeanoEqual for (Z, S) { + type T = False; +} + +impl PeanoEqual for (S, S) where (A, B): PeanoEqual { + type T = <(A, B) as PeanoEqual>::T; +} + +trait PeanoLT { + type T; +} + +impl PeanoLT for (Z, Z) { + type T = False; +} + +impl PeanoLT for (S, Z) { + type T = False; +} + +impl PeanoLT for (Z, S) { + type T = True; +} + +impl PeanoLT for (S, S) where (A, B): PeanoLT { + type T = <(A, B) as PeanoLT>::T; +} + +trait PeanoAbsDiff { + type C; +} + +impl PeanoAbsDiff for (Z, Z) { + type C = Z; +} + +impl PeanoAbsDiff for (Z, S) { + type C = S; +} + +impl PeanoAbsDiff for (S, Z) { + type C = S; +} + +impl PeanoAbsDiff for (S, S) where (A, B): PeanoAbsDiff { + type C = <(A, B) as PeanoAbsDiff>::C; +} + +trait Range { + type Xs; +} + +impl Range for Z { + type Xs = Nil; +} + +impl Range for S where N: Range { + type Xs = Cons; +} + +fn accepts_true(_: True) {} +fn legal_compare(x: <(S, S) as PeanoEqual>::T) { + accepts_true(x) +} + +trait Apply { + type R; +} + +struct Conj1(PhantomData); + +impl Apply for (Conj1, X) { + type R = Cons; +} + +trait Map { + type Ys; +} + +impl Map for (F, Nil) { + type Ys = Nil; +} + +impl Map for (F, Cons) where (F, X): Apply, (F, Xs): Map { + type Ys = Cons<<(F, X) as Apply>::R, <(F, Xs) as Map>::Ys>; +} + +trait MapCat { + type Zs; +} + +impl MapCat for (F, Nil) { + type Zs = Nil; +} + +impl MapCat for (F, Xs) where (F, Xs): Map, <(F, Xs) as Map>::Ys: ListConcatAll { + type Zs = <<(F, Xs) as Map>::Ys as ListConcatAll>::L; +} + +trait AppendIf { + type Zs; +} + +impl AppendIf for (True, X, Ys) { + type Zs = Cons; +} + +impl AppendIf for (False, X, Ys) { + type Zs = Ys; +} + +trait Filter { + type Ys; +} + +impl Filter for (F, Nil) { + type Ys = Nil; +} + +impl Filter for (F, Cons) where (F, X): Apply, (F, Xs): Filter, (<(F, X) as Apply>::R, X, <(F, Xs) as Filter>::Ys): AppendIf { + type Ys = <(<(F, X) as Apply>::R, X, <(F, Xs) as Filter>::Ys) as AppendIf>::Zs; +} + +struct Queen(PhantomData, PhantomData); +struct Queen1(PhantomData); + +impl Apply for (Queen1, Y) { + type R = Queen; +} + +trait QueensInRow { + type Queens; +} + +impl QueensInRow for (N, X) where N: Range, (Queen1, ::Xs): Map { + type Queens = <(Queen1, ::Xs) as Map>::Ys; +} + +trait Threatens { + type T; +} + +impl Threatens for (Queen, Queen) + where (Ax, Bx): PeanoEqual + PeanoAbsDiff, (Ay, By): PeanoEqual + PeanoAbsDiff, + (<(Ax, Bx) as PeanoEqual>::T, <(Ay, By) as PeanoEqual>::T): Or, + (<(Ax, Bx) as PeanoAbsDiff>::C, <(Ay, By) as PeanoAbsDiff>::C): PeanoEqual, + (<(<(Ax, Bx) as PeanoEqual>::T, <(Ay, By) as PeanoEqual>::T) as Or>::B, + <(<(Ax, Bx) as PeanoAbsDiff>::C, <(Ay, By) as PeanoAbsDiff>::C) as PeanoEqual>::T, + ): Or { + type T = <( + <(<(Ax, Bx) as PeanoEqual>::T, <(Ay, By) as PeanoEqual>::T) as Or>::B, + <(<(Ax, Bx) as PeanoAbsDiff>::C, <(Ay, By) as PeanoAbsDiff>::C) as PeanoEqual>::T, + ) as Or>::B; +} + +struct Threatens1(PhantomData); + +impl Apply for (Threatens1, B) where (A, B): Threatens { + type R = <(A, B) as Threatens>::T; +} + +trait Safe { + type T; +} + +impl Safe for (Config, Queen) + where (Threatens1, Config): Map, + <(Threatens1, Config) as Map>::Ys: AnyTrue, + <<(Threatens1, Config) as Map>::Ys as AnyTrue>::T: Not { + type T = <<<(Threatens1, Config) as Map>::Ys as AnyTrue>::T as Not>::B; +} + +struct Safe1(PhantomData); + +impl Apply for (Safe1, Queen) where (Config, Queen): Safe { + type R = <(Config, Queen) as Safe>::T; +} + +trait AddQueen { + type Cs; +} + +impl AddQueen for (N, X, C) + where (N, X): QueensInRow, + (Safe1, <(N, X) as QueensInRow>::Queens): Filter, + <(Conj1, (Safe1, <(N, X) as QueensInRow>::Queens)) as Filter>::Ys: Map { + type Cs = <<(Conj1, (Safe1, <(N, X) as QueensInRow>::Queens)) as Filter>::Ys as Map>::Ys; +} + +struct AddQueen2(PhantomData, PhantomData); + +impl Apply for (AddQueen2, C) where (N, X, C): AddQueen { + type R = <(N, X, C) as AddQueen>::Cs; +} + +trait AddQueenToAll { + type CsPrime; +} + +impl AddQueenToAll for (N, X, Cs) where (AddQueen2, Cs): MapCat { + type CsPrime = <(AddQueen2, Cs) as MapCat>::Zs; +} + +trait AddQueensIf { + type CsPrime; +} + +impl AddQueensIf for (False, N, X, Cs) { + type CsPrime = Cs; +} + +impl AddQueensIf for (True, N, X, Cs) + where (N, X, Cs): AddQueenToAll, + (N, S, <(N, X, Cs) as AddQueenToAll>::CsPrime): AddQueens { + type CsPrime = <(N, S, <(N, X, Cs) as AddQueenToAll>::CsPrime) as AddQueens>::CsPrime; +} + +trait AddQueens { + type CsPrime; +} + +impl AddQueens for (N, X, Cs) + where (X, N): PeanoLT, + (<(X, N) as PeanoLT>::T, N, X, Cs): AddQueensIf { + type CsPrime = <(<(X, N) as PeanoLT>::T, N, X, Cs) as AddQueensIf>::CsPrime; +} + +trait Solution { + type C; +} + +impl Solution for N where (N, Z, Cons): AddQueens, <(N, Z, Cons) as AddQueens>::CsPrime: First { + type C = <<(N, Z, Cons) as AddQueens>::CsPrime as First>::X; +} + +fn solve() -> ::C { + todo!() +} + +fn main() { + // we should be able to read the type off the error here + let _: () = solve(); +} -- cgit v1.2.3