How to code first order logic formula in C? - c

I am newbie in C and new to stackoveflow too. I have some problems in coding first oder formula like
forall([X],implies(X,f(X)))
Here x is a variable, implies is predicate and f is function. It sounds like for all x, x implies function of x i'e f(x).
using C. Any kind of suggestions and help will be appreciated.

First order formulas have boolean propositional parts (in your example, "implies(x,f(x))") and quantifiers ("Forall x").
You should already know that coding a function call "f(x)" is coded exactly that way in C.
You code the propositional part as boolean C code using logic connectives. For your example, "implication" isn't a native C operator so you have to substitute slightly different code for it. In c, the "?" operator does the trick. "a?b:c" produces "b" if "a" is true, and "c" otherwise. For your example:
x?f(x):false
Quantifiers mean you have to enumerate the set of possible values of the quantified variable, which always has some abstract type. In logic, this set might be infinite, but it computers it is not. In your case, you need to enumerate the set of values which could be "x"s. To do that, you need a way to represent a set; a cheesy way to do that in C is to use an array to hold the set members X, and to iterate through the array:
type_of_x set_of_x[1000];
... fill x somehow ...
for(i=1;i<number_of_set_elements;i++)
{ x= set_of_x[i];
... evaluate formula ...
}
Since a "forall" is false if any propositional instance is false, you need to exit the enumeration when you find a false example:
boolean set_of_x[1000]; // in your example, x must be a boolean variable
// forall x
... fill x somehow ...
final_value=true;
for (i=1;i<number_set_elements; i++)
{ x= set_of_x[i];
if (x?f(x):false)
{ final_value=false;
break;
}
}
... final_value set correctly here...
"exists" is true if any propositional instance is true, so you need to exit the enumeration when you find a true result:
// exists x
... fill x somehow ...
final_value=false;
for (i=1;i<number_set_elements; i++)
{ x= set_of_x[i];
if (x?f(x):false)
{ final_value=true;
break;
}
}
... final_value set correctly here...
If you have multiple quantifiers, you'll end up with nested loops, one loop for each quantifier. If your formula is complex, you'll likely need several intermediate boolean variables to compute the values of the various parts.
You'll also end up with a variety of "sets" (some arrays, some linked lists, some hash tables) so you'll need to learn how to use these data structures. Also, your quantified values might not be booleans, but that's OK;
you can still pass them to functions that compute boolean values. To compute the FOL for:
forall p:Person old(p) and forall f:Food ~likes(p,f)
the following code skeleton would be used (details left to the reader):
person array_of_persons[...];
foods array_of_foods[...]
for (i=...
{ p=array_of_persons[i];
is_old = old(p);
for(j=...
{ f=array_of_foods[j];
...
if (is_old && !likes(p,f)) ...
}
}

C is an imperative programming language. "Imperative" here means that execution happens via the programmer specifically telling the computer what to do.
For what you want, Prolog is more appropriate. It is based on first-order predicate logic, and execution happens by trying to "find a resolution refutation of the negated query" that's specified by the user's goal. This approach is very unlike C since execution is much more implicit and the expression of intent looks much different.
If you have lots of time, you can write your own constraint solver or Prolog interpreter in C, but by default, C has no first-class support for what you're looking for.

Related

Theory of arrays in Z3: (1) model is difficult to understand, (2) do not know how to implement functions and (3) difference with sequences

Following to the question published in How expressive can we be with arrays in Z3(Py)? An example, I expressed the following formula in Z3Py:
Exists i::Integer s.t. (0<=i<|arr|) & (avg(arr)+t<arr[i])
This means: whether there is a position i::0<i<|arr| in the array whose value a[i] is greater than the average of the array avg(arr) plus a given threshold t.
The solution in Z3Py:
t = Int('t')
avg_arr = Int('avg_arr')
len_arr = Int('len_arr')
arr = Array('arr', IntSort(), IntSort())
phi_1 = And(0 <= i, i< len_arr)
phi_2 = (t+avg_arr<arr[i])
phi = Exists(i, And(phi_1, phi_2))
s = Solver()
s.add(phi)
print(s.check())
print(s.model())
Note that, (1) the formula is satisfiable and (2) each time I execute it, I get a different model. For instance, I just got: [avg_a = 0, t = 7718, len_arr = 1, arr = K(Int, 7719)].
I have three questions now:
What does arr = K(Int, 7719)] mean? Does this mean the array contains one Int element with value 7719? In that case, what does the K mean?
Of course, this implementation is wrong in the sense that the average and length values are independent from the array itself. How can I implement simple avg and len functions?
Where is the i index in the model given by the solver?
Also, in which sense would this implementation be different using sequences instead of arrays?
(1) arr = K(Int, 7719) means that it's a constant array. That is, at every location it has the value 7719. Note that this is truly "at every location," i.e., at every integer value. There's no "size" of the array in SMTLib parlance. For that, use sequences.
(2) Indeed, your average/length etc are not related at all to the array. There are ways of modeling this using quantifiers, but I'd recommend staying away from that. They are brittle, hard to code and maintain, and furthermore any interesting theorem you want to prove will get an unknown as answer.
(3) The i you declared and the i you used as the existential is completely independent of each other. (Latter is just a trick so z3 can recognize it as a value.) But I guess you removed that now.
The proper way to model such problems is using sequences. (Although, you shouldn't expect much proof performance there either.) Start here: https://microsoft.github.io/z3guide/docs/theories/Sequences/ and see how much you can push it through. Functions like avg will need a recursive definition most likely, for that you can use RecAddDefinition, for an example see: https://stackoverflow.com/a/68457868/936310
Stack-overflow works the best when you try to code these yourself and ask very specific questions about how to proceed, as opposed to overarching questions. (But you already knew that!) Best of luck..

Handling double-variable switch statement with macro in C

Let's say I have two pointers to two structs a and b. These two structs each contain an enum, which we'll call x. Given any possible a and b, I want to call a specific function based on the values of their x enums.
What is interesting in my case is that the functions that I want to call look like:
X0_to_X1();
X0_to_X2();
...
X1_to_X0();
...
etc
where X0, X1 etc are possible values of the enum x, meaning that there are X_to_Y functions for every and each combination of the values of the x enum.
The obvious "naive" solution to this would be a switch statement which would be quite big (given that x has quite a few possible values):
switch (a->x) {
case X0:
switch (b->x) {
case X1:
X0_to_X1();
break;
// ... and so on and so forth for every possible pair!
My first attempt at solving this a bit more elegantly was to implement a macro that, given two values of x, could form a function call:
#define CALL_FUNCTION(x1, x2) x1 ## _to_ ## x2 ()
This however does not work, as in my code I never can know the actual values of x before runtime, so it ends up looking like:
CALL_FUNCTION(a->x, b->x);
which of course gets converted to:
a->x_to_b->x();
which makes absolutely no sense.
Is there a way to solve this problem more elegantly, or should I just bite the bullet and implement the enormous switch statement instead?
This problem screams for a lookup table, where you store pointers to the various functions and they are keyed by the enumeration values.
If your enum values are sequential (and no two enumeration constants share the same value), then you can build a lookup table as a simple 2D array:
enum x_t { X0, X1, X2, ..., NUM_X };
void (*lookup[NUM_X][NUM_X])(void) = {
{ NULL, X0_to_X1, X0_to_X2, X0_to_X3, ... },
{ X1_to_X0, NULL, X1_to_X2, X1_to_X3, ... },
{ X2_to_X0, X2_to_X1, NULL, X2_to_X3, ... },
...
};
That assumes you don’t have an "identity” function when your x and y are the same.
Then, you call the desired function by indexing into to table like so:
if ( x != y )
lookup[x][y]();
No, it isn’t pretty, but it beats nested switch statements. You can hide that behind a macro or another function call if you wish.
If your enumeration values aren’t sequential then this particular implementation won’t work - you’d have to build your lookup table a different way, using lists or sparse matrices. But while the setup code may be tedious, it will greatly simplify the logic on the calling side.

String expansion in openCL

I have a simple task of expanding the string FX according to the following rules:
X -> X+YF+
Y-> -FX-Y
In OpenCL, string manipulation is not supported but the use of an array of characters is. How would a kernel program that expands this string in parallel look like in openCL?
More details:
Consider the expansion of 'FX' in the python code below.
axiom = "FX"
def expand(s):
switch = {
"X": "X+YF+",
"Y": "-FX-Y",
}
return switch.get(s, s)
def expand_once(string):
return [expand(c) for c in string]
def expand_n(s, n):
for i in range(n):
s = ''.join(expand_once(s))
return s
expanded = expand_n(axiom, 200)
The result expanded will be a result of expanding the axiom 'FX' 200 times. This is a rather slow process thus the need to do it on openCL for parallelization.
This process results in an array of strings which I will then use to draw a dragon curve.
below is an example of how I would come up with such a dragon curve: This part is not of much importance. The expansion on OpenCL is the crucial part.
import turtles
from PIL import Image
turtles.setposition(5000, 5000)
turtles.left(90) # Go up to start.
for c in expanded:
if c == "F":
turtles.forward(10)
elif c == "-":
turtles.left(90)
elif c == "+":
turtles.right(90)
# Write out the image.
im = Image.fromarray(turtles.canvas)
im.save("dragon_curve.jpg")
Recursive algorithms like this don't especially lend themselves to GPU acceleration, especially as the data set changes its size on each iteration.
If you do really need to do this iteratively, the challenge is for each work-item to know where in the output string to place its result. One way to do this would be to assign work groups a specific substring of the input, and on every iteration, keep count of the total number of Xs and Ys in each workgroup-sized substring of the output. From this you can calculate how much that substring will expand in one iteration, and if you accumulate those values, you'll know the offset of the output of each substring expansion. Whether this is efficient is another question. :-)
However, your algorithm is actually fairly predictable: you can calculate precisely how large the final string will be given the initial string and number of iterations. The best way to generate this string with OpenCL would be to come up with a non-recursive function which analytically calculates the character at position N given M iterations, and then call that function once per work-item, with the (known!) final length of the string as the work size. I don't know if it's possible to come up with such a function, but it seems like it might be, and if it is possible, this is probably the most efficient way to do it on a GPU.
It seems like this might be possible: as far as I can tell, the result will be highly periodic:
FX
FX+YF+
FX+YF++-FX-YF+
FX+YF++-FX-YF++-FX+YF+--FX-YF+
FX+YF++-FX-YF++-FX+YF+--FX-YF++-FX+YF++-FX-YF+--FX+YF+--FX-YF+
^^^^^^ ^^^^^^^ ^^^^^^^ ^^^^^^^ ^^^^^^^ ^^^^^^^ ^^^^^^^ ^^^^^^^
A* B A B A B A B
As far as I can see, those A blocks are all identical, and so are the Bs. (apart from the first A which is effectively at position -1) You can therefore determine the characters at 14 positions out of every 16 completely deterministically. I strongly suspect it's possible to work out the pattern of +s and -s that connects them too. If you figure that out, the solution becomes pretty easy.
Note though that when you have that function, you probably don't even need to put the result in a giant string: you can just feed your drawing algorithm with that function directly.

Implementing chained iterators in a Ruby C extension

I see that there's a relatively new feature in Ruby which allows chained iteration -- in other words, instead of each_with_indices { |x,i,j| ... } you might do each.with_indices { |x,i,j| ... }, where #each returns an Enumerator object, and Enumerator#with_indices causes the additional yield parameters to be included.
So, Enumerator has its own method #with_index, presumably for one-dimensional objects, source found here. But I can't figure out the best way to adapt this to other objects.
To be clear, and in response to comments: Ruby doesn't have an #each_with_indices right now -- it's only got an #each_with_index. (That's why I want to create one.)
A series of questions, themselves chained:
How would one adapt chained iteration to a one-dimensional object? Simply do an include Enumerable?
Presumably the above (#1) would not work for an n-dimensional object. Would one create an EnumerableN class, derived from Enumerable, but with #with_index converted into #with_indices?
Can #2 be done for Ruby extensions written in C? For example, I have a matrix class which stores various types of data (floats, doubles, integers, sometimes regular Ruby objects, etc.). Enumeration needs to check the data type (dtype) first as per the example below.
Example:
VALUE nm_dense_each(VALUE nm) {
volatile VALUE nm = nmatrix; // Not sure this actually does anything.
DENSE_STORAGE* s = NM_STORAGE_DENSE(nm); // get the storage pointer
RETURN_ENUMERATOR(nm, 0, 0);
if (NM_DTYPE(nm) == nm::RUBYOBJ) { // matrix stores VALUEs
// matrix of Ruby objects -- yield those objects directly
for (size_t i = 0; i < nm_storage_count_max_elements(s); ++i)
rb_yield( reinterpret_cast<VALUE*>(s->elements)[i] );
} else { // matrix stores non-Ruby data (int, float, etc)
// We're going to copy the matrix element into a Ruby VALUE and then operate on it. This way user can't accidentally
// modify it and cause a seg fault.
for (size_t i = 0; i < nm_storage_count_max_elements(s); ++i) {
// rubyobj_from_cval() converts any type of data into a VALUE using macros such as INT2FIX()
VALUE v = rubyobj_from_cval((char*)(s->elements) + i*DTYPE_SIZES[NM_DTYPE(nm)], NM_DTYPE(nm)).rval;
rb_yield( v ); // yield to the copy we made
}
}
}
So, to combine my three questions into one: How would I write, in C, a #with_indices to chain onto the NMatrix#each method above?
I don't particularly want anyone to feel like I'm asking them to code this for me, though if you did want to, we'd love to have you involved in our project. =)
But if you know of some example elsewhere on the web of how this is done, that'd be perfect -- or if you could just explain in words, that'd be lovely too.
#with_index is a method of Enumerator: http://ruby-doc.org/core-1.9.3/Enumerator.html#method-i-with_index
I suppose you could make a subclass of Enumerator that has #with_indices and have your #each return an instance of that class? That's the first thing that comes to mind, although your enumerator might have to be pretty coupled to the originating class...
Since you are saying that you are also interested in Ruby linguistics, not just C, let me contribute my 5 cents, without claiming to actually answer the question. #each_with_index and #with_index already became so idiomatic, that majority of the people rely on the index being a number. Therefore, if you go and implement your NMatrix#each_with_index in such way, that in the block { |e, i| ... } it would supply eg. arrays [0, 0], [0, 1], [0, 2], [1, 0], [1, 1], ... as index i, you would surprise people. Also, if others chain your NMatrix#each enumerator with #with_index method, they will receive just a single number as index. So, indeed, you are right to conclude that you need a distinct method to take care for the 2 indices-type (or, more generally, n indices for higher dimension matrices):
matrix.each_with_indices { |e, indices| ... }
This method should return a 2-dimensional (n-dimensional) array as indices == [i, j] . You should not go for the version:
matrix.each_with_indices { |e, i, j| ... }
As for the #with_index method, it is not your concern at all. If your NMatrix provides #each method (which it certainly does), then #with_index will work normally with it, out of your control. And you do not need to ponder about introducing matrix-specific #with_indices, because #each itself is not really specific to matrices, but to one-dimensional ordered collections of any sort. Finally, sorry for not being a skilled C programmer to cater to your C-related part of the question.

evaluating array expressions

I'm using Z3-3.2's c-api (on linux) for solving QF_AUFBV problems.
If the formula is satisfiable, I'd like to read out the value of the free array variables from the model.
I tried something along the lines of the following code and I'd like to know if the general idea of how to do this is right:
void evaluate(Z3_context context, Z3_model model, Z3_ast array)
{
Z3_ast value;
Z3_bool success = Z3_eval(context, model, array, &value);
if (success) {
unsigned num_entries;
if (Z3_is_array_value(context, model, value, &num_entries)) {
Z3_ast indices[num_entries];
Z3_ast values[num_entries];
Z3_ast def;
Z3_get_array_value(context, model, array, num_entries, indices, values, &def);
// do something with indices, values, and def
}
}
}
The input Z3_ast array is definitely a free array expression. Z3_eval returns true, so we seem to have successfully evaluated the expression, but then Z3_is_array_value returns false. I would have expected the result of a successfull Z3_eval on an array expression to be an array value, so why is this not the case?
By the way: We managed to get at the desired information by iterating over all model_func_decls and trying to find the right one for that array by comparing their get_symbol_string. So the information seems to be available somewhere in Z3, but that hardly counts as a nice solution.
Thanks for any help on this.
Best regards,
Florian
The evaluator is a bit more powerful than the API for accessing array values.
The function is_array_value succeeds only when the represented array is of the form
(store (store (store (... (const v) ...) ..)..))
or of the form as-array[f], where f is a finite unary function.
The is_array_value and get_array_value functions can be implemented using the existing API
and are exposed for convenience
(as you describe, except we can avoid using string comparisons and instead use comparisons on
the function declarations that are enumeration sorts).
So it sounds like we would be able to support more in your case and I am curious how the model value
looks like. Would you be able to provide additional information about the example that does not pass? (print it?)
Thanks

Resources