New version of the units package v0.12

After thinking a lot about this, thank you so much for this suggestion !
It was right under my nose, but I could not see it.
I have pushed a new version with the following fix:

  • resulting quantities have now the form Value*Quantity[Unit].

That means your example now works:

?- qeval(Speed is metre / second ), Speed = Value*Units.
Speed = 1*kind_of(isq:length/isq:time)[si:metre/si:second],
Value = 1,
Units = kind_of(isq:length/isq:time)[si:metre/si:second].

I continue to use dicts for the internal of the libraries because they are very convenient to work with as an implementor.
But I think I was reluctant to let users interact with dicts because of the usual pitfalls around dicts.

Now, it remains that reverting the two statements: Speed = Value*Units, qeval(Speed is metre / second ) does not work, because I can’t know when parsing Value*Units that Units should be a unit and not a value.
Currently, I disambiguate by wrapping the variables with functors like this:

?- Speed = Value * unit Unit, qeval(Speed is metre / second ).
Speed = 1*unit (si:metre/si:second),
Value = 1,
Unit = si:metre/si:second.
?- qeval(quantity Speed =:= metre / second ).
Speed = 1*kind_of(isq:length/isq:time)[si:metre/si:second].

I’m not sure I fully understand your suggestion.
The problem I see is that would introduce nondeterminism during parsing, and that is not an option.
When encountering a variable, I would not know if the variable is a:

  • value
  • unit
  • quantity[unit]
  • value*quantity[unit]
    Those are the 4 possibilities.

First of all, I have removed the use of u: or q: qualifiers.
For units and quantities like si:metre or isq:speed, the original libraries organized them using c++ namespaces, so that users could selectively import the units they wanted.
I thought of doing the same by piggy backing on swi-prolog module system, but I have not yet really implemented this.