Using pyDatalog for constraint stores - logic-programming

Consider the following rules:
pyDatalog.create_atoms('X')
pyDatalog.create_atoms('Y')
pyDatalog.create_atoms('a')
pyDatalog.create_atoms('b')
b(X,1) <= (X<0)
b(X,Y) <= (X==1) & (Y>0)
a(X,Y) <= b(X,Y) & (X>0)
And the problem of finding the constraints that satisfy: a(X,1)
The question is: Can you use pyDatalog to come up with the list [(X==1)] ? or [(X>0), (X==1)]?
Thanks,

Unfortunately not, at least with the current version :-)
pyDatalog can solve discrete constraint problems, not general constraint problems like the one you describe. pyDatalog can only return values, not criteria like X>0.
Note: you can combine the first 4 statements in just one:
pyDatalog.create_atoms('X, Y, a, b')

Related

Why is my code returning all records when I am trying to subset inside for loop - R?

for (i in 1:length(data$name)){
if (!is.na(data$years[i]) >= 34 & !is.na(data$gender[i]) == "male" & !is.na(data$classification[i]) == "mid"){
print(data$name)
}
}
There's a few problems in your code. I am assuming this is a class exercise or similar, so I'll add a bit extra detail to illustrate where you've missed a step.
First of all you loop works fine, but your if condition is not completely correct.
!is.na(data$years[i]) >= 34
All of your conditions look (somewhat) like this. The idea is obvious, you want to "check that data$years[i] is not null, and above 34". But in R (and most languages) you have to check these seperately.
!is.na(data$years[i]) && data$years[i] >= 34
Similar for the rest of your conditions.
Next your print statement is printing out everything, because this is what you're asking it to:
print(data$name)
is "ignorant" of anything else you've done up till now. It seems you want to print the specific record, eg:
print(data$name[i])
And this is the way to go about it.
Now R has a thing called "vectorization", so we could wrap this entire loop up in one go:
data$name[!is.na(data$years) & !is.na(data$gender) & !is.na(data$classification) & data$year > 34 & data$gender == "male" & data$classification == "mid"]
But I am assuming that is not part of your current exercise. Note the slight (but important) difference that for vectorized (eg. more than 1) condition I use single & but for single conditions I use 2 &&. The latter is optimized to be "lazy" for single inputs (thus faster).
Perhaps you can try subset + complete.cases like below
subset(
data,
years >= 34 & gender == "male" & classification == "mid" & complete.cases(data[c("years", "gender", "classification")])
)$name

Subtotals with ArrayFormula()

I've created a simple table and trying to split data with subtotals.
A indicates the subtotal lines.
B contains the rows number for previous subtotal. This is just extra field to simplify formulas.
C Contains some amounts.
D Contains subtotals of amounts between previous and current subtotal line.
The subtotal formula has the following view:
=ArrayFormula(
IF($A2:$A; MMULT(
($B2:$B < TRANSPOSE(ROW($A2:$A))) * (TRANSPOSE(ROW($A2:$A)) < ROW($A2:$A));
IF(ISNUMBER(C2:C); C2:C; 0)
); )
)
The problem is that the formula is extrimely slow. Is there a way to make it faster?
Example file:
https://docs.google.com/spreadsheets/d/1HPGeLZfar2s6pIQMVdQ8mIPzNdw2ESqKAwZfo4IicnA/edit?usp=sharing
You could also try this much simpler formula:
=ArrayFormula(
if(B3:B="","",
sumif(row(B3:B),"<="&row(B3:B),C3:C)-
sumif(row(B3:B),"<="&B3:B,C3:C)
)
)
Yes there is
The easier is to remove the blank rows below the data range.
One that might require maintenance, replace open reference like $A2:$A by closed references, i.e. $A2:$A100
One that incresase the formula complexity an volatility, put each open reference inside ARRAY_CONSTRAIN but it's easier to maintain in case that new data rows were added
use the "necessary" range:
=ARRAYFORMULA(IFERROR(IF(A2:A; MMULT((
INDIRECT("B2:B"&MAX(IF(B2:B="";; ROW(B2:B)))) < TRANSPOSE(ROW(
INDIRECT("A2:A"&MAX(IF(A2:A=TRUE; ROW(A2:A); )))))) * (TRANSPOSE(ROW(
INDIRECT("A2:A"&MAX(IF(A2:A=TRUE; ROW(A2:A); ))))) < ROW(
INDIRECT("A2:A"&MAX(IF(A2:A=TRUE; ROW(A2:A); ))))); IF(ISNUMBER(
INDIRECT("C2:C"&MAX(IF(C2:C="";; ROW(C2:C)+1))));
INDIRECT("C2:C"&MAX(IF(C2:C="";; ROW(C2:C)+1))); 0)); )))
this should be way faster...

Cassandra bitwise operations and operators (&, or, not)

My use case is the following:
I have a table that has a bigint clustering column X. I also have a value Y that is a bitmask in this use case. I want to do the following query
select * from table where key1 = something1 AND key2 = something2 AND (X & Y) = 1
where the & is the bitwise and operation between X and Y. Is this possible in cassandra?
Also does cassandra have and, or, xor and not operators?
No, Cassandra "operators" are limited to >, >=, <= and >
They are used in range queries on the sorted clustering column after having selected a primary key.
What you want would be a sort of filtering, not a range query.
You can read the post here to know more about the WHERE clause: http://www.datastax.com/dev/blog/a-deep-look-to-the-cql-where-clause

PyDatalog: list of values in answer

In PyDatalog I have defined the following assertions:
#stations
assert_fact('station', 'A' ,'yellow')
assert_fact('station', 'B' ,'yellow')
assert_fact('station', 'C' ,'yellow')
assert_fact('station', 'D' ,'yellow')
#sections
assert_fact('stretch', 'A' ,'B')
assert_fact('stretch', 'B' ,'C')
assert_fact('stretch', 'C', 'D')
And I would like to ask the database if there is a way to get to D from A.
The following code should work, because it answers set([()]) if there is a way, and None if there isn't. But it doesn't give me the result of the different evaluations of Z. I would like to know also the route, for example: A B C D
load("""
route(X,Y) <= stretch(X,Y)
route(X,Y) <= stretch(X,Z) & route(Z,Y)
""")
I have tried with unbound values, but it only gives me the result of the first iteration:
load("""
route(X,Y,P) <= stretch(X,Y) & (P==Y)
route(X,Y,P) <= stretch(X,P) & route(P,Y,Z)
""")
I think that the problem is that it only takes P in the first iteration. Or should I use aggregation functions? I don't understand very well how I could use concat...
Thanks in advance.
You need a predicate with a variable that contains the nodes between the 2 end points. You could use the following definition of route():
load("""
route(X,P, Y) <= stretch(X,Y) & (P==[])
route(X,P, Y) <= stretch(X,Z) & route(Z,P1,Y) & ~(Z in P1) & (P==[Z]+P1)
""")
print(pyDatalog.ask("route('A', P, 'D')"))
# prints set([(('B', 'C'),)])
Lists are supported since pyDatalog 0.13.

PostgreSQL - CREATE INDEX

I'm working with PostgreSQL to create some data types written in C.
For example, I have:
typedef struct Point3D
{
char id[50];
double x;
double y;
double z;
Point3D;
}
The input and output functions are working properly.
But the problem is the following:
Every id of Point3D must be unique (and can be NULL), so I have decided to create an unique index on this field id, but is that possible?
I'm thinking in something like this:
CREATE UNIQUE INDEX test_point3d_idx ON test_point3d (( getID(columname) ));
where getID returns the field ID of columname.
But I need to implement getID and I am really blocked.
Any advice?
The Postgres manual section "Interfacing Extensions To Indexes" explains indexes on user-defined types like your Point3D. That requires a fair amount of work. I don't know any shortcuts.
Unrelated to your question: are you sure you need this C-language Point3D datatype? Mistakes in such a datatype definition can "confuse or even crash the server". I presume the same applies to C-language operator functions supporting it.
Could you create tables with four columns, one for each Point3D field? Otherwise, could you forego C in favor of a simple CREATE TYPE point3d AS (id char(50), x float8, y float8, z float8)? Perhaps not, but worth a shot...
A unique column will allow multiple values of NULL because NULL is an unknown value so one null compared to another can never really be considered to be equal. Now logically you might consider NULL = NULL to be true, but unique constraint doesn't work that way.
Simple example to prove it.
CREATE TABLE test2
(
unq_id integer NULL,
CONSTRAINT uq_test2 UNIQUE (unq_id)
);
INSERT INTO test2
SElECT NULL;
INSERT INTO test2
SElECT NULL;
INSERT INTO test2
SElECT NULL;
SELECT *
FROM test2;

Resources