;;; -*- Mode: Lisp; Package: Puser; Base: 10.; Options: ((World Peano)); -*- ;;; (C) Copyright 1983,1984,1985, Uppsala University ;;factorial and fibonacci in LM-Prolog, first without using built-in predicates (define-predicate help ((help) (lisp-value ?help prolog:*peano-help*) (format t "~%~a" ?help))) (define-predicate plus ((plus 0)) ((plus ?sum 0 . ?addends) (plus ?sum . ?addends)) ((plus (1+ ?sum) (1+ ?x) . ?addends) (plus ?sum ?x . ?addends))) (define-predicate times ((times (1+ 0))) ((times 0 0 . ?)) ((times ?product (1+ ?x-1) . ?multiplicands) (times ?product-m . ?multiplicands) (times ?product-y ?x-1 ?product-m) (plus ?product ?product-y ?product-m))) (define-predicate factorial ((factorial (1+ 0) 0)) ((factorial ?factorial (1+ ?n-1)) (factorial ?factorial-of-n-1 ?n-1) (times ?factorial (1+ ?n-1) ?factorial-of-n-1))) (define-predicate fibonacci ((fibonacci 0 0)) ((fibonacci (1+ 0) (1+ 0))) ((fibonacci ?fib (1+ (1+ ?x))) (fibonacci ?a (1+ ?x)) (fibonacci ?b ?x) (plus ?fib ?a ?b))) ;;now for the more efficient versions (define-predicate ordinary-factorial :(options (argument-list (factorial +n))) ((ordinary-factorial 1 0)) ((ordinary-factorial ?f ?n) (> ?n 0) ;;otherwise can loop on negative numbers while backtracking (difference ?n-1 ?n 1) (ordinary-factorial ?factorial-of-n-1 ?n-1) (product ?f ?factorial-of-n-1 ?n))) (define-predicate ordinary-fibonacci :(options (argument-list (fibonacci +n))) ((ordinary-fibonacci 0 0)) ((ordinary-fibonacci 1 1)) ((ordinary-fibonacci ?fib ?n) (difference ?n-1 ?n 1) (ordinary-fibonacci ?a ?n-1) (difference ?n-2 ?n-1 1) (ordinary-fibonacci ?b ?n-2) (sum ?fib ?a ?b)))