Prolog development with Emacs

This page shows you how to configure GNU Emacs and XEmacs for effective Prolog development.
Note: For smaller editing tasks, SWI-Prolog ships with its own editor, an Emacs clone called PceEmacs. You can try it with:
?- emacs.
This built-in editor provides a limited subset of Emacs features. Since some of the features shown on this page are inspired by PceEmacs, I call this collection PceProlog.

Video: Prolog development with GNU Emacs

Editing Prolog code

There is an excellent Prolog mode for Emacs, maintained by Stefan Bruda.

Recent GNU Emacs versions also ship with a variant of this mode. Unfortunately though, the variant that ships with GNU Emacs contains modifications that cause severe regressions with indenting and navigation. Therefore, I recommend you use the version that is directly supplied by Stefan until these mistakes are corrected.

To obtain PceEmacs-style behaviour and use the mode with SWI-Prolog, add to your .emacs:
(setq prolog-system 'swi
      prolog-program-switches '((swi ("-G128M" "-T128M" "-L128M" "-O"))
                                (t nil))
      prolog-electric-if-then-else-flag t)
Note in particular the use of prolog-electric-if-then-else-flag:
prolog-electric-if-then-else-flag: Non-nil makes `(', `>' and `;' electric to automatically indent if-then-else constructs.

For nice comment blocks as in PceEmacs, add the following to your .emacs to insert a comment block with C-c q:
(defun prolog-insert-comment-block ()
  "Insert a PceEmacs-style comment block like /* - - ... - - */ "
  (let ((dashes "-"))
    (dotimes (_ 36) (setq dashes (concat "- " dashes)))
    (insert (format "/* %s\n\n%s */" dashes dashes))
    (forward-line -1)

(global-set-key "\C-cq" 'prolog-insert-comment-block)
In addition, I recommend the following definition so that C-c l inserts :- use_module(library()). and places the point between the inner parentheses.
(global-set-key "\C-cl" (lambda ()
                          (insert ":- use_module(library()).")
                          (forward-char -3)))

Prolog interaction

Use ediprolog to evaluate embedded queries in Emacs buffers:

Factorial using CLP(FD)

As of GNU Emacs 24.3, you can install ediprolog from the Emacs Lisp Package Archive (ELPA) with:

M-x package-install RET ediprolog RET

Syntax checking

As of GNU Emacs version 22.1, flymake ships with Emacs. This enables on-the-fly syntax checking, using the Prolog compiler as checker. To use it with SWI-Prolog, add the following to your .emacs:
(add-hook 'prolog-mode-hook
          (lambda ()
            (require 'flymake)
            (make-local-variable 'flymake-allowed-file-name-masks)
            (make-local-variable 'flymake-err-line-patterns)
            (setq flymake-err-line-patterns
                  '(("ERROR: (?\\(.*?\\):\\([0-9]+\\)" 1 2)
                    ("Warning: (\\(.*\\):\\([0-9]+\\)" 1 2)))
            (setq flymake-allowed-file-name-masks
                  '(("\\.pl\\'" flymake-prolog-init)))
            (flymake-mode 1)))

(defun flymake-prolog-init ()
  (let* ((temp-file   (flymake-init-create-temp-buffer-copy
         (local-file  (file-relative-name
                       (file-name-directory buffer-file-name))))
    (list "swipl" (list "-q" "-t" "halt" "-s " local-file))))

Tracing Prolog execution

There are Emacs definitions that mimic a limited subset of SWI-Prolog's graphical tracer within the Emacs buffer. They are available as etrace.

etrace is mostly a proof of concept at this point and may be useful for you if you do not have X11 installed.

Instead of tracing, consider using declarative debugging to locate mistakes in Prolog programs.

More about Prolog: The Power of Prolog

Main page