Follow @miniKanren

The name

The core miniKanren language is very simple, with only three logical operators and one interface operator.

The core language, using Scheme as the host language, is described in this short, interactive tutorial.

miniKanren has been implemented in a growing number of host languages, including Scheme, Racket, Clojure,

Haskell, Python, JavaScript, Scala, Ruby, OCaml, and PHP, among many other languages.

miniKanren is designed to be easily modified and extended; extensions include Constraint Logic Programming,

probabilistic logic programming, nominal logic programming, and tabling.

A detailed discussion of the differences between miniKanren and Prolog can be found here.

- (Upcoming!) Fourth miniKanren workshop at ICFP 2022 (Call for Papers)
- Third miniKanren workshop at ICFP 2021 (Proceedings) (Workshop Videos)
- Second miniKanren workshop at ICFP 2020 (Proceedings)
- First miniKanren workshop at ICFP 2019 (Proceedings)
- miniKanren confo at Clojure/West 2013

The MIT Press, Cambridge, MA, 2018

Source code from the book

Recordings of previous uncourse hangouts.

miniKanren with extensions for symbolic constraint solving. Includes compatibility files for Racket and various Scheme implementations.

microKanren with temporal logic programming

Related to an earlier, similar implementation

microKanren

A minimal miniKanren implementation, as described in the 2013 Scheme Workshop paper

microKanren implementation using Martelli-Montanari unification algorithm

microKanren w/simple complete search

A modified/improved microKanren implementation, as described in the 2016 DLS paper.

alphaKanren

miniKanren extended with nominal logic programming, as described in the 2007 Scheme Workshop paper.

probKanren

Research prototype of miniKanren with probabilistic inference.

chicken-miniKanren

miniKanren implementation for chicken scheme

gerbilog

gerbiKanren

miniKanren implementations for gerbil scheme

microKanren-sagittarius

miniKanren implementation for R7RS sagittarius scheme 0.6.0 based on (microKanren) with the

`=/=`

operation added.rKanren

miniKanren with guided search, as described in the 2013 Scheme Workshop paper.

miniKanren in guile-log, a Guile Scheme library.

bkanren

miniKanren with constraint extensions that runs under Bigloo Scheme.

Fork: bkanren

miniKANREN R7RS

CLP(SMT) miniKanren

staged miniKanren

explorations of multi-stage logic programming in miniKanren

Static Kanren

A variant of miniKanren which returns better answers

ykanren

amk on S9fes

semiKanren

Logic programming using semiunification for R-ASUP instances

slpKanren

Stochastic Logic Programs (SLP) style probabilistic logic programming in miniKanren. (Deprecated--please see probKanren instead.)

sokuza-kanren

Oleg Kiselyov's minimal implementation of logic programming.

miniKanren with extensions for symbolic constraint solving. Includes compatibility files for Racket and various Scheme implementations.

cKanren

miniKanren extended with Constraint Logic Programming (CLP); an improved version of the system described in the 2011 Scheme Workshop paper.

Racket-miniKanren

vanilla miniKanren Racket port

recursive miniKanren

recursive miniKanren implementation in Racket.

zKanren

cKanren with fair conjunction

Datalog in miniKanren

racket qkanren

alphaKanren revisited

dbKanren

roxanren

Experimental fusion of miniKanren and Rosette

(core.logic cheatsheet, courtesy of Benjamin Peter)

A literate Clojure implementation of microKanren.

Annotated source code.

async-mu-kanren

Proof-of-concept implementation of muKanren using CSP (core.async)

rank Kanren

rKanren extension of core.logic

Eleusis

maikurokanren

yaukanren

miniKanren

cslogic

kanrenmo

Logic

uKanren.NET

Described here in prose.

NMiniKanren

cl-microkanrens

mini-kanren

mu-kanren

Kanren-Fset (Fset collection library support for cl-kanren-trs)

logic.dart

exo

Another elm-microKanren

microKanren

Project homepage for this Elm implementation of the uKanren language.

lolkanren_erlang

mukanren

logic

A logic programming library for F#

MiniKanren

An attempted implementation of MiniKanren in F#.

gominikanren

ukanren-go

kanren

Molog

HaskellKanren (HK)

MiniKanrenT

featherweight

hKanren

HKanren

Haskell microKanren with miniKanren extensions

HOuKanren

A twist to uKanren to support Higher-Order Relational Programming.

Khaaaaaaanren!

DS-Kanren

An alternative version adapted to use Streamly

An adaptation written as a Haskell EDSL

MicroKanren.hs

mu-kanren

ukanren

uKanren

MicroKanren.lhs

micro-kanren

hasKanren

negation kanren

hKanren

microKanren-demo

μKanren in Haskell 98.

Hywaii

Adderall

ikanren

microKandris

Supersedes an older version.

microKanren in Java.

miniKanren4j

Archelogic

java8kanren

miniKanren in Java 8.

Java miniKanren

Browser based miniKanren editor and REPL, with constraints.

GitHub repo

microScopeKanren

A JavaScript implementation of microKanren with a focus on inspecting programs as they run.

Example, vizualizing

`appendo`

mu-kanren

A step-by-step MicroKanren evaluator.

GitHub repo

Kanrens

microJSKanren

lolkanren

jolic

node-kanren

microKanren JS

uKanren

microKanren

mk.js

ramo

ramda-logic

reason.js

logic.js

rlg

SebuKanren

Lil Kanren

MiniKanren

yet another microKanren in Julia

kanren

LogikalDB

miniKanren.lua

muko

ml-mukanren

microKanren-SML

sml-kanren

Statically typed embedding of miniKanren into Objective Caml.

kanren

minikanren-ocaml

Logical

php-microKanren

Related to an earlier project microKanren-pony

pony-kanren

A Prolog implementation of microKanren.

miniKanren.pl

MiniKanren in Lisp in Prolog. Accompanies the Technical Interview

kanrens

pykanren

pythological

LogPy

miniKANREN Python

microkanrenpy

microKanren

Another microkanren

microkanren.py

micro_kanren

miniKanren

MiniKanren

kanren

A Ruby implementation to accompany Hello, declarative world

mini_kraken

rskanren

kanren

mu-kanren

Tributary

Very simple uKanren implementation

mukan

ukanren-rs

miniKANREN

Canrun

A Rust implementation described in Announcing Canrun

proto-vulcan

Microkanren in Scala

minikanren-scala

minikanren-scala

sKanren

mukanren

kanren (Sokuza-kanren in Scala)

shen-minikanren

Smalltalk Hub link to microkanren-pharo

microkanrenst

SmallKanren

How to implement microKraren in Pharo

SwiftKanren

SwiftyKanren

miniKanren.swift

microKanren.ts

microKanren

Typescript MicroKanren

Barliman is a prototype "smart editor" that performs real-time program synthesis to try to make the programmer's life a little easier.

minimips, a minikanren mips assembler/disassembler.

rewrite-rule completion in miniKanren

Luke McCulloch's Interval constraint programming dissertation work

A relational SKI combinator calculus

Symbolic manipulation of PyMC models, graphs

Mkanren: Relational/Kanren Automata theory

mediKanren

Project for reasoning over the SemMedDB knowledge base, using miniKanren + heuristics

Specializer for microKanren

uKanren transformations

miniKanren as an extensible EDSL

The Sheet Music Generator.

blog post

expresso

A clojure library for symbolic manipulation of Algebraic Expressions.

tutorial

blog post

webdriver-logic

Logic programming API for testing web applications using clj-webdriver.

Clojure/conj 2012 talk

damp.ekeko

Ekeko enables querying and manipulating an Eclipse workspace using applicative logic programs.

anouncement

screencast

damp.qwal

QWAL is a path expression library to allow querying graphlike structures using core.logic in Clojure.

damp.qwalkeko

Scrape and reason over Java projects stored on git.

peano

Using logic programming (Clojure's core.logic) for test data manipulation and generation.

kibit

kibit is a static code analyzer for Clojure which uses core.logic to search for patterns of code for which there might exist a more idiomatic function or macro.

parsing-packet-with-logic

A small experiment in parsing packets in a style similar to Erlang's

`<<...>>`

using core.logic.maze.logic

Solving mazes using core.logic.

Janus: Consumer-driven Contracts and Mocks

Consumer-driven contracts using core.logic.

Monotony

Monotony is a solution to the problem of how to schedule things in a way that humans find intuitive.

QWAL

QWAL is a path expression library to allow querying graphlike structures using core.logic in Clojure.

FunnyQT

FunnyQT is a model querying and transformation library.

symbol

symbol is a compiler of a subset of Clojure syntax to C++.

guzheng

guzheng is a library for doing branch coverage analysis of Clojure code.

Adventure in Clojure core.logic

Text adventure game in core.logic.

The core.logic wiki also has links to projects using core.logic.

audio

Papers We Love NYC, Wednesday, April 12, 2017.

William E. Byrd (joint work with Michael Ballantyne, Gregory Rosenblatt, and Matthew Might)

A Unified Approach to Solving Seven Programming Problems (Functional Pearl) International Conference on Functional Programming (ICFP), Oxford, England, 4 September 2017.

paper | interactive paper | downloadable artifact | Barliman

Tom Stuart

Hello, declarative world

LRUG August 2015 Meetup, August 8, 2015.

Dan Friedman and Jason Hemann

How to be a good host: miniKanren as a case study

Curry On, Prague, Czech Republic, 7 July 2015.

William Byrd

The Promise of Relational Programming

PolyConf 15, Poznań, Poland, 2 July 2015.

Bodil Stokke

μKanren: Running the Little Things Backwards

EuroClojure, Barcelona, Spain, 25 June 2015.

Daniel Brady

Little Logic Languages

Scheme Workshop, Washington, D.C., 19 November 2014.

Jason Hemann and Dan Friedman

Write the Other Half of Your Program: From Functional to Logic Programming

Strange Loop, St. Louis, September 18, 2014.

William E. Byrd

Relational Programming in miniKanren, Part 1 and Part 2

Logic Night

Lambda Lounge Utah, Sandy, UT, May 13, 2014.

Daniel P. Friedman and William E. Byrd

A Relational Exploration of the Chomsky Hierarchy

Strange Loop, St. Louis, September, 2013.

William E. Byrd and Daniel P. Friedman

Fun with Relational Interpreters in miniKanren

flatmap 2013, Oslo, Norway, May 14, 2013 (keynote).

William E. Byrd and Daniel P. Friedman

miniKanren Philosophy

Clojure/conj 2012, Raleigh, NC, November 16, 2012.

(Beware the pink tint!)

Daniel P. Friedman and William E. Byrd

Relational Programming in miniKanren

Strange Loop 2012, St. Louis, MO, September 24, 2012

source code

Daniel P. Friedman and William E. Byrd

miniKanren "untalk"

Clojure/conj 2011, Raleigh, NC, November 10, 2011.

From Greek to Clojure

Clojure/conj, Alexandria, VA, November 14, 2013

source code | slides

Craig Brozefsky

Core.logic and SQL Killed my ORM

Clojure/West 2013, Portland, OR, March 19th, 2013.

David Nolen

The Refined Clojurist

Clojure Exchange 2012, London, December 6, 2012

Daniel Gregoire

Web Testing with Logic Programming

Clojure/conj 2012, Raleigh, NC, November 17, 2012.

webdriver-logic project

Steve Miner

Challenges for Logic Programming

Clojure/conj 2012, Raleigh, NC, November 17, 2012.

Edmund Jackson

An Introduction to Logic Programming on the JVM with core.logic (Clojure)

FP Days 2012, Cambridge, October 25, 2012

David Nolen

core.logic: A tutorial reconstruction ("unsession")

Strange Loop 2012, St. Louis, MO, September 24, 2012

Edmund Jackson

core.logic.intro

EuroClojure 2012, London, May 24, 2012

source code

Ryan Senior

Practical core.logic

Clojure/West 2012, San Jose, March 17, 2012

Ambrose Bonnaire-Sergeant

Introduction to Logic Programming with Clojure

Clojure/conj 2011, Raleigh, NC, November 10, 2011.

Constraint programming in the browser

(Talk focuses on the Cassowary constraint solver for GUI layout, but also discusses core.logic.)

JSConf US, Amelia Island, FL, May 31, 2013

Logic programming in the wild (video not posted yet)

Ryan Senior

Intro to CLP with core.logic

Adam Foltzer

Molog: Typed Functional Logic Programming in Haskell

source code

David Nolen

The Architecture of core.logic

Nada Amin

core.logic.nominal (video not posted yet)

source code

William E. Byrd and Daniel P. Friedman

The Unreasonable Schemers (video not posted yet)

source code

Jason Hemann miniKanren Interview

For Code Mesh 2016

William E. Byrd

Episode 9: Will Byrd and miniKanren

On the Functional Geekery podcast

William E. Byrd

William Byrd on Logic and Relational Programming, miniKanren

Recorded by InfoQ at Code Mesh 2013, London, England, December, 2013

A Core.logic Primer

Logic Programming for the Social Web

Constraint microKanren in the CLP Scheme

Indiana University, Bloomington, IN,

December 19, 2019.

Thomas L. McCulloch

Feasible form parameter design of complex ship hull form geometry

University of New Orleans, New Orleans, LA,

December 20, 2018.

William E. Byrd

Relational Programming in miniKanren: Techniques, Applications, and Implementations

Indiana University, Bloomington, IN,

September 30, 2009.

Easier to read, single-spaced, re-typeset version of Will's dissertation, released under Creative Commons Attribution 4.0 International (CC BY 4.0) license.

Разработка транслятора из реляционного языка программирования в функциональный

(Note: Russian. In English, "Development of a Translator from a Relational Programming Language to a Functional Language")

ITMO University, Saint Petersburg, Russia,

2020.

Lisa Zhang

Leveraging Constraint Logic Programming for Neural Network Guided Program Synthesis

University of Toronto, Toronto, Canada,

2016.

Kaylen FJ Wheeler

Representing Game Dialogue as Expressions in First-Order Logic

University of Western Ontario, London, Ontario, Canada,

2013.

Relational Conditionals With Pseudo-Functions

South-Eastern Finland University of Applied Sciences, Mikkeli, Finland,

April, 2019. (Bachelor's Thesis)

Emily Fox

Automated Canon Composition

Churchill College, University of Cambridge, Cambridge, UK,

May 10, 2016. (Computer Science Tripos - Part II)

Ramana Kumar

Mechanising Aspects of miniKanren in HOL

Australian National University, Canberra, Australian Capital Territory, Australia,

May 2010. (Undergraduate Honors Thesis)

Towards Answering "Am I On the Right Track?" Automatically using Program Synthesis.

In SPLASH-E 2019.

Paper

Lisa Zhang, Gregory Rosenblatt, Ethan Fetaya, Renjie Liao, William E. Byrd, Matthew Might, Raquel Urtasun, and Richard Zemel.

Neural Guided Constraint Logic Programming for Program Synthesis.

In Advances in Neural Information Processing Systems 31 (NeurIPS 2018), 2018.

Paper and poster

Full proceedings

William E. Byrd, Michael Ballantyne, Gregory Rosenblatt, and Matthew Might

A Unified Approach to Solving Seven Programming Problems (Functional Pearl)

In Proceedings of the ACM on Programming Languages (PACMPL), 1, ICFP, Article 8 (August 2017), 26 pages. DOI.

Interactive version of the paper, created by Nada Amin.

Jason Hemann, Daniel P. Friedman, William E. Byrd, and Matthew Might

A Small Embedding of Logic Programming with a Simple Complete Search

In Proceedings of the 12th Symposium on Dynamic Languages (DLS 2016), Amsterdam, Netherlands, 2016.

Jason Hemann and Daniel P. Friedman

A Framework for Extending microKanren with Constraints

In Proceedings of the 2015 Workshop on Scheme and Functional Programming (Scheme '15), Vancouver, British Columbia, 2015.

Peter Kourzanov

Bidirectional parsing: a functional/logic perspective

In 2014 International Symposium on Implementation and Application of Functional Language (IFL 2014), Boston, MA, October, 2014.

Daniel Brady, Jason Hemann and Daniel P. Friedman

Little Languages for Relational Programming.

In Proceedings of the 2014 Workshop on Scheme and Functional Programming (Scheme '14), Washington, DC, 2014.

Complete source code (Scheme)

Erik Wennstrom

Tableau-Based Model Generation for Relational Syllogistic Logics.

In Proceedings of the 2014 International Symposium on Artificial Intelligence and Mathematics (ISAIM 2014), Fort Lauderdale, FL, January, 2014.

Jason Hemann and Daniel P. Friedman.

microKanren: A Minimal Functional Core for Relational Programming.

In Proceedings of the 2013 Workshop on Scheme and Functional Programming (Scheme '13), Alexandria, VA, 2013.

Complete source code (Scheme)

Cameron Swords and Daniel P. Friedman.

rKanren: Guided Search in miniKanren.

In Proceedings of the 2013 Workshop on Scheme and Functional Programming (Scheme '13), Alexandria, VA, 2013.

Complete source code (Scheme)

Zoltan Varju, Richard Littauer and Peteris Ernis.

Using Clojure in Linguistic Computing

In Proceedings of the 5th European Lisp Symposium, Zadar, Croatia, 2012.

William E. Byrd, Eric Holk, and Daniel P. Friedman.

miniKanren, Live and Untagged: Quine Generation via Relational Interpreters (Programming Pearl).

To appear in the Proceedings of the 2012 Workshop on Scheme and Functional Programming, Copenhagen, Denmark, 2012.

Complete source code (Scheme)

Claire E. Alvis, Jeremiah J. Willcock, Kyle M. Carter, William E. Byrd, and Daniel P. Friedman.

cKanren: miniKanren with Constraints.

In Proceedings of the 2011 Workshop on Scheme and Functional Programming (Scheme '11), Portland, OR, 2011.

Complete source code (R6RS Scheme)

Ramana Kumar and Michael Norrish

(Nominal) unification by recursive descent with triangular substitutions

In Proceedings of the First international conference on Interactive Theorem Proving (ITP'10),

Springer-Verlag Berlin, pp. 51-66, 2010.

Andrew W. Keep, Michael D. Adams, Lindsey Kuper, William E. Byrd, and Daniel P. Friedman.

A Pattern-matcher for miniKanren -or- How to Get into Trouble with CPS Macros.

In Proceedings of the 2009 Workshop on Scheme and Functional Programming,

Cal Poly Technical Report CPSLO-CSC-09-03, pp. 37-45, 2009.

Joseph P. Near, William E. Byrd and Daniel P. Friedman.

alphaleanTAP: A Declarative Theorem Prover for First-Order Classical Logic.

In Proceedings of the 24th International Conference on Logic Programming (ICLP 2008),

LNCS vol. 5366, Springer-Verlag, Heidelberg, pp. 238-252, 2008.

Complete source code--R6RS Scheme and Prolog (.zip file)

Oleg Kiselyov, William E. Byrd, Daniel P. Friedman and Chung-chieh Shan

Pure, declarative, and constructive arithmetic relations (declarative pearl).

In Proceedings of the 9th International Symposium on Functional and Logic Programming,

ed. Jacques Garrigue and Manuel Hermenegildo, pp. 64-80.

LNCS vol. 4989, Springer, 2008.

William E. Byrd and Daniel P. Friedman

alphaKanren: A Fresh Name in Nominal Logic Programming.

In Proceedings of the 2007 Workshop on Scheme and Functional Programming,

Universite Laval Technical Report DIUL-RT-0701, pp. 79-90.

Authors' revised version (recommended)

Revised source code (R5RS Scheme)

Larisse D. Voufo

A miniKanren Interactive Proof System for Deciding the Truth of (simple) Quantied Boolean Formulae

William E. Byrd and Daniel P. Friedman

From Variadic Functions to Variadic Relations: A miniKanren Perspective.

In Proceedings of the 2006 Scheme and Functional Programming Workshop,

University of Chicago Technical Report TR-2006-06, 2006, pp. 105-117.

Oleg Kiselyov, Chung-chieh Shan, Daniel P. Friedman, and Amr Sabry

Backtracking, interleaving, and terminating monad transformers: (functional pearl).

In Proceedings of the 10th ACM SIGPLAN International Conference on Functional Programming (ICFP '05),

ACM Press, New York, pp. 192-203, 2005.

blog post

source code

January 2013.

October 25, 2013.

Bytecode Assembler in Core.Logic

related blog post

Dec 13, 2012.

ekeko project

August 14, 2012.

Topic: Claire shows off a new macro for defining constraints using attributed variables, a new version of the matche pattern matching macro, and the implementation of templateo (declarative

`copy_term`

) (URL). Norman demos his code for solving nonogrids problems. Will talks about CPSing miniKanren programs.Hangout #12, Sunday, June 23, 2013.

Topic: Gary shows off his CLP(FD) program to layout 2D figures; Will describes the new, apparently fixed

`templateo`

constraint, and explains how it is used in a relational term reducer for the untyped lambda-calculus.Hangout #11, Sunday, June 9, 2013.

Topic: Unexpected memory usage in

`conde`

, and how to fix it in CLP(FD); meta-interpreters in miniKanren (code); what do you need to know to use miniKanren effectively?; Will's new book on miniKanren (in progress).Hangout #10, Sunday, June 2, 2013.

Topic: We discuss CLP(Set) and declarative

`copy_term`

(a.k.a., `templateo`

) (code). Lindsey shows off LVish (code). David poses a core.logic puzzle. Dan and Jason discuss miniC, a minimal miniKanren without macros. Will shows off a relational lambda calculus reducer (code).Hangout #9, Sunday, May 19, 2013.

Topic: Will shows off a meta-circular interpreter for miniKanren (code), and describes the outline for a new book he is writing on relational programming (book).

Hangout #8, Sunday, May 5, 2013.

Topic: Dan and Jason show off a cool way to implement mutual recursion in an interpreter. Will and the gang then live-code a relational interpreter for general Deterministic Finite Automata (code).

Hangout #7, Sunday, April 28, 2013.

Topic: Translating simple Scheme functions to miniKanren using correctness-preserving transformations.

Hangout #6, Sunday, April 21, 2013.

Topic: Live coding/real-time solution of a simple problem solved by Michael. Also, Claire discusses new features of cKanren in Racket.

Hangout #5, Sunday, April 14, 2013.

Topic: Stump the Chump! Will partially translates miniKanren's unify function from Scheme into miniKanren (code). Also, discussion of extra-logical operators, and new miniKanren features in progress: CLP(Set), constraint handling rules, lazy constraints for recursion.

Hangout #4, Sunday, April 7, 2013.

Topic: Debugging miniKanren programs; Constraint Logic Programming over sets (based on the paper Sets and Constraint Logic Programming by Dovier, et al., 2000).

Hangout #3, Sunday, March 31, 2013.

Implementation of simplified miniKanren (source code).

Hangout #2, March 24, 2013.

Implementing disequality constraints, absento/presento constraints, miniKanren Confo at Clojure/West, relational CESK machine.

Hangout #1, March 10, 2013.

A little miniKanren history, what it means to be relational, a relational variant of copy-term, debugging miniKanren programs.

Episode 9 with Kevin Lynagh and Paul deGrandis: web dev ennui, CRDTs, and core.logic

Recorded December 14th, 2012.

Logic Programming is Underrated

The Simply Typed Lambda Calculus in 20 Lines Redux

From David Nolen's old blog (courtesy of the Internet Archive's Wayback Machine):

Know Your Bounds

friendlier

sudoku

A Logic Programming Reading List

Logic Programming & JavaScript

core.logic & VPRI STEPS

Another Taste of cKanren

A Taste of cKanren

Simple Type Inference For The Simply Typed Lambda Calculus in ~20 Lines

Logos -> core.logic

Crazy Ideas

Fun

Spring Cleaning

Simple Constraints

~2.1ms

Tabling in Logos

Pattern Matching

Finally ... a clue

Performance Matters

Faster Unification

Logic Programming and Performance

A Short Break

Life Without Tail Call Optimization

Announcing Logos

A miniKanren introduction via Clojure

Generating Propositional Logic Proofs

lx in core.logic #3: Finite State Transducers

lx in core.logic #2: Jumps, Flexible Transitions and Parsing

Finite State Machines in core.logic

Byte Packing with core.logic

The Composing Schemer

Finding cliques in graphs using core.logic

Maximum cliques algorithm in Clojure

Logic Programming Part 3 (List Logic)

Logic Programming Part 2 (Building Blocks)

Logic Programming Part 1

Lojic Part One

Meta Machinations

Build An Arrow

Meta Machinations

Arrowed Core.logic

More Core.logic

Messin With Core.logic

The Reasoned Scheduler

Appendo the Great

cKanren time!

Replicating Datomic/Datalog queries with core.logic, take 2

Replicating Datomic/Datalog queries with core.logic, take 1

N-Queens with core.logic, take 2

N-Queens with core.logic, take 1

The First Time Programming Scared Me

Solving Logic Puzzles With Clojure's Core Logic, Part One

PPfAI Chapter 1 in Clojure Core.Logic

Thanks to Shantanu Kumar, Martin Trojer, and Gergely Nagy for improving the site by submitting a pull request.