using Nemerle using Nemerle.Utility using Nemerle.Logging using Nemerle.Collections using Nemerle.Imperative using Nemerle.Profiling set namespace Fx7 public class PAtom : Atom public this (t1 : Term) base (t1, null) assert (t1.Name == "and" || t1.Name == "or") mutable neg_clauses : list [Clause] mutable pos_clauses : list [Clause] Core : Core get term1.Core [Profile] \ public GetDefiningClauses (neg : bool) : list [Clause] if (neg) when (neg_clauses == null) neg_clauses = Convert (term1, true) neg_clauses else when (pos_clauses == null) pos_clauses = Convert (term1, false) pos_clauses Convert (f : Term, neg : bool) : list [Clause] def seen = Hashtable () // flatten children and convert to literals def get_children (_, t, acc) if (t.Name == f.Name) t.FoldIndexedChildren (acc, get_children) else def lit = if (t.Name == "not") ~Core.TermToLiteral (MinDepth, t.OnlyChild) else Core.TermToLiteral (MinDepth, t) if (seen.Contains (lit)) acc else seen [lit] = lit lit :: acc def children = get_children (0, f, []) def us = GetLiteral (false) assert (!neg, $"term: $this") if (f.Name == "or") if (neg) $[Core.MakeClause (array [~c, us], Rule.NegOr ()) | c in children] else [Core.MakeClause ((~us :: children).ToArray (), Rule.Or ())] else if (neg) [Core.MakeClause ((us :: children.Map (~_)).ToArray (), Rule.NegAnd ())] else $[Core.MakeClause (array [~us, c], Rule.And ()) | c in children]