% this is a COMPLETE axiomatization of the nodes % engine_status, sensor_valid, ydot, and ydot_sens, for ALL times. % some bizarre things (bugs?) were also fixed for the initial T=0 cases. % there is a simplified version of fwd_action (as otherwise there was too % many other nodes I had to type in: I think these are enough). % This assumes UNNORMALISED random declarations. To get probabilities, % divide each value by the sum of all values. This is just syntactic sugar. % [of course HUGIN does it because they never convert to probabilities until % the very end - this is the advance they have over % Laurentzin and Spiegalhalter (sp?).] % the engine_status is either OK or is not OK. engine_status(S,0) <- engine_status_init(S). prob engine_status_init(not_ok):1,engine_status_init(ok):999999. engine_status(V1,T+1) <- engine_status(V,T) & status_changes(V,V1,T). prob status_changes(ok,ok,T):999999, status_changes(ok,not_ok,T):1. prob status_changes(not_ok,ok,T):1, status_changes(not_ok,not_ok,T):9. % the (which?) sensor is either valid or invalid. [it is funny that the % sensor validity is independent for each time step] prob sensor_valid(T):1,sensor_invalid(T):9999. % One change we are making is that speeds are numbers to the nearest 10km/h. % this lets us do arithmetic and comparisons on them. [presumably it % was not done originally as there is no arithmetic on domain values in hugin] % ydot(V,T) is true if V is the y-velocity (to nearest 10 kmph) at time T % here is an example of propositional independence we exploit: % ydot only depends on fwd_action if engine_status is OK ydot(V,T) <- engine_status(not_ok,T) & broken_engine_produces(V,T). prob broken_engine_produces(0,T):100000, broken_engine_produces(10,T):10, broken_engine_produces(20,T):1, broken_engine_produces(30,T):1. % if you maintain speed there is a normal change to the next time step ydot(V1,T+1) <- engine_status(ok,T+1) & fwd_action(maintain,T+1) & ydot(V,T) & normal_ch(DV,T) & max(0,V+DV,V1). % if you slow down, then you tend to go at 10 km/h slower % than the normal change ydot(V1,T+1) <- engine_status(ok,T+1) & fwd_action(slower,T+1) & ydot(V,T) & normal_ch(DV,T) & max(0,V+DV-10,V1). % if you speed up, then you tend to go at 10 km/h faster % than the normal change ydot(V1,T+1) <- engine_status(ok,T+1) & fwd_action(faster,T+1) & ydot(V,T) & normal_ch(DV,T) & max(0,V+DV+10,V1). % normal_ch(V,T) means that V is a normal change in y-direction at time T, % modulo the change by the action. % these seem to be a bit strange, but they are essentailly the same as the ones % given. The 10s at the extremes seem to high - but this is what was there! random(X,normal_ch(X,T), [-50: 10, -40: 10, -30: 10, -20: 100, -10: 500, 0 : 1000, 10 : 500, 20 : 100, 30 : 10, 40 : 10, 50 : 10]). % it seems bizzare to me that ydot(V,0) should depend on fwd_action(_,0) % AND IF IT DOES IT SHOULD BE THE OPPOSITE RELATIONSHIP TO THE ONE GIVEN. % IE, I WOULD EXPECT IT TO BE MORE LIKELY THAT SLOW CARS ARE TRYING TO GO % FASTER AND FAST CARS ARE TRYING TO GO SLOWER!!!!!!! ydot(V,0) <- engine_status(ok,0) & expected_velocity(V,0). random(X,expected_velocity(X,0), [0:5, 10:20, 20:40, 30:70, 40:100, 50:100, 60:100, 70:100, 80:100, 90:100, 100:100, 110:50, 120:10, 130:5 ]). % the forward actions are to go slower, maintain speed or go faster: % here I have simplified it so that the forward action is independent % for each time step. - it means axiomatizing much more of the network, % and I am too lazy, even if it is just a mechanical excercise. prob fwd_action(slower,T):10, fwd_action(maintain,T):80, fwd_action(faster):10. % ydot_sens(V,T) means the velocoty sensor has a reading of V at time T. ydot_sens(V,T) <- sensor_invalid(T) & random_reading(V,T). % random_reading(V,T) is true if invalid sensor is producing value V at time T prob random_reading(0,T): 1, random_reading(10,T):1, random_reading(20,T):1, random_reading(30,T):1, random_reading(40,T):1, random_reading(50,T):1, random_reading(60,T):1, random_reading(70,T):1, random_reading(80,T):1, random_reading(90,T):1, random_reading(100,T):1, random_reading(110,T):1, random_reading(120,T):1, random_reading(130,T):1 . ydot_sens(V,T) <- sensor_valid(T) & ydot(V1,T) & sensor_error(E) & V is E+V1. % sensor_error(E,T) is true if valid sensor has error E at time T prob sensor_error(-50,T): 1, sensor_error(-40,T): 1, sensor_error(-30,T): 1, sensor_error(-20,T): 10, sensor_error(-10,T): 100, sensor_error(0,T) : 1000, sensor_error(10,T) : 100, sensor_error(20,T) : 10, sensor_error(30,T) : 1, sensor_error(40,T) : 1, sensor_error(50,T) : 1 . % also: my guess is that this would look more elegant if we made the predicates % in the random sets simpler. you can tell my predicate names - they are % much longer!!!! max(X,Y,YV) <- Y>=X & YV is Y. max(X,Y,XV) <- X>Y & XV is X. % predict ydot(80,0)&ydot(60,0+1). % predict ydot(50,0)&ydot(20,0+1). % predict ydot(50,0)&ydot(20,0+1)&ydot(0,0+1+1). % observe ydot_sens(50,0)&ydot_sens(20,0+1)&ydot_sens(0,0+1+1). % predict ydot(50,0)&ydot(20,0+1)&ydot(0,0+1+1).