Asserting predicates using Tau Prolog for Javascript - javascript

There, I've been trying this issue for over 2 days now and have got nothing to show for it. Therefore, would appreciate some help on this issue.
Issue: Attempting to assert a new predicate using Tau Prolog for Javascript returns a false result. The exact same query results in True when using SWI-Prolog.
The program is taken from a textarea in a HTML page. Everything is local on a single computer only.
**Prolog rules**
<textarea class="example-textinput example-program" id="program">
breads([parmesan, honeywheat]).
</textarea>
**Javascript in the same HTML page**
<script>
var session = pl.create();
var program = document.getElementById("program").value;
session.consult(program);
session.query(`asserta(chosen_meats(variable_to_be_asserted)).`);
session.answers(show())
function show() {
// Return callback function
return function (answer) {
// Valid answer
console.log(answer);
if (pl.type.is_substitution(answer)) {
// Get the value of the food
var output = answer.lookup("X");
console.log(output);
}
};
}
</script>
What I've attempted:
Declaring dynamic predicates in Prolog.
E.g
<textarea class="example-textinput example-program" id="program">
breads([parmesan, honeywheat]).
:- dynamic chosen_meats/1.
</textarea>
Changing to asserta, assertz and assert, when calling the query.
Result: In the callback function show(), false is always getting printed out whenever asserting is attempted.
TermĀ {ref: 6065, id: "throw", args: Array(1), indicator: "throw/1"}
is printed out whenever a query of chosen_meats(X). is done.
However, normal predicate calling such as
session.query("breads(X).");
gives the correct output at
"[parmesan,honeywheat]", when tostring method is used.
Edit: Online Tau Prolog gives the same issue
http://tau-prolog.org/
Error has been expanded as :
error parsing program: error(syntax_error('. or operator expected'), [line(1), column(11), found(client)])
for
:-dynamic client/1.
and
assertz(client(x)).

The syntax error is the clue to the problem, you're missing some parenthesis. Only some Prolog dialects do not require them, so it's best practice to always include them for portability:
:- dynamic(chosen_meats/2).
?- asserta(chosen_meats(chicken, roast)).
true.
I put the solution in the sandbox, query test.: http://tau-prolog.org/sandbox/ZFgsdJkP

Related

How to use a user's submitted code, and get its errors to have relevant info?

So I'm creating a mod for the singleplayer browser game Cookie Clicker. In my mod I allow the user to insert in their own code to do their own special things to interact with my mod's main function.
However, when the user codes on my custom editor, I want to "test" their code before they save to make sure no errors happen, and if they do, display a error message with what they did and where they did it. Getting the error is easy with a try/catch. But I noticed the error message is:
SynaxError: missing ) after argument list
at new Function (<anonymous>)
at HTMLAnchorElement.save.onclick (chrome-extension://dhdgffkkebhmkfjojejmpbldmpobfkfo/userscript.html?name=Building%2520Sorter.user.js&id=18320655-b018-42e2-8fa5-7fb0cc8d2d70:578:24)
Which isn't helpful for me at all. The most I could salvage from this is the first line. However, that doesn't tell the user at all where the error is located in their code.
the 578:24 that points to the supposed error is:
try{
//code.value is a STRING of the user's code
let func = new Function(code.value);//<-- error points here in my source code.
func.call(null, [[0, 1, 2], Game]);
save.classList.remove('ModBuildingSorter_unsaved');
}
catch(e){
console.dir(e);
}
What I would like to happen is when the user sumbits:
return function(array){
return array.sort(function(building1,building2){
return building1.price - building2.price;
};// missing array.sort closing parenthesis
}
get's ran, I can get a syntax error telling me it's on line 4
Is there a way I can do this? Make the user's code act kinda like it's own file and try running it so I can find out which row & column the error is located?
You could, in theory, run the function from an eval()
i.e.:
try {
let a = "function test(o){console.lo(o)}test('hello');" // Minified function
eval(a)
} catch (e) {
console.log(e)
}
Here is the unminified function for example purposes:
function test(o)
{
console.lo(o) // <-- Error
}
test('hello');
and this returns the error correctly, which is
TypeError: console.lo is not a function
at test (eval at <anonymous> (D:\StackOverflowSandbox\index.js:3:5), <anonymous>:1:26)
Hope I've helped.

Return text from URL in GTM Custom JS variable

I need to capture text from the file saved under URL (ex. https://fiddle.jshell.net/robots.txt) And return it under the function.
What is on my mind:
function(){
var url = 'https://fiddle.jshell.net/robots.txt'
var storedText;
fetch(url)
.then(function(response) {
response.text().then(function(text) {
storedText = text;
done();
});
});
function done() {
return storedText;
}
});
Unfortunately this function is not working. I received an error: Error at line 2, character 2: Parse error. primary expression expected Type: JavaScript compiler error
This should be used as a Custom JavasSript Variable in Google Tag Manager
Also this How do I return the response from an asynchronous call? is not explaining my issue and all solutions were checked by me, nothing worked due Parse error or console error.
I have to use GTM custom JavaScrip Variable, I can use anything else.
Simpler JS than better.
Function done() returns storedText value to a point of call, i. e. it works but returns nothing.
I would not recommend using an external call within a custom Custom JavasSript Variable in GTM:
You can not really control how often a Custom JavasSript Variable is executed in GTM. An it is executed a lot.
Just do the test and run a console log from a custom javascript variable.

chrome.tabs.executeScript(): How to get result of content script?

According to the documentation for chrome.tabs.executeScript (MDN), the callback function accepts an "array of any result" result set from the execution of the script(s). How exactly do you use this to get results? All of my attempts end up with undefined being passed to the callback.
I have tried returning a value at the end of my content script, which threw a Uncaught SyntaxError: Illegal return statement. I tried using the optional code object argument {code: "return "Hello";} with no success.
I feel like I am not understanding what is meant by "The result of the script in every injected frame", in the documentation.
chrome.tabs.executeScript() returns an Array with "the result of the script" from each tab/frame in which the script is run.
"The result of the script" is the value of the last evaluated statement, which can be the value returned by a function (i.e. an IIFE, using a return statement). Generally, this will be the same thing that the console would display as the results of the execution (not console.log(), but the results) if you executed the code/script from the Web Console (F12) (e.g. for the script var foo='my result';foo;, the results array will contain the string "my result" as an element). If your code is short, you can try executing it from the console.
Here is some example code taken from another answer of mine:
chrome.browserAction.onClicked.addListener(function(tab) {
console.log('Injecting content script(s)');
//On Firefox document.body.textContent is probably more appropriate
chrome.tabs.executeScript(tab.id,{
code: 'document.body.innerText;'
//If you had something somewhat more complex you can use an IIFE:
//code: '(function (){return document.body.innerText;})();'
//If your code was complex, you should store it in a
// separate .js file, which you inject with the file: property.
},receiveText);
});
//tabs.executeScript() returns the results of the executed script
// in an array of results, one entry per frame in which the script
// was injected.
function receiveText(resultsArray){
console.log(resultsArray[0]);
}
This will inject a content script to get the .innerText of the <body> when the browser action button is clicked. you will need the activeTab permission.
As an example of what these produce, you can open up the web page console (F12) and type in document.body.innerText; or (function (){return document.body.innerText;})(); to see what will be returned.

Script not printing error in JavaScript Chrome console

I have just spent far too long trying to find a problem with the code below.
In turned out that because of the context that addRoute was called in, keys() was not returning the keys of the results object. To fix this I had to use Object.keys() despite it working without a problem in the JavaScript console (which I later realised was because of the context).
My question is, why didn't this show in my JavaScript console? It took me quite a while to realise (I have cropped the full code, the actual function is a lot bigger).
Wrong, but no error in the console:
Map.prototype.addRoute = function (results) {
var sectionsIDs = keys(results);
}
Correct
Map.prototype.addRoute = function (results) {
var sectionsIDs = Object.keys(results);
}
Your first function uses the keys console API function.
That "Command Line API Reference" page includes the warning:
Note: This API is only available from within the console itself. You cannot access the Command Line API from scripts on the page.
Thus, it is by design that the keys function only exists for code run directly on the console.
Chrome gives you a small hint about the keys function being a console-only function if you view it in the console:
> keys
function keys(object) { [Command Line API] }

node.js "undefined" mysteriously appears

I have the following node.js files:
//test.js:
var hash=require('./hash');
var sys=require('sys');
sys.puts(hash.hash("asdf","asdf"));
and
//hash.js:
var exec=require('child_process').exec;
var sys=require('sys');
exports.hash=function(data,hash_type){
exec('pwd',function callback(error,stdout,stderr){
sys.puts(stdout);
});
}
When I do node test.js, I get the following output:
eamorr#Compaq6000:~/Desktop/simple-hash$ node test.js
undefined
/home/hynese/Desktop/nodejs-simple-hash
Why am I getting "undefined"??? I'm really stuck here...
Any help is greatly appreciated.
Many thanks in advance,
Change:
sys.puts(hash.hash("asdf","asdf"));
to just:
hash.hash("asdf","asdf");
You're outputting the return value of hash.hash, although since you didn't provide a return value, the language returns undefined, which is then outputted to the screen. You already output the result of the system command in the callback, so you don't need another sys.puts.
As a side note, you probably don't need to name that callback function callback.

Categories

Resources