Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

154
LINES

< > BotCompany Repo | #1000773 // Prolog engine (include)

JavaX fragment (include)

// assumes translator 747

// variable assignments
static class Ass {
  new Map<S, O> map;
  
  void assign(S var, O value) {
    O v = map.get(var);
    if (v == null)
      map.put(var, value);
    else if (!v.equals(value))
      fail("mismatch");
  }
}

static class Pred {
}

static class Assign extends Pred {
  S var;
  O value;
  
  *(S *var, O *value) {}
}

static class And extends Pred {
  new List<Pred> parts;
  
  *(Pred... parts) {
    this.parts = new ArrayList<Pred>(Arrays.asList(parts));
  }
}

static class Or extends Pred {
  new List<Pred> parts;
  
  *(Pred... parts) {
    this.parts = new ArrayList<Pred>(Arrays.asList(parts));
  }
}

static void eval(Pred p, Ass ass) {
  if (p instanceof Assign) {
    Assign a = cast p;
    ass.assign(a.var, a.value);
  } else if (p instanceof And) {
    And a = cast p;
    for (Pred part : a.parts)
      eval(part, ass);
  } else
    fail(structure(p));
}

static void shouldFail(Pred p) {
  try {
    eval(p, new Ass);
    fail("did not fail");
  } catch (RuntimeException e) {
    print("OK (expected fail): " + structure(p));
  }
}

static <X> List<X> singleton(X x) {
  new List<X> list;
  list.add(x);
  return list;
}

static abstract class Iter {
  abstract Ass next();
}

static class Singleton extends Iter {
  Ass value;
  
  *(Ass *value) {}
  
  Ass next() {
    if (value != null) {
      Ass v = value; value = null; return v;
    }
    return null;
  }
}

static class OrIterator extends Iter {
  Or o;
  int i;
  
  *(Or *o) {}
  
  public Ass next() {
    if (i >= o.parts.size()) return null;
    new Ass ass;
    eval(o.parts.get(i++), ass);
    return ass;
  }
}

static Iter multiEval(Pred p) {
  if (p instanceof Or) {
    Or o = cast p;
    return new OrIterator(o);
  } else {
    new Ass ass;
    eval(p, ass);
    return new Singleton(ass);
  }
}

p {
  new Ass ass;
  eval(new Assign("x", new Integer(1)), ass);
  print(structure(ass));
  
  ass = new Ass;
  eval(new And(
    new Assign("x", new Integer(1)),
    new Assign("y", new Integer(2))), ass);
  print(structure(ass));
  
  shouldFail(new And(
    new Assign("x", new Integer(1)),
    new Assign("x", new Integer(2))));
    
  // test multiEval
  
  L<Ass> list = all(multiEval(new Assign("a", new Integer(5))));
  assertEquals(1, list.size());
  print(structure(list));
  
  list = all(multiEval(new Or(
    new Assign("a", new Integer(5)),
    new Assign("a", new Integer(7)))));
  assertEquals(2, list.size());
  print(structure(list));
}

static L<Ass> all(Iter it) {
  new L<Ass> l;
  while (true) {
    Ass ass = it.next();
    if (ass != null)
      l.add(ass);
    else
      break;
  }
  return l;
}

static void assertEquals(O x, O y) {
  if (!(x == null ? y == null : x.equals(y)))
    fail(structure(x) + " != " + structure(y));
}

Author comment

Began life as a copy of #1000772

download  show line numbers  debug dex  old transpilations   

Travelled to 13 computer(s): aoiabmzegqzx, bhatertpkbcr, cbybwowwnfue, cfunsshuasjs, gwrvuhgaqvyk, ishqpsrjomds, lpdgvwnxivlt, mqqgnosmbjvj, pyentgdyhuwx, pzhvpgtvlbxg, tslmcundralx, tvejysmllsmz, vouqrxazstgt

No comments. add comment

Snippet ID: #1000773
Snippet name: Prolog engine (include)
Eternal ID of this version: #1000773/1
Text MD5: bf0927083a4a9547006a9177e4a25895
Author: stefan
Category:
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2015-08-26 21:31:42
Source code size: 2947 bytes / 154 lines
Pitched / IR pitched: No / Yes
Views / Downloads: 621 / 580
Referenced in: #3000382 - Answer for ferdie (>> t = 1, f = 0)
#3000383 - Answer for funkoverflow (>> t=1, f=0 okay)