2016-02-03 10 views
6

kullanarak örnektir: Ben yapmak istiyorum nehesaplayın ulaşılabilirlik Frama-c kullanıcısının değeri analizi Burada

int in; 
int sum(int n){ 
    int log_input = n; 
    int log_global = in; 
    return 0; 
} 

int main(){ 
    int n = Frama_C_interval(-10, 10); 
    in = n; 
    if (n > 0){ 
     sum(n + 4); 
    } 
    return 0; 
} 

ana başlatılmış zaman giriş değişkeni n aralığını bulmaktır sonuçları bu işlev toplamına ulaşmak. Bu örnekte doğru aralık [1, 10].

örneklemde

, ben küresel değer orijinal girdi "save" ve değişken oluşturuldu log_global içine atama ve böylece sonuçlandı orijinal girdi keşfederek fonksiyon toplamı yeniden kullanmaya istiyorum fonksiyona ulaşmada. Bu örnekte frama-c'yi çalıştırırken, log_input aralığının [5, 14] ve log_global aralığının [-10, 10] olduğunu görürüz. Bunun nedenini anlıyorum -'daki değeri, ana'un başlangıcında ayarlanır ve n üzerindeki diğer işlemlerden etkilenmez.

Bunu frama-c'de değiştirmenin basit bir yolu olup olmadığını merak ediyordum? Belki de frama-c kodundaki basit bir değişiklik? Ben

Bir ilgisiz bir fikir ana yılında ise ifadesi manipüle etmek oldu:

if (in > 0){ 
    sum(in + 4); 
} 

yerine n küresel değişkeni kullanılır. Bu gerçekten doğru aralıklarla sonuçlanır, ancak bu çözüm daha karmaşık işlevlere ve daha derin çağrı yığınlarına iyi ölçeklenmez.

cevap

3

İşte olası bir çözüm. Yerleşik Frama_C_interval_split ve uygun bir -slevel N kullanın (burada, en az N=21). işlev sum N kez N, olası her değeri için bir incelenecektir, ve sonuç

int n = Frama_C_interval_split(-10, 10); 

sonuç kesin olacaktır:

[value] Values at end of function sum: 
    log_input ∈ [5..14] 
    log_global ∈ [1..10] 
    __retres ∈ {0} 

(Temel olarak, bu kılavuz Model-gerçekleştirmek tutarındadır kontrol etmek, bu yüzden performanslar büyük değerler için iyi olmayacaktır.)

+0

Doğru sonuçlar almıyor gibiyim, log_input [5, MaxInt] ve log_global [MinInt, MaxInt], belki de bir sürüm sorunu mu? Sodyum kullanıyorum. Ayrıca eğer doğru anlarsam, bu bilinmeyen veya çok geniş aralıklarla uygulanamaz, değil mi? –

+0

Benim hatam, 'Frama_C_interval_split', yayınlanan sürümün bir parçası değil. Aynı sonucu, "Frama_C_interval": '// @ assert n == -10 | n == -9 || ... n == 10'. Ve aslında, bu büyük aralıklarla işe yaramaz. Diğer yandan, tam otomatikliği hedeflemezseniz, akıllı bir bölümleme yapabilirsiniz: '// @ assert n <= 0 || n > 0' bu durumda çalışacaktır. – byako