Difference between revisions of "Functor Domain Versioning"
m (structure) |
m (category) |
||
(One intermediate revision by the same user not shown) | |||
Line 1: | Line 1: | ||
It is problematic to update functor domains, if terms have been persisted in serialized form (e.g. using <vp>save</vp> to save the terms in a file). | It is problematic to update functor domains, if terms have been persisted in serialized form (e.g. using <vp>save</vp> to save the terms in a file). | ||
Line 134: | Line 132: | ||
(It is however not recommend using binary serialization for inter-session persistence). | (It is however not recommend using binary serialization for inter-session persistence). | ||
[[Category: | [[Category:Data types and handling|{{PAGENAME}}]] |
Latest revision as of 15:58, 19 February 2019
It is problematic to update functor domains, if terms have been persisted in serialized form (e.g. using save to save the terms in a file).
The persisted terms will be in the old format, but the program expects the new format.
domains ppp = fct( integer A, real B, string C ).
In the file the terms will look like this
fct(7,19.5,"something")
Now we want to have an additional integer list in fct:
domains ppp = fct( integer A, real B, string C, integer* NewInfo ).
However, a serialized version of such a term looks like this:
fct(7,19.5,"something",[23,53,1])
And therefore we can no longer read our old terms; they lack a list.
The attributes default/1 and retiredFunctor/1 can help dealing with such problems.
Default values
The last arguments of a functor can have default values:
domains ppp = fct( integer A, real B, string C, integer* NewInfo [default([])] ).
The default attribute does not change anything within the program; it only affects the deserialization. If during deserialization we meet the closing parenthesis too soon we supply default values for the remaining arguments.
Notice that this will only work for text deserialization, in binary form there is no way to determine whether there are fewer arguments or not.
T = toTerm(ppp, "fct(7,19.5,\"something\")")
Will make this binding of T
T = fct(7, 19.5, "something", [])
I.e. the default argument [] will be added to the term during the deserialization, to compensate for the missing term.
The default attribute does not have any effect for the code that must be written in the program, in that code the last argument must always be present.
clauses q() = fct(7,19.5,"something"). % illegal: missing last argument
Retired functors
Assume that we not only want to add an extra integer list to the fct functor, we also want to drop the real B.
domains ppp = fct( integer A, string C, integer* NewInfo ).
Now deserialization cannot be handled simply by adding a default argument to the last attributes.
Instead the old functor alternative fct can be retired and replaced by a new fct2:
domains ppp = fct(integer A, real B, string C) [retiredFunctor(aaa::fct_ppp)]; fct2(integer A, string C, integer* New).
The retiredFunctor attribute says that this alternative is no longer in the domain; it can however still be expected in serialized terms. When met in a serialized term, the predicate aaa::fct_ppp will be used to correct the problem. The predicate aaa::fct_ppp must have the type:
predicates fct_ppp : (integer A, real B, string C) -> ppp NewValue.
I.e. it takes the arguments of the old functor and returns a value in the functor domain.
We can implement fct_ppp like this:
clauses fct_ppp(A, _B, C) = fct2(A, C, []).
T = toTerm(ppp, "fct(7,19.5,\"something\")")
Will effectively correspond to this predicate call
T = aaa::fct_ppp(7, 19.5, "something")
And will therefore result in this binding:
T = fct2(7, "something", [])
The retired functor does not exist inside the program; the program can only see the rest of the functors, i.e. the non-retired ones.
predicates pred : (ppp P). clauses pred(fct(A, B, C)) :- ... % illegal this functor does not exist it is retired pred(fct2(A, C, New)) :- ... % This is the only case in the code
retiredFunctor/1 will also work for binary serializations, provided:
- The old domain had more than one alternative (so there are functor numbers in the serialization)
- New alternatives are added last (to retain functor numbers)
(It is however not recommend using binary serialization for inter-session persistence).