3 ms·
You can do this in SWI Prolog using the between/3 predicate for the inequality, and the is/2 predicate for the arithmetic.
by colanderman 10y ago
You can do this in SWI Prolog using the between/3 predicate for the inequality, and the is/2 predicate for the arithmetic.
- colanderman 10y agoExample, now that I'm at a terminal: fib(X, X) :- between(0, 1, X). fib(X, Y) :- (var(Y) -> between(2, infinite, X); MaxX is Y + 1, between(2, MaxX, X)), X1 is X - 1, X2 is X - 2, fib(X1, Y1), fib(X2, Y2), Y is Y1 + Y2. The trick with var/1 allows the fib(-, +) instantiation to terminate (albeit very slowly). Otherwise it's not necessary. What's even cooler is SWI-Prolog's CLP support. You can write fib/2 in the obvious manner and support all instantiations: ?- use_module(library(clpfd)). fib(X, X) :- X #>= 0, X #=< 1, indomain(X). fib(X, Y) :- X #>= 2, X #=< Y + 1, X1 #= X - 1, X2 #= X - 2, Y #= Y1 + Y2, fib(X1, Y1), fib(X2, Y2).
- thisrod 10y agoWhen I tried out Prolog, I was struck by the inelegance of is/2. There has to be something like it, because no one knows how to write an interpreter for arcsin(X,Y) :- sin(Y,X). However, MetaPost can do that for linear expressions. You can say (in Prolog syntax) midpoint(X,Y,Z) :- Z == (X+Y)/2. two(X) :- midpoint(0,X,1). And the MetaPost interpreter will find the solution two(2). Does anyone know of Prolog extensions that can solve linear algebra problems like that?
- colanderman 10y agoSWI-Prolog has CLP extensions to do exactly that: http://www.swi-prolog.org/pldoc/man?section=clp http://www.swi-prolog.org/pldoc/man?section=clp ?- use_module(library(clpq)). midpoint(X, Y, Z) :- {Z =:= (X+Y)/2}. two(X) :- midpoint(0, X, 1). does what you want.
- thisrod 10y agoThank you. It's a relief to know that I don't need to invent it.