Vi introducerar Raffinationsreflektion, ett nytt ramverk för att bygga SMT-baserade kontrollörer. Nyckelidén är att spegla koden som implementerar en användardefinierad funktion i funktionens (utmatnings)förfiningstyp. Som en följd av detta, vid användning av funktionen, är funktionsdefinitionen omedelbar i SMT-logiken på ett exakt sätt som tillåter decimerbar verifiering. Reflektering gör det möjligt för användaren att skriva ekvationssäkra program bara genom att skriva andra program t.ex. Använda mönstermatchning och rekursion för att utföra fall-splitting och induktion. Således visar vi, genom principen om propositions-as-types, att reflektion tillåter specificering av godtyckliga funktionella korrekthetsegenskaper. Slutligen introducerar vi en proof-search algoritm som heter Proof by Logical Evaluation som använder tekniker från modellkontroll och abstrakt tolkning, för att helt automatisera ekvationstänkande. Vi har implementerat reflektion i Liqid Haskell och använt den för att verifiera att de allmänt använda instanserna av Monoid, Applicative, Funkor, och Monad typeclasses faktiskt uppfyller viktiga algebraiska lagar som krävs för att göra kunderna säkra, och har använt reflektion för att bygga det första biblioteket som faktiskt verifierar antaganden om associativitet och beställning som är avgörande för säker deterministisk parallellism. och förklara därför varför ett givet bevisförsök misslyckas [Leino och Pit-Claudel 2016]. I andra änden har vi typ-teori (TT) baserade teoremtestare (t.ex. Coq och Agda) som använder typ-nivå beräkning (normalisering) för att underlätta principiella resonemang om att avsluta användardefinierade funktioner, men som kräver att användaren att leverera lemmas eller skriva tips till ansvarsfrihet bevis över decideable teorier. Vi introducerar Raffinationsreflektion, ett nytt ramverk för att bygga SMT-baserade kontrollörer, som tillåter specifikation av godtyckliga egenskaper och ändå möjliggör komplett, automatiserad SMT-baserad resonemang om användardefinierade funktioner. I tidigare arbete, förfining typer [Constable och Smith 1987; Rushby et al. 1998 ] — som utsmyckning av grundtyper (t.ex. Integer) med SMT-beslutbara predikat (t.ex. (v:Integer 0 ≤ v && v < 100}) — användes för att eftermontera så kallad ytlig verifiering, t.ex. kontroll av arraygränser, till flera språk: ML [Bengtson et al. 2008; Rondon m.fl. 2008; Xi och Pfenning 1998], C [Condit et al. 2007; Rondon m.fl. 2010], Haskell [Vazou et al. 2014], TypeScript [Vekris et al. 2016] och Racket [ Kent et al. Denna förordning träder i kraft den tjugonde dagen efter det att den har offentliggjorts i Europeiska unionens officiella tidning. I detta arbete utökar vi förädlingstyper med förädlingsreflektion, vilket leder till följande tre bidrag. 1. Vad är det för fel på dig? Raffinering Reflektion Vårt första bidrag är begreppet förfining reflektion. För att resonera om användardefinierade funktioner reflekteras funktionens implementation i specifikationen (output) förfining, vilket omvandlar funktionens typsignatur till en exakt beskrivning av funktionens beteende. Denna enkla idé har en djupgående följd: vid användning av funktionen ger standardregeln för (beroende) funktionstillämpningen ett exakt sätt att resonera om funktionen (4). Vårt andra bidrag är ett bibliotek av kombinatorer som låter programmerare komponera sofistikerade bevis från grundläggande finesser och funktionsdefinitioner. Våra korrekturkombinatorer låter programmerare använda befintliga språkmekanismer, som grenar (för att koda fall splits), rekursion (för att koda induktion), och funktioner (för att koda extra lemmas), för att skriva bevis som ser väldigt mycket ut som deras penna-och-papper analoger (-2). Dessutom, eftersom bevis är bokstavligen bara program, använder vi principen om propositions-as-types [Wadler 2015] (känd som Curry-howard isomorphism [Howards 1980] ) för att visa att SMT-baserade kontrollörer kan uttrycka alla naturliga avdrag bevis, vilket ger en trevlig genomförande av naturliga avdrag som kan användas för pedagogiska ändamål ( och 3). 3. Vad är det som händer? Fullständig verifiering Medan ekvationsproofs kan vara mycket enkelt och uttrycksfullt, kan skriva ut dem snabbt få utmattande. Vårt tredje bidrag är Proof by Logical Evaluation (PLE) en ny bevissökningsalgoritm som automatiserar ekvationstänkande. Den viktigaste idén i PLE är att efterlikna typnivåberäkning inom SMT-logik genom att representera funktioner i en bevakad form [Dijkstra 1975] och upprepade gånger utveckla funktion application termer genom att ögonblickliga dem med sin definition som motsvarar ett aktiverat skydd. Vi formaliserar en uppfattning om ekvationsbevis och visar att ovanstående strategi är komplett: d.v.s. Det är garanterat att hitta ett ekvationssäkert om man finns. Dessutom använder man tekniker från litteraturen om abstrakt tolkning [Cousot and Cousot 1977] och modellkontroll [Clarke et al. 1992], Vi visar att ovanstående bevissökning motsvarar en universell (eller måste) abstraktion av de konkreta semantik av de användardefinierade funktionerna. Eftersom dessa funktioner är totala, får vi alltså den glädjande garantin att bevissökningen upphör (6). Vi utvärderar vår strategi genom att implementera förfining reflektion och PLE i Liqid Haskell [Vazou et al. 2014], vilket gör Haskell till ett teorem bevis. Genom att använda ett befintligt programmeringsspråk kan vi dra nytta av en mogen kompilator och ett ekosystem av bibliotek, samtidigt som vi håller bevis och program på samma språk. Vi visar fördelarna med denna omvandling genom att bevisa typklass lagar. Haskells maskin av typklass har lett till en serie expressiva abstraktioner och optimeringar som, för att vara korrekt, på ett avgörande sätt kräver typklassfall för att lyda viktiga algebraiska lagar. Vi visar hur reflektion och PLE kan användas för att verifiera att allmänt använda instanser
REF introducerar förfining reflexion så att en funktions genomförande återspeglas i specifikationen av utdataförfiningstyp.
Refinement reflection: complete verification with SMT