2

Some of my Prolog programs could profit quite a bit if I could replace all (is)/2-based integer arithmetics by their counterpart.

So I want the power ... with ... so I can replace X is 10^3 with something clpfd-y :)

Consider the following five Prolog processors supporting :

  • GNU Prolog 1.4.4

    ?- X #= 10^3.
    uncaught exception: error(type_error(fd_evaluable,(^)/2),(#=)/2)
    
    ?- X #= 10**3.
    X = 1000.
    
  • SWI-Prolog 7.3.14

    ?- use_module(library(clpfd)).  % autoload would be even more awesome
    true.
    
    ?- X #= 10^3.
    X = 1000.
    
    ?- X #= 10**3.
    ERROR: Domain error: `clpfd_expression' expected, found `10**3'
    
  • B-Prolog 8.1

    ?- X #= 10^3.
    X #= 10^3.
    *** error(illegal_array_access,10^3)
    
    ?- X #= 10**3.
    X = 1000.
    
  • SICStus Prolog 4.3.2

    ?- use_module(library(clpfd)).
    true.
    
    ?- X #= 10^3.
    ! Existence error in (^)/2
    ! constraint user:wi(^)/2 does not exist
    ! goal:  10^3
    
    ?- X #= 10**3.
    ! Existence error in user:(**)/2
    ! constraint user:(**)/2 does not exist
    ! goal:  10**3
    

Ideas / hints / advice, please. What can I do? Use some compatibility layer(s), perhaps?

Thank you in advance!

repeat
  • 18,496
  • 4
  • 54
  • 166
  • 1
    Far more difficult will be to handle numeric range differences ! See for instance Markus Triska [thesis](http://www.metalevel.at/drt.pdf) – CapelliC Dec 25 '15 at 08:20
  • @CapelliC. I didn't get that... What exactly are you referring to? Please point me to some page in mat's thesis... Or are you possibly referring to one of the following limitations? How multiple solvers can interact gracefully? Or how built-ins like `length/2` can't handle FD vars because the implementation hasn't caught up yet? – repeat Dec 25 '15 at 09:23
  • @CapelliC. Merry X-mas, btw! Rise and shine for the lord has come to the Earth... – repeat Dec 25 '15 at 09:25
  • start on page 21 (par. 3.3.1), then read on :) – CapelliC Dec 25 '15 at 10:29
  • @CapelliC: Aye! Aye! Thank you! – repeat Dec 25 '15 at 13:02
  • @CapelliC. So you are worried about some of the idiosyncrasies that [tag:gnu-prolog] has.... right? – repeat Dec 25 '15 at 13:26
  • 1
    not really... but I like Prolog for its own merits, and despite its problems... I appreciate the efforts to make it more useful, and hope Markus will succeed fully with his high level objectives. From an engineering viewpoint (that's the perspective from where I read your question), consider that the author of B-Prolog created a *new* language (Picat) to be free and unencumbered from Prolog heritage. – CapelliC Dec 25 '15 at 18:58
  • @CapelliC. Fair enough. OTOH Neng-Fa Zhou stated in https://groups.google.com/forum/#!topic/picat-lang/A-ooHX8k9mA (02/2015): "B-Prolog's development is not stopped, but the main focus has shifted to Picat. *Picat share the same engine with B-Prolog.* You can load and run B-Prolog's byte code with Picat as follows: [...]" No bridges are burned:-) – repeat Dec 25 '15 at 19:14
  • Note the difference between: `X in -1..1, Y #=(X*X)*(X*X).` and `X in -1..1, Y#=X*X*X*X.` – false Dec 25 '15 at 21:45
  • @false. With SICStus clpfd? mat's clpfd: `?- Xin -1..1, Y #=(X*X)*(X*X).` Answer: `X in -1..1, X^4#=Y, Y in 0..1.` and `?- X in -1..1, Y #=X*X*X*X.` has answer: `X in -1..1, X^4#=Y, Y in 0..1` (same) – repeat Dec 25 '15 at 22:00
  • @repeat: SICStus. See your own tags – false Dec 25 '15 at 22:01
  • In general, `X^Y` should propagate more easily and more thoroughly than `X*X*...*X`. So pow would be a win for sicstus clpfd... – repeat Dec 25 '15 at 22:04
  • Try `X^X#=X.` anywhere – false Dec 25 '15 at 22:32
  • Did you considered Logtalk ? Imo it's **absolutely** the best for portability. A portability layer is also available in Swipl and several others (well, at least I believe...) – CapelliC Dec 25 '15 at 23:27
  • @false. I tried `X^X #= X` in SWI. I got the answer `X^X #= X`, so it did not propagate a bit. Sure, I would have liked different answers (like `X in {-1}\/{1}` or `X in -1..1, X*X #= 1` or `X in -1..1, X^X #= X` better), but that's a different issue... For in SWI `X #= 1^1` runs. In SICStus I have to write `X is 1^1`... – repeat Dec 26 '15 at 07:00

2 Answers2

2

Quick hack to the rescue?

Warning: massive overkill ahead, but... does it even work? And is it portable?

Let's check it out!

  • SWI-Prolog 7.3.14

    • using

      ?- use_module(library(clpq)).
      true.
      
      ?- clpq:{X = 10^3}, integer(X).
      X = 1000.                          % <== SUCCESS!
      
    • using

      ?- use_module(library(clpr)).
      true.
      
      ?- clpr:{X = 10^3}, integer(X).
      false.
      
  • SICStus Prolog 4.3.2

    • using

      ?- use_module(library(clpq)).
      true.
      
      ?- clpq:{X = 10^3}, integer(X).
      false.
      
    • using

      ?- use_module(library(clpr)).
      true.
      
      ?- clpr:{X = 10^3}, integer(X).
      false.
      

1X success, 3X failure... Works, well, kind of... Then again, I guess it ain't it.

repeat
  • 18,496
  • 4
  • 54
  • 166
  • 2
    `clpr` and `clpq` do work as expected: a float `1000.0` for `10^3` ; and a `rat(1000,1)` for `clpq`. – false Dec 25 '15 at 22:29
  • I fear clpfd is not compatible - out of the box, at least - with clpq/clpr. So your solution seems very hacky to me.... sorry. Maybe 'simple' term rewriting, with goal_expansion, could help, and eventually syntax macros based on :- if(swi) or :-if(sictus)... – CapelliC Dec 26 '15 at 01:56
  • @false. It's a matter of expectations. So (while that breaks my hack), should clpq in SWI rather give `rat(1000,1)` instead of `1000`, too? – repeat Dec 26 '15 at 07:35
  • @CapelliC. Which problems did you encounter mixing two solvers? Would you see combining solvers as promising/interesting? Apart from mixed-integer linear programming? So far, I have found the following about solver interoperability via attributed variables: https://sicstus.sics.se/sicstus/docs/latest4/html/sicstus.html/CLPFD-Coexisting.html#CLPFD-Coexisting , https://sicstus.sics.se/sicstus/docs/latest4/html/sicstus.html/lib_002datts.html . – repeat Dec 26 '15 at 07:50
  • I don't know enough to answer your question... sorry but I'm - kind of - self learner, so maybe it's just my intuition... – CapelliC Dec 26 '15 at 11:41
  • @CapelliC. Okay, no problem! None at all! But I won't let you off my hook regarding that "modelling and solving constraint problems *cooperatively* in different clp(X) " question :-) – repeat Dec 26 '15 at 13:22
  • @repeat: You are now throwing everything into a single question. Your question was about power. clpq and clpr have since the early 1990s always had `^` as an exponentiation operator. But they are not directly compatible with the integers. Never had, and as for clpr never should be. – false Dec 27 '15 at 20:33
  • @false. Thx 4 pointing out that the question should not have the tag [tag:clpq]! – repeat Dec 27 '15 at 20:45
0

You can use for constant expressions:

?- X is 10^3.
X = 1000.

Which should work in a ISO compliant prolog thanks to corr2.

It will also propagate inside CLP(FD) as if it were X #= 10^3:

?- Y #= X+1, X is 10^3.
Y = 1001
X = 1000