def test_member(self): x = V.make_variable("x") y = V.make_variable("y") z = V.make_variable("z") p = Prolog() p.fact(x.pair(y.pair(x)).make_const("member")) p.head_body( x.pair(y.pair(z)).make_const("member"), x.pair(y).make_const("member")) w = [] p.go( x.pair(L.make_const(1).make_const(2).make_const(3)).make_const( "member"), lambda: w.append(x.value())) self.assertEqual(w, [3, 2, 1])
def test(self): x = V.make_variable('x') t = [1, 2, 3] p = Prolog() for e in t: p.fact(C.make_const(e)) w = [] p.go(x, lambda: w.append(x.value())) self.assertEqual(w, t)
def test_member_hard(self): x = V.make_variable("x") y = V.make_variable("y") z = V.make_variable("z") p = Prolog() p.fact(x.pair(y.pair(x)).make_const("member")) p.head_body( x.pair(y.pair(z)).make_const("member"), x.pair(y).make_const("member")) w = [] m = L.make_const(1).make_const(2).make_const(3).make_const(4) n = L.make_const(0).make_const(2).make_const(4).make_const(6) p.go( x.pair(m).make_const("member") & x.pair(n).make_const("member"), lambda: w.append(x.value())) self.assertEqual(w, [4, 2])
def test_conjunction(self): x = V.make_variable('x') p = Prolog() p.fact(C.make_const(1).make_const("single")) p.fact(C.make_const(2).make_const("single")) p.head_body(x.pair(x).make_const("double"), x.make_const("single")) w = [] def check(): w.append(x.value()) if check.counter >= 10: assert False check.counter += 1 check.counter = 0 p.go(x.pair(x).make_const("double"), check) self.assertEqual(w, [1, 2])
def test_head_body_conjunction(self): x = V.make_variable("x") y = V.make_variable("y") p = Prolog() p.fact(C.make_const(1).make_const('a')) p.fact(C.make_const(2).make_const('b')) p.head_body( x.pair(y).make_const('c'), x.make_const('a') & y.make_const('b')) w = 0 def check(): nonlocal w w += 1 self.assertEqual(x.value(), 1) self.assertEqual(y.value(), 2) p.go(x.pair(y).make_const('c'), check) self.assertEqual(w, 1)
def test_and_nested(self): w = 0 p = Prolog() for e in [1, 2, 3]: p.fact(C.make_const(e)) def go(): nonlocal w w += 1 p.go(C.make_const(1) & (C.make_const(2) & C.make_const(3)), go) self.assertEqual(w, 1)
def test_two_answers(self): x = V.make_variable("x") y = V.make_variable("y") p = Prolog() p.fact(x) p.fact(y) w = [] p.go(C.make_const(1), lambda: w.append(None)) self.assertEqual(w, [None, None])
def test_instantiation(self): x = V.make_variable("x") p = Prolog() p.fact(x) w = 0 def do(): nonlocal w w += 1 p.go(C.make_const(1) & C.make_const(2), do) self.assertEqual(w, 1)
def test_head_body_conjunction_warmup_warmup_y_unassigned(self): x = V.make_variable("x") y = V.make_variable("y") p = Prolog() p.fact(C.make_const(1).make_const('a')) p.fact(C.make_const(2).make_const('b')) w = 0 def check(): nonlocal w w += 1 self.assertEqual(x.value(), 1) with self.assertRaises(Exception): y.value() p.go(x.make_const('a'), check) self.assertEqual(w, 1)
def test_last(self): a = V.make_variable('a') b = V.make_variable('b') c = V.make_variable('c') x = V.make_variable('x') y = V.make_variable('y') z = V.make_variable('z') p = Prolog() p.fact(x.pair(y.pair(x)).make_const("member")) p.head_body( x.pair(y.pair(z)).make_const("member"), x.pair(y).make_const("member")) p.fact(L.pair(x).pair(x).make_const("append")) p.head_body( a.pair(x).pair(b).pair(c.pair(x)).make_const("append"), a.pair(b).pair(c).make_const("append")) def do(): for q in [x, y]: s = [] p.go( a.pair(q).make_const("member"), lambda: s.append(a.value())) w.append(s) w = [] p.go( x.pair(y).pair(L.make_const('c').make_const('b').make_const( 'a')).make_const('append'), do) self.assertEqual(w, [[], ['a', 'b', 'c'], ['a'], ['b', 'c'], ['a', 'b'], ['c'], ['a', 'b', 'c'], []])
from prolog import Prolog, QuerySet import os prolog = Prolog(path_to_swipl=os.environ["path_to_swipl"]) @prolog.predicate def person(name: str, age: int): yield name, age @prolog.predicate def old(name: str): x = prolog.query_var("Y") y = prolog.query_var("Y") return person(name, x) and y > 60 prolog << person("andrew", 12) prolog << person("arseny", 15) prolog << person("vitalii", 73) prolog.load_predicates() X = prolog.query_var("X") Y = prolog.query_var("Y") q = prolog >> person(X, Y) print(q.fetch()) # generator object print(q.fetchone()) # {"x": "andrew", "y": 12}
from prolog import Prolog, ANONYMOUS_QV as _, Predicate from dataclasses import dataclass from typing import List import os prolog = Prolog(path_to_swipl=os.environ["path_to_swipl"]) @dataclass class Person(Predicate): name: str sex: int age: int children: List[str] prolog << Person("Gomez", 0, 52, ["Wednesday", "Pugsley"]) prolog << Person("Morticia", 1, 48, ["Wednesday", "Pugsley"]) prolog << Person("Pugsley", 0, 13, []) prolog << Person("Wednesday", 1, 13, []) prolog << Person("Grandmama", 1, 100, ["Gomez"]) prolog.load_predicates() q = Person.filter(children=[_ | _]) for person in q.fetch(prolog): print(person.name, "has children")
def main(): print("BigMAC Android Policy Processor") print(" by Grant Hernandez (https://hernan.de/z)") print("") parser = argparse.ArgumentParser() parser.add_argument('--vendor', required=True) parser.add_argument("policy_name") parser.add_argument('--debug', action='store_true', help="Enable debug logging.") parser.add_argument( '--debug-init', action='store_true', help="Drop into an IPython shell after simulating the boot process.") parser.add_argument('--skip-boot', action='store_true', help="Don't simulate the boot process.") parser.add_argument('--draw-graph', action='store_true') parser.add_argument('--focus-set') parser.add_argument('--save', action='store_true', help="Save the instantiated policy graph.") parser.add_argument('--load', action='store_true', help="Reload the saved instantiated policy graph.") parser.add_argument('--save-policy', action='store_true', help="Generate selinux.txt for debugging.") parser.add_argument('--list-objects', action='store_true') parser.add_argument('--dont-expand-objects', action='store_true') parser.add_argument( '--prolog', action='store_true', help="Compile Prolog helpers and start the query engine") args = parser.parse_args() if args.load and args.save: log.info("--load and --save are exclusive options") return 1 if args.debug: logging.getLogger().setLevel(logging.DEBUG) if args.policy_name[-1] == "/": args.policy_name = args.policy_name[:-1] args.policy_name = os.path.basename(args.policy_name) policy_results_dir = os.path.join(POLICY_RESULTS_DIR, args.vendor.lower(), args.policy_name) if not os.access(policy_results_dir, os.R_OK): log.error("Policy directory does not exist or is not readable") return 1 log.info("Loading android security policy %s (%s)", args.policy_name, args.vendor) asp = AndroidSecurityPolicy(args.vendor, args.policy_name) aspc = ASPCodec(asp) try: asp = aspc.load() except ValueError as e: log.error("Saved policy is corrupt: %s", e) return 1 android_version = asp.get_android_version() major, minor, revision = android_version log.info("Image summary: %s", asp.get_properties()["summary"]) # Treble handling if major == 8: file_contexts = read_file_contexts( asp.get_saved_file_path("plat_file_contexts")) file_contexts += read_file_contexts( asp.get_saved_file_path("nonplat_file_contexts")) elif major >= 9: file_contexts = read_file_contexts( asp.get_saved_file_path("plat_file_contexts")) file_contexts += read_file_contexts( asp.get_saved_file_path("vendor_file_contexts")) else: file_contexts = read_file_contexts( asp.get_saved_file_path("file_contexts")) log.info("Loaded %d file contexts", len(file_contexts)) primary_filesystem = asp.fs_policies[0] if args.load: try: inst = aspc._load_db("inst") except ValueError as e: log.error("Unable to load saved instantiation: %s", e) return 1 else: inst = main_process(args, asp, aspc, file_contexts, primary_filesystem, android_version) if inst is None: return if args.debug: from IPython import embed oldlevel = logging.getLogger().getEffectiveLevel() logging.getLogger().setLevel(logging.INFO) embed() logging.getLogger().setLevel(oldlevel) if args.list_objects: output_filename = '%s-files.txt' % (args.policy_name.replace( "..", "_").replace(os.sep, "")) log.info("Saving file list to %s", output_filename) with open(output_filename, 'w') as fp: fp.write(primary_filesystem.list_path("*")) output_filename = '%s-processes.txt' % (args.policy_name.replace( "..", "_").replace(os.sep, "")) log.info("Saving process list to %s", output_filename) with open(output_filename, 'w') as fp: fp.write(inst.list_processes()) if args.prolog: G = inst.fully_instantiate() pl = Prolog(G, aspc.db_dir, inst, asp) if pl.compile_all(): pl.interact() if args.draw_graph: GDF = graph["graphs"]["dataflow"] GP = graph["graphs"]["process"] GSUB = graph["graphs"]["subject"] focus_set = set() if args.focus_set: focus_names = args.focus_set.split(",") focus_set = set(focus_names) plot(GDF, "dataflow.svg", prune=True, debug=False, focus_set=focus_set) plot(GP, "process.svg", debug=False) plot(GSUB, "subject.svg", debug=False) return 0