Skip to content

Latest commit

 

History

History

core-logic-primer

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 

Core Logic Primer

First steps into the wonderful world of logic programming.

Putting it simply

A fairly common way of software development

  • 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.

An alternate route exists

  • 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.

Getting started

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.

Recommended Route

  1. Start your REPL
  2. Work through A Core.logic Primer
  3. Play around in the REPL, at least using ==, !=, conso, appendo, membero, distincto, fresh, everyg
  4. Visit core.logic Introduction (Slides 8 to 29)
  5. Try some larger examples:
  6. Prepare for Facts And Relations using core.logic Introduction (Slides 30 to 35)
    Note: The clojure.core.logic syntax has slightly changed. See rpssl.clj of this repository.
  7. Conclude and recap with A Very Gentle Introduction To Relational & Functional Programming
  8. Find yourself something to implement. Maybe a Mastermind solver using clojure.core.logic?
  9. Share your thoughts and experiences on the next Clojure User Group Bonn session

Background

Resources