
void notpair() {
  printf("not a pair");
  writeln();
  cleanup_();
  return; // return not reached
}

int kar(int x) {
  if (Mpairp(x))
    return Mcar(x);
  else {
    notpair();
    return 0; // return not reached
  }
}

int kdr(int x) {
  if (Mpairp(x))
    return Mcdr(x);
  else {
    notpair();
    return 0; // return not reached
  }
}

int kaar(int x) {
  return kar(kar(x));
}

int kadr(int x) {
  return kar(kdr(x));
}

int kdar(int x) {
  return kdr(kar(x));
}

int kddr(int x) {
  return kdr(kdr(x));
}

int list_tail(int x, int n) {
  int idx;

  for (idx = 1; idx <= n; idx++)
    if (Mpairp(x))
      x = Mcdr(x);
    else
      notpair();
 
  if (Mpairp(x))
    return x;
  else {
    notpair();
    return 0; // return not reached
  }
}

int list_tail_integer(int x, int n) {
  return list_tail(x, get_integer_val(n));
}

int list_ref(int x, int n) {
  int idx;

  for (idx = 1; idx <= n; idx++)
    if (Mpairp(x))
      x = Mcdr(x);
    else
      notpair();
 
  if (Mpairp(x))
    return Mcar(x);
  else {
    notpair();
    return 0; // return not reached
  }
}

int list_ref_integer(int x, int n) {
  return list_ref(x, get_integer_val(n));
}

int brute_list_ref(int x, int n) {
  int idx;

  for (idx = 1; idx <= n; idx++)
    x = Mcdr(x);
  return Mcar(x);
}

int last(int x) {
  if (Mnull(x))
    return 0;
  else {
    while (Mcdr(x))
      x = Mcdr(x);
    return x;
  }
}

int memq_(int x, int y) {
  int processing;
  int ret;
  int car_y;
  processing = 1;
  while (processing) {
    if (y) {
      car_y = kar(y);
      if (eq(x, car_y) == Mtrue) {
        processing = 0;
        ret = y;
      }
      else
        y = Mcdr(y);
    }
    else {
      processing = 0;
      ret = Mfalse;
    }
  }
  return ret;
}

int memv_(int x, int y) {
  int processing;
  int ret;
  int car_y;
  processing = 1;
  while (processing) {
    if (Mpairp(y)) {
      car_y = kar(y);
      if (eqv(x, car_y) == Mtrue) {
        processing = 0;
        ret = y;
      }
      else
        y = Mcdr(y);
    }
    else {
      processing = 0;
      ret = Mfalse;
    }
  }
  return ret;
}

int member_(int x, int y) {
  int processing;
  int ret;
  int car_y;
  processing = 1;
  while (processing) {
    if (Mpairp(y)) {
      car_y = kar(y);
      if (equalp(x, car_y) == Mtrue) {
        processing = 0;
        ret = y;
      }
      else
        y = kdr(y);
    }
    else {
      processing = 0;
      ret = Mfalse;
    }
  }
  return ret;
}

int assq_(int x, int alist) {
  int processing;
  int ret;
  int z;
  int a;

  processing = 1;
  while (processing) {
    if (Mpairp(alist)) {
      z = Mcar(alist);
      a = Mcar(z);
      if (eq(x, a) == Mtrue) {
        processing = 0;
        ret = z;
      }
      else
        alist = Mcdr(alist);
    }
    else {
      processing = 0;
      ret = Mfalse;
    }
  }
  return ret;
}

int assv_(int x, int alist) {
  int processing;
  int ret;
  int z;
  int a;

  processing = 1;
  while (processing) {
    if (Mpairp(alist)) {
      z = Mcar(alist);
      a = Mcar(z);
      if (eqv(x, a) == Mtrue) {
        processing = 0;
        ret = z;
      }
      else
        alist = Mcdr(alist);
    }
    else {
      processing = 0;
      ret = Mfalse;
    }
  }
  return ret;
}
