def ref(items, n):
    return (head(items) if n == 0
            else ref(tail(items), n - 1))
def make_vect(x, y):
    return pair(x, y)
def xcor_vect(vector):
    return head(vector)
def ycor_vect(vector):
    return tail(vector)
def scale_vect(factor, vector):
    return make_vect(factor * xcor_vect(vector), 
                     factor * ycor_vect(vector))
def add_vect(vector1, vector2):
    return make_vect(xcor_vect(vector1)  
                     + xcor_vect(vector2), 
                     ycor_vect(vector1)  
                     + ycor_vect(vector2))
def sub_vect(vector1, vector2):
    return make_vect(xcor_vect(vector1)  
                     - xcor_vect(vector2), 
                     ycor_vect(vector1)  
                     - ycor_vect(vector2))
def make_frame(origin, edge1, edge2):
    return llist(origin, edge1, edge2)
def origin_frame(frame):
    return ref(frame, 0)
def edge1_frame(frame):
    return ref(frame, 1)
def edge2_frame(frame):
    return ref(frame, 2)
def frame_coord_map(frame):
    return lambda v: add_vect(origin_frame(frame), 
                         add_vect(scale_vect(xcor_vect(v), 
                                             edge1_frame(frame)), 
                                  scale_vect(ycor_vect(v), 
                                             edge2_frame(frame))))

my_origin = make_vect(1, 2)
my_edge_1 = make_vect(3, 4)
my_edge_2 = make_vect(5, 6)
my_frame = make_frame(my_origin, my_edge_1, my_edge_2)
my_coord_map = frame_coord_map(my_frame)
my_vector = make_vect(1, 2)
my_mapped_vector = my_coord_map(my_vector)
print(my_mapped_vector)

# expected: [ 14, 18 ]
