pasp.app

  1import pasp
  2import sys
  3
  4ARGUMENTS = ["sem", "psem", "help"]
  5ARGUMENTS_SHORTCUTS = ["s", "p", "h"]
  6ARGUMENTS_HELP = {
  7  "sem": "Sets the semantics of the logic program.",
  8  "psem": "Sets the probabilistic semantics of the program.",
  9  "help": "Shows this help message."
 10}
 11ARGUMENTS_VALUES = {
 12  "sem": [
 13    ("stable", "Stable model semantics."),
 14    ("lstable", "L-stable model semantics."),
 15    ("partial", "Partial model semantics."),
 16    ("smproblog", "SMProbLog semantics."),
 17  ],
 18  "psem": [
 19    ("credal", "Credal semantics."),
 20    ("maxent", "Max-Entropy (uniform) semantics."),
 21  ],
 22  "help": None,
 23}
 24ARGUMENTS_HEADERS = [f"--{ARGUMENTS[i]}=<val> | -{ARGUMENTS_SHORTCUTS[i]} <val>" \
 25                     if ARGUMENTS_VALUES[a] is not None \
 26                     else f"--{ARGUMENTS[i]} | -{ARGUMENTS_SHORTCUTS[i]}" \
 27                     for i, a in enumerate(ARGUMENTS)]
 28ARGUMENTS_VALUES_HEADERS = {k: [ARGUMENTS_VALUES[k][i][0] for i in range(len(ARGUMENTS_VALUES[k]))] \
 29                            if ARGUMENTS_VALUES[k] is not None else None for k in ARGUMENTS}
 30ARGUMENTS_LJUST = len(max(ARGUMENTS_HEADERS, key=len))
 31ARGUMENTS_VALUES_LJUST = {k: len(max(ARGUMENTS_VALUES_HEADERS[k], key=len)) \
 32                          if ARGUMENTS_VALUES[k] is not None else None for k in ARGUMENTS}
 33
 34EXAMPLES = [
 35"""
 36  % Runs the prisoners example with credal inference and stable semantics.
 37  pasp examples/prisoners.lp
 38
 39  ℙ(e1 | u) = [0.290426, 0.379192]
 40  ℙ(e1 | not b, u) = [0.450125, 0.549875]
 41  ℙ(g | e1, u) = [0.000000, 1.000000]
 42  ℙ(d) = [0.000000, 1.000000]
 43  ℙ(e1 | g, u) = [0.000000, 0.549875]
 44  ℙ(e1 | ga, u) = [0.279971, 0.390743]
 45""",
 46"""
 47  % Runs the 3-coloring example with credal inference and L-stable semantics.
 48  pasp --sem=lstable examples/3coloring.lp
 49
 50  ℙ(c(1,r)) = [0.000000, 1.000000]
 51  ℙ(e(1,2) | undef f) = [0.772727, 0.772727]
 52  ℙ(undef f) = [0.064453, 0.064453]
 53""",
 54"""
 55  % Runs the insomnia example with Max-Entropy inference and stable semantics.
 56  pasp --psem=maxent examples/insomnia.lp
 57
 58  ℙ(insomnia) = [0.300000, 0.300000]
 59  ℙ(work) = [0.650000, 0.650000]
 60  ℙ(sleep) = [0.350000, 0.350000]
 61  ℙ(not sleep) = [0.650000, 0.650000]
 62  ℙ(not work) = [0.350000, 0.350000]
 63""",
 64]
 65
 66def print_help():
 67  print("""pasp - Probabilistic Answer Set Programming
 68Usage: pasp [options] [files]
 69
 70OPTIONS\n""")
 71  for i, a in enumerate(ARGUMENTS):
 72    print("  " + ARGUMENTS_HEADERS[i].ljust(ARGUMENTS_LJUST, ' ') + " : " + ARGUMENTS_HELP[a])
 73    if ARGUMENTS_VALUES[a] is not None:
 74      print("    Possible values:")
 75      for j in range(len(ARGUMENTS_VALUES[a])):
 76        print("      " + \
 77              ARGUMENTS_VALUES_HEADERS[a][j].ljust(ARGUMENTS_VALUES_LJUST[a], ' ') + " : " + \
 78              ARGUMENTS_VALUES[a][j][1])
 79
 80  print("\nDefault values for options come first.")
 81  print("\nEXAMPLES")
 82
 83  for e in EXAMPLES:
 84    print(e)
 85
 86  print("\npasp is available at https://github.com/RenatoGeh/pasp.")
 87  print("Get help/report bugs via: https://github.com/RenatoGeh/issues.")
 88
 89def try_arg(args: dict, a: str, pre: int, sep: str):
 90  if a.startswith(pre):
 91    T = a.split(sep)
 92    arg = T[0][len(pre):]
 93    if arg == "h" or arg == "help":
 94      print_help()
 95      sys.exit(0)
 96    is_shortcut = True
 97    try: arg = ARGUMENTS[ARGUMENTS_SHORTCUTS.index(arg)]
 98    except: is_shortcut = False
 99    if (arg not in ARGUMENTS) and (not is_shortcut):
100      print(f"Unrecognized command: {T[0]}!")
101      print_help()
102      sys.exit(1)
103    if len(T) != 2:
104      print(f"Unable to parse argument-value: {a}!")
105      print_help()
106      sys.exit(1)
107    val = T[1]
108    if val not in ARGUMENTS_VALUES_HEADERS[arg]:
109      print(f"Unrecognized option {val} for argument {arg}!")
110      print_help()
111      sys.exit(1)
112    args[arg] = val
113    return True
114  return False
115
116def parse_args() -> dict:
117  args = {k: ARGUMENTS_VALUES[k][0][0] if ARGUMENTS_VALUES[k] is not None else None \
118          for k in ARGUMENTS}
119  files = []
120  I = enumerate(sys.argv[1:], start = 1)
121  for i, a in I:
122    # Hack to make sure the second try_arg only occurs when -- does not work.
123    if (not try_arg(args, a, "--", "=")):
124      if try_arg(args, a + " " + sys.argv[i+1] if i+1 < len(sys.argv) else a, "-", " "):
125        next(I)
126      else:
127        files.append(a)
128
129  return args, files
130
131def main():
132  print("pasp version", pasp.__version__)
133  A, F = parse_args()
134  if len(F) > 0:
135    P = pasp.parse(*F, semantics = A["sem"])
136    if "psemantics" not in P.directives: P.directives["psemantics"] = {"psemantics": A["psem"]}
137    P()
138  else:
139    print("Reading from stdin")
140    inp = ""
141    for l in sys.stdin: inp += l
142    pasp.exact(pasp.parse(inp, from_str = True, semantics = A["sem"]), psemantics = A["psem"])
143  return 0
144
145if __name__ == "__main__": main()
ARGUMENTS = ['sem', 'psem', 'help']
ARGUMENTS_SHORTCUTS = ['s', 'p', 'h']
ARGUMENTS_HELP = {'sem': 'Sets the semantics of the logic program.', 'psem': 'Sets the probabilistic semantics of the program.', 'help': 'Shows this help message.'}
ARGUMENTS_VALUES = {'sem': [('stable', 'Stable model semantics.'), ('lstable', 'L-stable model semantics.'), ('partial', 'Partial model semantics.'), ('smproblog', 'SMProbLog semantics.')], 'psem': [('credal', 'Credal semantics.'), ('maxent', 'Max-Entropy (uniform) semantics.')], 'help': None}
ARGUMENTS_HEADERS = ['--sem=<val> | -s <val>', '--psem=<val> | -p <val>', '--help | -h']
ARGUMENTS_VALUES_HEADERS = {'sem': ['stable', 'lstable', 'partial', 'smproblog'], 'psem': ['credal', 'maxent'], 'help': None}
ARGUMENTS_LJUST = 23
ARGUMENTS_VALUES_LJUST = {'sem': 9, 'psem': 6, 'help': None}
EXAMPLES = ['\n % Runs the prisoners example with credal inference and stable semantics.\n pasp examples/prisoners.lp\n\n ℙ(e1 | u) = [0.290426, 0.379192]\n ℙ(e1 | not b, u) = [0.450125, 0.549875]\n ℙ(g | e1, u) = [0.000000, 1.000000]\n ℙ(d) = [0.000000, 1.000000]\n ℙ(e1 | g, u) = [0.000000, 0.549875]\n ℙ(e1 | ga, u) = [0.279971, 0.390743]\n', '\n % Runs the 3-coloring example with credal inference and L-stable semantics.\n pasp --sem=lstable examples/3coloring.lp\n\n ℙ(c(1,r)) = [0.000000, 1.000000]\n ℙ(e(1,2) | undef f) = [0.772727, 0.772727]\n ℙ(undef f) = [0.064453, 0.064453]\n', '\n % Runs the insomnia example with Max-Entropy inference and stable semantics.\n pasp --psem=maxent examples/insomnia.lp\n\n ℙ(insomnia) = [0.300000, 0.300000]\n ℙ(work) = [0.650000, 0.650000]\n ℙ(sleep) = [0.350000, 0.350000]\n ℙ(not sleep) = [0.650000, 0.650000]\n ℙ(not work) = [0.350000, 0.350000]\n']
def try_arg(args: dict, a: str, pre: int, sep: str):
 90def try_arg(args: dict, a: str, pre: int, sep: str):
 91  if a.startswith(pre):
 92    T = a.split(sep)
 93    arg = T[0][len(pre):]
 94    if arg == "h" or arg == "help":
 95      print_help()
 96      sys.exit(0)
 97    is_shortcut = True
 98    try: arg = ARGUMENTS[ARGUMENTS_SHORTCUTS.index(arg)]
 99    except: is_shortcut = False
100    if (arg not in ARGUMENTS) and (not is_shortcut):
101      print(f"Unrecognized command: {T[0]}!")
102      print_help()
103      sys.exit(1)
104    if len(T) != 2:
105      print(f"Unable to parse argument-value: {a}!")
106      print_help()
107      sys.exit(1)
108    val = T[1]
109    if val not in ARGUMENTS_VALUES_HEADERS[arg]:
110      print(f"Unrecognized option {val} for argument {arg}!")
111      print_help()
112      sys.exit(1)
113    args[arg] = val
114    return True
115  return False
def parse_args() -> dict:
117def parse_args() -> dict:
118  args = {k: ARGUMENTS_VALUES[k][0][0] if ARGUMENTS_VALUES[k] is not None else None \
119          for k in ARGUMENTS}
120  files = []
121  I = enumerate(sys.argv[1:], start = 1)
122  for i, a in I:
123    # Hack to make sure the second try_arg only occurs when -- does not work.
124    if (not try_arg(args, a, "--", "=")):
125      if try_arg(args, a + " " + sys.argv[i+1] if i+1 < len(sys.argv) else a, "-", " "):
126        next(I)
127      else:
128        files.append(a)
129
130  return args, files
def main():
132def main():
133  print("pasp version", pasp.__version__)
134  A, F = parse_args()
135  if len(F) > 0:
136    P = pasp.parse(*F, semantics = A["sem"])
137    if "psemantics" not in P.directives: P.directives["psemantics"] = {"psemantics": A["psem"]}
138    P()
139  else:
140    print("Reading from stdin")
141    inp = ""
142    for l in sys.stdin: inp += l
143    pasp.exact(pasp.parse(inp, from_str = True, semantics = A["sem"]), psemantics = A["psem"])
144  return 0