:- use_module(library(clpfd)).
:- style_check(-singleton).
pointer([
		[0x11118d48,0],
		[0x11118d50,0],
		[0x11118d58,0],
		[0x11118d60,0],
		[0x11118d68,279196224],
		[0x11118d70,279196416],
		[0x11118d78,0],
		[0x11118d80,0],
		[0x11118d88,0],
		[0x11118da0,0],
		[0x11118da8,0],
		[0x11118db0,286362944],
		[0x11118db8,1047376768],
		[0x11118dc0,0],
		[0x11118dc8,0],
		[0x11118dd0,0],
		[0x11118dd8,282149805],
		[0x11118de8,0],
		[0x11118df0,0],
		[0x11118df8,0],
		[0x11118e00,282062164],
		[0x11118e10,265448976],
		[0x11118e18,265448896],
		[0x11118e20,0],
		[0x11118e28,285999872],
		[0x11118e30,1047531752],
		[0x11118e38,0],
		[0x11118e40,0],
		[0x11118e48,0],
		[0x11118e50,286363216],
		[0x11118e58,286363216],
		[0x11118e68,1045511808],
		[0x11118e70,0],
		[0x11118e78,0],
		[0x11118e80,280005984],
		[0x11118e88,279091264],
		[0x11118e90,279287104],
		[0x11118e98,279091584],
		[0x11118ea0,279091520],
		[0x11118ea8,279091360],
		[0x11118eb0,279178720],
		[0x11118eb8,279090944],
		[0x11118ec0,0],
		[0x11118ec8,286363456],
		[0x11118ee0,0],
		[0x11118ee8,286363456],
		[0x11118ef0,286363328],
		[0x11118ef8,286363328],
		[0x11118f00,0],
		[0x11118f08,0],
		[0x11118f10,0],
		[0x11118f18,1045538904],
		[0x11118f20,0],
		[0x11118f28,0],
		[0x11118f30,0],
		[0x11118f38,0],
		[0x11118f40,282040178],
		[0x11118f48,0],
		[0x11118f58,0],
		[0x11118f60,0],
		[0x11118f68,0],
		[0x11118f70,0],
		[0x11118f78,0],
		[0x11118f80,0],
		[0x11118f88,0],
		[0x11118f90,0],
		[0x11118f98,0],
		[0x11118fa0,0],
		[0x11118fa8,0],
		[0x11118fb0,0],
		[0x11118fb8,0],
		[0x11118fc0,287119136],
		[0x11118fc8,287125776],
		[0x11118fd0,265502064],
		[0x11118fd8,265502016],
		[0x11118fe0,0],
		[0x11118fe8,0],
		[0x11118ff0,0],
		[0x11118ff8,0],
		[0x11119000,0],
		[0x11119008,0],
		[0x11119010,0],
		[0x11119018,0],
		[0x11119020,0],
		[0x11119028,286363688],
		[0x11119030,286363688],
		[0x11119038,0],
		[0x11119040,0],
		[0x11119048,0],
		[0x11119050,290605376],
		[0x11119058,1037233024],
		[0x11119060,0],
		[0x11119068,0],
		[0x11119070,286363760],
		[0x11119078,286363760],
		[0x11119080,286363776],
		[0x11119088,286363776],
		[0x11119090,286363792],
		[0x11119098,286363792],
		[0x111190a0,0],
		[0x111190a8,0],
		[0x111190b0,286363824],
		[0x111190b8,286363824],
		[0x111190c0,279218880],
		[0x111190c8,279218816],
		[0x111190d0,0],
		[0x111190d8,0],
		[0x111190e0,0],
		[0x111190e8,0],
		[0x111190f0,286363888],
		[0x111190f8,286363888],
		[0x11119100,0],
		[0x11119108,286363912],
		[0x11119110,286363912],
		[0x11119118,265528720],
		[0x11119120,286363936],
		[0x11119128,0],
		[0x11119130,0],
		[0x11119138,0],
		[0x11119140,0],
		[0x11119148,0],
		[0x11119150,286363984],
		[0x11119158,286363984],
		[0x11119160,282343717],
		[0x11119170,265534720],
		[0x11119178,265534656],
		[0x11119180,0],
		[0x11119188,285292288],
		[0x11119190,809162984],
		[0x11119198,0],
		[0x111191a0,0],
		[0x111191a8,286364072],
		[0x111191b0,286364072],
		[0x111191b8,0],
		[0x111191c0,0],
		[0x111191c8,0],
		[0x111191d0,0],
		[0x111191d8,0],
		[0x111191e0,0],
		[0x111191e8,0],
		[0x111191f0,286364144],
		[0x111191f8,286364144],
		[0x11119200,282084802],
		[0x11119210,262903264],
		[0x11119218,0],
		[0x11119220,0],
		[0x11119228,0],
		[0x11119230,0],
		[0x11119238,282154763],
		[0x11119240,282155423],
		[0x11119248,0],
		[0x11119250,0],
		[0x11119258,0],
		[0x11119260,282154763],
		[0x11119268,0],
		[0x11119270,265552096],
		[0x11119278,264927024],
		[0x11119280,0],
		[0x11119288,286415488],
		[0x11119290,1038086376],
		[0x11119298,0],
		[0x111192a0,0],
		[0x111192a8,286364328],
		[0x111192b0,286364328],
		[0x111192b8,1045662736],
		[0x111192c0,1045662736],
		[0x111192c8,0],
		[0x111192d0,0],
		[0x111192d8,286364416],
		[0x111192e8,0],
		[0x111192f0,0],
		[0x111192f8,0],
		[0x11119300,286364424],
		[0x11119310,0],
		[0x11119320,286364448],
		[0x11119328,286364448],
		[0x11119330,0],
		[0x11119338,0],
		[0x11119340,0],
		[0x11119348,1030239744],
		[0x11119350,286571392],
		[0x11119358,286571392],
		[0x11119360,0],
		[0x11119368,286364520],
		[0x11119370,286364520],
		[0x11119378,0],
		[0x11119380,0],
		[0x11119388,0],
		[0x11119390,0],
		[0x11119398,0],
		[0x111193a0,282155575],
		[0x111193b0,265553536],
		[0x111193b8,265553472],
		[0x111193c0,0],
		[0x111193c8,286365984],
		[0x111193d0,809160936],
		[0x111193d8,0],
		[0x111193e0,281904823],
		[0x111193e8,0],
		[0x111193f8,286364768],
		[0x11119400,0],
		[0x11119408,0],
		[0x11119410,0],
		[0x11119418,0],
		[0x11119420,0],
		[0x11119428,0],
		[0x11119430,0],
		[0x11119438,0],
		[0x11119440,0],
		[0x11119448,0],
		[0x11119450,0],
		[0x11119458,0],
		[0x11119460,282734066],
		[0x11119468,0],
		[0x11119478,286364896],
		[0x11119480,0],
		[0x11119488,0],
		[0x11119490,0],
		[0x11119498,0],
		[0x111194a0,0],
		[0x111194a8,0],
		[0x111194b0,0],
		[0x111194b8,0],
		[0x111194c0,0],
		[0x111194c8,0],
		[0x111194d0,0],
		[0x111194d8,0],
		[0x111194e0,282273065],
		[0x111194e8,286365160],
		[0x111194f8,0],
		[0x11119500,262793904],
		[0x11119508,0],
		[0x11119510,292349092],
		[0x11119518,286365152],
		[0x11119520,282553545],
		[0x11119528,286365156],
		[0x11119538,0],
		[0x11119540,262793904],
		[0x11119548,0],
		[0x11119550,292349092],
		[0x11119558,286365152],
		[0x11119560,281978999],
		[0x11119568,292349088],
		[0x11119578,0],
		[0x11119580,262793856],
		[0x11119588,0],
		[0x11119590,0],
		[0x11119598,0],
		[0x111195a0,0],
		[0x111195a8,0],
		[0x111195b0,0],
		[0x111195b8,0],
		[0x111195c0,0],
		[0x111195c8,0],
		[0x111195d0,0],
		[0x111195d8,0],
		[0x111195f0,0],
		[0x111195f8,0],
		[0x11119600,286362656],
		[0x11119608,286365344],
		[0x11119610,287251264],
		[0x11119618,282155797],
		[0x11119620,286274816],
		[0x11119628,286418272],
		[0x11119630,286365392],
		[0x11119638,286362704],
		[0x11119648,286075040],
		[0x11119650,282066622],
		[0x11119658,0],
		[0x11119660,0],
		[0x11119668,286365504],
		[0x11119678,0],
		[0x11119680,0],
		[0x11119688,0],
		[0x11119690,0],
		[0x11119698,0],
		[0x111196a0,286365184],
		[0x111196a8,286390272],
		[0x111196b0,287251360],
		[0x111196b8,282155821],
		[0x111196c0,286274976],
		[0x111196c8,286418432],
		[0x111196d0,286390320],
		[0x111196d8,286365232],
		[0x111196e8,286075072],
		[0x111196f0,1045517632],
		[0x111196f8,0],
		[0x11119700,0],
		[0x11119708,286365504],
		[0x11119718,0],
		[0x11119720,0],
		[0x11119728,0],
		[0x11119730,0],
		[0x11119738,0],
		[0x11119740,282155846],
		[0x11119750,286365600],
		[0x11119758,286365568],
		[0x11119760,1037157120],
		[0x11119768,1037158464],
		[0x11119770,286365344],
		[0x11119778,286365184],
		[0x11119780,282155865],
		[0x11119788,282558755],
		[0x11119790,282248876],
		[0x11119798,0],
		[0x111197a0,282140828],
		[0x111197a8,282105348],
		[0x111197b0,282064792],
		[0x111197b8,0],
		[0x111197c0,0],
		[0x111197c8,0],
		[0x111197d0,286365648],
		[0x111197d8,286365648],
		[0x111197e0,286365664],
		[0x111197e8,286365664],
		[0x111197f0,0],
		[0x111197f8,0],
		[0x11119810,0],
		[0x11119818,0],
		[0x11119820,0],
		[0x11119828,0],
		[0x11119830,0],
		[0x11119838,0],
		[0x11119840,0],
		[0x11119848,0],
		[0x11119850,286365776],
		[0x11119858,286365776],
		[0x11119870,0],
		[0x11119878,0],
		[0x11119880,0],
		[0x11119888,0],
		[0x11119890,0],
		[0x11119898,0],
		[0x111198b0,0],
		[0x111198b8,0],
		[0x111198c0,0],
		[0x111198c8,0],
		[0x111198d0,0],
		[0x111198d8,0],
		[0x111198e0,282171451],
		[0x111198f0,265856688],
		[0x111198f8,264927072],
		[0x11119900,0],
		[0x11119908,286414048],
		[0x11119910,889092328],
		[0x11119918,0],
		[0x11119920,282172108],
		[0x11119930,265856688],
		[0x11119938,264927072],
		[0x11119940,0],
		[0x11119948,286365920],
		[0x11119950,0],
		[0x11119958,0],
		[0x111199f0,0],
		[0x111199f8,0],
		[0x11119a78,0],
		[0x11119ba8,0],
		[0x11119bb0,0],
		[0x11119bb8,0],
		[0, 0]
]).
unknown([
		[0x11118e60,36028818493800448],
		[0, 0]
]).
long([
		[0x11118d40,8589934592],
		[0x11118d90,4294967296],
		[0x11118d98,13],
		[0x11118de0,344429],
		[0x11118e08,8],
		[0x11118ed0,4294967296],
		[0x11118ed8,9],
		[0x11118f50,71936407240704],
		[0x11119168,8],
		[0x11119208,292],
		[0x111192e0,1],
		[0x11119308,1953460082],
		[0x11119318,8589934592],
		[0x111193a8,8],
		[0x111193f0,1567663063040],
		[0x11119470,1567663063040],
		[0x111194f0,1803886264324],
		[0x11119530,1803886264324],
		[0x11119570,1254130450436],
		[0x111195e0,4400193994751],
		[0x111195e8,4096],
		[0x11119640,913],
		[0x11119670,2],
		[0x111196e0,914],
		[0x11119710,2],
		[0x11119748,12884902100],
		[0x11119800,5368709120000],
		[0x11119808,10],
		[0x11119860,5368709120000],
		[0x11119868,10],
		[0x111198a0,5368709120000],
		[0x111198a8,10],
		[0x111198e8,1],
		[0x11119928,1],
		[0x11119cd8,491328010095],
		[0, 0]
]).
int([
		[0x11118d40,0],
		[0x11118d44,2],
		[0x11118d48,0],
		[0x11118d4c,0],
		[0x11118d50,0],
		[0x11118d54,0],
		[0x11118d58,0],
		[0x11118d5c,0],
		[0x11118d60,0],
		[0x11118d64,0],
		[0x11118d78,0],
		[0x11118d7c,0],
		[0x11118d80,0],
		[0x11118d84,0],
		[0x11118d88,0],
		[0x11118d8c,0],
		[0x11118d90,0],
		[0x11118d94,1],
		[0x11118d98,13],
		[0x11118d9c,0],
		[0x11118da0,0],
		[0x11118da4,0],
		[0x11118da8,0],
		[0x11118dac,0],
		[0x11118dc0,0],
		[0x11118dc4,0],
		[0x11118dc8,0],
		[0x11118dcc,0],
		[0x11118dd0,0],
		[0x11118dd4,0],
		[0x11118de4,0],
		[0x11118de8,0],
		[0x11118dec,0],
		[0x11118df0,0],
		[0x11118df4,0],
		[0x11118df8,0],
		[0x11118dfc,0],
		[0x11118e08,8],
		[0x11118e0c,0],
		[0x11118e20,0],
		[0x11118e24,0],
		[0x11118e38,0],
		[0x11118e3c,0],
		[0x11118e40,0],
		[0x11118e44,0],
		[0x11118e48,0],
		[0x11118e4c,0],
		[0x11118e60,0],
		[0x11118e70,0],
		[0x11118e74,0],
		[0x11118e78,0],
		[0x11118e7c,0],
		[0x11118ec0,0],
		[0x11118ec4,0],
		[0x11118ed0,0],
		[0x11118ed4,1],
		[0x11118ed8,9],
		[0x11118edc,0],
		[0x11118ee0,0],
		[0x11118ee4,0],
		[0x11118f00,0],
		[0x11118f04,0],
		[0x11118f08,0],
		[0x11118f0c,0],
		[0x11118f10,0],
		[0x11118f14,0],
		[0x11118f20,0],
		[0x11118f24,0],
		[0x11118f28,0],
		[0x11118f2c,0],
		[0x11118f30,0],
		[0x11118f34,0],
		[0x11118f38,0],
		[0x11118f3c,0],
		[0x11118f48,0],
		[0x11118f4c,0],
		[0x11118f50,0],
		[0x11118f54,16749],
		[0x11118f58,0],
		[0x11118f5c,0],
		[0x11118f60,0],
		[0x11118f64,0],
		[0x11118f68,0],
		[0x11118f6c,0],
		[0x11118f70,0],
		[0x11118f74,0],
		[0x11118f78,0],
		[0x11118f7c,0],
		[0x11118f80,0],
		[0x11118f84,0],
		[0x11118f88,0],
		[0x11118f8c,0],
		[0x11118f90,0],
		[0x11118f94,0],
		[0x11118f98,0],
		[0x11118f9c,0],
		[0x11118fa0,0],
		[0x11118fa4,0],
		[0x11118fa8,0],
		[0x11118fac,0],
		[0x11118fb0,0],
		[0x11118fb4,0],
		[0x11118fb8,0],
		[0x11118fbc,0],
		[0x11118fe0,0],
		[0x11118fe4,0],
		[0x11118fe8,0],
		[0x11118fec,0],
		[0x11118ff0,0],
		[0x11118ff4,0],
		[0x11118ff8,0],
		[0x11118ffc,0],
		[0x11119000,0],
		[0x11119004,0],
		[0x11119008,0],
		[0x1111900c,0],
		[0x11119010,0],
		[0x11119014,0],
		[0x11119018,0],
		[0x1111901c,0],
		[0x11119020,0],
		[0x11119024,0],
		[0x11119038,0],
		[0x1111903c,0],
		[0x11119040,0],
		[0x11119044,0],
		[0x11119048,0],
		[0x1111904c,0],
		[0x11119060,0],
		[0x11119064,0],
		[0x11119068,0],
		[0x1111906c,0],
		[0x111190a0,0],
		[0x111190a4,0],
		[0x111190a8,0],
		[0x111190ac,0],
		[0x111190d0,0],
		[0x111190d4,0],
		[0x111190d8,0],
		[0x111190dc,0],
		[0x111190e0,0],
		[0x111190e4,0],
		[0x111190e8,0],
		[0x111190ec,0],
		[0x11119100,0],
		[0x11119104,0],
		[0x11119128,0],
		[0x1111912c,0],
		[0x11119130,0],
		[0x11119134,0],
		[0x11119138,0],
		[0x1111913c,0],
		[0x11119140,0],
		[0x11119144,0],
		[0x11119148,0],
		[0x1111914c,0],
		[0x11119168,8],
		[0x1111916c,0],
		[0x11119180,0],
		[0x11119184,0],
		[0x11119198,0],
		[0x1111919c,0],
		[0x111191a0,0],
		[0x111191a4,0],
		[0x111191b8,0],
		[0x111191bc,0],
		[0x111191c0,0],
		[0x111191c4,0],
		[0x111191c8,0],
		[0x111191cc,0],
		[0x111191d0,0],
		[0x111191d4,0],
		[0x111191d8,0],
		[0x111191dc,0],
		[0x111191e0,0],
		[0x111191e4,0],
		[0x111191e8,0],
		[0x111191ec,0],
		[0x11119208,292],
		[0x1111920c,0],
		[0x11119218,0],
		[0x1111921c,0],
		[0x11119220,0],
		[0x11119224,0],
		[0x11119228,0],
		[0x1111922c,0],
		[0x11119230,0],
		[0x11119234,0],
		[0x11119248,0],
		[0x1111924c,0],
		[0x11119250,0],
		[0x11119254,0],
		[0x11119258,0],
		[0x1111925c,0],
		[0x11119268,0],
		[0x1111926c,0],
		[0x11119280,0],
		[0x11119284,0],
		[0x11119298,0],
		[0x1111929c,0],
		[0x111192a0,0],
		[0x111192a4,0],
		[0x111192c8,0],
		[0x111192cc,0],
		[0x111192d0,0],
		[0x111192d4,0],
		[0x111192e0,1],
		[0x111192e4,0],
		[0x111192e8,0],
		[0x111192ec,0],
		[0x111192f0,0],
		[0x111192f4,0],
		[0x111192f8,0],
		[0x111192fc,0],
		[0x1111930c,0],
		[0x11119310,0],
		[0x11119314,0],
		[0x11119318,0],
		[0x1111931c,2],
		[0x11119330,0],
		[0x11119334,0],
		[0x11119338,0],
		[0x1111933c,0],
		[0x11119340,0],
		[0x11119344,0],
		[0x11119360,0],
		[0x11119364,0],
		[0x11119378,0],
		[0x1111937c,0],
		[0x11119380,0],
		[0x11119384,0],
		[0x11119388,0],
		[0x1111938c,0],
		[0x11119390,0],
		[0x11119394,0],
		[0x11119398,0],
		[0x1111939c,0],
		[0x111193a8,8],
		[0x111193ac,0],
		[0x111193c0,0],
		[0x111193c4,0],
		[0x111193d8,0],
		[0x111193dc,0],
		[0x111193e8,0],
		[0x111193ec,0],
		[0x111193f0,0],
		[0x111193f4,365],
		[0x11119400,0],
		[0x11119404,0],
		[0x11119408,0],
		[0x1111940c,0],
		[0x11119410,0],
		[0x11119414,0],
		[0x11119418,0],
		[0x1111941c,0],
		[0x11119420,0],
		[0x11119424,0],
		[0x11119428,0],
		[0x1111942c,0],
		[0x11119430,0],
		[0x11119434,0],
		[0x11119438,0],
		[0x1111943c,0],
		[0x11119440,0],
		[0x11119444,0],
		[0x11119448,0],
		[0x1111944c,0],
		[0x11119450,0],
		[0x11119454,0],
		[0x11119458,0],
		[0x1111945c,0],
		[0x11119468,0],
		[0x1111946c,0],
		[0x11119470,0],
		[0x11119474,365],
		[0x11119480,0],
		[0x11119484,0],
		[0x11119488,0],
		[0x1111948c,0],
		[0x11119490,0],
		[0x11119494,0],
		[0x11119498,0],
		[0x1111949c,0],
		[0x111194a0,0],
		[0x111194a4,0],
		[0x111194a8,0],
		[0x111194ac,0],
		[0x111194b0,0],
		[0x111194b4,0],
		[0x111194b8,0],
		[0x111194bc,0],
		[0x111194c0,0],
		[0x111194c4,0],
		[0x111194c8,0],
		[0x111194cc,0],
		[0x111194d0,0],
		[0x111194d4,0],
		[0x111194d8,0],
		[0x111194dc,0],
		[0x111194f0,4],
		[0x111194f4,420],
		[0x111194f8,0],
		[0x111194fc,0],
		[0x11119508,0],
		[0x1111950c,0],
		[0x11119530,4],
		[0x11119534,420],
		[0x11119538,0],
		[0x1111953c,0],
		[0x11119548,0],
		[0x1111954c,0],
		[0x11119570,4],
		[0x11119574,292],
		[0x11119578,0],
		[0x1111957c,0],
		[0x11119588,0],
		[0x1111958c,0],
		[0x11119590,0],
		[0x11119594,0],
		[0x11119598,0],
		[0x1111959c,0],
		[0x111195a0,0],
		[0x111195a4,0],
		[0x111195a8,0],
		[0x111195ac,0],
		[0x111195b0,0],
		[0x111195b4,0],
		[0x111195b8,0],
		[0x111195bc,0],
		[0x111195c0,0],
		[0x111195c4,0],
		[0x111195c8,0],
		[0x111195cc,0],
		[0x111195d0,0],
		[0x111195d4,0],
		[0x111195d8,0],
		[0x111195dc,0],
		[0x111195e4,1024],
		[0x111195e8,4096],
		[0x111195ec,0],
		[0x111195f0,0],
		[0x111195f4,0],
		[0x111195f8,0],
		[0x111195fc,0],
		[0x11119640,913],
		[0x11119644,0],
		[0x11119658,0],
		[0x1111965c,0],
		[0x11119660,0],
		[0x11119664,0],
		[0x11119670,2],
		[0x11119674,0],
		[0x11119678,0],
		[0x1111967c,0],
		[0x11119680,0],
		[0x11119684,0],
		[0x11119688,0],
		[0x1111968c,0],
		[0x11119690,0],
		[0x11119694,0],
		[0x11119698,0],
		[0x1111969c,0],
		[0x111196e0,914],
		[0x111196e4,0],
		[0x111196f8,0],
		[0x111196fc,0],
		[0x11119700,0],
		[0x11119704,0],
		[0x11119710,2],
		[0x11119714,0],
		[0x11119718,0],
		[0x1111971c,0],
		[0x11119720,0],
		[0x11119724,0],
		[0x11119728,0],
		[0x1111972c,0],
		[0x11119730,0],
		[0x11119734,0],
		[0x11119738,0],
		[0x1111973c,0],
		[0x11119748,212],
		[0x1111974c,3],
		[0x11119798,0],
		[0x1111979c,0],
		[0x111197b8,0],
		[0x111197bc,0],
		[0x111197c0,0],
		[0x111197c4,0],
		[0x111197c8,0],
		[0x111197cc,0],
		[0x111197f0,0],
		[0x111197f4,0],
		[0x111197f8,0],
		[0x111197fc,0],
		[0x11119800,0],
		[0x11119804,1250],
		[0x11119808,10],
		[0x1111980c,0],
		[0x11119810,0],
		[0x11119814,0],
		[0x11119818,0],
		[0x1111981c,0],
		[0x11119820,0],
		[0x11119824,0],
		[0x11119828,0],
		[0x1111982c,0],
		[0x11119830,0],
		[0x11119834,0],
		[0x11119838,0],
		[0x1111983c,0],
		[0x11119840,0],
		[0x11119844,0],
		[0x11119848,0],
		[0x1111984c,0],
		[0x11119860,0],
		[0x11119864,1250],
		[0x11119868,10],
		[0x1111986c,0],
		[0x11119870,0],
		[0x11119874,0],
		[0x11119878,0],
		[0x1111987c,0],
		[0x11119880,0],
		[0x11119884,0],
		[0x11119888,0],
		[0x1111988c,0],
		[0x11119890,0],
		[0x11119894,0],
		[0x11119898,0],
		[0x1111989c,0],
		[0x111198a0,0],
		[0x111198a4,1250],
		[0x111198a8,10],
		[0x111198ac,0],
		[0x111198b0,0],
		[0x111198b4,0],
		[0x111198b8,0],
		[0x111198bc,0],
		[0x111198c0,0],
		[0x111198c4,0],
		[0x111198c8,0],
		[0x111198cc,0],
		[0x111198d0,0],
		[0x111198d4,0],
		[0x111198d8,0],
		[0x111198dc,0],
		[0x111198e8,1],
		[0x111198ec,0],
		[0x11119900,0],
		[0x11119904,0],
		[0x11119918,0],
		[0x1111991c,0],
		[0x11119928,1],
		[0x1111992c,0],
		[0x11119940,0],
		[0x11119944,0],
		[0x11119950,0],
		[0x11119954,0],
		[0x11119958,0],
		[0x1111995c,0],
		[0x111199f0,0],
		[0x111199f4,0],
		[0x111199f8,0],
		[0x111199fc,0],
		[0x11119a78,0],
		[0x11119a7c,0],
		[0x11119ba8,0],
		[0x11119bac,0],
		[0x11119bb0,0],
		[0x11119bb4,0],
		[0x11119bb8,0],
		[0x11119bbc,0],
		[0x11119cdc,114],
		[0, 0]
]).
string_val([
		[0x11119308,1953460082],
		[0x11119960,3198722456695432226],
		[0x11119968,8386668381597623333],
		[0x11119970,7791353958646050665],
		[0x11119978,3180233089194749545],
		[0x11119980,7451613976710359072],
		[0x11119988,2987133850647553390],
		[0x11119990,4480311169313679392],
		[0x11119998,2323362765625255268],
		[0x111199a0,2893598134626758706],
		[0x111199a8,7234309766870429301],
		[0x111199b0,2893598123004684576],
		[0x111199b8,8531335287333406034],
		[0x111199c0,6138731919885869097],
		[0x111199c8,2317436475106147360],
		[0x111199d0,2318273164950446125],
		[0x111199d8,7959380333680608594],
		[0x111199e0,5917778763192038499],
		[0x111199e8,7308895158889431877],
		[0x11119a00,3198722456695432226],
		[0x11119a08,8315722355160671269],
		[0x11119a10,2893598134514296096],
		[0x11119a18,7234309766870429301],
		[0x11119a20,2893598123004684576],
		[0x11119a28,8531335287333406034],
		[0x11119a30,2967927268501757993],
		[0x11119a38,8317714377132223529],
		[0x11119a40,7955925832297244521],
		[0x11119a48,4847370906359572852],
		[0x11119a50,2747241361179950637],
		[0x11119a58,4340379691147339808],
		[0x11119a60,3539878923266437664],
		[0x11119a68,4847370872067533097],
		[0x11119a70,32483290449853997],
		[0x11119a80,4207528773226423330],
		[0x11119a88,7306097971997729829],
		[0x11119a90,2334031439603245174],
		[0x11119a98,7792670375836347490],
		[0x11119aa0,2675259560542893420],
		[0x11119aa8,7308910564438535276],
		[0x11119ab0,7358992207957008498],
		[0x11119ab8,2699960892541854060],
		[0x11119ac0,2891359485488032876],
		[0x11119ac8,7308892947874739496],
		[0x11119ad0,2891356540817186916],
		[0x11119ad8,7306032859624854056],
		[0x11119ae0,3472873714358430070],
		[0x11119ae8,7959312069250787625],
		[0x11119af0,7575164960043919731],
		[0x11119af8,4995099089510691950],
		[0x11119b00,2317513661104401731],
		[0x11119b08,4332556511145893926],
		[0x11119b10,2318544744440012860],
		[0x11119b18,2893598134626756913],
		[0x11119b20,7234309766870429301],
		[0x11119b28,2893598123004684576],
		[0x11119b30,8747515766028584274],
		[0x11119b38,2323362765625255268],
		[0x11119b40,2893598134626758706],
		[0x11119b48,7234309766870429301],
		[0x11119b50,2893598123004684576],
		[0x11119b58,8747515766028584274],
		[0x11119b60,2891352880348292452],
		[0x11119b68,3611953130089296168],
		[0x11119b70,2965955843865979184],
		[0x11119b78,4480311169313156137],
		[0x11119b80,5917778750106201186],
		[0x11119b88,3201607900681028421],
		[0x11119b90,8606165777051374112],
		[0x11119b98,4847370872072332654],
		[0x11119ba0,32483290449853997],
		[0x11119bc0,4207528773226423330],
		[0x11119bc8,7306097971997729829],
		[0x11119bd0,2334031439603245174],
		[0x11119bd8,2338816402727528289],
		[0x11119be0,8461256706636082786],
		[0x11119be8,7812660274802289696],
		[0x11119bf0,2338042681683288181],
		[0x11119bf8,2318265336218807333],
		[0x11119c00,7955443211268597800],
		[0x11119c08,2317511500817785957],
		[0x11119c10,7223260619297925160],
		[0x11119c18,3611955337699620453],
		[0x11119c20,8442041620150954288],
		[0x11119c28,2334102031740531566],
		[0x11119c30,5920025828778077801],
		[0x11119c38,2987686884021191493],
		[0x11119c40,2329822430775748128],
		[0x11119c48,3251644217937640508],
		[0x11119c50,2891359516067705120],
		[0x11119c58,7308892947874739496],
		[0x11119c60,2891356540817186916],
		[0x11119c68,7308003184461828648],
		[0x11119c70,4485057641359697017],
		[0x11119c78,2891359516068164128],
		[0x11119c80,7308892947874739496],
		[0x11119c88,2891356540817186916],
		[0x11119c90,7308003184461828648],
		[0x11119c98,2316574420780803193],
		[0x11119ca0,2322797617382238248],
		[0x11119ca8,2968189007599054898],
		[0x11119cb0,3261526774175770921],
		[0x11119cb8,5917778767470092606],
		[0x11119cc0,3201899228312716101],
		[0x11119cc8,7308284659438539296],
		[0x11119cd0,4480311169313156206],
		[0x11119cd8,491328010095],
		[0x11119ce0,3198722456695432226],
		[0x11119ce8,2675260698658890789],
		[0x11119cf0,2691780882273957228],
		[0x11119cf8,7020302756571590517],
		[0x11119d00,7812660274634518640],
		[0x11119d08,8319683848551211125],
		[0x11119d10,8028911400106796320],
		[0x11119d18,7216209593502032227],
		[0x11119d20,8317714377132223522],
		[0x11119d28,7955925832297244521],
		[0x11119d30,4847370906359572852],
		[0x11119d38,4476623618090221101],
		[0, 0]
]).
:- use_module(library(clpfd)).

isTrue([X, _]):-
    X == 49.

isTrue([_|Tail]):-
    isTrue(Tail).

log(File_name, Name, Addr, Base):-
    Offset #= Addr - Base,
    open(File_name, append, Stream),
    write(Stream, Name),
    write(Stream, ':'),
    write(Stream, Offset),
    nl(Stream),
    close(Stream).

start_query(Base_addr) :- 
    pointer(Ptr),
    string_val(Str),
    Ptr_profile = ([
        [MM2_addr, MM2_val],
        [Real_parent_addr, Real_parent_val],
        [Cred_addr, Cred_val],
        [FS_struct_addr, FS_struct_val]
    ]),
    Str_profile = ([
        [Comm_addr, Comm_val]    
    ]),
    chain([MM2_addr, Real_parent_addr, Cred_addr, Comm_addr, FS_struct_addr], #<),
    Real_parent_addr #> Comm_addr - 500,
    tuples_in(Ptr_profile, Ptr),
    tuples_in(Str_profile, Str),
    labeling([enum], [Real_parent_addr, Real_parent_val,  Comm_addr, Comm_val]),
    process_create(path('python'),
                ['subquery.py', Real_parent_val, "task_struct"],
                [stdout(pipe(In))]),
    read_string(In, Len, X),
    string_codes(X, Result),
    close(In),
    isTrue(Result).

query_test(Base_addr) :-
    statistics(real_time, [Start|_]),
    get_time(Current),
    %current_predicate(string_val/1),
    pointer(Ptr),
    string_val(Str),
    int(Int),
    Ptr_profile = ([
        [MM_addr, MM_val],
        [MM2_addr, MM2_val],
        [Tasks_addr, Tasks_val],
        [Parent_addr, Parent_val],
        [Real_parent_addr, Real_parent_val],
        [Child_addr, Child_val],
        [Group_leader_addr, Group_leader_val],
        [Thread_group_addr, Thread_group_val],
        [Real_cred_addr, Real_cred_val],
        [Cred_addr, Cred_val]
    ]),
    Str_profile = ([
        [Comm_addr, Comm_val]    
    ]),
    Int_profile = ([
        [Pid_addr, Pid_val],
        [Tgid_addr, Tgid_val]    
    ]),
    chain([Tasks_addr, MM_addr, MM2_addr, Pid_addr, Tgid_addr, Real_parent_addr, Parent_addr , Child_addr, 
           Group_leader_addr, Thread_group_addr, Real_cred_addr, Cred_addr, Comm_addr], #<),
    Tasks_addr #> Base_addr,
    Comm_addr #= Base_addr + 968,
    Tasks_addr #= Base_addr + 544,
    tuples_in(Ptr_profile, Ptr),
    tuples_in(Str_profile, Str),
    tuples_in(Int_profile, Int),
    labeling([enum], [Tasks_addr, Tasks_val, Comm_addr, Comm_val]),
    Comm_offset #= Comm_addr - Base_addr,
    Tasks_offset #= Tasks_addr - Base_addr,
    Tasks_val #> 0,
    query_list_head(Tasks_val, Comm_offset, Tasks_offset).


query_task_struct(Base_addr) :-
    statistics(real_time, [Start|_]),
    get_time(Current),
    current_predicate(string_val/1),
    pointer(Ptr),
    string_val(Str),
    int(Int),
    Ptr_profile = ([
        [MM_addr, MM_val],
        [MM2_addr, MM2_val],
        [Tasks_addr, Tasks_val],
        [Tasks2_addr, Tasks2_val],
        [Parent_addr, Parent_val],
        [Real_parent_addr, Real_parent_val],
        [Child_addr, Child_val],
        [Group_leader_addr, Group_leader_val],
        [Thread_group_addr, Thread_group_val],
        [Real_cred_addr, Real_cred_val],
        [Cred_addr, Cred_val]
    ]),
    Str_profile = ([
        [Comm_addr, Comm_val]    
    ]),
    Int_profile = ([
        [Pid_addr, Pid_val],
        [Tgid_addr, Tgid_val]    
    ]),
    chain([Tasks_addr, Tasks2_addr, MM_addr, MM2_addr, Pid_addr, Tgid_addr, Real_parent_addr, Parent_addr , Child_addr, 
           Group_leader_addr, Thread_group_addr, Real_cred_addr, Cred_addr, Comm_addr], #<),
    %MM2_addr #> Base_addr + 1000,
    MM2_addr #= MM_addr + 8,
    Tasks_addr #> MM2_addr - 100,
    Tasks2_addr #= Tasks_addr + 8,

    Tgid_addr #= Pid_addr + 4,
    Real_parent_addr #< Tgid_addr + 20,
    Real_parent_addr #= Parent_addr - 8,
    Child_addr #= Parent_addr + 8,
    %FIXME This may be too strong
    %Children next and prev 16 
    %Sibling next and prev  16
    Group_leader_addr #=< Child_addr +32,
    Cred_addr #= Real_cred_addr + 8,
    /*MM2_addr #= Base_addr + 1992,
    Comm_addr #= Base_addr + 1656,
    Tasks_addr #= Base_addr + 1904,*/


    tuples_in(Ptr_profile, Ptr),
    tuples_in(Str_profile, Str),
    tuples_in(Int_profile, Int),

    MM2_val #> 0,
    label([MM2_addr, MM2_val]),
    label([MM_addr, MM_val]),
    integer(MM2_val),
    query_mm_struct(MM2_val),
    labeling([enum], [Tasks_addr, Tasks_val, Comm_addr, Comm_val, Pid_addr, Tgid_addr]),

    Comm_offset #= Comm_addr - Base_addr,
    Tasks_offset #= Tasks_addr - Base_addr,
    Tasks_val #> 0,
    query_list_head(Tasks_val, Comm_offset, Tasks_offset),

    labeling([enum], [Tasks2_addr, Tasks2_val]),

    labeling([enum], [Real_parent_addr, Real_parent_val, Group_leader_addr, Group_leader_val, Child_addr, Child_val]),
    Real_parent_val #> 0,
    Group_leader_val #> 0,
    query_ts(Real_parent_val, Comm_offset, Tasks_offset),
    %query_list_head(Child_val-16, Comm_offset, Tasks_offset),
    query_ts(Group_leader_val, Comm_offset, Tasks_offset),

    labeling([enum], [Real_cred_addr, Real_cred_val, Cred_addr, Cred_val]),
    Cred_val #> 0,
    query_cred(Real_cred_val),
    query_cred(Cred_val),


    get_time(Now),
    Time_past is Now - Current,
    statistics(real_time, [End|_]),

    MM_offset #= MM2_addr - Base_addr,
    Real_parent_offset #= Real_parent_addr - Base_addr,
    Group_leader_offset #= Group_leader_addr - Base_addr,
    log("./profile/task_struct", "tasks", Tasks_addr, Base_addr),
    log("./profile/task_struct", "active_mm_struct", MM2_addr, Base_addr),
    log("./profile/task_struct", "comm", Comm_addr, Base_addr),
    log("./profile/task_struct", "parent", Parent_addr, Base_addr),
    log("./profile/task_struct", "group_leader", Group_leader_addr, Base_addr),
    log("./profile/task_struct", "cred", Cred_addr, Base_addr),
    log("./profile/task_struct", "pid", Pid_addr, Base_addr),
    log("./profile/task_struct", "task_struct time", End, Start),

    print_nl('tasks offset', Tasks_offset),
    print_nl('tasks offset', Tasks_val),
    print_nl('mm offset', MM_offset),
    print_nl('comm offset', Comm_offset),
    print_nl('real_parent', Real_parent_offset),
    print_nl('group_leader', Group_leader_offset),
    print_nl("Finished, total time", Time_past).

query_module(Base_addr) :-
    /* struct list_head list;
       char name[LEN]; 
       struct kernel_param *kp;
       struct module_layout core_layout;
       struct module_layout init_layout; 
       unsigned int core_size, init_size;
       unsigned int init_text_size, core_text_size;
    */
    %get_time(Current),
    statistics(real_time, [Start|_]),
    pointer(Ptr),
    string_val(Str),
    int(Int),
    /* Type Invariants */
    Ptr_profile = ([
        [List_addr, List_val],
        [KP_addr, KP_val],
        [Core_base_addr, Core_base_val]
    ]),
    Str_profile = ([
        [Name_addr, Name_val]    
    ]),
    Int_profile = ([
        [Core_size_addr, Core_size_val],
        [Core_text_size_addr, Core_text_size_val],
        [RO_size_addr, RO_size_val],
        [RO_init_size_addr, RO_init_size_val]
    ]),    
    
    tuples_in(Ptr_profile, Ptr),
    tuples_in(Str_profile, Str),
    tuples_in(Int_profile, Int),
    /* Order Invariants */
    chain([List_addr, Name_addr, KP_addr, Core_base_addr, Core_size_addr, 
            Core_text_size_addr, RO_size_addr, RO_init_size_addr], #<),
    RO_init_size_addr - Base_addr #< 1000,
    
    labeling([enum], [Name_addr, Name_val]),
    List_addr #= Name_addr - 16,
    labeling([enum], [List_addr, List_val]),
    Name_offset #= Name_addr - Base_addr,
    List_offset #= List_addr - Base_addr,
    query_list_head(List_val, Name_offset, List_offset),
    KP_val #> 0,
    labeling([enum], [KP_addr, KP_val]),
    query_kernel_param(KP_val),
    Core_size_addr #= Core_base_addr + 8,
    Core_size_val #> 0,
    Core_text_size_addr #= Core_size_addr + 4,
    Core_text_size_val #> 0,
    RO_size_addr #= Core_text_size_addr + 4,
    RO_init_size_addr #= RO_size_addr + 4,

    labeling([enum], [Core_base_addr, Core_size_addr, 
            Core_text_size_addr, RO_size_addr, RO_init_size_addr]),

    %get_time(End),
    statistics(real_time, [End|_]),
    %Time_past is End - Current,
    log("./profile/module", "list", List_addr, Base_addr),
    log("./profile/module", "name", Name_addr, Base_addr),
    log("./profile/module", "kp", KP_addr, Base_addr),
    log("./profile/module", "core_base", Core_base_addr, Base_addr),
    log("./profile/module", "core_size", Core_size_addr, Base_addr),
    log("./profile/module", "core_text_size", Core_text_size_addr, Base_addr),
    log("./profile/module", "module time", End, Start).
    %print_nl("Finished, total time", Time_past).

query_mount_hash(Base_addr) :-
    statistics(real_time, [Start|_]),
    pointer(Ptr),
    Ptr_profile = ([
        [Mount_addr, Mount_val]
    ]),
    tuples_in(Ptr_profile, Ptr),
    Mount_addr #< Base_addr + 250,
    Mount_val #> 0,
    labeling([enum], [Mount_addr, Mount_val]),
    query_mount(Mount_val),
    statistics(real_time, [End|_]),
    log("./profile/mount_hash", "mount", Mount_addr, Base_addr),
    log("./profile/mount_hash", "mount_hash time", End, Start).

query_net_device(Base_addr) :- 
    /*
        char             name[NAMSIZ];
        struct list_head dev_list;
        unsigned char    addr_len;
        unsigned int     promiscuity;
        struct in_device *ip_ptr;
    */
    statistics(real_time, [Start|_]),
    %get_time(Current),
    pointer(Ptr),
    string_val(Str),
    int(Int),
    /* Type Invariants */
    Ptr_profile = ([
        [Dev_list_addr, Dev_list_val],
        [IP_ptr_addr, IP_ptr_val]
    ]),
    Str_profile = ([
        [Name_addr, Name_val]
    ]),
    Int_profile = ([
        [Promisc_addr, Promisc_val],
        [Addr_len_addr, Addr_len_val]
    ]),    
    
    tuples_in(Ptr_profile, Ptr),
    tuples_in(Str_profile, Str),
    tuples_in(Int_profile, Int),
    /* Hard to determine offsets for addr_len and promisc */
    chain([Name_addr, Dev_list_addr, Addr_len_addr, Promisc_addr, IP_ptr_addr], #<),
    Name_addr #>= Base_addr,
    Name_offset #= Name_addr - Base_addr,
    IP_ptr_addr #< Base_addr + 1000,
    /* dev_list offset can be hardcoded since it remains the same */
    Dev_list_addr #= Base_addr + 80,
    labeling([enum], [Name_addr, Dev_list_addr, Dev_list_val]),
    /* do not have a good constrain to narrow down ip_ptr, use its rough offset
       to reduce the search space. 
     */
    IP_ptr_addr #> Base_addr + 700,
    IP_ptr_val #> 0,
    labeling([enum], [IP_ptr_addr, IP_ptr_val]),
    query_in_device(IP_ptr_val),

    %get_time(End),
    %Time_past is End - Current,
    statistics(real_time, [End|_]),

    log("./profile/net_device", "name", Name_addr, Base_addr),
    log("./profile/net_device", "ip_ptr", IP_ptr_addr, Base_addr),
    log("./profile/net_device", "dev_list", Dev_list_addr, Base_addr),
    log("./profile/net_device", "net_device time", End, Start).


query_inet_sock(Base_addr) :-
    /* As defined in source code, sk and pinet6 has to be 
       the first two members of inet_sock, which means we
       can hardcode this rule.
    */
    /*skc_family at offset 16 short contained in a unsigned number 
     First half of sock_common can be viewed as unchanged, so it's safe to use
       some hardcoded ruels to help pinpoint some offsets.  
    sk_buff_head, two non-zero pointers, one unsigned long, one integer.
    sk_protocol is a unsigned long number after sk_write_buffer, and they have the same offset. */
    %get_time(Current),
    statistics(real_time, [Start|_]),
    pointer(Ptr),
    long(Ulg),
    int(Int),
    /* Type Invariants */
    Ptr_profile = ([
        [Sk_receive_queue_addr, Sk_receive_queue_val],
        [Sk_receive_queue_prev_addr, Sk_receive_queue_prev_val],
        [Sk_send_head_addr, Sk_send_head_val],
        [Sk_write_queue_addr, Sk_write_queue_val],
        [Sk_write_queue_prev_addr, Sk_write_queue_prev_val]
    ]),
    Ulong_profile = ([
        [Skc_family_addr, Skc_family_val],
        [Sk_protocol_addr, Sk_protocol_val]
    ]),
    Int_profile = ([
        [Sk_rcvlowat_addr, Sk_rcvlowat_val],
        [Receive_lock_addr, Receive_lock_val],
        [Write_lock_addr, Write_lock_val],
        [Qlen_receive_addr, Qlen_receive_val],
        [Qlen_write_addr, Qlen_write_val]
    ]),    
    
    tuples_in(Ptr_profile, Ptr),
    tuples_in(Ulong_profile, Ulg),
    tuples_in(Int_profile, Int),

    Sk_protocol_val #> 0,
    Skc_family_addr #= Base_addr + 16,
    Skc_family_val #> 0,
    Sk_receive_queue_val #> 0,
    Sk_receive_queue_prev_val #> 0,
    Sk_write_queue_val #> 0,
    Sk_write_queue_prev_val #> 0,
    chain([Skc_family_addr, Sk_rcvlowat_addr, Sk_receive_queue_addr, Sk_receive_queue_prev_addr, Qlen_receive_addr, Receive_lock_addr,
          Sk_send_head_addr, Sk_write_queue_addr, Sk_write_queue_prev_addr, Qlen_write_addr, Write_lock_addr,
          Sk_protocol_addr], #<),
    /* sock_common is at least 136 */
    Sk_receive_queue_addr #> Base_addr + 136,
    Sk_receive_queue_addr #=< Sk_rcvlowat_addr + 28,
    Sk_protocol_addr #= Sk_write_queue_addr + 160,
    Sk_protocol_addr #< Base_addr + 700,
    Sk_receive_queue_prev_addr #= Sk_receive_queue_addr + 8,
    Qlen_receive_addr #= Sk_receive_queue_prev_addr + 8,
    Receive_lock_addr #= Qlen_receive_addr + 4,
    Sk_write_queue_addr #= Sk_send_head_addr + 8,
    Sk_write_queue_prev_addr #= Sk_write_queue_addr + 8,
    Qlen_write_addr #= Sk_write_queue_prev_addr + 8,
    Write_lock_addr #= Qlen_write_addr + 4,

    labeling([enum], [Skc_family_addr, Sk_receive_queue_addr, Sk_write_queue_addr, Sk_protocol_addr]),

    %get_time(End),
    %Time_past is End - Current,
    statistics(real_time, [End|_]),


    log("./profile/inet_sock", "sk_receive_queue", Sk_receive_queue_addr, Base_addr),
    log("./profile/inet_sock", "Sk_write_queue", Sk_write_queue_addr, Base_addr),
    log("./profile/inet_sock", "Skc_family", Skc_family_addr, Base_addr),
    log("./profile/inet_sock", "Sk_protocol", Sk_protocol_addr, Base_addr),
    log("./profile/inet_sock", "inet_sock time", End, Start).

query_resource(Base_addr) :-
    /*
        start
        end
        *name
        *parent
        *sibling
        *child -> non-zero
    */
    /* This structure remains unchanged, thus we can have some
       hardcoded rules to help inference. */

    statistics(real_time, [Start|_]),
    pointer(Ptr),
    long(Ulg),
    int(Int),
    /* Type Invariants */
    Ptr_profile = ([
        [Name_addr, Name_val],
        [Parent_addr, Parent_val],
        [Sibling_addr, Sibling_val],
        [Child_addr, Child_val]
    ]),
    Ulong_profile = ([
        [End_addr, End_val],
        [Flags_addr, Flags_val]
    ]),
    Int_profile = ([
        [Start_addr, Start_val]
    ]),    
    
    tuples_in(Ptr_profile, Ptr),
    tuples_in(Ulong_profile, Ulg),
    tuples_in(Int_profile, Int),

    Child_val #> 0,
    Start_addr #>= Base_addr,
    chain([Start_addr, End_addr, Name_addr, Flags_addr, Parent_addr, Sibling_addr, Child_addr], #<),
    %Name_addr #= Base_addr + 16,
    Child_addr #=< Base_addr + 64,
    labeling([enum], [Start_addr, End_addr, Name_addr, Name_val]),
    query_string_pointer(Name_val),
    Name_offset #= Name_addr - Base_addr,
    labeling([enum], [Child_addr, Child_val]),
    query_name_pointer(Child_val, Name_offset),

    statistics(real_time, [End|_]),


    log("./profile/resource", "Start_addr", Start_addr, Base_addr),
    log("./profile/resource", "End_addr", End_addr, Base_addr),
    log("./profile/resource", "Name_addr", Name_addr, Base_addr),
    log("./profile/resource", "Child_addr", Child_addr, Base_addr),
    log("./profile/resource", "resource time", End, Start).

query_neigh_tables(Base_addr) :-
    statistics(real_time, [Start|_]),
    pointer(Ptr),
    Ptr_profile = ([
        [Neigh_table_addr, Neigh_table_val]
    ]),
    tuples_in(Ptr_profile, Ptr),
    Neigh_table_addr #=< Base_addr + 32,
    labeling([enum], [Neigh_table_addr, Neigh_table_val]),
    query_neigh_table(Neigh_table_val),

    statistics(real_time, [End|_]),
    log("./profile/neigh_tables", "neigh_table", Neigh_table_addr, Base_addr),
    log("./profile/neigh_tables", "neigh_tables time", End, Start).

query_seq_operations(Base_addr) :-
    statistics(real_time, [Start|_]),
    /* Four successive function pointers */
    pointer(Ptr),
    Ptr_profile = ([
        [Start_addr, Start_val],
        [Stop_addr, Stop_val],
        [Next_addr, Next_val],
        [Show_addr, Show_val]
    ]),
    tuples_in(Ptr_profile, Ptr),
    chain([Start_addr, Stop_addr, Next_addr, Show_addr], #<),
    Start_addr #= Base_addr,
    Show_addr #= Base_addr + 24,
    Start_val #> 0,
    Stop_val #> 0,
    Next_val #> 0,
    Show_val #> 0,
    statistics(real_time, [End|_]),
    log("./profile/seq_operations", "seq_operations time", End, Start).


query_tcp_seq_afinfo(Base_addr) :-
    statistics(real_time, [Start|_]),

    pointer(Ptr),
    int(Int),
    Ptr_profile = ([
        [Name_addr, Name_val],
        [F_ops_addr, F_ops_val],
        [Ops_addr, Ops_val]
    ]),
    Int_profile = ([
        [Family_addr, Family_val]
    ]),
    tuples_in(Ptr_profile, Ptr),
    tuples_in(Int_profile, Int),
    Name_addr #= Base_addr,
    Ops_addr #= Base_addr + 24,
    chain([Name_addr, Family_addr, F_ops_addr, Ops_addr], #<),
    
    labeling([enum], [Name_addr, Name_val]),
    query_string_pointer(Name_val),
    statistics(real_time, [End|_]),
    log("./profile/tcp_seq_afinfo", "tcp_seq_afinfo time", End, Start).

query_udp_seq_afinfo(Base_addr) :-
    statistics(real_time, [Start|_]),

    pointer(Ptr),
    int(Int),
    Ptr_profile = ([
        [Name_addr, Name_val],
        [Udp_table_addr, Udp_table_val],
        [F_ops_addr, F_ops_val],
        [Ops_addr, Ops_val]
    ]),
    Int_profile = ([
        [Family_addr, Family_val]
    ]),
    tuples_in(Ptr_profile, Ptr),
    tuples_in(Int_profile, Int),
    Name_addr #= Base_addr,
    Ops_addr #= Base_addr + 32,
    chain([Name_addr, Family_addr, Udp_table_addr, F_ops_addr, Ops_addr], #<),
    
    labeling([enum], [Name_addr, Name_val]),
    query_string_pointer(Name_val),
    statistics(real_time, [End|_]),
    log("./profile/udp_seq_afinfo", "udp_seq_afinfo time", End, Start).

query_tty_driver(Base_addr) :-
    statistics(real_time, [Start|_]),

    /* tty_driver remains unchanged, some rules are hardcoded. */
    pointer(Ptr),
    int(Int),
    Ptr_profile = ([
        [Driver_name_addr, Driver_name_val],
        [Name_addr, Name_val],
        [Ttys_addr, Ttys_val],
        [Tty_drivers_addr, Tty_drivers_val]
    ]),
    Int_profile = ([
        [Magic_addr, Magic_val],
        [Kref_addr, Kref_val],
        [Name_base_addr, Name_base_val],
        [Major_addr, Major_val],
        [Minor_start_addr, Minor_start_val],
        [Num_addr, Num_val]
    ]),
    tuples_in(Ptr_profile, Ptr),
    tuples_in(Int_profile, Int),
    Magic_addr #= Base_addr,
    Kref_addr #= Magic_addr + 4,
    Num_addr #= Name_base + 12,
    Ttys_addr #= Base_addr + 128,
    Tty_drivers_addr #= Base_addr + 168,
    chain([Magic_addr, Kref_addr, Driver_name_addr, Name_addr, Name_base_addr, Major_addr, Minor_start_addr,
            Num_addr, Ttys_addr, Tty_drivers_addr], #<),
    labeling([enum], [Driver_name_addr, Driver_name_val, Name_addr, Name_val]),
    query_string_pointer(Driver_name_val),
    query_string_pointer(Name_val),
    statistics(real_time, [End|_]),
    log("./profile/tty_driver", "tty_driver time", End, Start).

query_proc_dir_entry(Base_addr) :-
    statistics(real_time, [Start|_]),

    pointer(Ptr),
    int(Int),
    long(Ulg),
    Ptr_profile = ([
        [Proc_iops_addr, Proc_iops_val],
        [Proc_fops_addr, Proc_fops_val]
    ]),
    Int_profile = ([
        [Low_ino_addr, Low_ino_val],
        [Mode_addr, Mode_val],
        [Nlink_addr, Nlink_val],
        [Uid_addr, Uid_val],
        [Gid_addr, Gid_val]
    ]),

    tuples_in(Ptr_profile, Ptr),
    tuples_in(Int_profile, Int),
    Low_ino_addr #= Base_addr,
    Gid_addr #= Low_ino_addr + 16,
    Proc_fops_addr #= Proc_iops_addr + 8,
    Proc_fops_addr #=< Base_addr + 40,
    chain([Low_ino_addr, Mode_addr, Nlink_addr, Uid_addr, Gid_addr, Proc_iops_addr, Proc_fops_addr], #<),
    labeling([enum], [Proc_iops_addr, Proc_iops_val, Proc_fops_addr, Proc_fops_val]),
    Proc_fops_val #> 0,
    %Proc_iops_val #> 0,
    %query_inode_operations(Proc_iops_val),
    query_inode_operations(Proc_fops_val),
    statistics(real_time, [End|_]),
    log("./profile/proc_dir_entry", "proc_dir_entry time", End, Start).

query_kset(Base_addr) :-
    /* skip */
    1 #= 1.



test(Base_addr) :-
    get_time(Current),
    current_predicate(string_val/1),
    pointer(Ptr),
    string_val(Str),
    int(Int),
    Ptr_profile = ([
        [MM2_addr, MM2_val],
        [Tasks_addr, Tasks_val],
        [Parent_addr, Parent_val],
        [Real_parent_addr, Real_parent_val],
        [Child_addr, Child_val],
        [Group_leader_addr, Group_leader_val],
        [Thread_group_addr, Thread_group_val],
        [Cred_addr, Cred_val],
        [FS_struct_addr, FS_struct_val]
    ]),
    Str_profile = ([
        [Comm_addr, Comm_val]    
    ]),
    Int_profile = ([
        [Pid_addr, Pid_val],
        [Tgid_addr, Tgid_val]    
    ]),
    chain([Tasks_addr, MM2_addr, Pid_addr, Tgid_addr, Parent_addr, Real_parent_addr, Child_addr, 
           Group_leader_addr, Thread_group_addr, Cred_addr, Comm_addr, FS_struct_addr], #<),
    MM2_addr #> Base_addr + 1000,
    Tasks_addr #> MM2_addr - 100,
    FS_struct_addr #< Base_addr + 3000,
    Tgid_addr #= Pid_addr + 4,
    Parent_addr #< Tgid_addr + 20,
    Real_parent_addr #= Parent_addr + 8,
    Child_addr #= Real_parent_addr +8,
    Group_leader_addr #=< Child_addr +32,
    %Comm_addr #= Base_addr + 2584,
    %Tasks_addr #= Base_addr + 1904,
    %FS_struct_addr #= Base_addr + 2640,


    tuples_in(Ptr_profile, Ptr),
    tuples_in(Str_profile, Str),
    tuples_in(Int_profile, Int),

    label([MM2_addr, MM2_val]),
    % make query after labeling
    MM2_val #> 0,
    query_mm_struct(MM2_val),
    labeling([enum], [Tasks_addr, Tasks_val,  Comm_addr, Comm_val ]),
    %Tasks_addr #= Base_addr + 2040,
    Comm_offset #= Comm_addr - Base_addr,
    Tasks_offset #= Tasks_addr - Base_addr,
    Tasks_val #> 0,
    query_list_head(Tasks_val, Comm_offset, Tasks_offset),

    


    get_time(End),
    Time_past is End - Current,
    MM_offset #= MM2_addr - Base_addr,
    Real_parent_offset #= Real_parent_addr - Base_addr,
    Group_leader_offset #= Group_leader_addr - Base_addr,
    
    print_nl('tasks offset', Tasks_offset),
    print_nl('mm offset', MM_offset),
    print_nl('comm offset', Comm_offset),
    print_nl('real_parent', Real_parent_offset),
    print_nl('group_leader', Group_leader_offset),
    print_nl("Finished, total time", Time_past).

query_neigh_table(Base_addr) :-
    process_create(path('python'),
                    ['subquery.py', Base_addr, "neigh_table"],
                    [stdout(pipe(In))]),
    read_string(In, Len, X),
    string_codes(X, Result),
    close(In),
    isTrue(Result).

query_string_pointer(Val) :- 
    process_create(path('python'),
                    ['subquery.py', Val, "string_pointer"],
                    [stdout(pipe(In))]),
    read_string(In, Len, X),
    string_codes(X, Result),
    close(In),
    isTrue(Result).

query_name_pointer(Val, Name_offset) :-
    process_create(path('python'),
                    ['subquery.py', Val, "name_pointer", Name_offset],
                    [stdout(pipe(In))]),
    read_string(In, Len, X),
    string_codes(X, Result),
    close(In),
    isTrue(Result).

query_mount(Base_addr) :- 
    process_create(path('python'),
                    ['subquery.py', Base_addr, "mount"],
                    [stdout(pipe(In))]),
    read_string(In, Len, X),
    string_codes(X, Result),
    close(In),
    isTrue(Result).

query_mount_struct(Val, Offset) :- 
    process_create(path('python'),
                    ['subquery.py', Val, "mount_struct", Offset],
                    [stdout(pipe(In))]),
    read_string(In, Len, X),
    string_codes(X, Result),
    close(In),
    isTrue(Result).

query_vfs_mount(Vfsmount_val) :-
    process_create(path('python'),
                    ['subquery.py', Vfsmount_val, "vfs_mount"],
                    [stdout(pipe(In))]),
    read_string(In, Len, X),
    string_codes(X, Result),
    close(In),
    isTrue(Result).

query_dentry(Dentry_val) :-
    process_create(path('python'),
                    ['subquery.py', Dentry_val, "dentry"],
                    [stdout(pipe(In))]),
    read_string(In, Len, X),
    string_codes(X, Result),
    close(In),
    isTrue(Result).

query_kernel_param(KP_val) :-
    process_create(path('python'),
                    ['subquery.py', KP_val, "kernel_param"],
                    [stdout(pipe(In))]),
    read_string(In, Len, X),
    string_codes(X, Result),
    close(In),
    isTrue(Result).

query_in_device(IP_ptr_val) :-
    process_create(path('python'),
                    ['subquery.py', IP_ptr_val, "in_device"],
                    [stdout(pipe(In))]),
    read_string(In, Len, X),
    string_codes(X, Result),
    close(In),
    isTrue(Result).

query_inode_operations(Base_addr) :-
    process_create(path('python'),
                    ['subquery.py', Base_addr, "inode_operations"],
                    [stdout(pipe(In))]),
    read_string(In, Len, X),
    string_codes(X, Result),
    close(In),
    isTrue(Result).

query_mm_struct(MM2_val) :-
    process_create(path('python'),
                    ['subquery.py', MM2_val, "mm_struct"],
                    [stdout(pipe(In))]),
    read_string(In, Len, X),
    string_codes(X, Result),
    close(In),
    isTrue(Result).

query_list_head(Tasks_val, Comm_offset, Tasks_offset) :-
    process_create(path('python'),
                    ['subquery.py', Tasks_val, "list_head", Comm_offset, Tasks_offset],
                    [stdout(pipe(In))]),
    read_string(In, Len, X),
    string_codes(X, Result),
    close(In),
    isTrue(Result).

query_tasks(Tasks_val, Comm_offset, Tasks_offset) :-
    process_create(path('python'),
                    ['subquery.py', Tasks_val, "tasks", Comm_offset, Tasks_offset],
                    [stdout(pipe(In))]),
    read_string(In, Len, X),
    string_codes(X, Result),
    close(In),
    isTrue(Result).

query_child(Child_val, Comm_offset, Child_offset) :-
    process_create(path('python'),
                    ['subquery.py', Child_val, "child", Comm_offset, Child_offset],
                    [stdout(pipe(In))]),
    read_string(In, Len, X),
    string_codes(X, Result),
    close(In),
    isTrue(Result).

query_ts(Base_addr, Comm_offset, Tasks_offset) :-
    process_create(path('python'),
                    ['subquery.py', Base_addr, "ts", Comm_offset, Tasks_offset],
                    [stdout(pipe(In))]),
    read_string(In, Len, X),
    string_codes(X, Result),
    close(In),
    isTrue(Result).

query_cred(Base_addr) :-
    process_create(path('python'),
                    ['subquery.py', Base_addr, "cred"],
                    [stdout(pipe(In))]),
    read_string(In, Len, X),
    string_codes(X, Result),
    close(In),
    isTrue(Result).
query_fs_struct(Base_addr) :-
    process_create(path('python'),
                    ['subquery.py', Base_addr, "fs_struct"],
                    [stdout(pipe(In))]),
    read_string(In, Len, X),
    string_codes(X, Result),
    close(In),
    isTrue(Result).

print_nl(Name, Content):- 
    print(Name),
    print(':'),
    print(Content),
    nl.
