3 ms·
> I'm simply saying that for the restricted case of safety semantics alone, this deduction can be done. And I'm saying it can't be done, at least not in a fund
by muldvarp 3y ago
> I'm simply saying that for the restricted case of safety semantics alone, this deduction can be done.
And I'm saying it can't be done, at least not in a fundamentally less tedious and hard way than Frama-C.
> Yes, it is impossible to deduce semantic equivalence of arbitrary functions. The question is whether it is possible to deduce that annotations capture the safety semantics of the body.
It isn't in general.
> If you have a concrete example it would be helpful here – but for the restricted concerns of safety, not for arbitrary constructs.
Safety is not a "restricted concern": You can for every property P easily construct a function that is safe if and only if property P holds. I'll be using Python because this example (which I like) requires arbitrary size integers. You could obviously also implement this in C, you'd just need to implement arbitrary size integers (or use a library that implements them):
def collatz(x):
if x % 2 == 0:
return x // 2
return x * 3 + 1
def cycle(f, x):
tortoise = f(x)
hare = f(f(x))
while tortoise != hare:
tortoise = f(tortoise)
hare = f(f(hare))
return hare
buffer = [0, 0, 0, 0, 0]
x = int(input())
if x >= 1:
collatz_cycle_element = cycle(collatz, x)
print(buffer[collatz_cycle_element]) # this is safe (or is it?)
This takes as an input an arbitrary positive integer x, searches for a cycle in the Collatz sequence beginning with that number and returns an arbitrary element of that cycle. It is conjectured that for every positive integer this cycle will be 4 -> 2 -> 1 -> 4 -> ... and thus this program is safe if and only if the Collatz conjecture holds.
Another example would be a C program that generates random planar graphs, computes their chromatic numbers and then collects statistics about them in an `int statistics[5]`:
#include <stdio.h>
void main() {
int statistics[5] = {0};
for(int i = 0; i < 1000; i++) {
struct graph g = generate_random_planar_graph();
int chromatic_number = compute_chromatic_number(g);
statistics[chromatic_number] += 1;
}
printf("%i, %i, %i, %i", statistics[1], statistics[2], statistics[3], statistics[4]);
}
The safety of this program requires you to prove that `generate_random_planar_graph` always returns a planar graph, that `compute_chromatic_number` correctly identifies the chromatic number and that the chromatic number of every planar graph is less than 5.
- akiarie 3y agoThought provoking stuff! I really appreciate how much effort you've put into this. However, the main reason why this argument is flawed is it omits the heart of the matter: the annotations. Xr0 empowers programmers to propagate safety semantics. A program that is only safe if the Collatz conjecture holds is (surprise) only safe if the Collatz conjecture holds. So in Xr0 the only requirement we would impose is that this program be augmented with an annotation that communicates that it is only safe if the Collatz conjecture is true. So the flaw in the reasoning is we haven't claimed that Xr0 can prove arbitrary programs are safe. We've claimed that Xr0 can prove the correspondence between the safety semantics denoted in an annotation and a function body. Above there are no annotations given which would specify "this program is safe only if the Collatz conjecture is true". It shouldn't be hard to prove the correspondence between such an annotation and the program you've written, e.g.: def main(): ~ [ buffer = [0, 0, 0, 0, 0] x = int(input()) if x >= 1: collatz_cycle_element = cycle(collatz, x) print(buffer[collatz_cycle_element]) ] buffer = [0, 0, 0, 0, 0] x = int(input()) if x >= 1: collatz_cycle_element = cycle(collatz, x) print(buffer[collatz_cycle_element]) It's the principle of propagating the safety-determining factors of the function that we're stressing, not some kind of almighty power to judge that arbitrary constructs are safe or not.
- muldvarp 3y ago> It's the principle of propagating the safety-determining factors of the function that we're stressing That's the main function. It's the function that gets called when the program starts. Where do you want to propagate the "safety-determining factors" to? If I'm just supposed to read the annotations on the `main` function (and those annotations can basically just be a copy of it's body), then why do I need the annotations at all? I could also read the program to determine whether it's safe.
- akiarie 3y agoIt's because we're dealing with an extreme example in which a program's safety depends on the resolution of an open problem. If the program's safety depends on the semantics of C and how they've been used in a function, it will be possible to deal with all the conditions upon which a program could be unsafe (in the sense of the standard safety vulnerabilities – like those listed here [0]). Doing so would lead to denouement, so that the annotation to the main function would be empty (meaning none of those bugs can occur). Programs that might be unsafe should not be verifiable. [0]: https://alexgaynor.net/2020/may/27/science-on-memory-unsafety-and-security/ https://alexgaynor.net/2020/may/27/science-on-memory-unsafet...