I'm wondering if it is possible to define a dynamic predicate with the same name and arity as a builtin predicate inside a module. I was hoping it would be enough to hide the builtin predicates in my module using delete_import_module/2. Alas, that doesn't seem to work. For instance, I cannot create a clause for halt/1 inside module foo:
?- delete_import_module(foo, user).
true.
?- asserta(foo:halt(x)).
ERROR: No permission to modify static procedure `halt/1'
ERROR: In:
ERROR: [10] assert(foo:halt(x))
ERROR: [9] toplevel_call(user:user: ...) at /usr/lib64/swipl-8.4.1/boot/toplevel.pl:1117
It still seems to think I'm talking about system:halt/1 even though that's not even visible in foo. Why is that?
I have noticed that the problem goes away if I try to call the predicate before adding the clause:
?- delete_import_module(foo, user).
true.
?- foo:halt(_).
Correct to: "system:halt(_)"? no
ERROR: Unknown procedure: foo:halt/1
ERROR: However, there are definitions for:
ERROR: halt/0
ERROR:
ERROR: In:
ERROR: [10] foo:halt(_20078)
ERROR: [9] toplevel_call(user:foo: ...) at /usr/lib64/swipl-8.4.1/boot/toplevel.pl:1117
Exception: (10) foo:halt(_8960) ? no debug
?- assert(foo:halt(_)).
true.
?- #(listing, foo).
:- dynamic halt/1.
halt(_).
true.
I've also tried poking the predicate in other ways (using current_predicate/1 and clause/2), but that doesn't have the same effect.
So while this does solve the problem, I still wonder what is going on here. Is this a bug? I'm using SWI Prolog 8.4.1 on Fedora Linux.
Related
I'm writing the following nested function where dfsVisit uses the arrays "numCaminos" and "colores" declared in the outer function
However the kotlin compiler is giving me a "variable expected" error on the assignments in lines 31 and 34 specifically, this error doesn't show up on any of the other Array assignments within the nested dfsVisit function. I tried de-nesting the functions and passing the arrays as arguments of dfsVisit but the problem persisted on those 2 assignments specifically. Why could this be happening?
I'm running the Kotlin compiler in Manjaro Linux through the repository package
Note: Sorry for using a picture instead of a code block, the post editor was giving me some formatting issues.
Just remove !! from the left side of the assignment. It doesn't really make sense there.
Crew,
I'm one of those types that insists on defining my variables with SETF. I've upgraded to a new machine (and a new version of SBCL) and it's not letting me get away with doing that (naturally, I get the appropriate "==> undefined variable..." error)
My problem here is, I've already written 20,000 lines of code (incorrectly) defining my variables with SETF and i don't like the prospect of re-writing all of my code to get the interpreter to digest it all.
Is there a way to shut down that error such that interpretation can continue?
Any help is appreciated.
Sincerely,
-Todd
One option is to set up your package environment so that a bare symbol setf refers to my-gross-hack::setf instead of cl:setf. For example, you could set things up like:
(defpackage #:my-gross-hack
(:use #:cl)
(:shadow #:setf))
;;; define your own setf here
(defpackage #:my-project
(use #:cl)
(shadowing-import-from #:my-gross-hack #:setf))
;;; proceed to use setf willy-nilly
You can handle warnings, so that compilation terminates; while doing so, you can collect enough information to fix your code.
Tested with SBCL 1.3.13.
Handle warnings
I have warnings when using setf with undefined variables. The following invokes the debugger, from which I can invoke muffle-warning:
(handler-bind ((warning #'invoke-debugger))
(compile nil '(lambda () (setf *shame* :on-you))))
The warning is of type SIMPLE-WARNING, which has the following accessors: SIMPLE-CONDITION-FORMAT-CONTROL and SIMPLE-CONDITION-FORMAT-ARGUMENTS.
(defparameter *setf-declarations* nil)
(defun handle-undefined-variables (condition)
(when (and (typep condition 'simple-warning)
(string= (simple-condition-format-control condition)
"undefined ~(~A~): ~S"))
(let* ((arguments (simple-condition-format-arguments condition))
(variable (and (eq (first arguments) :variable)
(second arguments))))
(when variable
(proclaim `(special ,variable))
(push variable *setf-declarations*)
(invoke-restart 'muffle-warning)))))
Use that as a handler:
(handler-bind ((warning #'handle-undefined-variables))
;; compilation, quickload, asdf ...
)
The above handler is not robust: the error message might change in future versions, the code assumes the arguments follow a given pattern, ... But this needs only work once, since from now on you are going to declare all your variables.
Fix your code
Now that your code compiles, get rid of the ugly. Or at least, add proper declarations.
(with-open-file (out #P"declarations.lisp" :direction :output)
(let ((*package* (find-package :cl-user)))
(format out
"(in-package :cl-user)~%~%~{(defvar ~(~S~))~%~}"
*setf-declarations*)))
This iterates over all the symbols you collected and write declarations inside a single file.
In my example, it would contain:
(in-package :cl-user)
(defvar *shame*)
Try to cleanly recompile without handling errors, by loading this file early in your compilation process, but after packages are defined. Eventually, you may want to find the time to move those declarations in place of the setf expressions that triggered a warning.
Using SWI-Prolog (Multi-threaded, 64 bits, Version 7.3.5),
we proceed step by step:
Define dcg nonterminal a//1 in module dcgAux (pronounced: "di-SEE-goh"):
:- module(dcgAux,[a//1]).
a(0) --> [].
a(s(N)) --> [a], a(N).
Run the following queries—using phrase/2 and apply:foldl/4:
?- use_module([library(apply),dcgAux]).
true.
?- phrase( foldl( a,[s(0),s(s(0))]),[a,a,a]).
true.
?- phrase( foldl(dcgAux:a,[s(0),s(s(0))]),[a,a,a]).
true.
?- phrase(apply:foldl(dcgAux:a,[s(0),s(s(0))]),[a,a,a]).
true.
?- phrase(apply:foldl( a,[s(0),s(s(0))]),[a,a,a]).
ERROR: apply:foldl_/4: Undefined procedure: apply:a/3
нет! Quite a surprise—and not a good one. Have we been missing some unknown unknowns?
To get rid of above irritating behavior, we must first find out the reason(s) causing it:
?- import_module(apply,M), M=user.
false.
?- phrase(apply:foldl(a,[s(0),s(s(0))]),[a,a,a]).
ERROR: apply:foldl_/4: Undefined procedure: apply:a/3
?- add_import_module(apply,user,end).
true.
?- import_module(apply,M), M=user. % sic!
M = user. % `?- import_module(apply,user).` fails!
?- phrase(apply:foldl(a,[s(0),s(s(0))]),[a,a,a]).
true.
What's going on? The way I see it is this:
Module expansion of the goal passed to foldl/4 is limited.
Quoting from the SWI-Prolog manual page on import_module/2:
All normal modules only import from user, which imports from system.
SWI's library(apply) only "inherits" from system, but not user.
If we clone module apply to applY (and propagate the new module name), we observe:
?- use_module(applY).
true.
?- phrase(applY:foldl(a,[s(0),s(s(0))]),[a,a,a]). % was: ERROR
true. % now: OK!
Please share your ideas on how I could/should proceed!
(I have not yet run a similar experiment with other Prolog processors.)
This is an inherent feature/bug of predicate based module systems in the Quintus tradition. That is, this module system was first developed for Quintus Prolog. It was adopted subsequently by SICStus (after 0.71), then (more or less) by 13211-2, then by YAP, and (with some modifications) by SWI.
The problem here is what exactly an explicit qualification means. As long as the goal is no meta-predicate, things are trivially resolvable: Take the module of the innermost qualification. However, once you have meta-predicates, the meta-arguments need to be informed of that module ; or not. If the meta-arguments are informed, we say that the colon sets the calling context, if not, then some other means is needed for that purpose.
In Quintus tradition, the meta-arguments are taken into account. With the result you see. As a consequence you cannot compare two implementations of the same meta-predicate in the same module directly. There are other approaches most notably IF and ECLiPSe that do not change the calling context via the colon. This has advantages and disadvantages. The best is to compare them case by case.
Here is a recent case. Take lambdas and how they are put into a module
in SICStus, in SWI, and in ECLiPSe.
As for the Quintus/SICStus/YAP/SWI module system, I'd rather use it in the most conservative manner possible. That is:
no explicit qualification, consider the infix : as something internal
clean, checkable meta-declarations - insert on purpose an undefined predicate just to see whether or not cross-referencing is able to detect the problem (in SWI that's check or make).
use the common subset, avoid the many bells and whistles - there are many well meant extensions...
do more versatile things the pedestrian way: reexport by adding an appropriate module and add a dummy definition. Similarly, instead of renaming, import things from an interface module.
be always aware that module systems have inherently some limits. No matter how you twist or turn it. There is no completely seamless module system, for the very purpose of modules is to separate code and concerns.
1: To be precise, SICStus' adaptation of Quintus modules did only include : for module sensitive arguments in meta_predicate declarations. The integers 0..9, which are so important for higher-order programming based on call/N were only introduced about 20 years later in
4.2.0 released 2011-03-08.
I am trying to call one of the 2 modules (fifo_test_1 or fifo_test_2) depending on the value of bit data[0] in the following Verilog code.
module VC_selector(data);
input [10:0] data;
always # (data[0])
begin
if(~data[0])
begin
fifo_test_1 t1(.buf_in(data));
end
else if (data[0])
begin
fifo_test_2 t2 (.buf_in(data));
end
end
endmodule
fifo_test_1 and fifo_test_2 modules are working fine. But the above code gives these errors:
** Error: C:/Users/Swayam/Documents/VC_selector.v(8): Undefined variable: fifo_test_1.
** Error: C:/Users/Swayam/Documents/VC_selector.v(8): near "t1": syntax error, unexpected IDENTIFIER
** Error: C:/Users/Swayam/Documents/VC_selector.v(12): Undefined variable: fifo_test_2.
** Error: C:/Users/Swayam/Documents/VC_selector.v(12): near "t2": syntax error, unexpected IDENTIFIER
Please help me debug the code.
You cannot change the modules included while the hardware is running. The modules must be a constant during execution. For that reason, you can't include a module definition inside an always statement.
One thing you could do is move the two modules outside the always block and use some logic to switch between their outputs. Because neither of the fifo modules have outputs that would be rather difficult to do in this particular case, but it is possible in the general case.
assign my_switched_output = data[0] ? module_1_output : module_2_output;
The ternary operator (used here) allows you to do this switching that it appears you are attempting to do.
Another thing to make sure you have done is to include both the module file you are trying to simulate/synthesize AND all of the submodule verilog files you need in the command. How to include all of these files based on the simulator.
In other words, should it be 0 or : or something else? The Prolog systems SICStus, YAP, and SWI all indicate this as :. Is this appropriate? Shouldn't it be rather a 0 which means a term that can be called by call/1?
To check your system type:
| ?- predicate_property(predicate_property(_,_),P).
P = (meta_predicate predicate_property(:,?)) ? ;
P = built_in ? ;
P = jitted ? ;
no
I should add that meta-arguments — at least as in the form used here — cannot guarantee the same algebraic properties we expect from pure relations:
?- S=user:false, predicate_property(S,built_in).
S = user:false.
?- predicate_property(S,built_in), S=user:false.
false.
Here is the relevant part from ISO/IEC 13211-2:
7.2.2 predicate_property/2
7.2.2.1 Description
predicate_property(Prototype, Property) is true in the calling context of a module M iff the procedure
associated with the argument Prototype has predicate property
Property.
...
7.2.2.2 Template and modes
predicate_property(+prototype, ?predicate_property)
7.2.2.3 Errors
a) Prototype is a variable — instantiation_error.
...
c) Prototype is neither a variable nor a callable term —
type_error(callable, Prototype).
...
7.2.2.4 Examples
Goals attempted in the context of the module
bar.
predicate_property(q(X), exported).
succeeds, X is not instantiated.
...
Thats an interesting question. First I think there are two
kinds of predicate_property/2 predicates. The first kind
takes a callable and is intended to work smoothly with
for example vanilla interpreters and built-ins such as
write/1, nl/0, etc.., i.e.:
solve((A,B)) :- !, solve(A), solve(B).
solve(A) :- predicate_property(A, built_in), !, A.
solve(A) :- clause(A,B), solve(B).
For the first kind, I guess the 0 meta argument specifier
would work fine. The second kind of predicate_property/2
predicates works with predicate indicators. Callable
and predicate indicators are both notions already defined
in the ISO core standard.
A predicate indicator has the form F/N, where F is an atom
and N is an integer. Matters get a little bit more complicated
if modules are present, especially because of the operator
precedence of (:)/2 versus (/)/2. If predicate property works
with predicate indicators, we can still code the vanilla
interpreter:
solve((A,B)) :- !, solve(A), solve(B).
solve(A) :- functor(A,F,N), predicate_property(F/N, built_in), !, A.
solve(A) :- clause(A,B), solve(B).
Here we loose the connection of a possible meta argument
0, for example of solve/1, with predicate property. Because
functor/3 has usually no meta predicate declaration. Also
to transfer module information via functor/3 to
predicate_property/2 is impossible, since functor/3 is agnostic to
modules, it usually has no realization that can deal with
arguments that contain module qualification.
There are now two issues:
1) Can we give typing and/or should we give typing to predicates
such as functor/3.
2) Can we extend functor/3 so that it can convey module
qualification.
Here are my thoughts:
1) Would need a more elaborate type system. One that would
allow overloading of predicates with multiple types. For
example functor/3 could have two types:
:- meta_predicate functor(?,?,?).
:- meta_predicate functor(0,?,?).
The real power of overloading multiple types would only
shine in predicates such as (=)/2. Here we would have:
:- meta_predicate =(?,?).
:- meta_predicate =(0,0).
Thus allowing for more type inference, if one side of
(=)/2 is a goal we could deduced that the other side
is also a goal.
But matter are not so simple, it would possibly make
sense to have also a form of type cast, or some other
mechanism to restrict the overloading. Something which
is not covered by introducing just a meta predicate
directive. This would require further constructs inside
the terms and goals.
Learning form lambda Prolog or some dependent type
system, could be advantageous. For example (=)/2 can
be viewed as parametrized by a type A, i.e.:
:- meta_predicate =(A,A).
2) For Jekejeke Prolog I have provided an alternative
functor/3 realization. The predicate is sys_modfunc_site/2.
And it works bidirectionally like functor/3, but returns
and accepts the predicate indicator as one whole thing.
Here are some example runs:
?- sys_modfunc_site(a:b(x,y), X).
X = a:b/2
?- sys_modfunc_site(X, a:b/2).
X = a:b(_A,_B)
The result of the predicate could be called a generalized
predicate indicator. It is what SWI-Prolog already understands
for example in listing/1. So it could have the same meta argument
specification as listing/1 has. Which is current : in SWI-Prolog.
So we would have, and subsequently predicate_property/2 would
take the : in its first argument:
:- meta_predicate sys_modfunc_site(?,?).
:- meta_predicate sys_modfunc_site(0,:).
The vanilla interpreter, that can also deal with modules, then
reads as follows. Unfortunately a further predicate is needed,
sys_indicator_colon/2, which compresses a qualified predicate
indicator into an ordinary predicate indicator, since our
predicate_property/2 does not understand generalized predicate
indicators for efficiency reasons:
solve((A,B)) :- !, solve(A), solve(B).
solve(A) :-
sys_modfunc_site(A,I),
sys_indicator_colon(J,I),
predicate_property(J, built_in), !, A.
solve(A) :- clause(A,B), solve(B).
The above implements a local semantic of the colon (:)/2,
compared to the rather far reaching semantic of the colon
(:)/2 as described in the ISO module standard. The far
reaching semantic imputes a module name on all the literals
of a query. The local semantic only expects a qualified
literal and just applies the module name to that literal.
Jekejeke only implements local semantic with the further
provision that call-site is not changed. So under the hood
sys_modfunc_site/2 and sys_indicator_colon/2 have also to
transfer the call-site so that predicate_property/2 makes
the right decision for unqualified predicates, i.e. resolving
the predicate name by respecting imports etc..
Finally a little epilog:
The call-site transfer of Jekejeke Prolog is a pure runtime
thing, and doesn't need some compile time manipulation, especially
no ad hoc adding of module qualifiers at compile time. As a result
certain algebraic properties are preserved. For example assume
we have the following clause:
?- [user].
foo:bar.
^D
Then the following things work fine, since not only sys_modfunc_site/2
is bidirectional, but also sys_indicator_colon/2:
?- S = foo:bar/0, sys_indicator_colon(R,S), predicate_property(R,static).
S = foo:bar/0,
R = 'foo%bar'/0
?- predicate_property(R,static), sys_indicator_colon(R,S), S = foo:bar/0.
R = 'foo%bar'/0,
S = foo:bar/0
And of course predicate_property/2 works with different input and
output modes. But I guess the SWI-Prolog phaenomenom has first an
issue that a bare bone variable is prefixed with the current module. And
since false is not in user, but in system, it will not show false.
In output mode it will not show predicates which are equal by resolution.
Check out in SWI-Prolog:
?- predicate_property(X, built_in), write(X), nl, fail; true.
portray(_G2778)
ignore(_G2778)
...
?- predicate_property(user:X, built_in), write(X), nl, fail; true.
prolog_load_file(_G71,_G72)
portray(_G71)
...
?- predicate_property(system:X, built_in), write(X), nl, fail; true.
...
false
...
But even if the SWI-Prolog predicate_property/2 predicate would
allow bar bone variables, i.e. output goals, we would see less
commutativity in the far reaching semantic than in the local
semantic. In the far reaching semantic M:G means interpreting G
inside the module M, i.e. respecting the imports of the module M,
which might transpose the functor considerable.
The far reaching semantic is the cause that user:false means
system:false. On the other hand, in the local semantics, where M:G
means M:G and nothing else, we have the algebraic property more often.
In the local semantics user:false would never mean system:false.
Bye