}
@Override
public Expression substitute(IPersistentMap bindings) {
int i=0;
Expression nxv=null;
Expression nxk=null;
for (;i<length; i++) {
Expression k=keys.get(i);
nxk=k.substitute(bindings);
Expression x=vals.get(i);
nxv=x.substitute(bindings);
if (nxk==null) return null;
if (nxk!=k) break;
if (nxv==null) return null;
if (nxv!=x) break;
}
if (i==length) return this; // no changes
ArrayList<Expression> alv=new ArrayList<Expression>();
ArrayList<Expression> alk=new ArrayList<Expression>();
for (int j=0; j<i; j++) {
alk.add(keys.get(j));
alv.add(vals.get(j));
}
alk.add(nxk);
alv.add(nxv);
for (;i<length; i++) {
Expression k=keys.get(i);
nxk=k.substitute(bindings);
if (nxk==null) return null;
alk.add(nxk);
Expression x=vals.get(i);
nxv=x.substitute(bindings);
if (nxv==null) return null;
alv.add(nxv);
}
return create(alk,alv);
}