This is probably related to a comp.lang.prolog-discussion.
I'm getting several warnings like this using Eclipse with the SICStus SPIDER:
The plain meta argument (Y) is passed as a closure argument
(with 0 suppressed arguments) to the callee.
Here is a code sample:
% Prologs set_of is baroque %% RS-140614 130sec runtime vs. 28sec runtime
:- meta_predicate set_of(+,:,+) .
set_of(X,Y,Z):- %%
setof(X,Y^Y,Z),!; %% Trick to avoid alternatives
Z=[]. %% What is wrong with empty sets ?
How can I get rid of the SPIDER warnings?
I'm not really interested in simply suppressing the warnings.
I'm using the latest version of SPIDER IDE (0.0.51), and SICStus Prolog 4.2.3.
There are several issues in the code you show.
Bad meta argument
First, the built-in predicate setof/3 has the following properties:
?- predicate_property(setof(A,B,C),P).
P = (meta_predicate setof(?,0,?))
; P = built_in
; P = jittable.
which closely corresponds to the ISO declarations in ISO/IEC 13211-1:
8.10.3.2 Template and modes
setof(?term, +callable_term, ?list)
The second argument is a goal to be executed by call/1. No extra arguments are needed. This is what the 0 tells us.
On the other hand, your code you show contains a different meta predicate declaration:
:- meta_predicate(set_of(+,:,+)) .
Here, the second argument is a :. In SICStus, YAP, and SWI, the : means: This argument will be automatically qualified with the current module, such that the module information can be passed further on. Think of asserta(:). Here, the argument is not a goal but a clause.
So what you need to fix this, is to replace : by 0. And you might indicate this fact in the variable name used. That is, Goal_0 for call(Goal_0), Goal_1 for call(Goal_1, Arg1), Goal_2for call(Goal_2, Arg1, Arg2) etc.
Bad modes
The + in the first and third argument is inappropriate. The 3rd argument is commonly an uninstantiated variable to be unified with the resulting list.
Prolog's setof/3 baroque?
% Prologs set_of is baroque
The comment probably wants to say that setof/3 contains superfluous ornaments. In fact, setof/3 is much more versatile than mentioned set_of/3. Take this recent question or that. Often you first think about a very specific situation. Say, you want the list of actors of a particular movie. Then, later on you want to ask what movies there are. It is this generalization which works very smoothly with setof/3 whereas it is extremely complex if you do not have it.
Another very useful way to use setof/3 is when you want to eliminate redundant answers:
?- (X=2;X=1;X=2).
X = 2
; X = 1
; X = 2.
?- setof(t, (X=2;X=1;X=2), _).
X = 1
; X = 2.
Try to emulate that efficiently.
Runtime overheads
They are next to negligible. If you really believe that there are overheads, simply use setof/3 with a single goal. In this manner preprocessing is next to naught.
Related
Been stuck for a while, hoping someone with experience could help me a bit...
Right now I'm reading Ini like this three times but wish to do it dynamically to improve my codes in the long run.
IniRead, Alert_price_low, %TrackerFile%, Item, Alert_price_low
IniRead, Alert_price_high, %TrackerFile%, Item, Alert_price_high
IniRead, Alert_checkbox, %TrackerFile%, Item, Alert_checkbox
I made this function below trying to read it dynamically, but doesn't return anything...
FindIniSettings(TrackerFile, Alert_checkbox)
FindIniSettings(TrackerFile, x){
x := IniRead, %x%, TrackerFile, Item, %x%
return x
}
How my Ini file content looks like:
[Item]
Alert_price_low=777
Alert_price_high=999
Alert_checkbox=1
Thanks!
The problem here is pretty much just with the usage of the new expression syntax.
Seems you've been using only the deprecated legacy syntax, and functions are not apart of that.
So first problem is here
FindIniSettings(TrackerFile, Alert_checkbox)
Here you're not in legacy syntax, so to specify strings you quote them.
FindIniSettings(TrackerFile, "Alert_checkbox")
(And I'm assuming TrackerFile here is a variable that contains some iniFileNameOrPath.ini string)
Also, you're not storing the return value of this function anywhere.
Second problem is here
x := IniRead, %x%, TrackerFile, Item, %x%
Firstly, commands are legacy, they don't return values like that.
You can't use an := operator to get the return value.
They return values only by writing the output to the requested variable, which will be specified in the first parameter of the command.
You specified the output variable to be named whatever x contains. This is no good since you can't possibly know what the output variable is going to be during runtime (without some unnecessary extra tricks).
Also, be quite confusing to name the output to be the same as input key. Though, that would work.
So two problems there, := and the first %x%, and there's still some more to go which is right here:
, TrackerFile,
Commands are legacy, as mentioned above, they exclusively use the legacy syntax in every parameter (unless otherwise specified in the documentation).
So, you're passing in the literal text "TrackerFile", not whatever string should be stored inside the variable named TrackerFile.
In legacy syntax, you refer to the contents of a variable by wrapping it around in %%, as you've been doing before. Maybe you just forgot here.
But really, I'd recommend you try to get used to ditching the legacy syntax. So what you could/should do, is starting off the parameter with a single % followed up by a space. This makes ahk interpret an expression on that parameter, as opposed to using the legacy syntax. In the modern expression syntax you refer to a variable just by typing its name. No stupid %%s needed.
So here's the fixed script you should end up with. I made this example fully legacy syntax free as a demonstration:
TrackerFile := "test.ini"
returnValueOfThisFunction := FindIniSettings(TrackerFile, "Alert_price_low")
MsgBox, % "Yay, the function returned a value for us:`n" returnValueOfThisFunction
return
FindIniSettings(TrackerFile, key)
{
;even specified the string "Item" explicitly as a string
;this is not needed, but it just looks right to me
;I wouldn't want to specify a legacy parameter there
;in the middle of all this
IniRead, output, % TrackerFile, % "Item", % key
MsgBox, % "Now the variable named ""output"" contains the result of the above command (" output ").`nWe can now return it to the caller."
return output
}
So yeah, pretty much just problems understanding legacy syntax vs expression syntax.
You can give a read to a previous answer of mine here about usage of %% vs % .
And here's a good page on the AHK documentation about the scripting language and legacy vs. modern expression.
I am defining a variable in the beginning of my source code in MATLAB. Now I would like to know at which lines this variable effects something. In other words, I would like to see all lines in which that variable is read out. This wish does not only include all accesses in the current function, but also possible accesses in sub-functions that use this variable as an input argument. In this way, I can see in a quick way where my change of this variable takes any influence.
Is there any possibility to do so in MATLAB? A graphical marking of the corresponding lines would be nice but a command line output might be even more practical.
You may always use "Find Files" to search for a certain keyword or expression. In my R2012a/Windows version is in Edit > Find Files..., with the keyboard shortcut [CTRL] + [SHIFT] + [F].
The result will be a list of lines where the searched string is found, in all the files found in the specified folder. Please check out the options in the search dialog for more details and flexibility.
Later edit: thanks to #zinjaai, I noticed that #tc88 required that this tool should track the effect of the name of the variable inside the functions/subfunctions. I think this is:
very difficult to achieve. The problem of running trough all the possible values and branching on every possible conditional expression is... well is hard. I think is halting-problem-hard.
in 90% of the case the assumption that the output of a function is influenced by the input is true. But the input and the output are part of the same statement (assigning the result of a function) so looking for where the variable is used as argument should suffice to identify what output variables are affected..
There are perverse cases where functions will alter arguments that are handle-type (because the argument is not copied, but referenced). This side-effect will break the assumption 2, and is one of the main reasons why 1. Outlining the cases when these side effects take place is again, hard, and is better to assume that all of them are modified.
Some other cases are inherently undecidable, because they don't depend on the computer states, but on the state of the "outside world". Example: suppose one calls uigetfile. The function returns a char type when the user selects a file, and a double type for the case when the user chooses not to select a file. Obviously the two cases will be treated differently. How could you know which variables are created/modified before the user deciding?
In conclusion: I think that human intuition, plus the MATLAB Debugger (for run time), and the Find Files (for quick search where a variable is used) and depfun (for quick identification of function dependence) is way cheaper. But I would like to be wrong. :-)
I've written a piece of code which calls numerous functions, which in turn also call several sub-functions.
I am calling the main file from the command line and supplementing the call with certain arguments to initiate certain modes I have accounted for.
E.g. octave classify_file.m --debug <file> would run in my custom debug mode, which sets a constant debug to 1 and subsequently outputs all plots and relevant variables. Omitting the argument outputs only 1 variable.
Similarily I have a template and a histogram mode, which essentially all do the same thing, except output some more variables, matrices and plots depending on the mode.
As it is now, I have to include the debug, template and histogram constants as arguments to each and every function if I want them to be influenced by the respective modes.
This is cumbersome and confusing, there has to be a better way. I've never worked with global variables, but would this be a good place to use one? What's an elegant solution for this problem?
This is a situation in which global variables will come in handy, although as you may be aware they are sometimes frowned upon, and can also have certain performance implications in matlab. Personally I don't think passing the mode all the way down the call stack is too bad - although are you treating all 3 as separate arguments? The least you could do is put them in a struct in your highest level function so that you only have 1 argument:
mode.debug = [whatever]
mode.histogram = [whatever]
mode.template = [whatever]
myFunction(mode);
OR, if you can only have one mode at a time what about some integer constants?
mode = MODE_DEBUG
or
mode = MODE_NONE
I would define the constants by creating short functions, this is how the pi constant works for example.
Finally, there is an alternative to global variables which I rather like, which is functions that use persistent variables. For example:
function m = debugMode(newValue)
persistant isModeOn;
if nargin > 0
isModeOn = newValue
end
m = isModeOn;
end
This way you can call debugMode(1) to set it on, and you can call m = debugMode anywhere to get the value.
This is a thought example of what I am thinking of:
test = 'x > 0';
while str2func(test)
Do your thing
x=x-1;
end
Is it possible to store whole logical operations in a variable like this?
Of course the str2func will break here. If it is possible this function will likely be something else. And I have only added apostrophes to the test variable content, because I cannot think of what else would be the storing method.
I can see it usefull when sending arguments to functions and alike. But mostly I'm just wondering, because I have never seen it done in any programming language before.
You can store the textual representation of a function in a variable and evaluate it, for example
test = 'x > 0';
eval(test)
should result in 1 or 0 depending on x's value.
But you shouldn't use eval for reasons too-often covered here on SO for me to bother repeating. You should instead become familiar with functions and function handles. For example
test = #(x)x>0
makes test a handle to a function which tests whether its argument is greater than 0 or not.
Many languages which are interpreted at run-time, as opposed to compiled languages, have similar capabilities.
This is C macro weirdness question.
Is it possible to write a macro that takes string constant X ("...") as argument and evaluates to sting Y of same length such that each character of Y is [constant] arithmetic expression of corresponding character of X.
This is not possible, right ?
No, the C preprocessor considers string literals to be a single token and therefore it cannot perform any such manipulation.
What you are asking for should be done in actual C code. If you are worried about runtime performance and wish to delegate this fixed task at compile time, modern optimising compilers should successfully deal with code like this - they can unroll any loops and pre-compute any fixed expressions, while taking code size and CPU cache use patterns into account, which the preprocessor has no idea about.
On the other hand, you may want your code to include such a modified string literal, but do not want or need the original - e.g. you want to have obfuscated text that your program will decode and you do not want to have the original strings in your executable. In that case, you can use some build-system scripting to do that by, for example, using another C program to produce the modified strings and defining them as macros in the C compiler command line for your actual program.
As already said by others, the preprocessor sees entire strings as tokens. There is only one exception the _Pragma operator, that takes a string as argument and tokenizes its contents to pass it to a #pragma directive.
So unless your targeting a _Pragma the only way to do things in the preprocessing phases is to have them written as token sequences, manipulate them and to stringify them at the end.