Des 6.7 requiring SWI-Prolog 7.4

Hi Fernando,

DES is getting more and more complete! I was wondering about sticking to SWI-Prolog 7.4. Looking at the SourceForge download it is claimed it is unlikely to work with 8.x. Why is this? Version 7 introduced serious incompatibilities, but 8 is pretty compatible to 7. I tried to load it under 8.3.29. That seems to work fine, except for some “Illegal multibyte Sequence” messages which seems to be mostly caused by non-ASCII code used in comments. Is there a test suite?

I was also wondering whether tabling would make a significant simplification and possible speedup for processing Datalog?

 Cheers --- Jan

Hi Jan,

DES is getting more and more complete!

Thanks!

I was wondering about sticking to SWI-Prolog 7.4. Looking at the SourceForge download it is claimed it is unlikely to work with 8.x. Why is this?

Maybe the disclaimer was too strong since most tests will work. However, some tweaks to the DES code should be done to make all them work. For example, the representation of rationals. In its current state, for the fuzzy part of the system, one can get:

Background coloured in red is what is expected, while yellow is what is get.

In addition, there was an issue with the ODBC driver:

Is there a test suite?

Yes, but not in the common way. I run a batch file with inputs such as those above and its output is compared to a valid output with the windiff tool, which highlights differences.

I was also wondering whether tabling would make a significant simplification and possible speedup for processing Datalog?

Tabling is an awesome addition to SWI-Prolog (great work!). While speedup would be undoubtedly and hugely improved if using it, I see two drawbacks: First, there are some features (nulls, duplicates, top-n solutions…) that might not be directly mapped to tabling, though I did not dig enough into SWI-Prolog tabling to be completely sure. I think that (some of) those features needs the tabling engine to be aware of them. Second, it would be an implementation targeted at SWI-Prolog which would not work with SICStus Prolog, and two interfaces should be developed (as an aside note, Ciao Prolog and GNU Prolog were also supported and might be recovered in the future).

All the best,
Fernando

1 Like

That is a bit odd. If the Prolog flag prefer_rationals is set to false (which is the default), 9/50 evaluates to 0.18. Only if this flag is set to true the result is 9r50. Could it be that you set this to true in your personal init file? I do :slight_smile:

This should be fixed. Not a lot happened to the ODBC driver. Can you describe how to reproduce this? I’d prefer to have this fixed …

Possibly. We’ve seen some discussion here on the semantics of null :slight_smile: Although tabling gives you basically the same advantages over plain Prolog as Datalog in terms of termination and well founded semantics (if you support that), there could be details that are hard to match.

Portability :frowning: I fear we stay with the ISO limitations forever :frowning: Ciao has tabling these days (but no well founded semantics AFAIK).

I also have an interest in this as I try to keep the Wiki topic

correct.

As that is a Wiki topic you can change it/add to it or make a separate version for use with DES. Also if you see a need to have a change or addition made let me know. That topic is actually used more often than I anticipated.

I think I used the default configuration for this flag. Anyway, I explicitly changed this but the outcome was the same:

DES> /system_mode fuzzy

FDES> /c examples/fuzzy/near

Info: 0 rules consulted.
Info: 3 equations consulted.

FDES> madrid near lisboa

Info: Processing:
  answer :-
    madrid near lisboa.
{
  answer(3r25)
}
Info: 1 tuple computed.          

FDES> /t

?- current_prolog_flag(prefer_rationals,X).
X = 'false'.

Anyway, I think that, with time to dig into it, this can be addressed (I’m starting the new academic course…)

P.S. With respect to the ODBC issue, I will prepare a reproducible case.

1 Like

I see. A quick scan comes with this stack:

     [52] _593524 is rationalize(1.0)
     [51] 'nf_q':nf_number(1.0, _593522)
     [49] 'nf_q':nf(1.0*1.0, _593520)
     [48] 'nf_q':nf(- (1.0*1.0), _593518)
     [47] 'nf_q':nf(_593476-1.0*1.0, _593486)
     [46] 'nf_q':{_593476=1.0*1.0}
     [45] clpq_solve(1.0*1.0, _593458)
     [42] t_norm_aux([1.0, 1.0], 'product', _593454)
     [40] t_norm_matrix_j(1, 1, 1, 2, 'near', vector(vector('$mutable'(1.0, '$mutable'(0.0, _593412)), '$mutable'(0.6, '$mutable'(0.0, _593418))), vector('$mutable'(0.6, '$mutable'(0.0, _593424)), '$mutable'(1.0, '$mutable'(0.0, _593430)))), _593434)

Now I’m not an expert in this. I always lived under the impression that clpq is clp for rational numbers and clpr is mostly the same for real numbers. But then, I find in des_fuzzy.pl this, which suggests you really want clpq.

   clpq_solve(Degree-MaxResDegree,NewDegree), % Do not lose precision due to floating point calculations

Doesn’t look like hard to fix. I think in q_to_number/2 add a clause like this provides a portable fix:

:- if(current_predicate(rational/1)).
q_to_number(Rat, Num) :-
   rational(Rat),
   !,
   Num is float(Rat).
:- endif.

Note that both SICStus and SWI support :- if(Cond).:- else.:- endif. blocks that allow you to use the same code with both systems. Both also implement the flag version_data to get the dialect and version. Testing features rather than versions provides better portability!

Many thanks, Jan! I’ll try this fix.

Duplicates would be an issue only if you’re using multisets and care about execution order. As I recall, Datalog allows both bottom-up and top-down execution (e.g., magic sets and tabling), so why would duplicates be an issue?

And nulls are weird in SQL, so if you have Relational Algebra and SQL in DES, how do you resolve the differences?

Duplicates would be an issue only if you’re using multisets and care about execution order. As I recall, Datalog allows both bottom-up and top-down execution (e.g., magic sets and tabling), so why would duplicates be an issue?

Indeed, DES can use both multisets and sets (selectable with the commands /duplicates on and /duplicates off, respectively), and order is also handled (with the metapredicate order_by). Both features were intended to be able to translate SQL into Datalog.

Execution order is relevant for the semantics for the combination of metapredicates, such as in the query top(1,order_by(t(X),[X])), which retrieves the first solution of t(X) when it is sorted in ascending order. Again, this was driven by dealing with SQL.

And nulls are weird in SQL, so if you have Relational Algebra and SQL in DES, how do you resolve the differences?

Yes they are. DES implements an approximation to nulls in SQL that behaves the same as current SQL implementation in most use cases for teaching basic SQL. The following paper describes some aspects of the implementation of outer join operations:

[Sae12a] [BibTeX] F. Sáenz-Pérez, “Outer Joins in a Deductive Database System”, Electronic Notes in Theoretical Computer Science, vol. 282, pp. 73-88, May, 2012.

The fix passed all the tests! Thanks again, Jan.

1 Like

I guess not the ODBC one, no? Or was that caused by rational numbers that don’t cross the ODBC interface well? Would be nice if we can donate version 7.4 to the museum :slight_smile:

I guess not the ODBC one, no?

Only fixed the rational numbers issue. For the ODBC connection, the error raises with the following version of SQL Server (default configuration):

Microsoft SQL Server 2014 - 12.0.2269.0 (X64) Jun 10 2015 03:35:45 Copyright (c) Microsoft Corporation Express Edition (64-bit) on Windows NT 6.3 <X64> (Build 19043: )

For a database “test” with a table “dual” including a single column “void” with type “int”:

image.png

By debugging the connection to this database and extracting its metadata, it seems that the issue comes from the call to odbc_column/3 (library/odbc.pl in the SWI-Prolog installation) in:

table_column(Connection, Table, Column, Tuple) :-
( var(Table)
-> odbc_current_table(Connection, Table)
; true
),
( ground(Column) % force determinism
-> odbc_column(Connection, Table, Tuple),
arg(4, Tuple, Column), !
; odbc_column(Connection, Table, Tuple),
arg(4, Tuple, Column)
).

SWI-Prolog Version 7.4.2:

Call: (58) 'odbc':odbc_column('$odbc_connection'(6028676), 'dual', _55912) ? creep
Exit: (58) 'odbc':odbc_column('$odbc_connection'(6028676), 'dual', row('test', 'dbo', 'dual', 'void', 4, 'int', 10, 4, 0, 10, 1, '$null$', '$null$', 4, '$null$', '$null$', 1, 'YES', 0, 0, 0, 0, '$null$', '$null$', '$null$', '$null$', '$null$', '$null$', 38)) ?

SWI-Prolog Version 8.2.4-1:

* Call: (62) 'odbc':odbc_column('$odbc_connection'(145719600), 'dual', _110658) ? skip
* Exception: (61) 'odbc':table_column('$odbc_connection'(145719600), 'dual', _110264, _110734) ?

And the ODBC configuration is as follows:

Other ODBC connections seem to work well in version 8.2.4-1 (Access, PostgreSQL, MySQL, Oracle, DB2).