// field ::= 'fst' | 'snd' // Relations representing the program: // ploadconst : loc -> reg -> num -> type (l : x = n) // pallocpair : loc -> reg -> reg -> reg -> type (l : x = < y , z >) // pgetfield : loc -> reg -> reg -> field -> type (l : x = y.f) // psetfield : loc -> reg -> field -> reg -> type (l : x.f = y) // values are numbers or locations: // value = | loc(l) // The relations we want to define: // valueofreg : reg -> value -> type // valueoffield : loc -> field -> value -> type // size of DB: // there are n lines in the program. // we only consider values, registers, and locations, // that appear in the program, // so there are // O(n) values, regs, and locs // and a constant number of fields. // Thus, the completed DB can have // O(n^2) valueofreg facts and the same for valueoffield. // The completed DB thus has O(n^2) facts. // // prefix firings are annotated on each rule // O(n) there are at most O(n) ploadconst facts valueofreg(?r,?n) :- ploadconst(?l, ?r, ?n). // O(n^3) the line from the program fixes most thing, // but then there are O(n) locations ?l // and O(n) values ?v valueofreg(?r1,?v) :- pgetfield(?l2, ?r1, ?r2, ?f), valueofreg(?r2, loc(?l)), valueoffield(?l , ?f, ?v). // O(n^3) O(n) lines in the program, // and then O(n) ?v and O(n) ?l valueoffield(?l , ?f , ?v) :- psetfield(?l2 , ?r1 , ?f , ?r2), valueofreg(?r2 , ?v), valueofreg(?r1 , loc(?l)). // O(n^2) valueoffield(?l , 'fst' , ?v1) :- pallocpair(?l , ?r , ?r1 , ?r2), valueofreg(?r1 , ?v1). // O(n^2) valueoffield(?l , 'snd' , ?v2) :- pallocpair(?l , ?r , ?r1 , ?r2), valueofreg(?r2 , ?v2). // O(n) valueofreg(?r , loc(?l)) :- pallocpair(?l , ?r , ?r2 , ?r3). // Overall: O(n^3) because the prefix firings dominate // the completed database // ---------------------------------------------------------------------- // the progam ploadconst('l1', 'w', 0). // l1 : w = 0 ploadconst('l2', 'x', 1). // l2 : x = 1 ploadconst('l3', 'y', 2). // l3 : y = 2 ploadconst('l4', 'z', 3). // l4 : z = 3 pallocpair('l5', 'p1', 'w', 'x'). // l5 : p1 = < w , x > pallocpair('l6', 'p2', 'y', 'z'). // l6 : p2 = < y , z > pallocpair('l7' , 'p' , 'p1' , 'p2'). // l7 : p = psetfield('l12', 'p', 'fst', 'p2'). // l12 : p.fst = p2 psetfield('l13', 'p', 'snd', 'p1'). // l13 : p.snd = p1 pgetfield('l8', 'p1' , 'p' , 'fst'). // l8 : p1 = p.fst pgetfield('l9', 'p2' , 'p' , 'snd'). // l9 : p2 = p.snd pgetfield('l10', 'r1', 'p1' , 'fst'). // l10 : r1 = p1.fst pgetfield('l11', 'r2', 'p2' , 'snd'). // l11 : r2 = p2.snd // SHOULD BE: 0,2 ?- valueofreg('r1',?v1). // SHOULD BE: 3,1 ?- valueofreg('r2',?v2).