Prolog: Difference between overriding predicate and using it - object

I feel really stupid, and feel like I'm missing something.
I've basically got two files:
module.pl for the universal logic rules (meant to be reusable)
state.pl one for the current scenario
In the module file (module.pl) I've declared:
inside(Food,Eater,T) :-
isTime(T),
injestEvent(InjEvent),
justAfter(T,InjEvent),
actorOfEvent(InjEvent, Eater),
objectOfEvent(InjEvent, Food).
Q1) I've had to declare all those other predicates with singleton variables (in the same file), just to stop module.pl complaining they don't exist:
isTime(_T).
justAfter(_Time,_Event).
actorOfEvent(_Event, _ActorOfEvent).
objectOfEvent(_Event,_ActorOfEvent).
Is that right?
Q2) I can't use those predicates like justAfter/2 my other file without it saying:
Local definition of user:justAfter/2 overrides weak import from module
How can I use the predicates I've imported from my module, rather redefining it?

Prolog modules were designed to hide auxiliary predicates. They don't provide a concept of interface that allows separating predicate declarations from predicate definitions. That's why the compiler complains if you export predicates that are not defined. From your description, I assume you tried something like:
----- module.pl -----
:- module(module, [
inside/3, isTime/1, injestEvent/1, justAfter/2, actorOfEvent/2, objectOfEvent/2
]).
inside(Food,Eater,T) :-
isTime(T),
injestEvent(InjEvent),
justAfter(T,InjEvent),
actorOfEvent(InjEvent, Eater),
objectOfEvent(InjEvent, Food).
---------------------
which results in:
?- [module].
ERROR: Exported procedure module:justAfter/2 is not defined
ERROR: Exported procedure module:isTime/1 is not defined
ERROR: Exported procedure module:injestEvent/1 is not defined
ERROR: Exported procedure module:objectOfEvent/2 is not defined
ERROR: Exported procedure module:actorOfEvent/2 is not defined
true.
You attempted to workaround this error by adding local definitions. But this just result in the second problem you describe. When you do something like:
?- use_module(module).
You import all the predicates exported by module, including those that you want to define in state.pl. Therefore, the compiler warns you, when loading state.pl, that this file is overriding those predicates. E.g. with:
----- state.pl -----
isTime(1).
injestEvent(injEvent).
justAfter(1, injEvent).
actorOfEvent(injEvent, eater).
objectOfEvent(injEvent, food).
--------------------
we get:
?- [state].
Warning: /Users/pmoura/Desktop/state.pl:1:
Local definition of user:isTime/1 overrides weak import from module
Warning: /Users/pmoura/Desktop/state.pl:2:
Local definition of user:injestEvent/1 overrides weak import from module
Warning: /Users/pmoura/Desktop/state.pl:3:
Local definition of user:justAfter/2 overrides weak import from module
Warning: /Users/pmoura/Desktop/state.pl:4:
Local definition of user:actorOfEvent/2 overrides weak import from module
Warning: /Users/pmoura/Desktop/state.pl:5:
Local definition of user:objectOfEvent/2 overrides weak import from module
true.
Although these are warnings and not errors, calling the inside/3 predicate will not give you what you want:
?- inside(Food,Eater,T).
true.
Where are the bindings?!? Let's trace the call to highlight the cause:
?- trace.
true.
[trace] ?- inside(Food,Eater,T).
Call: (8) module:inside(_2508, _2510, _2512) ? creep
Call: (9) module:isTime(_2512) ? creep
Exit: (9) module:isTime(_2512) ? creep
Call: (9) module:injestEvent(_2804) ? creep
Exit: (9) module:injestEvent(_2804) ? creep
Call: (9) module:justAfter(_2512, _2806) ? creep
Exit: (9) module:justAfter(_2512, _2806) ? creep
Call: (9) module:actorOfEvent(_2804, _2510) ? creep
Exit: (9) module:actorOfEvent(_2804, _2510) ? creep
Call: (9) module:objectOfEvent(_2804, _2508) ? creep
Exit: (9) module:objectOfEvent(_2804, _2508) ? creep
Exit: (8) module:inside(_2508, _2510, _2512) ? creep
true.
The trace makes it clear that the "state" predicates are being called in the wrong context.
A clean solution is to use Logtalk objects instead of Prolog modules. Logtalk extends Prolog and supports most systems, including SWI-Prolog. It supports interfaces/protocols as first-class entities (which solve the first problem you mention) and supports inheritance and calling predicates in their usage context (which solves the second problem). You could use e.g.
----- common.lgt -----
:- object(common).
:- public([
inside/3, isTime/1, injestEvent/1, justAfter/2, actorOfEvent/2, objectOfEvent/2
]).
inside(Food,Eater,T) :-
% call the next predicates in "self", i.e. in the
% object that received the inside/3 message
::isTime(T),
::injestEvent(InjEvent),
::justAfter(T,InjEvent),
::actorOfEvent(InjEvent, Eater),
::objectOfEvent(InjEvent, Food).
:- end_object.
----------------------
and then represent "state" as:
----- state.lgt -----
:- object(state, extends(common)).
isTime(1).
injestEvent(injEvent).
justAfter(1, injEvent).
actorOfEvent(injEvent, eater).
objectOfEvent(injEvent, food).
:- end_object.
---------------------
A quick test (after installing Logtalk):
$ swilgt
...
?- {common, state}.
...
true.
?- state::inside(Food,Eater,T).
Food = food,
Eater = eater,
T = 1.
As a bonus, you can define as many "state" objects as you need. You can also have default definitions for the "state" predicates in the common object. These will be inherited and used when the "state" objects don't provide a definition for a particular predicate. For example, let's add to common the clause:
objectOfEvent(injEvent, drink).
and delete (or comment out) the clause objectOfEvent(injEvent, food). from state. Save and reload and retrying the query will give you:
?- {*}. % abbreviation for Logtalk's make
% Redefining object common
...
% Redefining object state
...
true.
?- state::inside(Food,Eater,T).
Food = drink,
Eater = eater,
T = 1.
If needed, you can also dynamically create new state objects instead of defining them in source files. For example:
?- create_object(s2, [extends(common)], [], [isTime(42), ...]).
This may not be the answer you were looking for but this is also the case where the best answer is to use the right tool^H^H^H^H encapsulation mechanism for the job. Your programming pattern is also a quite common one (and one of the reasons Logtalk was developed).

It's very simple to add a basic form of 'object orientation'.
Let's say we have a clause in a module logic:
:- module(logic, [inside/4]).
% apply the rule to a specified module (expected to be a state object)
inside(M,Food,Eater,T) :-
M:isTime(T),
M:injestEvent(InjEvent),
M:justAfter(T, InjEvent),
M:actorOfEvent(InjEvent, Eater),
M:objectOfEvent(InjEvent, Food).
and we have a lot of state objects pertinent: in a file state1.pl
isTime(10).
injestEvent(eat).
justAfter(10, eat).
actorOfEvent(eat, mick).
objectOfEvent(eat, food).
and in a file state2.pl
isTime(20).
injestEvent(sleep).
justAfter(20, sleep).
actorOfEvent(sleep, everyone).
objectOfEvent(sleep, dream).
then a possible session:
?- [logic].
true.
?- s1:consult(state1).
true.
?- s2:consult(state2).
true.
?- inside(s1,Food,Eater,T).
Food = food,
Eater = mick,
T = 10.
?- inside(s2,What,Who,T).
What = dream,
Who = everyone,
T = 20.
A small generalization, worth to try:
inside(M,Food,Eater,T) :-
resolve(M),
M:isTime(T),
...
where resolve/1 could be
resolve(M) :- var(M) -> current_module(M), catch(M:isTime(_),_,fail) ; true.
this trick enable 'browsing the objects':
?- inside(M,X,Y,Z).
M = s2,
X = dream,
Y = everyone,
Z = 20 ;
M = s1,
X = food,
Y = mick,
Z = 10 ;
false.

An alternative to CapelliC is the use of Prolog dicts. They have been introduced by SWI-Prolog and since release 1.3.0 they are also available in Jekejeke Prolog. If the receiver is not needed, one can simply use an underscore.
File state1.pl:
:- module(state1, [isTime/2, injestEvent/2, justAfter/3,
actorOfEvent/3, objectOfEvent/3]).
:- reexport(logic).
_.isTime() := 10.
_.injestEvent() := eat.
_.justAfter(10) := eat.
_.actorOfEvent(eat) := mick.
_.objectOfEvent(eat) := food.
File state2.pl:
:- module(state2, [isTime/2, injestEvent/2, justAfter/3,
actorOfEvent/3, objectOfEvent/3]).
:- reexport(logic).
_.isTime() := 20.
_.injestEvent() := sleep.
_.justAfter(20) := sleep.
_.actorOfEvent(sleep) := everyone.
_.objectOfEvent(sleep) := dream.
File logic.pl:
:- module(logic, [inside/4]).
M.inside(Food,Eater) := T :-
T = M.isTime(),
InjEvent = M.injestEvent(),
InjEvent = M.justAfter(T),
Eater = M.actorOfEvent(InjEvent),
Food = M.objectOfEvent(InjEvent).
To make the logic also visible in state1 and state2 use reexport/1. This allows sending a message to state1 or state2, but nevertheless a method from logic will be processed. Here is an example run:
Welcome to SWI-Prolog (threaded, 64 bits, version 7.7.19)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
?- T = state1{}.inside(Food,Eater).
T = 10,
Food = food,
Eater = mick.
?- T = state2{}.inside(Food,Eater).
T = 20,
Food = dream,
Eater = everyone.
The exports of isTime/2, injestEvent/2, etc.. will go away with the upcoming release 1.3.1 of Jekejeke Prolog when we have made ('.')/3 call-site aware. But the result for Jekejeke Prolog is the same:
Jekejeke Prolog 3, Runtime Library 1.3.0
(c) 1985-2018, XLOG Technologies GmbH, Switzerland
?- T = state1{}.inside(Food,Eater).
T = 10,
Food = food,
Eater = mick
?- T = state2{}.inside(Food,Eater).
T = 20,
Food = dream,
Eater = everyone

Related

Representing a constant symbol in Sympy such that it is not a free_symbol

Application
I want to create a python function (e.g., Laplacian(expr)). The Laplacian operator is defined as taking the sum of the second partial derivatives of expr with respect to each variable (e.g., Laplacian(f(x,y,z)) is diff(f,x,x) + diff(f,y,y) + diff(f,z,z). In the expression, there may be arbitrary constants c,k, etc that are not variables as far as the expression is concerned. Just as you cannot take the derivative diff(f,126), taking the derivative of the expression with respect to c is not defined.
Need I need to be able to extract the non-constant free symbols from an expression.
Problem
Though I can construct c = Symbol('c', constant=True, number=True) in Sympy, c.is_constant() evaluates to False. Similarly, g(c).is_constant() evaluates to false. For my application, the symbol c should have the exact same behavior as E.is_constant() == True and g(E).is_constant() == True, as it is a number.
Caveats
I cannot register c as a singleton, as it is only defined with respect to this particular proof or expression.
I cannot construct it in the same way values like E are constructed, as there is no specific numeric value for it to be assigned to.
I cannot simply add a constants keyword to Laplacian, as I do not know all such constants that may appear (just as it would not make sense to add constants=[1,2,3,4,...] to solve()).
I cannot simply add a variables keyword to Laplacian, as I do not know the variables that appear in the expression.
The desired usage is as follows:
>>> C = ... # somehow create the constant
>>> symbols_that_arent_constant_numbers(g(C))
set()
>>> symbols_that_arent_constant_numbers(g(C, x))
{x}
>>> g(C).is_constant()
True
stretch goals: It would be awesome to have an arbitrary constant symbol that absorbs other constant terms in the same way that constantsimp operates. Consider introducing an integration constant c into an expression, and then multiplying that expression by I. As far as we are concerned algebraically, cI=c without loosing any generality.
Note
Per Oscar Benjamin's comments on question, current best practices when constructing a sympy-style method (like Laplacian) is to pass a constants or variables keyword into a method. Bare that in mind when applying the following solution. Furthermore, free_symbols has many applications within Sympy, so using another class that has established semantics may have unexpected side-effects.
(I am not accepting my own solution in the event that a better one comes along, as Mr. Benjamin has pointed out there are many open related issues.)
Solution
Sympy provides a mechanism to create such a constant: sympy.physics.units.quantities.Quantity. Its behavior is equivalent to Symbol and singleton constants, but most notably it does not appear as a free symbol. This can help prevent code from interpreting it as a variable that may be differentiated, etc.
from sympy.physics.units.quantities import Quantity
C = Quantity('C')
print("C constant? : ", C.is_constant())
print("C free symbols : ", C.free_symbols)
print("x constant? : ", x.is_constant())
print("g(C) constant? : ", g(C).is_constant())
print("g(x) constant? : ", g(x).is_constant())
print("g(C,x) constant : ", g(C,x).is_constant())
print("g(C) free symbols : ", g(C).free_symbols)
print("g(C,x) free symbols: ", g(C,x).free_symbols)
assert C.is_constant()
assert C.free_symbols == set([])
assert g(C).is_constant()
assert g(C, x).is_constant() == g(x).is_constant() # consistent interface
assert g(C).free_symbols == set([])
assert g(C, x).free_symbols == set([x])
assert [5/C] == solve(C*x -5, x)
The above snippet produces the following output when tested in sympy==1.5.1:
C constant? : True
C free symbols : set()
x constant? : False
g(C) constant? : True
g(x) constant? : None
g(C,x) constant : None
g(C) free symbols : set()
g(C,x) free symbols: {x}
Note that while g(C).is_constant()==True, we see that g(x).is_constant() == None, as well as g(C,x).is_constant() == None. Consequently, I only assert that those two applications have a consistent interface.

Unexpected results in playing with relations

/*
sig a {
}
sig b {
}
*/
pred rel_test(r : univ -> univ) {
# r = 1
}
run {
some r : univ -> univ {
rel_test [r]
}
} for 2
Running this small test, $r contains one element in every generated instance. When sig a and sig b are uncommented, however, the first instance is this:
In my explanation, $r has 9 tuples here and still, the predicate which asks for a one tuple relation succeeds. Where am I wrong?
An auxiliary question: are these two declarations equivalent?
pred rel_test(r : univ -> univ)
pred rel_test(r : set univ -> univ)
The problem is that with the Forbid Overflow option set to No the integer semantics in Alloy is wrap around, and with the default scope of 3 (bits), then indeed 9=1, as you can confirm in the evaluator.
With the signatures a and b commented the biggest relation that can be generated with scope 2 has 4 tuples (since the max size of univ is 2), so the problem does not occur.
It also does not occur in the latest build because I believe it comes with the Forbid Overflow option set to Yes by default, and with that option the semantics of integers rules out instances where overflows occur, precisely the case when you compute the size of the relation with 9 tuples. More details about this alternative integer semantics can be found in the paper "Preventing arithmetic overflows in Alloy" by Aleksandar Milicevic and Daniel Jackson.
On the main question: what version of Alloy are you using? I'm unable to replicate the behavior you describe (using Alloy 4.2 of 22 Feb 2015 on OS X 10.6.8).
On the auxiliary question: it appears so. (The language reference is not quite as explicit as one might wish, but it begins one part of its discussion of multiplicities with "If the right-hand expression denotes a unary relation ..." and (in what I take to be the context so defined) "the default multiplicity is one"; the conditional would make no sense if the default multiplicity were always one.
On the other hand, the same interpretive logic would lead to the conclusion that the language reference believes that unary multiplicity keywords are only allowed before expressions denoting unary relations (which would appear to make r: set univ -> univ ungrammatical). But Alloy accepts the expression and parses it as set (univ -> univ). (The alternative parse, (set univ) -> univ, would be very hard to assign a meaning to.)

Prolog Design Pattern to extend module predicates

Imagine we have the familytree module below (simple example) :
:- module(familytree, [
father/2,
mother/2,
%[...]
]).
father(X,Y) :- male(X),parent(X,Y).
father(unknown, _) :- male(unknown).
mother(X,Y) :- female(X),parent(X,Y).
mother(unknown, _) :- female(unknown).
sister(X,Y) :- female(X),parent(Z,X),parent(Z,Y), X \= Y.
%[... other relation predicates ... ]
I want to use this module predicates with different "dbs", for examples with :
:- module(familytree_xyz, []).
male(james).
male(fred).
male(mike).
female(betty).
female(sandra).
parent(james, fred).
parent(betty, fred).
Or :
:- module(familytree_simpson, []).
male(homer).
male(bart).
female(marge).
female(lisa).
parent(homer, bart).
%[...]
I need :
to choose db on runtime, not on compilation.
to use one or more dbs in same time.
to extend db, for eg. create a “familytree_simpson_extended” db module with other Simpson family members extending “familytree_simpson” db module (see above example)
to be swi-prolog compliant.
For now, I tried to play with term_expansion/2, discontiguous/1, multifile/1, dynamic/1 and thread_local/1 directives, but :
term_expansion/2 seems only usable on compile time,
discontiguous/1, multifile/1, not adapted,
dynamic dbs in prolog are seen as an “Evil” practice, however lot of packages and libraries use its (pengines, broadcast module,http lib, for examples).
thread_local/1 is not very documented and seems not often used in prolog source code (swi-prolog).
With playing with dynamic predicate, I update previous code as follow :
%familytree.pl
:- module(familytree, [
familytree_cleanup_db/0,
familytree_use_db/1,
%[... previous declarations ...]
]).
dynamic male/1, female/1, parent/2.
familytree_cleanup_db :-
retractall(male/1),
retractall(female/1),
retractall(parent/2).
familytree_use_db(ModuleName) :-
assert(male(X) :- ModuleName:male(X)),
assert(female(X) :- ModuleName:female(X)),
assert(parent(X,Y) :- ModuleName:parent(X,Y)).
%[... previous predicates ...]
And :
%main.pl
% use familytree tool predicates
:- use_module(familytree).
%load all familytree dbs at compile time.
:- use_module(familytree_xyz).
:- use_module(familytree_simpson).
:- use_module(familytree_simpson_extended).
main_xyz:-
familytree_cleanup_db,
familytree_use_db(familytree_xyz),
process.
main_simpson_all :-
familytree_cleanup_db,
familytree_use_db(familytree_simpson),
familytree_use_db(familytree_simpson_extended),
process.
process :-
findall(X, father(X,_), Xs),
write(Xs).
And it's ok to use with different db as follow :
?- main_simpson_all.
[homer,homer,abraham]
true.
?- main_xyz.
[james]
true.
So, sorry for the length of the post. Questions :
What are the criteria, pros/cons to consider with this dynamic predicates solution ? is it a good solution ?
What are the best practice / specific design pattern for prolog to do that in a clean / robust code ?**
What's about using thread_local/1 instead dynamic/1 and encapsulate call to new thread to avoid cleanup db?
Expanding my comment, the Logtalk solution is straightforward. First, define a root object with the family relations predicate:
:- object(familytree).
:- public([
father/2, mother/2,
sister/2, brother/2
]).
:- public([
parent/2,
male/1, female/1
]).
father(Father, Child) :-
::male(Father),
::parent(Father, Child).
mother(Mother, Child) :-
::female(Mother),
::parent(Mother, Child).
sister(Sister, Child) :-
::female(Sister),
::parent(Parent, Sister),
::parent(Parent, Child),
Sister \== Child.
brother(Brother, Child) :-
::male(Brother),
::parent(Parent, Brother),
::parent(Parent, Child),
Brother \== Child.
:- end_object.
Note that the lookup of the definitions of the male/1, female/1, and parent/2 starts in self, i.e. in the object, the database, that will receive the queries about the family relations. An example, derived from your sample code would be:
:- object(simpsons,
extends(familytree)).
male(homer).
male(bart).
female(marge).
female(lisa).
parent(homer, bart).
parent(homer, lisa).
parent(marge, bart).
parent(marge, lisa).
:- end_object.
An example query can be:
?- simpsons::parent(homer, Child).
Child = bart ;
Child = lisa.
You can them as many family databases as you want, load them at the same time, and define specializations of them at will. For example:
:- object(simpsons_extended,
extends(simpsons)).
male(Male) :-
^^male(Male).
male(abe).
male(herb).
female(Male) :-
^^female(Male).
female(gaby).
female(mona).
parent(Parent, Child) :-
^^parent(Parent, Child).
parent(abe, homer).
parent(abe, herb).
parent(gaby, herb).
parent(mona, homer).
:- end_object.
This solution fulfills all your requirements. SWI-Prolog is one of the supported Prolog compilers. You can install Logtalk using on of its installers. Alternatively, for SWI-Prolog, you can simply type:
?- pack_install(logtalk).
Update
In your comment to this solution, you asked about injecting a database into the family tree object logic. That's easy but it also requires a different approach. First define familytree as:
:- object(familytree).
:- public([
father/2, mother/2,
sister/2, brother/2
]).
:- public([
parent/2,
male/1, female/1
]).
:- multifile([
parent/2,
male/1, female/1
]).
father(Father, Child) :-
male(Father),
parent(Father, Child).
mother(Mother, Child) :-
female(Mother),
parent(Mother, Child).
sister(Sister, Child) :-
female(Sister),
parent(Parent, Sister),
parent(Parent, Child),
Sister \== Child.
brother(Brother, Child) :-
male(Brother),
parent(Parent, Brother),
parent(Parent, Child),
Brother \== Child.
:- end_object.
Note that is this alternative, we call male/1, female/1, and parent/2 as local predicates but they are also declared as multifile predicates. Now we need to "inject" a family database in the familytree object:
:- category(simpsons).
:- multifile([
familytree::male/1,
familytree::female/1,
familytree::parent/2
]).
familytree::male(homer).
familytree::male(bart).
familytree::female(marge).
familytree::female(lisa).
familytree::parent(homer, bart).
familytree::parent(homer, lisa).
familytree::parent(homer, maggie).
familytree::parent(marge, bart).
familytree::parent(marge, lisa).
familytree::parent(marge, maggie).
:- end_category.
Usage example (assuming familytree.lgt and simpsons.lgt files):
?- {familytree, simpsons}.
...
yes
A couple of sample queries:
?- familytree::parent(homer, Child).
Child = bart ;
Child = lisa ;
Child = maggie.
?- familytree::male(Male).
Male = homer ;
Male = bart.
?- familytree::father(Father, Child).
Father = homer,
Child = bart ;
Father = homer,
Child = lisa ;
Father = homer,
Child = maggie ;
false.
Since the source database obviously plays an important role in your use case, I suggest to make its dedicated identifier explicit in your definitions, so that it is always clear which family source you are actually referencing:
db_male(xyz, james).
db_male(simpsons, bart).
db_female(xyz, betty).
db_female(simpsons, marge).
db_parent_of(xyz, james, fred).
So, you basically have the public and multifile db_male/2, db_female/2, db_parent_of/3 predicates.
Self-contained modules can extend the existing definitions with their own source knowledge bases, made explicit in the first argument. This is where term_expansion/2 and the like may help you: Since the database name is the same within each single module, you can write expansion code that augments module-specific definitions of male/1, female/1 etc. with the suitable db argument and rewrites this to db_male/2 etc. Notice that this rewriting need only happen at compilation time. At run-time, you can supply any DB you choose as the first argument of these predicates.
It is also obvious how global definitions of female/1, male/1 may look like:
male(M) :- db_male(_, M).
Notice also that I am using names like parent_of/2 to make clear which argument is what.
assertz/1 can be used to dynamically augment each individual database when required, again supplying the name explicitly. However, for clean and robust code, I would do as much as possible at compilation time.
An alternative is the use of Prolog dicts. They have been introduced by SWI-Prolog and since release 1.3.0 they are also available in Jekejeke Prolog. If the receiver is not needed, one can simply use an underscore.
File simpson.pl:
:- module(simpson, [gender/3, parent/3]).
:- reexport(familytree).
_.gender(homer) := male.
_.gender(bart) := male.
_.gender(marge) := female.
_.gender(lisa) := female.
_.parent(homer) := bart.
_.parent(homer) := lisa.
_.parent(homer) := maggie.
_.parent(marge) := bart.
_.parent(marge) := lisa.
_.parent(marge) := maggie.
File xyz.pl:
:- module(xyz, [gender/3, parent/3]).
:- reexport(familytree).
_.gender(james) := male.
_.gender(fred) := male.
_.gender(mike) := male.
_.gender(betty) := female.
_.gender(sandra) := female.
_.parent(james) := fred.
_.parent(betty) := fred.
File familytree.pl:
:- module(familytree, [father/3]).
M.father(X) := Y :-
male = M.gender(X),
Y = M.parent(X).
To make the familytree also visible in simpson and xyz use reexport/1. This allows sending a message to simpson or xyz, but nevertheless a method from familytree will be processed. Here is an example run:
Welcome to SWI-Prolog (threaded, 64 bits, version 7.7.19)
SWI-Prolog comes with ABSOLUTELY NO WARRANTY. This is free software.
?- Y = simpson{}.father(X).
Y = bart,
X = homer ;
Y = lisa,
X = homer ;
Y = maggie,
X = homer ;
false.
?- Y = xyz{}.father(X).
Y = fred,
X = james ;
false.
The exports of gender/3, parent/3, etc.. will go away with the upcoming release 1.3.1 of Jekejeke Prolog when we have made ('.')/3 call-site aware. But the result for Jekejeke Prolog is the same:
Jekejeke Prolog 3, Runtime Library 1.3.0
(c) 1985-2018, XLOG Technologies GmbH, Switzerland
?- Y = simpson{}.father(X).
Y = bart,
X = homer ;
Y = lisa,
X = homer ;
Y = maggie,
X = homer ;
No
?- Y = xyz{}.father(X).
Y = fred,
X = james ;
No

ANTLR4 Semantic Predicates that is Context Dependent Does Not Work

I am parsing a C++ like declaration with this scaled down grammar (many details removed to make it a fully working example). It fails to work mysteriously (at least to me). Is it related to the use of context dependent predicate? If yes, what is the proper way to implement the "counting the number of child nodes logic"?
grammar CPPProcessor;
cppCompilationUnit : decl_specifier_seq? init_declarator* ';' EOF;
init_declarator: declarator initializer?;
declarator: identifier;
initializer: '=0';
decl_specifier_seq
locals [int cnt=0]
#init { $cnt=0; }
: decl_specifier+ ;
decl_specifier : #init { System.out.println($decl_specifier_seq::cnt); }
'const'
| {$decl_specifier_seq::cnt < 1}? type_specifier {$decl_specifier_seq::cnt += 1;} ;
type_specifier: identifier ;
identifier:IDENTIFIER;
CRLF: '\r'? '\n' -> channel(2);
WS: [ \t\f]+ -> channel(1);
IDENTIFIER:[_a-zA-Z] [0-9_a-zA-Z]* ;
I need to implement the standard C++ rule that no more than 1 type_specifier is allowed under an decl_specifier_seq.
Semantic predicate before type_specifier seems to be the solution. And the count is naturally declared as a local variable in decl_specifier_seq since nested decl_specifier_seq are possible.
But it seems that a context dependent semantic predicate like the one I used will produce incorrect parsing i.e. a semantic predicate that references $attributes. First an input file with correct result (to illustrate what a normal parse tree looks like):
int t=0;
and the parse tree:
But, an input without the '=0' to aid the parsing
int t;
0
1
line 1:4 no viable alternative at input 't'
1
the parsing failed with the 'no viable alternative' error (the numbers printed in the console is debug print of the $decl_specifier_cnt::cnt value as a verification of the test condition). i.e. the semantic predicate cannot prevent the t from being parsed as type_specifier and t is no longer considered a init_declarator. What is the problem here? Is it because a context dependent predicate having $decl_specifier_seq::cnt is used?
Does it mean context dependent predicate cannot be used to implement "counting the number of child nodes" logic?
EDIT
I tried new versions whose predicate uses member variable instead of the $decl_specifier_seq::cnt and surprisingly the grammar now works proving that the Context Dependent predicate did cause the previous grammar to fail:
....
#parser::members {
public int cnt=0;
}
decl_specifier
#init {System.out.println("cnt:"+cnt); }
:
'const'
| {cnt<1 }? type_specifier {cnt++;} ;
A normal parse tree is resulted:
This gives rise to the question of how to support nested rule if we must use member variables to replace the local variables to avoid context sensitive predicates?
And a weird result is that if I add a /*$ctx*/ after the predicate, it fails again:
decl_specifier
#init {System.out.println("cnt:"+cnt); }
:
'const'
| {cnt<1 /*$ctx*/ }? type_specifier {cnt++;} ;
line 1:4 no viable alternative at input 't'
The parsing failed with no viable alternative. Why the /*$ctx*/ causes the parsing to fail like when $decl_specifier_seq::cnt is used although the actual logic uses a member variable only?
And, without the /*$ctx*/, another issue related to the predicate called before #init block appears(described here)
ANTLR 4 evaluates semantic predicates in two cases.
The generated code evaluates a semantic predicate during parsing, and throws an exception of the evaluation returns false. All predicates traversed during parsing are evaluated in this way, including context-dependent predicates and predicates which do not appear at the left side of a decision.
The prediction method evaluates predicates in order to make correct decisions during parsing. In this case, predicates which appear anywhere other than the left edge of the decision being evaluated are assumed to return true (i.e. they are ignored). In addition, context-dependent predicates are only evaluated if the context data is available. The prediction algorithm will not create context structures that were not already provided by the parsing code. If a context-dependent predicate is encountered during prediction and no context is available, the predicate is assumed to return true (i.e. it is ignored for that decision).
The code generator does not evaluate the semantics of the target language, so it has no way to know that $ctx is semantically irrelevant when it appears in /*$ctx*/. Both cases result in the predicate being treated as context-dependent.

ocaml style: parameterize programs

I have a OCaml program which modules have lots of functions that depend on a parameter, i.e. "dimension". This parameter is determined once at the beginning of a run of the code and stays constant until termination.
My question is: how can I write the code shorter, so that my functions do not all require a "dimension" parameter. Those modules call functions of each other, so there is no strict hierarchy (or I can't see this) between the modules.
how is the ocaml style to adress this problem? Do I have to use functors or are there other means?
You probably cannot evaluate the parameter without breaking dependencies between modules, otherwise you would just define it in one of the modules where it is accessible from other modules. A solution that comes to my mind is a bit "daring". Define the parameter as a lazy value, and suspend in it a dereference of a "global cell":
let hidden_box = ref None
let initialize_param p =
match !hidden_box with None -> hidden_box := Some p | _ -> assert false
let param =
lazy (match !hidden_box with None -> assert false | Some p -> p)
The downside is that Lazy.force param is a bit verbose.
ETA: Note that "there is no strict hierarchy between the modules" is either:
false, or
you have a recursive module definition, or
you are tying the recursive knot somewhere.
In case (2) you can just put everything into a functor. In case (3) you are passing parameters already.

Resources