I am attempting to locate the nth element of a List in Prolog. Here is the code I am attempting to use:
Cells = [OK, _, _, _, _, _] .
...
next_safe(_) :-
facing(CurrentDirection),
delta(CurrentDirection, Delta),
in_cell(OldLoc),
NewLoc is OldLoc + Delta,
nth1(NewLoc, Cells, SafetyIdentifier),
SafetyIdentifier = OK .
Basically, I am trying to check to see if a given cell is "OK" to move into. Am I missing something?
there is a predfined predicate called nth0 ..
5 ?- nth0(1,[1,2,3],X).
X = 2.
6 ?- listing(nth0).
lists:nth0(A, B, C) :-
integer(A), !,
A>=0,
nth0_det(A, B, C).
lists:nth0(A, B, C) :-
var(A), !,
nth_gen(B, C, 0, A).
true.
index listing start from 0
hope this helps ..
Louis, I'm not entirely clear on what you're aiming to do with this code, but a couple of comments that might hopefully help.
Things that start with a capital letter in Prolog are variables to be matched against in rules. _ is a special symbol that can be used in place of a variable name to indicate that any value can match.
next_safe(_) is therefore only capable of providing you with a true/false answer if you give it a specific value. One of the major benefits of Prolog is the ability to unify against a variable through backtracking (as ony said). This would mean that when written correctly you could just ask Prolog next_safe(X). and it would return all the possible values (safe moves) that unify with X.
To go back to the first point about capital letters. This means that OK is actually a variable waiting to be matched. It is effectively an empty box that you are trying to match against another empty box. I think what you're intending is to use the value ok which is different. You do not assign to variables in the same way that you do in other programming styles. Something like the following might be closer to what you are looking for, though I'm still not sure it's right as it looks like you're trying to assign things but I'm not certain how your nth1 works.
Cells = [ok, _, _, _, _, _] .
...
next_safe(NewLoc) :-
facing(CurrentDirection),
delta(CurrentDirection, Delta),
in_cell(OldLoc),
NewLoc is OldLoc + Delta,
nth1(NewLoc, Cells, ok).
Related
Structured text seems to delight in making the simple really difficult (much more used to C). Could somebody please rearrange this so it will compile.
VAR_GLOBAL
ErrorStg : Array[0 .. 10] of STRING[16] := "Good","Bad","Fsked";
END_VAR
Did you read the compiler error at all...?
The working version at least on CODESYS 3 based platforms:
ErrorStg : ARRAY[0 .. 10] OF STRING[16] := ['Good','Bad','Fsked'];
The working version at least on CODESYS 2 based platforms:
ErrorStg : ARRAY[0 .. 10] OF STRING[16] := 'Good', 'Bad', 'Fsked';
You should use ' instead of " with regular strings.
When you initialize an array on the definition line, you have to give all of the values (all 11 in your case).
As an alternative, I would suggest a much easier solution - use an init routine to assign the values. If you are opposed to “burning boot time”, you can still solve by defining a FB called InitGlobals and then define a FB_INIT method and put your assignments there. FB_INIT executes as soon as the object exists and not when your program runs. Add an instance of InitGlobals to your code, of course.
In the Hash documentation, the section on Object keys seems to imply that you can use any type as a Hash key as long as you indicate but I am having trouble when trying to use an array as the key:
> my %h{Array};
{}
> %h{[1,2]} = [3,4];
Type check failed in binding to parameter 'key'; expected Array but got Int (1)
in block <unit> at <unknown file> line 1
Is it possible to do this?
The [1,2] inside the %h{[1,2]} = [3,4] is interpreted as a slice. So it tries to assign %h{1} and %{2}. And since the key must be an Array, that does not typecheck well. Which is what the error message is telling you.
If you itemize the array, it "does" work:
my %h{Array};
%h{ $[1,2] } = [3,4];
say %h.perl; # (my Any %{Array} = ([1, 2]) => $[3, 4])
However, that probably does not get what you want, because:
say %h{ $[1,2] }; # (Any)
That's because object hashes use the value of the .WHICH method as the key in the underlying array.
say [1,2].WHICH; say [1,2].WHICH;
# Array|140324137953800
# Array|140324137962312
Note that the .WHICH values for those seemingly identical arrays are different.
That's because Arrays are mutable. As Lists can be, so that's not really going to work.
So what are you trying to achieve? If the order of the values in the array is not important, you can probably use Sets as keys:
say [1,2].Set.WHICH; say [1,2].Set.WHICH
# Set|AEA2F4CA275C3FE01D5709F416F895F283302FA2
# Set|AEA2F4CA275C3FE01D5709F416F895F283302FA2
Note that these two .WHICHes are the same. So you could maybe write this as:
my %h{Set};
dd %h{ (1,2).Set } = (3,4); # $(3, 4)
dd %h; # (my Any %{Set} = ((2,1).Set) => $(3, 4))
Hope this clarifies things. More info at: https://docs.raku.org/routine/WHICH
If you are really only interested in use of an Object Hash for some reason, refer to Liz's answer here and especially the answers to, and comments on, a similar earlier question.
The (final1) focus of this answer is a simple way to use an Array like [1,'abc',[3/4,Mu,["more",5e6],9.9],"It's {<sunny rainy>.pick} today"] as a regular string hash key.
The basic principle is use of .perl to approximate an immutable "value type" array until such time as there is a canonical immutable Positional type with a more robust value type .WHICH.
A simple way to use an array as a hash key
my %hash;
%hash{ [1,2,3].perl } = 'foo';
say %hash{ [1,2,3].perl }; # displays 'foo'
.perl converts its argument to a string of Perl 6 code that's a literal version of that argument.
say [1,2,3].perl; # displays '[1, 2, 3]'
Note how spaces have been added but that doesn't matter.
This isn't a perfect solution. You'll obviously get broken results if you mutate the array between key accesses. Less obviously you'll get broken results corresponding to any limitations or bugs in .perl:
say [my %foo{Array},42].perl; # displays '[(my Any %{Array}), 42]'
1 This is, hopefully, the end of my final final answer to your question. See my earlier 10th (!!) version of this answer for discussion of the alternative of using prefix ~ to achieve a more limited but similar effect and/or to try make some sense of my exchange with Liz in the comments below.
Problem:
Hello, I have been struggling recently in my programming endeavours. I have managed to receive the output below from Google Speech to Text, but I cannot figure out how draw data from this block.
Excerpt 1:
[VoiceMain]: Successfully initialized
{"result":[]}
{"result":[{"alternative":[{"transcript":"hello","confidence":0.46152416},{"transcript":"how low"},{"transcript":"how lo"},{"transcript":"how long"},{"transcript":"Polo"}],"final":true}],"result_index":0}
[VoiceMain]: Successfully initialized
{"result":[]}
{"result":[{"alternative":[{"transcript":"hello"},{"transcript":"how long"},{"transcript":"how low"},{"transcript":"howlong"}],"final":true}],"result_index":0}
Objective:
My goal is to extract the string "hello" (without the quotation marks) from the first transcript of each block and set it equal to a variable. The problem arises when I do not know what the phrase will be. Instead of "hello", the phrase may be a string of any length. Even if it is a different string, I would still like to set it to the same variable to which the phrase "hello" would have been set to.
Furthermore, I would like to extract the number after the word "confidence". In this case, it is 0.46152416. Data type does not matter for the confidence variable. The confidence variable appears to be more difficult to extract from the blocks because it may or may not be present. If it is not present, it must be ignored. If it is present however, it must be detected and stored as a variable.
Also please note that this text block is stored within a file named "CurlOutput.txt".
All help or advice related to solving this problem is greatly appreciated.
You could do this with regex, but then I am assuming you will want to use this as a dict later in your code. So here is a python approach to building this result as a dictionary.
import json
with open('CurlOutput.txt') as f:
lines = f.read().splitlines()
flag = '{"result":[]} '
for line in lines: # Loop through each lin in file
if flag in line: # check if this is a line with data on it
results = json.loads(line.replace(flag, ''))['result'] # Load data as a dict
# If you just want to change first index of alternative
# results[0]['alternative'][0]['transcript'] = 'myNewString'
# If you want to check all alternative for confidence and transcript
for result in results[0]['alternative']: # Loop over each alternative
transcript = result['transcript']
confidence = None
if 'confidence' in result:
confidence = result['confidence']
# now do whatever you want with confidence and transcript.
For a query simple as that
runDb . select . from $ \cell -> do
where_ $ cell ^. CellCode ==. val "x"
return cell
I want to apply a function before the comparison of the field value with "x". The reason is that the cell code has trailing spaces in the database and nothing easier than trimming them away, e.g. with strip from Data.Text. However, my initial approach of using fmap (twice) resulted in
No Instance for (Functor SqlExpr)
I know that there are functions provides by Esqueleto, like just, that accomplish similar things specifically (I couldn't find the implementation of just, though).
Is there a way to apply any function on the packed value?
While writing: in my specific case, I just might want to use like.
EDIT: Added the specific function I want to apply.
What kind of function to you want to apply?
Here is how someone added the ability to call the chr() function in a query:
https://github.com/krisajenkins/esqueleto/commit/fa1d1c888770e297fef52d76b6cb68342a6c0376
If it is a built-in function (or a user-definable function), perhaps you can do something similar.
See here for a post that adds the postgresql function trim:
import Database.Esqueleto.Internal.Sql
trim :: (IsString s) => SqlExpr (Value s) -> SqlExpr (Value s) -> SqlExpr (Value s)
trim pattern target =
unsafeSqlFunction "trim" (unsafeSqlBinOp "FROM" pattern target)
(If you're not using postgres, you may need to consult the documentation from your database to find if it supports something similar.)
unsafeSqlFunction can be used to import any function your database supports, but it is unsafe because you have the responsibility to make sure the type signature is actually what your database expects. The name will be copied literally to your SQL.
unsafeSqlBinOp is similar, but it defines a binary operation: unsafeSqlBinOp "FROM" "a" "b" is translated into the SQL "a" FROM "b".
With this, you should be able to do:
runDb . select . from $ \cell -> do
where_ $ trim " " (cell ^. CellCode) ==. val "x"
return cell
I have a data frame DF which contains numerous variables. Each variable is present twice because I am conducting an analysis of "couples".
Among others, DF has a series of indicators of diversity :
DF$div1.1, DF$div2.1, .... , DF$divN.1, DF$div.1.2, ..., DF$divN.2
Similarly, it has a series of indicators of another characteristic:
DF$char1.1, DF$char2.1, .... , DF$charM.1, DF$char.1.2, ..., DF$charM.2
Here's a link to an example of DF: http://shorttext.com/5d90dd64
Each time the ".1", ".2" stand for the couple member considered.
My goal:
For each indicator divI and charJ, I want to create another variable DF$divchar that takes the value DF$divI.1 when DF$charJ.1>DF$charJ.2; and DF$divI.2 when DF$charJ.1<DF$charJ.2.
Here is the solution I came up with, it seems somehow very intricate and sometimes behaves in strange ways:
I created a series of binary variables that take the value one if DF$charJ.1>DF$charJ.2. The are stored under DF$CharMax.1.
Here's how I created it:
DF$CharMax.1 <- as.data.frame(
sapply(1:length(nam),
function(n)
as.numeric(DF[names(DF)==names.1[n]]
>DF[names(DF)==names.2[n]])
))
I created the function BinaryExtract:
BinaryExtract <- function(var1, var2, extract) {var1*extract +var2*(1-extract)}
I created the matrix NameFull that contains all the possible combinations of div and char, separated with "YY"
NameFull <- sapply(c("div1",...,"divN")
, function(nam) paste(nam, names(DF$YMax.1), sep="YY")
And then I create all my variables:
DF[, as.vector(NameFull)] <- lapply(as.vector(NameFull), function(e)
BinaryExtract(DF[,paste0(unlist(strsplit(e,"YY"))[1],".1")]
, DF[, paste0(unlist(strsplit(e,"YY"))[1],".1")]
, DF$charMax.1[unlist(strsplit(e,"YY"))[2]]))
My Problem
A. It looks like a very complicated solution for something that simple. What am I missing?
B. Moreover, when I print DF, just typing DF in the command window, I do not see the variables NameFull. They seem to appear with the names of char.
Here's what I get: http://shorttext.com/5d9102c
Similarly, I have tried to change all their names to get rid of the "YY" and it does not seem to work:
names(DF[, as.vector(NameFull)]) <- as.vector(c("div1",...,"divN"), sapply(, function(nam)
paste(nam, names(DF$YMax.1), sep=".")))
When I look at names(DF), I keep getting the old names with the "YY"
However, I do get a result if I explicitly call for them
> DF[,"divIYYcharJ"]
I would really appreciate any suggestion, comment and explanation. I am quite new to R ad was more used to Stata. I feel there is something deeply inefficient here. Thanks