Related
I want to represent edges as pairs using the hyphen operator, i.e., From-To.
I want to represent nodes as pairs as well (denoting FCA concepts), i.e., Extent-Intent.
So I get something like the following:
([1]-[a])-([2,3]-[b])
The brackets make sure the expression is properly disambiguated: the single outer hyphen denotes the edge operator, the two inner hyphens denote the node operator.
Here is my problem:
?- X = (a-b)-(c-d), X = Y1-Y2-Y3.
X = a-b- (c-d),
Y1 = a,
Y2 = b,
Y3 = c-d
I was expecting this to fail instead...
My questions:
Why are the brackets removed in the (displayed) binding of X?
Why is the first hyphen interpreted in a different way than the third one?
Possibly relevant, precedence rules for the hyphen operator:
?- current_op(P,T,-).
P = 200,
T = fy ;
P = 500,
T = yfx.
(This is in SWI-Prolog developer branch, but I doubt this will be SWI-specific.)
Usually, write_canonical is very useful in understanding how Prolog interprets operators.
?- write_canonical(a-b-c).
-(-(a,b),c)
true.
?- write_canonical(a-(b-c)).
-(a,-(b,c))
true.
?- write_canonical(a-b-c-d).
-(-(-(a,b),c),d)
true.
?- write_canonical(a-b-(c-d)).
-(-(a,b),-(c,d))
true.
And then, this sort of makes sense, assuming that all hyphens here are binary operators with the right hand argument having the strictly lower precedence:
?- X = (a-b)-(c-d), X = Y1-(Y2-Y3).
X = a-b- (c-d),
Y1 = a-b,
Y2 = c,
Y3 = d.
?- X = (a-b)-(c-d), X = (Y1-Y2)-Y3.
X = a-b- (c-d),
Y1 = a,
Y2 = b,
Y3 = c-d.
The first brackets are not strictly necessary to display the nested term -(-(a,b),-(c,d)). The second pair of brackets is necessary, otherwise it would mean -(-(-(a,b),c),d).
PS. Since I am not good enough to always keep operator precedence rules in my head, I try to avoid operators. There is nothing wrong with explicit functors. The hyphen of course is very useful for predicates like keysort/2 and libraries like library(ugraphs).
I have got a vector in MATLAB that represents function values. I am plotting these, but want to highlight the ones that are in a specific range. In particular I am interested in all points with function value close to, but less than 'v'. I.e. for a value 'x', I want to highlight this point if
abs( x - v ) < epsilon && x < v
If I want to select all the points 'x' such that
abs( x - v) < epsilon
what I have got to work is (I am not sure if this is good coding practice or not)
inds = (abs( xs - v ) < epsilon ) ;
and then plot the xs against my ys in axes a
plot( a, ys(inds), xs(inds), 'ks ' ) ;
This approach is no longer working if I try and do
inds = (abs( xs - v) < epsilon && xs < v ) ;
In this case I am getting the following error, no matter how I arrange the brackets:
'Operands to the || and && operators must be convertible to logical scalar values.'
I guess I have two questions
1.) Why does the approach not work if I try and use the logical &&? As far as I can see I am using expressions that can be converted to logical scalar values
2.) Is this a good way to select a subset of points in MATLAB?
Thanks,
Keeran
That's because && is only for scalar values. You have vectors, not scalars, so you have to use & instead:
inds = ( abs(xs-v) < epsilon & xs < v );
Other than that yes, it is the right way to select a subset of points.
For reference, note that & also works for scalars. The reason to have && is that it is potentially faster for scalars (see doc).
I tried to write a prolog code that can understand student program written in C#. Now I'm stuck in the process of recognizing the 'if' statement in student's program. For example:
The following is the code that I expect from the student.
int d = int.Parse(Console.ReadLine()); // value d is inputted by user
int s = 0;
if (d>0)
s = 2;
else if (d==0)
s = 1;
else
s = 0;
I defined the goal of this expected code as:
goal:-
hasVarName(Vid_s, s),
hasVarName(Vid_d, d),
hasVarValue(Vid_d, Vd),
((not(gt(Vd,0)); hasVarValue(Vid_s, 2)), %eq: [Vd>0] -> [val_s = 2]
((gt(Vd,0); not(eq(Vd,0)); hasVarValue(Vid_s, 1)), %eq: [~(Vd>0)^(Vd=0)] -> [val_s = 1]
((gt(Vd,0); eq(Vd,0); hasVarValue(Vid_s, 0). %eq: [~(Vd>0)^~(Vd=0)] -> [val_s = 0]
The problem is how can I represent the above student code in prolog facts and rules, to find out that the goal is satisfied for any possible conditions.
I tried to change the first part of the student code to become facts like the following, but don't really know how to represent the student's 'if' statement as facts/rules in prolog (I guess, I should not change it to prolog 'if', right?)
hasVarName(varID_d, d)
hasVarValue(varID_d, val_d) %it is unknown, so I represent it as symbol 'val_d'
hasVarName(varID_s, s)
hasVarValue(varID_s, 0)
And another one, in my goal, when I have comparison such as gt(Vd,0) I think I cannot use the prolog greater than operator, neither Vd> 0 nor Vd #> 0 cause the value in Vd is actually a certain value entered by user, but it is represented as symbolic value (in this case it is: val_d).
Note: using the above goal, I think the defined goal will be satisfied if student code is changed to the following code.
int d = int.Parse(Console.ReadLine()); // value d is inputted by user
int s = 0;
if (d>0)
s = 2;
else if (d==0)
s = 1;
or
int d = int.Parse(Console.ReadLine()); // value d is inputted by user
int s = 10; // any random initialization
if (d>0)
{
int x = 2; // unnecessary step, but still Ok.
s = x;
}
else if (d==0)
s = 1;
else
s = 0;
But again, I need help/idea how this code can be represented in prolog as action/rule/fact to meet the goal.
Any help is really appreciated.
Many thanks
I guess you tried to model if-then-else via implication, using
the following boolean identity:
A -> B == ~A v B.
Instead of using conjunctions of implications, it is easier
to use disjunction to choose between branches, and conjunction
along the control flow. But that you exclude previous if-conditions
via negation is still necessary.
Take your example:
if (d>0)
s = 2;
else if (d==0)
s = 1;
else
s = 0;
You can use CLP( * ) to model it. Add extra variables so that
variables are not overridden, but this is not a problem in the
small above snippet. In CLP( * ) the above snippet becomes, I
am using CLP(FD) for simplicity:
Welcome to SWI-Prolog (Multi-threaded, 64 bits, Version 6.3.0)
Copyright (c) 1990-2012 University of Amsterdam, VU Amsterdam
?- use_module(library(clpfd)).
?- [user].
that_if(D, S) :-
(D #> 0, S #= 2;
D #=< 0, D #= 0, S #= 1;
D #=< 0, D #\= 0, S #= 0)
^D
In a decent CLP( * ) system you can arbitrarily instantiate or
constrain D or S in a query. We get for example already
in CLP(FD):
/* What conditions give result S #= 1 ? */
?- S #= 1, that_if(D, S).
S = 1,
D = 0 .
/* What results give condition D #= 1 */
?- D #= 1, that_if(D, S).
D = 1,
S = 2 ;
false.
/* What conditions give a result S #=< 1 */
?- S #=< 1, that_if(D, S).
S = 1,
D = 0 ;
S = 0,
D in inf.. -1.
/* What results give a condition D #>= 0 */
?- D #>= 0, that_if(D, S).
S = 2,
D in 1..sup ;
D = 0,
S = 1 ;
false.
Bye
Usually a language implementation requires an abstract syntax tree, where it's convenient to specify the semantic actions that implements the constructs we are allowed to express.
You seem skipping the phase of building the syntax tree, and (by hand?) represent the intermediate level of the program.
If you stick to such medium level representation, you can use a recursive term (an abstract tree, in effect) like if(Condition, Then, Else) where each var it's in turn a syntax tree.
Otherwise, a more practical representation (usually applied for imperative language), use the concepts of basic blocks (an instruction sequence without jumps) and then labels, to describe the execution flow.
The result it's a graph, and the behaviour of the program is determined by the 'topology' of that representation.
goal:-
hasVarName(Vid_s, s),
hasVarName(Vid_d, d),
hasVarValue(Vid_d, Vd),
%eq: [Vd>0] -> [val_s = 2]
((not(gt(Vd,0)); hasVarValue(Vid_s, 2), goto(label(0))),
%eq: [~(Vd>0)^(Vd=0)] -> [val_s = 1]
((gt(Vd,0); not(eq(Vd,0)); hasVarValue(Vid_s, 1), goto(label(0))),
%eq: [~(Vd>0)^~(Vd=0)] -> [val_s = 0]
((gt(Vd,0); eq(Vd,0); hasVarValue(Vid_s, 0)), % the goto is useless here...
label(0),
.....
Note that I didn't pay any attention to describe correctly your sample program, just placed the jumps to show this possibility...
edit I think that the general problem can't be solved, being equivalent to the halting problem for a Turing Machine. For the particular case at hand, without loops, I would attack the problem using abstract interpretation on the AST. I.e. an interpreter that computes what's interesting.
If it's feasible depends on the generality of your target programs. You should be able to partition the integer domain for each variable involved in each condition point. Things become rapidly complex...
Specifically, at the condition point of the IF THEN ELSE attempt to partition the domain. Using such approach, let Prolog execute the IF testing both branches, propagating the values. But, as I said, is not really easy...
I use the LINQ Aggregate operator quite often. Essentially, it lets you "accumulate" a function over a sequence by repeatedly applying the function on the last computed value of the function and the next element of the sequence.
For example:
int[] numbers = ...
int result = numbers.Aggregate(0, (result, next) => result + next * next);
will compute the sum of the squares of the elements of an array.
After some googling, I discovered that the general term for this in functional programming is "fold". This got me curious about functions that could be written as folds. In other words, the f in f = fold op.
I think that a function that can be computed with this operator only needs to satisfy (please correct me if I am wrong):
f(x1, x2, ..., xn) = f(f(x1, x2, ..., xn-1), xn)
This property seems common enough to deserve a special name. Is there one?
An Iterated binary operation may be what you are looking for.
You would also need to add some stopping conditions like
f(x) = something
f(x1,x2) = something2
They define a binary operation f and another function F in the link I provided to handle what happens when you get down to f(x1,x2).
To clarify the question: 'sum of squares' is a special function because it has the property that it can be expressed in terms of the fold functional plus a lambda, ie
sumSq = fold ((result, next) => result + next * next) 0
Which functions f have this property, where dom f = { A tuples }, ran f :: B?
Clearly, due to the mechanics of fold, the statement that f is foldable is the assertion that there exists an h :: A * B -> B such that for any n > 0, x1, ..., xn in A, f ((x1,...xn)) = h (xn, f ((x1,...,xn-1))).
The assertion that the h exists says almost the same thing as your condition that
f((x1, x2, ..., xn)) = f((f((x1, x2, ..., xn-1)), xn)) (*)
so you were very nearly correct; the difference is that you are requiring A=B which is a bit more restrictive than being a general fold-expressible function. More problematically though, fold in general also takes a starting value a, which is set to a = f nil. The main reason your formulation (*) is wrong is that it assumes that h is whatever f does on pair lists, but that is only true when h(x, a) = a. That is, in your example of sum of squares, the starting value you gave to Accumulate was 0, which is a does-nothing when you add it, but there are fold-expressible functions where the starting value does something, in which case we have a fold-expressible function which does not satisfy (*).
For example, take this fold-expressible function lengthPlusOne:
lengthPlusOne = fold ((result, next) => result + 1) 1
f (1) = 2, but f(f(), 1) = f(1, 1) = 3.
Finally, let's give an example of a functions on lists not expressible in terms of fold. Suppose we had a black box function and tested it on these inputs:
f (1) = 1
f (1, 1) = 1 (1)
f (2, 1) = 1
f (1, 2, 1) = 2 (2)
Such a function on tuples (=finite lists) obviously exists (we can just define it to have those outputs above and be zero on any other lists). Yet, it is not foldable because (1) implies h(1,1)=1, while (2) implies h(1,1)=2.
I don't know if there is other terminology than just saying 'a function expressible as a fold'. Perhaps a (left/right) context-free list function would be a good way of describing it?
In functional programming, fold is used to aggregate results on collections like list, array, sequence... Your formulation of fold is incorrect, which leads to confusion. A correct formulation could be:
fold f e [x1, x2, x3,..., xn] = f((...f(f(f(e, x1),x2),x3)...), xn)
The requirement for f is actually very loose. Lets say the type of elements is T and type of e is U. So function f indeed takes two arguments, the first one of type U and the second one of type T, and returns a value of type U (because this value will be supplied as the first argument of function f again). In short, we have an "accumulate" function with a signature f: U * T -> U. Due to this reason, I don't think there is a formal term for these kinds of function.
In your example, e = 0, T = int, U = int and your lambda function (result, next) => result + next * next has a signaturef: int * int -> int, which satisfies the condition of "foldable" functions.
In case you want to know, another variant of fold is foldBack, which accumulates results with the reverse order from xn to x1:
foldBack f [x1, x2,..., xn] e = f(x1,f(x2,...,f(n,e)...))
There are interesting cases with commutative functions, which satisfy f(x, y) = f(x, y), when fold and foldBack return the same result. About fold itself, it is a specific instance of catamorphism in category theory. You can read more about catamorphism here.
I am wondering if there is a way to generate a key based on the relationship between two entities in a way that the key for relationship a->b is the same as the key for relationship b->a.
Desirably this would be a hash function which takes either relationship member but generates the same output regardless of the order the members are presented in.
Obviously you could do this with numbers (e.g. add(2,3) is equivalent to add(3,2)). The problem for me is that I do not want add(1,4) to equal add(2,3). Obviously any hash function has overlap but I mean a weak sense of uniqueness.
My naive (and performance undesirable) thought is:
function orderIndifferentHash(string val1, string val2)
{
return stringMerge(hash(val1), hash(val2));
/* String merge will 'add' each character (with wrapping).
The pre-hash is to lengthen strings to at least 32 characters */
}
In your function orderIndifferentHash you could first order val1 and val2 by some criteria and then apply any hash function you like to get the result.
function orderIndifferentHash( val1, val2 ) {
if( val1 < val2 ) {
first = val1
second = val2
}
else {
first = val2
second = val1
}
hashInput = concat( first, second )
return someHash( hashInput )
// or as an alternative:
// return concat( someHash( first ), someHash( second ) )
}
With numbers, one way to achieve that is for two numbers x and y take the x-th prime and y-th prime and calculate the product of these primes. That way you will guarantee the uniqueness of the product for each distinct pair of x and y and independence from the argument order. Of course, in order to do that with any practically meaningful efficiency you'll need to keep a prime table for all possible values of x and y. If x and y are chosen from relatively small range, this will work. But if range is large, the table itself becomes prohibitively impractical, and you'll have no other choice but to accept some probability of collision (like keep a reasonably sized table of N primes and select the x%N-th prime for the given value of x).
Alternative solution, already mentioned in the other answers is to build a perfect hash function that works on your x and y values and then simply concatenate the hashes for x and y. The order independence is achieved by pre-sorting x and y. Of course, building a perfect hash is only possible for a set of arguments from a reasonably small range.
Something tells me that the primes-based approach will give you the shortest possible hash that satisfies the required conditions. No, not true.
You you are after:
Some function f(x, y) such that
f(x, y) == f(y, x)
f(x, y) != f(a, b) => (x == a and y == b) or (x == b and y == a)
There are going to be absolutely loads of these - off hand the one I can think of is "sorted concatenation":
Sort (x, y) by any ordering
Apply a hash function u(a) to x and y individually (where u(a) == u(b) implies a == b, and the length of u(a) is constant)
Concatenate u(x) and u(y).
In this case:
If x == y then then the two hashes are trivially the same, so without loss of generality x < y, hence:
f(y, x) = u(x) + u(y) = f(x, y)
Also, if f(x, y) == f(a, b), this means that either:
u(x) == u(a) and u(y) == u(b) => x == a and y == b, or
u(y) == u(a) and u(x) == u(b) => y == a and x == b
Short version:
Sort x and y, and then apply any hash function where the resulting hash length is constant.
Suppose you have any hash h(x,y). Then define f(x,y) = h(x,y) + h(y,x). Now you have a symmetric hash.
(If you do a trivial multiplicative "hash" then 1+3 and 2+2 might hash to the same value, but even something like h(x,y) = x*y*y will avoid that--just make sure there's some nonlinearity in at least one argument of the hash function.)