First steps into the wonderful world of logic programming.
- Analyse the initial situation
(Where am I?) - Define the destination to reach
(Where do I want to go?) - Work out the transformation strategy
(How do I get there?) - Implementing the transformation strategy
(Telling the computer exactly and step-by-step what to do)
followed by:
- Re-sharpening the initial situation
(sometimes because of an incomplete analysis in the first place) - Re-sharpening the destination to reach
(sometimes because of an inaccurate first definition) - Re-sharpening the transformation strategy
(as a mandatory consequence) - Debug your implementation
(also eliminating ordinary bugs)
but at these points in time, the program is already written. So we are working directly on the code. And all this re-sharpening feels like the normal way to debug.
- Analyse the initial situation thoroughly
You will have to do it anyway. But do it now. Not while debugging.
(Where am I exactly?) - Define the destination to reach thoroughly and use a formal way to write it down
You will have to do it anyway.
But do it now and be as precise as possible.
(Where do I want to go precisely?) - Use something to process your formal definition of the desired destination.
This something will use and combine standard algorithms and automata to transform the initial state into the required final state.
If done correctly and completely, you don't need to work out a transformation strategy anymore. And consequently, you don't have to implement and debug such transformation.
Create a new project
lein new core-logic-primer
add an additional dependency in your project.clj
:
[org.clojure/core.logic "0.8.10"]
and start using it in your namespace.
(ns core-logic-primer.core
(:refer-clojure :exclude [== !=])
(:use [clojure.core.logic]))
Some clojure.core.logic
symbols collide with clojure.core
symbols.
When writing pure logic code, simply exclude the corresponding clojure.core
symbols.
If you also want to use Facts and Relations (see rpssl.clj
example), add
(:require [clojure.core.logic.pldb :as db])
And for finite domains like all numbers between 1 and 9 (see sudoku.clj
example) just add
(:require [clojure.core.logic.fd :as fd])
And to use arithmetic relational operators, you can add
(:use [clojure.core.logic.arithmetic])
and prepare for more colliding symbols.
- Start your REPL
- Work through A Core.logic Primer
- Play around in the REPL, at least using ==, !=, conso, appendo, membero, distincto, fresh, everyg
- Visit core.logic Introduction (Slides 8 to 29)
- Try some larger examples:
- The
sudoku.clj
of this repository - Solving Logic Puzzles With Clojure core.logic
- The
- Prepare for Facts And Relations using
core.logic Introduction
(Slides 30 to 35)
Note: Theclojure.core.logic
syntax has slightly changed. Seerpssl.clj
of this repository. - Conclude and recap with A Very Gentle Introduction To Relational & Functional Programming
- Find yourself something to implement.
Maybe a Mastermind solver using
clojure.core.logic
? - Share your thoughts and experiences on the next Clojure User Group Bonn session
-
"The authors of The Reasoned Schemer believe that logic programming is a natural extension of functional programming (...)"
- core.logic Project Homepage
- core.logic API Reference
- core.logic Introduction
- A Core.logic Primer
- A Very Gentle Introduction To Relational & Functional Programming
- Solving Logic Puzzles With Clojure core.logic
- Game Characters with core.logic
- Logic Programming is Overrated
- Logic Programming is Underrated