diff --git a/demo/tacas2023/exp11/decision_logic/inc-expr-switch-2.py b/demo/tacas2023/exp11/decision_logic/inc-expr-switch-2.py
new file mode 100644
index 0000000000000000000000000000000000000000..138e0442e306efa30b18436506affac1e2ae20f7
--- /dev/null
+++ b/demo/tacas2023/exp11/decision_logic/inc-expr-switch-2.py
@@ -0,0 +1,71 @@
+from enum import Enum, auto
+import copy
+from typing import List
+
+class LaneObjectMode(Enum):
+    Vehicle = auto()
+    Ped = auto()        # Pedestrians
+    Sign = auto()       # Signs, stop signs, merge, yield etc.
+    Signal = auto()     # Traffic lights
+    Obstacle = auto()   # Static (to road/lane) obstacles
+
+class AgentMode(Enum):
+    Normal = auto()
+    SwitchLeft = auto()
+    SwitchLeft2 = auto()
+    SwitchRight = auto()
+    SwitchRight2 = auto()
+    Brake = auto()
+    Stop = auto()
+
+class TrackMode(Enum):
+    T0 = auto()
+    T1 = auto()
+    T2 = auto()
+    T3 = auto()
+    T4 = auto()
+
+class State:
+    x = 0.0
+    y = 0.0
+    theta = 0.0
+    v = 0.0
+    agent_mode: AgentMode = AgentMode.Normal
+    track_mode: TrackMode = TrackMode.T0
+    type: LaneObjectMode = LaneObjectMode.Vehicle
+
+def car_ahead(ego, others, track, track_map, thresh_far, thresh_close):
+    return any((thresh_far > track_map.get_longitudinal_position(other.track_mode, [other.x,other.y]) - track_map.get_longitudinal_position(ego.track_mode, [ego.x,ego.y]) > thresh_close \
+            and other.track_mode == track) for other in others)
+
+def decisionLogic(ego:State, others:List[State], track_map):
+    output = copy.deepcopy(ego)
+    if ego.agent_mode == AgentMode.Normal:
+        left_lane = track_map.h(ego.track_mode, ego.agent_mode, AgentMode.SwitchLeft)
+        left2_lane = track_map.h(ego.track_mode, ego.agent_mode, AgentMode.SwitchLeft2)
+        right_lane = track_map.h(ego.track_mode, ego.agent_mode, AgentMode.SwitchRight)
+        right2_lane = track_map.h(ego.track_mode, ego.agent_mode, AgentMode.SwitchRight2)
+        if car_ahead(ego, others, ego.track_mode, track_map, 5, 3):
+            # Switch left if left lane is empty
+            if left_lane != None and not car_ahead(ego, others, left_lane, track_map, 8, -3):
+                output.agent_mode = AgentMode.SwitchLeft
+                output.track_mode = left_lane
+            if left2_lane != None and not car_ahead(ego, others, left2_lane, track_map, 8, -3):
+                output.agent_mode = AgentMode.SwitchLeft2
+                output.track_mode = left2_lane
+            if right_lane != None and not car_ahead(ego, others, right_lane, track_map, 8, -3):
+                output.agent_mode = AgentMode.SwitchRight
+                output.track_mode = right_lane
+            if right2_lane != None and not car_ahead(ego, others, right2_lane, track_map, 8, -3):
+                output.agent_mode = AgentMode.SwitchRight2
+                output.track_mode = right2_lane
+    else:   # If switched enough, return to normal mode
+        lat = track_map.get_lateral_distance(ego.track_mode, [ego.x, ego.y])
+        lane_width = track_map.get_lane_width(ego.track_mode)
+        if ego.agent_mode == AgentMode.SwitchLeft and lat >= (lane_width-0.2) \
+                or ego.agent_mode == AgentMode.SwitchLeft2 and lat >= (lane_width * 2-0.2) \
+                or ego.agent_mode == AgentMode.SwitchRight and lat <= -(lane_width -0.2) \
+                or ego.agent_mode == AgentMode.SwitchRight2 and lat <= -(lane_width * 2-0.2):
+            output.agent_mode = AgentMode.Normal
+            output.track_mode = track_map.h(ego.track_mode, ego.agent_mode, AgentMode.Normal)
+    return output
diff --git a/demo/tacas2023/exp11/inc-expr-switch-2.py b/demo/tacas2023/exp11/inc-expr-switch-2.py
new file mode 100644
index 0000000000000000000000000000000000000000..dc38405f155e0c2bad4260cc4d364de4089d7790
--- /dev/null
+++ b/demo/tacas2023/exp11/inc-expr-switch-2.py
@@ -0,0 +1,127 @@
+from verse.agents.example_agent import CarAgentSwitch2, NPCAgent
+from verse.map.example_map import SimpleMap4Switch2
+
+from enum import Enum, auto
+from verse.plotter.plotter2D import reachtube_tree
+from verse.scenario.scenario import Benchmark
+import functools, pprint
+pp = functools.partial(pprint.pprint, compact=True, width=130)
+from typing import List
+
+class AgentMode(Enum):
+    Normal = auto()
+    SwitchLeft = auto()
+    SwitchLeft2 = auto()
+    SwitchRight = auto()
+    SwitchRight2 = auto()
+    Brake = auto()
+    Stop = auto()
+
+class LaneObjectMode(Enum):
+    Vehicle = auto()
+    Ped = auto()        # Pedestrians
+    Sign = auto()       # Signs, stop signs, merge, yield etc.
+    Signal = auto()     # Traffic lights
+    Obstacle = auto()   # Static (to road/lane) obstacles
+
+class TrackMode(Enum):
+    T0 = auto()
+    T1 = auto()
+    T2 = auto()
+    T3 = auto()
+    T4 = auto()
+
+def jerk(l: List[List[float]], x=0, y=0):
+    return [[l[0][0] - x, l[0][1] - y, *l[0][2:]], [l[1][0] + x, l[1][1] + y, *l[1][2:]]]
+
+def jerks(ls: List[List[List[float]]], js: List[List[float]]):
+    return [jerk(l, *j) for l, j in zip(ls, js)]
+
+def dupi(l: List[List[float]]):
+    return [[i, i] for i in l]
+
+def run(meas=False):
+    if bench.config.sim:
+        bench.scenario.simulator.cache_hits = (0, 0)
+    else:
+        bench.scenario.verifier.tube_cache_hits = (0,0)
+        bench.scenario.verifier.trans_cache_hits = (0,0)
+    traces = bench.run(60, 0.1)
+
+    if bench.config.dump:
+        traces.dump_tree()
+        traces.dump("main.json") 
+        traces.dump("tree2.json" if meas else "tree1.json") 
+
+    if bench.config.plot and meas:
+        fig = go.Figure()
+        if bench.config.sim:
+            fig = simulation_tree(traces, bench.scenario.map, fig, 1, 2, print_dim_list=[1, 2])
+        else:
+            fig = reachtube_tree(traces, bench.scenario.map, fig, 1, 2, [1, 2], 'lines',combine_rect=5)
+        fig.show()
+
+    if meas:
+        bench.report()
+
+if __name__ == "__main__":
+    import sys
+    bench = Benchmark(sys.argv)
+    input_code_name = './demo/tacas2023/exp11/decision_logic/inc-expr-switch-2.py'
+
+    if bench.config.plot:
+        import plotly.graph_objects as go
+        from verse.plotter.plotter2D import simulation_tree
+
+    smarts = [1, 3, 8]
+    for i in range(8):
+        id = i + 1
+        if id in smarts:
+            bench.scenario.add_agent(CarAgentSwitch2(f"car{id}", file_name=input_code_name))
+        else:
+            bench.scenario.add_agent(NPCAgent(f"car{id}"))
+    tmp_map = SimpleMap4Switch2()
+    bench.scenario.set_map(tmp_map)
+    mode_inits = ([
+            (AgentMode.Normal, TrackMode.T1), (AgentMode.Normal, TrackMode.T1),
+            (AgentMode.Normal, TrackMode.T0), (AgentMode.Normal, TrackMode.T0),
+            (AgentMode.Normal, TrackMode.T1), (AgentMode.Normal, TrackMode.T2),
+            (AgentMode.Normal, TrackMode.T2), (AgentMode.Normal, TrackMode.T2),
+        ],
+        [(LaneObjectMode.Vehicle,) for _ in range(8)])
+
+    poses = [
+        [0, 0, 0, 1.0], [10, 0, 0, 0.5],
+        [14, 3, 0, 0.6], [20, 3, 0, 0.5],
+        [30, 0, 0, 0.5], [28.5, -3, 0, 0.5],
+        [39.5, -3, 0, 0.5], [30, -3, 0, 0.6],
+    ]
+    _jerks = [[0, 0.05] if i + 1 in smarts else [] for i in range(8)]
+    cont_inits = dupi(poses)
+    if not bench.config.sim:
+        cont_inits = jerks(cont_inits, _jerks)
+    bench.scenario.set_init(cont_inits, *mode_inits)
+
+    args = bench.config.args
+
+    if 'b' in args:
+        run(True)
+    elif 'r' in args:
+        run()
+        run(True)
+    elif 'n' in args:
+        run()
+        poses[6][0] = 50
+        cont_inits = dupi(poses)
+        if not bench.config.sim:
+            cont_inits = jerks(cont_inits, _jerks)
+        bench.scenario.set_init(cont_inits, *mode_inits)
+        run(True)
+    elif '3' in args:
+        run()
+        bench.scenario.agent_dict["car3"] = CarAgentSwitch2('car3', file_name=input_code_name.replace(".py", "-fsw7.py"))
+        run(True)
+    elif '8' in args:
+        run()
+        bench.scenario.agent_dict["car8"] = CarAgentSwitch2('car8', file_name=input_code_name.replace(".py", "-fsw4.py"))
+        run(True)
diff --git a/verse/agents/example_agent/car_agent.py b/verse/agents/example_agent/car_agent.py
index d6a1d04f8aaeb3b4c01aa98b5cdcaf2db4d8544f..619739fcc0d11e92a8fcd4e668ef385ed503c79c 100644
--- a/verse/agents/example_agent/car_agent.py
+++ b/verse/agents/example_agent/car_agent.py
@@ -145,3 +145,37 @@ class WeirdCarAgent(CarAgent):
             return -self.gain, 0
         else:
             return 0, 0
+
+class CarAgentSwitch2(CarAgent):
+    def __init__(self, id, code = None, file_name = None):
+        super().__init__(id, code, file_name)
+
+    def action_handler(self, mode: List[str], state, lane_map:LaneMap)->Tuple[float, float]:
+        x,y,theta,v = state
+        vehicle_mode, vehicle_lane = mode
+        vehicle_pos = np.array([x,y])
+        a = 0
+        lane_width = lane_map.get_lane_width(vehicle_lane) 
+        d = -lane_map.get_lateral_distance(vehicle_lane, vehicle_pos)
+        if vehicle_mode == "Normal" or vehicle_mode == 'Stop':
+            pass
+        elif vehicle_mode == "SwitchLeft":
+            d += lane_width
+        elif vehicle_mode == "SwitchRight":
+            d -= lane_width
+        elif vehicle_mode == "SwitchLeft2":
+            d += lane_width * 2
+        elif vehicle_mode == "SwitchRight2":
+            d -= lane_width * 2
+        elif vehicle_mode == "Brake":
+            a = max(-self.accel, -v)
+        elif vehicle_mode == "Accel":
+            a = min(self.accel, self.speed - v)
+        else:
+            raise ValueError(f'Invalid mode: {vehicle_mode}')
+
+        heading = lane_map.get_lane_heading(vehicle_lane, vehicle_pos)
+        psi = wrap_to_pi(heading - theta)
+        steering = psi + np.arctan2(0.45*d, v)
+        steering = np.clip(steering, -0.61, 0.61)
+        return steering, a  
diff --git a/verse/map/example_map/simple_map2.py b/verse/map/example_map/simple_map2.py
index f7293dbb6a45350478eb7fb9fb0619ba6199d45d..7d7996797e65ad959ba32f3caeeed4f1c23be0dc 100644
--- a/verse/map/example_map/simple_map2.py
+++ b/verse/map/example_map/simple_map2.py
@@ -1,3 +1,4 @@
+from typing import Optional
 from verse.map import LaneMap, LaneSegment, StraightLane, CircularLane, Lane
 
 import numpy as np
@@ -132,6 +133,36 @@ class SimpleMap4(LaneMap):
     def right_lane(self,lane_mode):
         return self.right_dict[lane_mode]
 
+class SimpleMap4Switch2(LaneMap):
+    def __init__(self):
+        super().__init__()
+        self.add_lanes([Lane(f"T{i}", [StraightLane(f"seg{i}", [0, 6 - 3 * i], [100, 6 - 3 * i], 3)]) for i in range(5)])
+
+    def h(self, lane_idx: str, mode_src: str, mode_dest: str) -> Optional[str]:
+        src_sw, dst_sw = mode_src.startswith("Switch"), mode_dest.startswith("Switch")
+        if src_sw:
+            if dst_sw:
+                return None
+            else:
+                return "T" + lane_idx[2]
+        else:
+            if dst_sw:
+                typ = mode_dest[6:]
+                ind = int(lane_idx[1])
+                if typ == "Left" and ind > 0:
+                    new_ind = ind - 1
+                if typ == "Left2" and ind > 1:
+                    new_ind = ind - 2
+                elif typ == "Right" and ind < 4:
+                    new_ind = ind + 1
+                elif typ == "Right2" and ind < 3:
+                    new_ind = ind + 2
+                else:
+                    return None
+                return f"M{ind}{new_ind}"
+            else:
+                return lane_idx
+
 class SimpleMap5(LaneMap):
     def __init__(self):
         super().__init__()