How to persist custom or non trivial data types in swi-prolog with persistency library? - persistence

I want to persist my prolog database with peristency library (https://www.swi-prolog.org/pldoc/man?section=persistency).
I have a module file with something like this:
:- module(model,
[ campament/5
]).
:- use_module(library(persistency)).
:- persistent
campament(name:atom, date_from:date, date_to:date, ubication:text, description:text).
This definition is related to date data type (https://www.swi-prolog.org/pldoc/man?section=timedate), that is not present in error library (https://www.swi-prolog.org/pldoc/man?section=error) mentioned in persistent/1 (https://www.swi-prolog.org/pldoc/doc_for?object=persistent/1).
So, when I try to persist this clause I get an error:
?- use_module(model).
?- model:bd('data.db').
?- parse_time('20180720', iso_8601, From),
| parse_time('20180729', iso_8601, To),
| model:assert_campament('My campament', From, To, 'there', 'nothing').
ERROR: type `date' does not exist
ERROR: In:
ERROR: [15] throw(error(existence_error(type,date),_37572))
ERROR: [11] model:assert_campament('My campament', From, To, 'there', 'nothing') at /home/xxx/model.pl:9
ERROR: [9] <user>
ERROR:
ERROR: Note: some frames are missing due to last-call optimization.
ERROR: Re-run your program in debug mode (:- debug.) to get more detail.
How can I persist date like types? In must_be/2 (https://www.swi-prolog.org/pldoc/doc_for?object=must_be/2), one of possible types is:
...
any any term
type Term is a valid type specification
...
Regards.

Related

"In Unicode programs, must have the same structure layout, irrespective of the length" error

I'm now getting this error after making a small mod to a working program. The structures have the same type (though the tables are different) but I get this error? I've looked at similar postings but couldn't find an answer to this.
Codes snippets included.
* ---
,begin of TY_RESB_CDC
,MANDT type MANDT
,RSNUM type RSNUM
,RSPOS type RSPOS
,RSART type RSART
,UDATE type CDDATUM
,UTIME type CDUZEIT
.include type ZBW_MATERIAL_RESVN_RESB.
types: end of TY_RESB_CDC
,TT_RESB_CDC type hashed table of TY_RESB_CDC
with unique key RSNUM RSPOS RSART
,TT_RESB_STD type standard table of TY_RESB_CDC
with empty key
---
,LT_RESB_CDC type TT_RESB_CDC
,WA_RESB_CDC type TY_RESB_CDC "like LINE OF LT_RESB_CDC
,LT_RESB_STD type TT_RESB_STD
,WA_RESB_STD type TY_RESB_CDC "like line of LT_RESB_STD
---
move-corresponding <FS_DATA> to WA_RESB_STD.
" already exists in CDC
if WA_RESB_STD eq WA_RESB_CDC. "<FS_RESB_CDC>.
continue. "no change, skip this record
A component name cannot contain a dot in its name, in a Unicode program. Same for any other ABAP symbolic name.
The below code with name .include is not permitted. You were mistaken by DDIC structures, which have different rules.
TYPES: begin of TY_RESB_CDC,
...
UTIME type CDUZEIT,
.include type ZBW_MATERIAL_RESVN_RESB,
end of TY_RESB_CDC.
Instead, you should use the ABAP statement INCLUDE TYPE to include the components of a structure (e.g. ZBW_MATERIAL_RESVN_RESB in your case):
TYPES: begin of TY_RESB_CDC,
...
UTIME type CDUZEIT.
INCLUDE TYPE ZBW_MATERIAL_RESVN_RESB.
TYPES: end of TY_RESB_CDC.

I am getting an error in prolog in vs code please check

This is the code:
dog(rottweiler).
cat(sphynx). dog(poodle).
dog(bulldog). cat(bengal).
dog(dobermann).
cat(himalayan). cat(singapura).
ND THE ERROR IS:-
Warning: Clauses of dog/1 are not together in the source-file
Warning: Earlier definition at c:/users/dell/desktop/prolog/dog:1
Warning: Current predicate: cat/1
Warning: Use :- discontiguous dog/1. to suppress this message
Warning: c:/users/dell/desktop/prolog/dog:4:
Warning: Clauses of cat/1 are not together in the source-file
Warning: Earlier definition at c:/users/dell/desktop/prolog/dog:2
Warning: Current predicate: dog/1
Warning: Use :- discontiguous cat/1. to suppress this message.
TRUE
In Prolog, an n-ary predicate p, for n≥0, is defined by a procedure, which consists of one or more clauses whose conclusions are terms of the form p(a1, ..., an), where each a_i is an argument. Clauses belonging to the same procedure are expected to be declared in sequence, contiguously.
When the clauses of two or more distinct procedures appear interleaved in the source code, the compiler produces the warning messages you get. To suppress such messages, you can use a directive of the form :- discontiguous predicate/arity.
For example:
:- discontiguous dog/1.
:- discontiguous cat/1.
dog(rottweiler).
cat(sphynx).
dog(poodle).
dog(bulldog).
cat(bengal).
dog(dobermann).
cat(himalayan).
cat(singapura).
Note, however, that the best option is to follow the Prolog convention and modify your code as follows:
% clauses of the first procedure
dog(rottweiler).
dog(poodle).
dog(bulldog).
dog(dobermann).
% clauses of the second procedure
cat(sphynx).
cat(bengal).
cat(himalayan).
cat(singapura).

.Q.trp and bt handling

I saw (in .Q.fpn) the following technique to parse and show the bt object passed to .Q.trp function:
q)f:{x+1}
q).Q.trp[f;`a;{'(x;y)}]
'type
[4] f:{x+1}
^
[3] (.Q.trp)
[2] .Q.trp[f;`a;{'(x;y)}]
^
[0] .Q.trp[f;`a;{'(x;y)}]
^
'(x;y) seems like an exception building construction, - but Kx documentation says that there are only two ways of exception building: from symbol and from string. It is looks like we can built an exception from a list of (symbol; bt object).
So what the construction '(x;y) stands for?
Can we build something different than exception with '(x;y)?
My guess is that this is a specific signal recently allowed along with the addition of the .Q.trp/.Q.bt functionality. It looks like it works only for (symbol;bt object) or (string;bt object), anything else is unrecognized.
q).Q.trp[{1+x};`a;{'(x;y;1)}]
'stype
The output can be stored if returned without the signal:
q)r:.Q.trp[{1+x};`a;{(x;y)}]
and this type of signal seems to work in any context, not just within .Q.trp:
q)'("other";last r)
'other
[2] {1+x}
^
[1] (.Q.trp)
[0] r:.Q.trp[{1+x};`a;{(x;y)}]
I suspect the last r has a very specific format/shape that one could fabricate but it seems like an unnecessary use-case.
Bonus oddities:
This works:
q)'("other";())
'other
[0] '("other";())
^
but other things I've tried show up weird errors:
q)'("other";(();()))
pl0
pl0
q)
q)'("other";"abc")
srr

Is "create domain" allowed with a base type of json (or jsonb)?

I have a custom type with code similar to the following (shortened for brevity):
create domain massFraction as jsonb (
value->'h' > 0 and value->'h' is not null
);
Running this provokes the following error:
ERROR: type modifier is not allowed for type "jsonb"
The documentation makes no mention of json being a disallowed base type for a domain.
https://www.postgresql.org/docs/12/sql-createdomain.html
I also thought that it was perhaps the "not null" part of the constraint, which the documentation mentions is "tricky". Additionally, I've tried similar statements without any json operators. All of these seem to be disallowed.
I am obnoxiously prone to not reading documentation, and worse still about understanding documentation when I do bother to read it... so does it not exist, or am I looking in the wrong places to see if this is permitted? Why is it not permitted?
You're missing a CHECK after jsonb:
create domain massFraction as jsonb check (
value->'h' > 0 and value->'h' is not null
);
This results in another error:
ERROR: 42883: operator does not exist: jsonb > integer
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
I believe what you want is
CREATE DOMAIN massFraction AS jsonb CHECK (
CASE jsonb_typeof(value->'h')
-- only cast when it is safe to do so
-- note: this will reject numeric values stored as text in the json object (eg '{"h": "1"}')
WHEN 'number' THEN (value->>'h')::integer > 0
ELSE false
END
)
The error you're getting comes from the fact that you input is parsed as
CREATE DOMAIN massFraction AS jsonb(<modifier>) -- like in varchar(10)
As an aside I would recommend against using camelCase in postgresql, as massFraction is the same as massfraction (unless quoted) and postgresql will use the lowercased form when reporting errors, hints, etc.

Problem with the deprecation of the postgresql XML2 module 'xml_is_well_formed' function

We need to make extensive use of the 'xml_is_well_formed' function provided by the XML2 module.
Yet the documentation says that the xml2 module will be deprecated since "XML syntax checking and XPath queries"
is covered by the XML-related functionality based on the SQL/XML standard in the core server from PostgreSQL 8.3 onwards.
However, the core function XMLPARSE does not provide equivalent functionality since when it detects an invalid XML document,
it throws an error rather than returning a truth value (which is what we need and currently have with the 'xml_is_well_formed' function).
For example:
select xml_is_well_formed('<br></br2>');
xml_is_well_formed
--------------------
f
(1 row)
select XMLPARSE( DOCUMENT '<br></br2>' );
ERROR: invalid XML document
DETAIL: Entity: line 1: parser error : expected '>'
<br></br2>
^
Entity: line 1: parser error : Extra content at the end of the document
<br></br2>
^
Is there some way to use the new, core XML functionality to simply return a truth value
in the way that we need?.
Thanks,
-- Mike Berrow
After asking about this on the pgsql-hackers e-mail list, I am happy to report that the guys there agreed that it was still needed and they have now moved this function to the core.
See:
http://web.archiveorange.com/archive/v/alpsnGpFlZa76Oz8DjLs
and
http://postgresql.1045698.n5.nabble.com/review-xml-is-well-formed-td2258322.html