From 9c9444bece0727d4c9224c2f5e224869f1340ec7 Mon Sep 17 00:00:00 2001 From: Vitor Santos Costa Date: Mon, 16 Feb 2009 12:23:29 +0000 Subject: [PATCH] update package locations to a subdir packages --- packages/CLPBN/Makefile.in | 85 + packages/CLPBN/clpbn.yap | 397 + packages/CLPBN/clpbn/aggregates.yap | 283 + packages/CLPBN/clpbn/bnt.yap | 425 + packages/CLPBN/clpbn/connected.yap | 172 + packages/CLPBN/clpbn/discrete_utils.yap | 146 + packages/CLPBN/clpbn/display.yap | 71 + packages/CLPBN/clpbn/dists.yap | 316 + packages/CLPBN/clpbn/evidence.yap | 136 + packages/CLPBN/clpbn/examples/School/README | 53 + .../clpbn/examples/School/evidence_128.yap | 17 + .../CLPBN/clpbn/examples/School/parlearn.yap | 44 + .../CLPBN/clpbn/examples/School/sample32.yap | 2433 ++ .../CLPBN/clpbn/examples/School/schema.yap | 71 + .../clpbn/examples/School/school_128.yap | 18432 ++++++++++++++++ .../CLPBN/clpbn/examples/School/school_32.yap | 1238 ++ .../CLPBN/clpbn/examples/School/school_64.yap | 4706 ++++ .../CLPBN/clpbn/examples/School/tables.yap | 45 + packages/CLPBN/clpbn/examples/cg.yap | 35 + packages/CLPBN/clpbn/examples/sprinkler.yap | 31 + packages/CLPBN/clpbn/gibbs.yap | 546 + packages/CLPBN/clpbn/graphs.yap | 43 + packages/CLPBN/clpbn/graphviz.yap | 71 + packages/CLPBN/clpbn/hmm.yap | 83 + packages/CLPBN/clpbn/jt.yap | 528 + packages/CLPBN/clpbn/matrix_cpt_utils.yap | 267 + packages/CLPBN/clpbn/table.yap | 223 + packages/CLPBN/clpbn/topsort.yap | 34 + packages/CLPBN/clpbn/utils.yap | 116 + packages/CLPBN/clpbn/vel.yap | 274 + packages/CLPBN/clpbn/viterbi.yap | 235 + packages/CLPBN/clpbn/xbif.yap | 119 + packages/CLPBN/learning/aleph_params.yap | 306 + packages/CLPBN/learning/bnt_parms.yap | 121 + packages/CLPBN/learning/em.yap | 229 + .../CLPBN/learning/example/school_params.yap | 46 + packages/CLPBN/learning/example/train.yap | 2433 ++ packages/CLPBN/learning/learn_utils.yap | 100 + packages/CLPBN/learning/mle.yap | 113 + packages/MYDDAS/myddas.h | 159 + packages/MYDDAS/myddas_initialization.c | 112 + packages/MYDDAS/myddas_mysql.c | 725 + packages/MYDDAS/myddas_odbc.c | 745 + packages/MYDDAS/myddas_shared.c | 700 + packages/MYDDAS/myddas_statistics.c | 356 + packages/MYDDAS/myddas_statistics.h | 135 + packages/MYDDAS/myddas_statistics_structs.h | 50 + packages/MYDDAS/myddas_structs.h | 67 + packages/MYDDAS/myddas_top_level.c | 93 + packages/MYDDAS/myddas_util.c | 399 + packages/MYDDAS/myddas_wkb.h | 25 + packages/MYDDAS/myddas_wkb2prolog.c | 380 + packages/MYDDAS/myddas_wkb2prolog.h | 6 + packages/ProbLog/Makefile.in | 14 + packages/ProbLog/README | 7 + packages/ProbLog/examples/graph.pl | 86 + packages/ProbLog/examples/learn_graph.pl | 96 + packages/ProbLog/learning.yap | 1147 + packages/ProbLog/learning/logger.yap | 311 + packages/ProbLog/problog.yap | 958 + packages/ProbLog/problog/flags.yap | 284 + packages/ProbLog/problog/print.yap | 24 + packages/ProbLog/problog/tptree.yap | 500 + packages/ProbLog/simplecudd/Example.c | 281 + packages/ProbLog/simplecudd/LICENCE | 131 + packages/ProbLog/simplecudd/Makefile.in | 34 + packages/ProbLog/simplecudd/ProblogBDD.c | 670 + packages/ProbLog/simplecudd/SimpleCUDD.pl | 141 + packages/ProbLog/simplecudd/general.c | 234 + packages/ProbLog/simplecudd/general.h | 159 + packages/ProbLog/simplecudd/simplecudd.c | 1620 ++ packages/ProbLog/simplecudd/simplecudd.h | 287 + packages/cplint/Artistic | 201 + packages/cplint/COPYRIGHT_SLG | 18 + packages/cplint/Makefile.in | 168 + packages/cplint/README | 40 + packages/cplint/cpl.pl | 157 + packages/cplint/cplint.h | 49 + packages/cplint/cplint_Prob.c | 209 + packages/cplint/cplint_yap.c | 256 + packages/cplint/doc/manual.bbl | 90 + packages/cplint/doc/manual.css | 113 + packages/cplint/doc/manual.html | 1047 + packages/cplint/doc/manual.pdf | Bin 0 -> 118367 bytes packages/cplint/doc/manual.tex | 458 + packages/cplint/doc/manual0x.png | Bin 0 -> 1593 bytes packages/cplint/examples/alarm.cpl | 7 + packages/cplint/examples/coin.cpl | 17 + packages/cplint/examples/coin.uni | 0 packages/cplint/examples/coin2.cpl | 23 + packages/cplint/examples/coin2.uni | 9 + packages/cplint/examples/dice.cpl | 29 + packages/cplint/examples/dice.uni | 2 + packages/cplint/examples/ex.cpl | 13 + packages/cplint/examples/ex.uni | 6 + packages/cplint/examples/exapprox.cpl | 17 + packages/cplint/examples/exapprox.uni | 9 + packages/cplint/examples/exist.cpl | 32 + packages/cplint/examples/exist.uni | 8 + packages/cplint/examples/exist1.cpl | 31 + packages/cplint/examples/exist1.uni | 10 + packages/cplint/examples/exrange.cpl | 21 + packages/cplint/examples/exrange.uni | 6 + packages/cplint/examples/female.cpl | 26 + packages/cplint/examples/hiv.cpl | 27 + packages/cplint/examples/hiv.uni | 4 + packages/cplint/examples/invalid.cpl | 15 + packages/cplint/examples/invalid.uni | 7 + packages/cplint/examples/light.cpl | 26 + packages/cplint/examples/light.uni | 4 + packages/cplint/examples/mendel.cpl | 38 + packages/cplint/examples/mendel.uni | 13 + packages/cplint/examples/mendels.cpl | 30 + packages/cplint/examples/mendels.uni | 13 + packages/cplint/examples/paper_ref.cpl | 51 + packages/cplint/examples/paper_ref_not.cpl | 41 + packages/cplint/examples/paper_ref_simple.cpl | 45 + packages/cplint/examples/school.cpl | 796 + packages/cplint/examples/school_simple.cpl | 52 + packages/cplint/examples/school_simple.uni | 18 + packages/cplint/examples/student.cpl | 95 + packages/cplint/examples/student.uni | 29 + packages/cplint/examples/threesideddice.cpl | 39 + packages/cplint/examples/threesideddice.uni | 9 + packages/cplint/examples/throws.cpl | 21 + packages/cplint/examples/throws.uni | 6 + packages/cplint/examples/trigger.cpl | 13 + packages/cplint/examples/trigger.uni | 4 + packages/cplint/examples/twosideddice.cpl | 21 + packages/cplint/examples/win.cpl | 14 + packages/cplint/examples/win.uni | 6 + packages/cplint/lpad.pl | 2257 ++ packages/cplint/lpadclpbn.pl | 1183 + packages/cplint/lpadsld.pl | 1480 ++ packages/cplint/lpadvel.pl | 1538 ++ packages/cplint/semcpl.pl | 638 + packages/cplint/semlpad.pl | 529 + packages/cplint/semlpadsld.pl | 468 + packages/cplint/slg.pl | 2158 ++ packages/cplint/testcpl.pl | 124 + packages/cplint/testlpad.pl | 136 + packages/cplint/testlpadclpbn.pl | 212 + packages/cplint/testlpadsld_gbfalse.pl | 215 + packages/cplint/testlpadsld_gbtrue.pl | 246 + packages/cplint/testlpadsldit.pl | 236 + packages/cplint/testlpadslditc.pl | 236 + packages/cplint/testlpadslditr.pl | 234 + packages/cplint/testlpadvel.pl | 222 + packages/cplint/testsemcpl.pl | 127 + packages/cplint/testsemlpad.pl | 120 + packages/cplint/testsemlpadsld.pl | 128 + 151 files changed, 62955 insertions(+) create mode 100644 packages/CLPBN/Makefile.in create mode 100644 packages/CLPBN/clpbn.yap create mode 100644 packages/CLPBN/clpbn/aggregates.yap create mode 100644 packages/CLPBN/clpbn/bnt.yap create mode 100644 packages/CLPBN/clpbn/connected.yap create mode 100644 packages/CLPBN/clpbn/discrete_utils.yap create mode 100644 packages/CLPBN/clpbn/display.yap create mode 100644 packages/CLPBN/clpbn/dists.yap create mode 100644 packages/CLPBN/clpbn/evidence.yap create mode 100644 packages/CLPBN/clpbn/examples/School/README create mode 100644 packages/CLPBN/clpbn/examples/School/evidence_128.yap create mode 100644 packages/CLPBN/clpbn/examples/School/parlearn.yap create mode 100644 packages/CLPBN/clpbn/examples/School/sample32.yap create mode 100644 packages/CLPBN/clpbn/examples/School/schema.yap create mode 100644 packages/CLPBN/clpbn/examples/School/school_128.yap create mode 100644 packages/CLPBN/clpbn/examples/School/school_32.yap create mode 100644 packages/CLPBN/clpbn/examples/School/school_64.yap create mode 100644 packages/CLPBN/clpbn/examples/School/tables.yap create mode 100644 packages/CLPBN/clpbn/examples/cg.yap create mode 100644 packages/CLPBN/clpbn/examples/sprinkler.yap create mode 100644 packages/CLPBN/clpbn/gibbs.yap create mode 100644 packages/CLPBN/clpbn/graphs.yap create mode 100644 packages/CLPBN/clpbn/graphviz.yap create mode 100644 packages/CLPBN/clpbn/hmm.yap create mode 100644 packages/CLPBN/clpbn/jt.yap create mode 100644 packages/CLPBN/clpbn/matrix_cpt_utils.yap create mode 100644 packages/CLPBN/clpbn/table.yap create mode 100644 packages/CLPBN/clpbn/topsort.yap create mode 100644 packages/CLPBN/clpbn/utils.yap create mode 100644 packages/CLPBN/clpbn/vel.yap create mode 100644 packages/CLPBN/clpbn/viterbi.yap create mode 100644 packages/CLPBN/clpbn/xbif.yap create mode 100644 packages/CLPBN/learning/aleph_params.yap create mode 100644 packages/CLPBN/learning/bnt_parms.yap create mode 100644 packages/CLPBN/learning/em.yap create mode 100644 packages/CLPBN/learning/example/school_params.yap create mode 100644 packages/CLPBN/learning/example/train.yap create mode 100644 packages/CLPBN/learning/learn_utils.yap create mode 100644 packages/CLPBN/learning/mle.yap create mode 100644 packages/MYDDAS/myddas.h create mode 100644 packages/MYDDAS/myddas_initialization.c create mode 100755 packages/MYDDAS/myddas_mysql.c create mode 100755 packages/MYDDAS/myddas_odbc.c create mode 100644 packages/MYDDAS/myddas_shared.c create mode 100644 packages/MYDDAS/myddas_statistics.c create mode 100644 packages/MYDDAS/myddas_statistics.h create mode 100644 packages/MYDDAS/myddas_statistics_structs.h create mode 100644 packages/MYDDAS/myddas_structs.h create mode 100644 packages/MYDDAS/myddas_top_level.c create mode 100755 packages/MYDDAS/myddas_util.c create mode 100644 packages/MYDDAS/myddas_wkb.h create mode 100644 packages/MYDDAS/myddas_wkb2prolog.c create mode 100644 packages/MYDDAS/myddas_wkb2prolog.h create mode 100644 packages/ProbLog/Makefile.in create mode 100644 packages/ProbLog/README create mode 100644 packages/ProbLog/examples/graph.pl create mode 100644 packages/ProbLog/examples/learn_graph.pl create mode 100644 packages/ProbLog/learning.yap create mode 100644 packages/ProbLog/learning/logger.yap create mode 100644 packages/ProbLog/problog.yap create mode 100644 packages/ProbLog/problog/flags.yap create mode 100644 packages/ProbLog/problog/print.yap create mode 100644 packages/ProbLog/problog/tptree.yap create mode 100644 packages/ProbLog/simplecudd/Example.c create mode 100644 packages/ProbLog/simplecudd/LICENCE create mode 100644 packages/ProbLog/simplecudd/Makefile.in create mode 100644 packages/ProbLog/simplecudd/ProblogBDD.c create mode 100644 packages/ProbLog/simplecudd/SimpleCUDD.pl create mode 100644 packages/ProbLog/simplecudd/general.c create mode 100644 packages/ProbLog/simplecudd/general.h create mode 100644 packages/ProbLog/simplecudd/simplecudd.c create mode 100644 packages/ProbLog/simplecudd/simplecudd.h create mode 100644 packages/cplint/Artistic create mode 100644 packages/cplint/COPYRIGHT_SLG create mode 100644 packages/cplint/Makefile.in create mode 100644 packages/cplint/README create mode 100644 packages/cplint/cpl.pl create mode 100644 packages/cplint/cplint.h create mode 100644 packages/cplint/cplint_Prob.c create mode 100644 packages/cplint/cplint_yap.c create mode 100644 packages/cplint/doc/manual.bbl create mode 100644 packages/cplint/doc/manual.css create mode 100644 packages/cplint/doc/manual.html create mode 100644 packages/cplint/doc/manual.pdf create mode 100644 packages/cplint/doc/manual.tex create mode 100644 packages/cplint/doc/manual0x.png create mode 100644 packages/cplint/examples/alarm.cpl create mode 100644 packages/cplint/examples/coin.cpl create mode 100644 packages/cplint/examples/coin.uni create mode 100644 packages/cplint/examples/coin2.cpl create mode 100644 packages/cplint/examples/coin2.uni create mode 100644 packages/cplint/examples/dice.cpl create mode 100644 packages/cplint/examples/dice.uni create mode 100644 packages/cplint/examples/ex.cpl create mode 100644 packages/cplint/examples/ex.uni create mode 100644 packages/cplint/examples/exapprox.cpl create mode 100644 packages/cplint/examples/exapprox.uni create mode 100644 packages/cplint/examples/exist.cpl create mode 100644 packages/cplint/examples/exist.uni create mode 100644 packages/cplint/examples/exist1.cpl create mode 100644 packages/cplint/examples/exist1.uni create mode 100644 packages/cplint/examples/exrange.cpl create mode 100644 packages/cplint/examples/exrange.uni create mode 100644 packages/cplint/examples/female.cpl create mode 100644 packages/cplint/examples/hiv.cpl create mode 100644 packages/cplint/examples/hiv.uni create mode 100644 packages/cplint/examples/invalid.cpl create mode 100644 packages/cplint/examples/invalid.uni create mode 100644 packages/cplint/examples/light.cpl create mode 100644 packages/cplint/examples/light.uni create mode 100644 packages/cplint/examples/mendel.cpl create mode 100644 packages/cplint/examples/mendel.uni create mode 100644 packages/cplint/examples/mendels.cpl create mode 100644 packages/cplint/examples/mendels.uni create mode 100644 packages/cplint/examples/paper_ref.cpl create mode 100644 packages/cplint/examples/paper_ref_not.cpl create mode 100644 packages/cplint/examples/paper_ref_simple.cpl create mode 100644 packages/cplint/examples/school.cpl create mode 100644 packages/cplint/examples/school_simple.cpl create mode 100644 packages/cplint/examples/school_simple.uni create mode 100644 packages/cplint/examples/student.cpl create mode 100644 packages/cplint/examples/student.uni create mode 100644 packages/cplint/examples/threesideddice.cpl create mode 100644 packages/cplint/examples/threesideddice.uni create mode 100644 packages/cplint/examples/throws.cpl create mode 100644 packages/cplint/examples/throws.uni create mode 100644 packages/cplint/examples/trigger.cpl create mode 100644 packages/cplint/examples/trigger.uni create mode 100644 packages/cplint/examples/twosideddice.cpl create mode 100644 packages/cplint/examples/win.cpl create mode 100644 packages/cplint/examples/win.uni create mode 100644 packages/cplint/lpad.pl create mode 100644 packages/cplint/lpadclpbn.pl create mode 100644 packages/cplint/lpadsld.pl create mode 100644 packages/cplint/lpadvel.pl create mode 100644 packages/cplint/semcpl.pl create mode 100644 packages/cplint/semlpad.pl create mode 100644 packages/cplint/semlpadsld.pl create mode 100644 packages/cplint/slg.pl create mode 100644 packages/cplint/testcpl.pl create mode 100644 packages/cplint/testlpad.pl create mode 100644 packages/cplint/testlpadclpbn.pl create mode 100644 packages/cplint/testlpadsld_gbfalse.pl create mode 100644 packages/cplint/testlpadsld_gbtrue.pl create mode 100644 packages/cplint/testlpadsldit.pl create mode 100644 packages/cplint/testlpadslditc.pl create mode 100644 packages/cplint/testlpadslditr.pl create mode 100644 packages/cplint/testlpadvel.pl create mode 100644 packages/cplint/testsemcpl.pl create mode 100644 packages/cplint/testsemlpad.pl create mode 100644 packages/cplint/testsemlpadsld.pl diff --git a/packages/CLPBN/Makefile.in b/packages/CLPBN/Makefile.in new file mode 100644 index 000000000..04935d5b8 --- /dev/null +++ b/packages/CLPBN/Makefile.in @@ -0,0 +1,85 @@ +# +# default base directory for YAP installation +# +ROOTDIR = @prefix@ +# +# where the binary should be +# +BINDIR = $(ROOTDIR)/bin +# +# where YAP should look for libraries +# +LIBDIR=$(ROOTDIR)/lib/Yap +# +# where YAP should look for architecture-independent Prolog libraries +# +SHAREDIR=$(ROOTDIR)/share/Yap +# +# +# You shouldn't need to change what follows. +# +INSTALL=@INSTALL@ +INSTALL_DATA=@INSTALL_DATA@ +INSTALL_PROGRAM=@INSTALL_PROGRAM@ +srcdir=@srcdir@ + +CLPBN_TOP= $(srcdir)/clpbn.yap + +CLPBN_SRCDIR = $(srcdir)/clpbn + +CLPBN_LEARNING_SRCDIR = $(srcdir)/learning + +CLPBN_EXDIR = $(srcdir)/clpbn/examples + +CLPBN_PROGRAMS= \ + $(CLPBN_SRCDIR)/aggregates.yap \ + $(CLPBN_SRCDIR)/bnt.yap \ + $(CLPBN_SRCDIR)/connected.yap \ + $(CLPBN_SRCDIR)/discrete_utils.yap \ + $(CLPBN_SRCDIR)/display.yap \ + $(CLPBN_SRCDIR)/dists.yap \ + $(CLPBN_SRCDIR)/evidence.yap \ + $(CLPBN_SRCDIR)/gibbs.yap \ + $(CLPBN_SRCDIR)/graphs.yap \ + $(CLPBN_SRCDIR)/graphviz.yap \ + $(CLPBN_SRCDIR)/hmm.yap \ + $(CLPBN_SRCDIR)/jt.yap \ + $(CLPBN_SRCDIR)/matrix_cpt_utils.yap \ + $(CLPBN_SRCDIR)/table.yap \ + $(CLPBN_SRCDIR)/topsort.yap \ + $(CLPBN_SRCDIR)/utils.yap \ + $(CLPBN_SRCDIR)/vel.yap \ + $(CLPBN_SRCDIR)/viterbi.yap \ + $(CLPBN_SRCDIR)/xbif.yap + +CLPBN_LEARNING_PROGRAMS= \ + $(CLPBN_LEARNING_SRCDIR)/aleph_parms.yap \ + $(CLPBN_LEARNING_SRCDIR)/bnt_parms.yap \ + $(CLPBN_LEARNING_SRCDIR)/em.yap \ + $(CLPBN_LEARNING_SRCDIR)/learn_utils.yap \ + $(CLPBN_LEARNING_SRCDIR)/mle.yap + +CLPBN_SCHOOL_EXAMPLES= \ + $(CLPBN_EXDIR)/School/README \ + $(CLPBN_EXDIR)/School/evidence_128.yap \ + $(CLPBN_EXDIR)/School/schema.yap \ + $(CLPBN_EXDIR)/School/school_128.yap \ + $(CLPBN_EXDIR)/School/school_32.yap \ + $(CLPBN_EXDIR)/School/school_64.yap \ + $(CLPBN_EXDIR)/School/tables.yap + +CLPBN_EXAMPLES= \ + $(CLPBN_EXDIR)/cg.yap \ + $(CLPBN_EXDIR)/sprinkler.yap + + +install: $(CLBN_TOP) $(CLBN_PROGRAMS) $(CLPBN_PROGRAMS) + mkdir -p $(DESTDIR)$(SHAREDIR)/clpbn + mkdir -p $(DESTDIR)$(SHAREDIR)/clpbn/learning + mkdir -p $(DESTDIR)$(SHAREDIR)/clpbn/examples/School + for h in $(CLPBN_TOP); do $(INSTALL_DATA) $$h $(DESTDIR)$(SHAREDIR); done + for h in $(CLPBN_PROGRAMS); do $(INSTALL_DATA) $$h $(DESTDIR)$(SHAREDIR)/clpbn; done + for h in $(CLPBN_LEARNING_PROGRAMS); do $(INSTALL_DATA) $$h $(DESTDIR)$(SHAREDIR)/clpbn/learning; done + for h in $(CLPBN_EXAMPLES); do $(INSTALL_DATA) $$h $(DESTDIR)$(SHAREDIR)/clpbn/examples; done + for h in $(CLPBN_SCHOOL_EXAMPLES); do $(INSTALL_DATA) $$h $(DESTDIR)$(SHAREDIR)/clpbn/examples/School; done + diff --git a/packages/CLPBN/clpbn.yap b/packages/CLPBN/clpbn.yap new file mode 100644 index 000000000..c4f507f2d --- /dev/null +++ b/packages/CLPBN/clpbn.yap @@ -0,0 +1,397 @@ + + +:- module(clpbn, [{}/1, + clpbn_flag/2, + set_clpbn_flag/2, + clpbn_flag/3, + clpbn_key/2, + clpbn_init_solver/4, + clpbn_run_solver/3, + clpbn_init_solver/5, + clpbn_run_solver/4]). + +:- use_module(library(atts)). +:- use_module(library(lists)). +:- use_module(library(terms)). + +:- op( 500, xfy, with). + +% +% avoid the overhead of using goal_expansion/2. +% +:- multifile + user:term_expansion/2. + +:- dynamic + user:term_expansion/2. + +:- attribute key/1, dist/2, evidence/1, starter/0. + + +:- use_module('clpbn/vel', + [vel/3, + check_if_vel_done/1, + init_vel_solver/4, + run_vel_solver/3 + ]). + +:- use_module('clpbn/jt', + [jt/3, + init_jt_solver/4, + run_jt_solver/3 + ]). + +:- use_module('clpbn/bnt', + [do_bnt/3, + check_if_bnt_done/1 + ]). + +:- use_module('clpbn/gibbs', + [gibbs/3, + check_if_gibbs_done/1, + init_gibbs_solver/4, + run_gibbs_solver/3 + ]). + +:- use_module('clpbn/graphs', + [ + clpbn2graph/1 + ]). + +:- use_module('clpbn/dists', + [ + dist/4, + get_dist/4, + get_evidence_position/3, + get_evidence_from_position/3 + ]). + +:- use_module('clpbn/evidence', + [ + store_evidence/1, + incorporate_evidence/2, + check_stored_evidence/2, + add_evidence/2 + ]). + +:- use_module('clpbn/utils', + [ + sort_vars_by_key/3 + ]). + +:- use_module('clpbn/graphviz', + [clpbn2gviz/4]). + +:- dynamic solver/1,output/1,use/1,suppress_attribute_display/1, parameter_softening/1, em_solver/1. + +solver(vel). +em_solver(vel). + +%output(xbif(user_error)). +%output(gviz(user_error)). +output(no). +suppress_attribute_display(false). +parameter_softening(m_estimate(10)). + +clpbn_flag(Flag,Option) :- + clpbn_flag(Flag, Option, Option). + +set_clpbn_flag(Flag,Option) :- + clpbn_flag(Flag, _, Option). + +clpbn_flag(output,Before,After) :- + retract(output(Before)), + assert(output(After)). +clpbn_flag(solver,Before,After) :- + retract(solver(Before)), + assert(solver(After)). +clpbn_flag(em_solver,Before,After) :- + retract(em_solver(Before)), + assert(em_solver(After)). +clpbn_flag(bnt_solver,Before,After) :- + retract(bnt:bnt_solver(Before)), + assert(bnt:bnt_solver(After)). +clpbn_flag(bnt_path,Before,After) :- + retract(bnt:bnt_path(Before)), + assert(bnt:bnt_path(After)). +clpbn_flag(bnt_model,Before,After) :- + retract(bnt:bnt_model(Before)), + assert(bnt:bnt_model(After)). +clpbn_flag(suppress_attribute_display,Before,After) :- + retract(suppress_attribute_display(Before)), + assert(suppress_attribute_display(After)). +clpbn_flag(parameter_softening,Before,After) :- + retract(parameter_softening(Before)), + assert(parameter_softening(After)). + + +{_} :- + solver(none), !. +{Var = Key with Dist} :- + put_atts(El,[key(Key),dist(DistInfo,Parents)]), + dist(Dist, DistInfo, Key, Parents), + add_evidence(Var,Key,DistInfo,El). + +check_constraint(Constraint, _, _, Constraint) :- var(Constraint), !. +check_constraint((A->D), _, _, (A->D)) :- var(A), !. +check_constraint((([A|B].L)->D), Vars, NVars, (([A|B].NL)->D)) :- !, + check_cpt_input_vars(L, Vars, NVars, NL). +check_constraint(Dist, _, _, Dist). + +check_cpt_input_vars([], _, _, []). +check_cpt_input_vars([V|L], Vars, NVars, [NV|NL]) :- + replace_var(Vars, V, NVars, NV), + check_cpt_input_vars(L, Vars, NVars, NL). + +replace_var([], V, [], V). +replace_var([V|_], V0, [NV|_], NV) :- V == V0, !. +replace_var([_|Vars], V, [_|NVars], NV) :- + replace_var(Vars, V, NVars, NV). + +add_evidence(V,Key,Distinfo,NV) :- + nonvar(V), !, + get_evidence_position(V, Distinfo, Pos), + check_stored_evidence(Key, Pos), + clpbn:put_atts(NV,evidence(Pos)). +add_evidence(V,K,_,V) :- + add_evidence(K,V). + +clpbn_marginalise(V, Dist) :- + attributes:all_attvars(AVars), + project_attributes([V], AVars), + vel:get_atts(V, posterior(_,_,Dist,_)). + +% +% called by top-level +% or by call_residue/2 +% +project_attributes(GVars, AVars) :- + suppress_attribute_display(false), + AVars = [_|_], + solver(Solver), + ( GVars = [_|_] ; Solver = graphs), !, + clpbn_vars(AVars, DiffVars, AllVars), + get_clpbn_vars(GVars,CLPBNGVars0), + simplify_query_vars(CLPBNGVars0, CLPBNGVars), + (output(xbif(XBifStream)) -> clpbn2xbif(XBifStream,vel,AllVars) ; true), + (output(gviz(XBifStream)) -> clpbn2gviz(XBifStream,sort,AllVars,GVars) ; true), + ( + Solver = graphs + -> + write_out(Solver, [[]], AllVars, DiffVars) + ; + write_out(Solver, [CLPBNGVars], AllVars, DiffVars) + ). +project_attributes(_, _). + +clpbn_vars(AVars, DiffVars, AllVars) :- + sort_vars_by_key(AVars,SortedAVars,DiffVars), + incorporate_evidence(SortedAVars, AllVars). + +get_clpbn_vars([],[]). +get_clpbn_vars([V|GVars],[V|CLPBNGVars]) :- + get_atts(V, [key(_)]), !, + get_clpbn_vars(GVars,CLPBNGVars). +get_clpbn_vars([_|GVars],CLPBNGVars) :- + get_clpbn_vars(GVars,CLPBNGVars). + +simplify_query_vars(LVs0, LVs) :- + sort(LVs0,LVs1), + get_rid_of_ev_vars(LVs1,LVs). + +% +% some variables might already have evidence in the data-base. +% +get_rid_of_ev_vars([],[]). +get_rid_of_ev_vars([V|LVs0],LVs) :- + clpbn:get_atts(V, [dist(Id,_),evidence(Pos)]), !, + get_evidence_from_position(Ev, Id, Pos), + clpbn_display:put_atts(V, [posterior([],Ev,[],[])]), !, + get_rid_of_ev_vars(LVs0,LVs). +get_rid_of_ev_vars([V|LVs0],[V|LVs]) :- + get_rid_of_ev_vars(LVs0,LVs). + + +% do nothing if we don't have query variables to compute. +write_out(graphs, _, AVars, _) :- + clpbn2graph(AVars). +write_out(vel, GVars, AVars, DiffVars) :- + vel(GVars, AVars, DiffVars). +write_out(jt, GVars, AVars, DiffVars) :- + jt(GVars, AVars, DiffVars). +write_out(gibbs, GVars, AVars, DiffVars) :- + gibbs(GVars, AVars, DiffVars). +write_out(bnt, GVars, AVars, DiffVars) :- + do_bnt(GVars, AVars, DiffVars). + +get_bnode(Var, Goal) :- + get_atts(Var, [key(Key),dist(Dist,Parents)]), + get_dist(Dist,_,Domain,CPT), + (Parents = [] -> X = tab(Domain,CPT) ; X = tab(Domain,CPT,Parents)), + dist_goal(X, Key, Goal0), + include_evidence(Var, Goal0, Key, Goali), + include_starter(Var, Goali, Key, Goal). + +include_evidence(Var, Goal0, Key, ((Key:-Ev),Goal0)) :- + get_atts(Var, [evidence(Ev)]), !. +include_evidence(_, Goal0, _, Goal0). + +include_starter(Var, Goal0, Key, ((:-Key),Goal0)) :- + get_atts(Var, [starter]), !. +include_starter(_, Goal0, _, Goal0). + +dist_goal(Dist, Key, (Key=NDist)) :- + term_variables(Dist, DVars), + process_vars(DVars, DKeys), + my_copy_term(Dist,DVars, NDist,DKeys). + +my_copy_term(V, DVars, Key, DKeys) :- + find_var(DVars, V, Key, DKeys). +my_copy_term(A, _, A, _) :- atomic(A), !. +my_copy_term(T, Vs, NT, Ks) :- + T =.. [Na|As], + my_copy_terms(As, Vs, NAs, Ks), + NT =.. [Na|NAs]. + +my_copy_terms([], _, [], _). +my_copy_terms([A|As], Vs, [NA|NAs], Ks) :- + my_copy_term(A, Vs, NA, Ks), + my_copy_terms(As, Vs, NAs, Ks). + +find_var([V1|_], V, Key, [Key|_]) :- V1 == V, !. +find_var([_|DVars], V, Key, [_|DKeys]) :- + find_var(DVars, V, Key, DKeys). + +process_vars([], []). +process_vars([V|Vs], [K|Ks]) :- + process_var(V, K), + process_vars(Vs, Ks). + +process_var(V, K) :- get_atts(V, [key(K)]), !. +% oops: this variable has no attributes. +process_var(V, _) :- throw(error(instantiation_error,clpbn(attribute_goal(V)))). + +% +% unify a CLPBN variable with something. +% +verify_attributes(Var, T, Goals) :- + get_atts(Var, [key(Key),dist(Dist,Parents)]), !, + /* oops, someone trying to bind a clpbn constrained variable */ + Goals = [], + bind_clpbn(T, Var, Key, Dist, Parents). +verify_attributes(_, _, []). + + +bind_clpbn(T, Var, _, _, _) :- nonvar(T), + !, ( add_evidence(Var,T) -> true ; writeln(T:Var), fail ). +bind_clpbn(T, Var, Key, Dist, Parents) :- var(T), + get_atts(T, [key(Key1),dist(Dist1,Parents1)]), !, + bind_clpbns(Key, Dist, Parents, Key1, Dist1, Parents1), + ( + get_atts(T, [evidence(Ev1)]) -> + bind_evidence_from_extra_var(Ev1,Var) + ; + get_atts(Var, [evidence(Ev)]) -> + bind_evidence_from_extra_var(Ev,T) + ; + true). +bind_clpbn(_, Var, _, _, _, _) :- + use(bnt), + check_if_bnt_done(Var), !. +bind_clpbn(_, Var, _, _, _, _) :- + use(vel), + check_if_vel_done(Var), !. +bind_clpbn(_, Var, _, _, _, _) :- + use(jt), + check_if_vel_done(Var), !. +bind_clpbn(T, Var, Key0, _, _, _) :- + get_atts(Var, [key(Key)]), !, + ( + Key = Key0 -> true + ; + add_evidence(Var,T) + ). + +fresh_attvar(Var, NVar) :- + get_atts(Var, LAtts), + put_atts(NVar, LAtts). + +% I will now allow two CLPBN variables to be bound together. +%bind_clpbns(Key, Dist, Parents, Key, Dist, Parents). +bind_clpbns(Key, Dist, Parents, Key1, Dist1, Parents1) :- + Key == Key1, !, + get_dist(Dist,Type,Domain,Table), + get_dist(Dist1,Type1,Domain1,Table1), + ( Dist == Dist1, + same_parents(Parents,Parents1) + -> + true + ; + throw(error(domain_error(bayesian_domain),bind_clpbns(var(Dist, Key, Type, Domain, Table, Parents),var(Dist1, Key1, Type1, Domain1, Table1, Parents1)))) + ). +bind_clpbns(Key, _, _, _, Key1, _, _, _) :- + Key\=Key1, !, fail. +bind_clpbns(_, _, _, _, _, _, _, _) :- + format(user_error, 'unification of two bayesian vars not supported~n', []). + +same_parents([],[]). +same_parents([P|Parents],[P1|Parents1]) :- + same_node(P,P1), + same_parents(Parents,Parents1). + +same_node(P,P1) :- P == P1, !. +same_node(P,P1) :- + get_atts( P,[key(K)]), + get_atts(P1,[key(K)]), + P = P1. + + +bind_evidence_from_extra_var(Ev1,Var) :- + get_atts(Var, [evidence(Ev0)]), !, + Ev0 = Ev1. +bind_evidence_from_extra_var(Ev1,Var) :- + put_atts(Var, [evidence(Ev1)]). + +user:term_expansion((A :- {}), ( :- true )) :- !, % evidence + prolog_load_context(module, M), + store_evidence(M:A). + +clpbn_key(Var,Key) :- + get_atts(Var, [key(Key)]). + +% +% This is a routine to start a solver, called by the learning procedures (ie, em). +% LVs is a list of lists of variables one is interested in eventually marginalising out +% Vs0 gives the original graph +% AllDiffs gives variables that are not fully constrainted, ie, we don't fully know +% the key. In this case, we assume different instances will be bound to different +% values at the end of the day. +% +clpbn_init_solver(LVs, Vs0, VarsWithUnboundKeys, State) :- + solver(Solver), + clpbn_init_solver(Solver, LVs, Vs0, VarsWithUnboundKeys, State). + +clpbn_init_solver(gibbs, LVs, Vs0, VarsWithUnboundKeys, State) :- + init_gibbs_solver(LVs, Vs0, VarsWithUnboundKeys, State). +clpbn_init_solver(vel, LVs, Vs0, VarsWithUnboundKeys, State) :- + init_vel_solver(LVs, Vs0, VarsWithUnboundKeys, State). +clpbn_init_solver(jt, LVs, Vs0, VarsWithUnboundKeys, State) :- + init_jt_solver(LVs, Vs0, VarsWithUnboundKeys, State). + +% +% LVs is the list of lists of variables to marginalise +% Vs is the full graph +% Ps are the probabilities on LVs. +% +% +clpbn_run_solver(LVs, LPs, State) :- + solver(Solver, State), + clpbn_run_solver(Solver, LVs, LPs, State). + +clpbn_run_solver(gibbs, LVs, LPs, State) :- + run_gibbs_solver(LVs, LPs, State). +clpbn_run_solver(vel, LVs, LPs, State) :- + run_vel_solver(LVs, LPs, State). +clpbn_run_solver(jt, LVs, LPs, State) :- + run_jt_solver(LVs, LPs, State). + diff --git a/packages/CLPBN/clpbn/aggregates.yap b/packages/CLPBN/clpbn/aggregates.yap new file mode 100644 index 000000000..ac9ed492d --- /dev/null +++ b/packages/CLPBN/clpbn/aggregates.yap @@ -0,0 +1,283 @@ +% +% generate explicit CPTs +% +:- module(clpbn_aggregates, [ + check_for_agg_vars/2, + cpt_average/6, + cpt_average/7, + cpt_max/6, + cpt_min/6 + ]). + +:- use_module(library(clpbn), [{}/1]). + +:- use_module(library(lists), + [last/2, + sumlist/2, + sum_list/3, + max_list/2, + min_list/2, + nth0/3 + ]). + +:- use_module(library(matrix), + [matrix_new/3, + matrix_to_list/2, + matrix_set/3]). + +:- use_module(library('clpbn/dists'), + [ + dist/4, + get_dist_domain_size/2]). + +:- use_module(library('clpbn/matrix_cpt_utils'), + [normalise_CPT_on_lines/3]). + +check_for_agg_vars([], []). +check_for_agg_vars([V|Vs0], [V|Vs1]) :- + clpbn:get_atts(V, [key(K), dist(Id,Parents)]), !, + simplify_dist(Id, V, K, Parents, Vs0, Vs00), + check_for_agg_vars(Vs00, Vs1). +check_for_agg_vars([_|Vs0], Vs1) :- + check_for_agg_vars(Vs0, Vs1). + +% transform aggregate distribution into tree +simplify_dist(avg(Domain), V, Key, Parents, Vs0, VsF) :- !, + cpt_average([V|Parents], Key, Domain, NewDist, Vs0, VsF), + dist(NewDist, Id, Key, ParentsF), + clpbn:put_atts(V, [dist(Id,ParentsF)]). +simplify_dist(_, _, _, _, Vs0, Vs0). + +cpt_average(AllVars, Key, Els0, Tab, Vs, NewVs) :- + cpt_average(AllVars, Key, Els0, 1.0, Tab, Vs, NewVs). + +% support variables with evidence from domain. This should make everyone's life easier. +cpt_average([Ev|Vars], Key, Els0, Softness, p(Els0, CPT, NewParents), Vs, NewVs) :- + find_evidence(Vars, 0, TotEvidence, RVars), + build_avg_table(RVars, Vars, Els0, Key, TotEvidence, Softness, MAT0, NewParents0, Vs, IVs), + include_qevidence(Ev, MAT0, MAT, NewParents0, NewParents, Vs, IVs, NewVs), + matrix_to_list(MAT, CPT), writeln(NewParents: Vs: NewVs: CPT). + +% find all fixed kids, this simplifies significantly the function. +find_evidence([], TotEvidence, TotEvidence, []). +find_evidence([V|Vars], TotEvidence0, TotEvidence, RVars) :- + clpbn:get_atts(V,[evidence(Ev)]), !, + TotEvidenceI is TotEvidence0+Ev, + find_evidence(Vars, TotEvidenceI, TotEvidence, RVars). +find_evidence([V|Vars], TotEvidence0, TotEvidence, [V|RVars]) :- + find_evidence(Vars, TotEvidence0, TotEvidence, RVars). + +cpt_max([_|Vars], Key, Els0, CPT, Vs, NewVs) :- + build_max_table(Vars, Els0, Els0, Key, 1.0, CPT, Vs, NewVs). + +cpt_min([_|Vars], Key, Els0, CPT, Vs, NewVs) :- + build_min_table(Vars, Els0, Els0, Key, 1.0, CPT, Vs, NewVs). + +build_avg_table(Vars, OVars, Domain, _, TotEvidence, Softness, CPT, Vars, Vs, Vs) :- + length(Domain, SDomain), + int_power(Vars, SDomain, 1, TabSize), + TabSize =< 256, + /* case gmp is not there !! */ + TabSize > 0, !, + average_cpt(Vars, OVars, Domain, TotEvidence, Softness, CPT). +build_avg_table(Vars, OVars, Domain, Key, TotEvidence, Softness, CPT, [V1,V2], Vs, [V1,V2|NewVs]) :- + length(Vars,L), + LL1 is L//2, + LL2 is L-LL1, + list_split(LL1, Vars, L1, L2), + Min = 0, + length(Domain,Max1), Max is Max1-1, + build_intermediate_table(LL1, sum(Min,Max), L1, V1, Key, 1.0, 0, I1, Vs, Vs1), + build_intermediate_table(LL2, sum(Min,Max), L2, V2, Key, 1.0, I1, _, Vs1, NewVs), + average_cpt([V1,V2], OVars, Domain, TotEvidence, Softness, CPT). + +build_max_table(Vars, Domain, Softness, p(Domain, CPT, Vars), Vs, Vs) :- + length(Domain, SDomain), + int_power(Vars, SDomain, 1, TabSize), + TabSize =< 16, + /* case gmp is not there !! */ + TabSize > 0, !, + max_cpt(Vars, Domain, Softness, CPT). +build_max_table(Vars, Domain, Softness, p(Domain, CPT, [V1,V2]), Vs, [V1,V2|NewVs]) :- + length(Vars,L), + LL1 is L//2, + LL2 is L-LL1, + list_split(LL1, Vars, L1, L2), + build_intermediate_table(LL1, max(Domain,CPT), L1, V1, Key, 1.0, 0, I1, Vs, Vs1), + build_intermediate_table(LL2, max(Domain,CPT), L2, V2, Key, 1.0, I1, _, Vs1, NewVs), + max_cpt([V1,V2], Domain, Softness, CPT). + +build_min_table(Vars, Domain, Softness, p(Domain, CPT, Vars), Vs, Vs) :- + length(Domain, SDomain), + int_power(Vars, SDomain, 1, TabSize), + TabSize =< 16, + /* case gmp is not there !! */ + TabSize > 0, !, + min_cpt(Vars, Domain, Softness, CPT). +build_min_table(Vars, Domain, Softness, p(Domain, CPT, [V1,V2]), Vs, [V1,V2|NewVs]) :- + length(Vars,L), + LL1 is L//2, + LL2 is L-LL1, + list_split(LL1, Vars, L1, L2), + build_intermediate_table(LL1, min(Domain,CPT), L1, V1, Key, 1.0, 0, I1, Vs, Vs1), + build_intermediate_table(LL2, min(Domain,CPT), L2, V2, Key, 1.0, I1, _, Vs1, NewVs), + min_cpt([V1,V2], Domain, Softness, CPT). + +int_power([], _, TabSize, TabSize). +int_power([_|L], X, I0, TabSize) :- + I is I0*X, + int_power(L, X, I, TabSize). + +build_intermediate_table(1,_,[V],V, _, _, I, I, Vs, Vs) :- !. +build_intermediate_table(2, Op, [V1,V2], V, Key, Softness, I0, If, Vs, Vs) :- !, + If is I0+1, + generate_tmp_random(Op, 2, [V1,V2], V, Key, Softness, I0). +build_intermediate_table(N, Op, L, V, Key, Softness, I0, If, Vs, [V1,V2|NewVs]) :- + LL1 is N//2, + LL2 is N-LL1, + list_split(LL1, L, L1, L2), + I1 is I0+1, + build_intermediate_table(LL1, Op, L1, V1, Key, Softness, I1, I2, Vs, Vs1), + build_intermediate_table(LL2, Op, L2, V2, Key, Softness, I2, If, Vs1, NewVs), + generate_tmp_random(Op, N, [V1,V2], V, Key, Softness, I0). + +% averages are transformed into sums. +generate_tmp_random(sum(Min,Max), N, [V1,V2], V, Key, Softness, I) :- + Lower is Min*N, + Upper is Max*N, + generate_list(Lower, Upper, Nbs), + sum_cpt([V1,V2], Nbs, Softness, CPT), +% write(sum(Nbs, CPT, [V1,V2])),nl, % debugging + { V = 'AVG'(I,Key) with p(Nbs,CPT,[V1,V2]) }. +generate_tmp_random(max(Domain,CPT), _, [V1,V2], V, Key, I) :- + { V = 'MAX'(I,Key) with p(Domain,CPT,[V1,V2]) }. +generate_tmp_random(min(Domain,CPT), _, [V1,V2], V, Key, I) :- + { V = 'MIN'(I,Key) with p(Domain,CPT,[V1,V2]) }. + +generate_list(M, M, [M]) :- !. +generate_list(I, M, [I|Nbs]) :- + I1 is I+1, + generate_list(I1, M, Nbs). + +list_split(0, L, [], L) :- !. +list_split(I, [H|L], [H|L1], L2) :- + I1 is I-1, + list_split(I1, L, L1, L2). + +% +% if we have evidence, we need to check if we are always consistent, never consistent, or can be consistent +% +include_qevidence(V, MAT0, MAT, NewParents0, NewParents, Vs, IVs, NewVs) :- + clpbn:get_atts(V,[evidence(Ev)]), !, + normalise_CPT_on_lines(MAT0, MAT1, L1), + check_consistency(L1, Ev, MAT0, MAT1, L1, MAT, NewParents0, NewParents, Vs, IVs, NewVs). +include_qevidence(_, MAT, MAT, NewParents, NewParents, _, Vs, Vs). + +check_consistency(L1, Ev, MAT0, MAT1, L1, MAT, NewParents0, NewParents, Vs, IVs, NewVs) :- + sumlist(L1, Tot), + nth0(Ev, L1, Val), + (Val == Tot -> +writeln(Ev:L1:Val:1), + MAT1 = MAT, + NewParents = [], + Vs = NewVs + ; + Val == 0.0 -> +writeln(Ev:L1:Val:2), + throw(error(domain_error(incompatible_evidence),evidence(Ev))) + ; +writeln(Ev:L1:Val:3), + MAT0 = MAT, + NewParents = NewParents0, + IVs = NewVs + ). + + +% +% generate actual table, instead of trusting the solver +% + +average_cpt(Vs, OVars, Vals, Base, _, MCPT) :- + get_ds_lengths(Vs,Lengs), + length(OVars, N), + length(Vals, SVals), + matrix_new(floats,[SVals|Lengs],MCPT), + fill_in_average(Lengs,N,Base,MCPT). + +get_ds_lengths([],[]). +get_ds_lengths([V|Vs],[Sz|Lengs]) :- + get_vdist_size(V, Sz), + get_ds_lengths(Vs,Lengs). + +fill_in_average(Lengs, N, Base, MCPT) :- + generate(Lengs, Case), + average(Case, N, Base, Val), + matrix_set(MCPT,[Val|Case],1.0), + fail. +fill_in_average(_,_,_,_). + +generate([], []). +generate([N|Lengs], [C|Case]) :- + from(0,N,C), + generate(Lengs, Case). + +from(I,_,I). +from(I1,M,J) :- + I is I1+1, + I < M, + from(I,M,J). + +average(Case, N, Base, Val) :- + sum_list(Case, Base, Tot), + Val is integer(round(Tot/N)). + + +sum_cpt(Vs,Vals,_,CPT) :- + get_ds_lengths(Vs,Lengs), + length(Vals,SVals), + matrix_new(floats,[SVals|Lengs],MCPT), + fill_in_sum(Lengs,MCPT), + matrix_to_list(MCPT,CPT). + +fill_in_sum(Lengs,MCPT) :- + generate(Lengs, Case), + sumlist(Case, Val), + matrix_set(MCPT,[Val|Case],1.0), + fail. +fill_in_sum(_,_). + + +max_cpt(Vs,Vals,_,CPT) :- + get_ds_lengths(Vs,Lengs), + length(Vals,SVals), + matrix_new(floats,[SVals|Lengs],MCPT), + fill_in_max(Lengs,MCPT), + matrix_to_list(MCPT,CPT). + +fill_in_max(Lengs,MCPT) :- + generate(Lengs, Case), + max_list(Case, Val), + matrix_set(MCPT,[Val|Case],1.0), + fail. +fill_in_max(_,_). + + +min_cpt(Vs,Vals,_,CPT) :- + get_ds_lengths(Vs,Lengs), + length(Vals,SVals), + matrix_new(floats,[SVals|Lengs],MCPT), + fill_in_max(Lengs,MCPT), + matrix_to_list(MCPT,CPT). + +fill_in_min(Lengs,MCPT) :- + generate(Lengs, Case), + max_list(Case, Val), + matrix_set(MCPT,[Val|Case],1.0), + fail. +fill_in_min(_,_). + + +get_vdist_size(V, Sz) :- + clpbn:get_atts(V, [dist(Dist,_)]), + get_dist_domain_size(Dist, Sz). + diff --git a/packages/CLPBN/clpbn/bnt.yap b/packages/CLPBN/clpbn/bnt.yap new file mode 100644 index 000000000..f510abacd --- /dev/null +++ b/packages/CLPBN/clpbn/bnt.yap @@ -0,0 +1,425 @@ +:- module(bnt, [do_bnt/3, + create_bnt_graph/2, + check_if_bnt_done/1]). + +:- use_module(library('clpbn/display'), [ + clpbn_bind_vals/3]). + +:- use_module(library('clpbn/dists'), [ + get_dist_domain_size/2, + get_dist_domain/2, + get_dist_params/2 + ]). + +:- use_module(library('clpbn/discrete_utils'), [ + reorder_CPT/5]). + +:- use_module(library(matlab), [start_matlab/1, + close_matlab/0, + matlab_on/0, + matlab_eval_string/1, + matlab_eval_string/2, + matlab_matrix/4, + matlab_vector/2, + matlab_sequence/3, + matlab_initialized_cells/4, + matlab_get_variable/2, + matlab_call/2 + ]). + +:- use_module(library(dgraphs), [dgraph_new/1, + dgraph_add_vertices/3, + dgraph_add_edges/3, + dgraph_top_sort/2, + dgraph_vertices/2, + dgraph_edges/2 + ]). + +:- use_module(library(lists), [append/3, + member/2,nth/3]). + +:- use_module(library(ordsets), [ + ord_insert/3]). + +:- yap_flag(write_strings,on). + +% syntactic sugar for matlab_call. +:- op(800,yfx,<--). + +G <-- Y :- + matlab_call(Y,G). + +:- attribute bnt_id/1. + +:- dynamic bnt/1. + +:- dynamic bnt_solver/1, bnt_path/1, bnt_model/1. + +% belprop +bnt_solver(jtree). +% likelihood_weighting + +bnt_path("$HOME/Yap/CLPBN/FullBNT-1.0.4/BNT"). + + +% +% What BNT are we using: +% a propositional one +% a tied parameter one. +% +%bnt_model(propositional). +bnt_model(tied). +%bnt_model(dbn). + +/***************************************** + +BNT uses: + bnet + dag + discrete_nodes: which nodes are discrete (all by now), + node_sizes + engine + evidence + marg + +*****************************************/ + + +check_if_bnt_done(Var) :- + get_atts(Var, [map(_)]). + +do_bnt([], _, _) :- !. +do_bnt(QueryVars, AllVars, AllDiffs) :- + create_bnt_graph(AllVars, _, SortedVertices, NumberedVertices, Size), + set_inference, + add_evidence(SortedVertices, Size, NumberedVertices), + marginalize(QueryVars, SortedVertices, NumberedVertices, Ps), + clpbn_bind_vals(QueryVars, Ps, AllDiffs). + +create_bnt_graph(AllVars, Representatives) :- + create_bnt_graph(AllVars, Representatives, _, _, _). + +create_bnt_graph(AllVars, Representatives, SortedVertices, NumberedVertices, Size) :- + init_matlab, + sort_nodes(AllVars, SortedVertices), + number_graph(SortedVertices, NumberedVertices, 0, Size), + bnt_model(ModelType), + init_bnet(ModelType, SortedVertices, NumberedVertices, Size, Representatives). + + +% make sure MATLAB works. + +init_matlab :- + bnt(on), !. +init_matlab :- + start_matlab, + bnt_path(Path), + append("cd ",Path,Command), +% atom_concat('cd ', Path, Command), + matlab_eval_string(Command), + matlab_eval_string('addpath(genpathKPM(pwd))',_), + assert(bnt(on)). + + +start_matlab :- + matlab_on, !. +start_matlab :- + start_matlab('matlab -nojvm -nosplash'). + +sort_nodes(AllVars, SortedVertices) :- + bnt_model(tied), !, + extract_tied(AllVars, SortedVertices). +sort_nodes(AllVars, SortedVertices) :- + bnt_model(propositional), !, + extract_graph(AllVars, Graph), + dgraph_top_sort(Graph, SortedVertices). + +extract_tied(AllVars, SortedVars) :- + extract_kvars(AllVars,KVars), + keysort(KVars,SVars), + split_tied_vars(SVars,TVars, Vertices), + tied_graph(TVars,TGraph,Vertices), + dgraph_top_sort(TGraph, Sort), + distribute_tied_variables(Sort, TVars, 1, SortedVars). + +extract_kvars([],[]). +extract_kvars([V|AllVars],[N-i(V,Parents)|KVars]) :- + clpbn:get_atts(V, [dist(N,Parents)]), + extract_kvars(AllVars,KVars). + +split_tied_vars([],[],[]). +split_tied_vars([N-i(V,Par)|More],[N-g(Vs,Ns,Es)|TVars],[N|LNs]) :- + get_pars(Par,N,V,NPs,[],Es0,Es), + get_tied(More,N,Vs,[V],Ns,NPs,Es,Es0,SVars), + split_tied_vars(SVars,TVars,LNs). + +get_pars([],_,_,NPs,NPs,Es,Es). +get_pars([V|Par],N,V0,NPs,NPs0,Es,Es0) :- + clpbn:get_atts(V, [dist(N,_)]), !, + get_pars(Par,N,V0,NPs,NPs0,Es,[V-V0|Es0]). +get_pars([V|Par],N,V0,NPs,NPs0,Es,Es0) :- + clpbn:get_atts(V, [dist(M,_)]), + ord_insert(NPs0,M,NPsI), + get_pars(Par,N,V0,NPs,NPsI,Es,Es0). + +get_tied([N-i(V,Par)|More],N,Vs,Vs0,Ns,NPs,Es,Es0,SVars) :- !, + get_pars(Par,N,V,NPsI,NPs,EsI,Es0), + get_tied(More,N,Vs,[V|Vs0],Ns,NPsI,Es,EsI,SVars). +get_tied(More,_,Vs,Vs,Ns,Ns,Es,Es,More). + +tied_graph(TVars,Graph,Vertices) :- + dgraph_new(Graph0), + dgraph_add_vertices(Graph0, Vertices, Graph1), + get_tied_edges(TVars,Edges), + dgraph_add_edges(Graph1, Edges, Graph). + +get_tied_edges([],[]). +get_tied_edges([N-g(_,Vs,_)|TGraph],Edges) :- + add_tied(Vs,N,Edges,Edges0), + get_tied_edges(TGraph,Edges0). + +add_tied([],_,Edges,Edges). +add_tied([N1|Vs],N,[N1-N|Edges],Edges0) :- + add_tied(Vs,N,Edges,Edges0). + +distribute_tied_variables([], _, _, []). +distribute_tied_variables([N|Sort], TVars, I0, SortedVars) :- + member(N-g(Vs,_,_),TVars), + distribute_tied(Vs,I0,In,SortedVars,SortedVars0), + distribute_tied_variables(Sort, TVars, In, SortedVars0). + +distribute_tied([],I,I,Vs,Vs). +distribute_tied([V|Vs],I0,In,[V|NVs],NVs0) :- + I is I0+1, + put_atts(V, [bnt_id(I0)]), +% clpbn:get_atts(V,[key(K)]), + distribute_tied(Vs,I,In,NVs,NVs0). + +extract_graph(AllVars, Graph) :- + dgraph_new(Graph0), + dgraph_add_vertices(Graph0, AllVars, Graph1), + get_edges(AllVars,Edges), + dgraph_add_edges(Graph1, Edges, Graph). + +get_edges([],[]). +get_edges([V|AllVars],Edges) :- + clpbn:get_atts(V, [dist(_,Parents)]), + add_parent_child(Parents,V,Edges,Edges0), + get_edges(AllVars,Edges0). + +add_parent_child([],_,Edges,Edges). +add_parent_child([P|Parents],V,[P-V|Edges],Edges0) :- + add_parent_child(Parents,V,Edges,Edges0). + +number_graph([], [], I, I). +number_graph([V|SortedGraph], [I|Is], I0, IF) :- + I is I0+1, + put_atts(V, [bnt_id(I)]), +% clpbn:get_atts(V,[key(K)]), +% write(I:K),nl, + number_graph(SortedGraph, Is, I, IF). + +init_bnet(propositional, SortedGraph, NumberedGraph, Size, []) :- + build_dag(SortedGraph, Size), + init_discrete_nodes(SortedGraph, Size), + bnet <-- mk_bnet(dag, node_sizes, \discrete, discrete_nodes), + dump_cpts(SortedGraph, NumberedGraph). + +init_bnet(tied, SortedGraph, NumberedGraph, Size, Representatives) :- + build_dag(SortedGraph, Size), + init_discrete_nodes(SortedGraph, Size), + dump_tied_cpts(SortedGraph, NumberedGraph, Representatives). + +build_dag(SortedVertices, Size) :- + get_numbered_edges(SortedVertices, Edges), + mkdag(Size, Edges). + +get_numbered_edges([], []). +get_numbered_edges([V|SortedVertices], Edges) :- + clpbn:get_atts(V, [dist(_,Ps)]), + v2number(V,N), + add_numbered_edges(Ps, N, Edges, Edges0), + get_numbered_edges(SortedVertices, Edges0). + +add_numbered_edges([], _, Edges, Edges). +add_numbered_edges([P|Ps], N, [PN-N|Edges], Edges0) :- + v2number(P,PN), + add_numbered_edges(Ps, N, Edges, Edges0). + +v2number(V,N) :- + get_atts(V,[bnt_id(N)]). + +init_discrete_nodes(SortedGraph, Size) :- + matlab_sequence(1,Size,discrete_nodes), + mksizes(SortedGraph, Size). + +mkdag(N,Els) :- + Tot is N*N, + functor(Dag,dag,Tot), + add_els(Els,N,Dag), + Dag=..[_|L], + addzeros(L), + matlab_matrix(N,N,L,dag). + +add_els([],_,_). +add_els([X-Y|Els],N,Dag) :- + Pos is (X-1)*N+Y, + arg(Pos,Dag,1), + add_els(Els,N,Dag). + +addzeros([]). +addzeros([0|L]) :- !, + addzeros(L). +addzeros([1|L]) :- + addzeros(L). + +mksizes(SortedVertices, Size) :- + get_szs(SortedVertices,Sizes), + matlab_matrix(1,Size,Sizes,node_sizes). + +get_szs([],[]). +get_szs([V|SortedVertices],[LD|Sizes]) :- + clpbn:get_atts(V, [dist(Id,_)]), + get_dist_domain_size(Id,LD), + get_szs(SortedVertices,Sizes). + +dump_cpts([], []). +dump_cpts([V|SortedGraph], [I|Is]) :- + clpbn:get_atts(V, [dist(Id,Parents)]), + get_dist_params(Id,CPT), + reorder_cpt(CPT,V,Parents,Tab), + mkcpt(bnet,I,Tab), + dump_cpts(SortedGraph, Is). + +% +% This is complicated, the BNT and we have different orders +% +reorder_cpt(CPT,_, [], CPT) :- !. +reorder_cpt(CPT,V,Parents,Tab) :- + % get BNT label + get_sizes_and_ids(Parents,Ids), + % sort to BNT + keysort(Ids,NIds), + % get vars in order + extract_vars(NIds, [], NParents), + % do the actual work + reorder_CPT([V|Parents],CPT,[V|NParents],STab,_), + STab=..[_|Tab]. + +get_sizes_and_ids([],[]). +get_sizes_and_ids([V|Parents],[Id-V|Ids]) :- + get_atts(V, [bnt_id(Id)]), + get_sizes_and_ids(Parents,Ids). + +extract_vars([], L, L). +extract_vars([_-V|NIds], NParents, Vs) :- + extract_vars(NIds, [V|NParents], Vs). + +mkcpt(BayesNet, I, Tab) :- + (BayesNet.'CPD'({I})) <-- tabular_CPD(BayesNet,I,Tab). + +dump_tied_cpts(Graph, Is, Reps) :- + create_class_vector(Graph, Is, Classes, Reps0), + matlab_vector(Classes, eclass), + keysort(Reps0,Reps1), + representatives(Reps1,Reps), + bnet <-- mk_bnet(dag, node_sizes, \discrete, discrete_nodes, \equiv_class, eclass), + dump_tied_cpts(Reps). + +create_class_vector([], [], [],[]). +create_class_vector([V|Graph], [I|Is], [Id|Classes], [Id-v(V,I,Parents)|Sets]) :- + clpbn:get_atts(V, [dist(Id,Parents)]), + create_class_vector(Graph, Is,Classes,Sets). + +representatives([],[]). +representatives([Class-Rep|Reps1],[Class-Rep|Reps]) :- + nonrepresentatives(Reps1, Class, Reps2), + representatives(Reps2,Reps). + +nonrepresentatives([Class-_|Reps1], Class, Reps2) :- !, + nonrepresentatives(Reps1, Class, Reps2). +nonrepresentatives(Reps, _, Reps). + + +dump_tied_cpts([]). +dump_tied_cpts([Class-v(V,Id,Parents)|SortedGraph]) :- + get_dist_params(Class,CPT), + reorder_cpt(CPT,V,Parents,NCPT), + mktiedcpt(bnet,Id,Class,NCPT), + dump_tied_cpts(SortedGraph). + +mktiedcpt(BayesNet, V, Class, Tab) :- + (BayesNet.'CPD'({Class})) <-- tabular_CPD(BayesNet,V,Tab). + +set_inference :- + bnt_solver(Solver), + init_solver(Solver). + +init_solver(jtree) :- + engine <-- jtree_inf_engine(bnet). +init_solver(belprop) :- + engine <-- belprop_inf_engine(bnet). +init_solver(likelihood_weighting) :- + engine <-- likelihood_weighting_inf_engine(bnet). +init_solver(enumerative) :- + engine <-- enumerative_inf_engine(bnet). +init_solver(gibbs) :- + engine <-- gibbs_sampling_inf_engine(bnet). +init_solver(global_joint) :- + engine <-- global_joint_inf_engine(bnet). +init_solver(pearl) :- + engine <-- pearl_inf_engine(bnet). +init_solver(var_elim) :- + engine <-- var_elim_inf_engine(bnet). + +add_evidence(Graph, Size, Is) :- + mk_evidence(Graph, Is, LN), + matlab_initialized_cells( 1, Size, LN, evidence), + [engine_ev, loglik] <-- enter_evidence(engine, evidence). + +mk_evidence([], [], []). +mk_evidence([V|L], [I|Is], [ar(1,I,EvVal1)|LN]) :- + clpbn:get_atts(V, [evidence(EvVal)]), !, + EvVal1 is EvVal +1, + mk_evidence(L, Is, LN). +mk_evidence([_|L], [_|Is], LN) :- + mk_evidence(L, Is, LN). + +evidence_val(Ev,Val,[Ev|_],Val) :- !. +evidence_val(Ev,I0,[_|Domain],Val) :- + I1 is I0+1, + evidence_val(Ev,I1,Domain,Val). + +marginalize([[V]], _SortedVars,_NunmberedVars, Ps) :- !, + v2number(V,Pos), + marg <-- marginal_nodes(engine_ev, Pos), + matlab_get_variable( marg.'T', Ps). + +marginalize([Vs], SortedVars, NumberedVars,Ps) :- + bnt_solver(jtree),!, + matlab_get_variable(loglik, Den), + clpbn_display:get_all_combs(Vs, Vals), + mk_evidence(SortedVars, NumberedVars, Ev), + length(SortedVars,L), + cycle_values(Den, Ev, Vs, L, Vals, Ps). + +cycle_values(_D, _Ev, _Vs, _Size, [], []). + +cycle_values(Den,Ev,Vs,Size,[H|T],[HP|TP]):- + mk_evidence_query(Vs, H, EvQuery), + append(EvQuery,Ev,Instantiation), + matlab_initialized_cells( 1, Size, Instantiation, instantiation), + [engine_ev, logll] <-- enter_evidence(engine, instantiation), + matlab_get_variable(logll, Num), + HP is exp(Num-Den), + cycle_values(Den,Ev,Vs,Size,T,TP). + +mk_evidence_query([], [], []). +mk_evidence_query([V|L], [H|T], [ar(1,Pos,El)|LN]) :- + v2number(V,Pos), + clpbn:get_atts(V, [dist(Id,_)]), + get_dist_domain(Id,D), + nth(El,D,H), + mk_evidence_query(L, T, LN). + + diff --git a/packages/CLPBN/clpbn/connected.yap b/packages/CLPBN/clpbn/connected.yap new file mode 100644 index 000000000..7b0e90860 --- /dev/null +++ b/packages/CLPBN/clpbn/connected.yap @@ -0,0 +1,172 @@ + +:- module(clpbn_connected, + [clpbn_subgraphs/2, + influences/4, + init_influences/3, + influences/5]). + +:- use_module(library(dgraphs), + [dgraph_new/1, + dgraph_add_edges/3, + dgraph_add_vertex/3, + dgraph_neighbors/3, + dgraph_edge/3]). + +:- use_module(library(rbtrees), + [rb_new/1, + rb_insert/4, + rb_lookup/3]). + +:- attribute component/1. + +% search for connected components, that is, where we know that A influences B or B influences A. +clpbn_subgraphs(Vs, Gs) :- + mark_components(Vs, Components), + keysort(Components, Ordered), + same_key(Ordered, Gs). + +% ignore variables with evidence, +% the others mark the MB. +mark_components([], []). +mark_components([V|Vs], Components) :- + clpbn:get_atts(V, [evidence(_),dist(_,Parents)]), !, + merge_parents(Parents, _), + mark_components(Vs, Components). +mark_components([V|Vs], [Mark-V|Components]) :- + mark_var(V, Mark), + mark_components(Vs, Components). + +mark_var(V, Mark) :- + get_atts(V, [component(Mark)]), !, + clpbn:get_atts(V, [dist(_,Parents)]), !, + merge_parents(Parents, Mark). +mark_var(V, Mark) :- + clpbn:get_atts(V, [dist(_,Parents)]), !, + put_atts(V,[component(Mark)]), + merge_parents(Parents, Mark). + +merge_parents([], _). +merge_parents([V|Parents], Mark) :- + clpbn:get_atts(V,[evidence(_)]), !, + merge_parents(Parents, Mark). +merge_parents([V|Parents], Mark) :- + get_atts(V,[component(Mark)]), !, + merge_parents(Parents, Mark). +merge_parents([V|Parents], Mark) :- + put_atts(V,[component(Mark)]), + merge_parents(Parents, Mark). + + +same_key([],[]). +same_key([K-El|More],[[El|Els]|Gs]) :- + same_keys(More, K, Els, Rest), + same_key(Rest,Gs). + +same_keys([], _, [], []). +same_keys([K1-El|More], K, [El|Els], Rest) :- + K == K1, !, + same_keys(More, K, Els, Rest). +same_keys(Rest, _, [], Rest). + +influences_more([], _, _, Is, Is, Evs, Evs, V2, V2). +influences_more([V|LV], G, RG, Is0, Is, Evs0, Evs, GV0, GV2) :- + rb_lookup(V, _, GV0), !, + influences_more(LV, G, RG, Is0, Is, Evs0, Evs, GV0, GV2). +influences_more([V|LV], G, RG, Is0, Is, Evs0, Evs, GV0, GV3) :- + rb_insert(GV0, V, _, GV1), + follow_dgraph(V, G, RG, [V|Is0], Is1, [V|Evs0], Evs1, GV1, GV2), + influences_more(LV, G, RG, Is1, Is, Evs1, Evs, GV2, GV3). + +% search for the set of variables that influence V +influences(Vs, LV, Is, Evs) :- + init_influences(Vs, G, RG), + influences(LV, Is, Evs, G, RG). + +init_influences(Vs, G, RG) :- + dgraph_new(G0), + dgraph_new(RG0), + to_dgraph(Vs, G0, G, RG0, RG). + +influences([], [], [], _, _). +influences([V|LV], Is, Evs, G, RG) :- + rb_new(V0), + rb_insert(V0, V, _, V1), + follow_dgraph(V, G, RG, [V], Is1, [V], Evs1, V1, V2), + influences_more(LV, G, RG, Is1, Is, Evs1, Evs, V2, _). + +to_dgraph([], G, G, RG, RG). +to_dgraph([V|Vs], G0, G, RG0, RG) :- + clpbn:get_atts(V, [evidence(_),dist(_,Parents)]), !, + build_edges(Parents, V, Edges, REdges), + dgraph_add_edges(G0,[V-e|Edges],G1), + dgraph_add_edges(RG0,REdges,RG1), + to_dgraph(Vs, G1, G, RG1, RG). +to_dgraph([V|Vs], G0, G, RG0, RG) :- + clpbn:get_atts(V, [dist(_,Parents)]), + build_edges(Parents, V, Edges, REdges), + dgraph_add_vertex(G0,V,G1), + dgraph_add_edges(G1, Edges, G2), + dgraph_add_vertex(RG0,V,RG1), + dgraph_add_edges(RG1, REdges, RG2), + to_dgraph(Vs, G2, G, RG2, RG). + + +build_edges([], _, [], []). +build_edges([P|Parents], V, [P-V|Edges], [V-P|REdges]) :- + build_edges(Parents, V, Edges, REdges). + +follow_dgraph(V, G, RG, Is0, IsF, Evs0, EvsF, Visited0, Visited) :- + dgraph_neighbors(V, RG, Parents), + add_parents(Parents, G, RG, Is0, IsI, Evs0, EvsI, Visited0, Visited1), + dgraph_neighbors(V, G, Kids), + add_kids(Kids, G, RG, IsI, IsF, EvsI, EvsF, Visited1, Visited). + +add_parents([], _, _, Is, Is, Evs, Evs, Visited, Visited). +% been here already, can safely ignore. +add_parents([V|Vs], G, RG, Is0, IsF, Evs0, EvsF, Visited0, VisitedF) :- + rb_lookup(V, _, Visited0), !, + add_parents(Vs, G, RG, Is0, IsF, Evs0, EvsF, Visited0, VisitedF). +% evidence node, +% just say that we visited it +add_parents([V|Vs], G, RG, Is0, IsF, Evs0, EvsF, Visited0, VisitedF) :- + dgraph_edge(V,e,G), !, % has evidence + rb_insert(Visited0, V, _, VisitedI), + add_parents(Vs, G, RG, Is0, IsF, [V|Evs0], EvsF, VisitedI, VisitedF). +% non-evidence node, +% we will need to find its parents. +add_parents([V|Vs], G, RG, Is0, IsF, Evs0, EvsF, Visited0, VisitedF) :- + rb_insert(Visited0, V, _, VisitedI), + follow_dgraph(V, G, RG, [V|Is0], IsI, [V|Evs0], EvsI, VisitedI, VisitedII), + add_parents(Vs, G, RG, IsI, IsF, EvsI, EvsF, VisitedII, VisitedF). + +add_kids([], _, _, Is, Is, Evs, Evs, Visited, Visited). +add_kids([V|Vs], G, RG, Is0, IsF, Evs0, EvsF, Visited0, VisitedF) :- + dgraph_edge(V,e,G), % has evidence + % we will go there even if it was visited + ( rb_insert(Visited0, V, _, Visited1) -> + true + ; + % we've been there, but were we there as a father or as a kid? + not_in(Evs0, V), + Visited1 = Visited0 + ), + !, + dgraph_neighbors(V, RG, Parents), + add_parents(Parents, G, RG, Is0, Is1, [V|Evs0], EvsI, Visited1, VisitedI), + (Is1 = Is0 -> + % ignore whatever we did with this node, + % it didn't lead anywhere (all parents have evidence). + add_kids(Vs, G, RG, Is0, IsF, [V|Evs0], EvsF, Visited1, VisitedF) + ; + % insert parents + add_kids(Vs, G, RG, Is1, IsF, EvsI, EvsF, VisitedI, VisitedF) + ). +add_kids([_|Vs], G, RG, Is0, IsF, Evs0, EvsF, Visited0, VisitedF) :- + add_kids(Vs, G, RG, Is0, IsF, Evs0, EvsF, Visited0, VisitedF). + + +not_in([V1|_], V) :- V1 == V, !, fail. +not_in([_|Evs0], V) :- + not_in(Evs0, V). + + diff --git a/packages/CLPBN/clpbn/discrete_utils.yap b/packages/CLPBN/clpbn/discrete_utils.yap new file mode 100644 index 000000000..35d15e0e5 --- /dev/null +++ b/packages/CLPBN/clpbn/discrete_utils.yap @@ -0,0 +1,146 @@ + +:- module(discrete_utils, [project_from_CPT/3, + reorder_CPT/5, + get_dist_size/2]). + +:- use_module(dists, [get_dist_domain_size/2, + get_dist_domain/2]). +% +% remove columns from a table +% +project_from_CPT(V,tab(Table,Deps,Szs),tab(NewTable,NDeps,NSzs)) :- + propagate_evidence(V,Evs), + functor(Table,_,Max), + find_projection_factor(Deps, V, NDeps, Szs, NSzs, F, Sz), + OLoop is Max//(Sz*F), + project_outer_loop(0,OLoop,F,Sz,Table,Evs,NTabl), + NewTable =.. [t|NTabl]. + +propagate_evidence(V, Evs) :- + clpbn:get_atts(V, [evidence(Ev),dist(Id,_)]), !, + get_dist_domain(Id, Out), + generate_szs_with_evidence(Out,Ev,0,Evs,Found), + (var(Found) -> + clpbn:get_atts(V, [key(K)]), + throw(clpbn(evidence_does_not_match,K,Ev,[Out])) + ; + true + ). +propagate_evidence(_, _). + +generate_szs_with_evidence([],_,_,[],_). +generate_szs_with_evidence([_|Out],Ev,Ev,[ok|Evs],found) :- !, + I is Ev+1, + generate_szs_with_evidence(Out,Ev,I,Evs,found). +generate_szs_with_evidence([_|Out],Ev,I0,[not_ok|Evs],Found) :- + I is I0+1, + generate_szs_with_evidence(Out,Ev,I,Evs,Found). + +find_projection_factor([V|Deps], V1, Deps, [Sz|Szs], Szs, F, Sz) :- + V == V1, !, + mult(Szs, 1, F). +find_projection_factor([V|Deps], V1, [V|NDeps], [Sz|Szs], [Sz|NSzs], F, NSz) :- + find_projection_factor(Deps, V1, NDeps, Szs, NSzs, F, NSz). + +mult([], F, F). +mult([Sz|Szs], Sz0, F) :- + SzI is Sz0*Sz, + mult(Szs, SzI, F). + +project_outer_loop(OLoop,OLoop,_,_,_,_,[]) :- !. +project_outer_loop(I,OLoop,F,Sz,Table,Evs,NTabl) :- + Base is I*Sz*F, + project_mid_loop(0,F,Base,Sz,Table,Evs,NTabl,NTabl0), + I1 is I+1, + project_outer_loop(I1,OLoop,F,Sz,Table,Evs,NTabl0). + +project_mid_loop(F,F,_,_,_,_,NTabl,NTabl) :- !. +project_mid_loop(I,F,Base,Sz,Table,Evs,[Ent|NTablF],NTabl0) :- + I1 is I+1, + NBase is I+Base, + project_inner_loop(0,Sz,Evs,NBase,F,Table,0.0,Ent), + project_mid_loop(I1,F,Base,Sz,Table,Evs,NTablF,NTabl0). + +project_inner_loop(Sz,Sz,[],_,_,_,Ent,Ent) :- !. +project_inner_loop(I,Sz,[ok|Evs],NBase,F,Table,Ent0,Ent) :- !, + I1 is I+1, + Pos is NBase+I*F+1, + arg(Pos,Table,E1), + Ent1 is E1+Ent0, + project_inner_loop(I1,Sz,Evs,NBase,F,Table,Ent1,Ent). +project_inner_loop(I,Sz,[_|Evs],NBase,F,Table,Ent0,Ent) :- !, + I1 is I+1, + project_inner_loop(I1,Sz,Evs,NBase,F,Table,Ent0,Ent). + +% +% Given a set of variables Vs0 and a discrete CPT T0, +% reorder according to keysort if Vs is unbound, or according to Vs +% resulting in CPT +% TF. Sizes of variables in Vs are given as Sizes. +% +reorder_CPT(Vs0, T0, Vs, TF, Sizes) :- + var(Vs), !, + get_sizes(Vs0, Szs), + numb_vars(Vs0, Szs, _, VPs0, VLs0), + keysort(VLs0, VLs), + compute_new_factors(VLs, _, Vs, Sizes), + get_factors(VLs0,Fs), + length(T0,L), + functor(TF,t,L), + copy_to_new_array(T0, 0, VPs0, Fs, TF). +reorder_CPT(Vs0, T0, Vs, TF, Sizes) :- + get_sizes(Vs0, Szs), + numb_vars(Vs0, Szs, _, VPs0, VLs0), + sort_according_to_parent(Vs, VLs0, VLs), + compute_new_factors(VLs, _, Vs, Sizes), + get_factors(VLs0,Fs), + length(T0,L), + functor(TF,t,L), + copy_to_new_array(T0, 0, VPs0, Fs, TF). + +numb_vars([], [], 1, [], []). +numb_vars([V|Vs], [L|Ls], A0, [Ai|VPs], [V-(L,_)|VLs]) :- + numb_vars(Vs, Ls, Ai, VPs, VLs), + A0 is Ai*L. + +sort_according_to_parent([],[], []). +sort_according_to_parent([V|Vs],VLs0, [Arg|VLs]) :- + fetch_var(V,VLs0,VLsI,Arg), + sort_according_to_parent(Vs,VLsI, VLs). + +fetch_var(V,[V0-(L,A)|VLs],VLs,V0-(L,A)) :- V == V0, !. +fetch_var(V,[A|VLs0],[A|VLsI],Arg) :- + fetch_var(V,VLs0,VLsI,Arg). + +compute_new_factors([], 1, [], []). +compute_new_factors([V-(L,F)|VLs], NF, [V|Vs], [L|Szs]) :- + compute_new_factors(VLs, F, Vs, Szs), + NF is F*L. + +get_factors([],[]). +get_factors([_-(_,F)|VLs0],[F|Fs]) :- + get_factors(VLs0,Fs). + +copy_to_new_array([], _, _, _, _). +copy_to_new_array([P|Ps], I, F0s, Fs, S) :- + convert_factor(F0s, Fs, I, N), + I1 is I+1, + N1 is N+1, + arg(N1,S,P), + copy_to_new_array(Ps, I1, F0s, Fs, S). + +convert_factor([], [], _, 0). +convert_factor([F0|F0s], [F|Fs], I, OUT) :- + X is I//F0, + NI is I mod F0, + NEXT is F*X, + convert_factor(F0s, Fs, NI, OUT1), + OUT is OUT1+NEXT. + +get_sizes([], []). +get_sizes([V|Deps], [Sz|Sizes]) :- + clpbn:get_atts(V, [dist(Id,_)]), + get_dist_domain_size(Id,Sz), + get_sizes(Deps, Sizes). + + diff --git a/packages/CLPBN/clpbn/display.yap b/packages/CLPBN/clpbn/display.yap new file mode 100644 index 000000000..cce28aeee --- /dev/null +++ b/packages/CLPBN/clpbn/display.yap @@ -0,0 +1,71 @@ +:- module(clpbn_display, [ + clpbn_bind_vals/3]). + +:- use_module(library(lists), + [ + member/2 + ]). + +:- use_module(dists, [get_dist_domain/2]). + +:- attribute posterior/4. + + +% +% what is actually output +% +attribute_goal(V, G) :- + clpbn:suppress_attribute_display(false), + get_atts(V, [posterior(Vs,Vals,Ps,AllDiffs)]), + massage_out(Vs, Vals, Ps, G, AllDiffs, V). + +massage_out([], Ev, _, V=Ev, _, V) :- !. +massage_out(Vs, [D], [P], p(CEqs)=P, AllDiffs, _) :- !, + gen_eqs(Vs,D,Eqs), + add_alldiffs(AllDiffs,Eqs,CEqs). +massage_out(Vs, [D|Ds], [P|Ps], (p(CEqs)=P,G) , AllDiffs, V) :- + gen_eqs(Vs,D,Eqs), + add_alldiffs(AllDiffs,Eqs,CEqs), + massage_out(Vs, Ds, Ps, G, AllDiffs, V). + +gen_eqs([V], [D], (V=D)) :- !. +gen_eqs([V], D, (V=D)) :- !. +gen_eqs([V|Vs], [D|Ds], ((V=D),Eqs)) :- + gen_eqs(Vs,Ds,Eqs). + +add_alldiffs([],Eqs,Eqs). +add_alldiffs(AllDiffs,Eqs,(Eqs/alldiff(AllDiffs))). + + +clpbn_bind_vals([],[],_). +clpbn_bind_vals([Vs|MoreVs],[Ps|MorePs],AllDiffs) :- + clpbn_bind_vals2(Vs, Ps, AllDiffs), + clpbn_bind_vals(MoreVs,MorePs,AllDiffs). + +clpbn_bind_vals2([],_,_) :- !. +% simple case, we want a distribution on a single variable. +%bind_vals([V],Ps) :- !, +% clpbn:get_atts(V, [dist(Vals,_,_)]), +% put_atts(V, posterior([V], Vals, Ps)). +% complex case, we want a joint distribution, do it on a leader. +% should split on cliques ? +clpbn_bind_vals2(Vs,Ps,AllDiffs) :- + get_all_combs(Vs, Vals), + Vs = [V|_], + put_atts(V, posterior(Vs, Vals, Ps, AllDiffs)). + +get_all_combs(Vs, Vals) :- + get_all_doms(Vs,Ds), + findall(L,ms(Ds,L),Vals). + +get_all_doms([], []). +get_all_doms([V|Vs], [D|Ds]) :- + clpbn:get_atts(V, [dist(Id,_)]), + get_dist_domain(Id,D), + get_all_doms(Vs, Ds). + +ms([], []). +ms([H|L], [El|Els]) :- + member(El,H), + ms(L, Els). + diff --git a/packages/CLPBN/clpbn/dists.yap b/packages/CLPBN/clpbn/dists.yap new file mode 100644 index 000000000..4028c93ba --- /dev/null +++ b/packages/CLPBN/clpbn/dists.yap @@ -0,0 +1,316 @@ +% +% routines to manipulate distributions +% + +:- module(clpbn_dist, + [ + dist/1, + dist/4, + dists/1, + dist_new_table/2, + get_dist/4, + get_dist_matrix/5, + get_possibly_deterministic_dist_matrix/5, + get_dist_domain/2, + get_dist_domain_size/2, + get_dist_params/2, + get_dist_key/2, + get_evidence_position/3, + get_evidence_from_position/3, + dist_to_term/2, + empty_dist/2, + all_dist_ids/1, + randomise_all_dists/0, + randomise_dist/1, + uniformise_all_dists/0, + uniformise_dist/1, + reset_all_dists/0 + ]). + +:- use_module(library(lists),[is_list/1,nth0/3]). + +:- use_module(library(matrix), + [matrix_new/4, + matrix_new/3, + matrix_to_list/2, + matrix_to_logs/1]). + +:- use_module(library('clpbn/matrix_cpt_utils'), + [random_CPT/2, + uniform_CPT/2]). + +/* +:- mode dist(+, -). + +:- mode get_dist(+, -, -, -). + +:- mode get_dist_params(+, -). + +:- mode get_dist_domain_size(+, -). + +:- mode get_dist_domain(+, -). + +:- mode get_dist_nparams(+, -). + +:- mode dist(?). + +:- mode dist_to_term(+,-). +*/ + +/******************************************* + +store stuff in a DB of the form: + db(Id, Key, CPT, Type, Domain, CPTSize, DSize) + +where Id is the id, + Key is a skeleton of the key(main functor only) + cptsize is the table size or -1, + DSize is the domain size, + Type is + tab for tabular + avg for average + max for maximum + min for minimum + trans for HMMs + continuous + Domain is + a list of values + bool for [t,f] + aminoacids for [a,c,d,e,f,g,h,i,k,l,m,n,p,q,r,s,t,v,w,y] + dna for [a,c,g,t] + rna for [a,c,g,u] + reals + + +********************************************/ + + :- dynamic id/1. + +id(1). + +new_id(Id) :- + retract(id(Id)), + Id1 is Id+1, + assert(id(Id1)). + +reset_id :- + retract(id(_)), + assert(id(1)). + +dists(X) :- id(X1), X is X1-1. + +dist(V, Id, Key, Parents) :- + dist_unbound(V, Culprit), !, + when(Culprit, dist(V, Id, Key, Parents)). +dist(V, Id, Key, Parents) :- + var(Key), !, + when(Key, dist(V, Id, Key, Parents)). +dist(avg(Domain, Parents), avg(Domain), _, Parents). +dist(max(Domain, Parents), max(Domain), _, Parents). +dist(min(Domain, Parents), min(Domain), _, Parents). +dist(p(Type, CPT), Id, Key, FParents) :- + copy_structure(Key, Key0), + distribution(Type, CPT, Id, Key0, [], FParents). +dist(p(Type, CPT, Parents), Id, Key, FParents) :- + copy_structure(Key, Key0), + distribution(Type, CPT, Id, Key0, Parents, FParents). + +dist_unbound(V, ground(V)) :- + var(V), !. +dist_unbound(p(Type,_), ground(Type)) :- + \+ ground(Type), !. +dist_unbound(p(_,CPT), ground(CPT)) :- + \+ ground(CPT). +dist_unbound(p(Type,_,_), ground(Type)) :- + \+ ground(Type), !. +dist_unbound(p(_,CPT,_), ground(CPT)) :- + \+ ground(CPT). + +distribution(bool, trans(CPT), Id, Key, Parents, FParents) :- + is_list(CPT), !, + compress_hmm_table(CPT, Parents, Tab, FParents), + add_dist([t,f], trans, Tab, Parents, Key, Id). +distribution(bool, CPT, Id, Key, Parents, Parents) :- + is_list(CPT), !, + add_dist([t,f], tab, CPT, Parents, Key, Id). +distribution(aminoacids, trans(CPT), Id, Key, Parents, FParents) :- + is_list(CPT), !, + compress_hmm_table(CPT, Parents, Tab, FParents), + add_dist([a,c,d,e,f,g,h,i,k,l,m,n,p,q,r,s,t,v,w,y], trans, Tab, FParents, Key, Id). +distribution(aminoacids, CPT, Id, Key, Parents, Parents) :- + is_list(CPT), !, + add_dist([a,c,d,e,f,g,h,i,k,l,m,n,p,q,r,s,t,v,w,y], tab, CPT, Parents, Key, Id). +distribution(dna, trans(CPT), Key, Id, Parents, FParents) :- + is_list(CPT), !, + compress_hmm_table(CPT, Parents, Tab, FParents), + add_dist([a,c,g,t], trans, Tab, FParents, Key, Id). +distribution(dna, CPT, Id, Key, Parents, Parents) :- + is_list(CPT), !, + add_dist([a,c,g,t], tab, CPT, Key, Id). +distribution(rna, trans(CPT), Id, Key, Parents, FParents) :- + is_list(CPT), !, + compress_hmm_table(CPT, Parents, Tab, FParents, FParents), + add_dist([a,c,g,u], trans, Tab, Key, Id). +distribution(rna, CPT, Id, Key, Parents, Parents) :- + is_list(CPT), !, + add_dist([a,c,g,u], tab, CPT, Parents, Key, Id). +distribution(Domain, trans(CPT), Id, Key, Parents, FParents) :- + is_list(Domain), + is_list(CPT), !, + compress_hmm_table(CPT, Parents, Tab, FParents), + add_dist(Domain, trans, Tab, FParents, Key, Id). +distribution(Domain, CPT, Id, Key, Parents, Parents) :- + is_list(Domain), + is_list(CPT), !, + add_dist(Domain, tab, CPT, Parents, Key, Id). + +add_dist(Domain, Type, CPT, _, Key, Id) :- + recorded(clpbn_dist_db, db(Id, Key, CPT, Type, Domain, _, _), _), !. +add_dist(Domain, Type, CPT, Parents, Key, Id) :- + length(CPT, CPTSize), + length(Domain, DSize), + new_id(Id), + record_parent_sizes(Parents, Id, PSizes, [DSize|PSizes]), + recordz(clpbn_dist_db,db(Id, Key, CPT, Type, Domain, CPTSize, DSize),_). + + +record_parent_sizes([], Id, [], DSizes) :- + recordz(clpbn_dist_psizes,db(Id, DSizes),_). +record_parent_sizes([P|Parents], Id, [Size|Sizes], DSizes) :- + clpbn:get_atts(P,dist(Dist,_)), !, + get_dist_domain_size(Dist, Size), + record_parent_sizes(Parents, Id, Sizes, DSizes). +record_parent_sizes([_|_], _, _, _). + +% +% Often, * is used to code empty in HMMs. +% +compress_hmm_table([], [], [], []). +compress_hmm_table([*|L],[_|Parents],NL,NParents) :- !, + compress_hmm_table(L,Parents,NL,NParents). +compress_hmm_table([Prob|L],[P|Parents],[Prob|NL],[P|NParents]) :- + compress_hmm_table(L,Parents,NL,NParents). + +dist(Id) :- + recorded(clpbn_dist_db, db(Id, _, _, _, _, _, _), _). + +get_dist(Id, Type, Domain, Tab) :- + recorded(clpbn_dist_db, db(Id, _, Tab, Type, Domain, _, _), _). + +get_dist_matrix(Id, Parents, Type, Domain, Mat) :- + recorded(clpbn_dist_db, db(Id, _, Tab, Type, Domain, _, DomainSize), _), + get_dsizes(Parents, Sizes, []), + matrix_new(floats, [DomainSize|Sizes], Tab, Mat), + matrix_to_logs(Mat). + +get_possibly_deterministic_dist_matrix(Id, Parents, Type, Domain, Mat) :- + recorded(clpbn_dist_db, db(Id, _, Tab, Type, Domain, _, DomainSize), _), + get_dsizes(Parents, Sizes, []), + matrix_new(floats, [DomainSize|Sizes], Tab, Mat). + +get_dsizes([], Sizes, Sizes). +get_dsizes([P|Parents], [Sz|Sizes], Sizes0) :- + clpbn:get_atts(P,dist(Dist,_)), + get_dist_domain_size(Dist, Sz), + get_dsizes(Parents, Sizes, Sizes0). + +get_dist_params(Id, Parms) :- + recorded(clpbn_dist_db, db(Id, _, Parms, _, _, _, _), _). + +get_dist_domain_size(avg(D,_), DSize) :- !, + length(D, DSize). +get_dist_domain_size(Id, DSize) :- + recorded(clpbn_dist_db, db(Id, _, _, _, _, _, DSize), _). + +get_dist_domain(Id, Domain) :- + recorded(clpbn_dist_db, db(Id, _, _, _, Domain, _, _), _). + +get_dist_key(Id, Key) :- + recorded(clpbn_dist_db, db(Id, Key, _, _, _, _, _), _). + +get_dist_nparams(Id, NParms) :- + recorded(clpbn_dist_db, db(Id, _, _, _, _, NParms, _), _). + +get_evidence_position(El, avg(Domain), Pos) :- !, + nth0(Pos, Domain, El), !. +get_evidence_position(El, Id, Pos) :- + recorded(clpbn_dist_db, db(Id, _, _, _, Domain, _, _), _), + nth0(Pos, Domain, El), !. +get_evidence_position(El, Id, Pos) :- + recorded(clpbn_dist_db, db(Id, _, _, _, _, _, _), _), !, + throw(error(domain_error(evidence,Id),get_evidence_position(El, Id, Pos))). +get_evidence_position(El, Id, Pos) :- + throw(error(domain_error(no_distribution,Id),get_evidence_position(El, Id, Pos))). + +get_evidence_from_position(El, Id, Pos) :- + recorded(clpbn_dist_db, db(Id, _, _, _, Domain, _, _), _), + nth0(Pos, Domain, El), !. +get_evidence_from_position(El, Id, Pos) :- + recorded(clpbn_dist_db, db(Id, _, _, _, _, _, _), _), !, + throw(error(domain_error(evidence,Id),get_evidence_from_position(El, Id, Pos))). +get_evidence_from_position(El, Id, Pos) :- + throw(error(domain_error(no_distribution,Id),get_evidence_from_position(El, Id, Pos))). + +dist_to_term(_Id,_Term). + +empty_dist(Dist, TAB) :- + recorded(clpbn_dist_psizes,db(Dist, DSizes),_), !, + matrix_new(floats, DSizes, TAB). +empty_dist(Dist, TAB) :- + throw(error(domain_error(no_distribution,Dist),empty_dist(Dist,TAB))). + +dist_new_table(Id, NewMat) :- + matrix_to_list(NewMat, List), + recorded(clpbn_dist_db, db(Id, Key, _, A, B, C, D), R), + erase(R), + recorda(clpbn_dist_db, db(Id, Key, List, A, B, C, D), _), + fail. +dist_new_table(_, _). + +copy_structure(V, V) :- var(V), !. +copy_structure(V, _) :- primitive(V), !. +copy_structure(Key, Key0) :- + Key =.. [A|LKey], + copy_Lstructure(LKey, LKey0), + Key0 =.. [A|LKey0]. + +copy_Lstructure([], []). +copy_Lstructure([H|LKey], [NH|LKey0]) :- + copy_structure(H, NH), + copy_Lstructure(LKey, LKey0). + +randomise_all_dists :- + randomise_dist(_), + fail. +randomise_all_dists. + +randomise_dist(Dist) :- + recorded(clpbn_dist_psizes, db(Dist,DSizes), _), + random_CPT(DSizes, NewCPT), + dist_new_table(Dist, NewCPT). + +uniformise_all_dists :- + uniformise_dist(_), + fail. +uniformise_all_dists. + +uniformise_dist(Dist) :- + recorded(clpbn_dist_psizes, db(Dist,DSizes), _), + uniform_CPT(DSizes, NewCPT), + dist_new_table(Dist, NewCPT). + + +reset_all_dists :- + recorded(clpbn_dist_psizes, _, R), + erase(R), + fail. +reset_all_dists :- + recorded(clpbn_dist_db, _, R), + erase(R), + fail. +reset_all_dists :- + reset_id, + fail. +reset_all_dists. + + diff --git a/packages/CLPBN/clpbn/evidence.yap b/packages/CLPBN/clpbn/evidence.yap new file mode 100644 index 000000000..5319f663a --- /dev/null +++ b/packages/CLPBN/clpbn/evidence.yap @@ -0,0 +1,136 @@ +% +% +% +% + +:- module(clpbn_evidence, + [ + store_evidence/1, + incorporate_evidence/2, + check_stored_evidence/2, + add_evidence/2, + put_evidence/2 + ]). + +:- use_module(library(clpbn), [ + {}/1, + clpbn_flag/3, + set_clpbn_flag/2 + ]). + +:- use_module(library('clpbn/dists'), [ + get_evidence_position/3 + ]). + +:- use_module(library(rbtrees), [ + rb_new/1, + rb_lookup/3, + rb_insert/4 + ]). + +:- meta_predicate store_evidence(:). + +:- dynamic node/4, edge/2, evidence/2. + +% +% new evidence storage algorithm. The idea is that instead of +% redoing all the evidence every time we query the network, we shall +% keep a precompiled version around. +% +% the format is as follows: +% evidence_store:parent(Key,ParentList,[EvidenceChildren]) +% +% +store_evidence(G) :- + clpbn_flag(solver,PreviousSolver, graphs), + compute_evidence(G, PreviousSolver). + +compute_evidence(G, PreviousSolver) :- + catch(call_residue(G, Vars), Ball, evidence_error(Ball,PreviousSolver)), !, + store_graph(Vars), + set_clpbn_flag(solver, PreviousSolver). +compute_evidence(_,PreviousSolver) :- + set_clpbn_flag(solver, PreviousSolver). + + +evidence_error(Ball,PreviousSolver) :- + set_clpbn_flag(solver,PreviousSolver), + throw(Ball). + +store_graph([]). +store_graph([_-node(K,Dom,CPT,TVs,Ev)|Vars]) :- + \+ node(K,_,_,_), !, + assert(node(K,Dom,CPT,TVs)), + ( nonvar(Ev) -> assert(evidence(K,Ev)) ; true), + add_links(TVs,K), + store_graph(Vars). +store_graph([_|Vars]) :- + store_graph(Vars). + +add_links([],_). +add_links([K0|TVs],K) :- + assert(edge(K,K0)), + add_links(TVs,K). + + +incorporate_evidence(Vs,AllVs) :- + rb_new(Cache0), + create_open_list(Vs, OL, FL, Cache0, CacheI), + do_variables(OL, FL, CacheI), + extract_vars(OL, AllVs). + +create_open_list([], L, L, C, C). +create_open_list([V|Vs], [K-V|OL], FL, C0, CF) :- + clpbn:get_atts(V,[key(K)]), + add_evidence(K, V), + rb_insert(C0, K, V, CI), + create_open_list(Vs, OL, FL, CI, CF). + +do_variables([], [], _) :- !. +do_variables([K-V|Vs], Vf, C0) :- + check_for_evidence(K, V, Vf, Vff, C0, Ci), + do_variables(Vs, Vff, Ci). + +create_new_variable(K, V, Vf0, Vff, C0, Cf) :- + node(K,Dom, CPT, TVs), + { V = K with p(Dom, CPT, NTVs) }, + add_evidence(K, V), + add_variables(TVs, NTVs, Vf0, Vff, C0, Cf). + + +add_variables([], [], Vf, Vf, C, C). +add_variables([K|TVs], [V|NTVs], Vf0, Vff, C0, Cf) :- + rb_lookup(K, V, C0), !, + add_variables(TVs, NTVs, Vf0, Vff, C0, Cf). +add_variables([K|TVs], [V|NTVs], [K-V|Vf0], Vff, C0, Cf) :- + rb_insert(C0, K, V, C1), + create_new_variable(K, V, Vf0, Vf1, C1, C2), + add_variables(TVs, NTVs, Vf1, Vff, C2, Cf). + + +extract_vars([], []). +extract_vars([_-V|Cache], [V|AllVs]) :- + extract_vars(Cache, AllVs). + +%make sure that we are +check_stored_evidence(K, Ev) :- + evidence(K, Ev0), !, Ev0 = Ev. +check_stored_evidence(_, _). + +add_evidence(K, V) :- + evidence(K, Ev), !, + clpbn:put_atts(V, [evidence(Ev)]). +add_evidence(_, _). + + +check_for_evidence(_, V, Vf, Vf, C, C) :- + clpbn:get_atts(V, [evidence(_)]), !. +check_for_evidence(K, _, Vf0, Vff, C0, Ci) :- + findall(Rt,edge(Rt,K),Rts), + add_variables(Rts, _, Vf0, Vff, C0, Ci). + +put_evidence(K, V) :- + clpbn:get_atts(V, [dist(Id,_)]), + get_evidence_position(K, Id, Ev), + clpbn:put_atts(V, [evidence(Ev)]). + diff --git a/packages/CLPBN/clpbn/examples/School/README b/packages/CLPBN/clpbn/examples/School/README new file mode 100644 index 000000000..9c604316f --- /dev/null +++ b/packages/CLPBN/clpbn/examples/School/README @@ -0,0 +1,53 @@ + +This is a version of the school database, based on the PRM School example. + +There are four main files: + +school_128.yap: a school with 128 professors, 256 courses and 4096 students. +school_64.yap: medium size school +school_32.yap: small school + +schema.yap: the schema +tables: CPTs + + + + + +professor_ability(p0,X). + +professor_popularity(p0,X). + +professor_ability(p0,X), professor_popularity(p0,h). + +professor_ability(p0,h), professor_popularity(p0,X). + +registration_grade(r0,X). + +registration_grade(r0,X), registration_course(r0,C), course_difficulty(C,h). + +registration_grade(r0,X), registration_course(r0,C), course_difficulty(C,h), registration_student(r0,S), student_intelligence(S,h). + +registration_grade(r0,X), registration_course(r0,C), course_difficulty(C,l), registration_student(r0,S), student_intelligence(S,h). + +registration_satisfaction(r0,X). + +registration_satisfaction(r0,X), registration_student(r0,S), student_intelligence(S,h). + +registration_satisfaction(r0,X), registration_grade(r0,a). + +registration_satisfaction(r0,X), registration_grade(r0,d). + +registration_satisfaction(r0,h), registration_grade(r0,X). + +course_rating(c0,X). + +course_rating(c0,h), course_difficulty(c0,X). + +course_difficulty(c0,X). + +student_ranking(s0,X). + +student_ranking(s0,X), student_intelligence(s0,h). + + diff --git a/packages/CLPBN/clpbn/examples/School/evidence_128.yap b/packages/CLPBN/clpbn/examples/School/evidence_128.yap new file mode 100644 index 000000000..d3d72799f --- /dev/null +++ b/packages/CLPBN/clpbn/examples/School/evidence_128.yap @@ -0,0 +1,17 @@ + +:- [school_128]. + +professor_popularity(p0,h) :- {}. +professor_popularity(p3,h) :- {}. +professor_popularity(p5,l) :- {}. +professor_popularity(p45,h) :- {}. +professor_popularity(p15,m) :- {}. + +course_rating(c0, h) :- {}. +course_rating(c1, m) :- {}. +course_rating(c2, l) :- {}. +course_rating(c3, h) :- {}. +course_rating(c4, m) :- {}. +course_rating(c5, l) :- {}. +course_rating(c62, m) :- {}. + diff --git a/packages/CLPBN/clpbn/examples/School/parlearn.yap b/packages/CLPBN/clpbn/examples/School/parlearn.yap new file mode 100644 index 000000000..e722d8334 --- /dev/null +++ b/packages/CLPBN/clpbn/examples/School/parlearn.yap @@ -0,0 +1,44 @@ + +:- [pos:sample32]. + +:- ['~/Yap/work/CLPBN/clpbn/examples/School/school_32']. + +% These libraries provide same functionality. +:- [library('clpbn/learning/mle')]. +%:- [library('clpbn/learning/bnt_parms')]. + +:- [library(matrix)]. + +main :- + findall(X,goal(X),L), + learn_parameters(L,CPTs), + write_cpts(CPTs). + +goal(professor_ability(P,V)) :- + pos:professor_ability(P,V), + p(pa, M), random < M. +goal(professor_popularity(P,V)) :- + pos:professor_popularity(P,V), + p(pp, M), random < M. +goal(registration_grade(P,V)) :- + pos:registration_grade(P,V), + p(rg, M), random < M. +goal(student_intelligence(P,V)) :- + pos:student_intelligence(P,V), + p(si, M), random < M. +goal(course_difficulty(P,V)) :- + pos:course_difficulty(P,V), + p(cd, M), random < M. +goal(registration_satisfaction(P,V)) :- + pos:registration_satisfaction(P,V), + p(rs, M), random < M. + +% sampling parameter +p(_, 1.0). + +write_cpts([]). +write_cpts([CPT|CPTs]) :- + matrix_to_list(CPT,L), + format('CPT=~w~n',[L]), + write_cpts(CPTs). + diff --git a/packages/CLPBN/clpbn/examples/School/sample32.yap b/packages/CLPBN/clpbn/examples/School/sample32.yap new file mode 100644 index 000000000..f6dda7aef --- /dev/null +++ b/packages/CLPBN/clpbn/examples/School/sample32.yap @@ -0,0 +1,2433 @@ + + +professor_ability(p0,h). +professor_ability(p1,h). +professor_ability(p2,m). +professor_ability(p3,m). +professor_ability(p4,h). +professor_ability(p5,h). +professor_ability(p6,l). +professor_ability(p7,l). +professor_ability(p8,m). +professor_ability(p9,h). +professor_ability(p10,m). +professor_ability(p11,h). +professor_ability(p12,h). +professor_ability(p13,m). +professor_ability(p14,m). +professor_ability(p15,m). +professor_ability(p16,m). +professor_ability(p17,m). +professor_ability(p18,l). +professor_ability(p19,h). +professor_ability(p20,h). +professor_ability(p21,h). +professor_ability(p22,m). +professor_ability(p23,m). +professor_ability(p24,l). +professor_ability(p25,m). +professor_ability(p26,h). +professor_ability(p27,h). +professor_ability(p28,h). +professor_ability(p29,m). +professor_ability(p30,m). +professor_ability(p31,h). + + +course_difficulty(c0,h). +course_difficulty(c1,m). +course_difficulty(c2,l). +course_difficulty(c3,m). +course_difficulty(c4,m). +course_difficulty(c5,l). +course_difficulty(c6,m). +course_difficulty(c7,h). +course_difficulty(c8,h). +course_difficulty(c9,l). +course_difficulty(c10,m). +course_difficulty(c11,m). +course_difficulty(c12,m). +course_difficulty(c13,h). +course_difficulty(c14,m). +course_difficulty(c15,h). +course_difficulty(c16,l). +course_difficulty(c17,h). +course_difficulty(c18,m). +course_difficulty(c19,l). +course_difficulty(c20,m). +course_difficulty(c21,h). +course_difficulty(c22,m). +course_difficulty(c23,m). +course_difficulty(c24,h). +course_difficulty(c25,m). +course_difficulty(c26,l). +course_difficulty(c27,h). +course_difficulty(c28,m). +course_difficulty(c29,m). +course_difficulty(c30,m). +course_difficulty(c31,m). +course_difficulty(c32,l). +course_difficulty(c33,m). +course_difficulty(c34,l). +course_difficulty(c35,h). +course_difficulty(c36,h). +course_difficulty(c37,m). +course_difficulty(c38,m). +course_difficulty(c39,m). +course_difficulty(c40,h). +course_difficulty(c41,m). +course_difficulty(c42,h). +course_difficulty(c43,m). +course_difficulty(c44,m). +course_difficulty(c45,m). +course_difficulty(c46,m). +course_difficulty(c47,m). +course_difficulty(c48,m). +course_difficulty(c49,l). +course_difficulty(c50,m). +course_difficulty(c51,h). +course_difficulty(c52,h). +course_difficulty(c53,h). +course_difficulty(c54,m). +course_difficulty(c55,h). +course_difficulty(c56,m). +course_difficulty(c57,m). +course_difficulty(c58,h). +course_difficulty(c59,m). +course_difficulty(c60,h). +course_difficulty(c61,m). +course_difficulty(c62,l). +course_difficulty(c63,l). + + +student_intelligence(s0,l). +student_intelligence(s1,l). +student_intelligence(s2,h). +student_intelligence(s3,h). +student_intelligence(s4,h). +student_intelligence(s5,h). +student_intelligence(s6,m). +student_intelligence(s7,h). +student_intelligence(s8,h). +student_intelligence(s9,m). +student_intelligence(s10,m). +student_intelligence(s11,m). +student_intelligence(s12,h). +student_intelligence(s13,h). +student_intelligence(s14,h). +student_intelligence(s15,m). +student_intelligence(s16,h). +student_intelligence(s17,m). +student_intelligence(s18,m). +student_intelligence(s19,h). +student_intelligence(s20,m). +student_intelligence(s21,h). +student_intelligence(s22,h). +student_intelligence(s23,h). +student_intelligence(s24,m). +student_intelligence(s25,h). +student_intelligence(s26,m). +student_intelligence(s27,m). +student_intelligence(s28,m). +student_intelligence(s29,m). +student_intelligence(s30,h). +student_intelligence(s31,m). +student_intelligence(s32,m). +student_intelligence(s33,h). +student_intelligence(s34,l). +student_intelligence(s35,m). +student_intelligence(s36,l). +student_intelligence(s37,m). +student_intelligence(s38,h). +student_intelligence(s39,h). +student_intelligence(s40,h). +student_intelligence(s41,m). +student_intelligence(s42,m). +student_intelligence(s43,h). +student_intelligence(s44,h). +student_intelligence(s45,h). +student_intelligence(s46,l). +student_intelligence(s47,h). +student_intelligence(s48,m). +student_intelligence(s49,m). +student_intelligence(s50,h). +student_intelligence(s51,m). +student_intelligence(s52,m). +student_intelligence(s53,m). +student_intelligence(s54,h). +student_intelligence(s55,h). +student_intelligence(s56,l). +student_intelligence(s57,m). +student_intelligence(s58,h). +student_intelligence(s59,m). +student_intelligence(s60,m). +student_intelligence(s61,h). +student_intelligence(s62,m). +student_intelligence(s63,h). +student_intelligence(s64,l). +student_intelligence(s65,m). +student_intelligence(s66,h). +student_intelligence(s67,m). +student_intelligence(s68,h). +student_intelligence(s69,h). +student_intelligence(s70,l). +student_intelligence(s71,m). +student_intelligence(s72,h). +student_intelligence(s73,m). +student_intelligence(s74,h). +student_intelligence(s75,h). +student_intelligence(s76,h). +student_intelligence(s77,h). +student_intelligence(s78,h). +student_intelligence(s79,m). +student_intelligence(s80,m). +student_intelligence(s81,l). +student_intelligence(s82,h). +student_intelligence(s83,h). +student_intelligence(s84,m). +student_intelligence(s85,h). +student_intelligence(s86,m). +student_intelligence(s87,h). +student_intelligence(s88,h). +student_intelligence(s89,m). +student_intelligence(s90,h). +student_intelligence(s91,m). +student_intelligence(s92,h). +student_intelligence(s93,l). +student_intelligence(s94,l). +student_intelligence(s95,h). +student_intelligence(s96,m). +student_intelligence(s97,h). +student_intelligence(s98,h). +student_intelligence(s99,l). +student_intelligence(s100,h). +student_intelligence(s101,h). +student_intelligence(s102,m). +student_intelligence(s103,h). +student_intelligence(s104,l). +student_intelligence(s105,m). +student_intelligence(s106,h). +student_intelligence(s107,l). +student_intelligence(s108,m). +student_intelligence(s109,m). +student_intelligence(s110,m). +student_intelligence(s111,h). +student_intelligence(s112,m). +student_intelligence(s113,h). +student_intelligence(s114,m). +student_intelligence(s115,h). +student_intelligence(s116,m). +student_intelligence(s117,m). +student_intelligence(s118,m). +student_intelligence(s119,h). +student_intelligence(s120,h). +student_intelligence(s121,h). +student_intelligence(s122,m). +student_intelligence(s123,m). +student_intelligence(s124,h). +student_intelligence(s125,m). +student_intelligence(s126,m). +student_intelligence(s127,m). +student_intelligence(s128,m). +student_intelligence(s129,h). +student_intelligence(s130,m). +student_intelligence(s131,h). +student_intelligence(s132,h). +student_intelligence(s133,h). +student_intelligence(s134,h). +student_intelligence(s135,h). +student_intelligence(s136,m). +student_intelligence(s137,m). +student_intelligence(s138,l). +student_intelligence(s139,h). +student_intelligence(s140,h). +student_intelligence(s141,m). +student_intelligence(s142,m). +student_intelligence(s143,h). +student_intelligence(s144,h). +student_intelligence(s145,h). +student_intelligence(s146,m). +student_intelligence(s147,m). +student_intelligence(s148,m). +student_intelligence(s149,h). +student_intelligence(s150,l). +student_intelligence(s151,h). +student_intelligence(s152,h). +student_intelligence(s153,m). +student_intelligence(s154,m). +student_intelligence(s155,h). +student_intelligence(s156,m). +student_intelligence(s157,m). +student_intelligence(s158,h). +student_intelligence(s159,h). +student_intelligence(s160,m). +student_intelligence(s161,m). +student_intelligence(s162,h). +student_intelligence(s163,m). +student_intelligence(s164,m). +student_intelligence(s165,m). +student_intelligence(s166,m). +student_intelligence(s167,h). +student_intelligence(s168,h). +student_intelligence(s169,m). +student_intelligence(s170,m). +student_intelligence(s171,m). +student_intelligence(s172,h). +student_intelligence(s173,h). +student_intelligence(s174,h). +student_intelligence(s175,m). +student_intelligence(s176,m). +student_intelligence(s177,m). +student_intelligence(s178,h). +student_intelligence(s179,m). +student_intelligence(s180,m). +student_intelligence(s181,h). +student_intelligence(s182,m). +student_intelligence(s183,h). +student_intelligence(s184,h). +student_intelligence(s185,m). +student_intelligence(s186,m). +student_intelligence(s187,m). +student_intelligence(s188,h). +student_intelligence(s189,m). +student_intelligence(s190,h). +student_intelligence(s191,l). +student_intelligence(s192,h). +student_intelligence(s193,m). +student_intelligence(s194,m). +student_intelligence(s195,m). +student_intelligence(s196,h). +student_intelligence(s197,h). +student_intelligence(s198,h). +student_intelligence(s199,m). +student_intelligence(s200,h). +student_intelligence(s201,l). +student_intelligence(s202,h). +student_intelligence(s203,m). +student_intelligence(s204,h). +student_intelligence(s205,h). +student_intelligence(s206,h). +student_intelligence(s207,h). +student_intelligence(s208,m). +student_intelligence(s209,h). +student_intelligence(s210,m). +student_intelligence(s211,m). +student_intelligence(s212,m). +student_intelligence(s213,h). +student_intelligence(s214,h). +student_intelligence(s215,m). +student_intelligence(s216,h). +student_intelligence(s217,m). +student_intelligence(s218,h). +student_intelligence(s219,h). +student_intelligence(s220,h). +student_intelligence(s221,h). +student_intelligence(s222,h). +student_intelligence(s223,m). +student_intelligence(s224,l). +student_intelligence(s225,l). +student_intelligence(s226,m). +student_intelligence(s227,h). +student_intelligence(s228,h). +student_intelligence(s229,m). +student_intelligence(s230,m). +student_intelligence(s231,h). +student_intelligence(s232,m). +student_intelligence(s233,h). +student_intelligence(s234,l). +student_intelligence(s235,h). +student_intelligence(s236,h). +student_intelligence(s237,h). +student_intelligence(s238,h). +student_intelligence(s239,h). +student_intelligence(s240,h). +student_intelligence(s241,m). +student_intelligence(s242,l). +student_intelligence(s243,h). +student_intelligence(s244,h). +student_intelligence(s245,l). +student_intelligence(s246,m). +student_intelligence(s247,h). +student_intelligence(s248,m). +student_intelligence(s249,h). +student_intelligence(s250,m). +student_intelligence(s251,h). +student_intelligence(s252,m). +student_intelligence(s253,m). +student_intelligence(s254,m). +student_intelligence(s255,m). + + +professor_popularity(p0,h). +professor_popularity(p1,h). +professor_popularity(p2,l). +professor_popularity(p3,h). +professor_popularity(p4,h). +professor_popularity(p5,h). +professor_popularity(p6,l). +professor_popularity(p7,l). +professor_popularity(p8,m). +professor_popularity(p9,h). +professor_popularity(p10,l). +professor_popularity(p11,h). +professor_popularity(p12,h). +professor_popularity(p13,l). +professor_popularity(p14,m). +professor_popularity(p15,h). +professor_popularity(p16,m). +professor_popularity(p17,h). +professor_popularity(p18,l). +professor_popularity(p19,h). +professor_popularity(p20,h). +professor_popularity(p21,h). +professor_popularity(p22,h). +professor_popularity(p23,l). +professor_popularity(p24,l). +professor_popularity(p25,l). +professor_popularity(p26,m). +professor_popularity(p27,h). +professor_popularity(p28,h). +professor_popularity(p29,l). +professor_popularity(p30,m). +professor_popularity(p31,h). + + +registration_grade(r0,a). +registration_grade(r1,c). +registration_grade(r2,c). +registration_grade(r3,c). +registration_grade(r4,c). +registration_grade(r5,c). +registration_grade(r6,a). +registration_grade(r7,a). +registration_grade(r8,b). +registration_grade(r9,a). +registration_grade(r10,a). +registration_grade(r11,a). +registration_grade(r12,a). +registration_grade(r13,a). +registration_grade(r14,b). +registration_grade(r15,b). +registration_grade(r16,a). +registration_grade(r17,b). +registration_grade(r18,c). +registration_grade(r19,c). +registration_grade(r20,c). +registration_grade(r21,a). +registration_grade(r22,a). +registration_grade(r23,b). +registration_grade(r24,b). +registration_grade(r25,a). +registration_grade(r26,a). +registration_grade(r27,b). +registration_grade(r28,c). +registration_grade(r29,b). +registration_grade(r30,c). +registration_grade(r31,b). +registration_grade(r32,c). +registration_grade(r33,a). +registration_grade(r34,c). +registration_grade(r35,c). +registration_grade(r36,a). +registration_grade(r37,a). +registration_grade(r38,c). +registration_grade(r39,a). +registration_grade(r40,a). +registration_grade(r41,c). +registration_grade(r42,b). +registration_grade(r43,a). +registration_grade(r44,a). +registration_grade(r45,a). +registration_grade(r46,a). +registration_grade(r47,b). +registration_grade(r48,b). +registration_grade(r49,b). +registration_grade(r50,b). +registration_grade(r51,b). +registration_grade(r52,b). +registration_grade(r53,a). +registration_grade(r54,b). +registration_grade(r55,a). +registration_grade(r56,c). +registration_grade(r57,c). +registration_grade(r58,a). +registration_grade(r59,c). +registration_grade(r60,a). +registration_grade(r61,a). +registration_grade(r62,a). +registration_grade(r63,b). +registration_grade(r64,b). +registration_grade(r65,b). +registration_grade(r66,b). +registration_grade(r67,b). +registration_grade(r68,a). +registration_grade(r69,b). +registration_grade(r70,c). +registration_grade(r71,b). +registration_grade(r72,a). +registration_grade(r73,b). +registration_grade(r74,a). +registration_grade(r75,b). +registration_grade(r76,c). +registration_grade(r77,a). +registration_grade(r78,b). +registration_grade(r79,a). +registration_grade(r80,b). +registration_grade(r81,b). +registration_grade(r82,a). +registration_grade(r83,a). +registration_grade(r84,c). +registration_grade(r85,b). +registration_grade(r86,b). +registration_grade(r87,b). +registration_grade(r88,c). +registration_grade(r89,c). +registration_grade(r90,c). +registration_grade(r91,a). +registration_grade(r92,d). +registration_grade(r93,b). +registration_grade(r94,c). +registration_grade(r95,b). +registration_grade(r96,a). +registration_grade(r97,a). +registration_grade(r98,b). +registration_grade(r99,b). +registration_grade(r100,a). +registration_grade(r101,a). +registration_grade(r102,a). +registration_grade(r103,b). +registration_grade(r104,b). +registration_grade(r105,c). +registration_grade(r106,b). +registration_grade(r107,b). +registration_grade(r108,b). +registration_grade(r109,b). +registration_grade(r110,a). +registration_grade(r111,a). +registration_grade(r112,a). +registration_grade(r113,c). +registration_grade(r114,c). +registration_grade(r115,d). +registration_grade(r116,b). +registration_grade(r117,c). +registration_grade(r118,a). +registration_grade(r119,b). +registration_grade(r120,b). +registration_grade(r121,c). +registration_grade(r122,b). +registration_grade(r123,a). +registration_grade(r124,a). +registration_grade(r125,b). +registration_grade(r126,b). +registration_grade(r127,b). +registration_grade(r128,a). +registration_grade(r129,c). +registration_grade(r130,a). +registration_grade(r131,a). +registration_grade(r132,b). +registration_grade(r133,a). +registration_grade(r134,a). +registration_grade(r135,b). +registration_grade(r136,a). +registration_grade(r137,b). +registration_grade(r138,a). +registration_grade(r139,a). +registration_grade(r140,a). +registration_grade(r141,b). +registration_grade(r142,b). +registration_grade(r143,b). +registration_grade(r144,c). +registration_grade(r145,b). +registration_grade(r146,a). +registration_grade(r147,a). +registration_grade(r148,a). +registration_grade(r149,a). +registration_grade(r150,b). +registration_grade(r151,a). +registration_grade(r152,a). +registration_grade(r153,b). +registration_grade(r154,a). +registration_grade(r155,c). +registration_grade(r156,b). +registration_grade(r157,b). +registration_grade(r158,c). +registration_grade(r159,b). +registration_grade(r160,a). +registration_grade(r161,a). +registration_grade(r162,b). +registration_grade(r163,a). +registration_grade(r164,b). +registration_grade(r165,b). +registration_grade(r166,c). +registration_grade(r167,a). +registration_grade(r168,a). +registration_grade(r169,a). +registration_grade(r170,a). +registration_grade(r171,a). +registration_grade(r172,c). +registration_grade(r173,b). +registration_grade(r174,a). +registration_grade(r175,b). +registration_grade(r176,b). +registration_grade(r177,c). +registration_grade(r178,b). +registration_grade(r179,d). +registration_grade(r180,c). +registration_grade(r181,a). +registration_grade(r182,b). +registration_grade(r183,a). +registration_grade(r184,a). +registration_grade(r185,b). +registration_grade(r186,c). +registration_grade(r187,a). +registration_grade(r188,a). +registration_grade(r189,a). +registration_grade(r190,a). +registration_grade(r191,b). +registration_grade(r192,b). +registration_grade(r193,c). +registration_grade(r194,b). +registration_grade(r195,c). +registration_grade(r196,b). +registration_grade(r197,a). +registration_grade(r198,a). +registration_grade(r199,b). +registration_grade(r200,b). +registration_grade(r201,c). +registration_grade(r202,a). +registration_grade(r203,a). +registration_grade(r204,b). +registration_grade(r205,a). +registration_grade(r206,a). +registration_grade(r207,a). +registration_grade(r208,c). +registration_grade(r209,b). +registration_grade(r210,a). +registration_grade(r211,d). +registration_grade(r212,b). +registration_grade(r213,b). +registration_grade(r214,a). +registration_grade(r215,a). +registration_grade(r216,b). +registration_grade(r217,a). +registration_grade(r218,b). +registration_grade(r219,a). +registration_grade(r220,a). +registration_grade(r221,b). +registration_grade(r222,c). +registration_grade(r223,a). +registration_grade(r224,b). +registration_grade(r225,b). +registration_grade(r226,d). +registration_grade(r227,b). +registration_grade(r228,c). +registration_grade(r229,b). +registration_grade(r230,a). +registration_grade(r231,c). +registration_grade(r232,a). +registration_grade(r233,b). +registration_grade(r234,b). +registration_grade(r235,c). +registration_grade(r236,b). +registration_grade(r237,c). +registration_grade(r238,d). +registration_grade(r239,b). +registration_grade(r240,b). +registration_grade(r241,a). +registration_grade(r242,b). +registration_grade(r243,a). +registration_grade(r244,b). +registration_grade(r245,a). +registration_grade(r246,b). +registration_grade(r247,c). +registration_grade(r248,b). +registration_grade(r249,a). +registration_grade(r250,a). +registration_grade(r251,a). +registration_grade(r252,b). +registration_grade(r253,a). +registration_grade(r254,b). +registration_grade(r255,a). +registration_grade(r256,a). +registration_grade(r257,b). +registration_grade(r258,a). +registration_grade(r259,a). +registration_grade(r260,b). +registration_grade(r261,a). +registration_grade(r262,a). +registration_grade(r263,a). +registration_grade(r264,c). +registration_grade(r265,a). +registration_grade(r266,a). +registration_grade(r267,a). +registration_grade(r268,c). +registration_grade(r269,a). +registration_grade(r270,c). +registration_grade(r271,b). +registration_grade(r272,c). +registration_grade(r273,b). +registration_grade(r274,c). +registration_grade(r275,a). +registration_grade(r276,a). +registration_grade(r277,a). +registration_grade(r278,a). +registration_grade(r279,a). +registration_grade(r280,b). +registration_grade(r281,b). +registration_grade(r282,d). +registration_grade(r283,a). +registration_grade(r284,b). +registration_grade(r285,b). +registration_grade(r286,a). +registration_grade(r287,b). +registration_grade(r288,b). +registration_grade(r289,d). +registration_grade(r290,b). +registration_grade(r291,c). +registration_grade(r292,b). +registration_grade(r293,a). +registration_grade(r294,a). +registration_grade(r295,a). +registration_grade(r296,b). +registration_grade(r297,a). +registration_grade(r298,a). +registration_grade(r299,a). +registration_grade(r300,b). +registration_grade(r301,b). +registration_grade(r302,b). +registration_grade(r303,a). +registration_grade(r304,a). +registration_grade(r305,b). +registration_grade(r306,b). +registration_grade(r307,c). +registration_grade(r308,c). +registration_grade(r309,c). +registration_grade(r310,a). +registration_grade(r311,a). +registration_grade(r312,a). +registration_grade(r313,a). +registration_grade(r314,c). +registration_grade(r315,c). +registration_grade(r316,c). +registration_grade(r317,c). +registration_grade(r318,c). +registration_grade(r319,c). +registration_grade(r320,b). +registration_grade(r321,b). +registration_grade(r322,a). +registration_grade(r323,c). +registration_grade(r324,b). +registration_grade(r325,b). +registration_grade(r326,a). +registration_grade(r327,c). +registration_grade(r328,b). +registration_grade(r329,a). +registration_grade(r330,b). +registration_grade(r331,a). +registration_grade(r332,a). +registration_grade(r333,a). +registration_grade(r334,c). +registration_grade(r335,d). +registration_grade(r336,b). +registration_grade(r337,b). +registration_grade(r338,b). +registration_grade(r339,a). +registration_grade(r340,b). +registration_grade(r341,b). +registration_grade(r342,b). +registration_grade(r343,a). +registration_grade(r344,c). +registration_grade(r345,b). +registration_grade(r346,b). +registration_grade(r347,b). +registration_grade(r348,a). +registration_grade(r349,a). +registration_grade(r350,b). +registration_grade(r351,b). +registration_grade(r352,d). +registration_grade(r353,c). +registration_grade(r354,c). +registration_grade(r355,c). +registration_grade(r356,b). +registration_grade(r357,b). +registration_grade(r358,a). +registration_grade(r359,a). +registration_grade(r360,a). +registration_grade(r361,b). +registration_grade(r362,c). +registration_grade(r363,c). +registration_grade(r364,b). +registration_grade(r365,b). +registration_grade(r366,b). +registration_grade(r367,b). +registration_grade(r368,a). +registration_grade(r369,c). +registration_grade(r370,b). +registration_grade(r371,a). +registration_grade(r372,a). +registration_grade(r373,a). +registration_grade(r374,b). +registration_grade(r375,b). +registration_grade(r376,a). +registration_grade(r377,a). +registration_grade(r378,a). +registration_grade(r379,c). +registration_grade(r380,a). +registration_grade(r381,c). +registration_grade(r382,a). +registration_grade(r383,a). +registration_grade(r384,b). +registration_grade(r385,b). +registration_grade(r386,d). +registration_grade(r387,a). +registration_grade(r388,a). +registration_grade(r389,a). +registration_grade(r390,a). +registration_grade(r391,b). +registration_grade(r392,b). +registration_grade(r393,b). +registration_grade(r394,c). +registration_grade(r395,b). +registration_grade(r396,b). +registration_grade(r397,a). +registration_grade(r398,b). +registration_grade(r399,c). +registration_grade(r400,a). +registration_grade(r401,c). +registration_grade(r402,a). +registration_grade(r403,a). +registration_grade(r404,a). +registration_grade(r405,a). +registration_grade(r406,a). +registration_grade(r407,b). +registration_grade(r408,a). +registration_grade(r409,a). +registration_grade(r410,b). +registration_grade(r411,b). +registration_grade(r412,a). +registration_grade(r413,a). +registration_grade(r414,a). +registration_grade(r415,b). +registration_grade(r416,b). +registration_grade(r417,d). +registration_grade(r418,a). +registration_grade(r419,a). +registration_grade(r420,a). +registration_grade(r421,c). +registration_grade(r422,b). +registration_grade(r423,b). +registration_grade(r424,a). +registration_grade(r425,b). +registration_grade(r426,c). +registration_grade(r427,c). +registration_grade(r428,c). +registration_grade(r429,c). +registration_grade(r430,b). +registration_grade(r431,d). +registration_grade(r432,c). +registration_grade(r433,a). +registration_grade(r434,a). +registration_grade(r435,c). +registration_grade(r436,a). +registration_grade(r437,c). +registration_grade(r438,b). +registration_grade(r439,b). +registration_grade(r440,c). +registration_grade(r441,a). +registration_grade(r442,c). +registration_grade(r443,a). +registration_grade(r444,a). +registration_grade(r445,a). +registration_grade(r446,a). +registration_grade(r447,d). +registration_grade(r448,c). +registration_grade(r449,b). +registration_grade(r450,a). +registration_grade(r451,a). +registration_grade(r452,b). +registration_grade(r453,d). +registration_grade(r454,d). +registration_grade(r455,c). +registration_grade(r456,c). +registration_grade(r457,a). +registration_grade(r458,b). +registration_grade(r459,b). +registration_grade(r460,a). +registration_grade(r461,b). +registration_grade(r462,a). +registration_grade(r463,d). +registration_grade(r464,a). +registration_grade(r465,a). +registration_grade(r466,b). +registration_grade(r467,b). +registration_grade(r468,a). +registration_grade(r469,a). +registration_grade(r470,c). +registration_grade(r471,b). +registration_grade(r472,a). +registration_grade(r473,c). +registration_grade(r474,b). +registration_grade(r475,a). +registration_grade(r476,c). +registration_grade(r477,b). +registration_grade(r478,a). +registration_grade(r479,b). +registration_grade(r480,a). +registration_grade(r481,b). +registration_grade(r482,b). +registration_grade(r483,a). +registration_grade(r484,a). +registration_grade(r485,a). +registration_grade(r486,a). +registration_grade(r487,a). +registration_grade(r488,a). +registration_grade(r489,b). +registration_grade(r490,c). +registration_grade(r491,c). +registration_grade(r492,b). +registration_grade(r493,a). +registration_grade(r494,b). +registration_grade(r495,b). +registration_grade(r496,a). +registration_grade(r497,c). +registration_grade(r498,b). +registration_grade(r499,c). +registration_grade(r500,b). +registration_grade(r501,a). +registration_grade(r502,a). +registration_grade(r503,c). +registration_grade(r504,b). +registration_grade(r505,c). +registration_grade(r506,c). +registration_grade(r507,a). +registration_grade(r508,c). +registration_grade(r509,b). +registration_grade(r510,a). +registration_grade(r511,c). +registration_grade(r512,b). +registration_grade(r513,b). +registration_grade(r514,c). +registration_grade(r515,c). +registration_grade(r516,a). +registration_grade(r517,b). +registration_grade(r518,a). +registration_grade(r519,a). +registration_grade(r520,b). +registration_grade(r521,a). +registration_grade(r522,b). +registration_grade(r523,a). +registration_grade(r524,b). +registration_grade(r525,c). +registration_grade(r526,c). +registration_grade(r527,c). +registration_grade(r528,a). +registration_grade(r529,b). +registration_grade(r530,a). +registration_grade(r531,b). +registration_grade(r532,a). +registration_grade(r533,a). +registration_grade(r534,b). +registration_grade(r535,c). +registration_grade(r536,a). +registration_grade(r537,a). +registration_grade(r538,a). +registration_grade(r539,b). +registration_grade(r540,b). +registration_grade(r541,c). +registration_grade(r542,a). +registration_grade(r543,a). +registration_grade(r544,b). +registration_grade(r545,a). +registration_grade(r546,b). +registration_grade(r547,c). +registration_grade(r548,c). +registration_grade(r549,b). +registration_grade(r550,a). +registration_grade(r551,a). +registration_grade(r552,c). +registration_grade(r553,b). +registration_grade(r554,b). +registration_grade(r555,b). +registration_grade(r556,a). +registration_grade(r557,a). +registration_grade(r558,a). +registration_grade(r559,b). +registration_grade(r560,b). +registration_grade(r561,a). +registration_grade(r562,a). +registration_grade(r563,a). +registration_grade(r564,b). +registration_grade(r565,d). +registration_grade(r566,c). +registration_grade(r567,a). +registration_grade(r568,a). +registration_grade(r569,a). +registration_grade(r570,c). +registration_grade(r571,c). +registration_grade(r572,b). +registration_grade(r573,a). +registration_grade(r574,c). +registration_grade(r575,a). +registration_grade(r576,a). +registration_grade(r577,a). +registration_grade(r578,b). +registration_grade(r579,a). +registration_grade(r580,b). +registration_grade(r581,a). +registration_grade(r582,a). +registration_grade(r583,a). +registration_grade(r584,a). +registration_grade(r585,c). +registration_grade(r586,b). +registration_grade(r587,c). +registration_grade(r588,c). +registration_grade(r589,c). +registration_grade(r590,b). +registration_grade(r591,c). +registration_grade(r592,b). +registration_grade(r593,b). +registration_grade(r594,c). +registration_grade(r595,b). +registration_grade(r596,a). +registration_grade(r597,a). +registration_grade(r598,a). +registration_grade(r599,a). +registration_grade(r600,a). +registration_grade(r601,b). +registration_grade(r602,a). +registration_grade(r603,d). +registration_grade(r604,c). +registration_grade(r605,a). +registration_grade(r606,a). +registration_grade(r607,b). +registration_grade(r608,a). +registration_grade(r609,b). +registration_grade(r610,a). +registration_grade(r611,a). +registration_grade(r612,c). +registration_grade(r613,a). +registration_grade(r614,d). +registration_grade(r615,b). +registration_grade(r616,a). +registration_grade(r617,a). +registration_grade(r618,b). +registration_grade(r619,a). +registration_grade(r620,a). +registration_grade(r621,a). +registration_grade(r622,b). +registration_grade(r623,b). +registration_grade(r624,a). +registration_grade(r625,c). +registration_grade(r626,a). +registration_grade(r627,b). +registration_grade(r628,a). +registration_grade(r629,b). +registration_grade(r630,c). +registration_grade(r631,a). +registration_grade(r632,a). +registration_grade(r633,b). +registration_grade(r634,b). +registration_grade(r635,b). +registration_grade(r636,d). +registration_grade(r637,c). +registration_grade(r638,a). +registration_grade(r639,b). +registration_grade(r640,c). +registration_grade(r641,c). +registration_grade(r642,c). +registration_grade(r643,a). +registration_grade(r644,a). +registration_grade(r645,b). +registration_grade(r646,b). +registration_grade(r647,b). +registration_grade(r648,a). +registration_grade(r649,b). +registration_grade(r650,c). +registration_grade(r651,b). +registration_grade(r652,b). +registration_grade(r653,b). +registration_grade(r654,b). +registration_grade(r655,a). +registration_grade(r656,b). +registration_grade(r657,a). +registration_grade(r658,a). +registration_grade(r659,a). +registration_grade(r660,a). +registration_grade(r661,c). +registration_grade(r662,a). +registration_grade(r663,a). +registration_grade(r664,c). +registration_grade(r665,a). +registration_grade(r666,b). +registration_grade(r667,b). +registration_grade(r668,d). +registration_grade(r669,b). +registration_grade(r670,a). +registration_grade(r671,c). +registration_grade(r672,c). +registration_grade(r673,a). +registration_grade(r674,a). +registration_grade(r675,b). +registration_grade(r676,a). +registration_grade(r677,a). +registration_grade(r678,a). +registration_grade(r679,a). +registration_grade(r680,c). +registration_grade(r681,b). +registration_grade(r682,a). +registration_grade(r683,b). +registration_grade(r684,b). +registration_grade(r685,a). +registration_grade(r686,b). +registration_grade(r687,a). +registration_grade(r688,c). +registration_grade(r689,b). +registration_grade(r690,a). +registration_grade(r691,c). +registration_grade(r692,a). +registration_grade(r693,b). +registration_grade(r694,a). +registration_grade(r695,a). +registration_grade(r696,a). +registration_grade(r697,c). +registration_grade(r698,b). +registration_grade(r699,a). +registration_grade(r700,a). +registration_grade(r701,a). +registration_grade(r702,a). +registration_grade(r703,c). +registration_grade(r704,c). +registration_grade(r705,b). +registration_grade(r706,b). +registration_grade(r707,a). +registration_grade(r708,b). +registration_grade(r709,b). +registration_grade(r710,b). +registration_grade(r711,b). +registration_grade(r712,c). +registration_grade(r713,a). +registration_grade(r714,b). +registration_grade(r715,a). +registration_grade(r716,a). +registration_grade(r717,a). +registration_grade(r718,a). +registration_grade(r719,c). +registration_grade(r720,a). +registration_grade(r721,b). +registration_grade(r722,b). +registration_grade(r723,b). +registration_grade(r724,a). +registration_grade(r725,c). +registration_grade(r726,a). +registration_grade(r727,a). +registration_grade(r728,b). +registration_grade(r729,b). +registration_grade(r730,c). +registration_grade(r731,a). +registration_grade(r732,a). +registration_grade(r733,a). +registration_grade(r734,b). +registration_grade(r735,b). +registration_grade(r736,a). +registration_grade(r737,b). +registration_grade(r738,b). +registration_grade(r739,a). +registration_grade(r740,a). +registration_grade(r741,a). +registration_grade(r742,d). +registration_grade(r743,d). +registration_grade(r744,a). +registration_grade(r745,b). +registration_grade(r746,a). +registration_grade(r747,a). +registration_grade(r748,b). +registration_grade(r749,c). +registration_grade(r750,a). +registration_grade(r751,c). +registration_grade(r752,b). +registration_grade(r753,c). +registration_grade(r754,c). +registration_grade(r755,c). +registration_grade(r756,b). +registration_grade(r757,c). +registration_grade(r758,b). +registration_grade(r759,b). +registration_grade(r760,a). +registration_grade(r761,a). +registration_grade(r762,b). +registration_grade(r763,a). +registration_grade(r764,a). +registration_grade(r765,a). +registration_grade(r766,c). +registration_grade(r767,c). +registration_grade(r768,c). +registration_grade(r769,c). +registration_grade(r770,b). +registration_grade(r771,b). +registration_grade(r772,a). +registration_grade(r773,b). +registration_grade(r774,b). +registration_grade(r775,a). +registration_grade(r776,a). +registration_grade(r777,c). +registration_grade(r778,c). +registration_grade(r779,b). +registration_grade(r780,a). +registration_grade(r781,b). +registration_grade(r782,a). +registration_grade(r783,c). +registration_grade(r784,c). +registration_grade(r785,c). +registration_grade(r786,c). +registration_grade(r787,a). +registration_grade(r788,a). +registration_grade(r789,c). +registration_grade(r790,b). +registration_grade(r791,b). +registration_grade(r792,a). +registration_grade(r793,a). +registration_grade(r794,b). +registration_grade(r795,a). +registration_grade(r796,a). +registration_grade(r797,a). +registration_grade(r798,b). +registration_grade(r799,c). +registration_grade(r800,b). +registration_grade(r801,b). +registration_grade(r802,a). +registration_grade(r803,b). +registration_grade(r804,a). +registration_grade(r805,b). +registration_grade(r806,a). +registration_grade(r807,a). +registration_grade(r808,b). +registration_grade(r809,c). +registration_grade(r810,b). +registration_grade(r811,d). +registration_grade(r812,c). +registration_grade(r813,c). +registration_grade(r814,c). +registration_grade(r815,c). +registration_grade(r816,b). +registration_grade(r817,a). +registration_grade(r818,b). +registration_grade(r819,b). +registration_grade(r820,d). +registration_grade(r821,b). +registration_grade(r822,a). +registration_grade(r823,a). +registration_grade(r824,c). +registration_grade(r825,b). +registration_grade(r826,b). +registration_grade(r827,c). +registration_grade(r828,b). +registration_grade(r829,b). +registration_grade(r830,a). +registration_grade(r831,a). +registration_grade(r832,b). +registration_grade(r833,b). +registration_grade(r834,b). +registration_grade(r835,a). +registration_grade(r836,a). +registration_grade(r837,c). +registration_grade(r838,c). +registration_grade(r839,b). +registration_grade(r840,b). +registration_grade(r841,a). +registration_grade(r842,a). +registration_grade(r843,b). +registration_grade(r844,a). +registration_grade(r845,c). +registration_grade(r846,b). +registration_grade(r847,b). +registration_grade(r848,c). +registration_grade(r849,b). +registration_grade(r850,b). +registration_grade(r851,b). +registration_grade(r852,c). +registration_grade(r853,b). +registration_grade(r854,c). +registration_grade(r855,d). +registration_grade(r856,c). + +registration_satisfaction(r0,h). +registration_satisfaction(r1,l). +registration_satisfaction(r2,h). +registration_satisfaction(r3,m). +registration_satisfaction(r4,h). +registration_satisfaction(r5,h). +registration_satisfaction(r6,h). +registration_satisfaction(r7,h). +registration_satisfaction(r8,l). +registration_satisfaction(r9,h). +registration_satisfaction(r10,h). +registration_satisfaction(r11,h). +registration_satisfaction(r12,h). +registration_satisfaction(r13,h). +registration_satisfaction(r14,m). +registration_satisfaction(r15,h). +registration_satisfaction(r16,h). +registration_satisfaction(r17,l). +registration_satisfaction(r18,l). +registration_satisfaction(r19,m). +registration_satisfaction(r20,h). +registration_satisfaction(r21,h). +registration_satisfaction(r22,h). +registration_satisfaction(r23,m). +registration_satisfaction(r24,h). +registration_satisfaction(r25,h). +registration_satisfaction(r26,h). +registration_satisfaction(r27,h). +registration_satisfaction(r28,h). +registration_satisfaction(r29,h). +registration_satisfaction(r30,l). +registration_satisfaction(r31,h). +registration_satisfaction(r32,m). +registration_satisfaction(r33,h). +registration_satisfaction(r34,h). +registration_satisfaction(r35,h). +registration_satisfaction(r36,m). +registration_satisfaction(r37,h). +registration_satisfaction(r38,h). +registration_satisfaction(r39,h). +registration_satisfaction(r40,h). +registration_satisfaction(r41,h). +registration_satisfaction(r42,l). +registration_satisfaction(r43,h). +registration_satisfaction(r44,h). +registration_satisfaction(r45,h). +registration_satisfaction(r46,m). +registration_satisfaction(r47,h). +registration_satisfaction(r48,h). +registration_satisfaction(r49,h). +registration_satisfaction(r50,h). +registration_satisfaction(r51,h). +registration_satisfaction(r52,h). +registration_satisfaction(r53,h). +registration_satisfaction(r54,h). +registration_satisfaction(r55,h). +registration_satisfaction(r56,l). +registration_satisfaction(r57,h). +registration_satisfaction(r58,h). +registration_satisfaction(r59,l). +registration_satisfaction(r60,h). +registration_satisfaction(r61,h). +registration_satisfaction(r62,h). +registration_satisfaction(r63,h). +registration_satisfaction(r64,h). +registration_satisfaction(r65,h). +registration_satisfaction(r66,h). +registration_satisfaction(r67,m). +registration_satisfaction(r68,h). +registration_satisfaction(r69,m). +registration_satisfaction(r70,h). +registration_satisfaction(r71,h). +registration_satisfaction(r72,l). +registration_satisfaction(r73,h). +registration_satisfaction(r74,h). +registration_satisfaction(r75,h). +registration_satisfaction(r76,h). +registration_satisfaction(r77,h). +registration_satisfaction(r78,m). +registration_satisfaction(r79,h). +registration_satisfaction(r80,h). +registration_satisfaction(r81,h). +registration_satisfaction(r82,l). +registration_satisfaction(r83,m). +registration_satisfaction(r84,m). +registration_satisfaction(r85,h). +registration_satisfaction(r86,m). +registration_satisfaction(r87,m). +registration_satisfaction(r88,h). +registration_satisfaction(r89,h). +registration_satisfaction(r90,m). +registration_satisfaction(r91,h). +registration_satisfaction(r92,l). +registration_satisfaction(r93,h). +registration_satisfaction(r94,l). +registration_satisfaction(r95,h). +registration_satisfaction(r96,h). +registration_satisfaction(r97,h). +registration_satisfaction(r98,h). +registration_satisfaction(r99,h). +registration_satisfaction(r100,h). +registration_satisfaction(r101,h). +registration_satisfaction(r102,h). +registration_satisfaction(r103,h). +registration_satisfaction(r104,h). +registration_satisfaction(r105,l). +registration_satisfaction(r106,h). +registration_satisfaction(r107,l). +registration_satisfaction(r108,l). +registration_satisfaction(r109,h). +registration_satisfaction(r110,h). +registration_satisfaction(r111,h). +registration_satisfaction(r112,h). +registration_satisfaction(r113,h). +registration_satisfaction(r114,m). +registration_satisfaction(r115,l). +registration_satisfaction(r116,h). +registration_satisfaction(r117,h). +registration_satisfaction(r118,h). +registration_satisfaction(r119,h). +registration_satisfaction(r120,l). +registration_satisfaction(r121,h). +registration_satisfaction(r122,h). +registration_satisfaction(r123,l). +registration_satisfaction(r124,h). +registration_satisfaction(r125,m). +registration_satisfaction(r126,h). +registration_satisfaction(r127,h). +registration_satisfaction(r128,h). +registration_satisfaction(r129,h). +registration_satisfaction(r130,h). +registration_satisfaction(r131,h). +registration_satisfaction(r132,m). +registration_satisfaction(r133,h). +registration_satisfaction(r134,m). +registration_satisfaction(r135,h). +registration_satisfaction(r136,h). +registration_satisfaction(r137,h). +registration_satisfaction(r138,h). +registration_satisfaction(r139,h). +registration_satisfaction(r140,h). +registration_satisfaction(r141,l). +registration_satisfaction(r142,h). +registration_satisfaction(r143,h). +registration_satisfaction(r144,h). +registration_satisfaction(r145,l). +registration_satisfaction(r146,h). +registration_satisfaction(r147,l). +registration_satisfaction(r148,m). +registration_satisfaction(r149,h). +registration_satisfaction(r150,h). +registration_satisfaction(r151,h). +registration_satisfaction(r152,h). +registration_satisfaction(r153,h). +registration_satisfaction(r154,m). +registration_satisfaction(r155,m). +registration_satisfaction(r156,h). +registration_satisfaction(r157,m). +registration_satisfaction(r158,l). +registration_satisfaction(r159,m). +registration_satisfaction(r160,h). +registration_satisfaction(r161,h). +registration_satisfaction(r162,m). +registration_satisfaction(r163,h). +registration_satisfaction(r164,m). +registration_satisfaction(r165,m). +registration_satisfaction(r166,l). +registration_satisfaction(r167,h). +registration_satisfaction(r168,h). +registration_satisfaction(r169,h). +registration_satisfaction(r170,h). +registration_satisfaction(r171,h). +registration_satisfaction(r172,h). +registration_satisfaction(r173,h). +registration_satisfaction(r174,h). +registration_satisfaction(r175,h). +registration_satisfaction(r176,h). +registration_satisfaction(r177,h). +registration_satisfaction(r178,h). +registration_satisfaction(r179,l). +registration_satisfaction(r180,h). +registration_satisfaction(r181,m). +registration_satisfaction(r182,h). +registration_satisfaction(r183,l). +registration_satisfaction(r184,h). +registration_satisfaction(r185,h). +registration_satisfaction(r186,h). +registration_satisfaction(r187,h). +registration_satisfaction(r188,m). +registration_satisfaction(r189,h). +registration_satisfaction(r190,h). +registration_satisfaction(r191,h). +registration_satisfaction(r192,m). +registration_satisfaction(r193,h). +registration_satisfaction(r194,h). +registration_satisfaction(r195,h). +registration_satisfaction(r196,h). +registration_satisfaction(r197,h). +registration_satisfaction(r198,h). +registration_satisfaction(r199,h). +registration_satisfaction(r200,m). +registration_satisfaction(r201,h). +registration_satisfaction(r202,h). +registration_satisfaction(r203,h). +registration_satisfaction(r204,h). +registration_satisfaction(r205,h). +registration_satisfaction(r206,h). +registration_satisfaction(r207,h). +registration_satisfaction(r208,h). +registration_satisfaction(r209,h). +registration_satisfaction(r210,h). +registration_satisfaction(r211,m). +registration_satisfaction(r212,h). +registration_satisfaction(r213,h). +registration_satisfaction(r214,h). +registration_satisfaction(r215,h). +registration_satisfaction(r216,h). +registration_satisfaction(r217,h). +registration_satisfaction(r218,m). +registration_satisfaction(r219,h). +registration_satisfaction(r220,h). +registration_satisfaction(r221,m). +registration_satisfaction(r222,l). +registration_satisfaction(r223,h). +registration_satisfaction(r224,h). +registration_satisfaction(r225,l). +registration_satisfaction(r226,l). +registration_satisfaction(r227,h). +registration_satisfaction(r228,l). +registration_satisfaction(r229,l). +registration_satisfaction(r230,h). +registration_satisfaction(r231,l). +registration_satisfaction(r232,h). +registration_satisfaction(r233,m). +registration_satisfaction(r234,l). +registration_satisfaction(r235,h). +registration_satisfaction(r236,l). +registration_satisfaction(r237,m). +registration_satisfaction(r238,m). +registration_satisfaction(r239,m). +registration_satisfaction(r240,h). +registration_satisfaction(r241,h). +registration_satisfaction(r242,m). +registration_satisfaction(r243,h). +registration_satisfaction(r244,m). +registration_satisfaction(r245,h). +registration_satisfaction(r246,h). +registration_satisfaction(r247,l). +registration_satisfaction(r248,l). +registration_satisfaction(r249,h). +registration_satisfaction(r250,h). +registration_satisfaction(r251,h). +registration_satisfaction(r252,h). +registration_satisfaction(r253,h). +registration_satisfaction(r254,h). +registration_satisfaction(r255,h). +registration_satisfaction(r256,h). +registration_satisfaction(r257,m). +registration_satisfaction(r258,h). +registration_satisfaction(r259,h). +registration_satisfaction(r260,h). +registration_satisfaction(r261,h). +registration_satisfaction(r262,h). +registration_satisfaction(r263,m). +registration_satisfaction(r264,h). +registration_satisfaction(r265,h). +registration_satisfaction(r266,l). +registration_satisfaction(r267,h). +registration_satisfaction(r268,l). +registration_satisfaction(r269,h). +registration_satisfaction(r270,l). +registration_satisfaction(r271,h). +registration_satisfaction(r272,l). +registration_satisfaction(r273,h). +registration_satisfaction(r274,h). +registration_satisfaction(r275,h). +registration_satisfaction(r276,h). +registration_satisfaction(r277,h). +registration_satisfaction(r278,h). +registration_satisfaction(r279,h). +registration_satisfaction(r280,h). +registration_satisfaction(r281,m). +registration_satisfaction(r282,h). +registration_satisfaction(r283,h). +registration_satisfaction(r284,m). +registration_satisfaction(r285,m). +registration_satisfaction(r286,h). +registration_satisfaction(r287,h). +registration_satisfaction(r288,h). +registration_satisfaction(r289,l). +registration_satisfaction(r290,m). +registration_satisfaction(r291,h). +registration_satisfaction(r292,m). +registration_satisfaction(r293,h). +registration_satisfaction(r294,h). +registration_satisfaction(r295,m). +registration_satisfaction(r296,l). +registration_satisfaction(r297,h). +registration_satisfaction(r298,h). +registration_satisfaction(r299,h). +registration_satisfaction(r300,l). +registration_satisfaction(r301,h). +registration_satisfaction(r302,m). +registration_satisfaction(r303,h). +registration_satisfaction(r304,h). +registration_satisfaction(r305,l). +registration_satisfaction(r306,h). +registration_satisfaction(r307,l). +registration_satisfaction(r308,l). +registration_satisfaction(r309,m). +registration_satisfaction(r310,h). +registration_satisfaction(r311,l). +registration_satisfaction(r312,h). +registration_satisfaction(r313,h). +registration_satisfaction(r314,h). +registration_satisfaction(r315,h). +registration_satisfaction(r316,l). +registration_satisfaction(r317,l). +registration_satisfaction(r318,h). +registration_satisfaction(r319,m). +registration_satisfaction(r320,h). +registration_satisfaction(r321,l). +registration_satisfaction(r322,h). +registration_satisfaction(r323,l). +registration_satisfaction(r324,h). +registration_satisfaction(r325,h). +registration_satisfaction(r326,h). +registration_satisfaction(r327,m). +registration_satisfaction(r328,h). +registration_satisfaction(r329,h). +registration_satisfaction(r330,l). +registration_satisfaction(r331,h). +registration_satisfaction(r332,l). +registration_satisfaction(r333,h). +registration_satisfaction(r334,h). +registration_satisfaction(r335,h). +registration_satisfaction(r336,m). +registration_satisfaction(r337,h). +registration_satisfaction(r338,h). +registration_satisfaction(r339,h). +registration_satisfaction(r340,h). +registration_satisfaction(r341,l). +registration_satisfaction(r342,h). +registration_satisfaction(r343,h). +registration_satisfaction(r344,h). +registration_satisfaction(r345,m). +registration_satisfaction(r346,h). +registration_satisfaction(r347,m). +registration_satisfaction(r348,m). +registration_satisfaction(r349,h). +registration_satisfaction(r350,m). +registration_satisfaction(r351,h). +registration_satisfaction(r352,l). +registration_satisfaction(r353,h). +registration_satisfaction(r354,h). +registration_satisfaction(r355,h). +registration_satisfaction(r356,m). +registration_satisfaction(r357,m). +registration_satisfaction(r358,h). +registration_satisfaction(r359,l). +registration_satisfaction(r360,h). +registration_satisfaction(r361,m). +registration_satisfaction(r362,h). +registration_satisfaction(r363,l). +registration_satisfaction(r364,h). +registration_satisfaction(r365,m). +registration_satisfaction(r366,h). +registration_satisfaction(r367,h). +registration_satisfaction(r368,h). +registration_satisfaction(r369,h). +registration_satisfaction(r370,h). +registration_satisfaction(r371,h). +registration_satisfaction(r372,h). +registration_satisfaction(r373,h). +registration_satisfaction(r374,l). +registration_satisfaction(r375,h). +registration_satisfaction(r376,m). +registration_satisfaction(r377,h). +registration_satisfaction(r378,h). +registration_satisfaction(r379,h). +registration_satisfaction(r380,h). +registration_satisfaction(r381,m). +registration_satisfaction(r382,h). +registration_satisfaction(r383,h). +registration_satisfaction(r384,m). +registration_satisfaction(r385,m). +registration_satisfaction(r386,l). +registration_satisfaction(r387,h). +registration_satisfaction(r388,h). +registration_satisfaction(r389,h). +registration_satisfaction(r390,h). +registration_satisfaction(r391,l). +registration_satisfaction(r392,h). +registration_satisfaction(r393,h). +registration_satisfaction(r394,h). +registration_satisfaction(r395,h). +registration_satisfaction(r396,h). +registration_satisfaction(r397,h). +registration_satisfaction(r398,l). +registration_satisfaction(r399,h). +registration_satisfaction(r400,h). +registration_satisfaction(r401,l). +registration_satisfaction(r402,h). +registration_satisfaction(r403,h). +registration_satisfaction(r404,h). +registration_satisfaction(r405,h). +registration_satisfaction(r406,h). +registration_satisfaction(r407,h). +registration_satisfaction(r408,h). +registration_satisfaction(r409,h). +registration_satisfaction(r410,h). +registration_satisfaction(r411,l). +registration_satisfaction(r412,h). +registration_satisfaction(r413,l). +registration_satisfaction(r414,h). +registration_satisfaction(r415,m). +registration_satisfaction(r416,h). +registration_satisfaction(r417,h). +registration_satisfaction(r418,h). +registration_satisfaction(r419,h). +registration_satisfaction(r420,h). +registration_satisfaction(r421,h). +registration_satisfaction(r422,m). +registration_satisfaction(r423,h). +registration_satisfaction(r424,h). +registration_satisfaction(r425,h). +registration_satisfaction(r426,l). +registration_satisfaction(r427,h). +registration_satisfaction(r428,h). +registration_satisfaction(r429,h). +registration_satisfaction(r430,l). +registration_satisfaction(r431,m). +registration_satisfaction(r432,h). +registration_satisfaction(r433,h). +registration_satisfaction(r434,h). +registration_satisfaction(r435,m). +registration_satisfaction(r436,h). +registration_satisfaction(r437,h). +registration_satisfaction(r438,l). +registration_satisfaction(r439,h). +registration_satisfaction(r440,h). +registration_satisfaction(r441,h). +registration_satisfaction(r442,m). +registration_satisfaction(r443,h). +registration_satisfaction(r444,h). +registration_satisfaction(r445,h). +registration_satisfaction(r446,h). +registration_satisfaction(r447,m). +registration_satisfaction(r448,l). +registration_satisfaction(r449,h). +registration_satisfaction(r450,h). +registration_satisfaction(r451,h). +registration_satisfaction(r452,h). +registration_satisfaction(r453,h). +registration_satisfaction(r454,l). +registration_satisfaction(r455,m). +registration_satisfaction(r456,h). +registration_satisfaction(r457,h). +registration_satisfaction(r458,m). +registration_satisfaction(r459,m). +registration_satisfaction(r460,l). +registration_satisfaction(r461,h). +registration_satisfaction(r462,h). +registration_satisfaction(r463,l). +registration_satisfaction(r464,h). +registration_satisfaction(r465,h). +registration_satisfaction(r466,l). +registration_satisfaction(r467,h). +registration_satisfaction(r468,h). +registration_satisfaction(r469,h). +registration_satisfaction(r470,h). +registration_satisfaction(r471,h). +registration_satisfaction(r472,h). +registration_satisfaction(r473,l). +registration_satisfaction(r474,m). +registration_satisfaction(r475,h). +registration_satisfaction(r476,l). +registration_satisfaction(r477,m). +registration_satisfaction(r478,h). +registration_satisfaction(r479,l). +registration_satisfaction(r480,h). +registration_satisfaction(r481,m). +registration_satisfaction(r482,h). +registration_satisfaction(r483,h). +registration_satisfaction(r484,m). +registration_satisfaction(r485,h). +registration_satisfaction(r486,h). +registration_satisfaction(r487,h). +registration_satisfaction(r488,l). +registration_satisfaction(r489,m). +registration_satisfaction(r490,m). +registration_satisfaction(r491,l). +registration_satisfaction(r492,h). +registration_satisfaction(r493,h). +registration_satisfaction(r494,m). +registration_satisfaction(r495,h). +registration_satisfaction(r496,h). +registration_satisfaction(r497,h). +registration_satisfaction(r498,l). +registration_satisfaction(r499,h). +registration_satisfaction(r500,m). +registration_satisfaction(r501,h). +registration_satisfaction(r502,h). +registration_satisfaction(r503,l). +registration_satisfaction(r504,m). +registration_satisfaction(r505,h). +registration_satisfaction(r506,h). +registration_satisfaction(r507,h). +registration_satisfaction(r508,l). +registration_satisfaction(r509,m). +registration_satisfaction(r510,h). +registration_satisfaction(r511,l). +registration_satisfaction(r512,h). +registration_satisfaction(r513,h). +registration_satisfaction(r514,h). +registration_satisfaction(r515,l). +registration_satisfaction(r516,h). +registration_satisfaction(r517,m). +registration_satisfaction(r518,h). +registration_satisfaction(r519,h). +registration_satisfaction(r520,h). +registration_satisfaction(r521,h). +registration_satisfaction(r522,h). +registration_satisfaction(r523,h). +registration_satisfaction(r524,h). +registration_satisfaction(r525,l). +registration_satisfaction(r526,h). +registration_satisfaction(r527,l). +registration_satisfaction(r528,h). +registration_satisfaction(r529,h). +registration_satisfaction(r530,h). +registration_satisfaction(r531,m). +registration_satisfaction(r532,h). +registration_satisfaction(r533,h). +registration_satisfaction(r534,l). +registration_satisfaction(r535,m). +registration_satisfaction(r536,h). +registration_satisfaction(r537,h). +registration_satisfaction(r538,h). +registration_satisfaction(r539,h). +registration_satisfaction(r540,m). +registration_satisfaction(r541,h). +registration_satisfaction(r542,h). +registration_satisfaction(r543,h). +registration_satisfaction(r544,h). +registration_satisfaction(r545,h). +registration_satisfaction(r546,h). +registration_satisfaction(r547,l). +registration_satisfaction(r548,h). +registration_satisfaction(r549,h). +registration_satisfaction(r550,h). +registration_satisfaction(r551,h). +registration_satisfaction(r552,m). +registration_satisfaction(r553,m). +registration_satisfaction(r554,l). +registration_satisfaction(r555,m). +registration_satisfaction(r556,h). +registration_satisfaction(r557,h). +registration_satisfaction(r558,h). +registration_satisfaction(r559,h). +registration_satisfaction(r560,h). +registration_satisfaction(r561,h). +registration_satisfaction(r562,h). +registration_satisfaction(r563,m). +registration_satisfaction(r564,h). +registration_satisfaction(r565,l). +registration_satisfaction(r566,l). +registration_satisfaction(r567,h). +registration_satisfaction(r568,h). +registration_satisfaction(r569,h). +registration_satisfaction(r570,h). +registration_satisfaction(r571,l). +registration_satisfaction(r572,m). +registration_satisfaction(r573,h). +registration_satisfaction(r574,m). +registration_satisfaction(r575,h). +registration_satisfaction(r576,h). +registration_satisfaction(r577,h). +registration_satisfaction(r578,l). +registration_satisfaction(r579,h). +registration_satisfaction(r580,m). +registration_satisfaction(r581,h). +registration_satisfaction(r582,h). +registration_satisfaction(r583,h). +registration_satisfaction(r584,h). +registration_satisfaction(r585,h). +registration_satisfaction(r586,m). +registration_satisfaction(r587,m). +registration_satisfaction(r588,l). +registration_satisfaction(r589,l). +registration_satisfaction(r590,h). +registration_satisfaction(r591,h). +registration_satisfaction(r592,h). +registration_satisfaction(r593,h). +registration_satisfaction(r594,l). +registration_satisfaction(r595,m). +registration_satisfaction(r596,h). +registration_satisfaction(r597,h). +registration_satisfaction(r598,h). +registration_satisfaction(r599,h). +registration_satisfaction(r600,m). +registration_satisfaction(r601,m). +registration_satisfaction(r602,h). +registration_satisfaction(r603,h). +registration_satisfaction(r604,l). +registration_satisfaction(r605,h). +registration_satisfaction(r606,h). +registration_satisfaction(r607,l). +registration_satisfaction(r608,h). +registration_satisfaction(r609,h). +registration_satisfaction(r610,h). +registration_satisfaction(r611,h). +registration_satisfaction(r612,l). +registration_satisfaction(r613,h). +registration_satisfaction(r614,m). +registration_satisfaction(r615,l). +registration_satisfaction(r616,h). +registration_satisfaction(r617,h). +registration_satisfaction(r618,h). +registration_satisfaction(r619,h). +registration_satisfaction(r620,h). +registration_satisfaction(r621,h). +registration_satisfaction(r622,h). +registration_satisfaction(r623,l). +registration_satisfaction(r624,m). +registration_satisfaction(r625,l). +registration_satisfaction(r626,h). +registration_satisfaction(r627,h). +registration_satisfaction(r628,h). +registration_satisfaction(r629,h). +registration_satisfaction(r630,h). +registration_satisfaction(r631,h). +registration_satisfaction(r632,h). +registration_satisfaction(r633,h). +registration_satisfaction(r634,h). +registration_satisfaction(r635,m). +registration_satisfaction(r636,l). +registration_satisfaction(r637,m). +registration_satisfaction(r638,h). +registration_satisfaction(r639,h). +registration_satisfaction(r640,h). +registration_satisfaction(r641,h). +registration_satisfaction(r642,h). +registration_satisfaction(r643,h). +registration_satisfaction(r644,h). +registration_satisfaction(r645,h). +registration_satisfaction(r646,h). +registration_satisfaction(r647,h). +registration_satisfaction(r648,h). +registration_satisfaction(r649,h). +registration_satisfaction(r650,h). +registration_satisfaction(r651,h). +registration_satisfaction(r652,m). +registration_satisfaction(r653,l). +registration_satisfaction(r654,h). +registration_satisfaction(r655,h). +registration_satisfaction(r656,m). +registration_satisfaction(r657,h). +registration_satisfaction(r658,h). +registration_satisfaction(r659,h). +registration_satisfaction(r660,h). +registration_satisfaction(r661,h). +registration_satisfaction(r662,h). +registration_satisfaction(r663,h). +registration_satisfaction(r664,l). +registration_satisfaction(r665,h). +registration_satisfaction(r666,l). +registration_satisfaction(r667,h). +registration_satisfaction(r668,l). +registration_satisfaction(r669,h). +registration_satisfaction(r670,h). +registration_satisfaction(r671,h). +registration_satisfaction(r672,l). +registration_satisfaction(r673,l). +registration_satisfaction(r674,h). +registration_satisfaction(r675,l). +registration_satisfaction(r676,h). +registration_satisfaction(r677,h). +registration_satisfaction(r678,h). +registration_satisfaction(r679,h). +registration_satisfaction(r680,m). +registration_satisfaction(r681,h). +registration_satisfaction(r682,h). +registration_satisfaction(r683,h). +registration_satisfaction(r684,m). +registration_satisfaction(r685,h). +registration_satisfaction(r686,h). +registration_satisfaction(r687,l). +registration_satisfaction(r688,h). +registration_satisfaction(r689,m). +registration_satisfaction(r690,h). +registration_satisfaction(r691,h). +registration_satisfaction(r692,h). +registration_satisfaction(r693,h). +registration_satisfaction(r694,h). +registration_satisfaction(r695,h). +registration_satisfaction(r696,h). +registration_satisfaction(r697,m). +registration_satisfaction(r698,h). +registration_satisfaction(r699,h). +registration_satisfaction(r700,h). +registration_satisfaction(r701,h). +registration_satisfaction(r702,h). +registration_satisfaction(r703,l). +registration_satisfaction(r704,l). +registration_satisfaction(r705,l). +registration_satisfaction(r706,m). +registration_satisfaction(r707,h). +registration_satisfaction(r708,l). +registration_satisfaction(r709,m). +registration_satisfaction(r710,l). +registration_satisfaction(r711,h). +registration_satisfaction(r712,h). +registration_satisfaction(r713,h). +registration_satisfaction(r714,m). +registration_satisfaction(r715,h). +registration_satisfaction(r716,h). +registration_satisfaction(r717,h). +registration_satisfaction(r718,l). +registration_satisfaction(r719,l). +registration_satisfaction(r720,h). +registration_satisfaction(r721,h). +registration_satisfaction(r722,h). +registration_satisfaction(r723,h). +registration_satisfaction(r724,h). +registration_satisfaction(r725,h). +registration_satisfaction(r726,h). +registration_satisfaction(r727,h). +registration_satisfaction(r728,m). +registration_satisfaction(r729,h). +registration_satisfaction(r730,h). +registration_satisfaction(r731,h). +registration_satisfaction(r732,h). +registration_satisfaction(r733,h). +registration_satisfaction(r734,h). +registration_satisfaction(r735,h). +registration_satisfaction(r736,h). +registration_satisfaction(r737,h). +registration_satisfaction(r738,h). +registration_satisfaction(r739,h). +registration_satisfaction(r740,h). +registration_satisfaction(r741,h). +registration_satisfaction(r742,h). +registration_satisfaction(r743,h). +registration_satisfaction(r744,h). +registration_satisfaction(r745,m). +registration_satisfaction(r746,h). +registration_satisfaction(r747,h). +registration_satisfaction(r748,h). +registration_satisfaction(r749,m). +registration_satisfaction(r750,h). +registration_satisfaction(r751,h). +registration_satisfaction(r752,m). +registration_satisfaction(r753,m). +registration_satisfaction(r754,h). +registration_satisfaction(r755,l). +registration_satisfaction(r756,h). +registration_satisfaction(r757,h). +registration_satisfaction(r758,h). +registration_satisfaction(r759,l). +registration_satisfaction(r760,h). +registration_satisfaction(r761,h). +registration_satisfaction(r762,m). +registration_satisfaction(r763,h). +registration_satisfaction(r764,h). +registration_satisfaction(r765,h). +registration_satisfaction(r766,h). +registration_satisfaction(r767,h). +registration_satisfaction(r768,l). +registration_satisfaction(r769,l). +registration_satisfaction(r770,m). +registration_satisfaction(r771,m). +registration_satisfaction(r772,h). +registration_satisfaction(r773,m). +registration_satisfaction(r774,h). +registration_satisfaction(r775,h). +registration_satisfaction(r776,h). +registration_satisfaction(r777,l). +registration_satisfaction(r778,h). +registration_satisfaction(r779,h). +registration_satisfaction(r780,h). +registration_satisfaction(r781,m). +registration_satisfaction(r782,m). +registration_satisfaction(r783,m). +registration_satisfaction(r784,l). +registration_satisfaction(r785,l). +registration_satisfaction(r786,h). +registration_satisfaction(r787,h). +registration_satisfaction(r788,h). +registration_satisfaction(r789,h). +registration_satisfaction(r790,h). +registration_satisfaction(r791,h). +registration_satisfaction(r792,h). +registration_satisfaction(r793,m). +registration_satisfaction(r794,l). +registration_satisfaction(r795,h). +registration_satisfaction(r796,h). +registration_satisfaction(r797,h). +registration_satisfaction(r798,m). +registration_satisfaction(r799,m). +registration_satisfaction(r800,m). +registration_satisfaction(r801,h). +registration_satisfaction(r802,h). +registration_satisfaction(r803,h). +registration_satisfaction(r804,h). +registration_satisfaction(r805,h). +registration_satisfaction(r806,h). +registration_satisfaction(r807,l). +registration_satisfaction(r808,m). +registration_satisfaction(r809,l). +registration_satisfaction(r810,h). +registration_satisfaction(r811,l). +registration_satisfaction(r812,h). +registration_satisfaction(r813,m). +registration_satisfaction(r814,l). +registration_satisfaction(r815,h). +registration_satisfaction(r816,h). +registration_satisfaction(r817,h). +registration_satisfaction(r818,l). +registration_satisfaction(r819,h). +registration_satisfaction(r820,h). +registration_satisfaction(r821,m). +registration_satisfaction(r822,m). +registration_satisfaction(r823,h). +registration_satisfaction(r824,m). +registration_satisfaction(r825,l). +registration_satisfaction(r826,l). +registration_satisfaction(r827,l). +registration_satisfaction(r828,m). +registration_satisfaction(r829,l). +registration_satisfaction(r830,h). +registration_satisfaction(r831,h). +registration_satisfaction(r832,m). +registration_satisfaction(r833,h). +registration_satisfaction(r834,h). +registration_satisfaction(r835,h). +registration_satisfaction(r836,h). +registration_satisfaction(r837,h). +registration_satisfaction(r838,l). +registration_satisfaction(r839,m). +registration_satisfaction(r840,m). +registration_satisfaction(r841,h). +registration_satisfaction(r842,h). +registration_satisfaction(r843,h). +registration_satisfaction(r844,h). +registration_satisfaction(r845,l). +registration_satisfaction(r846,l). +registration_satisfaction(r847,h). +registration_satisfaction(r848,l). +registration_satisfaction(r849,h). +registration_satisfaction(r850,h). +registration_satisfaction(r851,h). +registration_satisfaction(r852,h). +registration_satisfaction(r853,h). +registration_satisfaction(r854,m). +registration_satisfaction(r855,h). +registration_satisfaction(r856,l). + + +course_rating(c0,m). +course_rating(c1,l). +course_rating(c2,m). +course_rating(c3,h). +course_rating(c4,h). +course_rating(c5,m). +course_rating(c6,h). +course_rating(c7,h). +course_rating(c8,m). +course_rating(c9,m). +course_rating(c10,m). +course_rating(c11,h). +course_rating(c12,m). +course_rating(c13,h). +course_rating(c14,h). +course_rating(c15,m). +course_rating(c16,h). +course_rating(c17,m). +course_rating(c18,h). +course_rating(c19,h). +course_rating(c20,h). +course_rating(c21,m). +course_rating(c22,h). +course_rating(c23,h). +course_rating(c24,m). +course_rating(c25,h). +course_rating(c26,m). +course_rating(c27,h). +course_rating(c28,m). +course_rating(c29,m). +course_rating(c30,h). +course_rating(c31,h). +course_rating(c32,h). +course_rating(c33,m). +course_rating(c34,h). +course_rating(c35,m). +course_rating(c36,h). +course_rating(c37,m). +course_rating(c38,m). +course_rating(c39,h). +course_rating(c40,m). +course_rating(c41,m). +course_rating(c42,h). +course_rating(c43,h). +course_rating(c44,h). +course_rating(c45,h). +course_rating(c46,l). +course_rating(c47,h). +course_rating(c48,h). +course_rating(c49,m). +course_rating(c50,l). +course_rating(c51,m). +course_rating(c52,h). +course_rating(c53,l). +course_rating(c54,h). +course_rating(c55,h). +course_rating(c56,h). +course_rating(c57,h). +course_rating(c58,l). +course_rating(c59,h). +course_rating(c60,h). +course_rating(c61,h). +course_rating(c62,h). +course_rating(c63,h). + + +student_ranking(s0,b). +student_ranking(s1,c). +student_ranking(s2,a). +student_ranking(s3,a). +student_ranking(s4,a). +student_ranking(s5,b). +student_ranking(s6,c). +student_ranking(s7,a). +student_ranking(s8,a). +student_ranking(s9,c). +student_ranking(s10,b). +student_ranking(s11,b). +student_ranking(s12,b). +student_ranking(s13,b). +student_ranking(s14,a). +student_ranking(s15,c). +student_ranking(s16,b). +student_ranking(s17,c). +student_ranking(s18,b). +student_ranking(s19,a). +student_ranking(s20,b). +student_ranking(s21,b). +student_ranking(s22,b). +student_ranking(s23,b). +student_ranking(s24,a). +student_ranking(s25,a). +student_ranking(s26,b). +student_ranking(s27,c). +student_ranking(s28,b). +student_ranking(s29,b). +student_ranking(s30,a). +student_ranking(s31,b). +student_ranking(s32,b). +student_ranking(s33,a). +student_ranking(s34,c). +student_ranking(s35,b). +student_ranking(s36,b). +student_ranking(s37,b). +student_ranking(s38,a). +student_ranking(s39,a). +student_ranking(s40,a). +student_ranking(s41,b). +student_ranking(s42,b). +student_ranking(s43,a). +student_ranking(s44,a). +student_ranking(s45,a). +student_ranking(s46,c). +student_ranking(s47,a). +student_ranking(s48,b). +student_ranking(s49,b). +student_ranking(s50,a). +student_ranking(s51,b). +student_ranking(s52,c). +student_ranking(s53,b). +student_ranking(s54,b). +student_ranking(s55,a). +student_ranking(s56,b). +student_ranking(s57,b). +student_ranking(s58,a). +student_ranking(s59,b). +student_ranking(s60,a). +student_ranking(s61,b). +student_ranking(s62,b). +student_ranking(s63,a). +student_ranking(s64,b). +student_ranking(s65,b). +student_ranking(s66,b). +student_ranking(s67,c). +student_ranking(s68,b). +student_ranking(s69,b). +student_ranking(s70,c). +student_ranking(s71,c). +student_ranking(s72,a). +student_ranking(s73,b). +student_ranking(s74,a). +student_ranking(s75,b). +student_ranking(s76,b). +student_ranking(s77,a). +student_ranking(s78,b). +student_ranking(s79,b). +student_ranking(s80,b). +student_ranking(s81,b). +student_ranking(s82,a). +student_ranking(s83,a). +student_ranking(s84,b). +student_ranking(s85,a). +student_ranking(s86,c). +student_ranking(s87,a). +student_ranking(s88,a). +student_ranking(s89,b). +student_ranking(s90,a). +student_ranking(s91,c). +student_ranking(s92,a). +student_ranking(s93,c). +student_ranking(s94,c). +student_ranking(s95,b). +student_ranking(s96,b). +student_ranking(s97,b). +student_ranking(s98,a). +student_ranking(s99,b). +student_ranking(s100,b). +student_ranking(s101,b). +student_ranking(s102,a). +student_ranking(s103,a). +student_ranking(s104,c). +student_ranking(s105,b). +student_ranking(s106,a). +student_ranking(s107,c). +student_ranking(s108,b). +student_ranking(s109,b). +student_ranking(s110,b). +student_ranking(s111,a). +student_ranking(s112,b). +student_ranking(s113,b). +student_ranking(s114,c). +student_ranking(s115,a). +student_ranking(s116,b). +student_ranking(s117,b). +student_ranking(s118,b). +student_ranking(s119,a). +student_ranking(s120,a). +student_ranking(s121,a). +student_ranking(s122,a). +student_ranking(s123,c). +student_ranking(s124,a). +student_ranking(s125,b). +student_ranking(s126,b). +student_ranking(s127,c). +student_ranking(s128,c). +student_ranking(s129,b). +student_ranking(s130,b). +student_ranking(s131,b). +student_ranking(s132,a). +student_ranking(s133,c). +student_ranking(s134,a). +student_ranking(s135,c). +student_ranking(s136,b). +student_ranking(s137,b). +student_ranking(s138,b). +student_ranking(s139,a). +student_ranking(s140,b). +student_ranking(s141,b). +student_ranking(s142,b). +student_ranking(s143,c). +student_ranking(s144,a). +student_ranking(s145,a). +student_ranking(s146,c). +student_ranking(s147,b). +student_ranking(s148,c). +student_ranking(s149,b). +student_ranking(s150,c). +student_ranking(s151,b). +student_ranking(s152,a). +student_ranking(s153,c). +student_ranking(s154,a). +student_ranking(s155,b). +student_ranking(s156,b). +student_ranking(s157,b). +student_ranking(s158,a). +student_ranking(s159,b). +student_ranking(s160,a). +student_ranking(s161,b). +student_ranking(s162,a). +student_ranking(s163,b). +student_ranking(s164,b). +student_ranking(s165,b). +student_ranking(s166,b). +student_ranking(s167,b). +student_ranking(s168,a). +student_ranking(s169,c). +student_ranking(s170,b). +student_ranking(s171,b). +student_ranking(s172,a). +student_ranking(s173,a). +student_ranking(s174,a). +student_ranking(s175,c). +student_ranking(s176,b). +student_ranking(s177,b). +student_ranking(s178,a). +student_ranking(s179,a). +student_ranking(s180,b). +student_ranking(s181,a). +student_ranking(s182,b). +student_ranking(s183,a). +student_ranking(s184,a). +student_ranking(s185,b). +student_ranking(s186,b). +student_ranking(s187,b). +student_ranking(s188,a). +student_ranking(s189,c). +student_ranking(s190,b). +student_ranking(s191,c). +student_ranking(s192,a). +student_ranking(s193,b). +student_ranking(s194,b). +student_ranking(s195,c). +student_ranking(s196,a). +student_ranking(s197,a). +student_ranking(s198,b). +student_ranking(s199,b). +student_ranking(s200,b). +student_ranking(s201,b). +student_ranking(s202,a). +student_ranking(s203,b). +student_ranking(s204,b). +student_ranking(s205,b). +student_ranking(s206,b). +student_ranking(s207,a). +student_ranking(s208,b). +student_ranking(s209,a). +student_ranking(s210,c). +student_ranking(s211,b). +student_ranking(s212,a). +student_ranking(s213,a). +student_ranking(s214,b). +student_ranking(s215,b). +student_ranking(s216,b). +student_ranking(s217,b). +student_ranking(s218,a). +student_ranking(s219,b). +student_ranking(s220,a). +student_ranking(s221,c). +student_ranking(s222,a). +student_ranking(s223,b). +student_ranking(s224,c). +student_ranking(s225,c). +student_ranking(s226,a). +student_ranking(s227,a). +student_ranking(s228,b). +student_ranking(s229,c). +student_ranking(s230,b). +student_ranking(s231,a). +student_ranking(s232,c). +student_ranking(s233,b). +student_ranking(s234,c). +student_ranking(s235,b). +student_ranking(s236,b). +student_ranking(s237,a). +student_ranking(s238,a). +student_ranking(s239,b). +student_ranking(s240,a). +student_ranking(s241,b). +student_ranking(s242,c). +student_ranking(s243,b). +student_ranking(s244,c). +student_ranking(s245,b). +student_ranking(s246,b). +student_ranking(s247,b). +student_ranking(s248,b). +student_ranking(s249,b). +student_ranking(s250,c). +student_ranking(s251,a). +student_ranking(s252,b). +student_ranking(s253,b). +student_ranking(s254,b). +student_ranking(s255,c). diff --git a/packages/CLPBN/clpbn/examples/School/schema.yap b/packages/CLPBN/clpbn/examples/School/schema.yap new file mode 100644 index 000000000..dfeb48ee1 --- /dev/null +++ b/packages/CLPBN/clpbn/examples/School/schema.yap @@ -0,0 +1,71 @@ + +/* base file for school database. Supposed to be called from school_*.yap */ + +professor_key(Key) :- + professor(Key). + +professor_ability(Key,Abi) :- + abi_table(Key, AbiDist), + { Abi = ability(Key) with p([h,m,l], AbiDist) }. + +professor_popularity(Key, Pop) :- + professor_ability(Key, Abi), + pop_table(Key,PopTable), + { Pop = popularity(Key) with + p([h,m,l], PopTable,[Abi]) }. + +registration_key(Key) :- + registration(Key, _, _). + +registration_course(Key, CKey) :- + registration(Key, CKey, _). + +registration_student(Key, SKey) :- + registration(Key, _, SKey). + +registration_grade(Key, Grade) :- + registration(Key, CKey, SKey), + course_difficulty(CKey, Dif), + student_intelligence(SKey, Int), + grade_table(Int, Dif, Table), + { Grade = grade(Key) with Table }. + +% registration_satisfaction(r0, h) :- {}. +registration_satisfaction(Key, Sat) :- + registration_course(Key, CKey), + course_professor(CKey, PKey), + professor_ability(PKey, Abi), + registration_grade(Key, Grade), + satisfaction_table(Abi, Grade, Table), + { Sat = satisfaction(Key) with Table }. + +course_key(Key) :- + course(Key,_). + +course_professor(Key, PKey) :- + course(Key, PKey). + +course_rating(CKey, Rat) :- + setof(Sat, RKey^(registration_course(RKey,CKey), registration_satisfaction(RKey,Sat)), Sats), + { Rat = rating(CKey) with avg([h,m,l],Sats) }. + +course_difficulty(Key, Dif) :- + dif_table(Key, Dist), + { Dif = difficulty(Key) with p([h,m,l], Dist) }. + +student_key(Key) :- + student(Key). + +student_intelligence(Key, Int) :- + int_table(Key, IDist, Domain), + { Int = intelligence(Key) with p(Domain, IDist) }. + +student_ranking(Key, Rank) :- + setof(Grade, CKey^(registration_student(CKey,Key), + registration_grade(CKey, Grade)), Grades), + { Rank = ranking(Key) with avg([a,b,c,d],Grades) }. + +:- ensure_loaded(tables). + + + diff --git a/packages/CLPBN/clpbn/examples/School/school_128.yap b/packages/CLPBN/clpbn/examples/School/school_128.yap new file mode 100644 index 000000000..260be5302 --- /dev/null +++ b/packages/CLPBN/clpbn/examples/School/school_128.yap @@ -0,0 +1,18432 @@ +/* +total_professors(128). + +total_courses(256). + +total_students(4096). + +*/ + +:- source. + +:- style_check(all). + +:- yap_flag(unknown,error). + +:- yap_flag(write_strings,on). + +:- use_module(library(clpbn)). + +:- [-schema]. + +professor(p0). +professor(p1). +professor(p2). +professor(p3). +professor(p4). +professor(p5). +professor(p6). +professor(p7). +professor(p8). +professor(p9). +professor(p10). +professor(p11). +professor(p12). +professor(p13). +professor(p14). +professor(p15). +professor(p16). +professor(p17). +professor(p18). +professor(p19). +professor(p20). +professor(p21). +professor(p22). +professor(p23). +professor(p24). +professor(p25). +professor(p26). +professor(p27). +professor(p28). +professor(p29). +professor(p30). +professor(p31). +professor(p32). +professor(p33). +professor(p34). +professor(p35). +professor(p36). +professor(p37). +professor(p38). +professor(p39). +professor(p40). +professor(p41). +professor(p42). +professor(p43). +professor(p44). +professor(p45). +professor(p46). +professor(p47). +professor(p48). +professor(p49). +professor(p50). +professor(p51). +professor(p52). +professor(p53). +professor(p54). +professor(p55). +professor(p56). +professor(p57). +professor(p58). +professor(p59). +professor(p60). +professor(p61). +professor(p62). +professor(p63). +professor(p64). +professor(p65). +professor(p66). +professor(p67). +professor(p68). +professor(p69). +professor(p70). +professor(p71). +professor(p72). +professor(p73). +professor(p74). +professor(p75). +professor(p76). +professor(p77). +professor(p78). +professor(p79). +professor(p80). +professor(p81). +professor(p82). +professor(p83). +professor(p84). +professor(p85). +professor(p86). +professor(p87). +professor(p88). +professor(p89). +professor(p90). +professor(p91). +professor(p92). +professor(p93). +professor(p94). +professor(p95). +professor(p96). +professor(p97). +professor(p98). +professor(p99). +professor(p100). +professor(p101). +professor(p102). +professor(p103). +professor(p104). +professor(p105). +professor(p106). +professor(p107). +professor(p108). +professor(p109). +professor(p110). +professor(p111). +professor(p112). +professor(p113). +professor(p114). +professor(p115). +professor(p116). +professor(p117). +professor(p118). +professor(p119). +professor(p120). +professor(p121). +professor(p122). +professor(p123). +professor(p124). +professor(p125). +professor(p126). +professor(p127). + + +course(c0,p45). +course(c1,p102). +course(c2,p15). +course(c3,p61). +course(c4,p31). +course(c5,p111). +course(c6,p111). +course(c7,p58). +course(c8,p75). +course(c9,p67). +course(c10,p59). +course(c11,p72). +course(c12,p36). +course(c13,p127). +course(c14,p56). +course(c15,p63). +course(c16,p69). +course(c17,p109). +course(c18,p48). +course(c19,p24). +course(c20,p59). +course(c21,p0). +course(c22,p42). +course(c23,p14). +course(c24,p32). +course(c25,p62). +course(c26,p55). +course(c27,p106). +course(c28,p20). +course(c29,p11). +course(c30,p10). +course(c31,p70). +course(c32,p116). +course(c33,p26). +course(c34,p126). +course(c35,p19). +course(c36,p11). +course(c37,p113). +course(c38,p79). +course(c39,p90). +course(c40,p54). +course(c41,p9). +course(c42,p31). +course(c43,p95). +course(c44,p12). +course(c45,p92). +course(c46,p28). +course(c47,p82). +course(c48,p79). +course(c49,p83). +course(c50,p107). +course(c51,p6). +course(c52,p81). +course(c53,p21). +course(c54,p22). +course(c55,p114). +course(c56,p89). +course(c57,p85). +course(c58,p93). +course(c59,p113). +course(c60,p95). +course(c61,p107). +course(c62,p45). +course(c63,p84). +course(c64,p5). +course(c65,p50). +course(c66,p104). +course(c67,p22). +course(c68,p38). +course(c69,p54). +course(c70,p105). +course(c71,p89). +course(c72,p61). +course(c73,p9). +course(c74,p52). +course(c75,p77). +course(c76,p106). +course(c77,p86). +course(c78,p25). +course(c79,p49). +course(c80,p42). +course(c81,p5). +course(c82,p62). +course(c83,p121). +course(c84,p30). +course(c85,p83). +course(c86,p103). +course(c87,p120). +course(c88,p34). +course(c89,p71). +course(c90,p98). +course(c91,p1). +course(c92,p46). +course(c93,p15). +course(c94,p85). +course(c95,p49). +course(c96,p65). +course(c97,p60). +course(c98,p71). +course(c99,p101). +course(c100,p109). +course(c101,p44). +course(c102,p65). +course(c103,p41). +course(c104,p66). +course(c105,p122). +course(c106,p119). +course(c107,p36). +course(c108,p75). +course(c109,p14). +course(c110,p87). +course(c111,p118). +course(c112,p23). +course(c113,p21). +course(c114,p112). +course(c115,p58). +course(c116,p105). +course(c117,p88). +course(c118,p46). +course(c119,p8). +course(c120,p18). +course(c121,p23). +course(c122,p13). +course(c123,p73). +course(c124,p37). +course(c125,p96). +course(c126,p120). +course(c127,p100). +course(c128,p26). +course(c129,p57). +course(c130,p68). +course(c131,p0). +course(c132,p114). +course(c133,p124). +course(c134,p43). +course(c135,p39). +course(c136,p117). +course(c137,p33). +course(c138,p69). +course(c139,p51). +course(c140,p52). +course(c141,p17). +course(c142,p48). +course(c143,p78). +course(c144,p47). +course(c145,p8). +course(c146,p122). +course(c147,p6). +course(c148,p98). +course(c149,p41). +course(c150,p18). +course(c151,p123). +course(c152,p43). +course(c153,p13). +course(c154,p66). +course(c155,p90). +course(c156,p110). +course(c157,p55). +course(c158,p39). +course(c159,p118). +course(c160,p101). +course(c161,p108). +course(c162,p119). +course(c163,p76). +course(c164,p100). +course(c165,p19). +course(c166,p104). +course(c167,p87). +course(c168,p53). +course(c169,p40). +course(c170,p16). +course(c171,p94). +course(c172,p72). +course(c173,p50). +course(c174,p29). +course(c175,p112). +course(c176,p70). +course(c177,p24). +course(c178,p123). +course(c179,p30). +course(c180,p67). +course(c181,p4). +course(c182,p10). +course(c183,p102). +course(c184,p27). +course(c185,p76). +course(c186,p60). +course(c187,p125). +course(c188,p116). +course(c189,p94). +course(c190,p110). +course(c191,p80). +course(c192,p80). +course(c193,p99). +course(c194,p25). +course(c195,p51). +course(c196,p124). +course(c197,p1). +course(c198,p4). +course(c199,p37). +course(c200,p44). +course(c201,p20). +course(c202,p2). +course(c203,p117). +course(c204,p74). +course(c205,p29). +course(c206,p92). +course(c207,p3). +course(c208,p57). +course(c209,p86). +course(c210,p17). +course(c211,p97). +course(c212,p77). +course(c213,p35). +course(c214,p78). +course(c215,p99). +course(c216,p103). +course(c217,p16). +course(c218,p97). +course(c219,p88). +course(c220,p126). +course(c221,p81). +course(c222,p38). +course(c223,p56). +course(c224,p53). +course(c225,p64). +course(c226,p108). +course(c227,p28). +course(c228,p64). +course(c229,p121). +course(c230,p91). +course(c231,p2). +course(c232,p32). +course(c233,p84). +course(c234,p115). +course(c235,p82). +course(c236,p12). +course(c237,p40). +course(c238,p96). +course(c239,p3). +course(c240,p125). +course(c241,p91). +course(c242,p35). +course(c243,p27). +course(c244,p63). +course(c245,p115). +course(c246,p7). +course(c247,p7). +course(c248,p127). +course(c249,p73). +course(c250,p74). +course(c251,p93). +course(c252,p34). +course(c253,p68). +course(c254,p47). +course(c255,p33). + + +student(s0). +student(s1). +student(s2). +student(s3). +student(s4). +student(s5). +student(s6). +student(s7). +student(s8). +student(s9). +student(s10). +student(s11). +student(s12). +student(s13). +student(s14). +student(s15). +student(s16). +student(s17). +student(s18). +student(s19). +student(s20). +student(s21). +student(s22). +student(s23). +student(s24). +student(s25). +student(s26). +student(s27). +student(s28). +student(s29). +student(s30). +student(s31). +student(s32). +student(s33). +student(s34). +student(s35). +student(s36). +student(s37). +student(s38). +student(s39). +student(s40). +student(s41). +student(s42). +student(s43). +student(s44). +student(s45). +student(s46). +student(s47). +student(s48). +student(s49). +student(s50). +student(s51). +student(s52). +student(s53). +student(s54). +student(s55). +student(s56). +student(s57). +student(s58). +student(s59). +student(s60). +student(s61). +student(s62). +student(s63). +student(s64). +student(s65). +student(s66). +student(s67). +student(s68). +student(s69). +student(s70). +student(s71). +student(s72). +student(s73). +student(s74). +student(s75). +student(s76). +student(s77). +student(s78). +student(s79). +student(s80). +student(s81). +student(s82). +student(s83). +student(s84). +student(s85). +student(s86). +student(s87). +student(s88). +student(s89). +student(s90). +student(s91). +student(s92). +student(s93). +student(s94). +student(s95). +student(s96). +student(s97). +student(s98). +student(s99). +student(s100). +student(s101). +student(s102). +student(s103). +student(s104). +student(s105). +student(s106). +student(s107). +student(s108). +student(s109). +student(s110). +student(s111). +student(s112). +student(s113). +student(s114). +student(s115). +student(s116). +student(s117). +student(s118). +student(s119). +student(s120). +student(s121). +student(s122). +student(s123). +student(s124). +student(s125). +student(s126). +student(s127). +student(s128). +student(s129). +student(s130). +student(s131). +student(s132). +student(s133). +student(s134). +student(s135). +student(s136). +student(s137). +student(s138). +student(s139). +student(s140). +student(s141). +student(s142). +student(s143). +student(s144). +student(s145). +student(s146). +student(s147). +student(s148). +student(s149). +student(s150). +student(s151). +student(s152). +student(s153). +student(s154). +student(s155). +student(s156). +student(s157). +student(s158). +student(s159). +student(s160). +student(s161). +student(s162). +student(s163). +student(s164). +student(s165). +student(s166). +student(s167). +student(s168). +student(s169). +student(s170). +student(s171). +student(s172). +student(s173). +student(s174). +student(s175). +student(s176). +student(s177). +student(s178). +student(s179). +student(s180). +student(s181). +student(s182). +student(s183). +student(s184). +student(s185). +student(s186). +student(s187). +student(s188). +student(s189). +student(s190). +student(s191). +student(s192). +student(s193). +student(s194). +student(s195). +student(s196). +student(s197). +student(s198). +student(s199). +student(s200). +student(s201). +student(s202). +student(s203). +student(s204). +student(s205). +student(s206). +student(s207). +student(s208). +student(s209). +student(s210). +student(s211). +student(s212). +student(s213). +student(s214). +student(s215). +student(s216). +student(s217). +student(s218). +student(s219). +student(s220). +student(s221). +student(s222). +student(s223). +student(s224). +student(s225). +student(s226). +student(s227). +student(s228). +student(s229). +student(s230). +student(s231). +student(s232). +student(s233). +student(s234). +student(s235). +student(s236). +student(s237). +student(s238). +student(s239). +student(s240). +student(s241). +student(s242). +student(s243). +student(s244). +student(s245). +student(s246). +student(s247). +student(s248). +student(s249). +student(s250). +student(s251). +student(s252). +student(s253). +student(s254). +student(s255). +student(s256). +student(s257). +student(s258). +student(s259). +student(s260). +student(s261). +student(s262). +student(s263). +student(s264). +student(s265). +student(s266). +student(s267). +student(s268). +student(s269). +student(s270). +student(s271). +student(s272). +student(s273). +student(s274). +student(s275). +student(s276). +student(s277). +student(s278). +student(s279). +student(s280). +student(s281). +student(s282). +student(s283). +student(s284). +student(s285). +student(s286). +student(s287). +student(s288). +student(s289). +student(s290). +student(s291). +student(s292). +student(s293). +student(s294). +student(s295). +student(s296). +student(s297). +student(s298). +student(s299). +student(s300). +student(s301). +student(s302). +student(s303). +student(s304). +student(s305). +student(s306). +student(s307). +student(s308). +student(s309). +student(s310). +student(s311). +student(s312). +student(s313). +student(s314). +student(s315). +student(s316). +student(s317). +student(s318). +student(s319). +student(s320). +student(s321). +student(s322). +student(s323). +student(s324). +student(s325). +student(s326). +student(s327). +student(s328). +student(s329). +student(s330). +student(s331). +student(s332). +student(s333). +student(s334). +student(s335). +student(s336). +student(s337). +student(s338). +student(s339). +student(s340). +student(s341). +student(s342). +student(s343). +student(s344). +student(s345). +student(s346). +student(s347). +student(s348). +student(s349). +student(s350). +student(s351). +student(s352). +student(s353). +student(s354). +student(s355). +student(s356). +student(s357). +student(s358). +student(s359). +student(s360). +student(s361). +student(s362). +student(s363). +student(s364). +student(s365). +student(s366). +student(s367). +student(s368). +student(s369). +student(s370). +student(s371). +student(s372). +student(s373). +student(s374). +student(s375). +student(s376). +student(s377). +student(s378). +student(s379). +student(s380). +student(s381). +student(s382). +student(s383). +student(s384). +student(s385). +student(s386). +student(s387). +student(s388). +student(s389). +student(s390). +student(s391). +student(s392). +student(s393). +student(s394). +student(s395). +student(s396). +student(s397). +student(s398). +student(s399). +student(s400). +student(s401). +student(s402). +student(s403). +student(s404). +student(s405). +student(s406). +student(s407). +student(s408). +student(s409). +student(s410). +student(s411). +student(s412). +student(s413). +student(s414). +student(s415). +student(s416). +student(s417). +student(s418). +student(s419). +student(s420). +student(s421). +student(s422). +student(s423). +student(s424). +student(s425). +student(s426). +student(s427). +student(s428). +student(s429). +student(s430). +student(s431). +student(s432). +student(s433). +student(s434). +student(s435). +student(s436). +student(s437). +student(s438). +student(s439). +student(s440). +student(s441). +student(s442). +student(s443). +student(s444). +student(s445). +student(s446). +student(s447). +student(s448). +student(s449). +student(s450). +student(s451). +student(s452). +student(s453). +student(s454). +student(s455). +student(s456). +student(s457). +student(s458). +student(s459). +student(s460). +student(s461). +student(s462). +student(s463). +student(s464). +student(s465). +student(s466). +student(s467). +student(s468). +student(s469). +student(s470). +student(s471). +student(s472). +student(s473). +student(s474). +student(s475). +student(s476). +student(s477). +student(s478). +student(s479). +student(s480). +student(s481). +student(s482). +student(s483). +student(s484). +student(s485). +student(s486). +student(s487). +student(s488). +student(s489). +student(s490). +student(s491). +student(s492). +student(s493). +student(s494). +student(s495). +student(s496). +student(s497). +student(s498). +student(s499). +student(s500). +student(s501). +student(s502). +student(s503). +student(s504). +student(s505). +student(s506). +student(s507). +student(s508). +student(s509). +student(s510). +student(s511). +student(s512). +student(s513). +student(s514). +student(s515). +student(s516). +student(s517). +student(s518). +student(s519). +student(s520). +student(s521). +student(s522). +student(s523). +student(s524). +student(s525). +student(s526). +student(s527). +student(s528). +student(s529). +student(s530). +student(s531). +student(s532). +student(s533). +student(s534). +student(s535). +student(s536). +student(s537). +student(s538). +student(s539). +student(s540). +student(s541). +student(s542). +student(s543). +student(s544). +student(s545). +student(s546). +student(s547). +student(s548). +student(s549). +student(s550). +student(s551). +student(s552). +student(s553). +student(s554). +student(s555). +student(s556). +student(s557). +student(s558). +student(s559). +student(s560). +student(s561). +student(s562). +student(s563). +student(s564). +student(s565). +student(s566). +student(s567). +student(s568). +student(s569). +student(s570). +student(s571). +student(s572). +student(s573). +student(s574). +student(s575). +student(s576). +student(s577). +student(s578). +student(s579). +student(s580). +student(s581). +student(s582). +student(s583). +student(s584). +student(s585). +student(s586). +student(s587). +student(s588). +student(s589). +student(s590). +student(s591). +student(s592). +student(s593). +student(s594). +student(s595). +student(s596). +student(s597). +student(s598). +student(s599). +student(s600). +student(s601). +student(s602). +student(s603). +student(s604). +student(s605). +student(s606). +student(s607). +student(s608). +student(s609). +student(s610). +student(s611). +student(s612). +student(s613). +student(s614). +student(s615). +student(s616). +student(s617). +student(s618). +student(s619). +student(s620). +student(s621). +student(s622). +student(s623). +student(s624). +student(s625). +student(s626). +student(s627). +student(s628). +student(s629). +student(s630). +student(s631). +student(s632). +student(s633). +student(s634). +student(s635). +student(s636). +student(s637). +student(s638). +student(s639). +student(s640). +student(s641). +student(s642). +student(s643). +student(s644). +student(s645). +student(s646). +student(s647). +student(s648). +student(s649). +student(s650). +student(s651). +student(s652). +student(s653). +student(s654). +student(s655). +student(s656). +student(s657). +student(s658). +student(s659). +student(s660). +student(s661). +student(s662). +student(s663). +student(s664). +student(s665). +student(s666). +student(s667). +student(s668). +student(s669). +student(s670). +student(s671). +student(s672). +student(s673). +student(s674). +student(s675). +student(s676). +student(s677). +student(s678). +student(s679). +student(s680). +student(s681). +student(s682). +student(s683). +student(s684). +student(s685). +student(s686). +student(s687). +student(s688). +student(s689). +student(s690). +student(s691). +student(s692). +student(s693). +student(s694). +student(s695). +student(s696). +student(s697). +student(s698). +student(s699). +student(s700). +student(s701). +student(s702). +student(s703). +student(s704). +student(s705). +student(s706). +student(s707). +student(s708). +student(s709). +student(s710). +student(s711). +student(s712). +student(s713). +student(s714). +student(s715). +student(s716). +student(s717). +student(s718). +student(s719). +student(s720). +student(s721). +student(s722). +student(s723). +student(s724). +student(s725). +student(s726). +student(s727). +student(s728). +student(s729). +student(s730). +student(s731). +student(s732). +student(s733). +student(s734). +student(s735). +student(s736). +student(s737). +student(s738). +student(s739). +student(s740). +student(s741). +student(s742). +student(s743). +student(s744). +student(s745). +student(s746). +student(s747). +student(s748). +student(s749). +student(s750). +student(s751). +student(s752). +student(s753). +student(s754). +student(s755). +student(s756). +student(s757). +student(s758). +student(s759). +student(s760). +student(s761). +student(s762). +student(s763). +student(s764). +student(s765). +student(s766). +student(s767). +student(s768). +student(s769). +student(s770). +student(s771). +student(s772). +student(s773). +student(s774). +student(s775). +student(s776). +student(s777). +student(s778). +student(s779). +student(s780). +student(s781). +student(s782). +student(s783). +student(s784). +student(s785). +student(s786). +student(s787). +student(s788). +student(s789). +student(s790). +student(s791). +student(s792). +student(s793). +student(s794). +student(s795). +student(s796). +student(s797). +student(s798). +student(s799). +student(s800). +student(s801). +student(s802). +student(s803). +student(s804). +student(s805). +student(s806). +student(s807). +student(s808). +student(s809). +student(s810). +student(s811). +student(s812). +student(s813). +student(s814). +student(s815). +student(s816). +student(s817). +student(s818). +student(s819). +student(s820). +student(s821). +student(s822). +student(s823). +student(s824). +student(s825). +student(s826). +student(s827). +student(s828). +student(s829). +student(s830). +student(s831). +student(s832). +student(s833). +student(s834). +student(s835). +student(s836). +student(s837). +student(s838). +student(s839). +student(s840). +student(s841). +student(s842). +student(s843). +student(s844). +student(s845). +student(s846). +student(s847). +student(s848). +student(s849). +student(s850). +student(s851). +student(s852). +student(s853). +student(s854). +student(s855). +student(s856). +student(s857). +student(s858). +student(s859). +student(s860). +student(s861). +student(s862). +student(s863). +student(s864). +student(s865). +student(s866). +student(s867). +student(s868). +student(s869). +student(s870). +student(s871). +student(s872). +student(s873). +student(s874). +student(s875). +student(s876). +student(s877). +student(s878). +student(s879). +student(s880). +student(s881). +student(s882). +student(s883). +student(s884). +student(s885). +student(s886). +student(s887). +student(s888). +student(s889). +student(s890). +student(s891). +student(s892). +student(s893). +student(s894). +student(s895). +student(s896). +student(s897). +student(s898). +student(s899). +student(s900). +student(s901). +student(s902). +student(s903). +student(s904). +student(s905). +student(s906). +student(s907). +student(s908). +student(s909). +student(s910). +student(s911). +student(s912). +student(s913). +student(s914). +student(s915). +student(s916). +student(s917). +student(s918). +student(s919). +student(s920). +student(s921). +student(s922). +student(s923). +student(s924). +student(s925). +student(s926). +student(s927). +student(s928). +student(s929). +student(s930). +student(s931). +student(s932). +student(s933). +student(s934). +student(s935). +student(s936). +student(s937). +student(s938). +student(s939). +student(s940). +student(s941). +student(s942). +student(s943). +student(s944). +student(s945). +student(s946). +student(s947). +student(s948). +student(s949). +student(s950). +student(s951). +student(s952). +student(s953). +student(s954). +student(s955). +student(s956). +student(s957). +student(s958). +student(s959). +student(s960). +student(s961). +student(s962). +student(s963). +student(s964). +student(s965). +student(s966). +student(s967). +student(s968). +student(s969). +student(s970). +student(s971). +student(s972). +student(s973). +student(s974). +student(s975). +student(s976). +student(s977). +student(s978). +student(s979). +student(s980). +student(s981). +student(s982). +student(s983). +student(s984). +student(s985). +student(s986). +student(s987). +student(s988). +student(s989). +student(s990). +student(s991). +student(s992). +student(s993). +student(s994). +student(s995). +student(s996). +student(s997). +student(s998). +student(s999). +student(s1000). +student(s1001). +student(s1002). +student(s1003). +student(s1004). +student(s1005). +student(s1006). +student(s1007). +student(s1008). +student(s1009). +student(s1010). +student(s1011). +student(s1012). +student(s1013). +student(s1014). +student(s1015). +student(s1016). +student(s1017). +student(s1018). +student(s1019). +student(s1020). +student(s1021). +student(s1022). +student(s1023). +student(s1024). +student(s1025). +student(s1026). +student(s1027). +student(s1028). +student(s1029). +student(s1030). +student(s1031). +student(s1032). +student(s1033). +student(s1034). +student(s1035). +student(s1036). +student(s1037). +student(s1038). +student(s1039). +student(s1040). +student(s1041). +student(s1042). +student(s1043). +student(s1044). +student(s1045). +student(s1046). +student(s1047). +student(s1048). +student(s1049). +student(s1050). +student(s1051). +student(s1052). +student(s1053). +student(s1054). +student(s1055). +student(s1056). +student(s1057). +student(s1058). +student(s1059). +student(s1060). +student(s1061). +student(s1062). +student(s1063). +student(s1064). +student(s1065). +student(s1066). +student(s1067). +student(s1068). +student(s1069). +student(s1070). +student(s1071). +student(s1072). +student(s1073). +student(s1074). +student(s1075). +student(s1076). +student(s1077). +student(s1078). +student(s1079). +student(s1080). +student(s1081). +student(s1082). +student(s1083). +student(s1084). +student(s1085). +student(s1086). +student(s1087). +student(s1088). +student(s1089). +student(s1090). +student(s1091). +student(s1092). +student(s1093). +student(s1094). +student(s1095). +student(s1096). +student(s1097). +student(s1098). +student(s1099). +student(s1100). +student(s1101). +student(s1102). +student(s1103). +student(s1104). +student(s1105). +student(s1106). +student(s1107). +student(s1108). +student(s1109). +student(s1110). +student(s1111). +student(s1112). +student(s1113). +student(s1114). +student(s1115). +student(s1116). +student(s1117). +student(s1118). +student(s1119). +student(s1120). +student(s1121). +student(s1122). +student(s1123). +student(s1124). +student(s1125). +student(s1126). +student(s1127). +student(s1128). +student(s1129). +student(s1130). +student(s1131). +student(s1132). +student(s1133). +student(s1134). +student(s1135). +student(s1136). +student(s1137). +student(s1138). +student(s1139). +student(s1140). +student(s1141). +student(s1142). +student(s1143). +student(s1144). +student(s1145). +student(s1146). +student(s1147). +student(s1148). +student(s1149). +student(s1150). +student(s1151). +student(s1152). +student(s1153). +student(s1154). +student(s1155). +student(s1156). +student(s1157). +student(s1158). +student(s1159). +student(s1160). +student(s1161). +student(s1162). +student(s1163). +student(s1164). +student(s1165). +student(s1166). +student(s1167). +student(s1168). +student(s1169). +student(s1170). +student(s1171). +student(s1172). +student(s1173). +student(s1174). +student(s1175). +student(s1176). +student(s1177). +student(s1178). +student(s1179). +student(s1180). +student(s1181). +student(s1182). +student(s1183). +student(s1184). +student(s1185). +student(s1186). +student(s1187). +student(s1188). +student(s1189). +student(s1190). +student(s1191). +student(s1192). +student(s1193). +student(s1194). +student(s1195). +student(s1196). +student(s1197). +student(s1198). +student(s1199). +student(s1200). +student(s1201). +student(s1202). +student(s1203). +student(s1204). +student(s1205). +student(s1206). +student(s1207). +student(s1208). +student(s1209). +student(s1210). +student(s1211). +student(s1212). +student(s1213). +student(s1214). +student(s1215). +student(s1216). +student(s1217). +student(s1218). +student(s1219). +student(s1220). +student(s1221). +student(s1222). +student(s1223). +student(s1224). +student(s1225). +student(s1226). +student(s1227). +student(s1228). +student(s1229). +student(s1230). +student(s1231). +student(s1232). +student(s1233). +student(s1234). +student(s1235). +student(s1236). +student(s1237). +student(s1238). +student(s1239). +student(s1240). +student(s1241). +student(s1242). +student(s1243). +student(s1244). +student(s1245). +student(s1246). +student(s1247). +student(s1248). +student(s1249). +student(s1250). +student(s1251). +student(s1252). +student(s1253). +student(s1254). +student(s1255). +student(s1256). +student(s1257). +student(s1258). +student(s1259). +student(s1260). +student(s1261). +student(s1262). +student(s1263). +student(s1264). +student(s1265). +student(s1266). +student(s1267). +student(s1268). +student(s1269). +student(s1270). +student(s1271). +student(s1272). +student(s1273). +student(s1274). +student(s1275). +student(s1276). +student(s1277). +student(s1278). +student(s1279). +student(s1280). +student(s1281). +student(s1282). +student(s1283). +student(s1284). +student(s1285). +student(s1286). +student(s1287). +student(s1288). +student(s1289). +student(s1290). +student(s1291). +student(s1292). +student(s1293). +student(s1294). +student(s1295). +student(s1296). +student(s1297). +student(s1298). +student(s1299). +student(s1300). +student(s1301). +student(s1302). +student(s1303). +student(s1304). +student(s1305). +student(s1306). +student(s1307). +student(s1308). +student(s1309). +student(s1310). +student(s1311). +student(s1312). +student(s1313). +student(s1314). +student(s1315). +student(s1316). +student(s1317). +student(s1318). +student(s1319). +student(s1320). +student(s1321). +student(s1322). +student(s1323). +student(s1324). +student(s1325). +student(s1326). +student(s1327). +student(s1328). +student(s1329). +student(s1330). +student(s1331). +student(s1332). +student(s1333). +student(s1334). +student(s1335). +student(s1336). +student(s1337). +student(s1338). +student(s1339). +student(s1340). +student(s1341). +student(s1342). +student(s1343). +student(s1344). +student(s1345). +student(s1346). +student(s1347). +student(s1348). +student(s1349). +student(s1350). +student(s1351). +student(s1352). +student(s1353). +student(s1354). +student(s1355). +student(s1356). +student(s1357). +student(s1358). +student(s1359). +student(s1360). +student(s1361). +student(s1362). +student(s1363). +student(s1364). +student(s1365). +student(s1366). +student(s1367). +student(s1368). +student(s1369). +student(s1370). +student(s1371). +student(s1372). +student(s1373). +student(s1374). +student(s1375). +student(s1376). +student(s1377). +student(s1378). +student(s1379). +student(s1380). +student(s1381). +student(s1382). +student(s1383). +student(s1384). +student(s1385). +student(s1386). +student(s1387). +student(s1388). +student(s1389). +student(s1390). +student(s1391). +student(s1392). +student(s1393). +student(s1394). +student(s1395). +student(s1396). +student(s1397). +student(s1398). +student(s1399). +student(s1400). +student(s1401). +student(s1402). +student(s1403). +student(s1404). +student(s1405). +student(s1406). +student(s1407). +student(s1408). +student(s1409). +student(s1410). +student(s1411). +student(s1412). +student(s1413). +student(s1414). +student(s1415). +student(s1416). +student(s1417). +student(s1418). +student(s1419). +student(s1420). +student(s1421). +student(s1422). +student(s1423). +student(s1424). +student(s1425). +student(s1426). +student(s1427). +student(s1428). +student(s1429). +student(s1430). +student(s1431). +student(s1432). +student(s1433). +student(s1434). +student(s1435). +student(s1436). +student(s1437). +student(s1438). +student(s1439). +student(s1440). +student(s1441). +student(s1442). +student(s1443). +student(s1444). +student(s1445). +student(s1446). +student(s1447). +student(s1448). +student(s1449). +student(s1450). +student(s1451). +student(s1452). +student(s1453). +student(s1454). +student(s1455). +student(s1456). +student(s1457). +student(s1458). +student(s1459). +student(s1460). +student(s1461). +student(s1462). +student(s1463). +student(s1464). +student(s1465). +student(s1466). +student(s1467). +student(s1468). +student(s1469). +student(s1470). +student(s1471). +student(s1472). +student(s1473). +student(s1474). +student(s1475). +student(s1476). +student(s1477). +student(s1478). +student(s1479). +student(s1480). +student(s1481). +student(s1482). +student(s1483). +student(s1484). +student(s1485). +student(s1486). +student(s1487). +student(s1488). +student(s1489). +student(s1490). +student(s1491). +student(s1492). +student(s1493). +student(s1494). +student(s1495). +student(s1496). +student(s1497). +student(s1498). +student(s1499). +student(s1500). +student(s1501). +student(s1502). +student(s1503). +student(s1504). +student(s1505). +student(s1506). +student(s1507). +student(s1508). +student(s1509). +student(s1510). +student(s1511). +student(s1512). +student(s1513). +student(s1514). +student(s1515). +student(s1516). +student(s1517). +student(s1518). +student(s1519). +student(s1520). +student(s1521). +student(s1522). +student(s1523). +student(s1524). +student(s1525). +student(s1526). +student(s1527). +student(s1528). +student(s1529). +student(s1530). +student(s1531). +student(s1532). +student(s1533). +student(s1534). +student(s1535). +student(s1536). +student(s1537). +student(s1538). +student(s1539). +student(s1540). +student(s1541). +student(s1542). +student(s1543). +student(s1544). +student(s1545). +student(s1546). +student(s1547). +student(s1548). +student(s1549). +student(s1550). +student(s1551). +student(s1552). +student(s1553). +student(s1554). +student(s1555). +student(s1556). +student(s1557). +student(s1558). +student(s1559). +student(s1560). +student(s1561). +student(s1562). +student(s1563). +student(s1564). +student(s1565). +student(s1566). +student(s1567). +student(s1568). +student(s1569). +student(s1570). +student(s1571). +student(s1572). +student(s1573). +student(s1574). +student(s1575). +student(s1576). +student(s1577). +student(s1578). +student(s1579). +student(s1580). +student(s1581). +student(s1582). +student(s1583). +student(s1584). +student(s1585). +student(s1586). +student(s1587). +student(s1588). +student(s1589). +student(s1590). +student(s1591). +student(s1592). +student(s1593). +student(s1594). +student(s1595). +student(s1596). +student(s1597). +student(s1598). +student(s1599). +student(s1600). +student(s1601). +student(s1602). +student(s1603). +student(s1604). +student(s1605). +student(s1606). +student(s1607). +student(s1608). +student(s1609). +student(s1610). +student(s1611). +student(s1612). +student(s1613). +student(s1614). +student(s1615). +student(s1616). +student(s1617). +student(s1618). +student(s1619). +student(s1620). +student(s1621). +student(s1622). +student(s1623). +student(s1624). +student(s1625). +student(s1626). +student(s1627). +student(s1628). +student(s1629). +student(s1630). +student(s1631). +student(s1632). +student(s1633). +student(s1634). +student(s1635). +student(s1636). +student(s1637). +student(s1638). +student(s1639). +student(s1640). +student(s1641). +student(s1642). +student(s1643). +student(s1644). +student(s1645). +student(s1646). +student(s1647). +student(s1648). +student(s1649). +student(s1650). +student(s1651). +student(s1652). +student(s1653). +student(s1654). +student(s1655). +student(s1656). +student(s1657). +student(s1658). +student(s1659). +student(s1660). +student(s1661). +student(s1662). +student(s1663). +student(s1664). +student(s1665). +student(s1666). +student(s1667). +student(s1668). +student(s1669). +student(s1670). +student(s1671). +student(s1672). +student(s1673). +student(s1674). +student(s1675). +student(s1676). +student(s1677). +student(s1678). +student(s1679). +student(s1680). +student(s1681). +student(s1682). +student(s1683). +student(s1684). +student(s1685). +student(s1686). +student(s1687). +student(s1688). +student(s1689). +student(s1690). +student(s1691). +student(s1692). +student(s1693). +student(s1694). +student(s1695). +student(s1696). +student(s1697). +student(s1698). +student(s1699). +student(s1700). +student(s1701). +student(s1702). +student(s1703). +student(s1704). +student(s1705). +student(s1706). +student(s1707). +student(s1708). +student(s1709). +student(s1710). +student(s1711). +student(s1712). +student(s1713). +student(s1714). +student(s1715). +student(s1716). +student(s1717). +student(s1718). +student(s1719). +student(s1720). +student(s1721). +student(s1722). +student(s1723). +student(s1724). +student(s1725). +student(s1726). +student(s1727). +student(s1728). +student(s1729). +student(s1730). +student(s1731). +student(s1732). +student(s1733). +student(s1734). +student(s1735). +student(s1736). +student(s1737). +student(s1738). +student(s1739). +student(s1740). +student(s1741). +student(s1742). +student(s1743). +student(s1744). +student(s1745). +student(s1746). +student(s1747). +student(s1748). +student(s1749). +student(s1750). +student(s1751). +student(s1752). +student(s1753). +student(s1754). +student(s1755). +student(s1756). +student(s1757). +student(s1758). +student(s1759). +student(s1760). +student(s1761). +student(s1762). +student(s1763). +student(s1764). +student(s1765). +student(s1766). +student(s1767). +student(s1768). +student(s1769). +student(s1770). +student(s1771). +student(s1772). +student(s1773). +student(s1774). +student(s1775). +student(s1776). +student(s1777). +student(s1778). +student(s1779). +student(s1780). +student(s1781). +student(s1782). +student(s1783). +student(s1784). +student(s1785). +student(s1786). +student(s1787). +student(s1788). +student(s1789). +student(s1790). +student(s1791). +student(s1792). +student(s1793). +student(s1794). +student(s1795). +student(s1796). +student(s1797). +student(s1798). +student(s1799). +student(s1800). +student(s1801). +student(s1802). +student(s1803). +student(s1804). +student(s1805). +student(s1806). +student(s1807). +student(s1808). +student(s1809). +student(s1810). +student(s1811). +student(s1812). +student(s1813). +student(s1814). +student(s1815). +student(s1816). +student(s1817). +student(s1818). +student(s1819). +student(s1820). +student(s1821). +student(s1822). +student(s1823). +student(s1824). +student(s1825). +student(s1826). +student(s1827). +student(s1828). +student(s1829). +student(s1830). +student(s1831). +student(s1832). +student(s1833). +student(s1834). +student(s1835). +student(s1836). +student(s1837). +student(s1838). +student(s1839). +student(s1840). +student(s1841). +student(s1842). +student(s1843). +student(s1844). +student(s1845). +student(s1846). +student(s1847). +student(s1848). +student(s1849). +student(s1850). +student(s1851). +student(s1852). +student(s1853). +student(s1854). +student(s1855). +student(s1856). +student(s1857). +student(s1858). +student(s1859). +student(s1860). +student(s1861). +student(s1862). +student(s1863). +student(s1864). +student(s1865). +student(s1866). +student(s1867). +student(s1868). +student(s1869). +student(s1870). +student(s1871). +student(s1872). +student(s1873). +student(s1874). +student(s1875). +student(s1876). +student(s1877). +student(s1878). +student(s1879). +student(s1880). +student(s1881). +student(s1882). +student(s1883). +student(s1884). +student(s1885). +student(s1886). +student(s1887). +student(s1888). +student(s1889). +student(s1890). +student(s1891). +student(s1892). +student(s1893). +student(s1894). +student(s1895). +student(s1896). +student(s1897). +student(s1898). +student(s1899). +student(s1900). +student(s1901). +student(s1902). +student(s1903). +student(s1904). +student(s1905). +student(s1906). +student(s1907). +student(s1908). +student(s1909). +student(s1910). +student(s1911). +student(s1912). +student(s1913). +student(s1914). +student(s1915). +student(s1916). +student(s1917). +student(s1918). +student(s1919). +student(s1920). +student(s1921). +student(s1922). +student(s1923). +student(s1924). +student(s1925). +student(s1926). +student(s1927). +student(s1928). +student(s1929). +student(s1930). +student(s1931). +student(s1932). +student(s1933). +student(s1934). +student(s1935). +student(s1936). +student(s1937). +student(s1938). +student(s1939). +student(s1940). +student(s1941). +student(s1942). +student(s1943). +student(s1944). +student(s1945). +student(s1946). +student(s1947). +student(s1948). +student(s1949). +student(s1950). +student(s1951). +student(s1952). +student(s1953). +student(s1954). +student(s1955). +student(s1956). +student(s1957). +student(s1958). +student(s1959). +student(s1960). +student(s1961). +student(s1962). +student(s1963). +student(s1964). +student(s1965). +student(s1966). +student(s1967). +student(s1968). +student(s1969). +student(s1970). +student(s1971). +student(s1972). +student(s1973). +student(s1974). +student(s1975). +student(s1976). +student(s1977). +student(s1978). +student(s1979). +student(s1980). +student(s1981). +student(s1982). +student(s1983). +student(s1984). +student(s1985). +student(s1986). +student(s1987). +student(s1988). +student(s1989). +student(s1990). +student(s1991). +student(s1992). +student(s1993). +student(s1994). +student(s1995). +student(s1996). +student(s1997). +student(s1998). +student(s1999). +student(s2000). +student(s2001). +student(s2002). +student(s2003). +student(s2004). +student(s2005). +student(s2006). +student(s2007). +student(s2008). +student(s2009). +student(s2010). +student(s2011). +student(s2012). +student(s2013). +student(s2014). +student(s2015). +student(s2016). +student(s2017). +student(s2018). +student(s2019). +student(s2020). +student(s2021). +student(s2022). +student(s2023). +student(s2024). +student(s2025). +student(s2026). +student(s2027). +student(s2028). +student(s2029). +student(s2030). +student(s2031). +student(s2032). +student(s2033). +student(s2034). +student(s2035). +student(s2036). +student(s2037). +student(s2038). +student(s2039). +student(s2040). +student(s2041). +student(s2042). +student(s2043). +student(s2044). +student(s2045). +student(s2046). +student(s2047). +student(s2048). +student(s2049). +student(s2050). +student(s2051). +student(s2052). +student(s2053). +student(s2054). +student(s2055). +student(s2056). +student(s2057). +student(s2058). +student(s2059). +student(s2060). +student(s2061). +student(s2062). +student(s2063). +student(s2064). +student(s2065). +student(s2066). +student(s2067). +student(s2068). +student(s2069). +student(s2070). +student(s2071). +student(s2072). +student(s2073). +student(s2074). +student(s2075). +student(s2076). +student(s2077). +student(s2078). +student(s2079). +student(s2080). +student(s2081). +student(s2082). +student(s2083). +student(s2084). +student(s2085). +student(s2086). +student(s2087). +student(s2088). +student(s2089). +student(s2090). +student(s2091). +student(s2092). +student(s2093). +student(s2094). +student(s2095). +student(s2096). +student(s2097). +student(s2098). +student(s2099). +student(s2100). +student(s2101). +student(s2102). +student(s2103). +student(s2104). +student(s2105). +student(s2106). +student(s2107). +student(s2108). +student(s2109). +student(s2110). +student(s2111). +student(s2112). +student(s2113). +student(s2114). +student(s2115). +student(s2116). +student(s2117). +student(s2118). +student(s2119). +student(s2120). +student(s2121). +student(s2122). +student(s2123). +student(s2124). +student(s2125). +student(s2126). +student(s2127). +student(s2128). +student(s2129). +student(s2130). +student(s2131). +student(s2132). +student(s2133). +student(s2134). +student(s2135). +student(s2136). +student(s2137). +student(s2138). +student(s2139). +student(s2140). +student(s2141). +student(s2142). +student(s2143). +student(s2144). +student(s2145). +student(s2146). +student(s2147). +student(s2148). +student(s2149). +student(s2150). +student(s2151). +student(s2152). +student(s2153). +student(s2154). +student(s2155). +student(s2156). +student(s2157). +student(s2158). +student(s2159). +student(s2160). +student(s2161). +student(s2162). +student(s2163). +student(s2164). +student(s2165). +student(s2166). +student(s2167). +student(s2168). +student(s2169). +student(s2170). +student(s2171). +student(s2172). +student(s2173). +student(s2174). +student(s2175). +student(s2176). +student(s2177). +student(s2178). +student(s2179). +student(s2180). +student(s2181). +student(s2182). +student(s2183). +student(s2184). +student(s2185). +student(s2186). +student(s2187). +student(s2188). +student(s2189). +student(s2190). +student(s2191). +student(s2192). +student(s2193). +student(s2194). +student(s2195). +student(s2196). +student(s2197). +student(s2198). +student(s2199). +student(s2200). +student(s2201). +student(s2202). +student(s2203). +student(s2204). +student(s2205). +student(s2206). +student(s2207). +student(s2208). +student(s2209). +student(s2210). +student(s2211). +student(s2212). +student(s2213). +student(s2214). +student(s2215). +student(s2216). +student(s2217). +student(s2218). +student(s2219). +student(s2220). +student(s2221). +student(s2222). +student(s2223). +student(s2224). +student(s2225). +student(s2226). +student(s2227). +student(s2228). +student(s2229). +student(s2230). +student(s2231). +student(s2232). +student(s2233). +student(s2234). +student(s2235). +student(s2236). +student(s2237). +student(s2238). +student(s2239). +student(s2240). +student(s2241). +student(s2242). +student(s2243). +student(s2244). +student(s2245). +student(s2246). +student(s2247). +student(s2248). +student(s2249). +student(s2250). +student(s2251). +student(s2252). +student(s2253). +student(s2254). +student(s2255). +student(s2256). +student(s2257). +student(s2258). +student(s2259). +student(s2260). +student(s2261). +student(s2262). +student(s2263). +student(s2264). +student(s2265). +student(s2266). +student(s2267). +student(s2268). +student(s2269). +student(s2270). +student(s2271). +student(s2272). +student(s2273). +student(s2274). +student(s2275). +student(s2276). +student(s2277). +student(s2278). +student(s2279). +student(s2280). +student(s2281). +student(s2282). +student(s2283). +student(s2284). +student(s2285). +student(s2286). +student(s2287). +student(s2288). +student(s2289). +student(s2290). +student(s2291). +student(s2292). +student(s2293). +student(s2294). +student(s2295). +student(s2296). +student(s2297). +student(s2298). +student(s2299). +student(s2300). +student(s2301). +student(s2302). +student(s2303). +student(s2304). +student(s2305). +student(s2306). +student(s2307). +student(s2308). +student(s2309). +student(s2310). +student(s2311). +student(s2312). +student(s2313). +student(s2314). +student(s2315). +student(s2316). +student(s2317). +student(s2318). +student(s2319). +student(s2320). +student(s2321). +student(s2322). +student(s2323). +student(s2324). +student(s2325). +student(s2326). +student(s2327). +student(s2328). +student(s2329). +student(s2330). +student(s2331). +student(s2332). +student(s2333). +student(s2334). +student(s2335). +student(s2336). +student(s2337). +student(s2338). +student(s2339). +student(s2340). +student(s2341). +student(s2342). +student(s2343). +student(s2344). +student(s2345). +student(s2346). +student(s2347). +student(s2348). +student(s2349). +student(s2350). +student(s2351). +student(s2352). +student(s2353). +student(s2354). +student(s2355). +student(s2356). +student(s2357). +student(s2358). +student(s2359). +student(s2360). +student(s2361). +student(s2362). +student(s2363). +student(s2364). +student(s2365). +student(s2366). +student(s2367). +student(s2368). +student(s2369). +student(s2370). +student(s2371). +student(s2372). +student(s2373). +student(s2374). +student(s2375). +student(s2376). +student(s2377). +student(s2378). +student(s2379). +student(s2380). +student(s2381). +student(s2382). +student(s2383). +student(s2384). +student(s2385). +student(s2386). +student(s2387). +student(s2388). +student(s2389). +student(s2390). +student(s2391). +student(s2392). +student(s2393). +student(s2394). +student(s2395). +student(s2396). +student(s2397). +student(s2398). +student(s2399). +student(s2400). +student(s2401). +student(s2402). +student(s2403). +student(s2404). +student(s2405). +student(s2406). +student(s2407). +student(s2408). +student(s2409). +student(s2410). +student(s2411). +student(s2412). +student(s2413). +student(s2414). +student(s2415). +student(s2416). +student(s2417). +student(s2418). +student(s2419). +student(s2420). +student(s2421). +student(s2422). +student(s2423). +student(s2424). +student(s2425). +student(s2426). +student(s2427). +student(s2428). +student(s2429). +student(s2430). +student(s2431). +student(s2432). +student(s2433). +student(s2434). +student(s2435). +student(s2436). +student(s2437). +student(s2438). +student(s2439). +student(s2440). +student(s2441). +student(s2442). +student(s2443). +student(s2444). +student(s2445). +student(s2446). +student(s2447). +student(s2448). +student(s2449). +student(s2450). +student(s2451). +student(s2452). +student(s2453). +student(s2454). +student(s2455). +student(s2456). +student(s2457). +student(s2458). +student(s2459). +student(s2460). +student(s2461). +student(s2462). +student(s2463). +student(s2464). +student(s2465). +student(s2466). +student(s2467). +student(s2468). +student(s2469). +student(s2470). +student(s2471). +student(s2472). +student(s2473). +student(s2474). +student(s2475). +student(s2476). +student(s2477). +student(s2478). +student(s2479). +student(s2480). +student(s2481). +student(s2482). +student(s2483). +student(s2484). +student(s2485). +student(s2486). +student(s2487). +student(s2488). +student(s2489). +student(s2490). +student(s2491). +student(s2492). +student(s2493). +student(s2494). +student(s2495). +student(s2496). +student(s2497). +student(s2498). +student(s2499). +student(s2500). +student(s2501). +student(s2502). +student(s2503). +student(s2504). +student(s2505). +student(s2506). +student(s2507). +student(s2508). +student(s2509). +student(s2510). +student(s2511). +student(s2512). +student(s2513). +student(s2514). +student(s2515). +student(s2516). +student(s2517). +student(s2518). +student(s2519). +student(s2520). +student(s2521). +student(s2522). +student(s2523). +student(s2524). +student(s2525). +student(s2526). +student(s2527). +student(s2528). +student(s2529). +student(s2530). +student(s2531). +student(s2532). +student(s2533). +student(s2534). +student(s2535). +student(s2536). +student(s2537). +student(s2538). +student(s2539). +student(s2540). +student(s2541). +student(s2542). +student(s2543). +student(s2544). +student(s2545). +student(s2546). +student(s2547). +student(s2548). +student(s2549). +student(s2550). +student(s2551). +student(s2552). +student(s2553). +student(s2554). +student(s2555). +student(s2556). +student(s2557). +student(s2558). +student(s2559). +student(s2560). +student(s2561). +student(s2562). +student(s2563). +student(s2564). +student(s2565). +student(s2566). +student(s2567). +student(s2568). +student(s2569). +student(s2570). +student(s2571). +student(s2572). +student(s2573). +student(s2574). +student(s2575). +student(s2576). +student(s2577). +student(s2578). +student(s2579). +student(s2580). +student(s2581). +student(s2582). +student(s2583). +student(s2584). +student(s2585). +student(s2586). +student(s2587). +student(s2588). +student(s2589). +student(s2590). +student(s2591). +student(s2592). +student(s2593). +student(s2594). +student(s2595). +student(s2596). +student(s2597). +student(s2598). +student(s2599). +student(s2600). +student(s2601). +student(s2602). +student(s2603). +student(s2604). +student(s2605). +student(s2606). +student(s2607). +student(s2608). +student(s2609). +student(s2610). +student(s2611). +student(s2612). +student(s2613). +student(s2614). +student(s2615). +student(s2616). +student(s2617). +student(s2618). +student(s2619). +student(s2620). +student(s2621). +student(s2622). +student(s2623). +student(s2624). +student(s2625). +student(s2626). +student(s2627). +student(s2628). +student(s2629). +student(s2630). +student(s2631). +student(s2632). +student(s2633). +student(s2634). +student(s2635). +student(s2636). +student(s2637). +student(s2638). +student(s2639). +student(s2640). +student(s2641). +student(s2642). +student(s2643). +student(s2644). +student(s2645). +student(s2646). +student(s2647). +student(s2648). +student(s2649). +student(s2650). +student(s2651). +student(s2652). +student(s2653). +student(s2654). +student(s2655). +student(s2656). +student(s2657). +student(s2658). +student(s2659). +student(s2660). +student(s2661). +student(s2662). +student(s2663). +student(s2664). +student(s2665). +student(s2666). +student(s2667). +student(s2668). +student(s2669). +student(s2670). +student(s2671). +student(s2672). +student(s2673). +student(s2674). +student(s2675). +student(s2676). +student(s2677). +student(s2678). +student(s2679). +student(s2680). +student(s2681). +student(s2682). +student(s2683). +student(s2684). +student(s2685). +student(s2686). +student(s2687). +student(s2688). +student(s2689). +student(s2690). +student(s2691). +student(s2692). +student(s2693). +student(s2694). +student(s2695). +student(s2696). +student(s2697). +student(s2698). +student(s2699). +student(s2700). +student(s2701). +student(s2702). +student(s2703). +student(s2704). +student(s2705). +student(s2706). +student(s2707). +student(s2708). +student(s2709). +student(s2710). +student(s2711). +student(s2712). +student(s2713). +student(s2714). +student(s2715). +student(s2716). +student(s2717). +student(s2718). +student(s2719). +student(s2720). +student(s2721). +student(s2722). +student(s2723). +student(s2724). +student(s2725). +student(s2726). +student(s2727). +student(s2728). +student(s2729). +student(s2730). +student(s2731). +student(s2732). +student(s2733). +student(s2734). +student(s2735). +student(s2736). +student(s2737). +student(s2738). +student(s2739). +student(s2740). +student(s2741). +student(s2742). +student(s2743). +student(s2744). +student(s2745). +student(s2746). +student(s2747). +student(s2748). +student(s2749). +student(s2750). +student(s2751). +student(s2752). +student(s2753). +student(s2754). +student(s2755). +student(s2756). +student(s2757). +student(s2758). +student(s2759). +student(s2760). +student(s2761). +student(s2762). +student(s2763). +student(s2764). +student(s2765). +student(s2766). +student(s2767). +student(s2768). +student(s2769). +student(s2770). +student(s2771). +student(s2772). +student(s2773). +student(s2774). +student(s2775). +student(s2776). +student(s2777). +student(s2778). +student(s2779). +student(s2780). +student(s2781). +student(s2782). +student(s2783). +student(s2784). +student(s2785). +student(s2786). +student(s2787). +student(s2788). +student(s2789). +student(s2790). +student(s2791). +student(s2792). +student(s2793). +student(s2794). +student(s2795). +student(s2796). +student(s2797). +student(s2798). +student(s2799). +student(s2800). +student(s2801). +student(s2802). +student(s2803). +student(s2804). +student(s2805). +student(s2806). +student(s2807). +student(s2808). +student(s2809). +student(s2810). +student(s2811). +student(s2812). +student(s2813). +student(s2814). +student(s2815). +student(s2816). +student(s2817). +student(s2818). +student(s2819). +student(s2820). +student(s2821). +student(s2822). +student(s2823). +student(s2824). +student(s2825). +student(s2826). +student(s2827). +student(s2828). +student(s2829). +student(s2830). +student(s2831). +student(s2832). +student(s2833). +student(s2834). +student(s2835). +student(s2836). +student(s2837). +student(s2838). +student(s2839). +student(s2840). +student(s2841). +student(s2842). +student(s2843). +student(s2844). +student(s2845). +student(s2846). +student(s2847). +student(s2848). +student(s2849). +student(s2850). +student(s2851). +student(s2852). +student(s2853). +student(s2854). +student(s2855). +student(s2856). +student(s2857). +student(s2858). +student(s2859). +student(s2860). +student(s2861). +student(s2862). +student(s2863). +student(s2864). +student(s2865). +student(s2866). +student(s2867). +student(s2868). +student(s2869). +student(s2870). +student(s2871). +student(s2872). +student(s2873). +student(s2874). +student(s2875). +student(s2876). +student(s2877). +student(s2878). +student(s2879). +student(s2880). +student(s2881). +student(s2882). +student(s2883). +student(s2884). +student(s2885). +student(s2886). +student(s2887). +student(s2888). +student(s2889). +student(s2890). +student(s2891). +student(s2892). +student(s2893). +student(s2894). +student(s2895). +student(s2896). +student(s2897). +student(s2898). +student(s2899). +student(s2900). +student(s2901). +student(s2902). +student(s2903). +student(s2904). +student(s2905). +student(s2906). +student(s2907). +student(s2908). +student(s2909). +student(s2910). +student(s2911). +student(s2912). +student(s2913). +student(s2914). +student(s2915). +student(s2916). +student(s2917). +student(s2918). +student(s2919). +student(s2920). +student(s2921). +student(s2922). +student(s2923). +student(s2924). +student(s2925). +student(s2926). +student(s2927). +student(s2928). +student(s2929). +student(s2930). +student(s2931). +student(s2932). +student(s2933). +student(s2934). +student(s2935). +student(s2936). +student(s2937). +student(s2938). +student(s2939). +student(s2940). +student(s2941). +student(s2942). +student(s2943). +student(s2944). +student(s2945). +student(s2946). +student(s2947). +student(s2948). +student(s2949). +student(s2950). +student(s2951). +student(s2952). +student(s2953). +student(s2954). +student(s2955). +student(s2956). +student(s2957). +student(s2958). +student(s2959). +student(s2960). +student(s2961). +student(s2962). +student(s2963). +student(s2964). +student(s2965). +student(s2966). +student(s2967). +student(s2968). +student(s2969). +student(s2970). +student(s2971). +student(s2972). +student(s2973). +student(s2974). +student(s2975). +student(s2976). +student(s2977). +student(s2978). +student(s2979). +student(s2980). +student(s2981). +student(s2982). +student(s2983). +student(s2984). +student(s2985). +student(s2986). +student(s2987). +student(s2988). +student(s2989). +student(s2990). +student(s2991). +student(s2992). +student(s2993). +student(s2994). +student(s2995). +student(s2996). +student(s2997). +student(s2998). +student(s2999). +student(s3000). +student(s3001). +student(s3002). +student(s3003). +student(s3004). +student(s3005). +student(s3006). +student(s3007). +student(s3008). +student(s3009). +student(s3010). +student(s3011). +student(s3012). +student(s3013). +student(s3014). +student(s3015). +student(s3016). +student(s3017). +student(s3018). +student(s3019). +student(s3020). +student(s3021). +student(s3022). +student(s3023). +student(s3024). +student(s3025). +student(s3026). +student(s3027). +student(s3028). +student(s3029). +student(s3030). +student(s3031). +student(s3032). +student(s3033). +student(s3034). +student(s3035). +student(s3036). +student(s3037). +student(s3038). +student(s3039). +student(s3040). +student(s3041). +student(s3042). +student(s3043). +student(s3044). +student(s3045). +student(s3046). +student(s3047). +student(s3048). +student(s3049). +student(s3050). +student(s3051). +student(s3052). +student(s3053). +student(s3054). +student(s3055). +student(s3056). +student(s3057). +student(s3058). +student(s3059). +student(s3060). +student(s3061). +student(s3062). +student(s3063). +student(s3064). +student(s3065). +student(s3066). +student(s3067). +student(s3068). +student(s3069). +student(s3070). +student(s3071). +student(s3072). +student(s3073). +student(s3074). +student(s3075). +student(s3076). +student(s3077). +student(s3078). +student(s3079). +student(s3080). +student(s3081). +student(s3082). +student(s3083). +student(s3084). +student(s3085). +student(s3086). +student(s3087). +student(s3088). +student(s3089). +student(s3090). +student(s3091). +student(s3092). +student(s3093). +student(s3094). +student(s3095). +student(s3096). +student(s3097). +student(s3098). +student(s3099). +student(s3100). +student(s3101). +student(s3102). +student(s3103). +student(s3104). +student(s3105). +student(s3106). +student(s3107). +student(s3108). +student(s3109). +student(s3110). +student(s3111). +student(s3112). +student(s3113). +student(s3114). +student(s3115). +student(s3116). +student(s3117). +student(s3118). +student(s3119). +student(s3120). +student(s3121). +student(s3122). +student(s3123). +student(s3124). +student(s3125). +student(s3126). +student(s3127). +student(s3128). +student(s3129). +student(s3130). +student(s3131). +student(s3132). +student(s3133). +student(s3134). +student(s3135). +student(s3136). +student(s3137). +student(s3138). +student(s3139). +student(s3140). +student(s3141). +student(s3142). +student(s3143). +student(s3144). +student(s3145). +student(s3146). +student(s3147). +student(s3148). +student(s3149). +student(s3150). +student(s3151). +student(s3152). +student(s3153). +student(s3154). +student(s3155). +student(s3156). +student(s3157). +student(s3158). +student(s3159). +student(s3160). +student(s3161). +student(s3162). +student(s3163). +student(s3164). +student(s3165). +student(s3166). +student(s3167). +student(s3168). +student(s3169). +student(s3170). +student(s3171). +student(s3172). +student(s3173). +student(s3174). +student(s3175). +student(s3176). +student(s3177). +student(s3178). +student(s3179). +student(s3180). +student(s3181). +student(s3182). +student(s3183). +student(s3184). +student(s3185). +student(s3186). +student(s3187). +student(s3188). +student(s3189). +student(s3190). +student(s3191). +student(s3192). +student(s3193). +student(s3194). +student(s3195). +student(s3196). +student(s3197). +student(s3198). +student(s3199). +student(s3200). +student(s3201). +student(s3202). +student(s3203). +student(s3204). +student(s3205). +student(s3206). +student(s3207). +student(s3208). +student(s3209). +student(s3210). +student(s3211). +student(s3212). +student(s3213). +student(s3214). +student(s3215). +student(s3216). +student(s3217). +student(s3218). +student(s3219). +student(s3220). +student(s3221). +student(s3222). +student(s3223). +student(s3224). +student(s3225). +student(s3226). +student(s3227). +student(s3228). +student(s3229). +student(s3230). +student(s3231). +student(s3232). +student(s3233). +student(s3234). +student(s3235). +student(s3236). +student(s3237). +student(s3238). +student(s3239). +student(s3240). +student(s3241). +student(s3242). +student(s3243). +student(s3244). +student(s3245). +student(s3246). +student(s3247). +student(s3248). +student(s3249). +student(s3250). +student(s3251). +student(s3252). +student(s3253). +student(s3254). +student(s3255). +student(s3256). +student(s3257). +student(s3258). +student(s3259). +student(s3260). +student(s3261). +student(s3262). +student(s3263). +student(s3264). +student(s3265). +student(s3266). +student(s3267). +student(s3268). +student(s3269). +student(s3270). +student(s3271). +student(s3272). +student(s3273). +student(s3274). +student(s3275). +student(s3276). +student(s3277). +student(s3278). +student(s3279). +student(s3280). +student(s3281). +student(s3282). +student(s3283). +student(s3284). +student(s3285). +student(s3286). +student(s3287). +student(s3288). +student(s3289). +student(s3290). +student(s3291). +student(s3292). +student(s3293). +student(s3294). +student(s3295). +student(s3296). +student(s3297). +student(s3298). +student(s3299). +student(s3300). +student(s3301). +student(s3302). +student(s3303). +student(s3304). +student(s3305). +student(s3306). +student(s3307). +student(s3308). +student(s3309). +student(s3310). +student(s3311). +student(s3312). +student(s3313). +student(s3314). +student(s3315). +student(s3316). +student(s3317). +student(s3318). +student(s3319). +student(s3320). +student(s3321). +student(s3322). +student(s3323). +student(s3324). +student(s3325). +student(s3326). +student(s3327). +student(s3328). +student(s3329). +student(s3330). +student(s3331). +student(s3332). +student(s3333). +student(s3334). +student(s3335). +student(s3336). +student(s3337). +student(s3338). +student(s3339). +student(s3340). +student(s3341). +student(s3342). +student(s3343). +student(s3344). +student(s3345). +student(s3346). +student(s3347). +student(s3348). +student(s3349). +student(s3350). +student(s3351). +student(s3352). +student(s3353). +student(s3354). +student(s3355). +student(s3356). +student(s3357). +student(s3358). +student(s3359). +student(s3360). +student(s3361). +student(s3362). +student(s3363). +student(s3364). +student(s3365). +student(s3366). +student(s3367). +student(s3368). +student(s3369). +student(s3370). +student(s3371). +student(s3372). +student(s3373). +student(s3374). +student(s3375). +student(s3376). +student(s3377). +student(s3378). +student(s3379). +student(s3380). +student(s3381). +student(s3382). +student(s3383). +student(s3384). +student(s3385). +student(s3386). +student(s3387). +student(s3388). +student(s3389). +student(s3390). +student(s3391). +student(s3392). +student(s3393). +student(s3394). +student(s3395). +student(s3396). +student(s3397). +student(s3398). +student(s3399). +student(s3400). +student(s3401). +student(s3402). +student(s3403). +student(s3404). +student(s3405). +student(s3406). +student(s3407). +student(s3408). +student(s3409). +student(s3410). +student(s3411). +student(s3412). +student(s3413). +student(s3414). +student(s3415). +student(s3416). +student(s3417). +student(s3418). +student(s3419). +student(s3420). +student(s3421). +student(s3422). +student(s3423). +student(s3424). +student(s3425). +student(s3426). +student(s3427). +student(s3428). +student(s3429). +student(s3430). +student(s3431). +student(s3432). +student(s3433). +student(s3434). +student(s3435). +student(s3436). +student(s3437). +student(s3438). +student(s3439). +student(s3440). +student(s3441). +student(s3442). +student(s3443). +student(s3444). +student(s3445). +student(s3446). +student(s3447). +student(s3448). +student(s3449). +student(s3450). +student(s3451). +student(s3452). +student(s3453). +student(s3454). +student(s3455). +student(s3456). +student(s3457). +student(s3458). +student(s3459). +student(s3460). +student(s3461). +student(s3462). +student(s3463). +student(s3464). +student(s3465). +student(s3466). +student(s3467). +student(s3468). +student(s3469). +student(s3470). +student(s3471). +student(s3472). +student(s3473). +student(s3474). +student(s3475). +student(s3476). +student(s3477). +student(s3478). +student(s3479). +student(s3480). +student(s3481). +student(s3482). +student(s3483). +student(s3484). +student(s3485). +student(s3486). +student(s3487). +student(s3488). +student(s3489). +student(s3490). +student(s3491). +student(s3492). +student(s3493). +student(s3494). +student(s3495). +student(s3496). +student(s3497). +student(s3498). +student(s3499). +student(s3500). +student(s3501). +student(s3502). +student(s3503). +student(s3504). +student(s3505). +student(s3506). +student(s3507). +student(s3508). +student(s3509). +student(s3510). +student(s3511). +student(s3512). +student(s3513). +student(s3514). +student(s3515). +student(s3516). +student(s3517). +student(s3518). +student(s3519). +student(s3520). +student(s3521). +student(s3522). +student(s3523). +student(s3524). +student(s3525). +student(s3526). +student(s3527). +student(s3528). +student(s3529). +student(s3530). +student(s3531). +student(s3532). +student(s3533). +student(s3534). +student(s3535). +student(s3536). +student(s3537). +student(s3538). +student(s3539). +student(s3540). +student(s3541). +student(s3542). +student(s3543). +student(s3544). +student(s3545). +student(s3546). +student(s3547). +student(s3548). +student(s3549). +student(s3550). +student(s3551). +student(s3552). +student(s3553). +student(s3554). +student(s3555). +student(s3556). +student(s3557). +student(s3558). +student(s3559). +student(s3560). +student(s3561). +student(s3562). +student(s3563). +student(s3564). +student(s3565). +student(s3566). +student(s3567). +student(s3568). +student(s3569). +student(s3570). +student(s3571). +student(s3572). +student(s3573). +student(s3574). +student(s3575). +student(s3576). +student(s3577). +student(s3578). +student(s3579). +student(s3580). +student(s3581). +student(s3582). +student(s3583). +student(s3584). +student(s3585). +student(s3586). +student(s3587). +student(s3588). +student(s3589). +student(s3590). +student(s3591). +student(s3592). +student(s3593). +student(s3594). +student(s3595). +student(s3596). +student(s3597). +student(s3598). +student(s3599). +student(s3600). +student(s3601). +student(s3602). +student(s3603). +student(s3604). +student(s3605). +student(s3606). +student(s3607). +student(s3608). +student(s3609). +student(s3610). +student(s3611). +student(s3612). +student(s3613). +student(s3614). +student(s3615). +student(s3616). +student(s3617). +student(s3618). +student(s3619). +student(s3620). +student(s3621). +student(s3622). +student(s3623). +student(s3624). +student(s3625). +student(s3626). +student(s3627). +student(s3628). +student(s3629). +student(s3630). +student(s3631). +student(s3632). +student(s3633). +student(s3634). +student(s3635). +student(s3636). +student(s3637). +student(s3638). +student(s3639). +student(s3640). +student(s3641). +student(s3642). +student(s3643). +student(s3644). +student(s3645). +student(s3646). +student(s3647). +student(s3648). +student(s3649). +student(s3650). +student(s3651). +student(s3652). +student(s3653). +student(s3654). +student(s3655). +student(s3656). +student(s3657). +student(s3658). +student(s3659). +student(s3660). +student(s3661). +student(s3662). +student(s3663). +student(s3664). +student(s3665). +student(s3666). +student(s3667). +student(s3668). +student(s3669). +student(s3670). +student(s3671). +student(s3672). +student(s3673). +student(s3674). +student(s3675). +student(s3676). +student(s3677). +student(s3678). +student(s3679). +student(s3680). +student(s3681). +student(s3682). +student(s3683). +student(s3684). +student(s3685). +student(s3686). +student(s3687). +student(s3688). +student(s3689). +student(s3690). +student(s3691). +student(s3692). +student(s3693). +student(s3694). +student(s3695). +student(s3696). +student(s3697). +student(s3698). +student(s3699). +student(s3700). +student(s3701). +student(s3702). +student(s3703). +student(s3704). +student(s3705). +student(s3706). +student(s3707). +student(s3708). +student(s3709). +student(s3710). +student(s3711). +student(s3712). +student(s3713). +student(s3714). +student(s3715). +student(s3716). +student(s3717). +student(s3718). +student(s3719). +student(s3720). +student(s3721). +student(s3722). +student(s3723). +student(s3724). +student(s3725). +student(s3726). +student(s3727). +student(s3728). +student(s3729). +student(s3730). +student(s3731). +student(s3732). +student(s3733). +student(s3734). +student(s3735). +student(s3736). +student(s3737). +student(s3738). +student(s3739). +student(s3740). +student(s3741). +student(s3742). +student(s3743). +student(s3744). +student(s3745). +student(s3746). +student(s3747). +student(s3748). +student(s3749). +student(s3750). +student(s3751). +student(s3752). +student(s3753). +student(s3754). +student(s3755). +student(s3756). +student(s3757). +student(s3758). +student(s3759). +student(s3760). +student(s3761). +student(s3762). +student(s3763). +student(s3764). +student(s3765). +student(s3766). +student(s3767). +student(s3768). +student(s3769). +student(s3770). +student(s3771). +student(s3772). +student(s3773). +student(s3774). +student(s3775). +student(s3776). +student(s3777). +student(s3778). +student(s3779). +student(s3780). +student(s3781). +student(s3782). +student(s3783). +student(s3784). +student(s3785). +student(s3786). +student(s3787). +student(s3788). +student(s3789). +student(s3790). +student(s3791). +student(s3792). +student(s3793). +student(s3794). +student(s3795). +student(s3796). +student(s3797). +student(s3798). +student(s3799). +student(s3800). +student(s3801). +student(s3802). +student(s3803). +student(s3804). +student(s3805). +student(s3806). +student(s3807). +student(s3808). +student(s3809). +student(s3810). +student(s3811). +student(s3812). +student(s3813). +student(s3814). +student(s3815). +student(s3816). +student(s3817). +student(s3818). +student(s3819). +student(s3820). +student(s3821). +student(s3822). +student(s3823). +student(s3824). +student(s3825). +student(s3826). +student(s3827). +student(s3828). +student(s3829). +student(s3830). +student(s3831). +student(s3832). +student(s3833). +student(s3834). +student(s3835). +student(s3836). +student(s3837). +student(s3838). +student(s3839). +student(s3840). +student(s3841). +student(s3842). +student(s3843). +student(s3844). +student(s3845). +student(s3846). +student(s3847). +student(s3848). +student(s3849). +student(s3850). +student(s3851). +student(s3852). +student(s3853). +student(s3854). +student(s3855). +student(s3856). +student(s3857). +student(s3858). +student(s3859). +student(s3860). +student(s3861). +student(s3862). +student(s3863). +student(s3864). +student(s3865). +student(s3866). +student(s3867). +student(s3868). +student(s3869). +student(s3870). +student(s3871). +student(s3872). +student(s3873). +student(s3874). +student(s3875). +student(s3876). +student(s3877). +student(s3878). +student(s3879). +student(s3880). +student(s3881). +student(s3882). +student(s3883). +student(s3884). +student(s3885). +student(s3886). +student(s3887). +student(s3888). +student(s3889). +student(s3890). +student(s3891). +student(s3892). +student(s3893). +student(s3894). +student(s3895). +student(s3896). +student(s3897). +student(s3898). +student(s3899). +student(s3900). +student(s3901). +student(s3902). +student(s3903). +student(s3904). +student(s3905). +student(s3906). +student(s3907). +student(s3908). +student(s3909). +student(s3910). +student(s3911). +student(s3912). +student(s3913). +student(s3914). +student(s3915). +student(s3916). +student(s3917). +student(s3918). +student(s3919). +student(s3920). +student(s3921). +student(s3922). +student(s3923). +student(s3924). +student(s3925). +student(s3926). +student(s3927). +student(s3928). +student(s3929). +student(s3930). +student(s3931). +student(s3932). +student(s3933). +student(s3934). +student(s3935). +student(s3936). +student(s3937). +student(s3938). +student(s3939). +student(s3940). +student(s3941). +student(s3942). +student(s3943). +student(s3944). +student(s3945). +student(s3946). +student(s3947). +student(s3948). +student(s3949). +student(s3950). +student(s3951). +student(s3952). +student(s3953). +student(s3954). +student(s3955). +student(s3956). +student(s3957). +student(s3958). +student(s3959). +student(s3960). +student(s3961). +student(s3962). +student(s3963). +student(s3964). +student(s3965). +student(s3966). +student(s3967). +student(s3968). +student(s3969). +student(s3970). +student(s3971). +student(s3972). +student(s3973). +student(s3974). +student(s3975). +student(s3976). +student(s3977). +student(s3978). +student(s3979). +student(s3980). +student(s3981). +student(s3982). +student(s3983). +student(s3984). +student(s3985). +student(s3986). +student(s3987). +student(s3988). +student(s3989). +student(s3990). +student(s3991). +student(s3992). +student(s3993). +student(s3994). +student(s3995). +student(s3996). +student(s3997). +student(s3998). +student(s3999). +student(s4000). +student(s4001). +student(s4002). +student(s4003). +student(s4004). +student(s4005). +student(s4006). +student(s4007). +student(s4008). +student(s4009). +student(s4010). +student(s4011). +student(s4012). +student(s4013). +student(s4014). +student(s4015). +student(s4016). +student(s4017). +student(s4018). +student(s4019). +student(s4020). +student(s4021). +student(s4022). +student(s4023). +student(s4024). +student(s4025). +student(s4026). +student(s4027). +student(s4028). +student(s4029). +student(s4030). +student(s4031). +student(s4032). +student(s4033). +student(s4034). +student(s4035). +student(s4036). +student(s4037). +student(s4038). +student(s4039). +student(s4040). +student(s4041). +student(s4042). +student(s4043). +student(s4044). +student(s4045). +student(s4046). +student(s4047). +student(s4048). +student(s4049). +student(s4050). +student(s4051). +student(s4052). +student(s4053). +student(s4054). +student(s4055). +student(s4056). +student(s4057). +student(s4058). +student(s4059). +student(s4060). +student(s4061). +student(s4062). +student(s4063). +student(s4064). +student(s4065). +student(s4066). +student(s4067). +student(s4068). +student(s4069). +student(s4070). +student(s4071). +student(s4072). +student(s4073). +student(s4074). +student(s4075). +student(s4076). +student(s4077). +student(s4078). +student(s4079). +student(s4080). +student(s4081). +student(s4082). +student(s4083). +student(s4084). +student(s4085). +student(s4086). +student(s4087). +student(s4088). +student(s4089). +student(s4090). +student(s4091). +student(s4092). +student(s4093). +student(s4094). +student(s4095). + + +registration(r0,c166,s0). +registration(r1,c11,s0). +registration(r2,c213,s0). +registration(r3,c188,s1). +registration(r4,c4,s1). +registration(r5,c191,s1). +registration(r6,c3,s1). +registration(r7,c55,s2). +registration(r8,c229,s2). +registration(r9,c158,s2). +registration(r10,c161,s2). +registration(r11,c67,s3). +registration(r12,c187,s3). +registration(r13,c121,s3). +registration(r14,c52,s4). +registration(r15,c160,s4). +registration(r16,c187,s4). +registration(r17,c144,s5). +registration(r18,c167,s5). +registration(r19,c224,s5). +registration(r20,c235,s6). +registration(r21,c126,s6). +registration(r22,c73,s6). +registration(r23,c79,s7). +registration(r24,c68,s7). +registration(r25,c100,s7). +registration(r26,c154,s8). +registration(r27,c55,s8). +registration(r28,c143,s8). +registration(r29,c195,s9). +registration(r30,c224,s9). +registration(r31,c147,s9). +registration(r32,c89,s10). +registration(r33,c113,s10). +registration(r34,c101,s10). +registration(r35,c66,s10). +registration(r36,c165,s11). +registration(r37,c235,s11). +registration(r38,c157,s11). +registration(r39,c137,s12). +registration(r40,c205,s12). +registration(r41,c130,s12). +registration(r42,c8,s12). +registration(r43,c83,s13). +registration(r44,c108,s13). +registration(r45,c36,s13). +registration(r46,c93,s13). +registration(r47,c211,s14). +registration(r48,c163,s14). +registration(r49,c54,s14). +registration(r50,c203,s15). +registration(r51,c211,s15). +registration(r52,c73,s15). +registration(r53,c67,s15). +registration(r54,c57,s16). +registration(r55,c136,s16). +registration(r56,c110,s16). +registration(r57,c12,s17). +registration(r58,c45,s17). +registration(r59,c172,s17). +registration(r60,c46,s18). +registration(r61,c164,s18). +registration(r62,c3,s18). +registration(r63,c247,s18). +registration(r64,c37,s19). +registration(r65,c60,s19). +registration(r66,c118,s19). +registration(r67,c25,s19). +registration(r68,c185,s20). +registration(r69,c165,s20). +registration(r70,c157,s20). +registration(r71,c232,s21). +registration(r72,c169,s21). +registration(r73,c188,s21). +registration(r74,c68,s22). +registration(r75,c5,s22). +registration(r76,c194,s22). +registration(r77,c238,s22). +registration(r78,c99,s23). +registration(r79,c168,s23). +registration(r80,c233,s23). +registration(r81,c236,s24). +registration(r82,c146,s24). +registration(r83,c67,s24). +registration(r84,c128,s25). +registration(r85,c209,s25). +registration(r86,c59,s25). +registration(r87,c245,s26). +registration(r88,c52,s26). +registration(r89,c137,s26). +registration(r90,c114,s27). +registration(r91,c36,s27). +registration(r92,c107,s27). +registration(r93,c7,s27). +registration(r94,c16,s28). +registration(r95,c201,s28). +registration(r96,c104,s28). +registration(r97,c183,s28). +registration(r98,c202,s29). +registration(r99,c159,s29). +registration(r100,c92,s29). +registration(r101,c140,s29). +registration(r102,c92,s30). +registration(r103,c233,s30). +registration(r104,c169,s30). +registration(r105,c229,s31). +registration(r106,c106,s31). +registration(r107,c165,s31). +registration(r108,c48,s32). +registration(r109,c85,s32). +registration(r110,c78,s32). +registration(r111,c185,s33). +registration(r112,c172,s33). +registration(r113,c127,s33). +registration(r114,c73,s34). +registration(r115,c210,s34). +registration(r116,c224,s34). +registration(r117,c156,s34). +registration(r118,c161,s35). +registration(r119,c250,s35). +registration(r120,c193,s35). +registration(r121,c234,s35). +registration(r122,c23,s35). +registration(r123,c148,s36). +registration(r124,c250,s36). +registration(r125,c209,s36). +registration(r126,c120,s37). +registration(r127,c83,s37). +registration(r128,c5,s37). +registration(r129,c84,s38). +registration(r130,c74,s38). +registration(r131,c33,s38). +registration(r132,c248,s38). +registration(r133,c120,s39). +registration(r134,c181,s39). +registration(r135,c236,s39). +registration(r136,c237,s40). +registration(r137,c230,s40). +registration(r138,c63,s40). +registration(r139,c2,s41). +registration(r140,c190,s41). +registration(r141,c204,s41). +registration(r142,c214,s41). +registration(r143,c27,s42). +registration(r144,c169,s42). +registration(r145,c218,s42). +registration(r146,c46,s42). +registration(r147,c134,s43). +registration(r148,c202,s43). +registration(r149,c215,s43). +registration(r150,c249,s43). +registration(r151,c233,s44). +registration(r152,c13,s44). +registration(r153,c155,s44). +registration(r154,c136,s45). +registration(r155,c171,s45). +registration(r156,c86,s45). +registration(r157,c151,s46). +registration(r158,c5,s46). +registration(r159,c116,s46). +registration(r160,c65,s47). +registration(r161,c186,s47). +registration(r162,c154,s47). +registration(r163,c67,s48). +registration(r164,c124,s48). +registration(r165,c87,s48). +registration(r166,c222,s49). +registration(r167,c46,s49). +registration(r168,c129,s49). +registration(r169,c123,s50). +registration(r170,c162,s50). +registration(r171,c80,s50). +registration(r172,c3,s50). +registration(r173,c160,s50). +registration(r174,c175,s51). +registration(r175,c106,s51). +registration(r176,c21,s51). +registration(r177,c28,s51). +registration(r178,c182,s52). +registration(r179,c155,s52). +registration(r180,c223,s52). +registration(r181,c122,s53). +registration(r182,c154,s53). +registration(r183,c44,s53). +registration(r184,c132,s53). +registration(r185,c33,s54). +registration(r186,c192,s54). +registration(r187,c98,s54). +registration(r188,c27,s55). +registration(r189,c148,s55). +registration(r190,c190,s55). +registration(r191,c212,s56). +registration(r192,c192,s56). +registration(r193,c248,s56). +registration(r194,c99,s57). +registration(r195,c138,s57). +registration(r196,c178,s57). +registration(r197,c104,s58). +registration(r198,c1,s58). +registration(r199,c134,s58). +registration(r200,c255,s59). +registration(r201,c249,s59). +registration(r202,c131,s59). +registration(r203,c7,s59). +registration(r204,c223,s60). +registration(r205,c207,s60). +registration(r206,c105,s60). +registration(r207,c18,s60). +registration(r208,c195,s61). +registration(r209,c208,s61). +registration(r210,c65,s61). +registration(r211,c3,s62). +registration(r212,c161,s62). +registration(r213,c26,s62). +registration(r214,c165,s62). +registration(r215,c37,s63). +registration(r216,c105,s63). +registration(r217,c74,s63). +registration(r218,c207,s64). +registration(r219,c238,s64). +registration(r220,c192,s64). +registration(r221,c70,s65). +registration(r222,c141,s65). +registration(r223,c248,s65). +registration(r224,c201,s66). +registration(r225,c183,s66). +registration(r226,c154,s66). +registration(r227,c94,s67). +registration(r228,c172,s67). +registration(r229,c127,s67). +registration(r230,c80,s67). +registration(r231,c168,s68). +registration(r232,c107,s68). +registration(r233,c246,s68). +registration(r234,c27,s68). +registration(r235,c21,s69). +registration(r236,c90,s69). +registration(r237,c171,s69). +registration(r238,c153,s69). +registration(r239,c65,s70). +registration(r240,c249,s70). +registration(r241,c129,s70). +registration(r242,c122,s71). +registration(r243,c214,s71). +registration(r244,c242,s71). +registration(r245,c141,s72). +registration(r246,c31,s72). +registration(r247,c203,s72). +registration(r248,c74,s73). +registration(r249,c243,s73). +registration(r250,c29,s73). +registration(r251,c137,s74). +registration(r252,c196,s74). +registration(r253,c72,s74). +registration(r254,c94,s75). +registration(r255,c242,s75). +registration(r256,c138,s75). +registration(r257,c35,s75). +registration(r258,c32,s76). +registration(r259,c21,s76). +registration(r260,c166,s76). +registration(r261,c32,s77). +registration(r262,c127,s77). +registration(r263,c142,s77). +registration(r264,c26,s77). +registration(r265,c131,s78). +registration(r266,c217,s78). +registration(r267,c7,s78). +registration(r268,c251,s78). +registration(r269,c109,s79). +registration(r270,c242,s79). +registration(r271,c151,s79). +registration(r272,c224,s80). +registration(r273,c144,s80). +registration(r274,c150,s80). +registration(r275,c33,s81). +registration(r276,c29,s81). +registration(r277,c160,s81). +registration(r278,c181,s82). +registration(r279,c235,s82). +registration(r280,c230,s82). +registration(r281,c101,s82). +registration(r282,c222,s83). +registration(r283,c110,s83). +registration(r284,c117,s83). +registration(r285,c78,s84). +registration(r286,c0,s84). +registration(r287,c66,s84). +registration(r288,c176,s85). +registration(r289,c100,s85). +registration(r290,c146,s85). +registration(r291,c114,s85). +registration(r292,c56,s86). +registration(r293,c178,s86). +registration(r294,c179,s86). +registration(r295,c208,s87). +registration(r296,c91,s87). +registration(r297,c24,s87). +registration(r298,c16,s87). +registration(r299,c246,s87). +registration(r300,c98,s88). +registration(r301,c15,s88). +registration(r302,c93,s88). +registration(r303,c210,s89). +registration(r304,c57,s89). +registration(r305,c113,s89). +registration(r306,c58,s89). +registration(r307,c147,s90). +registration(r308,c53,s90). +registration(r309,c100,s90). +registration(r310,c11,s91). +registration(r311,c21,s91). +registration(r312,c61,s91). +registration(r313,c238,s92). +registration(r314,c255,s92). +registration(r315,c152,s92). +registration(r316,c178,s93). +registration(r317,c205,s93). +registration(r318,c107,s93). +registration(r319,c206,s94). +registration(r320,c196,s94). +registration(r321,c33,s94). +registration(r322,c68,s94). +registration(r323,c72,s95). +registration(r324,c182,s95). +registration(r325,c20,s95). +registration(r326,c168,s96). +registration(r327,c185,s96). +registration(r328,c206,s96). +registration(r329,c217,s97). +registration(r330,c181,s97). +registration(r331,c188,s97). +registration(r332,c122,s97). +registration(r333,c28,s98). +registration(r334,c21,s98). +registration(r335,c106,s98). +registration(r336,c55,s99). +registration(r337,c228,s99). +registration(r338,c125,s99). +registration(r339,c67,s100). +registration(r340,c28,s100). +registration(r341,c194,s100). +registration(r342,c10,s100). +registration(r343,c61,s101). +registration(r344,c37,s101). +registration(r345,c142,s101). +registration(r346,c70,s102). +registration(r347,c117,s102). +registration(r348,c112,s102). +registration(r349,c38,s103). +registration(r350,c133,s103). +registration(r351,c108,s103). +registration(r352,c138,s103). +registration(r353,c183,s104). +registration(r354,c153,s104). +registration(r355,c1,s104). +registration(r356,c229,s105). +registration(r357,c253,s105). +registration(r358,c202,s105). +registration(r359,c233,s106). +registration(r360,c89,s106). +registration(r361,c200,s106). +registration(r362,c6,s107). +registration(r363,c33,s107). +registration(r364,c242,s107). +registration(r365,c56,s108). +registration(r366,c35,s108). +registration(r367,c97,s108). +registration(r368,c115,s108). +registration(r369,c133,s109). +registration(r370,c221,s109). +registration(r371,c40,s109). +registration(r372,c224,s110). +registration(r373,c78,s110). +registration(r374,c103,s110). +registration(r375,c76,s110). +registration(r376,c92,s111). +registration(r377,c236,s111). +registration(r378,c228,s111). +registration(r379,c63,s112). +registration(r380,c103,s112). +registration(r381,c207,s112). +registration(r382,c239,s113). +registration(r383,c149,s113). +registration(r384,c27,s113). +registration(r385,c63,s114). +registration(r386,c62,s114). +registration(r387,c206,s114). +registration(r388,c83,s115). +registration(r389,c143,s115). +registration(r390,c237,s115). +registration(r391,c246,s115). +registration(r392,c87,s116). +registration(r393,c94,s116). +registration(r394,c44,s116). +registration(r395,c137,s117). +registration(r396,c98,s117). +registration(r397,c145,s117). +registration(r398,c55,s117). +registration(r399,c142,s118). +registration(r400,c7,s118). +registration(r401,c115,s118). +registration(r402,c9,s119). +registration(r403,c25,s119). +registration(r404,c213,s119). +registration(r405,c19,s120). +registration(r406,c165,s120). +registration(r407,c9,s120). +registration(r408,c152,s121). +registration(r409,c197,s121). +registration(r410,c1,s121). +registration(r411,c88,s122). +registration(r412,c236,s122). +registration(r413,c191,s122). +registration(r414,c73,s123). +registration(r415,c50,s123). +registration(r416,c39,s123). +registration(r417,c247,s124). +registration(r418,c0,s124). +registration(r419,c114,s124). +registration(r420,c104,s125). +registration(r421,c116,s125). +registration(r422,c20,s125). +registration(r423,c108,s126). +registration(r424,c81,s126). +registration(r425,c240,s126). +registration(r426,c232,s126). +registration(r427,c14,s127). +registration(r428,c239,s127). +registration(r429,c233,s127). +registration(r430,c66,s128). +registration(r431,c137,s128). +registration(r432,c67,s128). +registration(r433,c32,s128). +registration(r434,c69,s129). +registration(r435,c72,s129). +registration(r436,c254,s129). +registration(r437,c254,s130). +registration(r438,c33,s130). +registration(r439,c169,s130). +registration(r440,c29,s131). +registration(r441,c15,s131). +registration(r442,c201,s131). +registration(r443,c26,s132). +registration(r444,c89,s132). +registration(r445,c242,s132). +registration(r446,c0,s133). +registration(r447,c53,s133). +registration(r448,c45,s133). +registration(r449,c112,s134). +registration(r450,c39,s134). +registration(r451,c249,s134). +registration(r452,c133,s135). +registration(r453,c199,s135). +registration(r454,c143,s135). +registration(r455,c206,s136). +registration(r456,c129,s136). +registration(r457,c153,s136). +registration(r458,c35,s137). +registration(r459,c151,s137). +registration(r460,c139,s137). +registration(r461,c8,s138). +registration(r462,c7,s138). +registration(r463,c90,s138). +registration(r464,c155,s139). +registration(r465,c251,s139). +registration(r466,c127,s139). +registration(r467,c55,s140). +registration(r468,c57,s140). +registration(r469,c193,s140). +registration(r470,c186,s140). +registration(r471,c182,s140). +registration(r472,c130,s141). +registration(r473,c152,s141). +registration(r474,c58,s141). +registration(r475,c189,s142). +registration(r476,c146,s142). +registration(r477,c224,s142). +registration(r478,c118,s143). +registration(r479,c198,s143). +registration(r480,c163,s143). +registration(r481,c171,s144). +registration(r482,c206,s144). +registration(r483,c199,s144). +registration(r484,c195,s145). +registration(r485,c120,s145). +registration(r486,c50,s145). +registration(r487,c107,s146). +registration(r488,c29,s146). +registration(r489,c226,s146). +registration(r490,c38,s146). +registration(r491,c168,s147). +registration(r492,c189,s147). +registration(r493,c213,s147). +registration(r494,c144,s147). +registration(r495,c53,s148). +registration(r496,c4,s148). +registration(r497,c204,s148). +registration(r498,c145,s149). +registration(r499,c144,s149). +registration(r500,c241,s149). +registration(r501,c191,s150). +registration(r502,c39,s150). +registration(r503,c53,s150). +registration(r504,c235,s150). +registration(r505,c92,s151). +registration(r506,c71,s151). +registration(r507,c96,s151). +registration(r508,c65,s152). +registration(r509,c237,s152). +registration(r510,c138,s152). +registration(r511,c72,s153). +registration(r512,c176,s153). +registration(r513,c55,s153). +registration(r514,c110,s154). +registration(r515,c114,s154). +registration(r516,c13,s154). +registration(r517,c159,s155). +registration(r518,c236,s155). +registration(r519,c220,s155). +registration(r520,c155,s155). +registration(r521,c38,s156). +registration(r522,c95,s156). +registration(r523,c198,s156). +registration(r524,c13,s156). +registration(r525,c90,s156). +registration(r526,c108,s157). +registration(r527,c233,s157). +registration(r528,c190,s157). +registration(r529,c73,s158). +registration(r530,c138,s158). +registration(r531,c108,s158). +registration(r532,c165,s159). +registration(r533,c254,s159). +registration(r534,c122,s159). +registration(r535,c110,s159). +registration(r536,c110,s160). +registration(r537,c91,s160). +registration(r538,c40,s160). +registration(r539,c40,s161). +registration(r540,c133,s161). +registration(r541,c214,s161). +registration(r542,c156,s162). +registration(r543,c96,s162). +registration(r544,c240,s162). +registration(r545,c93,s163). +registration(r546,c169,s163). +registration(r547,c120,s163). +registration(r548,c128,s163). +registration(r549,c149,s164). +registration(r550,c237,s164). +registration(r551,c82,s164). +registration(r552,c81,s165). +registration(r553,c74,s165). +registration(r554,c166,s165). +registration(r555,c20,s166). +registration(r556,c29,s166). +registration(r557,c253,s166). +registration(r558,c37,s167). +registration(r559,c244,s167). +registration(r560,c44,s167). +registration(r561,c200,s168). +registration(r562,c212,s168). +registration(r563,c199,s168). +registration(r564,c38,s169). +registration(r565,c50,s169). +registration(r566,c7,s169). +registration(r567,c178,s169). +registration(r568,c199,s170). +registration(r569,c158,s170). +registration(r570,c27,s170). +registration(r571,c108,s170). +registration(r572,c224,s171). +registration(r573,c214,s171). +registration(r574,c45,s171). +registration(r575,c74,s172). +registration(r576,c178,s172). +registration(r577,c91,s172). +registration(r578,c80,s173). +registration(r579,c204,s173). +registration(r580,c74,s173). +registration(r581,c149,s173). +registration(r582,c241,s173). +registration(r583,c29,s174). +registration(r584,c174,s174). +registration(r585,c23,s174). +registration(r586,c74,s175). +registration(r587,c0,s175). +registration(r588,c128,s175). +registration(r589,c160,s175). +registration(r590,c167,s176). +registration(r591,c208,s176). +registration(r592,c8,s176). +registration(r593,c54,s177). +registration(r594,c61,s177). +registration(r595,c148,s177). +registration(r596,c239,s178). +registration(r597,c32,s178). +registration(r598,c197,s178). +registration(r599,c17,s179). +registration(r600,c104,s179). +registration(r601,c130,s179). +registration(r602,c89,s179). +registration(r603,c223,s180). +registration(r604,c113,s180). +registration(r605,c237,s180). +registration(r606,c238,s181). +registration(r607,c20,s181). +registration(r608,c205,s181). +registration(r609,c117,s182). +registration(r610,c94,s182). +registration(r611,c184,s182). +registration(r612,c238,s182). +registration(r613,c59,s183). +registration(r614,c154,s183). +registration(r615,c111,s183). +registration(r616,c137,s183). +registration(r617,c240,s184). +registration(r618,c200,s184). +registration(r619,c123,s184). +registration(r620,c48,s184). +registration(r621,c50,s185). +registration(r622,c139,s185). +registration(r623,c157,s185). +registration(r624,c252,s185). +registration(r625,c167,s186). +registration(r626,c185,s186). +registration(r627,c119,s186). +registration(r628,c6,s187). +registration(r629,c108,s187). +registration(r630,c252,s187). +registration(r631,c249,s187). +registration(r632,c107,s188). +registration(r633,c19,s188). +registration(r634,c53,s188). +registration(r635,c131,s188). +registration(r636,c142,s189). +registration(r637,c17,s189). +registration(r638,c80,s189). +registration(r639,c82,s190). +registration(r640,c136,s190). +registration(r641,c141,s190). +registration(r642,c41,s190). +registration(r643,c151,s191). +registration(r644,c15,s191). +registration(r645,c180,s191). +registration(r646,c44,s192). +registration(r647,c251,s192). +registration(r648,c79,s192). +registration(r649,c74,s193). +registration(r650,c152,s193). +registration(r651,c140,s193). +registration(r652,c161,s193). +registration(r653,c122,s194). +registration(r654,c8,s194). +registration(r655,c35,s194). +registration(r656,c52,s195). +registration(r657,c41,s195). +registration(r658,c239,s195). +registration(r659,c119,s196). +registration(r660,c79,s196). +registration(r661,c0,s196). +registration(r662,c152,s197). +registration(r663,c154,s197). +registration(r664,c44,s197). +registration(r665,c90,s198). +registration(r666,c211,s198). +registration(r667,c176,s198). +registration(r668,c251,s199). +registration(r669,c37,s199). +registration(r670,c199,s199). +registration(r671,c103,s199). +registration(r672,c187,s200). +registration(r673,c50,s200). +registration(r674,c138,s200). +registration(r675,c191,s201). +registration(r676,c189,s201). +registration(r677,c183,s201). +registration(r678,c48,s202). +registration(r679,c209,s202). +registration(r680,c59,s202). +registration(r681,c211,s203). +registration(r682,c84,s203). +registration(r683,c120,s203). +registration(r684,c210,s204). +registration(r685,c125,s204). +registration(r686,c103,s204). +registration(r687,c100,s205). +registration(r688,c134,s205). +registration(r689,c128,s205). +registration(r690,c232,s206). +registration(r691,c95,s206). +registration(r692,c225,s206). +registration(r693,c172,s207). +registration(r694,c49,s207). +registration(r695,c180,s207). +registration(r696,c238,s208). +registration(r697,c149,s208). +registration(r698,c132,s208). +registration(r699,c80,s208). +registration(r700,c253,s209). +registration(r701,c165,s209). +registration(r702,c71,s209). +registration(r703,c26,s210). +registration(r704,c39,s210). +registration(r705,c198,s210). +registration(r706,c42,s211). +registration(r707,c0,s211). +registration(r708,c97,s211). +registration(r709,c72,s212). +registration(r710,c47,s212). +registration(r711,c146,s212). +registration(r712,c62,s212). +registration(r713,c237,s213). +registration(r714,c215,s213). +registration(r715,c162,s213). +registration(r716,c57,s214). +registration(r717,c38,s214). +registration(r718,c240,s214). +registration(r719,c237,s215). +registration(r720,c49,s215). +registration(r721,c63,s215). +registration(r722,c89,s216). +registration(r723,c188,s216). +registration(r724,c84,s216). +registration(r725,c127,s217). +registration(r726,c213,s217). +registration(r727,c251,s217). +registration(r728,c67,s218). +registration(r729,c127,s218). +registration(r730,c22,s218). +registration(r731,c85,s219). +registration(r732,c236,s219). +registration(r733,c124,s219). +registration(r734,c67,s220). +registration(r735,c50,s220). +registration(r736,c180,s220). +registration(r737,c171,s221). +registration(r738,c32,s221). +registration(r739,c240,s221). +registration(r740,c127,s222). +registration(r741,c68,s222). +registration(r742,c114,s222). +registration(r743,c13,s222). +registration(r744,c84,s223). +registration(r745,c238,s223). +registration(r746,c8,s223). +registration(r747,c76,s224). +registration(r748,c34,s224). +registration(r749,c138,s224). +registration(r750,c222,s225). +registration(r751,c56,s225). +registration(r752,c67,s225). +registration(r753,c134,s226). +registration(r754,c10,s226). +registration(r755,c122,s226). +registration(r756,c37,s227). +registration(r757,c218,s227). +registration(r758,c184,s227). +registration(r759,c143,s227). +registration(r760,c84,s228). +registration(r761,c2,s228). +registration(r762,c13,s228). +registration(r763,c98,s228). +registration(r764,c91,s229). +registration(r765,c24,s229). +registration(r766,c4,s229). +registration(r767,c39,s230). +registration(r768,c89,s230). +registration(r769,c177,s230). +registration(r770,c233,s231). +registration(r771,c48,s231). +registration(r772,c15,s231). +registration(r773,c25,s232). +registration(r774,c42,s232). +registration(r775,c114,s232). +registration(r776,c75,s233). +registration(r777,c156,s233). +registration(r778,c95,s233). +registration(r779,c179,s234). +registration(r780,c222,s234). +registration(r781,c224,s234). +registration(r782,c239,s234). +registration(r783,c125,s235). +registration(r784,c7,s235). +registration(r785,c70,s235). +registration(r786,c108,s236). +registration(r787,c165,s236). +registration(r788,c29,s236). +registration(r789,c6,s237). +registration(r790,c140,s237). +registration(r791,c235,s237). +registration(r792,c5,s238). +registration(r793,c223,s238). +registration(r794,c179,s238). +registration(r795,c255,s238). +registration(r796,c132,s239). +registration(r797,c141,s239). +registration(r798,c220,s239). +registration(r799,c186,s240). +registration(r800,c55,s240). +registration(r801,c98,s240). +registration(r802,c224,s241). +registration(r803,c176,s241). +registration(r804,c190,s241). +registration(r805,c29,s241). +registration(r806,c209,s241). +registration(r807,c59,s242). +registration(r808,c134,s242). +registration(r809,c174,s242). +registration(r810,c154,s242). +registration(r811,c248,s243). +registration(r812,c84,s243). +registration(r813,c159,s243). +registration(r814,c135,s243). +registration(r815,c5,s244). +registration(r816,c9,s244). +registration(r817,c14,s244). +registration(r818,c100,s245). +registration(r819,c211,s245). +registration(r820,c159,s245). +registration(r821,c73,s246). +registration(r822,c21,s246). +registration(r823,c22,s246). +registration(r824,c66,s247). +registration(r825,c24,s247). +registration(r826,c255,s247). +registration(r827,c85,s247). +registration(r828,c194,s248). +registration(r829,c150,s248). +registration(r830,c151,s248). +registration(r831,c236,s249). +registration(r832,c252,s249). +registration(r833,c102,s249). +registration(r834,c108,s250). +registration(r835,c255,s250). +registration(r836,c144,s250). +registration(r837,c244,s251). +registration(r838,c209,s251). +registration(r839,c130,s251). +registration(r840,c204,s251). +registration(r841,c165,s252). +registration(r842,c29,s252). +registration(r843,c201,s252). +registration(r844,c225,s253). +registration(r845,c121,s253). +registration(r846,c115,s253). +registration(r847,c55,s254). +registration(r848,c205,s254). +registration(r849,c151,s254). +registration(r850,c132,s255). +registration(r851,c144,s255). +registration(r852,c196,s255). +registration(r853,c48,s255). +registration(r854,c121,s256). +registration(r855,c164,s256). +registration(r856,c47,s256). +registration(r857,c1,s257). +registration(r858,c225,s257). +registration(r859,c42,s257). +registration(r860,c175,s257). +registration(r861,c39,s258). +registration(r862,c120,s258). +registration(r863,c74,s258). +registration(r864,c195,s259). +registration(r865,c252,s259). +registration(r866,c143,s259). +registration(r867,c93,s260). +registration(r868,c91,s260). +registration(r869,c199,s260). +registration(r870,c86,s261). +registration(r871,c127,s261). +registration(r872,c91,s261). +registration(r873,c212,s262). +registration(r874,c14,s262). +registration(r875,c223,s262). +registration(r876,c166,s262). +registration(r877,c19,s263). +registration(r878,c209,s263). +registration(r879,c234,s263). +registration(r880,c18,s264). +registration(r881,c60,s264). +registration(r882,c235,s264). +registration(r883,c175,s265). +registration(r884,c150,s265). +registration(r885,c37,s265). +registration(r886,c131,s266). +registration(r887,c206,s266). +registration(r888,c144,s266). +registration(r889,c231,s267). +registration(r890,c187,s267). +registration(r891,c9,s267). +registration(r892,c221,s268). +registration(r893,c96,s268). +registration(r894,c73,s268). +registration(r895,c8,s268). +registration(r896,c36,s268). +registration(r897,c218,s269). +registration(r898,c21,s269). +registration(r899,c231,s269). +registration(r900,c35,s269). +registration(r901,c102,s270). +registration(r902,c194,s270). +registration(r903,c183,s270). +registration(r904,c88,s270). +registration(r905,c136,s271). +registration(r906,c35,s271). +registration(r907,c96,s271). +registration(r908,c157,s272). +registration(r909,c5,s272). +registration(r910,c155,s272). +registration(r911,c238,s272). +registration(r912,c197,s273). +registration(r913,c236,s273). +registration(r914,c78,s273). +registration(r915,c252,s273). +registration(r916,c59,s274). +registration(r917,c32,s274). +registration(r918,c50,s274). +registration(r919,c174,s274). +registration(r920,c121,s275). +registration(r921,c41,s275). +registration(r922,c20,s275). +registration(r923,c42,s276). +registration(r924,c150,s276). +registration(r925,c191,s276). +registration(r926,c31,s277). +registration(r927,c9,s277). +registration(r928,c110,s277). +registration(r929,c10,s277). +registration(r930,c23,s278). +registration(r931,c30,s278). +registration(r932,c247,s278). +registration(r933,c72,s278). +registration(r934,c237,s279). +registration(r935,c7,s279). +registration(r936,c158,s279). +registration(r937,c40,s279). +registration(r938,c122,s280). +registration(r939,c47,s280). +registration(r940,c126,s280). +registration(r941,c146,s281). +registration(r942,c48,s281). +registration(r943,c59,s281). +registration(r944,c250,s282). +registration(r945,c110,s282). +registration(r946,c127,s282). +registration(r947,c120,s282). +registration(r948,c214,s283). +registration(r949,c135,s283). +registration(r950,c246,s283). +registration(r951,c238,s284). +registration(r952,c202,s284). +registration(r953,c175,s284). +registration(r954,c184,s285). +registration(r955,c211,s285). +registration(r956,c225,s285). +registration(r957,c91,s286). +registration(r958,c15,s286). +registration(r959,c34,s286). +registration(r960,c179,s287). +registration(r961,c127,s287). +registration(r962,c163,s287). +registration(r963,c158,s288). +registration(r964,c223,s288). +registration(r965,c197,s288). +registration(r966,c178,s289). +registration(r967,c141,s289). +registration(r968,c223,s289). +registration(r969,c133,s290). +registration(r970,c152,s290). +registration(r971,c70,s290). +registration(r972,c255,s291). +registration(r973,c237,s291). +registration(r974,c160,s291). +registration(r975,c69,s292). +registration(r976,c58,s292). +registration(r977,c221,s292). +registration(r978,c70,s293). +registration(r979,c27,s293). +registration(r980,c10,s293). +registration(r981,c81,s294). +registration(r982,c136,s294). +registration(r983,c106,s294). +registration(r984,c63,s294). +registration(r985,c202,s295). +registration(r986,c206,s295). +registration(r987,c160,s295). +registration(r988,c38,s296). +registration(r989,c11,s296). +registration(r990,c146,s296). +registration(r991,c144,s297). +registration(r992,c75,s297). +registration(r993,c122,s297). +registration(r994,c192,s297). +registration(r995,c171,s298). +registration(r996,c247,s298). +registration(r997,c39,s298). +registration(r998,c66,s299). +registration(r999,c63,s299). +registration(r1000,c39,s299). +registration(r1001,c175,s300). +registration(r1002,c55,s300). +registration(r1003,c167,s300). +registration(r1004,c114,s301). +registration(r1005,c189,s301). +registration(r1006,c154,s301). +registration(r1007,c194,s301). +registration(r1008,c241,s302). +registration(r1009,c152,s302). +registration(r1010,c30,s302). +registration(r1011,c106,s302). +registration(r1012,c69,s303). +registration(r1013,c154,s303). +registration(r1014,c132,s303). +registration(r1015,c67,s303). +registration(r1016,c45,s304). +registration(r1017,c122,s304). +registration(r1018,c185,s304). +registration(r1019,c224,s305). +registration(r1020,c62,s305). +registration(r1021,c75,s305). +registration(r1022,c242,s306). +registration(r1023,c127,s306). +registration(r1024,c111,s306). +registration(r1025,c11,s307). +registration(r1026,c75,s307). +registration(r1027,c69,s307). +registration(r1028,c222,s308). +registration(r1029,c236,s308). +registration(r1030,c7,s308). +registration(r1031,c87,s308). +registration(r1032,c161,s309). +registration(r1033,c219,s309). +registration(r1034,c82,s309). +registration(r1035,c128,s310). +registration(r1036,c96,s310). +registration(r1037,c16,s310). +registration(r1038,c241,s310). +registration(r1039,c47,s311). +registration(r1040,c102,s311). +registration(r1041,c130,s311). +registration(r1042,c1,s312). +registration(r1043,c22,s312). +registration(r1044,c189,s312). +registration(r1045,c8,s312). +registration(r1046,c131,s313). +registration(r1047,c239,s313). +registration(r1048,c67,s313). +registration(r1049,c75,s314). +registration(r1050,c107,s314). +registration(r1051,c50,s314). +registration(r1052,c14,s314). +registration(r1053,c235,s315). +registration(r1054,c242,s315). +registration(r1055,c100,s315). +registration(r1056,c117,s316). +registration(r1057,c92,s316). +registration(r1058,c109,s316). +registration(r1059,c211,s317). +registration(r1060,c231,s317). +registration(r1061,c49,s317). +registration(r1062,c233,s317). +registration(r1063,c232,s318). +registration(r1064,c39,s318). +registration(r1065,c105,s318). +registration(r1066,c88,s319). +registration(r1067,c52,s319). +registration(r1068,c13,s319). +registration(r1069,c120,s320). +registration(r1070,c102,s320). +registration(r1071,c23,s320). +registration(r1072,c3,s321). +registration(r1073,c119,s321). +registration(r1074,c218,s321). +registration(r1075,c80,s322). +registration(r1076,c204,s322). +registration(r1077,c55,s322). +registration(r1078,c11,s323). +registration(r1079,c159,s323). +registration(r1080,c138,s323). +registration(r1081,c210,s324). +registration(r1082,c31,s324). +registration(r1083,c174,s324). +registration(r1084,c90,s324). +registration(r1085,c147,s325). +registration(r1086,c67,s325). +registration(r1087,c103,s325). +registration(r1088,c223,s326). +registration(r1089,c46,s326). +registration(r1090,c219,s326). +registration(r1091,c223,s327). +registration(r1092,c218,s327). +registration(r1093,c124,s327). +registration(r1094,c205,s328). +registration(r1095,c27,s328). +registration(r1096,c221,s328). +registration(r1097,c232,s329). +registration(r1098,c35,s329). +registration(r1099,c254,s329). +registration(r1100,c169,s329). +registration(r1101,c62,s330). +registration(r1102,c90,s330). +registration(r1103,c11,s330). +registration(r1104,c159,s331). +registration(r1105,c145,s331). +registration(r1106,c27,s331). +registration(r1107,c251,s332). +registration(r1108,c149,s332). +registration(r1109,c50,s332). +registration(r1110,c18,s333). +registration(r1111,c59,s333). +registration(r1112,c182,s333). +registration(r1113,c132,s334). +registration(r1114,c124,s334). +registration(r1115,c190,s334). +registration(r1116,c240,s334). +registration(r1117,c44,s335). +registration(r1118,c239,s335). +registration(r1119,c196,s335). +registration(r1120,c3,s336). +registration(r1121,c49,s336). +registration(r1122,c204,s336). +registration(r1123,c107,s337). +registration(r1124,c227,s337). +registration(r1125,c0,s337). +registration(r1126,c252,s338). +registration(r1127,c103,s338). +registration(r1128,c108,s338). +registration(r1129,c126,s339). +registration(r1130,c151,s339). +registration(r1131,c86,s339). +registration(r1132,c219,s340). +registration(r1133,c91,s340). +registration(r1134,c53,s340). +registration(r1135,c219,s341). +registration(r1136,c16,s341). +registration(r1137,c60,s341). +registration(r1138,c251,s342). +registration(r1139,c163,s342). +registration(r1140,c25,s342). +registration(r1141,c254,s343). +registration(r1142,c50,s343). +registration(r1143,c216,s343). +registration(r1144,c19,s343). +registration(r1145,c251,s344). +registration(r1146,c109,s344). +registration(r1147,c128,s344). +registration(r1148,c254,s344). +registration(r1149,c239,s345). +registration(r1150,c102,s345). +registration(r1151,c221,s345). +registration(r1152,c58,s346). +registration(r1153,c158,s346). +registration(r1154,c38,s346). +registration(r1155,c56,s347). +registration(r1156,c195,s347). +registration(r1157,c26,s347). +registration(r1158,c191,s347). +registration(r1159,c57,s348). +registration(r1160,c135,s348). +registration(r1161,c181,s348). +registration(r1162,c142,s349). +registration(r1163,c55,s349). +registration(r1164,c191,s349). +registration(r1165,c44,s350). +registration(r1166,c34,s350). +registration(r1167,c141,s350). +registration(r1168,c124,s350). +registration(r1169,c162,s351). +registration(r1170,c254,s351). +registration(r1171,c227,s351). +registration(r1172,c129,s352). +registration(r1173,c11,s352). +registration(r1174,c193,s352). +registration(r1175,c132,s353). +registration(r1176,c22,s353). +registration(r1177,c100,s353). +registration(r1178,c158,s354). +registration(r1179,c202,s354). +registration(r1180,c137,s354). +registration(r1181,c25,s355). +registration(r1182,c14,s355). +registration(r1183,c67,s355). +registration(r1184,c110,s356). +registration(r1185,c221,s356). +registration(r1186,c206,s356). +registration(r1187,c75,s357). +registration(r1188,c77,s357). +registration(r1189,c253,s357). +registration(r1190,c48,s357). +registration(r1191,c177,s358). +registration(r1192,c60,s358). +registration(r1193,c247,s358). +registration(r1194,c124,s359). +registration(r1195,c195,s359). +registration(r1196,c230,s359). +registration(r1197,c132,s360). +registration(r1198,c138,s360). +registration(r1199,c34,s360). +registration(r1200,c60,s360). +registration(r1201,c106,s361). +registration(r1202,c79,s361). +registration(r1203,c247,s361). +registration(r1204,c213,s362). +registration(r1205,c124,s362). +registration(r1206,c103,s362). +registration(r1207,c180,s363). +registration(r1208,c209,s363). +registration(r1209,c247,s363). +registration(r1210,c166,s363). +registration(r1211,c34,s364). +registration(r1212,c0,s364). +registration(r1213,c86,s364). +registration(r1214,c24,s365). +registration(r1215,c138,s365). +registration(r1216,c60,s365). +registration(r1217,c198,s365). +registration(r1218,c212,s366). +registration(r1219,c105,s366). +registration(r1220,c210,s366). +registration(r1221,c211,s366). +registration(r1222,c8,s366). +registration(r1223,c129,s367). +registration(r1224,c224,s367). +registration(r1225,c221,s367). +registration(r1226,c178,s368). +registration(r1227,c198,s368). +registration(r1228,c253,s368). +registration(r1229,c226,s369). +registration(r1230,c139,s369). +registration(r1231,c101,s369). +registration(r1232,c141,s369). +registration(r1233,c169,s370). +registration(r1234,c9,s370). +registration(r1235,c212,s370). +registration(r1236,c69,s370). +registration(r1237,c64,s371). +registration(r1238,c11,s371). +registration(r1239,c91,s371). +registration(r1240,c107,s372). +registration(r1241,c127,s372). +registration(r1242,c1,s372). +registration(r1243,c226,s372). +registration(r1244,c81,s373). +registration(r1245,c255,s373). +registration(r1246,c42,s373). +registration(r1247,c197,s373). +registration(r1248,c135,s373). +registration(r1249,c131,s374). +registration(r1250,c11,s374). +registration(r1251,c20,s374). +registration(r1252,c161,s374). +registration(r1253,c165,s375). +registration(r1254,c186,s375). +registration(r1255,c169,s375). +registration(r1256,c239,s376). +registration(r1257,c0,s376). +registration(r1258,c46,s376). +registration(r1259,c216,s377). +registration(r1260,c218,s377). +registration(r1261,c196,s377). +registration(r1262,c57,s378). +registration(r1263,c89,s378). +registration(r1264,c191,s378). +registration(r1265,c233,s379). +registration(r1266,c142,s379). +registration(r1267,c30,s379). +registration(r1268,c21,s379). +registration(r1269,c29,s380). +registration(r1270,c42,s380). +registration(r1271,c140,s380). +registration(r1272,c203,s380). +registration(r1273,c233,s380). +registration(r1274,c116,s381). +registration(r1275,c172,s381). +registration(r1276,c214,s381). +registration(r1277,c3,s382). +registration(r1278,c96,s382). +registration(r1279,c8,s382). +registration(r1280,c205,s383). +registration(r1281,c51,s383). +registration(r1282,c22,s383). +registration(r1283,c140,s383). +registration(r1284,c146,s384). +registration(r1285,c228,s384). +registration(r1286,c190,s384). +registration(r1287,c3,s384). +registration(r1288,c55,s385). +registration(r1289,c165,s385). +registration(r1290,c239,s385). +registration(r1291,c29,s385). +registration(r1292,c44,s386). +registration(r1293,c99,s386). +registration(r1294,c6,s386). +registration(r1295,c220,s386). +registration(r1296,c6,s387). +registration(r1297,c188,s387). +registration(r1298,c223,s387). +registration(r1299,c187,s388). +registration(r1300,c159,s388). +registration(r1301,c145,s388). +registration(r1302,c154,s389). +registration(r1303,c123,s389). +registration(r1304,c139,s389). +registration(r1305,c96,s389). +registration(r1306,c78,s390). +registration(r1307,c101,s390). +registration(r1308,c27,s390). +registration(r1309,c10,s390). +registration(r1310,c232,s391). +registration(r1311,c58,s391). +registration(r1312,c40,s391). +registration(r1313,c158,s391). +registration(r1314,c182,s391). +registration(r1315,c173,s392). +registration(r1316,c10,s392). +registration(r1317,c189,s392). +registration(r1318,c34,s393). +registration(r1319,c47,s393). +registration(r1320,c167,s393). +registration(r1321,c150,s394). +registration(r1322,c121,s394). +registration(r1323,c89,s394). +registration(r1324,c5,s394). +registration(r1325,c115,s395). +registration(r1326,c79,s395). +registration(r1327,c214,s395). +registration(r1328,c92,s396). +registration(r1329,c225,s396). +registration(r1330,c118,s396). +registration(r1331,c158,s396). +registration(r1332,c89,s397). +registration(r1333,c186,s397). +registration(r1334,c205,s397). +registration(r1335,c103,s397). +registration(r1336,c205,s398). +registration(r1337,c209,s398). +registration(r1338,c193,s398). +registration(r1339,c105,s399). +registration(r1340,c179,s399). +registration(r1341,c192,s399). +registration(r1342,c26,s399). +registration(r1343,c17,s400). +registration(r1344,c50,s400). +registration(r1345,c163,s400). +registration(r1346,c120,s401). +registration(r1347,c93,s401). +registration(r1348,c237,s401). +registration(r1349,c99,s402). +registration(r1350,c25,s402). +registration(r1351,c91,s402). +registration(r1352,c117,s402). +registration(r1353,c208,s402). +registration(r1354,c132,s403). +registration(r1355,c125,s403). +registration(r1356,c168,s403). +registration(r1357,c107,s404). +registration(r1358,c65,s404). +registration(r1359,c79,s404). +registration(r1360,c15,s405). +registration(r1361,c211,s405). +registration(r1362,c35,s405). +registration(r1363,c229,s405). +registration(r1364,c204,s406). +registration(r1365,c106,s406). +registration(r1366,c214,s406). +registration(r1367,c196,s407). +registration(r1368,c25,s407). +registration(r1369,c7,s407). +registration(r1370,c53,s407). +registration(r1371,c42,s408). +registration(r1372,c167,s408). +registration(r1373,c121,s408). +registration(r1374,c247,s408). +registration(r1375,c162,s409). +registration(r1376,c125,s409). +registration(r1377,c69,s409). +registration(r1378,c192,s409). +registration(r1379,c225,s410). +registration(r1380,c180,s410). +registration(r1381,c163,s410). +registration(r1382,c206,s411). +registration(r1383,c154,s411). +registration(r1384,c44,s411). +registration(r1385,c3,s411). +registration(r1386,c224,s412). +registration(r1387,c205,s412). +registration(r1388,c197,s412). +registration(r1389,c238,s413). +registration(r1390,c46,s413). +registration(r1391,c58,s413). +registration(r1392,c213,s413). +registration(r1393,c19,s414). +registration(r1394,c1,s414). +registration(r1395,c170,s414). +registration(r1396,c240,s415). +registration(r1397,c194,s415). +registration(r1398,c62,s415). +registration(r1399,c244,s416). +registration(r1400,c41,s416). +registration(r1401,c90,s416). +registration(r1402,c244,s417). +registration(r1403,c249,s417). +registration(r1404,c147,s417). +registration(r1405,c116,s418). +registration(r1406,c201,s418). +registration(r1407,c195,s418). +registration(r1408,c178,s419). +registration(r1409,c157,s419). +registration(r1410,c217,s419). +registration(r1411,c140,s420). +registration(r1412,c223,s420). +registration(r1413,c116,s420). +registration(r1414,c244,s421). +registration(r1415,c39,s421). +registration(r1416,c88,s421). +registration(r1417,c252,s422). +registration(r1418,c40,s422). +registration(r1419,c214,s422). +registration(r1420,c208,s423). +registration(r1421,c75,s423). +registration(r1422,c238,s423). +registration(r1423,c235,s424). +registration(r1424,c216,s424). +registration(r1425,c15,s424). +registration(r1426,c175,s425). +registration(r1427,c97,s425). +registration(r1428,c230,s425). +registration(r1429,c88,s425). +registration(r1430,c22,s426). +registration(r1431,c12,s426). +registration(r1432,c207,s426). +registration(r1433,c195,s427). +registration(r1434,c116,s427). +registration(r1435,c250,s427). +registration(r1436,c246,s427). +registration(r1437,c31,s428). +registration(r1438,c249,s428). +registration(r1439,c78,s428). +registration(r1440,c201,s428). +registration(r1441,c3,s429). +registration(r1442,c47,s429). +registration(r1443,c224,s429). +registration(r1444,c240,s429). +registration(r1445,c157,s430). +registration(r1446,c80,s430). +registration(r1447,c160,s430). +registration(r1448,c40,s431). +registration(r1449,c46,s431). +registration(r1450,c145,s431). +registration(r1451,c95,s432). +registration(r1452,c140,s432). +registration(r1453,c220,s432). +registration(r1454,c1,s432). +registration(r1455,c24,s433). +registration(r1456,c36,s433). +registration(r1457,c206,s433). +registration(r1458,c28,s433). +registration(r1459,c77,s434). +registration(r1460,c231,s434). +registration(r1461,c181,s434). +registration(r1462,c149,s434). +registration(r1463,c63,s435). +registration(r1464,c29,s435). +registration(r1465,c134,s435). +registration(r1466,c37,s436). +registration(r1467,c221,s436). +registration(r1468,c164,s436). +registration(r1469,c53,s436). +registration(r1470,c140,s437). +registration(r1471,c68,s437). +registration(r1472,c148,s437). +registration(r1473,c32,s437). +registration(r1474,c25,s438). +registration(r1475,c247,s438). +registration(r1476,c206,s438). +registration(r1477,c7,s439). +registration(r1478,c91,s439). +registration(r1479,c226,s439). +registration(r1480,c151,s440). +registration(r1481,c165,s440). +registration(r1482,c86,s440). +registration(r1483,c228,s440). +registration(r1484,c179,s441). +registration(r1485,c194,s441). +registration(r1486,c226,s441). +registration(r1487,c135,s442). +registration(r1488,c38,s442). +registration(r1489,c169,s442). +registration(r1490,c237,s443). +registration(r1491,c79,s443). +registration(r1492,c203,s443). +registration(r1493,c5,s443). +registration(r1494,c6,s444). +registration(r1495,c212,s444). +registration(r1496,c35,s444). +registration(r1497,c125,s445). +registration(r1498,c175,s445). +registration(r1499,c47,s445). +registration(r1500,c213,s446). +registration(r1501,c23,s446). +registration(r1502,c115,s446). +registration(r1503,c39,s447). +registration(r1504,c123,s447). +registration(r1505,c111,s447). +registration(r1506,c246,s447). +registration(r1507,c37,s448). +registration(r1508,c195,s448). +registration(r1509,c177,s448). +registration(r1510,c1,s449). +registration(r1511,c164,s449). +registration(r1512,c192,s449). +registration(r1513,c137,s449). +registration(r1514,c220,s450). +registration(r1515,c172,s450). +registration(r1516,c146,s450). +registration(r1517,c65,s450). +registration(r1518,c232,s451). +registration(r1519,c235,s451). +registration(r1520,c135,s451). +registration(r1521,c252,s451). +registration(r1522,c119,s452). +registration(r1523,c143,s452). +registration(r1524,c35,s452). +registration(r1525,c35,s453). +registration(r1526,c12,s453). +registration(r1527,c245,s453). +registration(r1528,c167,s454). +registration(r1529,c33,s454). +registration(r1530,c129,s454). +registration(r1531,c65,s455). +registration(r1532,c177,s455). +registration(r1533,c81,s455). +registration(r1534,c141,s455). +registration(r1535,c156,s456). +registration(r1536,c69,s456). +registration(r1537,c41,s456). +registration(r1538,c21,s456). +registration(r1539,c103,s457). +registration(r1540,c235,s457). +registration(r1541,c24,s457). +registration(r1542,c168,s458). +registration(r1543,c135,s458). +registration(r1544,c84,s458). +registration(r1545,c98,s459). +registration(r1546,c156,s459). +registration(r1547,c244,s459). +registration(r1548,c66,s459). +registration(r1549,c179,s459). +registration(r1550,c236,s460). +registration(r1551,c219,s460). +registration(r1552,c244,s460). +registration(r1553,c253,s460). +registration(r1554,c43,s461). +registration(r1555,c44,s461). +registration(r1556,c154,s461). +registration(r1557,c120,s462). +registration(r1558,c159,s462). +registration(r1559,c106,s462). +registration(r1560,c132,s463). +registration(r1561,c68,s463). +registration(r1562,c237,s463). +registration(r1563,c204,s463). +registration(r1564,c211,s464). +registration(r1565,c119,s464). +registration(r1566,c164,s464). +registration(r1567,c215,s465). +registration(r1568,c178,s465). +registration(r1569,c130,s465). +registration(r1570,c95,s466). +registration(r1571,c127,s466). +registration(r1572,c60,s466). +registration(r1573,c104,s467). +registration(r1574,c185,s467). +registration(r1575,c22,s467). +registration(r1576,c143,s467). +registration(r1577,c120,s468). +registration(r1578,c124,s468). +registration(r1579,c110,s468). +registration(r1580,c255,s468). +registration(r1581,c241,s469). +registration(r1582,c44,s469). +registration(r1583,c129,s469). +registration(r1584,c249,s469). +registration(r1585,c217,s470). +registration(r1586,c111,s470). +registration(r1587,c101,s470). +registration(r1588,c233,s470). +registration(r1589,c58,s471). +registration(r1590,c194,s471). +registration(r1591,c74,s471). +registration(r1592,c215,s472). +registration(r1593,c54,s472). +registration(r1594,c104,s472). +registration(r1595,c65,s473). +registration(r1596,c160,s473). +registration(r1597,c220,s473). +registration(r1598,c75,s473). +registration(r1599,c190,s474). +registration(r1600,c27,s474). +registration(r1601,c255,s474). +registration(r1602,c128,s475). +registration(r1603,c227,s475). +registration(r1604,c72,s475). +registration(r1605,c184,s476). +registration(r1606,c224,s476). +registration(r1607,c108,s476). +registration(r1608,c168,s477). +registration(r1609,c156,s477). +registration(r1610,c19,s477). +registration(r1611,c235,s478). +registration(r1612,c152,s478). +registration(r1613,c5,s478). +registration(r1614,c71,s479). +registration(r1615,c28,s479). +registration(r1616,c194,s479). +registration(r1617,c56,s479). +registration(r1618,c192,s479). +registration(r1619,c84,s480). +registration(r1620,c12,s480). +registration(r1621,c112,s480). +registration(r1622,c83,s481). +registration(r1623,c229,s481). +registration(r1624,c7,s481). +registration(r1625,c157,s481). +registration(r1626,c125,s482). +registration(r1627,c119,s482). +registration(r1628,c179,s482). +registration(r1629,c21,s482). +registration(r1630,c136,s483). +registration(r1631,c178,s483). +registration(r1632,c179,s483). +registration(r1633,c184,s483). +registration(r1634,c7,s483). +registration(r1635,c255,s484). +registration(r1636,c74,s484). +registration(r1637,c201,s484). +registration(r1638,c130,s484). +registration(r1639,c193,s485). +registration(r1640,c215,s485). +registration(r1641,c228,s485). +registration(r1642,c114,s485). +registration(r1643,c132,s486). +registration(r1644,c89,s486). +registration(r1645,c121,s486). +registration(r1646,c98,s487). +registration(r1647,c17,s487). +registration(r1648,c112,s487). +registration(r1649,c55,s487). +registration(r1650,c220,s488). +registration(r1651,c190,s488). +registration(r1652,c55,s488). +registration(r1653,c239,s489). +registration(r1654,c189,s489). +registration(r1655,c231,s489). +registration(r1656,c175,s489). +registration(r1657,c240,s490). +registration(r1658,c139,s490). +registration(r1659,c135,s490). +registration(r1660,c109,s491). +registration(r1661,c227,s491). +registration(r1662,c215,s491). +registration(r1663,c49,s492). +registration(r1664,c89,s492). +registration(r1665,c251,s492). +registration(r1666,c186,s492). +registration(r1667,c151,s492). +registration(r1668,c208,s493). +registration(r1669,c68,s493). +registration(r1670,c29,s493). +registration(r1671,c86,s493). +registration(r1672,c60,s494). +registration(r1673,c229,s494). +registration(r1674,c69,s494). +registration(r1675,c52,s495). +registration(r1676,c3,s495). +registration(r1677,c127,s495). +registration(r1678,c144,s495). +registration(r1679,c216,s495). +registration(r1680,c242,s496). +registration(r1681,c116,s496). +registration(r1682,c186,s496). +registration(r1683,c34,s497). +registration(r1684,c252,s497). +registration(r1685,c172,s497). +registration(r1686,c37,s497). +registration(r1687,c43,s498). +registration(r1688,c189,s498). +registration(r1689,c57,s498). +registration(r1690,c229,s499). +registration(r1691,c116,s499). +registration(r1692,c47,s499). +registration(r1693,c89,s499). +registration(r1694,c29,s500). +registration(r1695,c39,s500). +registration(r1696,c170,s500). +registration(r1697,c165,s500). +registration(r1698,c175,s501). +registration(r1699,c172,s501). +registration(r1700,c165,s501). +registration(r1701,c96,s501). +registration(r1702,c109,s502). +registration(r1703,c118,s502). +registration(r1704,c132,s502). +registration(r1705,c162,s502). +registration(r1706,c142,s503). +registration(r1707,c138,s503). +registration(r1708,c205,s503). +registration(r1709,c62,s504). +registration(r1710,c37,s504). +registration(r1711,c169,s504). +registration(r1712,c203,s505). +registration(r1713,c13,s505). +registration(r1714,c202,s505). +registration(r1715,c117,s506). +registration(r1716,c9,s506). +registration(r1717,c218,s506). +registration(r1718,c135,s507). +registration(r1719,c234,s507). +registration(r1720,c90,s507). +registration(r1721,c200,s508). +registration(r1722,c31,s508). +registration(r1723,c208,s508). +registration(r1724,c66,s508). +registration(r1725,c192,s509). +registration(r1726,c204,s509). +registration(r1727,c62,s509). +registration(r1728,c143,s509). +registration(r1729,c49,s510). +registration(r1730,c57,s510). +registration(r1731,c47,s510). +registration(r1732,c63,s510). +registration(r1733,c82,s511). +registration(r1734,c237,s511). +registration(r1735,c113,s511). +registration(r1736,c75,s512). +registration(r1737,c11,s512). +registration(r1738,c176,s512). +registration(r1739,c11,s513). +registration(r1740,c124,s513). +registration(r1741,c67,s513). +registration(r1742,c18,s514). +registration(r1743,c5,s514). +registration(r1744,c221,s514). +registration(r1745,c169,s515). +registration(r1746,c195,s515). +registration(r1747,c209,s515). +registration(r1748,c2,s516). +registration(r1749,c114,s516). +registration(r1750,c112,s516). +registration(r1751,c174,s517). +registration(r1752,c219,s517). +registration(r1753,c99,s517). +registration(r1754,c161,s517). +registration(r1755,c107,s518). +registration(r1756,c174,s518). +registration(r1757,c10,s518). +registration(r1758,c22,s519). +registration(r1759,c185,s519). +registration(r1760,c231,s519). +registration(r1761,c250,s520). +registration(r1762,c238,s520). +registration(r1763,c49,s520). +registration(r1764,c219,s521). +registration(r1765,c65,s521). +registration(r1766,c133,s521). +registration(r1767,c129,s521). +registration(r1768,c135,s522). +registration(r1769,c243,s522). +registration(r1770,c16,s522). +registration(r1771,c236,s523). +registration(r1772,c98,s523). +registration(r1773,c192,s523). +registration(r1774,c44,s524). +registration(r1775,c61,s524). +registration(r1776,c201,s524). +registration(r1777,c223,s525). +registration(r1778,c34,s525). +registration(r1779,c200,s525). +registration(r1780,c195,s526). +registration(r1781,c183,s526). +registration(r1782,c167,s526). +registration(r1783,c132,s527). +registration(r1784,c131,s527). +registration(r1785,c243,s527). +registration(r1786,c121,s527). +registration(r1787,c32,s528). +registration(r1788,c249,s528). +registration(r1789,c140,s528). +registration(r1790,c155,s528). +registration(r1791,c128,s529). +registration(r1792,c91,s529). +registration(r1793,c7,s529). +registration(r1794,c68,s530). +registration(r1795,c7,s530). +registration(r1796,c241,s530). +registration(r1797,c229,s530). +registration(r1798,c239,s530). +registration(r1799,c175,s531). +registration(r1800,c139,s531). +registration(r1801,c180,s531). +registration(r1802,c246,s532). +registration(r1803,c212,s532). +registration(r1804,c183,s532). +registration(r1805,c81,s533). +registration(r1806,c129,s533). +registration(r1807,c66,s533). +registration(r1808,c207,s534). +registration(r1809,c143,s534). +registration(r1810,c20,s534). +registration(r1811,c112,s534). +registration(r1812,c79,s535). +registration(r1813,c80,s535). +registration(r1814,c248,s535). +registration(r1815,c234,s536). +registration(r1816,c186,s536). +registration(r1817,c61,s536). +registration(r1818,c237,s537). +registration(r1819,c138,s537). +registration(r1820,c94,s537). +registration(r1821,c85,s538). +registration(r1822,c41,s538). +registration(r1823,c121,s538). +registration(r1824,c202,s539). +registration(r1825,c80,s539). +registration(r1826,c53,s539). +registration(r1827,c5,s540). +registration(r1828,c205,s540). +registration(r1829,c223,s540). +registration(r1830,c80,s541). +registration(r1831,c157,s541). +registration(r1832,c45,s541). +registration(r1833,c133,s541). +registration(r1834,c52,s542). +registration(r1835,c237,s542). +registration(r1836,c194,s542). +registration(r1837,c176,s543). +registration(r1838,c190,s543). +registration(r1839,c248,s543). +registration(r1840,c124,s543). +registration(r1841,c46,s544). +registration(r1842,c246,s544). +registration(r1843,c30,s544). +registration(r1844,c192,s544). +registration(r1845,c86,s545). +registration(r1846,c253,s545). +registration(r1847,c57,s545). +registration(r1848,c25,s546). +registration(r1849,c169,s546). +registration(r1850,c167,s546). +registration(r1851,c213,s547). +registration(r1852,c179,s547). +registration(r1853,c120,s547). +registration(r1854,c102,s548). +registration(r1855,c30,s548). +registration(r1856,c27,s548). +registration(r1857,c217,s549). +registration(r1858,c247,s549). +registration(r1859,c209,s549). +registration(r1860,c2,s550). +registration(r1861,c78,s550). +registration(r1862,c102,s550). +registration(r1863,c14,s550). +registration(r1864,c122,s551). +registration(r1865,c10,s551). +registration(r1866,c15,s551). +registration(r1867,c40,s552). +registration(r1868,c128,s552). +registration(r1869,c124,s552). +registration(r1870,c82,s553). +registration(r1871,c70,s553). +registration(r1872,c63,s553). +registration(r1873,c167,s553). +registration(r1874,c204,s554). +registration(r1875,c74,s554). +registration(r1876,c165,s554). +registration(r1877,c156,s554). +registration(r1878,c109,s555). +registration(r1879,c123,s555). +registration(r1880,c227,s555). +registration(r1881,c72,s556). +registration(r1882,c147,s556). +registration(r1883,c214,s556). +registration(r1884,c13,s556). +registration(r1885,c43,s557). +registration(r1886,c227,s557). +registration(r1887,c181,s557). +registration(r1888,c51,s558). +registration(r1889,c231,s558). +registration(r1890,c41,s558). +registration(r1891,c106,s558). +registration(r1892,c52,s559). +registration(r1893,c94,s559). +registration(r1894,c15,s559). +registration(r1895,c168,s559). +registration(r1896,c154,s560). +registration(r1897,c203,s560). +registration(r1898,c82,s560). +registration(r1899,c69,s560). +registration(r1900,c120,s561). +registration(r1901,c14,s561). +registration(r1902,c128,s561). +registration(r1903,c229,s561). +registration(r1904,c24,s562). +registration(r1905,c198,s562). +registration(r1906,c201,s562). +registration(r1907,c29,s563). +registration(r1908,c95,s563). +registration(r1909,c176,s563). +registration(r1910,c137,s563). +registration(r1911,c51,s564). +registration(r1912,c243,s564). +registration(r1913,c106,s564). +registration(r1914,c107,s564). +registration(r1915,c57,s565). +registration(r1916,c185,s565). +registration(r1917,c5,s565). +registration(r1918,c12,s565). +registration(r1919,c77,s565). +registration(r1920,c66,s566). +registration(r1921,c133,s566). +registration(r1922,c90,s566). +registration(r1923,c63,s567). +registration(r1924,c94,s567). +registration(r1925,c169,s567). +registration(r1926,c38,s567). +registration(r1927,c131,s568). +registration(r1928,c67,s568). +registration(r1929,c3,s568). +registration(r1930,c141,s569). +registration(r1931,c105,s569). +registration(r1932,c124,s569). +registration(r1933,c13,s570). +registration(r1934,c132,s570). +registration(r1935,c63,s570). +registration(r1936,c67,s571). +registration(r1937,c75,s571). +registration(r1938,c72,s571). +registration(r1939,c138,s572). +registration(r1940,c214,s572). +registration(r1941,c240,s572). +registration(r1942,c48,s573). +registration(r1943,c170,s573). +registration(r1944,c15,s573). +registration(r1945,c180,s574). +registration(r1946,c186,s574). +registration(r1947,c20,s574). +registration(r1948,c93,s575). +registration(r1949,c69,s575). +registration(r1950,c88,s575). +registration(r1951,c44,s576). +registration(r1952,c230,s576). +registration(r1953,c73,s576). +registration(r1954,c134,s576). +registration(r1955,c175,s577). +registration(r1956,c119,s577). +registration(r1957,c206,s577). +registration(r1958,c14,s577). +registration(r1959,c214,s578). +registration(r1960,c255,s578). +registration(r1961,c162,s578). +registration(r1962,c77,s578). +registration(r1963,c77,s579). +registration(r1964,c103,s579). +registration(r1965,c30,s579). +registration(r1966,c33,s579). +registration(r1967,c187,s579). +registration(r1968,c14,s580). +registration(r1969,c144,s580). +registration(r1970,c255,s580). +registration(r1971,c197,s581). +registration(r1972,c145,s581). +registration(r1973,c80,s581). +registration(r1974,c253,s581). +registration(r1975,c149,s582). +registration(r1976,c172,s582). +registration(r1977,c246,s582). +registration(r1978,c5,s583). +registration(r1979,c188,s583). +registration(r1980,c131,s583). +registration(r1981,c96,s583). +registration(r1982,c52,s584). +registration(r1983,c174,s584). +registration(r1984,c14,s584). +registration(r1985,c17,s585). +registration(r1986,c188,s585). +registration(r1987,c0,s585). +registration(r1988,c144,s586). +registration(r1989,c203,s586). +registration(r1990,c48,s586). +registration(r1991,c195,s587). +registration(r1992,c74,s587). +registration(r1993,c160,s587). +registration(r1994,c54,s588). +registration(r1995,c109,s588). +registration(r1996,c191,s588). +registration(r1997,c197,s588). +registration(r1998,c86,s589). +registration(r1999,c157,s589). +registration(r2000,c201,s589). +registration(r2001,c254,s590). +registration(r2002,c101,s590). +registration(r2003,c109,s590). +registration(r2004,c126,s590). +registration(r2005,c86,s591). +registration(r2006,c50,s591). +registration(r2007,c74,s591). +registration(r2008,c195,s591). +registration(r2009,c82,s591). +registration(r2010,c189,s592). +registration(r2011,c166,s592). +registration(r2012,c20,s592). +registration(r2013,c72,s592). +registration(r2014,c209,s593). +registration(r2015,c125,s593). +registration(r2016,c65,s593). +registration(r2017,c91,s593). +registration(r2018,c84,s594). +registration(r2019,c111,s594). +registration(r2020,c247,s594). +registration(r2021,c37,s594). +registration(r2022,c28,s595). +registration(r2023,c139,s595). +registration(r2024,c195,s595). +registration(r2025,c64,s596). +registration(r2026,c13,s596). +registration(r2027,c240,s596). +registration(r2028,c179,s596). +registration(r2029,c160,s597). +registration(r2030,c127,s597). +registration(r2031,c112,s597). +registration(r2032,c121,s598). +registration(r2033,c144,s598). +registration(r2034,c105,s598). +registration(r2035,c173,s598). +registration(r2036,c219,s599). +registration(r2037,c38,s599). +registration(r2038,c7,s599). +registration(r2039,c150,s599). +registration(r2040,c78,s600). +registration(r2041,c187,s600). +registration(r2042,c85,s600). +registration(r2043,c24,s601). +registration(r2044,c35,s601). +registration(r2045,c4,s601). +registration(r2046,c245,s601). +registration(r2047,c227,s602). +registration(r2048,c93,s602). +registration(r2049,c169,s602). +registration(r2050,c27,s603). +registration(r2051,c204,s603). +registration(r2052,c115,s603). +registration(r2053,c222,s604). +registration(r2054,c224,s604). +registration(r2055,c106,s604). +registration(r2056,c146,s605). +registration(r2057,c147,s605). +registration(r2058,c235,s605). +registration(r2059,c144,s605). +registration(r2060,c227,s606). +registration(r2061,c232,s606). +registration(r2062,c164,s606). +registration(r2063,c0,s606). +registration(r2064,c47,s607). +registration(r2065,c90,s607). +registration(r2066,c247,s607). +registration(r2067,c61,s607). +registration(r2068,c207,s608). +registration(r2069,c193,s608). +registration(r2070,c51,s608). +registration(r2071,c167,s609). +registration(r2072,c128,s609). +registration(r2073,c235,s609). +registration(r2074,c86,s610). +registration(r2075,c16,s610). +registration(r2076,c29,s610). +registration(r2077,c8,s611). +registration(r2078,c18,s611). +registration(r2079,c55,s611). +registration(r2080,c29,s612). +registration(r2081,c232,s612). +registration(r2082,c32,s612). +registration(r2083,c176,s612). +registration(r2084,c119,s613). +registration(r2085,c168,s613). +registration(r2086,c116,s613). +registration(r2087,c69,s614). +registration(r2088,c119,s614). +registration(r2089,c49,s614). +registration(r2090,c5,s614). +registration(r2091,c176,s615). +registration(r2092,c241,s615). +registration(r2093,c95,s615). +registration(r2094,c70,s615). +registration(r2095,c46,s616). +registration(r2096,c49,s616). +registration(r2097,c19,s616). +registration(r2098,c73,s617). +registration(r2099,c121,s617). +registration(r2100,c54,s617). +registration(r2101,c86,s618). +registration(r2102,c133,s618). +registration(r2103,c18,s618). +registration(r2104,c186,s619). +registration(r2105,c27,s619). +registration(r2106,c177,s619). +registration(r2107,c41,s620). +registration(r2108,c235,s620). +registration(r2109,c144,s620). +registration(r2110,c196,s620). +registration(r2111,c31,s621). +registration(r2112,c37,s621). +registration(r2113,c85,s621). +registration(r2114,c130,s622). +registration(r2115,c152,s622). +registration(r2116,c169,s622). +registration(r2117,c242,s623). +registration(r2118,c50,s623). +registration(r2119,c15,s623). +registration(r2120,c102,s624). +registration(r2121,c223,s624). +registration(r2122,c166,s624). +registration(r2123,c219,s624). +registration(r2124,c39,s625). +registration(r2125,c142,s625). +registration(r2126,c25,s625). +registration(r2127,c5,s626). +registration(r2128,c26,s626). +registration(r2129,c230,s626). +registration(r2130,c6,s627). +registration(r2131,c239,s627). +registration(r2132,c175,s627). +registration(r2133,c50,s628). +registration(r2134,c6,s628). +registration(r2135,c45,s628). +registration(r2136,c31,s629). +registration(r2137,c29,s629). +registration(r2138,c239,s629). +registration(r2139,c85,s630). +registration(r2140,c89,s630). +registration(r2141,c90,s630). +registration(r2142,c186,s631). +registration(r2143,c137,s631). +registration(r2144,c196,s631). +registration(r2145,c121,s631). +registration(r2146,c217,s632). +registration(r2147,c43,s632). +registration(r2148,c97,s632). +registration(r2149,c104,s633). +registration(r2150,c147,s633). +registration(r2151,c55,s633). +registration(r2152,c106,s633). +registration(r2153,c220,s634). +registration(r2154,c68,s634). +registration(r2155,c85,s634). +registration(r2156,c114,s635). +registration(r2157,c172,s635). +registration(r2158,c222,s635). +registration(r2159,c1,s635). +registration(r2160,c126,s636). +registration(r2161,c99,s636). +registration(r2162,c108,s636). +registration(r2163,c47,s637). +registration(r2164,c13,s637). +registration(r2165,c0,s637). +registration(r2166,c44,s638). +registration(r2167,c12,s638). +registration(r2168,c140,s638). +registration(r2169,c31,s639). +registration(r2170,c236,s639). +registration(r2171,c75,s639). +registration(r2172,c39,s640). +registration(r2173,c123,s640). +registration(r2174,c171,s640). +registration(r2175,c29,s641). +registration(r2176,c143,s641). +registration(r2177,c190,s641). +registration(r2178,c245,s642). +registration(r2179,c192,s642). +registration(r2180,c244,s642). +registration(r2181,c227,s643). +registration(r2182,c144,s643). +registration(r2183,c8,s643). +registration(r2184,c240,s644). +registration(r2185,c16,s644). +registration(r2186,c73,s644). +registration(r2187,c189,s645). +registration(r2188,c155,s645). +registration(r2189,c176,s645). +registration(r2190,c210,s645). +registration(r2191,c48,s645). +registration(r2192,c77,s646). +registration(r2193,c176,s646). +registration(r2194,c20,s646). +registration(r2195,c206,s646). +registration(r2196,c235,s647). +registration(r2197,c16,s647). +registration(r2198,c53,s647). +registration(r2199,c42,s648). +registration(r2200,c66,s648). +registration(r2201,c205,s648). +registration(r2202,c211,s648). +registration(r2203,c240,s649). +registration(r2204,c15,s649). +registration(r2205,c197,s649). +registration(r2206,c88,s649). +registration(r2207,c197,s650). +registration(r2208,c21,s650). +registration(r2209,c222,s650). +registration(r2210,c175,s650). +registration(r2211,c124,s651). +registration(r2212,c79,s651). +registration(r2213,c254,s651). +registration(r2214,c100,s651). +registration(r2215,c250,s651). +registration(r2216,c8,s652). +registration(r2217,c23,s652). +registration(r2218,c13,s652). +registration(r2219,c222,s653). +registration(r2220,c103,s653). +registration(r2221,c55,s653). +registration(r2222,c11,s654). +registration(r2223,c129,s654). +registration(r2224,c102,s654). +registration(r2225,c71,s654). +registration(r2226,c114,s655). +registration(r2227,c138,s655). +registration(r2228,c44,s655). +registration(r2229,c163,s656). +registration(r2230,c167,s656). +registration(r2231,c24,s656). +registration(r2232,c247,s656). +registration(r2233,c77,s656). +registration(r2234,c92,s657). +registration(r2235,c66,s657). +registration(r2236,c73,s657). +registration(r2237,c85,s658). +registration(r2238,c163,s658). +registration(r2239,c78,s658). +registration(r2240,c136,s658). +registration(r2241,c223,s659). +registration(r2242,c128,s659). +registration(r2243,c146,s659). +registration(r2244,c173,s660). +registration(r2245,c166,s660). +registration(r2246,c76,s660). +registration(r2247,c48,s660). +registration(r2248,c168,s661). +registration(r2249,c153,s661). +registration(r2250,c29,s661). +registration(r2251,c61,s662). +registration(r2252,c72,s662). +registration(r2253,c202,s662). +registration(r2254,c12,s663). +registration(r2255,c213,s663). +registration(r2256,c9,s663). +registration(r2257,c172,s663). +registration(r2258,c180,s664). +registration(r2259,c94,s664). +registration(r2260,c184,s664). +registration(r2261,c56,s665). +registration(r2262,c207,s665). +registration(r2263,c157,s665). +registration(r2264,c124,s665). +registration(r2265,c108,s666). +registration(r2266,c156,s666). +registration(r2267,c118,s666). +registration(r2268,c16,s667). +registration(r2269,c4,s667). +registration(r2270,c149,s667). +registration(r2271,c220,s668). +registration(r2272,c140,s668). +registration(r2273,c205,s668). +registration(r2274,c163,s669). +registration(r2275,c137,s669). +registration(r2276,c253,s669). +registration(r2277,c177,s670). +registration(r2278,c43,s670). +registration(r2279,c239,s670). +registration(r2280,c39,s671). +registration(r2281,c189,s671). +registration(r2282,c7,s671). +registration(r2283,c77,s672). +registration(r2284,c180,s672). +registration(r2285,c214,s672). +registration(r2286,c26,s673). +registration(r2287,c212,s673). +registration(r2288,c159,s673). +registration(r2289,c226,s674). +registration(r2290,c138,s674). +registration(r2291,c35,s674). +registration(r2292,c189,s674). +registration(r2293,c84,s675). +registration(r2294,c150,s675). +registration(r2295,c187,s675). +registration(r2296,c205,s675). +registration(r2297,c77,s676). +registration(r2298,c188,s676). +registration(r2299,c91,s676). +registration(r2300,c23,s677). +registration(r2301,c191,s677). +registration(r2302,c44,s677). +registration(r2303,c223,s677). +registration(r2304,c39,s678). +registration(r2305,c208,s678). +registration(r2306,c122,s678). +registration(r2307,c26,s679). +registration(r2308,c240,s679). +registration(r2309,c60,s679). +registration(r2310,c96,s680). +registration(r2311,c174,s680). +registration(r2312,c136,s680). +registration(r2313,c1,s680). +registration(r2314,c216,s680). +registration(r2315,c35,s681). +registration(r2316,c235,s681). +registration(r2317,c69,s681). +registration(r2318,c160,s682). +registration(r2319,c41,s682). +registration(r2320,c140,s682). +registration(r2321,c183,s683). +registration(r2322,c9,s683). +registration(r2323,c245,s683). +registration(r2324,c197,s683). +registration(r2325,c17,s684). +registration(r2326,c114,s684). +registration(r2327,c106,s684). +registration(r2328,c98,s684). +registration(r2329,c41,s685). +registration(r2330,c223,s685). +registration(r2331,c6,s685). +registration(r2332,c36,s686). +registration(r2333,c216,s686). +registration(r2334,c134,s686). +registration(r2335,c114,s687). +registration(r2336,c65,s687). +registration(r2337,c109,s687). +registration(r2338,c226,s687). +registration(r2339,c167,s688). +registration(r2340,c153,s688). +registration(r2341,c127,s688). +registration(r2342,c118,s689). +registration(r2343,c246,s689). +registration(r2344,c210,s689). +registration(r2345,c68,s689). +registration(r2346,c167,s690). +registration(r2347,c52,s690). +registration(r2348,c169,s690). +registration(r2349,c136,s691). +registration(r2350,c84,s691). +registration(r2351,c52,s691). +registration(r2352,c12,s692). +registration(r2353,c119,s692). +registration(r2354,c117,s692). +registration(r2355,c234,s692). +registration(r2356,c118,s693). +registration(r2357,c5,s693). +registration(r2358,c154,s693). +registration(r2359,c173,s693). +registration(r2360,c142,s693). +registration(r2361,c11,s694). +registration(r2362,c214,s694). +registration(r2363,c4,s694). +registration(r2364,c169,s694). +registration(r2365,c10,s695). +registration(r2366,c239,s695). +registration(r2367,c230,s695). +registration(r2368,c53,s696). +registration(r2369,c157,s696). +registration(r2370,c31,s696). +registration(r2371,c16,s697). +registration(r2372,c3,s697). +registration(r2373,c222,s697). +registration(r2374,c231,s698). +registration(r2375,c113,s698). +registration(r2376,c47,s698). +registration(r2377,c201,s699). +registration(r2378,c108,s699). +registration(r2379,c35,s699). +registration(r2380,c47,s700). +registration(r2381,c210,s700). +registration(r2382,c255,s700). +registration(r2383,c123,s700). +registration(r2384,c60,s701). +registration(r2385,c107,s701). +registration(r2386,c39,s701). +registration(r2387,c94,s701). +registration(r2388,c25,s702). +registration(r2389,c35,s702). +registration(r2390,c231,s702). +registration(r2391,c234,s702). +registration(r2392,c201,s703). +registration(r2393,c186,s703). +registration(r2394,c98,s703). +registration(r2395,c146,s703). +registration(r2396,c14,s704). +registration(r2397,c165,s704). +registration(r2398,c92,s704). +registration(r2399,c88,s705). +registration(r2400,c118,s705). +registration(r2401,c248,s705). +registration(r2402,c117,s705). +registration(r2403,c166,s705). +registration(r2404,c181,s706). +registration(r2405,c102,s706). +registration(r2406,c16,s706). +registration(r2407,c19,s707). +registration(r2408,c59,s707). +registration(r2409,c252,s707). +registration(r2410,c230,s707). +registration(r2411,c104,s708). +registration(r2412,c13,s708). +registration(r2413,c176,s708). +registration(r2414,c113,s708). +registration(r2415,c81,s709). +registration(r2416,c3,s709). +registration(r2417,c112,s709). +registration(r2418,c235,s710). +registration(r2419,c189,s710). +registration(r2420,c183,s710). +registration(r2421,c227,s711). +registration(r2422,c214,s711). +registration(r2423,c224,s711). +registration(r2424,c72,s712). +registration(r2425,c155,s712). +registration(r2426,c106,s712). +registration(r2427,c175,s712). +registration(r2428,c40,s713). +registration(r2429,c227,s713). +registration(r2430,c199,s713). +registration(r2431,c76,s713). +registration(r2432,c192,s714). +registration(r2433,c111,s714). +registration(r2434,c69,s714). +registration(r2435,c194,s714). +registration(r2436,c144,s715). +registration(r2437,c183,s715). +registration(r2438,c170,s715). +registration(r2439,c99,s716). +registration(r2440,c221,s716). +registration(r2441,c45,s716). +registration(r2442,c15,s717). +registration(r2443,c209,s717). +registration(r2444,c66,s717). +registration(r2445,c172,s718). +registration(r2446,c131,s718). +registration(r2447,c26,s718). +registration(r2448,c254,s719). +registration(r2449,c25,s719). +registration(r2450,c188,s719). +registration(r2451,c125,s720). +registration(r2452,c187,s720). +registration(r2453,c52,s720). +registration(r2454,c126,s721). +registration(r2455,c46,s721). +registration(r2456,c53,s721). +registration(r2457,c171,s721). +registration(r2458,c140,s722). +registration(r2459,c135,s722). +registration(r2460,c216,s722). +registration(r2461,c231,s723). +registration(r2462,c165,s723). +registration(r2463,c125,s723). +registration(r2464,c41,s723). +registration(r2465,c195,s724). +registration(r2466,c45,s724). +registration(r2467,c123,s724). +registration(r2468,c149,s724). +registration(r2469,c44,s725). +registration(r2470,c119,s725). +registration(r2471,c133,s725). +registration(r2472,c185,s725). +registration(r2473,c72,s726). +registration(r2474,c175,s726). +registration(r2475,c55,s726). +registration(r2476,c97,s727). +registration(r2477,c33,s727). +registration(r2478,c142,s727). +registration(r2479,c102,s728). +registration(r2480,c194,s728). +registration(r2481,c230,s728). +registration(r2482,c99,s729). +registration(r2483,c141,s729). +registration(r2484,c123,s729). +registration(r2485,c169,s730). +registration(r2486,c9,s730). +registration(r2487,c192,s730). +registration(r2488,c236,s731). +registration(r2489,c76,s731). +registration(r2490,c35,s731). +registration(r2491,c220,s732). +registration(r2492,c223,s732). +registration(r2493,c45,s732). +registration(r2494,c85,s732). +registration(r2495,c117,s732). +registration(r2496,c119,s733). +registration(r2497,c159,s733). +registration(r2498,c99,s733). +registration(r2499,c4,s733). +registration(r2500,c7,s733). +registration(r2501,c82,s734). +registration(r2502,c144,s734). +registration(r2503,c106,s734). +registration(r2504,c248,s734). +registration(r2505,c47,s735). +registration(r2506,c181,s735). +registration(r2507,c2,s735). +registration(r2508,c161,s736). +registration(r2509,c220,s736). +registration(r2510,c214,s736). +registration(r2511,c85,s737). +registration(r2512,c162,s737). +registration(r2513,c81,s737). +registration(r2514,c168,s738). +registration(r2515,c147,s738). +registration(r2516,c43,s738). +registration(r2517,c50,s738). +registration(r2518,c64,s739). +registration(r2519,c55,s739). +registration(r2520,c183,s739). +registration(r2521,c70,s740). +registration(r2522,c177,s740). +registration(r2523,c105,s740). +registration(r2524,c152,s741). +registration(r2525,c6,s741). +registration(r2526,c173,s741). +registration(r2527,c78,s742). +registration(r2528,c101,s742). +registration(r2529,c105,s742). +registration(r2530,c216,s742). +registration(r2531,c181,s743). +registration(r2532,c41,s743). +registration(r2533,c66,s743). +registration(r2534,c213,s744). +registration(r2535,c150,s744). +registration(r2536,c242,s744). +registration(r2537,c39,s744). +registration(r2538,c63,s744). +registration(r2539,c222,s745). +registration(r2540,c120,s745). +registration(r2541,c201,s745). +registration(r2542,c41,s745). +registration(r2543,c118,s746). +registration(r2544,c212,s746). +registration(r2545,c203,s746). +registration(r2546,c84,s747). +registration(r2547,c14,s747). +registration(r2548,c207,s747). +registration(r2549,c226,s748). +registration(r2550,c144,s748). +registration(r2551,c53,s748). +registration(r2552,c119,s749). +registration(r2553,c3,s749). +registration(r2554,c142,s749). +registration(r2555,c127,s750). +registration(r2556,c85,s750). +registration(r2557,c195,s750). +registration(r2558,c160,s751). +registration(r2559,c42,s751). +registration(r2560,c95,s751). +registration(r2561,c146,s752). +registration(r2562,c59,s752). +registration(r2563,c41,s752). +registration(r2564,c171,s753). +registration(r2565,c180,s753). +registration(r2566,c199,s753). +registration(r2567,c62,s754). +registration(r2568,c94,s754). +registration(r2569,c254,s754). +registration(r2570,c186,s755). +registration(r2571,c236,s755). +registration(r2572,c249,s755). +registration(r2573,c149,s756). +registration(r2574,c200,s756). +registration(r2575,c141,s756). +registration(r2576,c36,s757). +registration(r2577,c248,s757). +registration(r2578,c165,s757). +registration(r2579,c250,s758). +registration(r2580,c21,s758). +registration(r2581,c249,s758). +registration(r2582,c116,s758). +registration(r2583,c208,s759). +registration(r2584,c40,s759). +registration(r2585,c122,s759). +registration(r2586,c185,s760). +registration(r2587,c168,s760). +registration(r2588,c147,s760). +registration(r2589,c158,s760). +registration(r2590,c25,s761). +registration(r2591,c153,s761). +registration(r2592,c151,s761). +registration(r2593,c95,s761). +registration(r2594,c226,s762). +registration(r2595,c133,s762). +registration(r2596,c217,s762). +registration(r2597,c125,s762). +registration(r2598,c137,s763). +registration(r2599,c60,s763). +registration(r2600,c122,s763). +registration(r2601,c159,s764). +registration(r2602,c20,s764). +registration(r2603,c233,s764). +registration(r2604,c100,s765). +registration(r2605,c187,s765). +registration(r2606,c212,s765). +registration(r2607,c99,s765). +registration(r2608,c74,s766). +registration(r2609,c3,s766). +registration(r2610,c184,s766). +registration(r2611,c80,s767). +registration(r2612,c183,s767). +registration(r2613,c202,s767). +registration(r2614,c80,s768). +registration(r2615,c138,s768). +registration(r2616,c160,s768). +registration(r2617,c41,s768). +registration(r2618,c11,s769). +registration(r2619,c132,s769). +registration(r2620,c201,s769). +registration(r2621,c222,s769). +registration(r2622,c44,s770). +registration(r2623,c147,s770). +registration(r2624,c27,s770). +registration(r2625,c239,s771). +registration(r2626,c173,s771). +registration(r2627,c178,s771). +registration(r2628,c182,s772). +registration(r2629,c16,s772). +registration(r2630,c93,s772). +registration(r2631,c20,s773). +registration(r2632,c30,s773). +registration(r2633,c16,s773). +registration(r2634,c155,s774). +registration(r2635,c77,s774). +registration(r2636,c60,s774). +registration(r2637,c73,s775). +registration(r2638,c40,s775). +registration(r2639,c65,s775). +registration(r2640,c30,s776). +registration(r2641,c185,s776). +registration(r2642,c223,s776). +registration(r2643,c46,s777). +registration(r2644,c41,s777). +registration(r2645,c247,s777). +registration(r2646,c239,s778). +registration(r2647,c152,s778). +registration(r2648,c146,s778). +registration(r2649,c244,s779). +registration(r2650,c96,s779). +registration(r2651,c10,s779). +registration(r2652,c15,s779). +registration(r2653,c160,s780). +registration(r2654,c92,s780). +registration(r2655,c182,s780). +registration(r2656,c255,s781). +registration(r2657,c109,s781). +registration(r2658,c20,s781). +registration(r2659,c52,s782). +registration(r2660,c69,s782). +registration(r2661,c153,s782). +registration(r2662,c199,s783). +registration(r2663,c152,s783). +registration(r2664,c132,s783). +registration(r2665,c115,s783). +registration(r2666,c65,s784). +registration(r2667,c175,s784). +registration(r2668,c193,s784). +registration(r2669,c162,s784). +registration(r2670,c55,s784). +registration(r2671,c168,s785). +registration(r2672,c48,s785). +registration(r2673,c177,s785). +registration(r2674,c102,s786). +registration(r2675,c142,s786). +registration(r2676,c96,s786). +registration(r2677,c118,s787). +registration(r2678,c242,s787). +registration(r2679,c180,s787). +registration(r2680,c77,s788). +registration(r2681,c25,s788). +registration(r2682,c197,s788). +registration(r2683,c178,s788). +registration(r2684,c189,s789). +registration(r2685,c205,s789). +registration(r2686,c191,s789). +registration(r2687,c129,s790). +registration(r2688,c45,s790). +registration(r2689,c31,s790). +registration(r2690,c200,s791). +registration(r2691,c212,s791). +registration(r2692,c21,s791). +registration(r2693,c97,s791). +registration(r2694,c159,s792). +registration(r2695,c195,s792). +registration(r2696,c227,s792). +registration(r2697,c213,s793). +registration(r2698,c80,s793). +registration(r2699,c228,s793). +registration(r2700,c157,s793). +registration(r2701,c209,s794). +registration(r2702,c178,s794). +registration(r2703,c174,s794). +registration(r2704,c112,s794). +registration(r2705,c219,s795). +registration(r2706,c112,s795). +registration(r2707,c250,s795). +registration(r2708,c25,s796). +registration(r2709,c0,s796). +registration(r2710,c4,s796). +registration(r2711,c25,s797). +registration(r2712,c243,s797). +registration(r2713,c54,s797). +registration(r2714,c248,s798). +registration(r2715,c121,s798). +registration(r2716,c46,s798). +registration(r2717,c79,s798). +registration(r2718,c22,s799). +registration(r2719,c92,s799). +registration(r2720,c30,s799). +registration(r2721,c46,s799). +registration(r2722,c195,s800). +registration(r2723,c72,s800). +registration(r2724,c65,s800). +registration(r2725,c178,s800). +registration(r2726,c59,s801). +registration(r2727,c130,s801). +registration(r2728,c81,s801). +registration(r2729,c84,s802). +registration(r2730,c55,s802). +registration(r2731,c88,s802). +registration(r2732,c141,s802). +registration(r2733,c4,s803). +registration(r2734,c190,s803). +registration(r2735,c132,s803). +registration(r2736,c182,s804). +registration(r2737,c205,s804). +registration(r2738,c106,s804). +registration(r2739,c135,s804). +registration(r2740,c224,s805). +registration(r2741,c85,s805). +registration(r2742,c89,s805). +registration(r2743,c155,s806). +registration(r2744,c229,s806). +registration(r2745,c195,s806). +registration(r2746,c68,s806). +registration(r2747,c159,s807). +registration(r2748,c117,s807). +registration(r2749,c200,s807). +registration(r2750,c30,s808). +registration(r2751,c98,s808). +registration(r2752,c216,s808). +registration(r2753,c150,s809). +registration(r2754,c47,s809). +registration(r2755,c229,s809). +registration(r2756,c179,s810). +registration(r2757,c238,s810). +registration(r2758,c178,s810). +registration(r2759,c148,s811). +registration(r2760,c50,s811). +registration(r2761,c208,s811). +registration(r2762,c107,s812). +registration(r2763,c29,s812). +registration(r2764,c149,s812). +registration(r2765,c218,s813). +registration(r2766,c88,s813). +registration(r2767,c180,s813). +registration(r2768,c98,s814). +registration(r2769,c193,s814). +registration(r2770,c174,s814). +registration(r2771,c22,s815). +registration(r2772,c209,s815). +registration(r2773,c156,s815). +registration(r2774,c131,s816). +registration(r2775,c175,s816). +registration(r2776,c66,s816). +registration(r2777,c186,s817). +registration(r2778,c203,s817). +registration(r2779,c189,s817). +registration(r2780,c141,s817). +registration(r2781,c245,s818). +registration(r2782,c33,s818). +registration(r2783,c36,s818). +registration(r2784,c254,s819). +registration(r2785,c7,s819). +registration(r2786,c22,s819). +registration(r2787,c120,s820). +registration(r2788,c98,s820). +registration(r2789,c3,s820). +registration(r2790,c25,s821). +registration(r2791,c134,s821). +registration(r2792,c108,s821). +registration(r2793,c218,s821). +registration(r2794,c196,s822). +registration(r2795,c29,s822). +registration(r2796,c39,s822). +registration(r2797,c242,s823). +registration(r2798,c14,s823). +registration(r2799,c98,s823). +registration(r2800,c87,s824). +registration(r2801,c25,s824). +registration(r2802,c193,s824). +registration(r2803,c122,s824). +registration(r2804,c14,s825). +registration(r2805,c144,s825). +registration(r2806,c98,s825). +registration(r2807,c197,s825). +registration(r2808,c102,s826). +registration(r2809,c188,s826). +registration(r2810,c148,s826). +registration(r2811,c0,s827). +registration(r2812,c149,s827). +registration(r2813,c29,s827). +registration(r2814,c58,s828). +registration(r2815,c23,s828). +registration(r2816,c170,s828). +registration(r2817,c10,s828). +registration(r2818,c115,s829). +registration(r2819,c2,s829). +registration(r2820,c85,s829). +registration(r2821,c23,s829). +registration(r2822,c209,s830). +registration(r2823,c148,s830). +registration(r2824,c215,s830). +registration(r2825,c56,s830). +registration(r2826,c66,s831). +registration(r2827,c45,s831). +registration(r2828,c253,s831). +registration(r2829,c146,s832). +registration(r2830,c40,s832). +registration(r2831,c44,s832). +registration(r2832,c72,s833). +registration(r2833,c132,s833). +registration(r2834,c22,s833). +registration(r2835,c193,s834). +registration(r2836,c147,s834). +registration(r2837,c166,s834). +registration(r2838,c169,s834). +registration(r2839,c206,s835). +registration(r2840,c210,s835). +registration(r2841,c194,s835). +registration(r2842,c89,s836). +registration(r2843,c188,s836). +registration(r2844,c131,s836). +registration(r2845,c198,s837). +registration(r2846,c171,s837). +registration(r2847,c242,s837). +registration(r2848,c132,s838). +registration(r2849,c151,s838). +registration(r2850,c194,s838). +registration(r2851,c83,s838). +registration(r2852,c156,s838). +registration(r2853,c107,s839). +registration(r2854,c140,s839). +registration(r2855,c55,s839). +registration(r2856,c31,s839). +registration(r2857,c166,s840). +registration(r2858,c39,s840). +registration(r2859,c135,s840). +registration(r2860,c76,s841). +registration(r2861,c89,s841). +registration(r2862,c159,s841). +registration(r2863,c34,s841). +registration(r2864,c36,s842). +registration(r2865,c9,s842). +registration(r2866,c233,s842). +registration(r2867,c87,s843). +registration(r2868,c103,s843). +registration(r2869,c130,s843). +registration(r2870,c154,s843). +registration(r2871,c67,s844). +registration(r2872,c50,s844). +registration(r2873,c53,s844). +registration(r2874,c108,s845). +registration(r2875,c220,s845). +registration(r2876,c222,s845). +registration(r2877,c6,s846). +registration(r2878,c211,s846). +registration(r2879,c247,s846). +registration(r2880,c32,s846). +registration(r2881,c159,s847). +registration(r2882,c197,s847). +registration(r2883,c100,s847). +registration(r2884,c111,s848). +registration(r2885,c170,s848). +registration(r2886,c187,s848). +registration(r2887,c32,s848). +registration(r2888,c237,s849). +registration(r2889,c241,s849). +registration(r2890,c73,s849). +registration(r2891,c123,s850). +registration(r2892,c187,s850). +registration(r2893,c229,s850). +registration(r2894,c193,s850). +registration(r2895,c24,s851). +registration(r2896,c115,s851). +registration(r2897,c69,s851). +registration(r2898,c71,s851). +registration(r2899,c31,s852). +registration(r2900,c101,s852). +registration(r2901,c141,s852). +registration(r2902,c242,s852). +registration(r2903,c128,s853). +registration(r2904,c20,s853). +registration(r2905,c98,s853). +registration(r2906,c207,s853). +registration(r2907,c45,s854). +registration(r2908,c240,s854). +registration(r2909,c186,s854). +registration(r2910,c58,s854). +registration(r2911,c83,s855). +registration(r2912,c182,s855). +registration(r2913,c251,s855). +registration(r2914,c35,s856). +registration(r2915,c251,s856). +registration(r2916,c8,s856). +registration(r2917,c39,s857). +registration(r2918,c220,s857). +registration(r2919,c124,s857). +registration(r2920,c9,s858). +registration(r2921,c5,s858). +registration(r2922,c109,s858). +registration(r2923,c128,s859). +registration(r2924,c93,s859). +registration(r2925,c177,s859). +registration(r2926,c221,s859). +registration(r2927,c63,s860). +registration(r2928,c230,s860). +registration(r2929,c252,s860). +registration(r2930,c79,s860). +registration(r2931,c47,s861). +registration(r2932,c35,s861). +registration(r2933,c137,s861). +registration(r2934,c72,s861). +registration(r2935,c40,s862). +registration(r2936,c221,s862). +registration(r2937,c195,s862). +registration(r2938,c64,s863). +registration(r2939,c151,s863). +registration(r2940,c250,s863). +registration(r2941,c102,s864). +registration(r2942,c68,s864). +registration(r2943,c34,s864). +registration(r2944,c210,s865). +registration(r2945,c54,s865). +registration(r2946,c205,s865). +registration(r2947,c180,s866). +registration(r2948,c171,s866). +registration(r2949,c239,s866). +registration(r2950,c31,s867). +registration(r2951,c0,s867). +registration(r2952,c133,s867). +registration(r2953,c8,s868). +registration(r2954,c103,s868). +registration(r2955,c37,s868). +registration(r2956,c222,s869). +registration(r2957,c13,s869). +registration(r2958,c77,s869). +registration(r2959,c234,s870). +registration(r2960,c63,s870). +registration(r2961,c155,s870). +registration(r2962,c38,s870). +registration(r2963,c223,s871). +registration(r2964,c93,s871). +registration(r2965,c12,s871). +registration(r2966,c192,s872). +registration(r2967,c60,s872). +registration(r2968,c196,s872). +registration(r2969,c226,s873). +registration(r2970,c157,s873). +registration(r2971,c189,s873). +registration(r2972,c229,s873). +registration(r2973,c135,s874). +registration(r2974,c9,s874). +registration(r2975,c148,s874). +registration(r2976,c160,s875). +registration(r2977,c139,s875). +registration(r2978,c193,s875). +registration(r2979,c0,s876). +registration(r2980,c147,s876). +registration(r2981,c130,s876). +registration(r2982,c209,s876). +registration(r2983,c132,s877). +registration(r2984,c220,s877). +registration(r2985,c242,s877). +registration(r2986,c46,s878). +registration(r2987,c28,s878). +registration(r2988,c60,s878). +registration(r2989,c216,s879). +registration(r2990,c36,s879). +registration(r2991,c31,s879). +registration(r2992,c167,s880). +registration(r2993,c199,s880). +registration(r2994,c126,s880). +registration(r2995,c31,s881). +registration(r2996,c114,s881). +registration(r2997,c111,s881). +registration(r2998,c232,s881). +registration(r2999,c169,s882). +registration(r3000,c106,s882). +registration(r3001,c150,s882). +registration(r3002,c27,s883). +registration(r3003,c87,s883). +registration(r3004,c192,s883). +registration(r3005,c238,s884). +registration(r3006,c144,s884). +registration(r3007,c47,s884). +registration(r3008,c8,s885). +registration(r3009,c123,s885). +registration(r3010,c176,s885). +registration(r3011,c87,s886). +registration(r3012,c142,s886). +registration(r3013,c230,s886). +registration(r3014,c6,s887). +registration(r3015,c175,s887). +registration(r3016,c172,s887). +registration(r3017,c150,s887). +registration(r3018,c199,s887). +registration(r3019,c2,s888). +registration(r3020,c180,s888). +registration(r3021,c65,s888). +registration(r3022,c151,s889). +registration(r3023,c142,s889). +registration(r3024,c67,s889). +registration(r3025,c213,s890). +registration(r3026,c187,s890). +registration(r3027,c211,s890). +registration(r3028,c79,s891). +registration(r3029,c20,s891). +registration(r3030,c139,s891). +registration(r3031,c24,s892). +registration(r3032,c157,s892). +registration(r3033,c169,s892). +registration(r3034,c87,s893). +registration(r3035,c2,s893). +registration(r3036,c192,s893). +registration(r3037,c135,s893). +registration(r3038,c241,s894). +registration(r3039,c211,s894). +registration(r3040,c198,s894). +registration(r3041,c95,s895). +registration(r3042,c79,s895). +registration(r3043,c232,s895). +registration(r3044,c189,s896). +registration(r3045,c167,s896). +registration(r3046,c161,s896). +registration(r3047,c107,s896). +registration(r3048,c54,s897). +registration(r3049,c247,s897). +registration(r3050,c168,s897). +registration(r3051,c69,s897). +registration(r3052,c75,s898). +registration(r3053,c102,s898). +registration(r3054,c232,s898). +registration(r3055,c168,s899). +registration(r3056,c145,s899). +registration(r3057,c135,s899). +registration(r3058,c130,s899). +registration(r3059,c246,s900). +registration(r3060,c68,s900). +registration(r3061,c0,s900). +registration(r3062,c232,s901). +registration(r3063,c66,s901). +registration(r3064,c99,s901). +registration(r3065,c5,s902). +registration(r3066,c201,s902). +registration(r3067,c87,s902). +registration(r3068,c78,s903). +registration(r3069,c161,s903). +registration(r3070,c163,s903). +registration(r3071,c237,s904). +registration(r3072,c195,s904). +registration(r3073,c207,s904). +registration(r3074,c118,s904). +registration(r3075,c35,s905). +registration(r3076,c182,s905). +registration(r3077,c166,s905). +registration(r3078,c156,s905). +registration(r3079,c235,s906). +registration(r3080,c18,s906). +registration(r3081,c243,s906). +registration(r3082,c54,s907). +registration(r3083,c227,s907). +registration(r3084,c161,s907). +registration(r3085,c233,s907). +registration(r3086,c120,s908). +registration(r3087,c225,s908). +registration(r3088,c105,s908). +registration(r3089,c12,s909). +registration(r3090,c38,s909). +registration(r3091,c107,s909). +registration(r3092,c57,s910). +registration(r3093,c139,s910). +registration(r3094,c23,s910). +registration(r3095,c205,s911). +registration(r3096,c88,s911). +registration(r3097,c84,s911). +registration(r3098,c63,s912). +registration(r3099,c242,s912). +registration(r3100,c233,s912). +registration(r3101,c32,s913). +registration(r3102,c163,s913). +registration(r3103,c142,s913). +registration(r3104,c248,s914). +registration(r3105,c184,s914). +registration(r3106,c107,s914). +registration(r3107,c239,s915). +registration(r3108,c110,s915). +registration(r3109,c166,s915). +registration(r3110,c145,s916). +registration(r3111,c147,s916). +registration(r3112,c243,s916). +registration(r3113,c161,s917). +registration(r3114,c118,s917). +registration(r3115,c156,s917). +registration(r3116,c147,s918). +registration(r3117,c53,s918). +registration(r3118,c74,s918). +registration(r3119,c55,s919). +registration(r3120,c157,s919). +registration(r3121,c152,s919). +registration(r3122,c36,s920). +registration(r3123,c191,s920). +registration(r3124,c152,s920). +registration(r3125,c24,s920). +registration(r3126,c128,s921). +registration(r3127,c145,s921). +registration(r3128,c191,s921). +registration(r3129,c80,s922). +registration(r3130,c108,s922). +registration(r3131,c237,s922). +registration(r3132,c143,s923). +registration(r3133,c112,s923). +registration(r3134,c76,s923). +registration(r3135,c224,s924). +registration(r3136,c186,s924). +registration(r3137,c17,s924). +registration(r3138,c72,s925). +registration(r3139,c251,s925). +registration(r3140,c74,s925). +registration(r3141,c217,s925). +registration(r3142,c205,s926). +registration(r3143,c114,s926). +registration(r3144,c255,s926). +registration(r3145,c127,s927). +registration(r3146,c128,s927). +registration(r3147,c74,s927). +registration(r3148,c155,s928). +registration(r3149,c197,s928). +registration(r3150,c102,s928). +registration(r3151,c246,s929). +registration(r3152,c6,s929). +registration(r3153,c194,s929). +registration(r3154,c163,s930). +registration(r3155,c54,s930). +registration(r3156,c224,s930). +registration(r3157,c232,s930). +registration(r3158,c253,s930). +registration(r3159,c50,s931). +registration(r3160,c57,s931). +registration(r3161,c216,s931). +registration(r3162,c75,s931). +registration(r3163,c160,s932). +registration(r3164,c245,s932). +registration(r3165,c213,s932). +registration(r3166,c116,s932). +registration(r3167,c119,s932). +registration(r3168,c239,s933). +registration(r3169,c189,s933). +registration(r3170,c60,s933). +registration(r3171,c178,s934). +registration(r3172,c76,s934). +registration(r3173,c90,s934). +registration(r3174,c41,s935). +registration(r3175,c24,s935). +registration(r3176,c255,s935). +registration(r3177,c27,s935). +registration(r3178,c51,s936). +registration(r3179,c23,s936). +registration(r3180,c27,s936). +registration(r3181,c187,s937). +registration(r3182,c114,s937). +registration(r3183,c57,s937). +registration(r3184,c16,s938). +registration(r3185,c123,s938). +registration(r3186,c221,s938). +registration(r3187,c243,s938). +registration(r3188,c240,s939). +registration(r3189,c47,s939). +registration(r3190,c35,s939). +registration(r3191,c112,s940). +registration(r3192,c158,s940). +registration(r3193,c86,s940). +registration(r3194,c111,s941). +registration(r3195,c55,s941). +registration(r3196,c209,s941). +registration(r3197,c4,s941). +registration(r3198,c161,s942). +registration(r3199,c58,s942). +registration(r3200,c113,s942). +registration(r3201,c227,s943). +registration(r3202,c202,s943). +registration(r3203,c81,s943). +registration(r3204,c205,s944). +registration(r3205,c41,s944). +registration(r3206,c14,s944). +registration(r3207,c255,s945). +registration(r3208,c239,s945). +registration(r3209,c25,s945). +registration(r3210,c138,s946). +registration(r3211,c225,s946). +registration(r3212,c40,s946). +registration(r3213,c152,s947). +registration(r3214,c250,s947). +registration(r3215,c121,s947). +registration(r3216,c26,s947). +registration(r3217,c195,s948). +registration(r3218,c85,s948). +registration(r3219,c240,s948). +registration(r3220,c212,s949). +registration(r3221,c31,s949). +registration(r3222,c158,s949). +registration(r3223,c252,s949). +registration(r3224,c73,s950). +registration(r3225,c10,s950). +registration(r3226,c44,s950). +registration(r3227,c28,s950). +registration(r3228,c89,s951). +registration(r3229,c76,s951). +registration(r3230,c238,s951). +registration(r3231,c22,s951). +registration(r3232,c167,s952). +registration(r3233,c216,s952). +registration(r3234,c175,s952). +registration(r3235,c209,s953). +registration(r3236,c188,s953). +registration(r3237,c208,s953). +registration(r3238,c192,s953). +registration(r3239,c234,s954). +registration(r3240,c94,s954). +registration(r3241,c150,s954). +registration(r3242,c253,s954). +registration(r3243,c6,s955). +registration(r3244,c105,s955). +registration(r3245,c255,s955). +registration(r3246,c149,s955). +registration(r3247,c27,s956). +registration(r3248,c177,s956). +registration(r3249,c153,s956). +registration(r3250,c125,s957). +registration(r3251,c151,s957). +registration(r3252,c183,s957). +registration(r3253,c109,s957). +registration(r3254,c198,s958). +registration(r3255,c192,s958). +registration(r3256,c55,s958). +registration(r3257,c205,s959). +registration(r3258,c149,s959). +registration(r3259,c84,s959). +registration(r3260,c235,s960). +registration(r3261,c193,s960). +registration(r3262,c241,s960). +registration(r3263,c90,s961). +registration(r3264,c161,s961). +registration(r3265,c217,s961). +registration(r3266,c244,s962). +registration(r3267,c159,s962). +registration(r3268,c120,s962). +registration(r3269,c247,s963). +registration(r3270,c243,s963). +registration(r3271,c245,s963). +registration(r3272,c98,s963). +registration(r3273,c226,s964). +registration(r3274,c37,s964). +registration(r3275,c148,s964). +registration(r3276,c97,s965). +registration(r3277,c251,s965). +registration(r3278,c13,s965). +registration(r3279,c239,s965). +registration(r3280,c219,s966). +registration(r3281,c225,s966). +registration(r3282,c153,s966). +registration(r3283,c59,s967). +registration(r3284,c125,s967). +registration(r3285,c42,s967). +registration(r3286,c114,s967). +registration(r3287,c149,s968). +registration(r3288,c207,s968). +registration(r3289,c10,s968). +registration(r3290,c1,s969). +registration(r3291,c169,s969). +registration(r3292,c40,s969). +registration(r3293,c77,s970). +registration(r3294,c242,s970). +registration(r3295,c239,s970). +registration(r3296,c84,s970). +registration(r3297,c19,s971). +registration(r3298,c109,s971). +registration(r3299,c220,s971). +registration(r3300,c72,s971). +registration(r3301,c166,s972). +registration(r3302,c236,s972). +registration(r3303,c249,s972). +registration(r3304,c35,s973). +registration(r3305,c253,s973). +registration(r3306,c217,s973). +registration(r3307,c169,s974). +registration(r3308,c249,s974). +registration(r3309,c31,s974). +registration(r3310,c200,s975). +registration(r3311,c149,s975). +registration(r3312,c87,s975). +registration(r3313,c75,s976). +registration(r3314,c68,s976). +registration(r3315,c233,s976). +registration(r3316,c253,s976). +registration(r3317,c12,s977). +registration(r3318,c14,s977). +registration(r3319,c9,s977). +registration(r3320,c176,s978). +registration(r3321,c64,s978). +registration(r3322,c196,s978). +registration(r3323,c232,s979). +registration(r3324,c143,s979). +registration(r3325,c131,s979). +registration(r3326,c45,s979). +registration(r3327,c208,s980). +registration(r3328,c67,s980). +registration(r3329,c155,s980). +registration(r3330,c48,s980). +registration(r3331,c35,s981). +registration(r3332,c96,s981). +registration(r3333,c20,s981). +registration(r3334,c254,s982). +registration(r3335,c13,s982). +registration(r3336,c213,s982). +registration(r3337,c226,s982). +registration(r3338,c5,s983). +registration(r3339,c112,s983). +registration(r3340,c174,s983). +registration(r3341,c114,s984). +registration(r3342,c71,s984). +registration(r3343,c90,s984). +registration(r3344,c223,s985). +registration(r3345,c49,s985). +registration(r3346,c250,s985). +registration(r3347,c1,s985). +registration(r3348,c169,s986). +registration(r3349,c204,s986). +registration(r3350,c74,s986). +registration(r3351,c170,s987). +registration(r3352,c239,s987). +registration(r3353,c94,s987). +registration(r3354,c108,s988). +registration(r3355,c37,s988). +registration(r3356,c233,s988). +registration(r3357,c238,s988). +registration(r3358,c246,s989). +registration(r3359,c182,s989). +registration(r3360,c162,s989). +registration(r3361,c234,s989). +registration(r3362,c1,s990). +registration(r3363,c132,s990). +registration(r3364,c195,s990). +registration(r3365,c190,s991). +registration(r3366,c238,s991). +registration(r3367,c181,s991). +registration(r3368,c131,s992). +registration(r3369,c70,s992). +registration(r3370,c113,s992). +registration(r3371,c97,s993). +registration(r3372,c211,s993). +registration(r3373,c65,s993). +registration(r3374,c103,s994). +registration(r3375,c56,s994). +registration(r3376,c199,s994). +registration(r3377,c189,s994). +registration(r3378,c39,s995). +registration(r3379,c203,s995). +registration(r3380,c101,s995). +registration(r3381,c102,s996). +registration(r3382,c214,s996). +registration(r3383,c122,s996). +registration(r3384,c56,s997). +registration(r3385,c53,s997). +registration(r3386,c68,s997). +registration(r3387,c199,s998). +registration(r3388,c123,s998). +registration(r3389,c62,s998). +registration(r3390,c159,s999). +registration(r3391,c14,s999). +registration(r3392,c176,s999). +registration(r3393,c23,s1000). +registration(r3394,c40,s1000). +registration(r3395,c21,s1000). +registration(r3396,c212,s1001). +registration(r3397,c175,s1001). +registration(r3398,c25,s1001). +registration(r3399,c208,s1001). +registration(r3400,c160,s1002). +registration(r3401,c216,s1002). +registration(r3402,c74,s1002). +registration(r3403,c132,s1003). +registration(r3404,c29,s1003). +registration(r3405,c168,s1003). +registration(r3406,c110,s1004). +registration(r3407,c53,s1004). +registration(r3408,c40,s1004). +registration(r3409,c200,s1005). +registration(r3410,c183,s1005). +registration(r3411,c83,s1005). +registration(r3412,c107,s1005). +registration(r3413,c223,s1006). +registration(r3414,c29,s1006). +registration(r3415,c244,s1006). +registration(r3416,c240,s1006). +registration(r3417,c72,s1007). +registration(r3418,c42,s1007). +registration(r3419,c168,s1007). +registration(r3420,c203,s1007). +registration(r3421,c101,s1008). +registration(r3422,c179,s1008). +registration(r3423,c228,s1008). +registration(r3424,c139,s1009). +registration(r3425,c162,s1009). +registration(r3426,c187,s1009). +registration(r3427,c228,s1010). +registration(r3428,c163,s1010). +registration(r3429,c122,s1010). +registration(r3430,c208,s1011). +registration(r3431,c100,s1011). +registration(r3432,c99,s1011). +registration(r3433,c129,s1012). +registration(r3434,c48,s1012). +registration(r3435,c115,s1012). +registration(r3436,c187,s1013). +registration(r3437,c157,s1013). +registration(r3438,c124,s1013). +registration(r3439,c253,s1014). +registration(r3440,c58,s1014). +registration(r3441,c28,s1014). +registration(r3442,c236,s1014). +registration(r3443,c108,s1015). +registration(r3444,c198,s1015). +registration(r3445,c168,s1015). +registration(r3446,c141,s1016). +registration(r3447,c9,s1016). +registration(r3448,c26,s1016). +registration(r3449,c234,s1017). +registration(r3450,c158,s1017). +registration(r3451,c201,s1017). +registration(r3452,c227,s1017). +registration(r3453,c87,s1018). +registration(r3454,c86,s1018). +registration(r3455,c191,s1018). +registration(r3456,c18,s1018). +registration(r3457,c170,s1019). +registration(r3458,c231,s1019). +registration(r3459,c198,s1019). +registration(r3460,c227,s1019). +registration(r3461,c137,s1020). +registration(r3462,c69,s1020). +registration(r3463,c209,s1020). +registration(r3464,c121,s1020). +registration(r3465,c92,s1021). +registration(r3466,c169,s1021). +registration(r3467,c6,s1021). +registration(r3468,c65,s1022). +registration(r3469,c204,s1022). +registration(r3470,c172,s1022). +registration(r3471,c211,s1023). +registration(r3472,c195,s1023). +registration(r3473,c227,s1023). +registration(r3474,c26,s1023). +registration(r3475,c88,s1024). +registration(r3476,c45,s1024). +registration(r3477,c0,s1024). +registration(r3478,c21,s1024). +registration(r3479,c171,s1025). +registration(r3480,c54,s1025). +registration(r3481,c172,s1025). +registration(r3482,c125,s1026). +registration(r3483,c42,s1026). +registration(r3484,c136,s1026). +registration(r3485,c48,s1027). +registration(r3486,c254,s1027). +registration(r3487,c236,s1027). +registration(r3488,c186,s1028). +registration(r3489,c159,s1028). +registration(r3490,c31,s1028). +registration(r3491,c228,s1029). +registration(r3492,c52,s1029). +registration(r3493,c158,s1029). +registration(r3494,c247,s1030). +registration(r3495,c44,s1030). +registration(r3496,c215,s1030). +registration(r3497,c160,s1031). +registration(r3498,c166,s1031). +registration(r3499,c119,s1031). +registration(r3500,c244,s1032). +registration(r3501,c200,s1032). +registration(r3502,c5,s1032). +registration(r3503,c141,s1033). +registration(r3504,c172,s1033). +registration(r3505,c190,s1033). +registration(r3506,c253,s1034). +registration(r3507,c52,s1034). +registration(r3508,c64,s1034). +registration(r3509,c134,s1034). +registration(r3510,c1,s1035). +registration(r3511,c187,s1035). +registration(r3512,c82,s1035). +registration(r3513,c147,s1035). +registration(r3514,c45,s1036). +registration(r3515,c108,s1036). +registration(r3516,c68,s1036). +registration(r3517,c234,s1036). +registration(r3518,c231,s1037). +registration(r3519,c87,s1037). +registration(r3520,c196,s1037). +registration(r3521,c202,s1037). +registration(r3522,c87,s1038). +registration(r3523,c226,s1038). +registration(r3524,c88,s1038). +registration(r3525,c160,s1038). +registration(r3526,c163,s1039). +registration(r3527,c157,s1039). +registration(r3528,c7,s1039). +registration(r3529,c141,s1040). +registration(r3530,c151,s1040). +registration(r3531,c188,s1040). +registration(r3532,c188,s1041). +registration(r3533,c219,s1041). +registration(r3534,c51,s1041). +registration(r3535,c119,s1042). +registration(r3536,c88,s1042). +registration(r3537,c82,s1042). +registration(r3538,c171,s1043). +registration(r3539,c37,s1043). +registration(r3540,c27,s1043). +registration(r3541,c115,s1044). +registration(r3542,c175,s1044). +registration(r3543,c71,s1044). +registration(r3544,c26,s1045). +registration(r3545,c27,s1045). +registration(r3546,c237,s1045). +registration(r3547,c253,s1045). +registration(r3548,c175,s1046). +registration(r3549,c148,s1046). +registration(r3550,c99,s1046). +registration(r3551,c32,s1047). +registration(r3552,c211,s1047). +registration(r3553,c178,s1047). +registration(r3554,c26,s1047). +registration(r3555,c99,s1047). +registration(r3556,c109,s1048). +registration(r3557,c139,s1048). +registration(r3558,c163,s1048). +registration(r3559,c178,s1048). +registration(r3560,c230,s1049). +registration(r3561,c161,s1049). +registration(r3562,c49,s1049). +registration(r3563,c169,s1050). +registration(r3564,c229,s1050). +registration(r3565,c4,s1050). +registration(r3566,c38,s1051). +registration(r3567,c193,s1051). +registration(r3568,c122,s1051). +registration(r3569,c222,s1052). +registration(r3570,c204,s1052). +registration(r3571,c213,s1052). +registration(r3572,c136,s1053). +registration(r3573,c10,s1053). +registration(r3574,c187,s1053). +registration(r3575,c41,s1054). +registration(r3576,c62,s1054). +registration(r3577,c16,s1054). +registration(r3578,c207,s1055). +registration(r3579,c41,s1055). +registration(r3580,c145,s1055). +registration(r3581,c190,s1055). +registration(r3582,c170,s1056). +registration(r3583,c163,s1056). +registration(r3584,c127,s1056). +registration(r3585,c167,s1057). +registration(r3586,c47,s1057). +registration(r3587,c240,s1057). +registration(r3588,c206,s1058). +registration(r3589,c74,s1058). +registration(r3590,c92,s1058). +registration(r3591,c228,s1059). +registration(r3592,c215,s1059). +registration(r3593,c165,s1059). +registration(r3594,c207,s1060). +registration(r3595,c213,s1060). +registration(r3596,c85,s1060). +registration(r3597,c195,s1060). +registration(r3598,c59,s1060). +registration(r3599,c86,s1061). +registration(r3600,c38,s1061). +registration(r3601,c251,s1061). +registration(r3602,c159,s1062). +registration(r3603,c83,s1062). +registration(r3604,c62,s1062). +registration(r3605,c250,s1062). +registration(r3606,c6,s1063). +registration(r3607,c120,s1063). +registration(r3608,c244,s1063). +registration(r3609,c80,s1064). +registration(r3610,c164,s1064). +registration(r3611,c174,s1064). +registration(r3612,c84,s1065). +registration(r3613,c204,s1065). +registration(r3614,c193,s1065). +registration(r3615,c160,s1065). +registration(r3616,c53,s1065). +registration(r3617,c102,s1066). +registration(r3618,c61,s1066). +registration(r3619,c115,s1066). +registration(r3620,c109,s1067). +registration(r3621,c144,s1067). +registration(r3622,c54,s1067). +registration(r3623,c227,s1067). +registration(r3624,c34,s1068). +registration(r3625,c221,s1068). +registration(r3626,c228,s1068). +registration(r3627,c85,s1068). +registration(r3628,c254,s1069). +registration(r3629,c23,s1069). +registration(r3630,c41,s1069). +registration(r3631,c94,s1070). +registration(r3632,c30,s1070). +registration(r3633,c25,s1070). +registration(r3634,c224,s1070). +registration(r3635,c203,s1071). +registration(r3636,c248,s1071). +registration(r3637,c114,s1071). +registration(r3638,c54,s1071). +registration(r3639,c239,s1072). +registration(r3640,c155,s1072). +registration(r3641,c82,s1072). +registration(r3642,c96,s1073). +registration(r3643,c98,s1073). +registration(r3644,c71,s1073). +registration(r3645,c44,s1074). +registration(r3646,c172,s1074). +registration(r3647,c149,s1074). +registration(r3648,c170,s1074). +registration(r3649,c46,s1075). +registration(r3650,c76,s1075). +registration(r3651,c115,s1075). +registration(r3652,c140,s1076). +registration(r3653,c182,s1076). +registration(r3654,c74,s1076). +registration(r3655,c67,s1077). +registration(r3656,c60,s1077). +registration(r3657,c181,s1077). +registration(r3658,c164,s1077). +registration(r3659,c22,s1078). +registration(r3660,c118,s1078). +registration(r3661,c35,s1078). +registration(r3662,c133,s1079). +registration(r3663,c48,s1079). +registration(r3664,c88,s1079). +registration(r3665,c4,s1080). +registration(r3666,c90,s1080). +registration(r3667,c99,s1080). +registration(r3668,c145,s1080). +registration(r3669,c250,s1081). +registration(r3670,c121,s1081). +registration(r3671,c28,s1081). +registration(r3672,c210,s1081). +registration(r3673,c175,s1082). +registration(r3674,c207,s1082). +registration(r3675,c84,s1082). +registration(r3676,c10,s1082). +registration(r3677,c108,s1083). +registration(r3678,c46,s1083). +registration(r3679,c175,s1083). +registration(r3680,c209,s1084). +registration(r3681,c106,s1084). +registration(r3682,c122,s1084). +registration(r3683,c211,s1085). +registration(r3684,c27,s1085). +registration(r3685,c249,s1085). +registration(r3686,c90,s1086). +registration(r3687,c134,s1086). +registration(r3688,c124,s1086). +registration(r3689,c246,s1087). +registration(r3690,c7,s1087). +registration(r3691,c228,s1087). +registration(r3692,c148,s1088). +registration(r3693,c203,s1088). +registration(r3694,c48,s1088). +registration(r3695,c58,s1089). +registration(r3696,c244,s1089). +registration(r3697,c6,s1089). +registration(r3698,c171,s1090). +registration(r3699,c187,s1090). +registration(r3700,c226,s1090). +registration(r3701,c17,s1090). +registration(r3702,c249,s1091). +registration(r3703,c45,s1091). +registration(r3704,c119,s1091). +registration(r3705,c210,s1092). +registration(r3706,c86,s1092). +registration(r3707,c31,s1092). +registration(r3708,c21,s1093). +registration(r3709,c197,s1093). +registration(r3710,c188,s1093). +registration(r3711,c159,s1093). +registration(r3712,c221,s1094). +registration(r3713,c208,s1094). +registration(r3714,c216,s1094). +registration(r3715,c203,s1094). +registration(r3716,c188,s1095). +registration(r3717,c245,s1095). +registration(r3718,c68,s1095). +registration(r3719,c39,s1096). +registration(r3720,c142,s1096). +registration(r3721,c194,s1096). +registration(r3722,c239,s1097). +registration(r3723,c29,s1097). +registration(r3724,c89,s1097). +registration(r3725,c176,s1098). +registration(r3726,c177,s1098). +registration(r3727,c172,s1098). +registration(r3728,c115,s1099). +registration(r3729,c68,s1099). +registration(r3730,c217,s1099). +registration(r3731,c150,s1099). +registration(r3732,c228,s1100). +registration(r3733,c111,s1100). +registration(r3734,c107,s1100). +registration(r3735,c41,s1101). +registration(r3736,c229,s1101). +registration(r3737,c130,s1101). +registration(r3738,c170,s1102). +registration(r3739,c31,s1102). +registration(r3740,c88,s1102). +registration(r3741,c70,s1103). +registration(r3742,c111,s1103). +registration(r3743,c0,s1103). +registration(r3744,c176,s1104). +registration(r3745,c136,s1104). +registration(r3746,c13,s1104). +registration(r3747,c129,s1105). +registration(r3748,c124,s1105). +registration(r3749,c41,s1105). +registration(r3750,c224,s1105). +registration(r3751,c122,s1106). +registration(r3752,c131,s1106). +registration(r3753,c76,s1106). +registration(r3754,c117,s1107). +registration(r3755,c80,s1107). +registration(r3756,c66,s1107). +registration(r3757,c231,s1107). +registration(r3758,c38,s1108). +registration(r3759,c63,s1108). +registration(r3760,c64,s1108). +registration(r3761,c173,s1109). +registration(r3762,c206,s1109). +registration(r3763,c92,s1109). +registration(r3764,c126,s1109). +registration(r3765,c27,s1110). +registration(r3766,c182,s1110). +registration(r3767,c56,s1110). +registration(r3768,c96,s1111). +registration(r3769,c49,s1111). +registration(r3770,c70,s1111). +registration(r3771,c201,s1112). +registration(r3772,c141,s1112). +registration(r3773,c23,s1112). +registration(r3774,c104,s1112). +registration(r3775,c205,s1113). +registration(r3776,c10,s1113). +registration(r3777,c79,s1113). +registration(r3778,c141,s1113). +registration(r3779,c249,s1114). +registration(r3780,c254,s1114). +registration(r3781,c18,s1114). +registration(r3782,c112,s1115). +registration(r3783,c181,s1115). +registration(r3784,c74,s1115). +registration(r3785,c1,s1116). +registration(r3786,c143,s1116). +registration(r3787,c108,s1116). +registration(r3788,c158,s1117). +registration(r3789,c123,s1117). +registration(r3790,c48,s1117). +registration(r3791,c190,s1118). +registration(r3792,c97,s1118). +registration(r3793,c207,s1118). +registration(r3794,c155,s1119). +registration(r3795,c205,s1119). +registration(r3796,c25,s1119). +registration(r3797,c167,s1120). +registration(r3798,c79,s1120). +registration(r3799,c252,s1120). +registration(r3800,c200,s1121). +registration(r3801,c42,s1121). +registration(r3802,c171,s1121). +registration(r3803,c129,s1121). +registration(r3804,c21,s1122). +registration(r3805,c16,s1122). +registration(r3806,c232,s1122). +registration(r3807,c135,s1122). +registration(r3808,c197,s1123). +registration(r3809,c49,s1123). +registration(r3810,c210,s1123). +registration(r3811,c240,s1123). +registration(r3812,c217,s1124). +registration(r3813,c178,s1124). +registration(r3814,c254,s1124). +registration(r3815,c23,s1125). +registration(r3816,c203,s1125). +registration(r3817,c125,s1125). +registration(r3818,c120,s1125). +registration(r3819,c120,s1126). +registration(r3820,c19,s1126). +registration(r3821,c66,s1126). +registration(r3822,c85,s1127). +registration(r3823,c36,s1127). +registration(r3824,c60,s1127). +registration(r3825,c36,s1128). +registration(r3826,c180,s1128). +registration(r3827,c55,s1128). +registration(r3828,c104,s1129). +registration(r3829,c125,s1129). +registration(r3830,c134,s1129). +registration(r3831,c94,s1130). +registration(r3832,c11,s1130). +registration(r3833,c175,s1130). +registration(r3834,c198,s1131). +registration(r3835,c158,s1131). +registration(r3836,c8,s1131). +registration(r3837,c129,s1132). +registration(r3838,c254,s1132). +registration(r3839,c205,s1132). +registration(r3840,c141,s1133). +registration(r3841,c24,s1133). +registration(r3842,c198,s1133). +registration(r3843,c252,s1134). +registration(r3844,c236,s1134). +registration(r3845,c55,s1134). +registration(r3846,c151,s1134). +registration(r3847,c155,s1135). +registration(r3848,c20,s1135). +registration(r3849,c56,s1135). +registration(r3850,c150,s1136). +registration(r3851,c255,s1136). +registration(r3852,c115,s1136). +registration(r3853,c59,s1137). +registration(r3854,c9,s1137). +registration(r3855,c148,s1137). +registration(r3856,c21,s1138). +registration(r3857,c192,s1138). +registration(r3858,c145,s1138). +registration(r3859,c30,s1139). +registration(r3860,c242,s1139). +registration(r3861,c40,s1139). +registration(r3862,c36,s1140). +registration(r3863,c212,s1140). +registration(r3864,c173,s1140). +registration(r3865,c96,s1141). +registration(r3866,c242,s1141). +registration(r3867,c129,s1141). +registration(r3868,c70,s1142). +registration(r3869,c46,s1142). +registration(r3870,c231,s1142). +registration(r3871,c114,s1143). +registration(r3872,c246,s1143). +registration(r3873,c161,s1143). +registration(r3874,c183,s1143). +registration(r3875,c27,s1144). +registration(r3876,c119,s1144). +registration(r3877,c247,s1144). +registration(r3878,c22,s1145). +registration(r3879,c231,s1145). +registration(r3880,c0,s1145). +registration(r3881,c37,s1146). +registration(r3882,c211,s1146). +registration(r3883,c11,s1146). +registration(r3884,c108,s1147). +registration(r3885,c111,s1147). +registration(r3886,c193,s1147). +registration(r3887,c85,s1147). +registration(r3888,c50,s1147). +registration(r3889,c61,s1148). +registration(r3890,c195,s1148). +registration(r3891,c205,s1148). +registration(r3892,c110,s1149). +registration(r3893,c182,s1149). +registration(r3894,c112,s1149). +registration(r3895,c232,s1150). +registration(r3896,c203,s1150). +registration(r3897,c197,s1150). +registration(r3898,c173,s1151). +registration(r3899,c194,s1151). +registration(r3900,c225,s1151). +registration(r3901,c231,s1151). +registration(r3902,c22,s1152). +registration(r3903,c100,s1152). +registration(r3904,c243,s1152). +registration(r3905,c180,s1153). +registration(r3906,c134,s1153). +registration(r3907,c41,s1153). +registration(r3908,c103,s1154). +registration(r3909,c127,s1154). +registration(r3910,c136,s1154). +registration(r3911,c56,s1154). +registration(r3912,c205,s1155). +registration(r3913,c168,s1155). +registration(r3914,c202,s1155). +registration(r3915,c151,s1156). +registration(r3916,c101,s1156). +registration(r3917,c82,s1156). +registration(r3918,c20,s1156). +registration(r3919,c91,s1157). +registration(r3920,c30,s1157). +registration(r3921,c252,s1157). +registration(r3922,c53,s1157). +registration(r3923,c2,s1158). +registration(r3924,c184,s1158). +registration(r3925,c52,s1158). +registration(r3926,c93,s1159). +registration(r3927,c116,s1159). +registration(r3928,c250,s1159). +registration(r3929,c130,s1160). +registration(r3930,c220,s1160). +registration(r3931,c43,s1160). +registration(r3932,c213,s1161). +registration(r3933,c68,s1161). +registration(r3934,c72,s1161). +registration(r3935,c173,s1162). +registration(r3936,c187,s1162). +registration(r3937,c85,s1162). +registration(r3938,c177,s1163). +registration(r3939,c224,s1163). +registration(r3940,c203,s1163). +registration(r3941,c44,s1163). +registration(r3942,c195,s1164). +registration(r3943,c205,s1164). +registration(r3944,c95,s1164). +registration(r3945,c188,s1164). +registration(r3946,c239,s1165). +registration(r3947,c6,s1165). +registration(r3948,c129,s1165). +registration(r3949,c93,s1166). +registration(r3950,c15,s1166). +registration(r3951,c1,s1166). +registration(r3952,c229,s1166). +registration(r3953,c79,s1167). +registration(r3954,c76,s1167). +registration(r3955,c33,s1167). +registration(r3956,c121,s1167). +registration(r3957,c190,s1168). +registration(r3958,c215,s1168). +registration(r3959,c41,s1168). +registration(r3960,c235,s1169). +registration(r3961,c179,s1169). +registration(r3962,c207,s1169). +registration(r3963,c48,s1170). +registration(r3964,c41,s1170). +registration(r3965,c143,s1170). +registration(r3966,c150,s1170). +registration(r3967,c111,s1171). +registration(r3968,c252,s1171). +registration(r3969,c29,s1171). +registration(r3970,c31,s1171). +registration(r3971,c212,s1172). +registration(r3972,c240,s1172). +registration(r3973,c99,s1172). +registration(r3974,c60,s1172). +registration(r3975,c33,s1173). +registration(r3976,c70,s1173). +registration(r3977,c255,s1173). +registration(r3978,c41,s1173). +registration(r3979,c127,s1174). +registration(r3980,c192,s1174). +registration(r3981,c20,s1174). +registration(r3982,c195,s1175). +registration(r3983,c181,s1175). +registration(r3984,c192,s1175). +registration(r3985,c175,s1176). +registration(r3986,c6,s1176). +registration(r3987,c217,s1176). +registration(r3988,c2,s1176). +registration(r3989,c236,s1177). +registration(r3990,c14,s1177). +registration(r3991,c22,s1177). +registration(r3992,c122,s1178). +registration(r3993,c229,s1178). +registration(r3994,c60,s1178). +registration(r3995,c6,s1178). +registration(r3996,c0,s1179). +registration(r3997,c231,s1179). +registration(r3998,c158,s1179). +registration(r3999,c103,s1179). +registration(r4000,c61,s1180). +registration(r4001,c155,s1180). +registration(r4002,c240,s1180). +registration(r4003,c81,s1180). +registration(r4004,c238,s1181). +registration(r4005,c149,s1181). +registration(r4006,c96,s1181). +registration(r4007,c128,s1182). +registration(r4008,c247,s1182). +registration(r4009,c101,s1182). +registration(r4010,c123,s1182). +registration(r4011,c45,s1183). +registration(r4012,c5,s1183). +registration(r4013,c246,s1183). +registration(r4014,c67,s1183). +registration(r4015,c26,s1184). +registration(r4016,c196,s1184). +registration(r4017,c247,s1184). +registration(r4018,c99,s1184). +registration(r4019,c105,s1184). +registration(r4020,c195,s1185). +registration(r4021,c94,s1185). +registration(r4022,c4,s1185). +registration(r4023,c86,s1186). +registration(r4024,c102,s1186). +registration(r4025,c76,s1186). +registration(r4026,c66,s1187). +registration(r4027,c92,s1187). +registration(r4028,c72,s1187). +registration(r4029,c180,s1188). +registration(r4030,c63,s1188). +registration(r4031,c61,s1188). +registration(r4032,c52,s1189). +registration(r4033,c245,s1189). +registration(r4034,c134,s1189). +registration(r4035,c15,s1189). +registration(r4036,c35,s1190). +registration(r4037,c16,s1190). +registration(r4038,c175,s1190). +registration(r4039,c113,s1191). +registration(r4040,c163,s1191). +registration(r4041,c126,s1191). +registration(r4042,c2,s1191). +registration(r4043,c140,s1192). +registration(r4044,c79,s1192). +registration(r4045,c194,s1192). +registration(r4046,c29,s1193). +registration(r4047,c156,s1193). +registration(r4048,c204,s1193). +registration(r4049,c11,s1194). +registration(r4050,c31,s1194). +registration(r4051,c52,s1194). +registration(r4052,c39,s1195). +registration(r4053,c215,s1195). +registration(r4054,c126,s1195). +registration(r4055,c162,s1195). +registration(r4056,c72,s1196). +registration(r4057,c208,s1196). +registration(r4058,c230,s1196). +registration(r4059,c137,s1197). +registration(r4060,c64,s1197). +registration(r4061,c104,s1197). +registration(r4062,c244,s1197). +registration(r4063,c220,s1198). +registration(r4064,c214,s1198). +registration(r4065,c71,s1198). +registration(r4066,c227,s1199). +registration(r4067,c58,s1199). +registration(r4068,c212,s1199). +registration(r4069,c243,s1200). +registration(r4070,c101,s1200). +registration(r4071,c149,s1200). +registration(r4072,c108,s1201). +registration(r4073,c197,s1201). +registration(r4074,c196,s1201). +registration(r4075,c13,s1202). +registration(r4076,c95,s1202). +registration(r4077,c77,s1202). +registration(r4078,c214,s1203). +registration(r4079,c16,s1203). +registration(r4080,c9,s1203). +registration(r4081,c253,s1203). +registration(r4082,c62,s1204). +registration(r4083,c253,s1204). +registration(r4084,c69,s1204). +registration(r4085,c40,s1205). +registration(r4086,c231,s1205). +registration(r4087,c199,s1205). +registration(r4088,c185,s1205). +registration(r4089,c194,s1206). +registration(r4090,c195,s1206). +registration(r4091,c1,s1206). +registration(r4092,c198,s1206). +registration(r4093,c22,s1207). +registration(r4094,c191,s1207). +registration(r4095,c45,s1207). +registration(r4096,c30,s1207). +registration(r4097,c244,s1208). +registration(r4098,c190,s1208). +registration(r4099,c80,s1208). +registration(r4100,c200,s1208). +registration(r4101,c43,s1209). +registration(r4102,c198,s1209). +registration(r4103,c242,s1209). +registration(r4104,c10,s1209). +registration(r4105,c28,s1210). +registration(r4106,c52,s1210). +registration(r4107,c136,s1210). +registration(r4108,c181,s1211). +registration(r4109,c158,s1211). +registration(r4110,c81,s1211). +registration(r4111,c163,s1212). +registration(r4112,c169,s1212). +registration(r4113,c101,s1212). +registration(r4114,c146,s1213). +registration(r4115,c222,s1213). +registration(r4116,c133,s1213). +registration(r4117,c209,s1213). +registration(r4118,c94,s1214). +registration(r4119,c215,s1214). +registration(r4120,c14,s1214). +registration(r4121,c3,s1214). +registration(r4122,c4,s1215). +registration(r4123,c45,s1215). +registration(r4124,c223,s1215). +registration(r4125,c19,s1216). +registration(r4126,c45,s1216). +registration(r4127,c46,s1216). +registration(r4128,c203,s1217). +registration(r4129,c245,s1217). +registration(r4130,c90,s1217). +registration(r4131,c3,s1218). +registration(r4132,c210,s1218). +registration(r4133,c83,s1218). +registration(r4134,c48,s1219). +registration(r4135,c242,s1219). +registration(r4136,c114,s1219). +registration(r4137,c57,s1219). +registration(r4138,c218,s1220). +registration(r4139,c71,s1220). +registration(r4140,c226,s1220). +registration(r4141,c230,s1220). +registration(r4142,c10,s1221). +registration(r4143,c252,s1221). +registration(r4144,c138,s1221). +registration(r4145,c183,s1221). +registration(r4146,c128,s1222). +registration(r4147,c178,s1222). +registration(r4148,c152,s1222). +registration(r4149,c243,s1223). +registration(r4150,c183,s1223). +registration(r4151,c63,s1223). +registration(r4152,c146,s1224). +registration(r4153,c99,s1224). +registration(r4154,c239,s1224). +registration(r4155,c97,s1225). +registration(r4156,c198,s1225). +registration(r4157,c143,s1225). +registration(r4158,c161,s1225). +registration(r4159,c19,s1226). +registration(r4160,c127,s1226). +registration(r4161,c243,s1226). +registration(r4162,c239,s1227). +registration(r4163,c133,s1227). +registration(r4164,c219,s1227). +registration(r4165,c92,s1228). +registration(r4166,c177,s1228). +registration(r4167,c214,s1228). +registration(r4168,c201,s1229). +registration(r4169,c96,s1229). +registration(r4170,c152,s1229). +registration(r4171,c43,s1230). +registration(r4172,c37,s1230). +registration(r4173,c218,s1230). +registration(r4174,c59,s1231). +registration(r4175,c182,s1231). +registration(r4176,c11,s1231). +registration(r4177,c226,s1232). +registration(r4178,c128,s1232). +registration(r4179,c213,s1232). +registration(r4180,c95,s1233). +registration(r4181,c197,s1233). +registration(r4182,c0,s1233). +registration(r4183,c61,s1234). +registration(r4184,c152,s1234). +registration(r4185,c117,s1234). +registration(r4186,c64,s1234). +registration(r4187,c221,s1235). +registration(r4188,c160,s1235). +registration(r4189,c100,s1235). +registration(r4190,c145,s1236). +registration(r4191,c196,s1236). +registration(r4192,c100,s1236). +registration(r4193,c160,s1237). +registration(r4194,c54,s1237). +registration(r4195,c76,s1237). +registration(r4196,c142,s1237). +registration(r4197,c141,s1237). +registration(r4198,c99,s1238). +registration(r4199,c5,s1238). +registration(r4200,c10,s1238). +registration(r4201,c10,s1239). +registration(r4202,c254,s1239). +registration(r4203,c143,s1239). +registration(r4204,c4,s1240). +registration(r4205,c92,s1240). +registration(r4206,c214,s1240). +registration(r4207,c118,s1241). +registration(r4208,c55,s1241). +registration(r4209,c216,s1241). +registration(r4210,c200,s1241). +registration(r4211,c103,s1242). +registration(r4212,c73,s1242). +registration(r4213,c221,s1242). +registration(r4214,c128,s1242). +registration(r4215,c20,s1242). +registration(r4216,c13,s1243). +registration(r4217,c90,s1243). +registration(r4218,c163,s1243). +registration(r4219,c171,s1244). +registration(r4220,c52,s1244). +registration(r4221,c42,s1244). +registration(r4222,c187,s1244). +registration(r4223,c254,s1245). +registration(r4224,c200,s1245). +registration(r4225,c189,s1245). +registration(r4226,c145,s1246). +registration(r4227,c147,s1246). +registration(r4228,c21,s1246). +registration(r4229,c24,s1247). +registration(r4230,c146,s1247). +registration(r4231,c7,s1247). +registration(r4232,c229,s1248). +registration(r4233,c133,s1248). +registration(r4234,c91,s1248). +registration(r4235,c155,s1248). +registration(r4236,c104,s1249). +registration(r4237,c60,s1249). +registration(r4238,c219,s1249). +registration(r4239,c15,s1250). +registration(r4240,c242,s1250). +registration(r4241,c158,s1250). +registration(r4242,c156,s1251). +registration(r4243,c11,s1251). +registration(r4244,c108,s1251). +registration(r4245,c253,s1252). +registration(r4246,c137,s1252). +registration(r4247,c192,s1252). +registration(r4248,c216,s1253). +registration(r4249,c89,s1253). +registration(r4250,c252,s1253). +registration(r4251,c226,s1254). +registration(r4252,c221,s1254). +registration(r4253,c144,s1254). +registration(r4254,c250,s1255). +registration(r4255,c89,s1255). +registration(r4256,c182,s1255). +registration(r4257,c158,s1255). +registration(r4258,c230,s1256). +registration(r4259,c20,s1256). +registration(r4260,c62,s1256). +registration(r4261,c193,s1256). +registration(r4262,c52,s1257). +registration(r4263,c46,s1257). +registration(r4264,c210,s1257). +registration(r4265,c92,s1257). +registration(r4266,c159,s1258). +registration(r4267,c243,s1258). +registration(r4268,c79,s1258). +registration(r4269,c77,s1259). +registration(r4270,c209,s1259). +registration(r4271,c130,s1259). +registration(r4272,c175,s1259). +registration(r4273,c32,s1259). +registration(r4274,c41,s1260). +registration(r4275,c14,s1260). +registration(r4276,c124,s1260). +registration(r4277,c157,s1261). +registration(r4278,c127,s1261). +registration(r4279,c203,s1261). +registration(r4280,c244,s1262). +registration(r4281,c115,s1262). +registration(r4282,c152,s1262). +registration(r4283,c163,s1262). +registration(r4284,c7,s1263). +registration(r4285,c207,s1263). +registration(r4286,c197,s1263). +registration(r4287,c22,s1264). +registration(r4288,c33,s1264). +registration(r4289,c15,s1264). +registration(r4290,c145,s1265). +registration(r4291,c148,s1265). +registration(r4292,c162,s1265). +registration(r4293,c202,s1266). +registration(r4294,c178,s1266). +registration(r4295,c47,s1266). +registration(r4296,c205,s1267). +registration(r4297,c42,s1267). +registration(r4298,c99,s1267). +registration(r4299,c87,s1268). +registration(r4300,c244,s1268). +registration(r4301,c129,s1268). +registration(r4302,c236,s1269). +registration(r4303,c135,s1269). +registration(r4304,c101,s1269). +registration(r4305,c40,s1269). +registration(r4306,c201,s1270). +registration(r4307,c80,s1270). +registration(r4308,c56,s1270). +registration(r4309,c66,s1270). +registration(r4310,c192,s1271). +registration(r4311,c227,s1271). +registration(r4312,c111,s1271). +registration(r4313,c35,s1272). +registration(r4314,c165,s1272). +registration(r4315,c89,s1272). +registration(r4316,c131,s1273). +registration(r4317,c31,s1273). +registration(r4318,c243,s1273). +registration(r4319,c231,s1274). +registration(r4320,c237,s1274). +registration(r4321,c247,s1274). +registration(r4322,c126,s1275). +registration(r4323,c229,s1275). +registration(r4324,c140,s1275). +registration(r4325,c84,s1275). +registration(r4326,c254,s1276). +registration(r4327,c71,s1276). +registration(r4328,c130,s1276). +registration(r4329,c66,s1276). +registration(r4330,c36,s1277). +registration(r4331,c131,s1277). +registration(r4332,c184,s1277). +registration(r4333,c93,s1278). +registration(r4334,c44,s1278). +registration(r4335,c100,s1278). +registration(r4336,c130,s1279). +registration(r4337,c195,s1279). +registration(r4338,c28,s1279). +registration(r4339,c10,s1280). +registration(r4340,c240,s1280). +registration(r4341,c42,s1280). +registration(r4342,c15,s1281). +registration(r4343,c112,s1281). +registration(r4344,c30,s1281). +registration(r4345,c197,s1281). +registration(r4346,c102,s1281). +registration(r4347,c71,s1282). +registration(r4348,c94,s1282). +registration(r4349,c122,s1282). +registration(r4350,c253,s1283). +registration(r4351,c66,s1283). +registration(r4352,c86,s1283). +registration(r4353,c130,s1284). +registration(r4354,c7,s1284). +registration(r4355,c112,s1284). +registration(r4356,c140,s1284). +registration(r4357,c79,s1285). +registration(r4358,c133,s1285). +registration(r4359,c223,s1285). +registration(r4360,c9,s1286). +registration(r4361,c62,s1286). +registration(r4362,c229,s1286). +registration(r4363,c173,s1286). +registration(r4364,c55,s1286). +registration(r4365,c114,s1287). +registration(r4366,c32,s1287). +registration(r4367,c158,s1287). +registration(r4368,c23,s1288). +registration(r4369,c68,s1288). +registration(r4370,c1,s1288). +registration(r4371,c135,s1288). +registration(r4372,c185,s1289). +registration(r4373,c38,s1289). +registration(r4374,c219,s1289). +registration(r4375,c14,s1290). +registration(r4376,c76,s1290). +registration(r4377,c204,s1290). +registration(r4378,c171,s1291). +registration(r4379,c183,s1291). +registration(r4380,c70,s1291). +registration(r4381,c44,s1292). +registration(r4382,c206,s1292). +registration(r4383,c161,s1292). +registration(r4384,c5,s1292). +registration(r4385,c81,s1292). +registration(r4386,c163,s1293). +registration(r4387,c205,s1293). +registration(r4388,c208,s1293). +registration(r4389,c210,s1293). +registration(r4390,c207,s1294). +registration(r4391,c151,s1294). +registration(r4392,c41,s1294). +registration(r4393,c4,s1295). +registration(r4394,c74,s1295). +registration(r4395,c87,s1295). +registration(r4396,c151,s1295). +registration(r4397,c113,s1295). +registration(r4398,c103,s1296). +registration(r4399,c205,s1296). +registration(r4400,c39,s1296). +registration(r4401,c28,s1297). +registration(r4402,c219,s1297). +registration(r4403,c80,s1297). +registration(r4404,c86,s1297). +registration(r4405,c209,s1298). +registration(r4406,c91,s1298). +registration(r4407,c249,s1298). +registration(r4408,c178,s1298). +registration(r4409,c176,s1299). +registration(r4410,c253,s1299). +registration(r4411,c130,s1299). +registration(r4412,c12,s1299). +registration(r4413,c6,s1300). +registration(r4414,c44,s1300). +registration(r4415,c87,s1300). +registration(r4416,c236,s1301). +registration(r4417,c125,s1301). +registration(r4418,c174,s1301). +registration(r4419,c214,s1302). +registration(r4420,c2,s1302). +registration(r4421,c205,s1302). +registration(r4422,c30,s1303). +registration(r4423,c177,s1303). +registration(r4424,c232,s1303). +registration(r4425,c68,s1304). +registration(r4426,c109,s1304). +registration(r4427,c34,s1304). +registration(r4428,c211,s1304). +registration(r4429,c108,s1305). +registration(r4430,c164,s1305). +registration(r4431,c27,s1305). +registration(r4432,c34,s1306). +registration(r4433,c191,s1306). +registration(r4434,c7,s1306). +registration(r4435,c243,s1307). +registration(r4436,c253,s1307). +registration(r4437,c172,s1307). +registration(r4438,c132,s1308). +registration(r4439,c74,s1308). +registration(r4440,c22,s1308). +registration(r4441,c53,s1308). +registration(r4442,c40,s1309). +registration(r4443,c17,s1309). +registration(r4444,c170,s1309). +registration(r4445,c22,s1310). +registration(r4446,c206,s1310). +registration(r4447,c196,s1310). +registration(r4448,c49,s1311). +registration(r4449,c220,s1311). +registration(r4450,c188,s1311). +registration(r4451,c224,s1312). +registration(r4452,c131,s1312). +registration(r4453,c148,s1312). +registration(r4454,c136,s1313). +registration(r4455,c93,s1313). +registration(r4456,c47,s1313). +registration(r4457,c180,s1314). +registration(r4458,c27,s1314). +registration(r4459,c190,s1314). +registration(r4460,c68,s1314). +registration(r4461,c83,s1315). +registration(r4462,c85,s1315). +registration(r4463,c157,s1315). +registration(r4464,c179,s1316). +registration(r4465,c205,s1316). +registration(r4466,c110,s1316). +registration(r4467,c160,s1317). +registration(r4468,c200,s1317). +registration(r4469,c43,s1317). +registration(r4470,c12,s1318). +registration(r4471,c233,s1318). +registration(r4472,c234,s1318). +registration(r4473,c114,s1319). +registration(r4474,c201,s1319). +registration(r4475,c156,s1319). +registration(r4476,c80,s1320). +registration(r4477,c94,s1320). +registration(r4478,c46,s1320). +registration(r4479,c33,s1321). +registration(r4480,c208,s1321). +registration(r4481,c247,s1321). +registration(r4482,c161,s1322). +registration(r4483,c113,s1322). +registration(r4484,c156,s1322). +registration(r4485,c92,s1322). +registration(r4486,c178,s1322). +registration(r4487,c37,s1323). +registration(r4488,c55,s1323). +registration(r4489,c22,s1323). +registration(r4490,c255,s1324). +registration(r4491,c99,s1324). +registration(r4492,c174,s1324). +registration(r4493,c120,s1325). +registration(r4494,c8,s1325). +registration(r4495,c26,s1325). +registration(r4496,c119,s1326). +registration(r4497,c23,s1326). +registration(r4498,c213,s1326). +registration(r4499,c57,s1326). +registration(r4500,c16,s1327). +registration(r4501,c247,s1327). +registration(r4502,c117,s1327). +registration(r4503,c18,s1328). +registration(r4504,c194,s1328). +registration(r4505,c199,s1328). +registration(r4506,c115,s1328). +registration(r4507,c83,s1329). +registration(r4508,c138,s1329). +registration(r4509,c102,s1329). +registration(r4510,c202,s1330). +registration(r4511,c69,s1330). +registration(r4512,c245,s1330). +registration(r4513,c254,s1331). +registration(r4514,c185,s1331). +registration(r4515,c167,s1331). +registration(r4516,c192,s1331). +registration(r4517,c45,s1332). +registration(r4518,c76,s1332). +registration(r4519,c250,s1332). +registration(r4520,c241,s1333). +registration(r4521,c72,s1333). +registration(r4522,c14,s1333). +registration(r4523,c209,s1334). +registration(r4524,c33,s1334). +registration(r4525,c120,s1334). +registration(r4526,c203,s1334). +registration(r4527,c206,s1335). +registration(r4528,c115,s1335). +registration(r4529,c98,s1335). +registration(r4530,c168,s1336). +registration(r4531,c77,s1336). +registration(r4532,c224,s1336). +registration(r4533,c154,s1337). +registration(r4534,c16,s1337). +registration(r4535,c164,s1337). +registration(r4536,c209,s1338). +registration(r4537,c23,s1338). +registration(r4538,c202,s1338). +registration(r4539,c188,s1339). +registration(r4540,c237,s1339). +registration(r4541,c129,s1339). +registration(r4542,c71,s1339). +registration(r4543,c58,s1340). +registration(r4544,c192,s1340). +registration(r4545,c152,s1340). +registration(r4546,c102,s1341). +registration(r4547,c188,s1341). +registration(r4548,c239,s1341). +registration(r4549,c152,s1342). +registration(r4550,c12,s1342). +registration(r4551,c219,s1342). +registration(r4552,c89,s1342). +registration(r4553,c16,s1343). +registration(r4554,c253,s1343). +registration(r4555,c66,s1343). +registration(r4556,c89,s1344). +registration(r4557,c172,s1344). +registration(r4558,c115,s1344). +registration(r4559,c97,s1345). +registration(r4560,c80,s1345). +registration(r4561,c130,s1345). +registration(r4562,c188,s1346). +registration(r4563,c105,s1346). +registration(r4564,c60,s1346). +registration(r4565,c246,s1346). +registration(r4566,c192,s1347). +registration(r4567,c229,s1347). +registration(r4568,c97,s1347). +registration(r4569,c111,s1348). +registration(r4570,c150,s1348). +registration(r4571,c125,s1348). +registration(r4572,c142,s1348). +registration(r4573,c198,s1349). +registration(r4574,c77,s1349). +registration(r4575,c112,s1349). +registration(r4576,c28,s1350). +registration(r4577,c8,s1350). +registration(r4578,c118,s1350). +registration(r4579,c197,s1351). +registration(r4580,c8,s1351). +registration(r4581,c20,s1351). +registration(r4582,c125,s1352). +registration(r4583,c167,s1352). +registration(r4584,c200,s1352). +registration(r4585,c136,s1353). +registration(r4586,c89,s1353). +registration(r4587,c173,s1353). +registration(r4588,c28,s1354). +registration(r4589,c218,s1354). +registration(r4590,c85,s1354). +registration(r4591,c228,s1355). +registration(r4592,c171,s1355). +registration(r4593,c51,s1355). +registration(r4594,c218,s1356). +registration(r4595,c112,s1356). +registration(r4596,c73,s1356). +registration(r4597,c180,s1357). +registration(r4598,c21,s1357). +registration(r4599,c255,s1357). +registration(r4600,c195,s1358). +registration(r4601,c69,s1358). +registration(r4602,c38,s1358). +registration(r4603,c113,s1359). +registration(r4604,c21,s1359). +registration(r4605,c19,s1359). +registration(r4606,c90,s1359). +registration(r4607,c58,s1360). +registration(r4608,c52,s1360). +registration(r4609,c66,s1360). +registration(r4610,c26,s1360). +registration(r4611,c205,s1360). +registration(r4612,c78,s1361). +registration(r4613,c121,s1361). +registration(r4614,c13,s1361). +registration(r4615,c234,s1361). +registration(r4616,c120,s1362). +registration(r4617,c226,s1362). +registration(r4618,c12,s1362). +registration(r4619,c211,s1363). +registration(r4620,c14,s1363). +registration(r4621,c164,s1363). +registration(r4622,c53,s1363). +registration(r4623,c210,s1363). +registration(r4624,c166,s1364). +registration(r4625,c70,s1364). +registration(r4626,c230,s1364). +registration(r4627,c208,s1365). +registration(r4628,c255,s1365). +registration(r4629,c211,s1365). +registration(r4630,c32,s1365). +registration(r4631,c54,s1366). +registration(r4632,c237,s1366). +registration(r4633,c62,s1366). +registration(r4634,c102,s1367). +registration(r4635,c154,s1367). +registration(r4636,c82,s1367). +registration(r4637,c95,s1368). +registration(r4638,c110,s1368). +registration(r4639,c92,s1368). +registration(r4640,c2,s1369). +registration(r4641,c77,s1369). +registration(r4642,c178,s1369). +registration(r4643,c89,s1369). +registration(r4644,c122,s1370). +registration(r4645,c4,s1370). +registration(r4646,c30,s1370). +registration(r4647,c214,s1370). +registration(r4648,c239,s1370). +registration(r4649,c231,s1371). +registration(r4650,c61,s1371). +registration(r4651,c221,s1371). +registration(r4652,c42,s1371). +registration(r4653,c203,s1371). +registration(r4654,c37,s1372). +registration(r4655,c131,s1372). +registration(r4656,c103,s1372). +registration(r4657,c227,s1373). +registration(r4658,c215,s1373). +registration(r4659,c207,s1373). +registration(r4660,c76,s1373). +registration(r4661,c67,s1374). +registration(r4662,c88,s1374). +registration(r4663,c255,s1374). +registration(r4664,c88,s1375). +registration(r4665,c242,s1375). +registration(r4666,c124,s1375). +registration(r4667,c81,s1375). +registration(r4668,c147,s1376). +registration(r4669,c252,s1376). +registration(r4670,c56,s1376). +registration(r4671,c86,s1377). +registration(r4672,c251,s1377). +registration(r4673,c246,s1377). +registration(r4674,c32,s1377). +registration(r4675,c139,s1378). +registration(r4676,c154,s1378). +registration(r4677,c221,s1378). +registration(r4678,c174,s1379). +registration(r4679,c175,s1379). +registration(r4680,c125,s1379). +registration(r4681,c214,s1380). +registration(r4682,c252,s1380). +registration(r4683,c105,s1380). +registration(r4684,c92,s1381). +registration(r4685,c202,s1381). +registration(r4686,c201,s1381). +registration(r4687,c93,s1381). +registration(r4688,c102,s1382). +registration(r4689,c85,s1382). +registration(r4690,c45,s1382). +registration(r4691,c41,s1383). +registration(r4692,c58,s1383). +registration(r4693,c208,s1383). +registration(r4694,c91,s1384). +registration(r4695,c228,s1384). +registration(r4696,c145,s1384). +registration(r4697,c63,s1385). +registration(r4698,c120,s1385). +registration(r4699,c213,s1385). +registration(r4700,c172,s1386). +registration(r4701,c55,s1386). +registration(r4702,c212,s1386). +registration(r4703,c48,s1387). +registration(r4704,c195,s1387). +registration(r4705,c87,s1387). +registration(r4706,c180,s1388). +registration(r4707,c0,s1388). +registration(r4708,c53,s1388). +registration(r4709,c225,s1389). +registration(r4710,c11,s1389). +registration(r4711,c123,s1389). +registration(r4712,c47,s1390). +registration(r4713,c12,s1390). +registration(r4714,c60,s1390). +registration(r4715,c146,s1391). +registration(r4716,c0,s1391). +registration(r4717,c79,s1391). +registration(r4718,c185,s1392). +registration(r4719,c19,s1392). +registration(r4720,c116,s1392). +registration(r4721,c1,s1392). +registration(r4722,c191,s1393). +registration(r4723,c209,s1393). +registration(r4724,c87,s1393). +registration(r4725,c12,s1394). +registration(r4726,c91,s1394). +registration(r4727,c230,s1394). +registration(r4728,c199,s1395). +registration(r4729,c251,s1395). +registration(r4730,c24,s1395). +registration(r4731,c72,s1396). +registration(r4732,c134,s1396). +registration(r4733,c141,s1396). +registration(r4734,c92,s1396). +registration(r4735,c10,s1396). +registration(r4736,c171,s1397). +registration(r4737,c134,s1397). +registration(r4738,c70,s1397). +registration(r4739,c187,s1398). +registration(r4740,c244,s1398). +registration(r4741,c166,s1398). +registration(r4742,c121,s1399). +registration(r4743,c21,s1399). +registration(r4744,c12,s1399). +registration(r4745,c35,s1399). +registration(r4746,c16,s1400). +registration(r4747,c18,s1400). +registration(r4748,c4,s1400). +registration(r4749,c31,s1400). +registration(r4750,c81,s1401). +registration(r4751,c95,s1401). +registration(r4752,c102,s1401). +registration(r4753,c110,s1402). +registration(r4754,c52,s1402). +registration(r4755,c11,s1402). +registration(r4756,c146,s1403). +registration(r4757,c192,s1403). +registration(r4758,c69,s1403). +registration(r4759,c123,s1403). +registration(r4760,c212,s1404). +registration(r4761,c56,s1404). +registration(r4762,c237,s1404). +registration(r4763,c250,s1405). +registration(r4764,c120,s1405). +registration(r4765,c111,s1405). +registration(r4766,c129,s1406). +registration(r4767,c101,s1406). +registration(r4768,c97,s1406). +registration(r4769,c179,s1407). +registration(r4770,c238,s1407). +registration(r4771,c231,s1407). +registration(r4772,c86,s1408). +registration(r4773,c192,s1408). +registration(r4774,c229,s1408). +registration(r4775,c119,s1409). +registration(r4776,c144,s1409). +registration(r4777,c230,s1409). +registration(r4778,c31,s1409). +registration(r4779,c121,s1410). +registration(r4780,c67,s1410). +registration(r4781,c13,s1410). +registration(r4782,c7,s1411). +registration(r4783,c65,s1411). +registration(r4784,c2,s1411). +registration(r4785,c132,s1412). +registration(r4786,c207,s1412). +registration(r4787,c44,s1412). +registration(r4788,c82,s1412). +registration(r4789,c1,s1413). +registration(r4790,c58,s1413). +registration(r4791,c108,s1413). +registration(r4792,c43,s1414). +registration(r4793,c194,s1414). +registration(r4794,c96,s1414). +registration(r4795,c239,s1415). +registration(r4796,c176,s1415). +registration(r4797,c221,s1415). +registration(r4798,c87,s1416). +registration(r4799,c63,s1416). +registration(r4800,c223,s1416). +registration(r4801,c209,s1416). +registration(r4802,c94,s1417). +registration(r4803,c211,s1417). +registration(r4804,c79,s1417). +registration(r4805,c87,s1417). +registration(r4806,c85,s1417). +registration(r4807,c106,s1418). +registration(r4808,c113,s1418). +registration(r4809,c53,s1418). +registration(r4810,c161,s1419). +registration(r4811,c72,s1419). +registration(r4812,c59,s1419). +registration(r4813,c156,s1419). +registration(r4814,c151,s1420). +registration(r4815,c67,s1420). +registration(r4816,c139,s1420). +registration(r4817,c134,s1420). +registration(r4818,c27,s1421). +registration(r4819,c121,s1421). +registration(r4820,c199,s1421). +registration(r4821,c152,s1422). +registration(r4822,c224,s1422). +registration(r4823,c246,s1422). +registration(r4824,c31,s1422). +registration(r4825,c195,s1423). +registration(r4826,c78,s1423). +registration(r4827,c117,s1423). +registration(r4828,c191,s1423). +registration(r4829,c154,s1424). +registration(r4830,c106,s1424). +registration(r4831,c75,s1424). +registration(r4832,c24,s1425). +registration(r4833,c237,s1425). +registration(r4834,c67,s1425). +registration(r4835,c206,s1425). +registration(r4836,c250,s1426). +registration(r4837,c82,s1426). +registration(r4838,c86,s1426). +registration(r4839,c203,s1426). +registration(r4840,c15,s1426). +registration(r4841,c99,s1427). +registration(r4842,c181,s1427). +registration(r4843,c240,s1427). +registration(r4844,c31,s1427). +registration(r4845,c122,s1428). +registration(r4846,c228,s1428). +registration(r4847,c110,s1428). +registration(r4848,c46,s1428). +registration(r4849,c154,s1429). +registration(r4850,c173,s1429). +registration(r4851,c153,s1429). +registration(r4852,c65,s1430). +registration(r4853,c255,s1430). +registration(r4854,c125,s1430). +registration(r4855,c174,s1431). +registration(r4856,c82,s1431). +registration(r4857,c170,s1431). +registration(r4858,c168,s1431). +registration(r4859,c206,s1432). +registration(r4860,c197,s1432). +registration(r4861,c208,s1432). +registration(r4862,c121,s1432). +registration(r4863,c140,s1433). +registration(r4864,c155,s1433). +registration(r4865,c224,s1433). +registration(r4866,c125,s1433). +registration(r4867,c246,s1434). +registration(r4868,c144,s1434). +registration(r4869,c125,s1434). +registration(r4870,c25,s1435). +registration(r4871,c120,s1435). +registration(r4872,c206,s1435). +registration(r4873,c75,s1436). +registration(r4874,c223,s1436). +registration(r4875,c40,s1436). +registration(r4876,c211,s1436). +registration(r4877,c252,s1437). +registration(r4878,c218,s1437). +registration(r4879,c146,s1437). +registration(r4880,c100,s1438). +registration(r4881,c253,s1438). +registration(r4882,c28,s1438). +registration(r4883,c138,s1438). +registration(r4884,c4,s1439). +registration(r4885,c145,s1439). +registration(r4886,c55,s1439). +registration(r4887,c200,s1440). +registration(r4888,c210,s1440). +registration(r4889,c24,s1440). +registration(r4890,c236,s1440). +registration(r4891,c212,s1441). +registration(r4892,c70,s1441). +registration(r4893,c8,s1441). +registration(r4894,c38,s1441). +registration(r4895,c27,s1441). +registration(r4896,c88,s1442). +registration(r4897,c5,s1442). +registration(r4898,c24,s1442). +registration(r4899,c226,s1443). +registration(r4900,c213,s1443). +registration(r4901,c253,s1443). +registration(r4902,c33,s1444). +registration(r4903,c106,s1444). +registration(r4904,c171,s1444). +registration(r4905,c250,s1444). +registration(r4906,c121,s1445). +registration(r4907,c130,s1445). +registration(r4908,c169,s1445). +registration(r4909,c175,s1446). +registration(r4910,c56,s1446). +registration(r4911,c43,s1446). +registration(r4912,c52,s1447). +registration(r4913,c164,s1447). +registration(r4914,c166,s1447). +registration(r4915,c254,s1448). +registration(r4916,c106,s1448). +registration(r4917,c213,s1448). +registration(r4918,c4,s1448). +registration(r4919,c9,s1449). +registration(r4920,c1,s1449). +registration(r4921,c153,s1449). +registration(r4922,c3,s1449). +registration(r4923,c166,s1450). +registration(r4924,c72,s1450). +registration(r4925,c253,s1450). +registration(r4926,c127,s1451). +registration(r4927,c48,s1451). +registration(r4928,c14,s1451). +registration(r4929,c224,s1451). +registration(r4930,c69,s1452). +registration(r4931,c100,s1452). +registration(r4932,c199,s1452). +registration(r4933,c109,s1452). +registration(r4934,c223,s1453). +registration(r4935,c198,s1453). +registration(r4936,c106,s1453). +registration(r4937,c157,s1454). +registration(r4938,c78,s1454). +registration(r4939,c86,s1454). +registration(r4940,c239,s1455). +registration(r4941,c162,s1455). +registration(r4942,c114,s1455). +registration(r4943,c187,s1456). +registration(r4944,c239,s1456). +registration(r4945,c208,s1456). +registration(r4946,c1,s1457). +registration(r4947,c140,s1457). +registration(r4948,c136,s1457). +registration(r4949,c205,s1458). +registration(r4950,c68,s1458). +registration(r4951,c154,s1458). +registration(r4952,c7,s1459). +registration(r4953,c39,s1459). +registration(r4954,c19,s1459). +registration(r4955,c176,s1460). +registration(r4956,c15,s1460). +registration(r4957,c192,s1460). +registration(r4958,c182,s1460). +registration(r4959,c246,s1460). +registration(r4960,c89,s1461). +registration(r4961,c132,s1461). +registration(r4962,c232,s1461). +registration(r4963,c215,s1462). +registration(r4964,c115,s1462). +registration(r4965,c188,s1462). +registration(r4966,c73,s1463). +registration(r4967,c207,s1463). +registration(r4968,c86,s1463). +registration(r4969,c156,s1463). +registration(r4970,c183,s1464). +registration(r4971,c227,s1464). +registration(r4972,c231,s1464). +registration(r4973,c249,s1464). +registration(r4974,c48,s1465). +registration(r4975,c123,s1465). +registration(r4976,c170,s1465). +registration(r4977,c177,s1466). +registration(r4978,c247,s1466). +registration(r4979,c75,s1466). +registration(r4980,c207,s1467). +registration(r4981,c143,s1467). +registration(r4982,c245,s1467). +registration(r4983,c102,s1467). +registration(r4984,c203,s1468). +registration(r4985,c173,s1468). +registration(r4986,c222,s1468). +registration(r4987,c123,s1468). +registration(r4988,c50,s1469). +registration(r4989,c25,s1469). +registration(r4990,c207,s1469). +registration(r4991,c182,s1470). +registration(r4992,c168,s1470). +registration(r4993,c6,s1470). +registration(r4994,c130,s1471). +registration(r4995,c90,s1471). +registration(r4996,c26,s1471). +registration(r4997,c18,s1471). +registration(r4998,c9,s1472). +registration(r4999,c179,s1472). +registration(r5000,c100,s1472). +registration(r5001,c89,s1473). +registration(r5002,c231,s1473). +registration(r5003,c170,s1473). +registration(r5004,c89,s1474). +registration(r5005,c161,s1474). +registration(r5006,c201,s1474). +registration(r5007,c250,s1475). +registration(r5008,c238,s1475). +registration(r5009,c164,s1475). +registration(r5010,c92,s1476). +registration(r5011,c142,s1476). +registration(r5012,c243,s1476). +registration(r5013,c103,s1476). +registration(r5014,c103,s1477). +registration(r5015,c131,s1477). +registration(r5016,c50,s1477). +registration(r5017,c61,s1478). +registration(r5018,c38,s1478). +registration(r5019,c249,s1478). +registration(r5020,c106,s1478). +registration(r5021,c254,s1479). +registration(r5022,c20,s1479). +registration(r5023,c22,s1479). +registration(r5024,c183,s1480). +registration(r5025,c121,s1480). +registration(r5026,c66,s1480). +registration(r5027,c50,s1481). +registration(r5028,c52,s1481). +registration(r5029,c91,s1481). +registration(r5030,c145,s1481). +registration(r5031,c18,s1482). +registration(r5032,c156,s1482). +registration(r5033,c80,s1482). +registration(r5034,c211,s1482). +registration(r5035,c187,s1483). +registration(r5036,c118,s1483). +registration(r5037,c104,s1483). +registration(r5038,c98,s1484). +registration(r5039,c14,s1484). +registration(r5040,c5,s1484). +registration(r5041,c27,s1484). +registration(r5042,c204,s1485). +registration(r5043,c189,s1485). +registration(r5044,c134,s1485). +registration(r5045,c202,s1486). +registration(r5046,c17,s1486). +registration(r5047,c172,s1486). +registration(r5048,c7,s1487). +registration(r5049,c29,s1487). +registration(r5050,c213,s1487). +registration(r5051,c113,s1487). +registration(r5052,c64,s1488). +registration(r5053,c182,s1488). +registration(r5054,c116,s1488). +registration(r5055,c112,s1488). +registration(r5056,c124,s1489). +registration(r5057,c104,s1489). +registration(r5058,c136,s1489). +registration(r5059,c141,s1490). +registration(r5060,c149,s1490). +registration(r5061,c131,s1490). +registration(r5062,c66,s1491). +registration(r5063,c47,s1491). +registration(r5064,c229,s1491). +registration(r5065,c246,s1492). +registration(r5066,c39,s1492). +registration(r5067,c247,s1492). +registration(r5068,c19,s1492). +registration(r5069,c16,s1493). +registration(r5070,c31,s1493). +registration(r5071,c67,s1493). +registration(r5072,c248,s1494). +registration(r5073,c245,s1494). +registration(r5074,c113,s1494). +registration(r5075,c238,s1495). +registration(r5076,c210,s1495). +registration(r5077,c105,s1495). +registration(r5078,c247,s1496). +registration(r5079,c99,s1496). +registration(r5080,c206,s1496). +registration(r5081,c16,s1497). +registration(r5082,c207,s1497). +registration(r5083,c170,s1497). +registration(r5084,c161,s1498). +registration(r5085,c179,s1498). +registration(r5086,c193,s1498). +registration(r5087,c212,s1499). +registration(r5088,c238,s1499). +registration(r5089,c0,s1499). +registration(r5090,c112,s1499). +registration(r5091,c14,s1500). +registration(r5092,c103,s1500). +registration(r5093,c210,s1500). +registration(r5094,c192,s1501). +registration(r5095,c74,s1501). +registration(r5096,c178,s1501). +registration(r5097,c171,s1502). +registration(r5098,c241,s1502). +registration(r5099,c99,s1502). +registration(r5100,c117,s1503). +registration(r5101,c26,s1503). +registration(r5102,c97,s1503). +registration(r5103,c228,s1503). +registration(r5104,c179,s1503). +registration(r5105,c165,s1504). +registration(r5106,c225,s1504). +registration(r5107,c148,s1504). +registration(r5108,c149,s1505). +registration(r5109,c144,s1505). +registration(r5110,c63,s1505). +registration(r5111,c166,s1506). +registration(r5112,c199,s1506). +registration(r5113,c23,s1506). +registration(r5114,c98,s1507). +registration(r5115,c163,s1507). +registration(r5116,c21,s1507). +registration(r5117,c7,s1508). +registration(r5118,c93,s1508). +registration(r5119,c154,s1508). +registration(r5120,c180,s1509). +registration(r5121,c32,s1509). +registration(r5122,c211,s1509). +registration(r5123,c133,s1509). +registration(r5124,c62,s1510). +registration(r5125,c4,s1510). +registration(r5126,c28,s1510). +registration(r5127,c177,s1511). +registration(r5128,c72,s1511). +registration(r5129,c19,s1511). +registration(r5130,c186,s1512). +registration(r5131,c109,s1512). +registration(r5132,c0,s1512). +registration(r5133,c99,s1513). +registration(r5134,c77,s1513). +registration(r5135,c11,s1513). +registration(r5136,c19,s1514). +registration(r5137,c185,s1514). +registration(r5138,c53,s1514). +registration(r5139,c233,s1515). +registration(r5140,c242,s1515). +registration(r5141,c93,s1515). +registration(r5142,c227,s1515). +registration(r5143,c191,s1516). +registration(r5144,c26,s1516). +registration(r5145,c0,s1516). +registration(r5146,c178,s1517). +registration(r5147,c193,s1517). +registration(r5148,c2,s1517). +registration(r5149,c188,s1518). +registration(r5150,c200,s1518). +registration(r5151,c168,s1518). +registration(r5152,c12,s1519). +registration(r5153,c180,s1519). +registration(r5154,c202,s1519). +registration(r5155,c221,s1520). +registration(r5156,c33,s1520). +registration(r5157,c132,s1520). +registration(r5158,c109,s1521). +registration(r5159,c162,s1521). +registration(r5160,c11,s1521). +registration(r5161,c240,s1522). +registration(r5162,c174,s1522). +registration(r5163,c211,s1522). +registration(r5164,c193,s1522). +registration(r5165,c163,s1523). +registration(r5166,c232,s1523). +registration(r5167,c196,s1523). +registration(r5168,c130,s1524). +registration(r5169,c198,s1524). +registration(r5170,c59,s1524). +registration(r5171,c72,s1525). +registration(r5172,c157,s1525). +registration(r5173,c77,s1525). +registration(r5174,c42,s1526). +registration(r5175,c211,s1526). +registration(r5176,c114,s1526). +registration(r5177,c223,s1527). +registration(r5178,c124,s1527). +registration(r5179,c139,s1527). +registration(r5180,c124,s1528). +registration(r5181,c127,s1528). +registration(r5182,c9,s1528). +registration(r5183,c204,s1529). +registration(r5184,c17,s1529). +registration(r5185,c142,s1529). +registration(r5186,c32,s1529). +registration(r5187,c20,s1530). +registration(r5188,c213,s1530). +registration(r5189,c92,s1530). +registration(r5190,c164,s1531). +registration(r5191,c154,s1531). +registration(r5192,c166,s1531). +registration(r5193,c208,s1532). +registration(r5194,c40,s1532). +registration(r5195,c249,s1532). +registration(r5196,c217,s1533). +registration(r5197,c39,s1533). +registration(r5198,c53,s1533). +registration(r5199,c176,s1534). +registration(r5200,c39,s1534). +registration(r5201,c103,s1534). +registration(r5202,c206,s1534). +registration(r5203,c47,s1535). +registration(r5204,c92,s1535). +registration(r5205,c198,s1535). +registration(r5206,c218,s1536). +registration(r5207,c19,s1536). +registration(r5208,c215,s1536). +registration(r5209,c124,s1537). +registration(r5210,c113,s1537). +registration(r5211,c18,s1537). +registration(r5212,c226,s1538). +registration(r5213,c250,s1538). +registration(r5214,c242,s1538). +registration(r5215,c204,s1539). +registration(r5216,c180,s1539). +registration(r5217,c216,s1539). +registration(r5218,c135,s1539). +registration(r5219,c157,s1540). +registration(r5220,c121,s1540). +registration(r5221,c167,s1540). +registration(r5222,c213,s1541). +registration(r5223,c197,s1541). +registration(r5224,c114,s1541). +registration(r5225,c66,s1541). +registration(r5226,c40,s1542). +registration(r5227,c26,s1542). +registration(r5228,c37,s1542). +registration(r5229,c150,s1543). +registration(r5230,c166,s1543). +registration(r5231,c104,s1543). +registration(r5232,c100,s1544). +registration(r5233,c132,s1544). +registration(r5234,c22,s1544). +registration(r5235,c80,s1544). +registration(r5236,c224,s1545). +registration(r5237,c197,s1545). +registration(r5238,c221,s1545). +registration(r5239,c88,s1546). +registration(r5240,c15,s1546). +registration(r5241,c206,s1546). +registration(r5242,c229,s1546). +registration(r5243,c120,s1547). +registration(r5244,c249,s1547). +registration(r5245,c214,s1547). +registration(r5246,c241,s1547). +registration(r5247,c234,s1548). +registration(r5248,c181,s1548). +registration(r5249,c136,s1548). +registration(r5250,c242,s1549). +registration(r5251,c17,s1549). +registration(r5252,c229,s1549). +registration(r5253,c253,s1550). +registration(r5254,c94,s1550). +registration(r5255,c228,s1550). +registration(r5256,c170,s1551). +registration(r5257,c167,s1551). +registration(r5258,c166,s1551). +registration(r5259,c0,s1551). +registration(r5260,c219,s1552). +registration(r5261,c5,s1552). +registration(r5262,c155,s1552). +registration(r5263,c149,s1553). +registration(r5264,c70,s1553). +registration(r5265,c67,s1553). +registration(r5266,c46,s1554). +registration(r5267,c110,s1554). +registration(r5268,c195,s1554). +registration(r5269,c181,s1555). +registration(r5270,c193,s1555). +registration(r5271,c174,s1555). +registration(r5272,c84,s1555). +registration(r5273,c107,s1556). +registration(r5274,c58,s1556). +registration(r5275,c120,s1556). +registration(r5276,c31,s1557). +registration(r5277,c83,s1557). +registration(r5278,c243,s1557). +registration(r5279,c9,s1557). +registration(r5280,c36,s1558). +registration(r5281,c166,s1558). +registration(r5282,c63,s1558). +registration(r5283,c134,s1559). +registration(r5284,c231,s1559). +registration(r5285,c243,s1559). +registration(r5286,c95,s1559). +registration(r5287,c130,s1560). +registration(r5288,c198,s1560). +registration(r5289,c43,s1560). +registration(r5290,c219,s1561). +registration(r5291,c68,s1561). +registration(r5292,c220,s1561). +registration(r5293,c22,s1562). +registration(r5294,c0,s1562). +registration(r5295,c92,s1562). +registration(r5296,c175,s1562). +registration(r5297,c239,s1563). +registration(r5298,c62,s1563). +registration(r5299,c184,s1563). +registration(r5300,c94,s1564). +registration(r5301,c253,s1564). +registration(r5302,c6,s1564). +registration(r5303,c238,s1565). +registration(r5304,c141,s1565). +registration(r5305,c66,s1565). +registration(r5306,c239,s1565). +registration(r5307,c202,s1566). +registration(r5308,c26,s1566). +registration(r5309,c253,s1566). +registration(r5310,c65,s1567). +registration(r5311,c45,s1567). +registration(r5312,c128,s1567). +registration(r5313,c127,s1568). +registration(r5314,c77,s1568). +registration(r5315,c63,s1568). +registration(r5316,c47,s1569). +registration(r5317,c221,s1569). +registration(r5318,c180,s1569). +registration(r5319,c19,s1570). +registration(r5320,c236,s1570). +registration(r5321,c71,s1570). +registration(r5322,c53,s1571). +registration(r5323,c60,s1571). +registration(r5324,c179,s1571). +registration(r5325,c120,s1571). +registration(r5326,c3,s1572). +registration(r5327,c70,s1572). +registration(r5328,c118,s1572). +registration(r5329,c183,s1573). +registration(r5330,c129,s1573). +registration(r5331,c188,s1573). +registration(r5332,c59,s1574). +registration(r5333,c247,s1574). +registration(r5334,c6,s1574). +registration(r5335,c53,s1575). +registration(r5336,c183,s1575). +registration(r5337,c168,s1575). +registration(r5338,c248,s1575). +registration(r5339,c16,s1576). +registration(r5340,c64,s1576). +registration(r5341,c108,s1576). +registration(r5342,c167,s1577). +registration(r5343,c50,s1577). +registration(r5344,c174,s1577). +registration(r5345,c178,s1578). +registration(r5346,c24,s1578). +registration(r5347,c33,s1578). +registration(r5348,c85,s1578). +registration(r5349,c137,s1579). +registration(r5350,c15,s1579). +registration(r5351,c129,s1579). +registration(r5352,c121,s1580). +registration(r5353,c85,s1580). +registration(r5354,c36,s1580). +registration(r5355,c220,s1581). +registration(r5356,c22,s1581). +registration(r5357,c175,s1581). +registration(r5358,c192,s1582). +registration(r5359,c20,s1582). +registration(r5360,c62,s1582). +registration(r5361,c229,s1583). +registration(r5362,c114,s1583). +registration(r5363,c54,s1583). +registration(r5364,c233,s1583). +registration(r5365,c207,s1584). +registration(r5366,c62,s1584). +registration(r5367,c240,s1584). +registration(r5368,c22,s1584). +registration(r5369,c52,s1585). +registration(r5370,c152,s1585). +registration(r5371,c201,s1585). +registration(r5372,c30,s1585). +registration(r5373,c164,s1586). +registration(r5374,c126,s1586). +registration(r5375,c171,s1586). +registration(r5376,c91,s1587). +registration(r5377,c85,s1587). +registration(r5378,c105,s1587). +registration(r5379,c107,s1587). +registration(r5380,c91,s1588). +registration(r5381,c242,s1588). +registration(r5382,c139,s1588). +registration(r5383,c66,s1588). +registration(r5384,c236,s1589). +registration(r5385,c18,s1589). +registration(r5386,c20,s1589). +registration(r5387,c3,s1589). +registration(r5388,c66,s1590). +registration(r5389,c125,s1590). +registration(r5390,c108,s1590). +registration(r5391,c235,s1591). +registration(r5392,c236,s1591). +registration(r5393,c100,s1591). +registration(r5394,c16,s1592). +registration(r5395,c17,s1592). +registration(r5396,c0,s1592). +registration(r5397,c104,s1593). +registration(r5398,c134,s1593). +registration(r5399,c209,s1593). +registration(r5400,c226,s1593). +registration(r5401,c155,s1594). +registration(r5402,c176,s1594). +registration(r5403,c237,s1594). +registration(r5404,c0,s1595). +registration(r5405,c242,s1595). +registration(r5406,c199,s1595). +registration(r5407,c43,s1595). +registration(r5408,c128,s1595). +registration(r5409,c150,s1596). +registration(r5410,c229,s1596). +registration(r5411,c198,s1596). +registration(r5412,c43,s1597). +registration(r5413,c17,s1597). +registration(r5414,c62,s1597). +registration(r5415,c63,s1597). +registration(r5416,c167,s1598). +registration(r5417,c137,s1598). +registration(r5418,c165,s1598). +registration(r5419,c89,s1598). +registration(r5420,c15,s1599). +registration(r5421,c31,s1599). +registration(r5422,c81,s1599). +registration(r5423,c48,s1599). +registration(r5424,c91,s1600). +registration(r5425,c13,s1600). +registration(r5426,c34,s1600). +registration(r5427,c17,s1600). +registration(r5428,c46,s1601). +registration(r5429,c145,s1601). +registration(r5430,c227,s1601). +registration(r5431,c88,s1601). +registration(r5432,c229,s1602). +registration(r5433,c131,s1602). +registration(r5434,c118,s1602). +registration(r5435,c191,s1602). +registration(r5436,c95,s1603). +registration(r5437,c103,s1603). +registration(r5438,c36,s1603). +registration(r5439,c149,s1603). +registration(r5440,c186,s1604). +registration(r5441,c162,s1604). +registration(r5442,c157,s1604). +registration(r5443,c97,s1604). +registration(r5444,c57,s1605). +registration(r5445,c190,s1605). +registration(r5446,c183,s1605). +registration(r5447,c201,s1606). +registration(r5448,c167,s1606). +registration(r5449,c16,s1606). +registration(r5450,c36,s1607). +registration(r5451,c179,s1607). +registration(r5452,c241,s1607). +registration(r5453,c55,s1607). +registration(r5454,c44,s1608). +registration(r5455,c246,s1608). +registration(r5456,c3,s1608). +registration(r5457,c40,s1609). +registration(r5458,c145,s1609). +registration(r5459,c242,s1609). +registration(r5460,c149,s1610). +registration(r5461,c69,s1610). +registration(r5462,c86,s1610). +registration(r5463,c143,s1611). +registration(r5464,c183,s1611). +registration(r5465,c169,s1611). +registration(r5466,c114,s1612). +registration(r5467,c148,s1612). +registration(r5468,c171,s1612). +registration(r5469,c207,s1612). +registration(r5470,c128,s1613). +registration(r5471,c16,s1613). +registration(r5472,c218,s1613). +registration(r5473,c6,s1614). +registration(r5474,c174,s1614). +registration(r5475,c125,s1614). +registration(r5476,c165,s1614). +registration(r5477,c36,s1615). +registration(r5478,c253,s1615). +registration(r5479,c77,s1615). +registration(r5480,c146,s1616). +registration(r5481,c198,s1616). +registration(r5482,c138,s1616). +registration(r5483,c66,s1617). +registration(r5484,c45,s1617). +registration(r5485,c65,s1617). +registration(r5486,c212,s1618). +registration(r5487,c134,s1618). +registration(r5488,c108,s1618). +registration(r5489,c238,s1619). +registration(r5490,c4,s1619). +registration(r5491,c48,s1619). +registration(r5492,c54,s1620). +registration(r5493,c83,s1620). +registration(r5494,c252,s1620). +registration(r5495,c161,s1621). +registration(r5496,c238,s1621). +registration(r5497,c91,s1621). +registration(r5498,c239,s1622). +registration(r5499,c128,s1622). +registration(r5500,c36,s1622). +registration(r5501,c121,s1622). +registration(r5502,c189,s1623). +registration(r5503,c50,s1623). +registration(r5504,c186,s1623). +registration(r5505,c143,s1624). +registration(r5506,c32,s1624). +registration(r5507,c64,s1624). +registration(r5508,c46,s1625). +registration(r5509,c137,s1625). +registration(r5510,c166,s1625). +registration(r5511,c220,s1625). +registration(r5512,c38,s1626). +registration(r5513,c3,s1626). +registration(r5514,c166,s1626). +registration(r5515,c147,s1627). +registration(r5516,c225,s1627). +registration(r5517,c145,s1627). +registration(r5518,c20,s1628). +registration(r5519,c23,s1628). +registration(r5520,c77,s1628). +registration(r5521,c146,s1628). +registration(r5522,c76,s1628). +registration(r5523,c75,s1629). +registration(r5524,c164,s1629). +registration(r5525,c30,s1629). +registration(r5526,c95,s1630). +registration(r5527,c94,s1630). +registration(r5528,c57,s1630). +registration(r5529,c224,s1631). +registration(r5530,c97,s1631). +registration(r5531,c239,s1631). +registration(r5532,c242,s1632). +registration(r5533,c97,s1632). +registration(r5534,c13,s1632). +registration(r5535,c239,s1633). +registration(r5536,c42,s1633). +registration(r5537,c231,s1633). +registration(r5538,c255,s1634). +registration(r5539,c13,s1634). +registration(r5540,c88,s1634). +registration(r5541,c164,s1634). +registration(r5542,c219,s1635). +registration(r5543,c186,s1635). +registration(r5544,c194,s1635). +registration(r5545,c34,s1636). +registration(r5546,c21,s1636). +registration(r5547,c185,s1636). +registration(r5548,c153,s1637). +registration(r5549,c17,s1637). +registration(r5550,c236,s1637). +registration(r5551,c223,s1638). +registration(r5552,c182,s1638). +registration(r5553,c167,s1638). +registration(r5554,c152,s1639). +registration(r5555,c162,s1639). +registration(r5556,c148,s1639). +registration(r5557,c149,s1640). +registration(r5558,c101,s1640). +registration(r5559,c55,s1640). +registration(r5560,c125,s1640). +registration(r5561,c0,s1641). +registration(r5562,c56,s1641). +registration(r5563,c159,s1641). +registration(r5564,c193,s1642). +registration(r5565,c204,s1642). +registration(r5566,c111,s1642). +registration(r5567,c9,s1643). +registration(r5568,c131,s1643). +registration(r5569,c183,s1643). +registration(r5570,c150,s1643). +registration(r5571,c22,s1644). +registration(r5572,c198,s1644). +registration(r5573,c13,s1644). +registration(r5574,c175,s1645). +registration(r5575,c90,s1645). +registration(r5576,c183,s1645). +registration(r5577,c29,s1646). +registration(r5578,c199,s1646). +registration(r5579,c20,s1646). +registration(r5580,c20,s1647). +registration(r5581,c210,s1647). +registration(r5582,c67,s1647). +registration(r5583,c4,s1648). +registration(r5584,c152,s1648). +registration(r5585,c249,s1648). +registration(r5586,c2,s1649). +registration(r5587,c249,s1649). +registration(r5588,c25,s1649). +registration(r5589,c174,s1649). +registration(r5590,c121,s1650). +registration(r5591,c221,s1650). +registration(r5592,c187,s1650). +registration(r5593,c107,s1651). +registration(r5594,c152,s1651). +registration(r5595,c242,s1651). +registration(r5596,c15,s1652). +registration(r5597,c194,s1652). +registration(r5598,c156,s1652). +registration(r5599,c177,s1653). +registration(r5600,c123,s1653). +registration(r5601,c169,s1653). +registration(r5602,c174,s1653). +registration(r5603,c21,s1654). +registration(r5604,c254,s1654). +registration(r5605,c37,s1654). +registration(r5606,c30,s1654). +registration(r5607,c143,s1655). +registration(r5608,c99,s1655). +registration(r5609,c52,s1655). +registration(r5610,c17,s1656). +registration(r5611,c251,s1656). +registration(r5612,c27,s1656). +registration(r5613,c178,s1657). +registration(r5614,c62,s1657). +registration(r5615,c97,s1657). +registration(r5616,c35,s1658). +registration(r5617,c215,s1658). +registration(r5618,c247,s1658). +registration(r5619,c115,s1659). +registration(r5620,c51,s1659). +registration(r5621,c5,s1659). +registration(r5622,c26,s1660). +registration(r5623,c120,s1660). +registration(r5624,c6,s1660). +registration(r5625,c36,s1661). +registration(r5626,c33,s1661). +registration(r5627,c221,s1661). +registration(r5628,c185,s1662). +registration(r5629,c106,s1662). +registration(r5630,c90,s1662). +registration(r5631,c194,s1663). +registration(r5632,c134,s1663). +registration(r5633,c245,s1663). +registration(r5634,c192,s1663). +registration(r5635,c71,s1664). +registration(r5636,c153,s1664). +registration(r5637,c58,s1664). +registration(r5638,c175,s1664). +registration(r5639,c6,s1665). +registration(r5640,c39,s1665). +registration(r5641,c41,s1665). +registration(r5642,c158,s1666). +registration(r5643,c238,s1666). +registration(r5644,c210,s1666). +registration(r5645,c18,s1666). +registration(r5646,c245,s1667). +registration(r5647,c107,s1667). +registration(r5648,c83,s1667). +registration(r5649,c175,s1668). +registration(r5650,c130,s1668). +registration(r5651,c141,s1668). +registration(r5652,c131,s1668). +registration(r5653,c149,s1669). +registration(r5654,c204,s1669). +registration(r5655,c198,s1669). +registration(r5656,c2,s1670). +registration(r5657,c175,s1670). +registration(r5658,c134,s1670). +registration(r5659,c173,s1671). +registration(r5660,c216,s1671). +registration(r5661,c155,s1671). +registration(r5662,c139,s1672). +registration(r5663,c193,s1672). +registration(r5664,c143,s1672). +registration(r5665,c132,s1673). +registration(r5666,c11,s1673). +registration(r5667,c10,s1673). +registration(r5668,c226,s1673). +registration(r5669,c182,s1674). +registration(r5670,c111,s1674). +registration(r5671,c43,s1674). +registration(r5672,c193,s1675). +registration(r5673,c140,s1675). +registration(r5674,c186,s1675). +registration(r5675,c189,s1676). +registration(r5676,c76,s1676). +registration(r5677,c120,s1676). +registration(r5678,c37,s1676). +registration(r5679,c70,s1677). +registration(r5680,c159,s1677). +registration(r5681,c20,s1677). +registration(r5682,c214,s1677). +registration(r5683,c76,s1678). +registration(r5684,c202,s1678). +registration(r5685,c139,s1678). +registration(r5686,c149,s1679). +registration(r5687,c3,s1679). +registration(r5688,c183,s1679). +registration(r5689,c39,s1680). +registration(r5690,c124,s1680). +registration(r5691,c122,s1680). +registration(r5692,c61,s1680). +registration(r5693,c215,s1680). +registration(r5694,c218,s1681). +registration(r5695,c249,s1681). +registration(r5696,c146,s1681). +registration(r5697,c112,s1681). +registration(r5698,c40,s1681). +registration(r5699,c151,s1682). +registration(r5700,c72,s1682). +registration(r5701,c200,s1682). +registration(r5702,c243,s1682). +registration(r5703,c129,s1683). +registration(r5704,c82,s1683). +registration(r5705,c189,s1683). +registration(r5706,c34,s1683). +registration(r5707,c162,s1684). +registration(r5708,c38,s1684). +registration(r5709,c73,s1684). +registration(r5710,c112,s1685). +registration(r5711,c109,s1685). +registration(r5712,c91,s1685). +registration(r5713,c99,s1686). +registration(r5714,c98,s1686). +registration(r5715,c134,s1686). +registration(r5716,c173,s1687). +registration(r5717,c206,s1687). +registration(r5718,c248,s1687). +registration(r5719,c65,s1688). +registration(r5720,c158,s1688). +registration(r5721,c17,s1688). +registration(r5722,c147,s1689). +registration(r5723,c154,s1689). +registration(r5724,c77,s1689). +registration(r5725,c224,s1690). +registration(r5726,c67,s1690). +registration(r5727,c228,s1690). +registration(r5728,c53,s1690). +registration(r5729,c154,s1691). +registration(r5730,c164,s1691). +registration(r5731,c33,s1691). +registration(r5732,c78,s1691). +registration(r5733,c137,s1692). +registration(r5734,c212,s1692). +registration(r5735,c226,s1692). +registration(r5736,c176,s1693). +registration(r5737,c120,s1693). +registration(r5738,c87,s1693). +registration(r5739,c186,s1693). +registration(r5740,c40,s1694). +registration(r5741,c1,s1694). +registration(r5742,c136,s1694). +registration(r5743,c213,s1695). +registration(r5744,c91,s1695). +registration(r5745,c87,s1695). +registration(r5746,c59,s1696). +registration(r5747,c223,s1696). +registration(r5748,c212,s1696). +registration(r5749,c121,s1696). +registration(r5750,c34,s1697). +registration(r5751,c160,s1697). +registration(r5752,c200,s1697). +registration(r5753,c155,s1697). +registration(r5754,c138,s1698). +registration(r5755,c169,s1698). +registration(r5756,c29,s1698). +registration(r5757,c117,s1698). +registration(r5758,c81,s1699). +registration(r5759,c220,s1699). +registration(r5760,c108,s1699). +registration(r5761,c243,s1700). +registration(r5762,c53,s1700). +registration(r5763,c120,s1700). +registration(r5764,c207,s1701). +registration(r5765,c127,s1701). +registration(r5766,c47,s1701). +registration(r5767,c95,s1701). +registration(r5768,c12,s1701). +registration(r5769,c216,s1702). +registration(r5770,c125,s1702). +registration(r5771,c47,s1702). +registration(r5772,c215,s1703). +registration(r5773,c162,s1703). +registration(r5774,c226,s1703). +registration(r5775,c255,s1704). +registration(r5776,c156,s1704). +registration(r5777,c109,s1704). +registration(r5778,c74,s1705). +registration(r5779,c225,s1705). +registration(r5780,c105,s1705). +registration(r5781,c213,s1705). +registration(r5782,c160,s1706). +registration(r5783,c158,s1706). +registration(r5784,c47,s1706). +registration(r5785,c96,s1706). +registration(r5786,c123,s1707). +registration(r5787,c126,s1707). +registration(r5788,c100,s1707). +registration(r5789,c227,s1708). +registration(r5790,c183,s1708). +registration(r5791,c207,s1708). +registration(r5792,c142,s1708). +registration(r5793,c11,s1709). +registration(r5794,c242,s1709). +registration(r5795,c190,s1709). +registration(r5796,c143,s1709). +registration(r5797,c128,s1709). +registration(r5798,c127,s1710). +registration(r5799,c119,s1710). +registration(r5800,c98,s1710). +registration(r5801,c56,s1711). +registration(r5802,c136,s1711). +registration(r5803,c64,s1711). +registration(r5804,c176,s1712). +registration(r5805,c247,s1712). +registration(r5806,c24,s1712). +registration(r5807,c116,s1712). +registration(r5808,c181,s1713). +registration(r5809,c204,s1713). +registration(r5810,c97,s1713). +registration(r5811,c139,s1714). +registration(r5812,c254,s1714). +registration(r5813,c15,s1714). +registration(r5814,c206,s1715). +registration(r5815,c162,s1715). +registration(r5816,c127,s1715). +registration(r5817,c0,s1715). +registration(r5818,c116,s1716). +registration(r5819,c135,s1716). +registration(r5820,c233,s1716). +registration(r5821,c190,s1716). +registration(r5822,c85,s1717). +registration(r5823,c151,s1717). +registration(r5824,c40,s1717). +registration(r5825,c142,s1717). +registration(r5826,c50,s1718). +registration(r5827,c3,s1718). +registration(r5828,c191,s1718). +registration(r5829,c33,s1719). +registration(r5830,c86,s1719). +registration(r5831,c109,s1719). +registration(r5832,c124,s1720). +registration(r5833,c67,s1720). +registration(r5834,c69,s1720). +registration(r5835,c197,s1721). +registration(r5836,c71,s1721). +registration(r5837,c10,s1721). +registration(r5838,c145,s1722). +registration(r5839,c175,s1722). +registration(r5840,c209,s1722). +registration(r5841,c38,s1722). +registration(r5842,c231,s1723). +registration(r5843,c72,s1723). +registration(r5844,c44,s1723). +registration(r5845,c94,s1724). +registration(r5846,c121,s1724). +registration(r5847,c73,s1724). +registration(r5848,c107,s1725). +registration(r5849,c157,s1725). +registration(r5850,c181,s1725). +registration(r5851,c241,s1725). +registration(r5852,c90,s1725). +registration(r5853,c53,s1726). +registration(r5854,c125,s1726). +registration(r5855,c67,s1726). +registration(r5856,c77,s1727). +registration(r5857,c193,s1727). +registration(r5858,c128,s1727). +registration(r5859,c81,s1728). +registration(r5860,c47,s1728). +registration(r5861,c145,s1728). +registration(r5862,c218,s1728). +registration(r5863,c164,s1729). +registration(r5864,c140,s1729). +registration(r5865,c99,s1729). +registration(r5866,c6,s1729). +registration(r5867,c74,s1730). +registration(r5868,c79,s1730). +registration(r5869,c25,s1730). +registration(r5870,c50,s1730). +registration(r5871,c215,s1731). +registration(r5872,c53,s1731). +registration(r5873,c142,s1731). +registration(r5874,c178,s1731). +registration(r5875,c9,s1732). +registration(r5876,c119,s1732). +registration(r5877,c31,s1732). +registration(r5878,c253,s1733). +registration(r5879,c59,s1733). +registration(r5880,c72,s1733). +registration(r5881,c203,s1733). +registration(r5882,c67,s1734). +registration(r5883,c166,s1734). +registration(r5884,c101,s1734). +registration(r5885,c105,s1734). +registration(r5886,c214,s1735). +registration(r5887,c184,s1735). +registration(r5888,c177,s1735). +registration(r5889,c211,s1735). +registration(r5890,c42,s1736). +registration(r5891,c5,s1736). +registration(r5892,c115,s1736). +registration(r5893,c127,s1737). +registration(r5894,c18,s1737). +registration(r5895,c101,s1737). +registration(r5896,c131,s1738). +registration(r5897,c83,s1738). +registration(r5898,c127,s1738). +registration(r5899,c200,s1739). +registration(r5900,c172,s1739). +registration(r5901,c91,s1739). +registration(r5902,c2,s1740). +registration(r5903,c237,s1740). +registration(r5904,c192,s1740). +registration(r5905,c85,s1740). +registration(r5906,c198,s1741). +registration(r5907,c8,s1741). +registration(r5908,c188,s1741). +registration(r5909,c231,s1742). +registration(r5910,c159,s1742). +registration(r5911,c20,s1742). +registration(r5912,c148,s1743). +registration(r5913,c89,s1743). +registration(r5914,c154,s1743). +registration(r5915,c226,s1743). +registration(r5916,c112,s1743). +registration(r5917,c98,s1744). +registration(r5918,c157,s1744). +registration(r5919,c0,s1744). +registration(r5920,c73,s1744). +registration(r5921,c179,s1745). +registration(r5922,c57,s1745). +registration(r5923,c94,s1745). +registration(r5924,c107,s1746). +registration(r5925,c246,s1746). +registration(r5926,c145,s1746). +registration(r5927,c255,s1746). +registration(r5928,c205,s1747). +registration(r5929,c161,s1747). +registration(r5930,c53,s1747). +registration(r5931,c125,s1748). +registration(r5932,c162,s1748). +registration(r5933,c74,s1748). +registration(r5934,c103,s1749). +registration(r5935,c185,s1749). +registration(r5936,c87,s1749). +registration(r5937,c245,s1749). +registration(r5938,c217,s1750). +registration(r5939,c69,s1750). +registration(r5940,c62,s1750). +registration(r5941,c121,s1751). +registration(r5942,c149,s1751). +registration(r5943,c154,s1751). +registration(r5944,c143,s1751). +registration(r5945,c5,s1752). +registration(r5946,c51,s1752). +registration(r5947,c144,s1752). +registration(r5948,c49,s1752). +registration(r5949,c139,s1753). +registration(r5950,c109,s1753). +registration(r5951,c231,s1753). +registration(r5952,c15,s1753). +registration(r5953,c222,s1753). +registration(r5954,c75,s1754). +registration(r5955,c154,s1754). +registration(r5956,c152,s1754). +registration(r5957,c180,s1755). +registration(r5958,c152,s1755). +registration(r5959,c75,s1755). +registration(r5960,c130,s1756). +registration(r5961,c243,s1756). +registration(r5962,c80,s1756). +registration(r5963,c141,s1756). +registration(r5964,c23,s1757). +registration(r5965,c30,s1757). +registration(r5966,c203,s1757). +registration(r5967,c31,s1758). +registration(r5968,c75,s1758). +registration(r5969,c221,s1758). +registration(r5970,c196,s1759). +registration(r5971,c178,s1759). +registration(r5972,c200,s1759). +registration(r5973,c19,s1760). +registration(r5974,c144,s1760). +registration(r5975,c43,s1760). +registration(r5976,c223,s1760). +registration(r5977,c79,s1761). +registration(r5978,c80,s1761). +registration(r5979,c217,s1761). +registration(r5980,c209,s1761). +registration(r5981,c120,s1762). +registration(r5982,c233,s1762). +registration(r5983,c89,s1762). +registration(r5984,c119,s1762). +registration(r5985,c8,s1763). +registration(r5986,c76,s1763). +registration(r5987,c37,s1763). +registration(r5988,c151,s1763). +registration(r5989,c211,s1763). +registration(r5990,c77,s1764). +registration(r5991,c199,s1764). +registration(r5992,c133,s1764). +registration(r5993,c190,s1764). +registration(r5994,c40,s1764). +registration(r5995,c78,s1765). +registration(r5996,c66,s1765). +registration(r5997,c224,s1765). +registration(r5998,c47,s1765). +registration(r5999,c162,s1766). +registration(r6000,c251,s1766). +registration(r6001,c86,s1766). +registration(r6002,c208,s1767). +registration(r6003,c93,s1767). +registration(r6004,c34,s1767). +registration(r6005,c96,s1767). +registration(r6006,c22,s1768). +registration(r6007,c170,s1768). +registration(r6008,c192,s1768). +registration(r6009,c194,s1769). +registration(r6010,c16,s1769). +registration(r6011,c142,s1769). +registration(r6012,c164,s1770). +registration(r6013,c72,s1770). +registration(r6014,c175,s1770). +registration(r6015,c241,s1771). +registration(r6016,c172,s1771). +registration(r6017,c233,s1771). +registration(r6018,c219,s1771). +registration(r6019,c13,s1772). +registration(r6020,c53,s1772). +registration(r6021,c0,s1772). +registration(r6022,c96,s1772). +registration(r6023,c249,s1773). +registration(r6024,c18,s1773). +registration(r6025,c189,s1773). +registration(r6026,c104,s1773). +registration(r6027,c84,s1774). +registration(r6028,c103,s1774). +registration(r6029,c169,s1774). +registration(r6030,c120,s1774). +registration(r6031,c162,s1775). +registration(r6032,c14,s1775). +registration(r6033,c219,s1775). +registration(r6034,c169,s1776). +registration(r6035,c130,s1776). +registration(r6036,c174,s1776). +registration(r6037,c192,s1777). +registration(r6038,c51,s1777). +registration(r6039,c248,s1777). +registration(r6040,c249,s1778). +registration(r6041,c164,s1778). +registration(r6042,c107,s1778). +registration(r6043,c127,s1779). +registration(r6044,c21,s1779). +registration(r6045,c51,s1779). +registration(r6046,c135,s1780). +registration(r6047,c14,s1780). +registration(r6048,c40,s1780). +registration(r6049,c94,s1781). +registration(r6050,c64,s1781). +registration(r6051,c150,s1781). +registration(r6052,c82,s1781). +registration(r6053,c227,s1782). +registration(r6054,c173,s1782). +registration(r6055,c0,s1782). +registration(r6056,c192,s1782). +registration(r6057,c109,s1783). +registration(r6058,c19,s1783). +registration(r6059,c144,s1783). +registration(r6060,c52,s1783). +registration(r6061,c66,s1784). +registration(r6062,c101,s1784). +registration(r6063,c210,s1784). +registration(r6064,c4,s1785). +registration(r6065,c105,s1785). +registration(r6066,c249,s1785). +registration(r6067,c33,s1786). +registration(r6068,c43,s1786). +registration(r6069,c255,s1786). +registration(r6070,c148,s1787). +registration(r6071,c187,s1787). +registration(r6072,c150,s1787). +registration(r6073,c69,s1788). +registration(r6074,c231,s1788). +registration(r6075,c216,s1788). +registration(r6076,c70,s1789). +registration(r6077,c116,s1789). +registration(r6078,c54,s1789). +registration(r6079,c130,s1789). +registration(r6080,c93,s1790). +registration(r6081,c230,s1790). +registration(r6082,c60,s1790). +registration(r6083,c98,s1790). +registration(r6084,c136,s1791). +registration(r6085,c90,s1791). +registration(r6086,c205,s1791). +registration(r6087,c124,s1791). +registration(r6088,c255,s1792). +registration(r6089,c251,s1792). +registration(r6090,c97,s1792). +registration(r6091,c248,s1793). +registration(r6092,c122,s1793). +registration(r6093,c86,s1793). +registration(r6094,c47,s1794). +registration(r6095,c158,s1794). +registration(r6096,c9,s1794). +registration(r6097,c65,s1794). +registration(r6098,c146,s1795). +registration(r6099,c145,s1795). +registration(r6100,c172,s1795). +registration(r6101,c232,s1796). +registration(r6102,c15,s1796). +registration(r6103,c217,s1796). +registration(r6104,c150,s1796). +registration(r6105,c247,s1797). +registration(r6106,c151,s1797). +registration(r6107,c177,s1797). +registration(r6108,c174,s1798). +registration(r6109,c79,s1798). +registration(r6110,c43,s1798). +registration(r6111,c166,s1799). +registration(r6112,c189,s1799). +registration(r6113,c133,s1799). +registration(r6114,c237,s1799). +registration(r6115,c17,s1799). +registration(r6116,c99,s1800). +registration(r6117,c54,s1800). +registration(r6118,c82,s1800). +registration(r6119,c253,s1801). +registration(r6120,c228,s1801). +registration(r6121,c64,s1801). +registration(r6122,c27,s1802). +registration(r6123,c16,s1802). +registration(r6124,c140,s1802). +registration(r6125,c36,s1802). +registration(r6126,c2,s1803). +registration(r6127,c245,s1803). +registration(r6128,c186,s1803). +registration(r6129,c230,s1804). +registration(r6130,c23,s1804). +registration(r6131,c142,s1804). +registration(r6132,c21,s1805). +registration(r6133,c149,s1805). +registration(r6134,c194,s1805). +registration(r6135,c36,s1806). +registration(r6136,c113,s1806). +registration(r6137,c248,s1806). +registration(r6138,c57,s1806). +registration(r6139,c254,s1807). +registration(r6140,c122,s1807). +registration(r6141,c219,s1807). +registration(r6142,c236,s1808). +registration(r6143,c125,s1808). +registration(r6144,c229,s1808). +registration(r6145,c232,s1809). +registration(r6146,c233,s1809). +registration(r6147,c91,s1809). +registration(r6148,c66,s1809). +registration(r6149,c176,s1810). +registration(r6150,c190,s1810). +registration(r6151,c207,s1810). +registration(r6152,c100,s1811). +registration(r6153,c70,s1811). +registration(r6154,c14,s1811). +registration(r6155,c109,s1811). +registration(r6156,c2,s1812). +registration(r6157,c133,s1812). +registration(r6158,c184,s1812). +registration(r6159,c51,s1813). +registration(r6160,c213,s1813). +registration(r6161,c118,s1813). +registration(r6162,c244,s1814). +registration(r6163,c174,s1814). +registration(r6164,c181,s1814). +registration(r6165,c159,s1815). +registration(r6166,c242,s1815). +registration(r6167,c49,s1815). +registration(r6168,c226,s1816). +registration(r6169,c140,s1816). +registration(r6170,c5,s1816). +registration(r6171,c105,s1817). +registration(r6172,c175,s1817). +registration(r6173,c112,s1817). +registration(r6174,c239,s1817). +registration(r6175,c119,s1818). +registration(r6176,c160,s1818). +registration(r6177,c168,s1818). +registration(r6178,c219,s1818). +registration(r6179,c68,s1819). +registration(r6180,c154,s1819). +registration(r6181,c164,s1819). +registration(r6182,c142,s1819). +registration(r6183,c187,s1820). +registration(r6184,c36,s1820). +registration(r6185,c236,s1820). +registration(r6186,c29,s1820). +registration(r6187,c41,s1821). +registration(r6188,c78,s1821). +registration(r6189,c0,s1821). +registration(r6190,c104,s1822). +registration(r6191,c24,s1822). +registration(r6192,c188,s1822). +registration(r6193,c137,s1822). +registration(r6194,c49,s1822). +registration(r6195,c120,s1823). +registration(r6196,c167,s1823). +registration(r6197,c209,s1823). +registration(r6198,c23,s1823). +registration(r6199,c250,s1824). +registration(r6200,c91,s1824). +registration(r6201,c142,s1824). +registration(r6202,c29,s1825). +registration(r6203,c242,s1825). +registration(r6204,c30,s1825). +registration(r6205,c120,s1826). +registration(r6206,c89,s1826). +registration(r6207,c251,s1826). +registration(r6208,c252,s1827). +registration(r6209,c88,s1827). +registration(r6210,c249,s1827). +registration(r6211,c182,s1828). +registration(r6212,c122,s1828). +registration(r6213,c249,s1828). +registration(r6214,c113,s1829). +registration(r6215,c142,s1829). +registration(r6216,c125,s1829). +registration(r6217,c113,s1830). +registration(r6218,c141,s1830). +registration(r6219,c1,s1830). +registration(r6220,c44,s1830). +registration(r6221,c29,s1831). +registration(r6222,c30,s1831). +registration(r6223,c130,s1831). +registration(r6224,c249,s1832). +registration(r6225,c185,s1832). +registration(r6226,c247,s1832). +registration(r6227,c244,s1833). +registration(r6228,c243,s1833). +registration(r6229,c91,s1833). +registration(r6230,c18,s1834). +registration(r6231,c211,s1834). +registration(r6232,c95,s1834). +registration(r6233,c209,s1835). +registration(r6234,c135,s1835). +registration(r6235,c253,s1835). +registration(r6236,c109,s1835). +registration(r6237,c239,s1836). +registration(r6238,c46,s1836). +registration(r6239,c111,s1836). +registration(r6240,c146,s1836). +registration(r6241,c57,s1837). +registration(r6242,c19,s1837). +registration(r6243,c237,s1837). +registration(r6244,c167,s1837). +registration(r6245,c46,s1838). +registration(r6246,c169,s1838). +registration(r6247,c9,s1838). +registration(r6248,c157,s1838). +registration(r6249,c123,s1839). +registration(r6250,c2,s1839). +registration(r6251,c120,s1839). +registration(r6252,c113,s1840). +registration(r6253,c206,s1840). +registration(r6254,c51,s1840). +registration(r6255,c150,s1841). +registration(r6256,c38,s1841). +registration(r6257,c59,s1841). +registration(r6258,c170,s1842). +registration(r6259,c161,s1842). +registration(r6260,c231,s1842). +registration(r6261,c250,s1843). +registration(r6262,c36,s1843). +registration(r6263,c16,s1843). +registration(r6264,c203,s1843). +registration(r6265,c177,s1844). +registration(r6266,c214,s1844). +registration(r6267,c96,s1844). +registration(r6268,c220,s1845). +registration(r6269,c81,s1845). +registration(r6270,c179,s1845). +registration(r6271,c180,s1845). +registration(r6272,c249,s1845). +registration(r6273,c231,s1846). +registration(r6274,c31,s1846). +registration(r6275,c197,s1846). +registration(r6276,c0,s1847). +registration(r6277,c5,s1847). +registration(r6278,c155,s1847). +registration(r6279,c130,s1848). +registration(r6280,c226,s1848). +registration(r6281,c129,s1848). +registration(r6282,c147,s1848). +registration(r6283,c133,s1849). +registration(r6284,c212,s1849). +registration(r6285,c209,s1849). +registration(r6286,c51,s1850). +registration(r6287,c134,s1850). +registration(r6288,c229,s1850). +registration(r6289,c215,s1850). +registration(r6290,c59,s1851). +registration(r6291,c141,s1851). +registration(r6292,c192,s1851). +registration(r6293,c223,s1852). +registration(r6294,c251,s1852). +registration(r6295,c241,s1852). +registration(r6296,c252,s1852). +registration(r6297,c192,s1853). +registration(r6298,c166,s1853). +registration(r6299,c157,s1853). +registration(r6300,c32,s1854). +registration(r6301,c192,s1854). +registration(r6302,c145,s1854). +registration(r6303,c101,s1855). +registration(r6304,c134,s1855). +registration(r6305,c124,s1855). +registration(r6306,c186,s1855). +registration(r6307,c245,s1855). +registration(r6308,c202,s1856). +registration(r6309,c219,s1856). +registration(r6310,c142,s1856). +registration(r6311,c103,s1856). +registration(r6312,c60,s1857). +registration(r6313,c220,s1857). +registration(r6314,c47,s1857). +registration(r6315,c84,s1858). +registration(r6316,c51,s1858). +registration(r6317,c199,s1858). +registration(r6318,c219,s1858). +registration(r6319,c88,s1859). +registration(r6320,c102,s1859). +registration(r6321,c135,s1859). +registration(r6322,c247,s1859). +registration(r6323,c93,s1860). +registration(r6324,c94,s1860). +registration(r6325,c192,s1860). +registration(r6326,c121,s1861). +registration(r6327,c221,s1861). +registration(r6328,c98,s1861). +registration(r6329,c242,s1862). +registration(r6330,c74,s1862). +registration(r6331,c33,s1862). +registration(r6332,c254,s1863). +registration(r6333,c113,s1863). +registration(r6334,c189,s1863). +registration(r6335,c241,s1864). +registration(r6336,c148,s1864). +registration(r6337,c219,s1864). +registration(r6338,c52,s1865). +registration(r6339,c50,s1865). +registration(r6340,c130,s1865). +registration(r6341,c187,s1865). +registration(r6342,c170,s1866). +registration(r6343,c135,s1866). +registration(r6344,c121,s1866). +registration(r6345,c243,s1867). +registration(r6346,c98,s1867). +registration(r6347,c87,s1867). +registration(r6348,c73,s1867). +registration(r6349,c130,s1868). +registration(r6350,c61,s1868). +registration(r6351,c141,s1868). +registration(r6352,c59,s1868). +registration(r6353,c199,s1869). +registration(r6354,c9,s1869). +registration(r6355,c196,s1869). +registration(r6356,c161,s1870). +registration(r6357,c133,s1870). +registration(r6358,c154,s1870). +registration(r6359,c27,s1871). +registration(r6360,c35,s1871). +registration(r6361,c227,s1871). +registration(r6362,c107,s1872). +registration(r6363,c80,s1872). +registration(r6364,c82,s1872). +registration(r6365,c181,s1873). +registration(r6366,c184,s1873). +registration(r6367,c123,s1873). +registration(r6368,c254,s1873). +registration(r6369,c15,s1874). +registration(r6370,c143,s1874). +registration(r6371,c7,s1874). +registration(r6372,c206,s1875). +registration(r6373,c84,s1875). +registration(r6374,c82,s1875). +registration(r6375,c244,s1876). +registration(r6376,c14,s1876). +registration(r6377,c142,s1876). +registration(r6378,c170,s1877). +registration(r6379,c236,s1877). +registration(r6380,c169,s1877). +registration(r6381,c22,s1878). +registration(r6382,c209,s1878). +registration(r6383,c12,s1878). +registration(r6384,c193,s1878). +registration(r6385,c46,s1879). +registration(r6386,c145,s1879). +registration(r6387,c148,s1879). +registration(r6388,c143,s1879). +registration(r6389,c191,s1880). +registration(r6390,c151,s1880). +registration(r6391,c237,s1880). +registration(r6392,c66,s1881). +registration(r6393,c160,s1881). +registration(r6394,c238,s1881). +registration(r6395,c252,s1882). +registration(r6396,c196,s1882). +registration(r6397,c93,s1882). +registration(r6398,c74,s1883). +registration(r6399,c111,s1883). +registration(r6400,c240,s1883). +registration(r6401,c133,s1883). +registration(r6402,c17,s1884). +registration(r6403,c251,s1884). +registration(r6404,c213,s1884). +registration(r6405,c103,s1884). +registration(r6406,c102,s1885). +registration(r6407,c89,s1885). +registration(r6408,c248,s1885). +registration(r6409,c25,s1885). +registration(r6410,c246,s1886). +registration(r6411,c102,s1886). +registration(r6412,c244,s1886). +registration(r6413,c226,s1886). +registration(r6414,c112,s1887). +registration(r6415,c154,s1887). +registration(r6416,c224,s1887). +registration(r6417,c163,s1888). +registration(r6418,c166,s1888). +registration(r6419,c66,s1888). +registration(r6420,c149,s1888). +registration(r6421,c151,s1889). +registration(r6422,c87,s1889). +registration(r6423,c88,s1889). +registration(r6424,c43,s1889). +registration(r6425,c187,s1890). +registration(r6426,c149,s1890). +registration(r6427,c145,s1890). +registration(r6428,c140,s1890). +registration(r6429,c46,s1891). +registration(r6430,c29,s1891). +registration(r6431,c147,s1891). +registration(r6432,c204,s1891). +registration(r6433,c155,s1892). +registration(r6434,c247,s1892). +registration(r6435,c59,s1892). +registration(r6436,c113,s1893). +registration(r6437,c45,s1893). +registration(r6438,c124,s1893). +registration(r6439,c111,s1893). +registration(r6440,c173,s1894). +registration(r6441,c183,s1894). +registration(r6442,c36,s1894). +registration(r6443,c16,s1894). +registration(r6444,c50,s1895). +registration(r6445,c60,s1895). +registration(r6446,c115,s1895). +registration(r6447,c136,s1896). +registration(r6448,c85,s1896). +registration(r6449,c107,s1896). +registration(r6450,c253,s1897). +registration(r6451,c76,s1897). +registration(r6452,c134,s1897). +registration(r6453,c125,s1898). +registration(r6454,c4,s1898). +registration(r6455,c30,s1898). +registration(r6456,c75,s1899). +registration(r6457,c208,s1899). +registration(r6458,c141,s1899). +registration(r6459,c59,s1900). +registration(r6460,c115,s1900). +registration(r6461,c131,s1900). +registration(r6462,c57,s1901). +registration(r6463,c115,s1901). +registration(r6464,c192,s1901). +registration(r6465,c142,s1902). +registration(r6466,c53,s1902). +registration(r6467,c146,s1902). +registration(r6468,c5,s1903). +registration(r6469,c247,s1903). +registration(r6470,c57,s1903). +registration(r6471,c33,s1904). +registration(r6472,c10,s1904). +registration(r6473,c197,s1904). +registration(r6474,c59,s1905). +registration(r6475,c139,s1905). +registration(r6476,c47,s1905). +registration(r6477,c141,s1906). +registration(r6478,c4,s1906). +registration(r6479,c186,s1906). +registration(r6480,c69,s1906). +registration(r6481,c74,s1907). +registration(r6482,c184,s1907). +registration(r6483,c253,s1907). +registration(r6484,c140,s1908). +registration(r6485,c44,s1908). +registration(r6486,c133,s1908). +registration(r6487,c139,s1908). +registration(r6488,c124,s1909). +registration(r6489,c82,s1909). +registration(r6490,c23,s1909). +registration(r6491,c33,s1910). +registration(r6492,c1,s1910). +registration(r6493,c179,s1910). +registration(r6494,c62,s1911). +registration(r6495,c177,s1911). +registration(r6496,c6,s1911). +registration(r6497,c11,s1912). +registration(r6498,c64,s1912). +registration(r6499,c80,s1912). +registration(r6500,c153,s1913). +registration(r6501,c8,s1913). +registration(r6502,c122,s1913). +registration(r6503,c6,s1914). +registration(r6504,c189,s1914). +registration(r6505,c130,s1914). +registration(r6506,c13,s1915). +registration(r6507,c9,s1915). +registration(r6508,c42,s1915). +registration(r6509,c72,s1915). +registration(r6510,c71,s1916). +registration(r6511,c72,s1916). +registration(r6512,c81,s1916). +registration(r6513,c142,s1917). +registration(r6514,c121,s1917). +registration(r6515,c139,s1917). +registration(r6516,c185,s1917). +registration(r6517,c83,s1918). +registration(r6518,c7,s1918). +registration(r6519,c231,s1918). +registration(r6520,c240,s1919). +registration(r6521,c74,s1919). +registration(r6522,c49,s1919). +registration(r6523,c239,s1920). +registration(r6524,c111,s1920). +registration(r6525,c221,s1920). +registration(r6526,c232,s1921). +registration(r6527,c239,s1921). +registration(r6528,c161,s1921). +registration(r6529,c138,s1921). +registration(r6530,c118,s1922). +registration(r6531,c220,s1922). +registration(r6532,c178,s1922). +registration(r6533,c44,s1923). +registration(r6534,c136,s1923). +registration(r6535,c126,s1923). +registration(r6536,c209,s1923). +registration(r6537,c236,s1924). +registration(r6538,c6,s1924). +registration(r6539,c161,s1924). +registration(r6540,c236,s1925). +registration(r6541,c191,s1925). +registration(r6542,c227,s1925). +registration(r6543,c84,s1926). +registration(r6544,c28,s1926). +registration(r6545,c119,s1926). +registration(r6546,c102,s1926). +registration(r6547,c116,s1927). +registration(r6548,c50,s1927). +registration(r6549,c242,s1927). +registration(r6550,c206,s1928). +registration(r6551,c18,s1928). +registration(r6552,c165,s1928). +registration(r6553,c46,s1929). +registration(r6554,c183,s1929). +registration(r6555,c36,s1929). +registration(r6556,c17,s1930). +registration(r6557,c85,s1930). +registration(r6558,c42,s1930). +registration(r6559,c22,s1931). +registration(r6560,c96,s1931). +registration(r6561,c49,s1931). +registration(r6562,c134,s1931). +registration(r6563,c112,s1932). +registration(r6564,c135,s1932). +registration(r6565,c85,s1932). +registration(r6566,c203,s1933). +registration(r6567,c167,s1933). +registration(r6568,c222,s1933). +registration(r6569,c81,s1933). +registration(r6570,c61,s1934). +registration(r6571,c248,s1934). +registration(r6572,c228,s1934). +registration(r6573,c155,s1934). +registration(r6574,c161,s1935). +registration(r6575,c115,s1935). +registration(r6576,c36,s1935). +registration(r6577,c78,s1936). +registration(r6578,c83,s1936). +registration(r6579,c19,s1936). +registration(r6580,c68,s1937). +registration(r6581,c185,s1937). +registration(r6582,c195,s1937). +registration(r6583,c74,s1937). +registration(r6584,c31,s1938). +registration(r6585,c159,s1938). +registration(r6586,c55,s1938). +registration(r6587,c20,s1939). +registration(r6588,c23,s1939). +registration(r6589,c154,s1939). +registration(r6590,c145,s1940). +registration(r6591,c166,s1940). +registration(r6592,c209,s1940). +registration(r6593,c115,s1941). +registration(r6594,c43,s1941). +registration(r6595,c104,s1941). +registration(r6596,c243,s1941). +registration(r6597,c121,s1942). +registration(r6598,c7,s1942). +registration(r6599,c28,s1942). +registration(r6600,c77,s1942). +registration(r6601,c240,s1943). +registration(r6602,c21,s1943). +registration(r6603,c254,s1943). +registration(r6604,c157,s1944). +registration(r6605,c112,s1944). +registration(r6606,c32,s1944). +registration(r6607,c55,s1945). +registration(r6608,c126,s1945). +registration(r6609,c71,s1945). +registration(r6610,c238,s1945). +registration(r6611,c92,s1946). +registration(r6612,c199,s1946). +registration(r6613,c48,s1946). +registration(r6614,c152,s1947). +registration(r6615,c246,s1947). +registration(r6616,c229,s1947). +registration(r6617,c238,s1948). +registration(r6618,c106,s1948). +registration(r6619,c157,s1948). +registration(r6620,c142,s1949). +registration(r6621,c80,s1949). +registration(r6622,c62,s1949). +registration(r6623,c220,s1950). +registration(r6624,c58,s1950). +registration(r6625,c166,s1950). +registration(r6626,c222,s1951). +registration(r6627,c62,s1951). +registration(r6628,c8,s1951). +registration(r6629,c246,s1952). +registration(r6630,c197,s1952). +registration(r6631,c21,s1952). +registration(r6632,c149,s1952). +registration(r6633,c191,s1952). +registration(r6634,c140,s1953). +registration(r6635,c239,s1953). +registration(r6636,c15,s1953). +registration(r6637,c123,s1954). +registration(r6638,c155,s1954). +registration(r6639,c24,s1954). +registration(r6640,c104,s1954). +registration(r6641,c249,s1955). +registration(r6642,c242,s1955). +registration(r6643,c237,s1955). +registration(r6644,c148,s1955). +registration(r6645,c151,s1956). +registration(r6646,c239,s1956). +registration(r6647,c115,s1956). +registration(r6648,c222,s1957). +registration(r6649,c36,s1957). +registration(r6650,c239,s1957). +registration(r6651,c22,s1958). +registration(r6652,c60,s1958). +registration(r6653,c69,s1958). +registration(r6654,c51,s1959). +registration(r6655,c231,s1959). +registration(r6656,c197,s1959). +registration(r6657,c98,s1959). +registration(r6658,c41,s1960). +registration(r6659,c29,s1960). +registration(r6660,c139,s1960). +registration(r6661,c126,s1960). +registration(r6662,c130,s1961). +registration(r6663,c237,s1961). +registration(r6664,c172,s1961). +registration(r6665,c132,s1961). +registration(r6666,c141,s1962). +registration(r6667,c90,s1962). +registration(r6668,c149,s1962). +registration(r6669,c132,s1963). +registration(r6670,c17,s1963). +registration(r6671,c187,s1963). +registration(r6672,c255,s1964). +registration(r6673,c113,s1964). +registration(r6674,c21,s1964). +registration(r6675,c88,s1964). +registration(r6676,c68,s1965). +registration(r6677,c187,s1965). +registration(r6678,c59,s1965). +registration(r6679,c199,s1966). +registration(r6680,c1,s1966). +registration(r6681,c240,s1966). +registration(r6682,c222,s1967). +registration(r6683,c242,s1967). +registration(r6684,c155,s1967). +registration(r6685,c42,s1968). +registration(r6686,c189,s1968). +registration(r6687,c35,s1968). +registration(r6688,c168,s1969). +registration(r6689,c167,s1969). +registration(r6690,c249,s1969). +registration(r6691,c248,s1970). +registration(r6692,c179,s1970). +registration(r6693,c11,s1970). +registration(r6694,c14,s1970). +registration(r6695,c111,s1971). +registration(r6696,c201,s1971). +registration(r6697,c34,s1971). +registration(r6698,c234,s1972). +registration(r6699,c222,s1972). +registration(r6700,c145,s1972). +registration(r6701,c97,s1972). +registration(r6702,c34,s1973). +registration(r6703,c255,s1973). +registration(r6704,c210,s1973). +registration(r6705,c144,s1973). +registration(r6706,c213,s1974). +registration(r6707,c191,s1974). +registration(r6708,c206,s1974). +registration(r6709,c199,s1975). +registration(r6710,c191,s1975). +registration(r6711,c93,s1975). +registration(r6712,c105,s1976). +registration(r6713,c236,s1976). +registration(r6714,c130,s1976). +registration(r6715,c75,s1977). +registration(r6716,c115,s1977). +registration(r6717,c57,s1977). +registration(r6718,c25,s1978). +registration(r6719,c128,s1978). +registration(r6720,c142,s1978). +registration(r6721,c175,s1979). +registration(r6722,c123,s1979). +registration(r6723,c195,s1979). +registration(r6724,c84,s1980). +registration(r6725,c53,s1980). +registration(r6726,c103,s1980). +registration(r6727,c179,s1980). +registration(r6728,c234,s1981). +registration(r6729,c114,s1981). +registration(r6730,c44,s1981). +registration(r6731,c149,s1982). +registration(r6732,c152,s1982). +registration(r6733,c104,s1982). +registration(r6734,c180,s1983). +registration(r6735,c87,s1983). +registration(r6736,c46,s1983). +registration(r6737,c72,s1984). +registration(r6738,c33,s1984). +registration(r6739,c67,s1984). +registration(r6740,c242,s1984). +registration(r6741,c65,s1985). +registration(r6742,c213,s1985). +registration(r6743,c83,s1985). +registration(r6744,c136,s1985). +registration(r6745,c78,s1986). +registration(r6746,c75,s1986). +registration(r6747,c58,s1986). +registration(r6748,c54,s1986). +registration(r6749,c73,s1987). +registration(r6750,c226,s1987). +registration(r6751,c148,s1987). +registration(r6752,c253,s1988). +registration(r6753,c195,s1988). +registration(r6754,c109,s1988). +registration(r6755,c156,s1988). +registration(r6756,c84,s1989). +registration(r6757,c210,s1989). +registration(r6758,c230,s1989). +registration(r6759,c170,s1989). +registration(r6760,c136,s1990). +registration(r6761,c7,s1990). +registration(r6762,c237,s1990). +registration(r6763,c213,s1991). +registration(r6764,c135,s1991). +registration(r6765,c226,s1991). +registration(r6766,c210,s1991). +registration(r6767,c63,s1991). +registration(r6768,c10,s1992). +registration(r6769,c202,s1992). +registration(r6770,c137,s1992). +registration(r6771,c104,s1993). +registration(r6772,c103,s1993). +registration(r6773,c91,s1993). +registration(r6774,c215,s1993). +registration(r6775,c72,s1993). +registration(r6776,c116,s1994). +registration(r6777,c99,s1994). +registration(r6778,c27,s1994). +registration(r6779,c49,s1995). +registration(r6780,c5,s1995). +registration(r6781,c100,s1995). +registration(r6782,c193,s1996). +registration(r6783,c146,s1996). +registration(r6784,c199,s1996). +registration(r6785,c234,s1997). +registration(r6786,c28,s1997). +registration(r6787,c146,s1997). +registration(r6788,c39,s1997). +registration(r6789,c181,s1998). +registration(r6790,c20,s1998). +registration(r6791,c187,s1998). +registration(r6792,c124,s1998). +registration(r6793,c74,s1998). +registration(r6794,c83,s1999). +registration(r6795,c37,s1999). +registration(r6796,c149,s1999). +registration(r6797,c176,s2000). +registration(r6798,c33,s2000). +registration(r6799,c99,s2000). +registration(r6800,c199,s2000). +registration(r6801,c26,s2001). +registration(r6802,c24,s2001). +registration(r6803,c136,s2001). +registration(r6804,c208,s2002). +registration(r6805,c35,s2002). +registration(r6806,c202,s2002). +registration(r6807,c246,s2003). +registration(r6808,c20,s2003). +registration(r6809,c19,s2003). +registration(r6810,c206,s2003). +registration(r6811,c201,s2004). +registration(r6812,c165,s2004). +registration(r6813,c230,s2004). +registration(r6814,c249,s2004). +registration(r6815,c168,s2004). +registration(r6816,c193,s2005). +registration(r6817,c148,s2005). +registration(r6818,c89,s2005). +registration(r6819,c60,s2006). +registration(r6820,c9,s2006). +registration(r6821,c191,s2006). +registration(r6822,c72,s2006). +registration(r6823,c5,s2007). +registration(r6824,c2,s2007). +registration(r6825,c24,s2007). +registration(r6826,c206,s2007). +registration(r6827,c224,s2007). +registration(r6828,c196,s2008). +registration(r6829,c23,s2008). +registration(r6830,c243,s2008). +registration(r6831,c194,s2009). +registration(r6832,c58,s2009). +registration(r6833,c231,s2009). +registration(r6834,c225,s2010). +registration(r6835,c179,s2010). +registration(r6836,c249,s2010). +registration(r6837,c83,s2011). +registration(r6838,c134,s2011). +registration(r6839,c65,s2011). +registration(r6840,c1,s2012). +registration(r6841,c231,s2012). +registration(r6842,c177,s2012). +registration(r6843,c181,s2013). +registration(r6844,c94,s2013). +registration(r6845,c22,s2013). +registration(r6846,c247,s2014). +registration(r6847,c71,s2014). +registration(r6848,c122,s2014). +registration(r6849,c188,s2015). +registration(r6850,c172,s2015). +registration(r6851,c242,s2015). +registration(r6852,c66,s2016). +registration(r6853,c133,s2016). +registration(r6854,c9,s2016). +registration(r6855,c83,s2016). +registration(r6856,c143,s2017). +registration(r6857,c173,s2017). +registration(r6858,c148,s2017). +registration(r6859,c60,s2017). +registration(r6860,c7,s2018). +registration(r6861,c239,s2018). +registration(r6862,c220,s2018). +registration(r6863,c60,s2019). +registration(r6864,c11,s2019). +registration(r6865,c40,s2019). +registration(r6866,c113,s2019). +registration(r6867,c26,s2020). +registration(r6868,c237,s2020). +registration(r6869,c40,s2020). +registration(r6870,c26,s2021). +registration(r6871,c122,s2021). +registration(r6872,c240,s2021). +registration(r6873,c249,s2022). +registration(r6874,c151,s2022). +registration(r6875,c37,s2022). +registration(r6876,c211,s2022). +registration(r6877,c225,s2023). +registration(r6878,c69,s2023). +registration(r6879,c16,s2023). +registration(r6880,c255,s2024). +registration(r6881,c84,s2024). +registration(r6882,c65,s2024). +registration(r6883,c77,s2025). +registration(r6884,c204,s2025). +registration(r6885,c48,s2025). +registration(r6886,c75,s2026). +registration(r6887,c61,s2026). +registration(r6888,c100,s2026). +registration(r6889,c216,s2026). +registration(r6890,c155,s2027). +registration(r6891,c200,s2027). +registration(r6892,c218,s2027). +registration(r6893,c114,s2028). +registration(r6894,c192,s2028). +registration(r6895,c15,s2028). +registration(r6896,c240,s2029). +registration(r6897,c222,s2029). +registration(r6898,c162,s2029). +registration(r6899,c163,s2029). +registration(r6900,c188,s2030). +registration(r6901,c110,s2030). +registration(r6902,c71,s2030). +registration(r6903,c20,s2031). +registration(r6904,c126,s2031). +registration(r6905,c11,s2031). +registration(r6906,c73,s2032). +registration(r6907,c180,s2032). +registration(r6908,c235,s2032). +registration(r6909,c49,s2032). +registration(r6910,c234,s2033). +registration(r6911,c13,s2033). +registration(r6912,c32,s2033). +registration(r6913,c224,s2034). +registration(r6914,c187,s2034). +registration(r6915,c24,s2034). +registration(r6916,c248,s2035). +registration(r6917,c23,s2035). +registration(r6918,c20,s2035). +registration(r6919,c187,s2035). +registration(r6920,c148,s2036). +registration(r6921,c4,s2036). +registration(r6922,c30,s2036). +registration(r6923,c157,s2036). +registration(r6924,c93,s2037). +registration(r6925,c106,s2037). +registration(r6926,c101,s2037). +registration(r6927,c79,s2037). +registration(r6928,c200,s2038). +registration(r6929,c80,s2038). +registration(r6930,c214,s2038). +registration(r6931,c246,s2039). +registration(r6932,c94,s2039). +registration(r6933,c220,s2039). +registration(r6934,c245,s2039). +registration(r6935,c74,s2040). +registration(r6936,c200,s2040). +registration(r6937,c239,s2040). +registration(r6938,c21,s2041). +registration(r6939,c30,s2041). +registration(r6940,c173,s2041). +registration(r6941,c203,s2041). +registration(r6942,c251,s2042). +registration(r6943,c58,s2042). +registration(r6944,c103,s2042). +registration(r6945,c204,s2043). +registration(r6946,c254,s2043). +registration(r6947,c193,s2043). +registration(r6948,c197,s2043). +registration(r6949,c242,s2043). +registration(r6950,c120,s2044). +registration(r6951,c112,s2044). +registration(r6952,c234,s2044). +registration(r6953,c193,s2045). +registration(r6954,c243,s2045). +registration(r6955,c68,s2045). +registration(r6956,c186,s2045). +registration(r6957,c109,s2046). +registration(r6958,c151,s2046). +registration(r6959,c73,s2046). +registration(r6960,c243,s2047). +registration(r6961,c172,s2047). +registration(r6962,c15,s2047). +registration(r6963,c118,s2048). +registration(r6964,c70,s2048). +registration(r6965,c142,s2048). +registration(r6966,c79,s2049). +registration(r6967,c96,s2049). +registration(r6968,c11,s2049). +registration(r6969,c132,s2050). +registration(r6970,c212,s2050). +registration(r6971,c61,s2050). +registration(r6972,c254,s2050). +registration(r6973,c80,s2051). +registration(r6974,c103,s2051). +registration(r6975,c10,s2051). +registration(r6976,c156,s2051). +registration(r6977,c162,s2052). +registration(r6978,c229,s2052). +registration(r6979,c3,s2052). +registration(r6980,c176,s2053). +registration(r6981,c246,s2053). +registration(r6982,c199,s2053). +registration(r6983,c14,s2054). +registration(r6984,c39,s2054). +registration(r6985,c176,s2054). +registration(r6986,c15,s2055). +registration(r6987,c96,s2055). +registration(r6988,c217,s2055). +registration(r6989,c172,s2056). +registration(r6990,c160,s2056). +registration(r6991,c65,s2056). +registration(r6992,c145,s2057). +registration(r6993,c54,s2057). +registration(r6994,c170,s2057). +registration(r6995,c33,s2058). +registration(r6996,c65,s2058). +registration(r6997,c183,s2058). +registration(r6998,c40,s2058). +registration(r6999,c214,s2059). +registration(r7000,c29,s2059). +registration(r7001,c88,s2059). +registration(r7002,c102,s2060). +registration(r7003,c150,s2060). +registration(r7004,c58,s2060). +registration(r7005,c74,s2060). +registration(r7006,c25,s2061). +registration(r7007,c229,s2061). +registration(r7008,c172,s2061). +registration(r7009,c78,s2062). +registration(r7010,c64,s2062). +registration(r7011,c98,s2062). +registration(r7012,c151,s2063). +registration(r7013,c152,s2063). +registration(r7014,c110,s2063). +registration(r7015,c175,s2064). +registration(r7016,c32,s2064). +registration(r7017,c223,s2064). +registration(r7018,c180,s2065). +registration(r7019,c245,s2065). +registration(r7020,c8,s2065). +registration(r7021,c127,s2065). +registration(r7022,c186,s2066). +registration(r7023,c187,s2066). +registration(r7024,c40,s2066). +registration(r7025,c66,s2066). +registration(r7026,c171,s2067). +registration(r7027,c178,s2067). +registration(r7028,c64,s2067). +registration(r7029,c129,s2067). +registration(r7030,c158,s2068). +registration(r7031,c238,s2068). +registration(r7032,c83,s2068). +registration(r7033,c195,s2069). +registration(r7034,c158,s2069). +registration(r7035,c62,s2069). +registration(r7036,c29,s2070). +registration(r7037,c75,s2070). +registration(r7038,c113,s2070). +registration(r7039,c121,s2071). +registration(r7040,c247,s2071). +registration(r7041,c191,s2071). +registration(r7042,c123,s2072). +registration(r7043,c16,s2072). +registration(r7044,c119,s2072). +registration(r7045,c34,s2073). +registration(r7046,c51,s2073). +registration(r7047,c149,s2073). +registration(r7048,c22,s2073). +registration(r7049,c254,s2074). +registration(r7050,c32,s2074). +registration(r7051,c106,s2074). +registration(r7052,c45,s2075). +registration(r7053,c211,s2075). +registration(r7054,c229,s2075). +registration(r7055,c3,s2076). +registration(r7056,c235,s2076). +registration(r7057,c5,s2076). +registration(r7058,c126,s2076). +registration(r7059,c205,s2077). +registration(r7060,c235,s2077). +registration(r7061,c100,s2077). +registration(r7062,c118,s2078). +registration(r7063,c246,s2078). +registration(r7064,c229,s2078). +registration(r7065,c24,s2078). +registration(r7066,c95,s2079). +registration(r7067,c122,s2079). +registration(r7068,c75,s2079). +registration(r7069,c108,s2080). +registration(r7070,c224,s2080). +registration(r7071,c172,s2080). +registration(r7072,c13,s2080). +registration(r7073,c248,s2081). +registration(r7074,c173,s2081). +registration(r7075,c19,s2081). +registration(r7076,c24,s2082). +registration(r7077,c211,s2082). +registration(r7078,c195,s2082). +registration(r7079,c175,s2083). +registration(r7080,c251,s2083). +registration(r7081,c31,s2083). +registration(r7082,c114,s2083). +registration(r7083,c253,s2083). +registration(r7084,c60,s2084). +registration(r7085,c48,s2084). +registration(r7086,c22,s2084). +registration(r7087,c98,s2085). +registration(r7088,c17,s2085). +registration(r7089,c35,s2085). +registration(r7090,c207,s2086). +registration(r7091,c226,s2086). +registration(r7092,c255,s2086). +registration(r7093,c173,s2087). +registration(r7094,c99,s2087). +registration(r7095,c216,s2087). +registration(r7096,c170,s2088). +registration(r7097,c10,s2088). +registration(r7098,c19,s2088). +registration(r7099,c14,s2089). +registration(r7100,c108,s2089). +registration(r7101,c208,s2089). +registration(r7102,c205,s2090). +registration(r7103,c188,s2090). +registration(r7104,c177,s2090). +registration(r7105,c93,s2091). +registration(r7106,c70,s2091). +registration(r7107,c108,s2091). +registration(r7108,c92,s2091). +registration(r7109,c79,s2092). +registration(r7110,c248,s2092). +registration(r7111,c92,s2092). +registration(r7112,c9,s2093). +registration(r7113,c3,s2093). +registration(r7114,c173,s2093). +registration(r7115,c87,s2094). +registration(r7116,c90,s2094). +registration(r7117,c146,s2094). +registration(r7118,c160,s2094). +registration(r7119,c14,s2095). +registration(r7120,c228,s2095). +registration(r7121,c33,s2095). +registration(r7122,c222,s2096). +registration(r7123,c68,s2096). +registration(r7124,c150,s2096). +registration(r7125,c221,s2097). +registration(r7126,c162,s2097). +registration(r7127,c34,s2097). +registration(r7128,c114,s2097). +registration(r7129,c236,s2098). +registration(r7130,c91,s2098). +registration(r7131,c18,s2098). +registration(r7132,c21,s2099). +registration(r7133,c110,s2099). +registration(r7134,c181,s2099). +registration(r7135,c14,s2100). +registration(r7136,c39,s2100). +registration(r7137,c104,s2100). +registration(r7138,c199,s2100). +registration(r7139,c6,s2101). +registration(r7140,c231,s2101). +registration(r7141,c8,s2101). +registration(r7142,c75,s2102). +registration(r7143,c80,s2102). +registration(r7144,c253,s2102). +registration(r7145,c160,s2102). +registration(r7146,c16,s2103). +registration(r7147,c33,s2103). +registration(r7148,c161,s2103). +registration(r7149,c253,s2103). +registration(r7150,c150,s2104). +registration(r7151,c206,s2104). +registration(r7152,c97,s2104). +registration(r7153,c22,s2105). +registration(r7154,c66,s2105). +registration(r7155,c0,s2105). +registration(r7156,c105,s2105). +registration(r7157,c71,s2106). +registration(r7158,c46,s2106). +registration(r7159,c223,s2106). +registration(r7160,c230,s2106). +registration(r7161,c8,s2107). +registration(r7162,c219,s2107). +registration(r7163,c50,s2107). +registration(r7164,c32,s2108). +registration(r7165,c133,s2108). +registration(r7166,c120,s2108). +registration(r7167,c167,s2108). +registration(r7168,c182,s2108). +registration(r7169,c179,s2109). +registration(r7170,c22,s2109). +registration(r7171,c75,s2109). +registration(r7172,c247,s2110). +registration(r7173,c189,s2110). +registration(r7174,c142,s2110). +registration(r7175,c181,s2111). +registration(r7176,c160,s2111). +registration(r7177,c39,s2111). +registration(r7178,c6,s2112). +registration(r7179,c76,s2112). +registration(r7180,c229,s2112). +registration(r7181,c192,s2113). +registration(r7182,c30,s2113). +registration(r7183,c171,s2113). +registration(r7184,c48,s2114). +registration(r7185,c17,s2114). +registration(r7186,c113,s2114). +registration(r7187,c37,s2114). +registration(r7188,c138,s2115). +registration(r7189,c66,s2115). +registration(r7190,c112,s2115). +registration(r7191,c188,s2115). +registration(r7192,c202,s2116). +registration(r7193,c75,s2116). +registration(r7194,c160,s2116). +registration(r7195,c64,s2116). +registration(r7196,c177,s2117). +registration(r7197,c253,s2117). +registration(r7198,c17,s2117). +registration(r7199,c246,s2118). +registration(r7200,c163,s2118). +registration(r7201,c155,s2118). +registration(r7202,c72,s2119). +registration(r7203,c80,s2119). +registration(r7204,c2,s2119). +registration(r7205,c114,s2120). +registration(r7206,c80,s2120). +registration(r7207,c142,s2120). +registration(r7208,c207,s2121). +registration(r7209,c8,s2121). +registration(r7210,c232,s2121). +registration(r7211,c178,s2122). +registration(r7212,c214,s2122). +registration(r7213,c17,s2122). +registration(r7214,c83,s2123). +registration(r7215,c237,s2123). +registration(r7216,c212,s2123). +registration(r7217,c30,s2124). +registration(r7218,c91,s2124). +registration(r7219,c73,s2124). +registration(r7220,c12,s2124). +registration(r7221,c4,s2125). +registration(r7222,c98,s2125). +registration(r7223,c16,s2125). +registration(r7224,c130,s2126). +registration(r7225,c206,s2126). +registration(r7226,c80,s2126). +registration(r7227,c169,s2126). +registration(r7228,c34,s2126). +registration(r7229,c146,s2127). +registration(r7230,c172,s2127). +registration(r7231,c147,s2127). +registration(r7232,c165,s2128). +registration(r7233,c128,s2128). +registration(r7234,c89,s2128). +registration(r7235,c47,s2129). +registration(r7236,c93,s2129). +registration(r7237,c18,s2129). +registration(r7238,c92,s2130). +registration(r7239,c9,s2130). +registration(r7240,c202,s2130). +registration(r7241,c43,s2130). +registration(r7242,c121,s2131). +registration(r7243,c139,s2131). +registration(r7244,c239,s2131). +registration(r7245,c64,s2132). +registration(r7246,c22,s2132). +registration(r7247,c3,s2132). +registration(r7248,c149,s2133). +registration(r7249,c13,s2133). +registration(r7250,c206,s2133). +registration(r7251,c115,s2134). +registration(r7252,c90,s2134). +registration(r7253,c234,s2134). +registration(r7254,c25,s2135). +registration(r7255,c201,s2135). +registration(r7256,c220,s2135). +registration(r7257,c56,s2136). +registration(r7258,c113,s2136). +registration(r7259,c74,s2136). +registration(r7260,c117,s2137). +registration(r7261,c27,s2137). +registration(r7262,c8,s2137). +registration(r7263,c98,s2137). +registration(r7264,c165,s2138). +registration(r7265,c46,s2138). +registration(r7266,c101,s2138). +registration(r7267,c106,s2138). +registration(r7268,c21,s2139). +registration(r7269,c56,s2139). +registration(r7270,c212,s2139). +registration(r7271,c46,s2140). +registration(r7272,c145,s2140). +registration(r7273,c23,s2140). +registration(r7274,c224,s2141). +registration(r7275,c211,s2141). +registration(r7276,c18,s2141). +registration(r7277,c130,s2141). +registration(r7278,c171,s2142). +registration(r7279,c175,s2142). +registration(r7280,c1,s2142). +registration(r7281,c203,s2142). +registration(r7282,c132,s2142). +registration(r7283,c227,s2143). +registration(r7284,c107,s2143). +registration(r7285,c43,s2143). +registration(r7286,c208,s2143). +registration(r7287,c123,s2144). +registration(r7288,c203,s2144). +registration(r7289,c72,s2144). +registration(r7290,c238,s2145). +registration(r7291,c94,s2145). +registration(r7292,c205,s2145). +registration(r7293,c197,s2146). +registration(r7294,c41,s2146). +registration(r7295,c86,s2146). +registration(r7296,c182,s2147). +registration(r7297,c166,s2147). +registration(r7298,c192,s2147). +registration(r7299,c192,s2148). +registration(r7300,c130,s2148). +registration(r7301,c32,s2148). +registration(r7302,c4,s2148). +registration(r7303,c54,s2149). +registration(r7304,c52,s2149). +registration(r7305,c22,s2149). +registration(r7306,c105,s2149). +registration(r7307,c210,s2150). +registration(r7308,c176,s2150). +registration(r7309,c69,s2150). +registration(r7310,c164,s2151). +registration(r7311,c63,s2151). +registration(r7312,c30,s2151). +registration(r7313,c5,s2151). +registration(r7314,c111,s2152). +registration(r7315,c159,s2152). +registration(r7316,c132,s2152). +registration(r7317,c69,s2152). +registration(r7318,c136,s2153). +registration(r7319,c156,s2153). +registration(r7320,c5,s2153). +registration(r7321,c190,s2153). +registration(r7322,c20,s2154). +registration(r7323,c193,s2154). +registration(r7324,c6,s2154). +registration(r7325,c14,s2155). +registration(r7326,c178,s2155). +registration(r7327,c106,s2155). +registration(r7328,c176,s2156). +registration(r7329,c82,s2156). +registration(r7330,c2,s2156). +registration(r7331,c32,s2157). +registration(r7332,c110,s2157). +registration(r7333,c152,s2157). +registration(r7334,c55,s2158). +registration(r7335,c237,s2158). +registration(r7336,c4,s2158). +registration(r7337,c141,s2158). +registration(r7338,c25,s2159). +registration(r7339,c56,s2159). +registration(r7340,c153,s2159). +registration(r7341,c174,s2159). +registration(r7342,c152,s2160). +registration(r7343,c13,s2160). +registration(r7344,c247,s2160). +registration(r7345,c169,s2160). +registration(r7346,c220,s2161). +registration(r7347,c252,s2161). +registration(r7348,c12,s2161). +registration(r7349,c14,s2162). +registration(r7350,c224,s2162). +registration(r7351,c225,s2162). +registration(r7352,c78,s2162). +registration(r7353,c152,s2163). +registration(r7354,c44,s2163). +registration(r7355,c176,s2163). +registration(r7356,c46,s2163). +registration(r7357,c184,s2164). +registration(r7358,c189,s2164). +registration(r7359,c70,s2164). +registration(r7360,c30,s2165). +registration(r7361,c247,s2165). +registration(r7362,c4,s2165). +registration(r7363,c251,s2165). +registration(r7364,c40,s2166). +registration(r7365,c33,s2166). +registration(r7366,c166,s2166). +registration(r7367,c29,s2166). +registration(r7368,c145,s2167). +registration(r7369,c108,s2167). +registration(r7370,c193,s2167). +registration(r7371,c239,s2168). +registration(r7372,c191,s2168). +registration(r7373,c199,s2168). +registration(r7374,c119,s2169). +registration(r7375,c14,s2169). +registration(r7376,c30,s2169). +registration(r7377,c219,s2170). +registration(r7378,c237,s2170). +registration(r7379,c181,s2170). +registration(r7380,c11,s2170). +registration(r7381,c53,s2171). +registration(r7382,c195,s2171). +registration(r7383,c178,s2171). +registration(r7384,c236,s2171). +registration(r7385,c215,s2172). +registration(r7386,c241,s2172). +registration(r7387,c242,s2172). +registration(r7388,c95,s2173). +registration(r7389,c73,s2173). +registration(r7390,c244,s2173). +registration(r7391,c180,s2174). +registration(r7392,c117,s2174). +registration(r7393,c194,s2174). +registration(r7394,c208,s2175). +registration(r7395,c190,s2175). +registration(r7396,c146,s2175). +registration(r7397,c128,s2176). +registration(r7398,c77,s2176). +registration(r7399,c204,s2176). +registration(r7400,c1,s2177). +registration(r7401,c80,s2177). +registration(r7402,c176,s2177). +registration(r7403,c59,s2177). +registration(r7404,c9,s2178). +registration(r7405,c45,s2178). +registration(r7406,c119,s2178). +registration(r7407,c213,s2179). +registration(r7408,c220,s2179). +registration(r7409,c161,s2179). +registration(r7410,c86,s2179). +registration(r7411,c250,s2180). +registration(r7412,c215,s2180). +registration(r7413,c248,s2180). +registration(r7414,c184,s2181). +registration(r7415,c124,s2181). +registration(r7416,c63,s2181). +registration(r7417,c142,s2182). +registration(r7418,c29,s2182). +registration(r7419,c137,s2182). +registration(r7420,c217,s2182). +registration(r7421,c58,s2183). +registration(r7422,c82,s2183). +registration(r7423,c20,s2183). +registration(r7424,c65,s2184). +registration(r7425,c51,s2184). +registration(r7426,c239,s2184). +registration(r7427,c203,s2184). +registration(r7428,c147,s2185). +registration(r7429,c141,s2185). +registration(r7430,c226,s2185). +registration(r7431,c186,s2186). +registration(r7432,c228,s2186). +registration(r7433,c112,s2186). +registration(r7434,c238,s2187). +registration(r7435,c161,s2187). +registration(r7436,c237,s2187). +registration(r7437,c12,s2187). +registration(r7438,c118,s2188). +registration(r7439,c187,s2188). +registration(r7440,c43,s2188). +registration(r7441,c125,s2189). +registration(r7442,c100,s2189). +registration(r7443,c180,s2189). +registration(r7444,c231,s2190). +registration(r7445,c200,s2190). +registration(r7446,c149,s2190). +registration(r7447,c41,s2191). +registration(r7448,c127,s2191). +registration(r7449,c118,s2191). +registration(r7450,c7,s2191). +registration(r7451,c248,s2191). +registration(r7452,c121,s2192). +registration(r7453,c147,s2192). +registration(r7454,c149,s2192). +registration(r7455,c130,s2193). +registration(r7456,c84,s2193). +registration(r7457,c103,s2193). +registration(r7458,c34,s2194). +registration(r7459,c187,s2194). +registration(r7460,c26,s2194). +registration(r7461,c58,s2194). +registration(r7462,c203,s2195). +registration(r7463,c18,s2195). +registration(r7464,c38,s2195). +registration(r7465,c188,s2196). +registration(r7466,c163,s2196). +registration(r7467,c112,s2196). +registration(r7468,c232,s2196). +registration(r7469,c250,s2197). +registration(r7470,c42,s2197). +registration(r7471,c24,s2197). +registration(r7472,c171,s2198). +registration(r7473,c134,s2198). +registration(r7474,c12,s2198). +registration(r7475,c97,s2198). +registration(r7476,c72,s2199). +registration(r7477,c153,s2199). +registration(r7478,c44,s2199). +registration(r7479,c71,s2200). +registration(r7480,c131,s2200). +registration(r7481,c141,s2200). +registration(r7482,c159,s2201). +registration(r7483,c236,s2201). +registration(r7484,c1,s2201). +registration(r7485,c165,s2202). +registration(r7486,c237,s2202). +registration(r7487,c141,s2202). +registration(r7488,c137,s2203). +registration(r7489,c243,s2203). +registration(r7490,c236,s2203). +registration(r7491,c153,s2204). +registration(r7492,c2,s2204). +registration(r7493,c165,s2204). +registration(r7494,c7,s2204). +registration(r7495,c195,s2205). +registration(r7496,c165,s2205). +registration(r7497,c50,s2205). +registration(r7498,c249,s2205). +registration(r7499,c178,s2206). +registration(r7500,c134,s2206). +registration(r7501,c64,s2206). +registration(r7502,c38,s2206). +registration(r7503,c3,s2206). +registration(r7504,c162,s2207). +registration(r7505,c214,s2207). +registration(r7506,c168,s2207). +registration(r7507,c113,s2208). +registration(r7508,c99,s2208). +registration(r7509,c238,s2208). +registration(r7510,c106,s2209). +registration(r7511,c252,s2209). +registration(r7512,c233,s2209). +registration(r7513,c101,s2210). +registration(r7514,c122,s2210). +registration(r7515,c168,s2210). +registration(r7516,c31,s2210). +registration(r7517,c88,s2211). +registration(r7518,c25,s2211). +registration(r7519,c84,s2211). +registration(r7520,c161,s2211). +registration(r7521,c13,s2212). +registration(r7522,c198,s2212). +registration(r7523,c194,s2212). +registration(r7524,c104,s2212). +registration(r7525,c185,s2213). +registration(r7526,c248,s2213). +registration(r7527,c254,s2213). +registration(r7528,c91,s2213). +registration(r7529,c143,s2214). +registration(r7530,c174,s2214). +registration(r7531,c87,s2214). +registration(r7532,c197,s2215). +registration(r7533,c44,s2215). +registration(r7534,c254,s2215). +registration(r7535,c39,s2216). +registration(r7536,c95,s2216). +registration(r7537,c175,s2216). +registration(r7538,c2,s2217). +registration(r7539,c140,s2217). +registration(r7540,c26,s2217). +registration(r7541,c223,s2218). +registration(r7542,c90,s2218). +registration(r7543,c169,s2218). +registration(r7544,c99,s2219). +registration(r7545,c65,s2219). +registration(r7546,c243,s2219). +registration(r7547,c224,s2220). +registration(r7548,c29,s2220). +registration(r7549,c76,s2220). +registration(r7550,c228,s2221). +registration(r7551,c254,s2221). +registration(r7552,c212,s2221). +registration(r7553,c170,s2222). +registration(r7554,c10,s2222). +registration(r7555,c156,s2222). +registration(r7556,c21,s2223). +registration(r7557,c93,s2223). +registration(r7558,c24,s2223). +registration(r7559,c244,s2223). +registration(r7560,c15,s2224). +registration(r7561,c80,s2224). +registration(r7562,c92,s2224). +registration(r7563,c190,s2225). +registration(r7564,c153,s2225). +registration(r7565,c54,s2225). +registration(r7566,c24,s2226). +registration(r7567,c106,s2226). +registration(r7568,c133,s2226). +registration(r7569,c105,s2226). +registration(r7570,c78,s2227). +registration(r7571,c233,s2227). +registration(r7572,c76,s2227). +registration(r7573,c87,s2228). +registration(r7574,c41,s2228). +registration(r7575,c238,s2228). +registration(r7576,c74,s2229). +registration(r7577,c250,s2229). +registration(r7578,c110,s2229). +registration(r7579,c125,s2230). +registration(r7580,c143,s2230). +registration(r7581,c6,s2230). +registration(r7582,c196,s2231). +registration(r7583,c110,s2231). +registration(r7584,c9,s2231). +registration(r7585,c167,s2231). +registration(r7586,c122,s2231). +registration(r7587,c44,s2232). +registration(r7588,c115,s2232). +registration(r7589,c142,s2232). +registration(r7590,c119,s2233). +registration(r7591,c226,s2233). +registration(r7592,c77,s2233). +registration(r7593,c57,s2233). +registration(r7594,c250,s2234). +registration(r7595,c28,s2234). +registration(r7596,c182,s2234). +registration(r7597,c37,s2234). +registration(r7598,c131,s2235). +registration(r7599,c195,s2235). +registration(r7600,c161,s2235). +registration(r7601,c203,s2235). +registration(r7602,c229,s2236). +registration(r7603,c142,s2236). +registration(r7604,c230,s2236). +registration(r7605,c141,s2237). +registration(r7606,c17,s2237). +registration(r7607,c27,s2237). +registration(r7608,c169,s2238). +registration(r7609,c79,s2238). +registration(r7610,c69,s2238). +registration(r7611,c49,s2238). +registration(r7612,c44,s2239). +registration(r7613,c108,s2239). +registration(r7614,c11,s2239). +registration(r7615,c138,s2239). +registration(r7616,c107,s2240). +registration(r7617,c160,s2240). +registration(r7618,c230,s2240). +registration(r7619,c136,s2241). +registration(r7620,c2,s2241). +registration(r7621,c47,s2241). +registration(r7622,c190,s2242). +registration(r7623,c229,s2242). +registration(r7624,c213,s2242). +registration(r7625,c231,s2243). +registration(r7626,c121,s2243). +registration(r7627,c44,s2243). +registration(r7628,c124,s2243). +registration(r7629,c177,s2244). +registration(r7630,c67,s2244). +registration(r7631,c173,s2244). +registration(r7632,c25,s2245). +registration(r7633,c81,s2245). +registration(r7634,c151,s2245). +registration(r7635,c3,s2245). +registration(r7636,c66,s2246). +registration(r7637,c249,s2246). +registration(r7638,c241,s2246). +registration(r7639,c245,s2247). +registration(r7640,c212,s2247). +registration(r7641,c127,s2247). +registration(r7642,c101,s2248). +registration(r7643,c179,s2248). +registration(r7644,c241,s2248). +registration(r7645,c107,s2249). +registration(r7646,c5,s2249). +registration(r7647,c6,s2249). +registration(r7648,c182,s2250). +registration(r7649,c209,s2250). +registration(r7650,c46,s2250). +registration(r7651,c72,s2251). +registration(r7652,c77,s2251). +registration(r7653,c216,s2251). +registration(r7654,c219,s2252). +registration(r7655,c44,s2252). +registration(r7656,c88,s2252). +registration(r7657,c217,s2253). +registration(r7658,c194,s2253). +registration(r7659,c167,s2253). +registration(r7660,c60,s2254). +registration(r7661,c192,s2254). +registration(r7662,c82,s2254). +registration(r7663,c153,s2254). +registration(r7664,c153,s2255). +registration(r7665,c159,s2255). +registration(r7666,c242,s2255). +registration(r7667,c32,s2255). +registration(r7668,c248,s2256). +registration(r7669,c79,s2256). +registration(r7670,c165,s2256). +registration(r7671,c242,s2257). +registration(r7672,c18,s2257). +registration(r7673,c131,s2257). +registration(r7674,c176,s2258). +registration(r7675,c169,s2258). +registration(r7676,c188,s2258). +registration(r7677,c127,s2259). +registration(r7678,c44,s2259). +registration(r7679,c222,s2259). +registration(r7680,c104,s2259). +registration(r7681,c113,s2260). +registration(r7682,c151,s2260). +registration(r7683,c55,s2260). +registration(r7684,c215,s2260). +registration(r7685,c81,s2261). +registration(r7686,c87,s2261). +registration(r7687,c247,s2261). +registration(r7688,c71,s2262). +registration(r7689,c160,s2262). +registration(r7690,c137,s2262). +registration(r7691,c155,s2263). +registration(r7692,c99,s2263). +registration(r7693,c227,s2263). +registration(r7694,c140,s2263). +registration(r7695,c69,s2264). +registration(r7696,c152,s2264). +registration(r7697,c16,s2264). +registration(r7698,c239,s2265). +registration(r7699,c226,s2265). +registration(r7700,c45,s2265). +registration(r7701,c196,s2266). +registration(r7702,c198,s2266). +registration(r7703,c178,s2266). +registration(r7704,c4,s2267). +registration(r7705,c76,s2267). +registration(r7706,c150,s2267). +registration(r7707,c221,s2268). +registration(r7708,c158,s2268). +registration(r7709,c36,s2268). +registration(r7710,c192,s2268). +registration(r7711,c33,s2269). +registration(r7712,c20,s2269). +registration(r7713,c75,s2269). +registration(r7714,c142,s2270). +registration(r7715,c206,s2270). +registration(r7716,c178,s2270). +registration(r7717,c161,s2271). +registration(r7718,c54,s2271). +registration(r7719,c193,s2271). +registration(r7720,c139,s2271). +registration(r7721,c246,s2272). +registration(r7722,c63,s2272). +registration(r7723,c122,s2272). +registration(r7724,c198,s2273). +registration(r7725,c41,s2273). +registration(r7726,c68,s2273). +registration(r7727,c227,s2273). +registration(r7728,c135,s2274). +registration(r7729,c197,s2274). +registration(r7730,c20,s2274). +registration(r7731,c40,s2275). +registration(r7732,c146,s2275). +registration(r7733,c28,s2275). +registration(r7734,c234,s2275). +registration(r7735,c124,s2276). +registration(r7736,c115,s2276). +registration(r7737,c126,s2276). +registration(r7738,c172,s2276). +registration(r7739,c78,s2277). +registration(r7740,c55,s2277). +registration(r7741,c196,s2277). +registration(r7742,c62,s2278). +registration(r7743,c217,s2278). +registration(r7744,c188,s2278). +registration(r7745,c2,s2278). +registration(r7746,c104,s2278). +registration(r7747,c9,s2279). +registration(r7748,c228,s2279). +registration(r7749,c240,s2279). +registration(r7750,c57,s2280). +registration(r7751,c181,s2280). +registration(r7752,c32,s2280). +registration(r7753,c235,s2281). +registration(r7754,c236,s2281). +registration(r7755,c186,s2281). +registration(r7756,c57,s2282). +registration(r7757,c135,s2282). +registration(r7758,c12,s2282). +registration(r7759,c67,s2283). +registration(r7760,c60,s2283). +registration(r7761,c26,s2283). +registration(r7762,c243,s2284). +registration(r7763,c119,s2284). +registration(r7764,c129,s2284). +registration(r7765,c233,s2285). +registration(r7766,c0,s2285). +registration(r7767,c92,s2285). +registration(r7768,c85,s2286). +registration(r7769,c19,s2286). +registration(r7770,c133,s2286). +registration(r7771,c85,s2287). +registration(r7772,c97,s2287). +registration(r7773,c203,s2287). +registration(r7774,c200,s2287). +registration(r7775,c74,s2287). +registration(r7776,c79,s2288). +registration(r7777,c56,s2288). +registration(r7778,c196,s2288). +registration(r7779,c124,s2288). +registration(r7780,c63,s2288). +registration(r7781,c55,s2289). +registration(r7782,c124,s2289). +registration(r7783,c51,s2289). +registration(r7784,c42,s2290). +registration(r7785,c40,s2290). +registration(r7786,c231,s2290). +registration(r7787,c133,s2290). +registration(r7788,c249,s2291). +registration(r7789,c217,s2291). +registration(r7790,c210,s2291). +registration(r7791,c179,s2292). +registration(r7792,c211,s2292). +registration(r7793,c176,s2292). +registration(r7794,c122,s2293). +registration(r7795,c171,s2293). +registration(r7796,c48,s2293). +registration(r7797,c245,s2294). +registration(r7798,c239,s2294). +registration(r7799,c95,s2294). +registration(r7800,c151,s2294). +registration(r7801,c113,s2295). +registration(r7802,c99,s2295). +registration(r7803,c71,s2295). +registration(r7804,c112,s2296). +registration(r7805,c84,s2296). +registration(r7806,c184,s2296). +registration(r7807,c177,s2296). +registration(r7808,c207,s2297). +registration(r7809,c235,s2297). +registration(r7810,c47,s2297). +registration(r7811,c157,s2297). +registration(r7812,c208,s2297). +registration(r7813,c29,s2298). +registration(r7814,c232,s2298). +registration(r7815,c76,s2298). +registration(r7816,c22,s2298). +registration(r7817,c172,s2299). +registration(r7818,c13,s2299). +registration(r7819,c7,s2299). +registration(r7820,c3,s2299). +registration(r7821,c165,s2300). +registration(r7822,c116,s2300). +registration(r7823,c154,s2300). +registration(r7824,c40,s2301). +registration(r7825,c93,s2301). +registration(r7826,c56,s2301). +registration(r7827,c78,s2302). +registration(r7828,c147,s2302). +registration(r7829,c32,s2302). +registration(r7830,c64,s2303). +registration(r7831,c216,s2303). +registration(r7832,c196,s2303). +registration(r7833,c245,s2303). +registration(r7834,c93,s2304). +registration(r7835,c190,s2304). +registration(r7836,c198,s2304). +registration(r7837,c211,s2305). +registration(r7838,c123,s2305). +registration(r7839,c118,s2305). +registration(r7840,c28,s2306). +registration(r7841,c76,s2306). +registration(r7842,c78,s2306). +registration(r7843,c47,s2306). +registration(r7844,c102,s2307). +registration(r7845,c104,s2307). +registration(r7846,c86,s2307). +registration(r7847,c233,s2308). +registration(r7848,c216,s2308). +registration(r7849,c239,s2308). +registration(r7850,c197,s2308). +registration(r7851,c112,s2309). +registration(r7852,c43,s2309). +registration(r7853,c189,s2309). +registration(r7854,c137,s2309). +registration(r7855,c226,s2310). +registration(r7856,c254,s2310). +registration(r7857,c229,s2310). +registration(r7858,c93,s2311). +registration(r7859,c142,s2311). +registration(r7860,c43,s2311). +registration(r7861,c121,s2312). +registration(r7862,c132,s2312). +registration(r7863,c9,s2312). +registration(r7864,c112,s2313). +registration(r7865,c69,s2313). +registration(r7866,c164,s2313). +registration(r7867,c46,s2313). +registration(r7868,c22,s2314). +registration(r7869,c218,s2314). +registration(r7870,c151,s2314). +registration(r7871,c195,s2315). +registration(r7872,c154,s2315). +registration(r7873,c103,s2315). +registration(r7874,c73,s2315). +registration(r7875,c75,s2316). +registration(r7876,c252,s2316). +registration(r7877,c1,s2316). +registration(r7878,c142,s2317). +registration(r7879,c240,s2317). +registration(r7880,c211,s2317). +registration(r7881,c88,s2318). +registration(r7882,c114,s2318). +registration(r7883,c89,s2318). +registration(r7884,c159,s2319). +registration(r7885,c230,s2319). +registration(r7886,c9,s2319). +registration(r7887,c32,s2320). +registration(r7888,c169,s2320). +registration(r7889,c251,s2320). +registration(r7890,c190,s2321). +registration(r7891,c152,s2321). +registration(r7892,c91,s2321). +registration(r7893,c175,s2321). +registration(r7894,c87,s2322). +registration(r7895,c171,s2322). +registration(r7896,c167,s2322). +registration(r7897,c5,s2322). +registration(r7898,c12,s2323). +registration(r7899,c218,s2323). +registration(r7900,c159,s2323). +registration(r7901,c19,s2323). +registration(r7902,c208,s2324). +registration(r7903,c117,s2324). +registration(r7904,c245,s2324). +registration(r7905,c255,s2325). +registration(r7906,c62,s2325). +registration(r7907,c192,s2325). +registration(r7908,c231,s2325). +registration(r7909,c29,s2326). +registration(r7910,c221,s2326). +registration(r7911,c123,s2326). +registration(r7912,c135,s2327). +registration(r7913,c101,s2327). +registration(r7914,c224,s2327). +registration(r7915,c137,s2327). +registration(r7916,c250,s2328). +registration(r7917,c22,s2328). +registration(r7918,c191,s2328). +registration(r7919,c239,s2328). +registration(r7920,c125,s2329). +registration(r7921,c35,s2329). +registration(r7922,c114,s2329). +registration(r7923,c104,s2330). +registration(r7924,c190,s2330). +registration(r7925,c246,s2330). +registration(r7926,c182,s2331). +registration(r7927,c134,s2331). +registration(r7928,c229,s2331). +registration(r7929,c194,s2332). +registration(r7930,c238,s2332). +registration(r7931,c89,s2332). +registration(r7932,c192,s2333). +registration(r7933,c221,s2333). +registration(r7934,c83,s2333). +registration(r7935,c78,s2334). +registration(r7936,c232,s2334). +registration(r7937,c37,s2334). +registration(r7938,c134,s2335). +registration(r7939,c211,s2335). +registration(r7940,c252,s2335). +registration(r7941,c148,s2335). +registration(r7942,c96,s2336). +registration(r7943,c224,s2336). +registration(r7944,c139,s2336). +registration(r7945,c66,s2337). +registration(r7946,c79,s2337). +registration(r7947,c195,s2337). +registration(r7948,c133,s2338). +registration(r7949,c164,s2338). +registration(r7950,c76,s2338). +registration(r7951,c13,s2338). +registration(r7952,c95,s2339). +registration(r7953,c110,s2339). +registration(r7954,c223,s2339). +registration(r7955,c199,s2340). +registration(r7956,c235,s2340). +registration(r7957,c17,s2340). +registration(r7958,c228,s2341). +registration(r7959,c155,s2341). +registration(r7960,c105,s2341). +registration(r7961,c48,s2341). +registration(r7962,c230,s2342). +registration(r7963,c187,s2342). +registration(r7964,c145,s2342). +registration(r7965,c225,s2343). +registration(r7966,c133,s2343). +registration(r7967,c179,s2343). +registration(r7968,c87,s2343). +registration(r7969,c33,s2344). +registration(r7970,c142,s2344). +registration(r7971,c113,s2344). +registration(r7972,c237,s2344). +registration(r7973,c14,s2345). +registration(r7974,c178,s2345). +registration(r7975,c155,s2345). +registration(r7976,c173,s2346). +registration(r7977,c116,s2346). +registration(r7978,c14,s2346). +registration(r7979,c121,s2346). +registration(r7980,c152,s2347). +registration(r7981,c65,s2347). +registration(r7982,c67,s2347). +registration(r7983,c214,s2348). +registration(r7984,c66,s2348). +registration(r7985,c253,s2348). +registration(r7986,c177,s2349). +registration(r7987,c140,s2349). +registration(r7988,c213,s2349). +registration(r7989,c173,s2349). +registration(r7990,c123,s2350). +registration(r7991,c222,s2350). +registration(r7992,c80,s2350). +registration(r7993,c3,s2351). +registration(r7994,c246,s2351). +registration(r7995,c192,s2351). +registration(r7996,c54,s2352). +registration(r7997,c175,s2352). +registration(r7998,c53,s2352). +registration(r7999,c207,s2352). +registration(r8000,c137,s2353). +registration(r8001,c106,s2353). +registration(r8002,c77,s2353). +registration(r8003,c145,s2354). +registration(r8004,c133,s2354). +registration(r8005,c249,s2354). +registration(r8006,c134,s2355). +registration(r8007,c48,s2355). +registration(r8008,c65,s2355). +registration(r8009,c189,s2356). +registration(r8010,c19,s2356). +registration(r8011,c229,s2356). +registration(r8012,c255,s2356). +registration(r8013,c15,s2357). +registration(r8014,c193,s2357). +registration(r8015,c136,s2357). +registration(r8016,c55,s2358). +registration(r8017,c233,s2358). +registration(r8018,c62,s2358). +registration(r8019,c199,s2359). +registration(r8020,c202,s2359). +registration(r8021,c6,s2359). +registration(r8022,c150,s2359). +registration(r8023,c213,s2360). +registration(r8024,c5,s2360). +registration(r8025,c242,s2360). +registration(r8026,c139,s2360). +registration(r8027,c77,s2360). +registration(r8028,c193,s2361). +registration(r8029,c182,s2361). +registration(r8030,c11,s2361). +registration(r8031,c35,s2362). +registration(r8032,c212,s2362). +registration(r8033,c132,s2362). +registration(r8034,c149,s2362). +registration(r8035,c230,s2362). +registration(r8036,c140,s2363). +registration(r8037,c68,s2363). +registration(r8038,c207,s2363). +registration(r8039,c135,s2364). +registration(r8040,c146,s2364). +registration(r8041,c109,s2364). +registration(r8042,c122,s2365). +registration(r8043,c37,s2365). +registration(r8044,c183,s2365). +registration(r8045,c195,s2365). +registration(r8046,c11,s2366). +registration(r8047,c59,s2366). +registration(r8048,c17,s2366). +registration(r8049,c28,s2367). +registration(r8050,c162,s2367). +registration(r8051,c141,s2367). +registration(r8052,c17,s2368). +registration(r8053,c115,s2368). +registration(r8054,c12,s2368). +registration(r8055,c89,s2368). +registration(r8056,c100,s2369). +registration(r8057,c39,s2369). +registration(r8058,c99,s2369). +registration(r8059,c175,s2369). +registration(r8060,c119,s2370). +registration(r8061,c60,s2370). +registration(r8062,c215,s2370). +registration(r8063,c141,s2371). +registration(r8064,c112,s2371). +registration(r8065,c122,s2371). +registration(r8066,c181,s2372). +registration(r8067,c97,s2372). +registration(r8068,c72,s2372). +registration(r8069,c234,s2373). +registration(r8070,c52,s2373). +registration(r8071,c189,s2373). +registration(r8072,c48,s2374). +registration(r8073,c109,s2374). +registration(r8074,c101,s2374). +registration(r8075,c201,s2374). +registration(r8076,c176,s2375). +registration(r8077,c104,s2375). +registration(r8078,c210,s2375). +registration(r8079,c73,s2376). +registration(r8080,c156,s2376). +registration(r8081,c52,s2376). +registration(r8082,c194,s2377). +registration(r8083,c170,s2377). +registration(r8084,c119,s2377). +registration(r8085,c39,s2377). +registration(r8086,c116,s2377). +registration(r8087,c112,s2378). +registration(r8088,c212,s2378). +registration(r8089,c243,s2378). +registration(r8090,c176,s2378). +registration(r8091,c187,s2379). +registration(r8092,c78,s2379). +registration(r8093,c225,s2379). +registration(r8094,c179,s2379). +registration(r8095,c46,s2380). +registration(r8096,c125,s2380). +registration(r8097,c26,s2380). +registration(r8098,c121,s2381). +registration(r8099,c246,s2381). +registration(r8100,c152,s2381). +registration(r8101,c43,s2381). +registration(r8102,c19,s2382). +registration(r8103,c238,s2382). +registration(r8104,c127,s2382). +registration(r8105,c166,s2382). +registration(r8106,c186,s2383). +registration(r8107,c119,s2383). +registration(r8108,c22,s2383). +registration(r8109,c113,s2384). +registration(r8110,c152,s2384). +registration(r8111,c27,s2384). +registration(r8112,c231,s2384). +registration(r8113,c86,s2385). +registration(r8114,c155,s2385). +registration(r8115,c103,s2385). +registration(r8116,c130,s2385). +registration(r8117,c29,s2386). +registration(r8118,c104,s2386). +registration(r8119,c251,s2386). +registration(r8120,c0,s2386). +registration(r8121,c64,s2386). +registration(r8122,c212,s2387). +registration(r8123,c36,s2387). +registration(r8124,c47,s2387). +registration(r8125,c48,s2388). +registration(r8126,c249,s2388). +registration(r8127,c106,s2388). +registration(r8128,c248,s2388). +registration(r8129,c19,s2389). +registration(r8130,c130,s2389). +registration(r8131,c146,s2389). +registration(r8132,c176,s2389). +registration(r8133,c45,s2390). +registration(r8134,c5,s2390). +registration(r8135,c21,s2390). +registration(r8136,c45,s2391). +registration(r8137,c22,s2391). +registration(r8138,c168,s2391). +registration(r8139,c188,s2391). +registration(r8140,c149,s2392). +registration(r8141,c35,s2392). +registration(r8142,c252,s2392). +registration(r8143,c42,s2393). +registration(r8144,c189,s2393). +registration(r8145,c247,s2393). +registration(r8146,c98,s2394). +registration(r8147,c4,s2394). +registration(r8148,c200,s2394). +registration(r8149,c74,s2394). +registration(r8150,c238,s2395). +registration(r8151,c71,s2395). +registration(r8152,c249,s2395). +registration(r8153,c254,s2396). +registration(r8154,c123,s2396). +registration(r8155,c9,s2396). +registration(r8156,c32,s2397). +registration(r8157,c50,s2397). +registration(r8158,c63,s2397). +registration(r8159,c237,s2397). +registration(r8160,c86,s2398). +registration(r8161,c233,s2398). +registration(r8162,c61,s2398). +registration(r8163,c251,s2398). +registration(r8164,c149,s2399). +registration(r8165,c111,s2399). +registration(r8166,c179,s2399). +registration(r8167,c123,s2400). +registration(r8168,c84,s2400). +registration(r8169,c140,s2400). +registration(r8170,c211,s2401). +registration(r8171,c189,s2401). +registration(r8172,c168,s2401). +registration(r8173,c37,s2402). +registration(r8174,c81,s2402). +registration(r8175,c70,s2402). +registration(r8176,c119,s2403). +registration(r8177,c13,s2403). +registration(r8178,c165,s2403). +registration(r8179,c250,s2404). +registration(r8180,c79,s2404). +registration(r8181,c31,s2404). +registration(r8182,c27,s2405). +registration(r8183,c46,s2405). +registration(r8184,c212,s2405). +registration(r8185,c73,s2405). +registration(r8186,c74,s2406). +registration(r8187,c123,s2406). +registration(r8188,c212,s2406). +registration(r8189,c188,s2406). +registration(r8190,c206,s2407). +registration(r8191,c102,s2407). +registration(r8192,c239,s2407). +registration(r8193,c64,s2408). +registration(r8194,c209,s2408). +registration(r8195,c92,s2408). +registration(r8196,c105,s2409). +registration(r8197,c86,s2409). +registration(r8198,c175,s2409). +registration(r8199,c254,s2410). +registration(r8200,c105,s2410). +registration(r8201,c233,s2410). +registration(r8202,c24,s2411). +registration(r8203,c55,s2411). +registration(r8204,c86,s2411). +registration(r8205,c159,s2412). +registration(r8206,c184,s2412). +registration(r8207,c81,s2412). +registration(r8208,c249,s2413). +registration(r8209,c124,s2413). +registration(r8210,c220,s2413). +registration(r8211,c105,s2413). +registration(r8212,c40,s2414). +registration(r8213,c217,s2414). +registration(r8214,c198,s2414). +registration(r8215,c48,s2414). +registration(r8216,c49,s2415). +registration(r8217,c210,s2415). +registration(r8218,c122,s2415). +registration(r8219,c229,s2416). +registration(r8220,c108,s2416). +registration(r8221,c50,s2416). +registration(r8222,c105,s2417). +registration(r8223,c192,s2417). +registration(r8224,c195,s2417). +registration(r8225,c123,s2418). +registration(r8226,c57,s2418). +registration(r8227,c13,s2418). +registration(r8228,c138,s2419). +registration(r8229,c207,s2419). +registration(r8230,c28,s2419). +registration(r8231,c69,s2420). +registration(r8232,c108,s2420). +registration(r8233,c255,s2420). +registration(r8234,c142,s2420). +registration(r8235,c80,s2420). +registration(r8236,c96,s2421). +registration(r8237,c171,s2421). +registration(r8238,c212,s2421). +registration(r8239,c143,s2421). +registration(r8240,c99,s2422). +registration(r8241,c250,s2422). +registration(r8242,c196,s2422). +registration(r8243,c136,s2423). +registration(r8244,c180,s2423). +registration(r8245,c25,s2423). +registration(r8246,c238,s2423). +registration(r8247,c245,s2423). +registration(r8248,c34,s2424). +registration(r8249,c178,s2424). +registration(r8250,c196,s2424). +registration(r8251,c253,s2425). +registration(r8252,c131,s2425). +registration(r8253,c175,s2425). +registration(r8254,c62,s2426). +registration(r8255,c45,s2426). +registration(r8256,c245,s2426). +registration(r8257,c200,s2427). +registration(r8258,c208,s2427). +registration(r8259,c103,s2427). +registration(r8260,c51,s2427). +registration(r8261,c206,s2428). +registration(r8262,c0,s2428). +registration(r8263,c30,s2428). +registration(r8264,c55,s2429). +registration(r8265,c91,s2429). +registration(r8266,c163,s2429). +registration(r8267,c197,s2430). +registration(r8268,c16,s2430). +registration(r8269,c22,s2430). +registration(r8270,c86,s2430). +registration(r8271,c137,s2430). +registration(r8272,c5,s2431). +registration(r8273,c17,s2431). +registration(r8274,c46,s2431). +registration(r8275,c33,s2432). +registration(r8276,c227,s2432). +registration(r8277,c22,s2432). +registration(r8278,c127,s2433). +registration(r8279,c243,s2433). +registration(r8280,c230,s2433). +registration(r8281,c231,s2434). +registration(r8282,c0,s2434). +registration(r8283,c26,s2434). +registration(r8284,c116,s2435). +registration(r8285,c63,s2435). +registration(r8286,c151,s2435). +registration(r8287,c168,s2435). +registration(r8288,c218,s2436). +registration(r8289,c9,s2436). +registration(r8290,c253,s2436). +registration(r8291,c2,s2437). +registration(r8292,c254,s2437). +registration(r8293,c189,s2437). +registration(r8294,c223,s2438). +registration(r8295,c42,s2438). +registration(r8296,c84,s2438). +registration(r8297,c211,s2439). +registration(r8298,c189,s2439). +registration(r8299,c197,s2439). +registration(r8300,c173,s2440). +registration(r8301,c182,s2440). +registration(r8302,c152,s2440). +registration(r8303,c14,s2441). +registration(r8304,c138,s2441). +registration(r8305,c132,s2441). +registration(r8306,c43,s2442). +registration(r8307,c175,s2442). +registration(r8308,c151,s2442). +registration(r8309,c157,s2442). +registration(r8310,c44,s2442). +registration(r8311,c155,s2443). +registration(r8312,c231,s2443). +registration(r8313,c114,s2443). +registration(r8314,c158,s2444). +registration(r8315,c44,s2444). +registration(r8316,c145,s2444). +registration(r8317,c79,s2444). +registration(r8318,c67,s2445). +registration(r8319,c182,s2445). +registration(r8320,c208,s2445). +registration(r8321,c106,s2446). +registration(r8322,c59,s2446). +registration(r8323,c89,s2446). +registration(r8324,c221,s2447). +registration(r8325,c77,s2447). +registration(r8326,c84,s2447). +registration(r8327,c252,s2447). +registration(r8328,c50,s2448). +registration(r8329,c154,s2448). +registration(r8330,c21,s2448). +registration(r8331,c253,s2449). +registration(r8332,c209,s2449). +registration(r8333,c14,s2449). +registration(r8334,c59,s2450). +registration(r8335,c87,s2450). +registration(r8336,c238,s2450). +registration(r8337,c49,s2451). +registration(r8338,c241,s2451). +registration(r8339,c118,s2451). +registration(r8340,c93,s2451). +registration(r8341,c93,s2452). +registration(r8342,c183,s2452). +registration(r8343,c89,s2452). +registration(r8344,c149,s2452). +registration(r8345,c118,s2453). +registration(r8346,c159,s2453). +registration(r8347,c164,s2453). +registration(r8348,c61,s2454). +registration(r8349,c121,s2454). +registration(r8350,c48,s2454). +registration(r8351,c3,s2455). +registration(r8352,c129,s2455). +registration(r8353,c59,s2455). +registration(r8354,c145,s2456). +registration(r8355,c98,s2456). +registration(r8356,c248,s2456). +registration(r8357,c233,s2457). +registration(r8358,c173,s2457). +registration(r8359,c181,s2457). +registration(r8360,c19,s2458). +registration(r8361,c255,s2458). +registration(r8362,c231,s2458). +registration(r8363,c143,s2459). +registration(r8364,c172,s2459). +registration(r8365,c50,s2459). +registration(r8366,c5,s2459). +registration(r8367,c113,s2460). +registration(r8368,c136,s2460). +registration(r8369,c53,s2460). +registration(r8370,c57,s2461). +registration(r8371,c102,s2461). +registration(r8372,c56,s2461). +registration(r8373,c203,s2461). +registration(r8374,c16,s2462). +registration(r8375,c26,s2462). +registration(r8376,c3,s2462). +registration(r8377,c178,s2462). +registration(r8378,c90,s2463). +registration(r8379,c75,s2463). +registration(r8380,c63,s2463). +registration(r8381,c40,s2464). +registration(r8382,c164,s2464). +registration(r8383,c223,s2464). +registration(r8384,c18,s2465). +registration(r8385,c236,s2465). +registration(r8386,c95,s2465). +registration(r8387,c93,s2465). +registration(r8388,c77,s2466). +registration(r8389,c65,s2466). +registration(r8390,c229,s2466). +registration(r8391,c31,s2467). +registration(r8392,c54,s2467). +registration(r8393,c201,s2467). +registration(r8394,c226,s2468). +registration(r8395,c237,s2468). +registration(r8396,c233,s2468). +registration(r8397,c69,s2469). +registration(r8398,c49,s2469). +registration(r8399,c223,s2469). +registration(r8400,c7,s2470). +registration(r8401,c87,s2470). +registration(r8402,c92,s2470). +registration(r8403,c109,s2471). +registration(r8404,c172,s2471). +registration(r8405,c7,s2471). +registration(r8406,c239,s2471). +registration(r8407,c210,s2472). +registration(r8408,c74,s2472). +registration(r8409,c213,s2472). +registration(r8410,c243,s2473). +registration(r8411,c142,s2473). +registration(r8412,c186,s2473). +registration(r8413,c157,s2474). +registration(r8414,c204,s2474). +registration(r8415,c191,s2474). +registration(r8416,c5,s2475). +registration(r8417,c182,s2475). +registration(r8418,c74,s2475). +registration(r8419,c82,s2475). +registration(r8420,c15,s2476). +registration(r8421,c142,s2476). +registration(r8422,c18,s2476). +registration(r8423,c189,s2477). +registration(r8424,c191,s2477). +registration(r8425,c126,s2477). +registration(r8426,c81,s2478). +registration(r8427,c17,s2478). +registration(r8428,c131,s2478). +registration(r8429,c119,s2478). +registration(r8430,c58,s2479). +registration(r8431,c190,s2479). +registration(r8432,c85,s2479). +registration(r8433,c93,s2479). +registration(r8434,c208,s2479). +registration(r8435,c224,s2480). +registration(r8436,c139,s2480). +registration(r8437,c212,s2480). +registration(r8438,c141,s2481). +registration(r8439,c201,s2481). +registration(r8440,c39,s2481). +registration(r8441,c57,s2482). +registration(r8442,c85,s2482). +registration(r8443,c81,s2482). +registration(r8444,c209,s2482). +registration(r8445,c189,s2483). +registration(r8446,c194,s2483). +registration(r8447,c34,s2483). +registration(r8448,c206,s2484). +registration(r8449,c211,s2484). +registration(r8450,c185,s2484). +registration(r8451,c143,s2484). +registration(r8452,c23,s2484). +registration(r8453,c237,s2485). +registration(r8454,c49,s2485). +registration(r8455,c230,s2485). +registration(r8456,c187,s2486). +registration(r8457,c100,s2486). +registration(r8458,c146,s2486). +registration(r8459,c186,s2486). +registration(r8460,c230,s2487). +registration(r8461,c131,s2487). +registration(r8462,c243,s2487). +registration(r8463,c234,s2488). +registration(r8464,c79,s2488). +registration(r8465,c165,s2488). +registration(r8466,c200,s2488). +registration(r8467,c119,s2489). +registration(r8468,c85,s2489). +registration(r8469,c151,s2489). +registration(r8470,c160,s2489). +registration(r8471,c220,s2490). +registration(r8472,c33,s2490). +registration(r8473,c182,s2490). +registration(r8474,c157,s2491). +registration(r8475,c151,s2491). +registration(r8476,c15,s2491). +registration(r8477,c162,s2492). +registration(r8478,c163,s2492). +registration(r8479,c41,s2492). +registration(r8480,c173,s2493). +registration(r8481,c80,s2493). +registration(r8482,c197,s2493). +registration(r8483,c20,s2494). +registration(r8484,c41,s2494). +registration(r8485,c227,s2494). +registration(r8486,c241,s2494). +registration(r8487,c124,s2495). +registration(r8488,c136,s2495). +registration(r8489,c165,s2495). +registration(r8490,c128,s2495). +registration(r8491,c174,s2496). +registration(r8492,c222,s2496). +registration(r8493,c73,s2496). +registration(r8494,c123,s2496). +registration(r8495,c17,s2497). +registration(r8496,c213,s2497). +registration(r8497,c222,s2497). +registration(r8498,c7,s2498). +registration(r8499,c17,s2498). +registration(r8500,c1,s2498). +registration(r8501,c199,s2499). +registration(r8502,c54,s2499). +registration(r8503,c156,s2499). +registration(r8504,c127,s2500). +registration(r8505,c1,s2500). +registration(r8506,c80,s2500). +registration(r8507,c216,s2501). +registration(r8508,c125,s2501). +registration(r8509,c11,s2501). +registration(r8510,c185,s2502). +registration(r8511,c221,s2502). +registration(r8512,c73,s2502). +registration(r8513,c44,s2503). +registration(r8514,c204,s2503). +registration(r8515,c47,s2503). +registration(r8516,c128,s2503). +registration(r8517,c18,s2504). +registration(r8518,c145,s2504). +registration(r8519,c169,s2504). +registration(r8520,c111,s2505). +registration(r8521,c254,s2505). +registration(r8522,c142,s2505). +registration(r8523,c14,s2506). +registration(r8524,c78,s2506). +registration(r8525,c175,s2506). +registration(r8526,c135,s2507). +registration(r8527,c102,s2507). +registration(r8528,c215,s2507). +registration(r8529,c144,s2508). +registration(r8530,c100,s2508). +registration(r8531,c176,s2508). +registration(r8532,c219,s2509). +registration(r8533,c24,s2509). +registration(r8534,c236,s2509). +registration(r8535,c147,s2510). +registration(r8536,c248,s2510). +registration(r8537,c41,s2510). +registration(r8538,c28,s2511). +registration(r8539,c172,s2511). +registration(r8540,c191,s2511). +registration(r8541,c28,s2512). +registration(r8542,c186,s2512). +registration(r8543,c69,s2512). +registration(r8544,c16,s2513). +registration(r8545,c83,s2513). +registration(r8546,c8,s2513). +registration(r8547,c110,s2514). +registration(r8548,c121,s2514). +registration(r8549,c61,s2514). +registration(r8550,c197,s2514). +registration(r8551,c249,s2515). +registration(r8552,c220,s2515). +registration(r8553,c231,s2515). +registration(r8554,c124,s2516). +registration(r8555,c216,s2516). +registration(r8556,c160,s2516). +registration(r8557,c189,s2517). +registration(r8558,c99,s2517). +registration(r8559,c86,s2517). +registration(r8560,c116,s2518). +registration(r8561,c34,s2518). +registration(r8562,c161,s2518). +registration(r8563,c178,s2519). +registration(r8564,c146,s2519). +registration(r8565,c205,s2519). +registration(r8566,c59,s2520). +registration(r8567,c18,s2520). +registration(r8568,c171,s2520). +registration(r8569,c167,s2521). +registration(r8570,c82,s2521). +registration(r8571,c181,s2521). +registration(r8572,c42,s2521). +registration(r8573,c12,s2522). +registration(r8574,c10,s2522). +registration(r8575,c203,s2522). +registration(r8576,c136,s2523). +registration(r8577,c40,s2523). +registration(r8578,c250,s2523). +registration(r8579,c111,s2524). +registration(r8580,c20,s2524). +registration(r8581,c38,s2524). +registration(r8582,c215,s2525). +registration(r8583,c66,s2525). +registration(r8584,c166,s2525). +registration(r8585,c226,s2526). +registration(r8586,c131,s2526). +registration(r8587,c89,s2526). +registration(r8588,c1,s2527). +registration(r8589,c142,s2527). +registration(r8590,c17,s2527). +registration(r8591,c59,s2528). +registration(r8592,c158,s2528). +registration(r8593,c203,s2528). +registration(r8594,c98,s2528). +registration(r8595,c143,s2529). +registration(r8596,c138,s2529). +registration(r8597,c104,s2529). +registration(r8598,c216,s2529). +registration(r8599,c149,s2530). +registration(r8600,c53,s2530). +registration(r8601,c135,s2530). +registration(r8602,c202,s2530). +registration(r8603,c21,s2531). +registration(r8604,c127,s2531). +registration(r8605,c121,s2531). +registration(r8606,c211,s2531). +registration(r8607,c52,s2532). +registration(r8608,c95,s2532). +registration(r8609,c213,s2532). +registration(r8610,c102,s2533). +registration(r8611,c131,s2533). +registration(r8612,c171,s2533). +registration(r8613,c77,s2533). +registration(r8614,c102,s2534). +registration(r8615,c189,s2534). +registration(r8616,c63,s2534). +registration(r8617,c193,s2534). +registration(r8618,c0,s2535). +registration(r8619,c254,s2535). +registration(r8620,c86,s2535). +registration(r8621,c196,s2536). +registration(r8622,c67,s2536). +registration(r8623,c81,s2536). +registration(r8624,c202,s2537). +registration(r8625,c211,s2537). +registration(r8626,c196,s2537). +registration(r8627,c36,s2537). +registration(r8628,c114,s2538). +registration(r8629,c201,s2538). +registration(r8630,c147,s2538). +registration(r8631,c62,s2539). +registration(r8632,c220,s2539). +registration(r8633,c154,s2539). +registration(r8634,c87,s2540). +registration(r8635,c47,s2540). +registration(r8636,c52,s2540). +registration(r8637,c52,s2541). +registration(r8638,c125,s2541). +registration(r8639,c71,s2541). +registration(r8640,c11,s2541). +registration(r8641,c173,s2542). +registration(r8642,c83,s2542). +registration(r8643,c230,s2542). +registration(r8644,c184,s2542). +registration(r8645,c53,s2543). +registration(r8646,c187,s2543). +registration(r8647,c192,s2543). +registration(r8648,c136,s2543). +registration(r8649,c238,s2544). +registration(r8650,c5,s2544). +registration(r8651,c213,s2544). +registration(r8652,c225,s2544). +registration(r8653,c27,s2545). +registration(r8654,c37,s2545). +registration(r8655,c200,s2545). +registration(r8656,c70,s2546). +registration(r8657,c59,s2546). +registration(r8658,c141,s2546). +registration(r8659,c246,s2547). +registration(r8660,c197,s2547). +registration(r8661,c140,s2547). +registration(r8662,c114,s2547). +registration(r8663,c20,s2548). +registration(r8664,c56,s2548). +registration(r8665,c45,s2548). +registration(r8666,c236,s2549). +registration(r8667,c163,s2549). +registration(r8668,c32,s2549). +registration(r8669,c38,s2550). +registration(r8670,c76,s2550). +registration(r8671,c190,s2550). +registration(r8672,c188,s2550). +registration(r8673,c45,s2551). +registration(r8674,c133,s2551). +registration(r8675,c36,s2551). +registration(r8676,c96,s2552). +registration(r8677,c17,s2552). +registration(r8678,c142,s2552). +registration(r8679,c83,s2552). +registration(r8680,c112,s2553). +registration(r8681,c172,s2553). +registration(r8682,c108,s2553). +registration(r8683,c165,s2554). +registration(r8684,c17,s2554). +registration(r8685,c9,s2554). +registration(r8686,c173,s2555). +registration(r8687,c185,s2555). +registration(r8688,c115,s2555). +registration(r8689,c191,s2556). +registration(r8690,c253,s2556). +registration(r8691,c231,s2556). +registration(r8692,c21,s2557). +registration(r8693,c0,s2557). +registration(r8694,c253,s2557). +registration(r8695,c94,s2558). +registration(r8696,c172,s2558). +registration(r8697,c88,s2558). +registration(r8698,c173,s2559). +registration(r8699,c178,s2559). +registration(r8700,c94,s2559). +registration(r8701,c149,s2559). +registration(r8702,c193,s2559). +registration(r8703,c167,s2560). +registration(r8704,c40,s2560). +registration(r8705,c89,s2560). +registration(r8706,c19,s2561). +registration(r8707,c27,s2561). +registration(r8708,c22,s2561). +registration(r8709,c19,s2562). +registration(r8710,c220,s2562). +registration(r8711,c86,s2562). +registration(r8712,c86,s2563). +registration(r8713,c232,s2563). +registration(r8714,c140,s2563). +registration(r8715,c70,s2563). +registration(r8716,c123,s2564). +registration(r8717,c136,s2564). +registration(r8718,c236,s2564). +registration(r8719,c57,s2564). +registration(r8720,c67,s2565). +registration(r8721,c208,s2565). +registration(r8722,c108,s2565). +registration(r8723,c120,s2565). +registration(r8724,c94,s2566). +registration(r8725,c30,s2566). +registration(r8726,c108,s2566). +registration(r8727,c129,s2567). +registration(r8728,c100,s2567). +registration(r8729,c18,s2567). +registration(r8730,c105,s2568). +registration(r8731,c128,s2568). +registration(r8732,c50,s2568). +registration(r8733,c191,s2569). +registration(r8734,c226,s2569). +registration(r8735,c174,s2569). +registration(r8736,c55,s2570). +registration(r8737,c228,s2570). +registration(r8738,c134,s2570). +registration(r8739,c202,s2570). +registration(r8740,c66,s2571). +registration(r8741,c157,s2571). +registration(r8742,c207,s2571). +registration(r8743,c44,s2571). +registration(r8744,c217,s2572). +registration(r8745,c156,s2572). +registration(r8746,c158,s2572). +registration(r8747,c29,s2572). +registration(r8748,c37,s2572). +registration(r8749,c178,s2573). +registration(r8750,c67,s2573). +registration(r8751,c142,s2573). +registration(r8752,c117,s2573). +registration(r8753,c156,s2574). +registration(r8754,c52,s2574). +registration(r8755,c48,s2574). +registration(r8756,c143,s2574). +registration(r8757,c132,s2575). +registration(r8758,c17,s2575). +registration(r8759,c22,s2575). +registration(r8760,c224,s2576). +registration(r8761,c55,s2576). +registration(r8762,c222,s2576). +registration(r8763,c16,s2577). +registration(r8764,c220,s2577). +registration(r8765,c202,s2577). +registration(r8766,c221,s2578). +registration(r8767,c202,s2578). +registration(r8768,c124,s2578). +registration(r8769,c125,s2578). +registration(r8770,c144,s2579). +registration(r8771,c177,s2579). +registration(r8772,c54,s2579). +registration(r8773,c108,s2580). +registration(r8774,c16,s2580). +registration(r8775,c153,s2580). +registration(r8776,c29,s2581). +registration(r8777,c171,s2581). +registration(r8778,c182,s2581). +registration(r8779,c237,s2581). +registration(r8780,c75,s2582). +registration(r8781,c204,s2582). +registration(r8782,c69,s2582). +registration(r8783,c33,s2583). +registration(r8784,c9,s2583). +registration(r8785,c139,s2583). +registration(r8786,c85,s2584). +registration(r8787,c26,s2584). +registration(r8788,c233,s2584). +registration(r8789,c122,s2585). +registration(r8790,c132,s2585). +registration(r8791,c18,s2585). +registration(r8792,c127,s2586). +registration(r8793,c105,s2586). +registration(r8794,c106,s2586). +registration(r8795,c9,s2586). +registration(r8796,c196,s2587). +registration(r8797,c190,s2587). +registration(r8798,c153,s2587). +registration(r8799,c229,s2588). +registration(r8800,c125,s2588). +registration(r8801,c155,s2588). +registration(r8802,c89,s2588). +registration(r8803,c44,s2589). +registration(r8804,c229,s2589). +registration(r8805,c90,s2589). +registration(r8806,c58,s2589). +registration(r8807,c251,s2590). +registration(r8808,c13,s2590). +registration(r8809,c80,s2590). +registration(r8810,c98,s2591). +registration(r8811,c207,s2591). +registration(r8812,c99,s2591). +registration(r8813,c205,s2592). +registration(r8814,c251,s2592). +registration(r8815,c67,s2592). +registration(r8816,c3,s2593). +registration(r8817,c239,s2593). +registration(r8818,c113,s2593). +registration(r8819,c239,s2594). +registration(r8820,c244,s2594). +registration(r8821,c248,s2594). +registration(r8822,c36,s2595). +registration(r8823,c48,s2595). +registration(r8824,c11,s2595). +registration(r8825,c127,s2596). +registration(r8826,c51,s2596). +registration(r8827,c119,s2596). +registration(r8828,c9,s2597). +registration(r8829,c50,s2597). +registration(r8830,c121,s2597). +registration(r8831,c179,s2597). +registration(r8832,c57,s2598). +registration(r8833,c15,s2598). +registration(r8834,c246,s2598). +registration(r8835,c249,s2599). +registration(r8836,c125,s2599). +registration(r8837,c65,s2599). +registration(r8838,c49,s2600). +registration(r8839,c71,s2600). +registration(r8840,c75,s2600). +registration(r8841,c110,s2601). +registration(r8842,c172,s2601). +registration(r8843,c3,s2601). +registration(r8844,c130,s2601). +registration(r8845,c217,s2602). +registration(r8846,c141,s2602). +registration(r8847,c80,s2602). +registration(r8848,c131,s2603). +registration(r8849,c251,s2603). +registration(r8850,c4,s2603). +registration(r8851,c62,s2604). +registration(r8852,c167,s2604). +registration(r8853,c164,s2604). +registration(r8854,c157,s2605). +registration(r8855,c73,s2605). +registration(r8856,c185,s2605). +registration(r8857,c234,s2606). +registration(r8858,c54,s2606). +registration(r8859,c229,s2606). +registration(r8860,c85,s2606). +registration(r8861,c19,s2607). +registration(r8862,c50,s2607). +registration(r8863,c251,s2607). +registration(r8864,c179,s2607). +registration(r8865,c184,s2608). +registration(r8866,c5,s2608). +registration(r8867,c88,s2608). +registration(r8868,c84,s2609). +registration(r8869,c85,s2609). +registration(r8870,c31,s2609). +registration(r8871,c148,s2609). +registration(r8872,c166,s2610). +registration(r8873,c94,s2610). +registration(r8874,c61,s2610). +registration(r8875,c246,s2611). +registration(r8876,c52,s2611). +registration(r8877,c69,s2611). +registration(r8878,c43,s2612). +registration(r8879,c72,s2612). +registration(r8880,c154,s2612). +registration(r8881,c202,s2613). +registration(r8882,c124,s2613). +registration(r8883,c132,s2613). +registration(r8884,c60,s2614). +registration(r8885,c132,s2614). +registration(r8886,c171,s2614). +registration(r8887,c255,s2614). +registration(r8888,c225,s2615). +registration(r8889,c44,s2615). +registration(r8890,c1,s2615). +registration(r8891,c168,s2616). +registration(r8892,c211,s2616). +registration(r8893,c49,s2616). +registration(r8894,c40,s2617). +registration(r8895,c33,s2617). +registration(r8896,c194,s2617). +registration(r8897,c141,s2617). +registration(r8898,c80,s2618). +registration(r8899,c38,s2618). +registration(r8900,c112,s2618). +registration(r8901,c236,s2619). +registration(r8902,c47,s2619). +registration(r8903,c112,s2619). +registration(r8904,c244,s2620). +registration(r8905,c233,s2620). +registration(r8906,c249,s2620). +registration(r8907,c230,s2620). +registration(r8908,c46,s2621). +registration(r8909,c234,s2621). +registration(r8910,c80,s2621). +registration(r8911,c147,s2621). +registration(r8912,c85,s2621). +registration(r8913,c128,s2622). +registration(r8914,c160,s2622). +registration(r8915,c124,s2622). +registration(r8916,c134,s2623). +registration(r8917,c47,s2623). +registration(r8918,c80,s2623). +registration(r8919,c190,s2624). +registration(r8920,c130,s2624). +registration(r8921,c71,s2624). +registration(r8922,c184,s2625). +registration(r8923,c234,s2625). +registration(r8924,c31,s2625). +registration(r8925,c25,s2626). +registration(r8926,c174,s2626). +registration(r8927,c190,s2626). +registration(r8928,c168,s2627). +registration(r8929,c68,s2627). +registration(r8930,c255,s2627). +registration(r8931,c83,s2628). +registration(r8932,c188,s2628). +registration(r8933,c9,s2628). +registration(r8934,c107,s2629). +registration(r8935,c86,s2629). +registration(r8936,c143,s2629). +registration(r8937,c230,s2629). +registration(r8938,c121,s2630). +registration(r8939,c178,s2630). +registration(r8940,c45,s2630). +registration(r8941,c100,s2630). +registration(r8942,c15,s2631). +registration(r8943,c133,s2631). +registration(r8944,c149,s2631). +registration(r8945,c66,s2632). +registration(r8946,c161,s2632). +registration(r8947,c147,s2632). +registration(r8948,c73,s2632). +registration(r8949,c30,s2633). +registration(r8950,c133,s2633). +registration(r8951,c65,s2633). +registration(r8952,c73,s2634). +registration(r8953,c66,s2634). +registration(r8954,c161,s2634). +registration(r8955,c47,s2635). +registration(r8956,c112,s2635). +registration(r8957,c200,s2635). +registration(r8958,c234,s2635). +registration(r8959,c67,s2636). +registration(r8960,c15,s2636). +registration(r8961,c223,s2636). +registration(r8962,c31,s2636). +registration(r8963,c190,s2637). +registration(r8964,c2,s2637). +registration(r8965,c3,s2637). +registration(r8966,c163,s2637). +registration(r8967,c33,s2638). +registration(r8968,c237,s2638). +registration(r8969,c109,s2638). +registration(r8970,c174,s2639). +registration(r8971,c179,s2639). +registration(r8972,c180,s2639). +registration(r8973,c84,s2640). +registration(r8974,c173,s2640). +registration(r8975,c143,s2640). +registration(r8976,c87,s2640). +registration(r8977,c153,s2641). +registration(r8978,c8,s2641). +registration(r8979,c210,s2641). +registration(r8980,c176,s2641). +registration(r8981,c7,s2642). +registration(r8982,c55,s2642). +registration(r8983,c21,s2642). +registration(r8984,c22,s2643). +registration(r8985,c200,s2643). +registration(r8986,c221,s2643). +registration(r8987,c202,s2644). +registration(r8988,c25,s2644). +registration(r8989,c43,s2644). +registration(r8990,c221,s2645). +registration(r8991,c240,s2645). +registration(r8992,c190,s2645). +registration(r8993,c109,s2646). +registration(r8994,c97,s2646). +registration(r8995,c202,s2646). +registration(r8996,c99,s2647). +registration(r8997,c148,s2647). +registration(r8998,c139,s2647). +registration(r8999,c60,s2648). +registration(r9000,c73,s2648). +registration(r9001,c226,s2648). +registration(r9002,c26,s2648). +registration(r9003,c103,s2649). +registration(r9004,c216,s2649). +registration(r9005,c247,s2649). +registration(r9006,c192,s2649). +registration(r9007,c45,s2650). +registration(r9008,c236,s2650). +registration(r9009,c254,s2650). +registration(r9010,c239,s2651). +registration(r9011,c180,s2651). +registration(r9012,c155,s2651). +registration(r9013,c254,s2651). +registration(r9014,c255,s2652). +registration(r9015,c173,s2652). +registration(r9016,c183,s2652). +registration(r9017,c67,s2653). +registration(r9018,c164,s2653). +registration(r9019,c237,s2653). +registration(r9020,c207,s2654). +registration(r9021,c209,s2654). +registration(r9022,c252,s2654). +registration(r9023,c212,s2655). +registration(r9024,c226,s2655). +registration(r9025,c76,s2655). +registration(r9026,c122,s2656). +registration(r9027,c131,s2656). +registration(r9028,c163,s2656). +registration(r9029,c145,s2657). +registration(r9030,c36,s2657). +registration(r9031,c234,s2657). +registration(r9032,c232,s2658). +registration(r9033,c197,s2658). +registration(r9034,c246,s2658). +registration(r9035,c55,s2658). +registration(r9036,c229,s2659). +registration(r9037,c204,s2659). +registration(r9038,c37,s2659). +registration(r9039,c245,s2660). +registration(r9040,c54,s2660). +registration(r9041,c182,s2660). +registration(r9042,c140,s2661). +registration(r9043,c194,s2661). +registration(r9044,c188,s2661). +registration(r9045,c100,s2661). +registration(r9046,c166,s2662). +registration(r9047,c8,s2662). +registration(r9048,c165,s2662). +registration(r9049,c202,s2663). +registration(r9050,c222,s2663). +registration(r9051,c96,s2663). +registration(r9052,c197,s2663). +registration(r9053,c7,s2663). +registration(r9054,c104,s2664). +registration(r9055,c79,s2664). +registration(r9056,c63,s2664). +registration(r9057,c103,s2664). +registration(r9058,c179,s2665). +registration(r9059,c215,s2665). +registration(r9060,c91,s2665). +registration(r9061,c60,s2666). +registration(r9062,c90,s2666). +registration(r9063,c26,s2666). +registration(r9064,c63,s2666). +registration(r9065,c100,s2667). +registration(r9066,c76,s2667). +registration(r9067,c228,s2667). +registration(r9068,c216,s2668). +registration(r9069,c6,s2668). +registration(r9070,c188,s2668). +registration(r9071,c206,s2669). +registration(r9072,c124,s2669). +registration(r9073,c142,s2669). +registration(r9074,c222,s2670). +registration(r9075,c21,s2670). +registration(r9076,c52,s2670). +registration(r9077,c230,s2671). +registration(r9078,c209,s2671). +registration(r9079,c215,s2671). +registration(r9080,c20,s2672). +registration(r9081,c43,s2672). +registration(r9082,c125,s2672). +registration(r9083,c66,s2672). +registration(r9084,c119,s2673). +registration(r9085,c142,s2673). +registration(r9086,c159,s2673). +registration(r9087,c118,s2674). +registration(r9088,c234,s2674). +registration(r9089,c60,s2674). +registration(r9090,c82,s2674). +registration(r9091,c170,s2674). +registration(r9092,c224,s2675). +registration(r9093,c223,s2675). +registration(r9094,c143,s2675). +registration(r9095,c196,s2676). +registration(r9096,c185,s2676). +registration(r9097,c112,s2676). +registration(r9098,c73,s2677). +registration(r9099,c124,s2677). +registration(r9100,c238,s2677). +registration(r9101,c106,s2678). +registration(r9102,c113,s2678). +registration(r9103,c231,s2678). +registration(r9104,c232,s2678). +registration(r9105,c196,s2679). +registration(r9106,c204,s2679). +registration(r9107,c245,s2679). +registration(r9108,c50,s2680). +registration(r9109,c104,s2680). +registration(r9110,c9,s2680). +registration(r9111,c234,s2680). +registration(r9112,c30,s2681). +registration(r9113,c163,s2681). +registration(r9114,c170,s2681). +registration(r9115,c103,s2681). +registration(r9116,c134,s2682). +registration(r9117,c18,s2682). +registration(r9118,c240,s2682). +registration(r9119,c223,s2683). +registration(r9120,c45,s2683). +registration(r9121,c54,s2683). +registration(r9122,c29,s2684). +registration(r9123,c111,s2684). +registration(r9124,c136,s2684). +registration(r9125,c83,s2685). +registration(r9126,c137,s2685). +registration(r9127,c110,s2685). +registration(r9128,c188,s2685). +registration(r9129,c20,s2686). +registration(r9130,c249,s2686). +registration(r9131,c232,s2686). +registration(r9132,c139,s2686). +registration(r9133,c168,s2687). +registration(r9134,c43,s2687). +registration(r9135,c244,s2687). +registration(r9136,c178,s2687). +registration(r9137,c252,s2687). +registration(r9138,c130,s2688). +registration(r9139,c150,s2688). +registration(r9140,c219,s2688). +registration(r9141,c37,s2689). +registration(r9142,c79,s2689). +registration(r9143,c232,s2689). +registration(r9144,c123,s2690). +registration(r9145,c200,s2690). +registration(r9146,c41,s2690). +registration(r9147,c54,s2690). +registration(r9148,c191,s2691). +registration(r9149,c12,s2691). +registration(r9150,c73,s2691). +registration(r9151,c71,s2692). +registration(r9152,c208,s2692). +registration(r9153,c130,s2692). +registration(r9154,c118,s2693). +registration(r9155,c251,s2693). +registration(r9156,c174,s2693). +registration(r9157,c49,s2694). +registration(r9158,c19,s2694). +registration(r9159,c212,s2694). +registration(r9160,c249,s2695). +registration(r9161,c48,s2695). +registration(r9162,c198,s2695). +registration(r9163,c67,s2695). +registration(r9164,c86,s2696). +registration(r9165,c48,s2696). +registration(r9166,c71,s2696). +registration(r9167,c7,s2697). +registration(r9168,c153,s2697). +registration(r9169,c174,s2697). +registration(r9170,c245,s2698). +registration(r9171,c144,s2698). +registration(r9172,c17,s2698). +registration(r9173,c136,s2699). +registration(r9174,c225,s2699). +registration(r9175,c60,s2699). +registration(r9176,c217,s2699). +registration(r9177,c24,s2700). +registration(r9178,c174,s2700). +registration(r9179,c80,s2700). +registration(r9180,c128,s2701). +registration(r9181,c190,s2701). +registration(r9182,c52,s2701). +registration(r9183,c139,s2701). +registration(r9184,c184,s2702). +registration(r9185,c72,s2702). +registration(r9186,c23,s2702). +registration(r9187,c80,s2702). +registration(r9188,c203,s2703). +registration(r9189,c16,s2703). +registration(r9190,c64,s2703). +registration(r9191,c82,s2704). +registration(r9192,c167,s2704). +registration(r9193,c46,s2704). +registration(r9194,c107,s2705). +registration(r9195,c223,s2705). +registration(r9196,c97,s2705). +registration(r9197,c15,s2706). +registration(r9198,c42,s2706). +registration(r9199,c239,s2706). +registration(r9200,c173,s2707). +registration(r9201,c235,s2707). +registration(r9202,c50,s2707). +registration(r9203,c235,s2708). +registration(r9204,c247,s2708). +registration(r9205,c141,s2708). +registration(r9206,c70,s2708). +registration(r9207,c213,s2709). +registration(r9208,c87,s2709). +registration(r9209,c128,s2709). +registration(r9210,c210,s2710). +registration(r9211,c61,s2710). +registration(r9212,c39,s2710). +registration(r9213,c147,s2711). +registration(r9214,c139,s2711). +registration(r9215,c39,s2711). +registration(r9216,c55,s2712). +registration(r9217,c151,s2712). +registration(r9218,c115,s2712). +registration(r9219,c33,s2713). +registration(r9220,c218,s2713). +registration(r9221,c117,s2713). +registration(r9222,c97,s2714). +registration(r9223,c199,s2714). +registration(r9224,c224,s2714). +registration(r9225,c32,s2714). +registration(r9226,c65,s2715). +registration(r9227,c102,s2715). +registration(r9228,c161,s2715). +registration(r9229,c115,s2716). +registration(r9230,c21,s2716). +registration(r9231,c135,s2716). +registration(r9232,c219,s2716). +registration(r9233,c173,s2716). +registration(r9234,c3,s2717). +registration(r9235,c135,s2717). +registration(r9236,c50,s2717). +registration(r9237,c166,s2717). +registration(r9238,c40,s2718). +registration(r9239,c97,s2718). +registration(r9240,c199,s2718). +registration(r9241,c215,s2718). +registration(r9242,c84,s2719). +registration(r9243,c56,s2719). +registration(r9244,c95,s2719). +registration(r9245,c109,s2720). +registration(r9246,c84,s2720). +registration(r9247,c229,s2720). +registration(r9248,c188,s2721). +registration(r9249,c50,s2721). +registration(r9250,c106,s2721). +registration(r9251,c139,s2722). +registration(r9252,c174,s2722). +registration(r9253,c210,s2722). +registration(r9254,c89,s2723). +registration(r9255,c107,s2723). +registration(r9256,c235,s2723). +registration(r9257,c20,s2723). +registration(r9258,c217,s2724). +registration(r9259,c214,s2724). +registration(r9260,c23,s2724). +registration(r9261,c108,s2725). +registration(r9262,c232,s2725). +registration(r9263,c205,s2725). +registration(r9264,c59,s2726). +registration(r9265,c245,s2726). +registration(r9266,c113,s2726). +registration(r9267,c235,s2726). +registration(r9268,c65,s2726). +registration(r9269,c86,s2727). +registration(r9270,c1,s2727). +registration(r9271,c250,s2727). +registration(r9272,c205,s2728). +registration(r9273,c26,s2728). +registration(r9274,c96,s2728). +registration(r9275,c133,s2728). +registration(r9276,c158,s2729). +registration(r9277,c149,s2729). +registration(r9278,c95,s2729). +registration(r9279,c119,s2730). +registration(r9280,c39,s2730). +registration(r9281,c221,s2730). +registration(r9282,c170,s2730). +registration(r9283,c132,s2731). +registration(r9284,c157,s2731). +registration(r9285,c229,s2731). +registration(r9286,c244,s2731). +registration(r9287,c102,s2732). +registration(r9288,c61,s2732). +registration(r9289,c54,s2732). +registration(r9290,c49,s2733). +registration(r9291,c158,s2733). +registration(r9292,c238,s2733). +registration(r9293,c77,s2734). +registration(r9294,c36,s2734). +registration(r9295,c62,s2734). +registration(r9296,c211,s2735). +registration(r9297,c249,s2735). +registration(r9298,c58,s2735). +registration(r9299,c99,s2736). +registration(r9300,c29,s2736). +registration(r9301,c84,s2736). +registration(r9302,c216,s2737). +registration(r9303,c17,s2737). +registration(r9304,c173,s2737). +registration(r9305,c161,s2737). +registration(r9306,c184,s2738). +registration(r9307,c94,s2738). +registration(r9308,c217,s2738). +registration(r9309,c10,s2739). +registration(r9310,c20,s2739). +registration(r9311,c141,s2739). +registration(r9312,c204,s2739). +registration(r9313,c45,s2740). +registration(r9314,c9,s2740). +registration(r9315,c116,s2740). +registration(r9316,c108,s2741). +registration(r9317,c44,s2741). +registration(r9318,c30,s2741). +registration(r9319,c60,s2742). +registration(r9320,c49,s2742). +registration(r9321,c4,s2742). +registration(r9322,c11,s2742). +registration(r9323,c179,s2742). +registration(r9324,c93,s2743). +registration(r9325,c55,s2743). +registration(r9326,c85,s2743). +registration(r9327,c151,s2743). +registration(r9328,c140,s2743). +registration(r9329,c53,s2744). +registration(r9330,c58,s2744). +registration(r9331,c160,s2744). +registration(r9332,c107,s2745). +registration(r9333,c156,s2745). +registration(r9334,c112,s2745). +registration(r9335,c96,s2745). +registration(r9336,c82,s2746). +registration(r9337,c124,s2746). +registration(r9338,c143,s2746). +registration(r9339,c30,s2747). +registration(r9340,c173,s2747). +registration(r9341,c139,s2747). +registration(r9342,c178,s2747). +registration(r9343,c57,s2748). +registration(r9344,c100,s2748). +registration(r9345,c244,s2748). +registration(r9346,c10,s2749). +registration(r9347,c7,s2749). +registration(r9348,c232,s2749). +registration(r9349,c34,s2750). +registration(r9350,c55,s2750). +registration(r9351,c254,s2750). +registration(r9352,c154,s2751). +registration(r9353,c213,s2751). +registration(r9354,c23,s2751). +registration(r9355,c105,s2752). +registration(r9356,c38,s2752). +registration(r9357,c198,s2752). +registration(r9358,c228,s2753). +registration(r9359,c135,s2753). +registration(r9360,c12,s2753). +registration(r9361,c57,s2753). +registration(r9362,c66,s2754). +registration(r9363,c157,s2754). +registration(r9364,c151,s2754). +registration(r9365,c162,s2755). +registration(r9366,c187,s2755). +registration(r9367,c63,s2755). +registration(r9368,c98,s2756). +registration(r9369,c112,s2756). +registration(r9370,c247,s2756). +registration(r9371,c145,s2756). +registration(r9372,c156,s2757). +registration(r9373,c41,s2757). +registration(r9374,c60,s2757). +registration(r9375,c98,s2758). +registration(r9376,c154,s2758). +registration(r9377,c110,s2758). +registration(r9378,c245,s2759). +registration(r9379,c238,s2759). +registration(r9380,c134,s2759). +registration(r9381,c146,s2759). +registration(r9382,c204,s2760). +registration(r9383,c42,s2760). +registration(r9384,c125,s2760). +registration(r9385,c205,s2760). +registration(r9386,c99,s2761). +registration(r9387,c6,s2761). +registration(r9388,c50,s2761). +registration(r9389,c40,s2762). +registration(r9390,c141,s2762). +registration(r9391,c136,s2762). +registration(r9392,c178,s2762). +registration(r9393,c245,s2763). +registration(r9394,c254,s2763). +registration(r9395,c68,s2763). +registration(r9396,c179,s2764). +registration(r9397,c58,s2764). +registration(r9398,c23,s2764). +registration(r9399,c159,s2764). +registration(r9400,c215,s2765). +registration(r9401,c189,s2765). +registration(r9402,c104,s2765). +registration(r9403,c230,s2766). +registration(r9404,c199,s2766). +registration(r9405,c180,s2766). +registration(r9406,c43,s2766). +registration(r9407,c80,s2767). +registration(r9408,c242,s2767). +registration(r9409,c50,s2767). +registration(r9410,c186,s2768). +registration(r9411,c51,s2768). +registration(r9412,c169,s2768). +registration(r9413,c167,s2768). +registration(r9414,c177,s2769). +registration(r9415,c128,s2769). +registration(r9416,c64,s2769). +registration(r9417,c88,s2770). +registration(r9418,c13,s2770). +registration(r9419,c231,s2770). +registration(r9420,c164,s2771). +registration(r9421,c96,s2771). +registration(r9422,c137,s2771). +registration(r9423,c81,s2772). +registration(r9424,c67,s2772). +registration(r9425,c103,s2772). +registration(r9426,c183,s2773). +registration(r9427,c111,s2773). +registration(r9428,c49,s2773). +registration(r9429,c239,s2773). +registration(r9430,c100,s2774). +registration(r9431,c153,s2774). +registration(r9432,c88,s2774). +registration(r9433,c10,s2775). +registration(r9434,c15,s2775). +registration(r9435,c131,s2775). +registration(r9436,c219,s2776). +registration(r9437,c123,s2776). +registration(r9438,c178,s2776). +registration(r9439,c87,s2777). +registration(r9440,c52,s2777). +registration(r9441,c234,s2777). +registration(r9442,c60,s2778). +registration(r9443,c40,s2778). +registration(r9444,c226,s2778). +registration(r9445,c154,s2778). +registration(r9446,c41,s2779). +registration(r9447,c91,s2779). +registration(r9448,c202,s2779). +registration(r9449,c71,s2779). +registration(r9450,c178,s2779). +registration(r9451,c161,s2780). +registration(r9452,c188,s2780). +registration(r9453,c244,s2780). +registration(r9454,c119,s2781). +registration(r9455,c26,s2781). +registration(r9456,c151,s2781). +registration(r9457,c73,s2782). +registration(r9458,c38,s2782). +registration(r9459,c246,s2782). +registration(r9460,c224,s2783). +registration(r9461,c134,s2783). +registration(r9462,c214,s2783). +registration(r9463,c174,s2783). +registration(r9464,c214,s2784). +registration(r9465,c215,s2784). +registration(r9466,c82,s2784). +registration(r9467,c49,s2784). +registration(r9468,c25,s2784). +registration(r9469,c121,s2785). +registration(r9470,c76,s2785). +registration(r9471,c204,s2785). +registration(r9472,c8,s2785). +registration(r9473,c198,s2786). +registration(r9474,c212,s2786). +registration(r9475,c55,s2786). +registration(r9476,c138,s2787). +registration(r9477,c117,s2787). +registration(r9478,c181,s2787). +registration(r9479,c86,s2788). +registration(r9480,c11,s2788). +registration(r9481,c78,s2788). +registration(r9482,c106,s2789). +registration(r9483,c140,s2789). +registration(r9484,c156,s2789). +registration(r9485,c239,s2790). +registration(r9486,c66,s2790). +registration(r9487,c149,s2790). +registration(r9488,c91,s2790). +registration(r9489,c89,s2790). +registration(r9490,c40,s2791). +registration(r9491,c42,s2791). +registration(r9492,c99,s2791). +registration(r9493,c54,s2792). +registration(r9494,c32,s2792). +registration(r9495,c208,s2792). +registration(r9496,c70,s2793). +registration(r9497,c87,s2793). +registration(r9498,c93,s2793). +registration(r9499,c103,s2794). +registration(r9500,c1,s2794). +registration(r9501,c138,s2794). +registration(r9502,c21,s2795). +registration(r9503,c229,s2795). +registration(r9504,c174,s2795). +registration(r9505,c241,s2796). +registration(r9506,c13,s2796). +registration(r9507,c225,s2796). +registration(r9508,c59,s2796). +registration(r9509,c117,s2797). +registration(r9510,c70,s2797). +registration(r9511,c158,s2797). +registration(r9512,c212,s2798). +registration(r9513,c126,s2798). +registration(r9514,c6,s2798). +registration(r9515,c77,s2798). +registration(r9516,c205,s2799). +registration(r9517,c133,s2799). +registration(r9518,c1,s2799). +registration(r9519,c3,s2800). +registration(r9520,c4,s2800). +registration(r9521,c56,s2800). +registration(r9522,c30,s2800). +registration(r9523,c31,s2801). +registration(r9524,c145,s2801). +registration(r9525,c242,s2801). +registration(r9526,c158,s2801). +registration(r9527,c93,s2802). +registration(r9528,c187,s2802). +registration(r9529,c15,s2802). +registration(r9530,c173,s2802). +registration(r9531,c49,s2803). +registration(r9532,c56,s2803). +registration(r9533,c130,s2803). +registration(r9534,c248,s2804). +registration(r9535,c217,s2804). +registration(r9536,c139,s2804). +registration(r9537,c142,s2805). +registration(r9538,c62,s2805). +registration(r9539,c77,s2805). +registration(r9540,c132,s2806). +registration(r9541,c3,s2806). +registration(r9542,c91,s2806). +registration(r9543,c236,s2806). +registration(r9544,c147,s2807). +registration(r9545,c50,s2807). +registration(r9546,c138,s2807). +registration(r9547,c69,s2808). +registration(r9548,c119,s2808). +registration(r9549,c99,s2808). +registration(r9550,c149,s2808). +registration(r9551,c127,s2809). +registration(r9552,c166,s2809). +registration(r9553,c67,s2809). +registration(r9554,c30,s2810). +registration(r9555,c75,s2810). +registration(r9556,c101,s2810). +registration(r9557,c162,s2811). +registration(r9558,c204,s2811). +registration(r9559,c106,s2811). +registration(r9560,c110,s2812). +registration(r9561,c64,s2812). +registration(r9562,c242,s2812). +registration(r9563,c134,s2812). +registration(r9564,c195,s2813). +registration(r9565,c182,s2813). +registration(r9566,c238,s2813). +registration(r9567,c100,s2814). +registration(r9568,c183,s2814). +registration(r9569,c67,s2814). +registration(r9570,c194,s2815). +registration(r9571,c47,s2815). +registration(r9572,c143,s2815). +registration(r9573,c173,s2816). +registration(r9574,c203,s2816). +registration(r9575,c49,s2816). +registration(r9576,c164,s2816). +registration(r9577,c249,s2817). +registration(r9578,c16,s2817). +registration(r9579,c185,s2817). +registration(r9580,c250,s2818). +registration(r9581,c60,s2818). +registration(r9582,c16,s2818). +registration(r9583,c195,s2818). +registration(r9584,c221,s2819). +registration(r9585,c176,s2819). +registration(r9586,c40,s2819). +registration(r9587,c223,s2819). +registration(r9588,c29,s2820). +registration(r9589,c159,s2820). +registration(r9590,c43,s2820). +registration(r9591,c185,s2821). +registration(r9592,c96,s2821). +registration(r9593,c156,s2821). +registration(r9594,c207,s2821). +registration(r9595,c148,s2822). +registration(r9596,c210,s2822). +registration(r9597,c163,s2822). +registration(r9598,c93,s2823). +registration(r9599,c215,s2823). +registration(r9600,c99,s2823). +registration(r9601,c116,s2823). +registration(r9602,c125,s2824). +registration(r9603,c215,s2824). +registration(r9604,c72,s2824). +registration(r9605,c113,s2825). +registration(r9606,c52,s2825). +registration(r9607,c160,s2825). +registration(r9608,c62,s2826). +registration(r9609,c124,s2826). +registration(r9610,c50,s2826). +registration(r9611,c53,s2826). +registration(r9612,c170,s2827). +registration(r9613,c156,s2827). +registration(r9614,c193,s2827). +registration(r9615,c145,s2827). +registration(r9616,c28,s2828). +registration(r9617,c190,s2828). +registration(r9618,c118,s2828). +registration(r9619,c217,s2829). +registration(r9620,c208,s2829). +registration(r9621,c168,s2829). +registration(r9622,c129,s2830). +registration(r9623,c151,s2830). +registration(r9624,c171,s2830). +registration(r9625,c8,s2830). +registration(r9626,c170,s2831). +registration(r9627,c89,s2831). +registration(r9628,c49,s2831). +registration(r9629,c100,s2832). +registration(r9630,c247,s2832). +registration(r9631,c11,s2832). +registration(r9632,c168,s2833). +registration(r9633,c185,s2833). +registration(r9634,c27,s2833). +registration(r9635,c55,s2834). +registration(r9636,c152,s2834). +registration(r9637,c195,s2834). +registration(r9638,c157,s2834). +registration(r9639,c131,s2835). +registration(r9640,c215,s2835). +registration(r9641,c235,s2835). +registration(r9642,c129,s2836). +registration(r9643,c124,s2836). +registration(r9644,c99,s2836). +registration(r9645,c14,s2837). +registration(r9646,c229,s2837). +registration(r9647,c141,s2837). +registration(r9648,c242,s2838). +registration(r9649,c238,s2838). +registration(r9650,c197,s2838). +registration(r9651,c111,s2839). +registration(r9652,c165,s2839). +registration(r9653,c173,s2839). +registration(r9654,c228,s2840). +registration(r9655,c224,s2840). +registration(r9656,c179,s2840). +registration(r9657,c81,s2840). +registration(r9658,c25,s2841). +registration(r9659,c231,s2841). +registration(r9660,c61,s2841). +registration(r9661,c191,s2842). +registration(r9662,c105,s2842). +registration(r9663,c164,s2842). +registration(r9664,c179,s2843). +registration(r9665,c47,s2843). +registration(r9666,c84,s2843). +registration(r9667,c70,s2844). +registration(r9668,c156,s2844). +registration(r9669,c178,s2844). +registration(r9670,c44,s2844). +registration(r9671,c215,s2844). +registration(r9672,c218,s2845). +registration(r9673,c107,s2845). +registration(r9674,c199,s2845). +registration(r9675,c125,s2846). +registration(r9676,c85,s2846). +registration(r9677,c92,s2846). +registration(r9678,c67,s2847). +registration(r9679,c13,s2847). +registration(r9680,c93,s2847). +registration(r9681,c197,s2848). +registration(r9682,c40,s2848). +registration(r9683,c22,s2848). +registration(r9684,c70,s2849). +registration(r9685,c223,s2849). +registration(r9686,c136,s2849). +registration(r9687,c37,s2849). +registration(r9688,c227,s2849). +registration(r9689,c87,s2850). +registration(r9690,c81,s2850). +registration(r9691,c4,s2850). +registration(r9692,c44,s2850). +registration(r9693,c245,s2851). +registration(r9694,c233,s2851). +registration(r9695,c187,s2851). +registration(r9696,c25,s2852). +registration(r9697,c67,s2852). +registration(r9698,c176,s2852). +registration(r9699,c11,s2853). +registration(r9700,c225,s2853). +registration(r9701,c30,s2853). +registration(r9702,c53,s2853). +registration(r9703,c92,s2854). +registration(r9704,c231,s2854). +registration(r9705,c122,s2854). +registration(r9706,c171,s2855). +registration(r9707,c96,s2855). +registration(r9708,c148,s2855). +registration(r9709,c230,s2856). +registration(r9710,c146,s2856). +registration(r9711,c228,s2856). +registration(r9712,c3,s2856). +registration(r9713,c253,s2857). +registration(r9714,c191,s2857). +registration(r9715,c77,s2857). +registration(r9716,c145,s2858). +registration(r9717,c237,s2858). +registration(r9718,c54,s2858). +registration(r9719,c24,s2859). +registration(r9720,c255,s2859). +registration(r9721,c201,s2859). +registration(r9722,c52,s2859). +registration(r9723,c9,s2859). +registration(r9724,c174,s2860). +registration(r9725,c97,s2860). +registration(r9726,c121,s2860). +registration(r9727,c13,s2861). +registration(r9728,c232,s2861). +registration(r9729,c123,s2861). +registration(r9730,c96,s2862). +registration(r9731,c7,s2862). +registration(r9732,c127,s2862). +registration(r9733,c63,s2862). +registration(r9734,c138,s2863). +registration(r9735,c66,s2863). +registration(r9736,c24,s2863). +registration(r9737,c48,s2863). +registration(r9738,c254,s2864). +registration(r9739,c40,s2864). +registration(r9740,c104,s2864). +registration(r9741,c138,s2865). +registration(r9742,c49,s2865). +registration(r9743,c26,s2865). +registration(r9744,c124,s2866). +registration(r9745,c13,s2866). +registration(r9746,c59,s2866). +registration(r9747,c35,s2866). +registration(r9748,c186,s2867). +registration(r9749,c15,s2867). +registration(r9750,c158,s2867). +registration(r9751,c23,s2867). +registration(r9752,c87,s2867). +registration(r9753,c27,s2868). +registration(r9754,c92,s2868). +registration(r9755,c225,s2868). +registration(r9756,c253,s2869). +registration(r9757,c140,s2869). +registration(r9758,c196,s2869). +registration(r9759,c45,s2870). +registration(r9760,c250,s2870). +registration(r9761,c169,s2870). +registration(r9762,c196,s2870). +registration(r9763,c75,s2871). +registration(r9764,c12,s2871). +registration(r9765,c65,s2871). +registration(r9766,c127,s2872). +registration(r9767,c115,s2872). +registration(r9768,c105,s2872). +registration(r9769,c8,s2873). +registration(r9770,c85,s2873). +registration(r9771,c155,s2873). +registration(r9772,c173,s2873). +registration(r9773,c130,s2874). +registration(r9774,c142,s2874). +registration(r9775,c19,s2874). +registration(r9776,c160,s2875). +registration(r9777,c188,s2875). +registration(r9778,c135,s2875). +registration(r9779,c130,s2876). +registration(r9780,c1,s2876). +registration(r9781,c161,s2876). +registration(r9782,c236,s2877). +registration(r9783,c187,s2877). +registration(r9784,c6,s2877). +registration(r9785,c133,s2877). +registration(r9786,c184,s2878). +registration(r9787,c109,s2878). +registration(r9788,c192,s2878). +registration(r9789,c21,s2879). +registration(r9790,c214,s2879). +registration(r9791,c156,s2879). +registration(r9792,c30,s2880). +registration(r9793,c80,s2880). +registration(r9794,c159,s2880). +registration(r9795,c219,s2880). +registration(r9796,c209,s2881). +registration(r9797,c98,s2881). +registration(r9798,c151,s2881). +registration(r9799,c152,s2882). +registration(r9800,c91,s2882). +registration(r9801,c148,s2882). +registration(r9802,c80,s2883). +registration(r9803,c101,s2883). +registration(r9804,c141,s2883). +registration(r9805,c68,s2884). +registration(r9806,c193,s2884). +registration(r9807,c170,s2884). +registration(r9808,c192,s2885). +registration(r9809,c86,s2885). +registration(r9810,c213,s2885). +registration(r9811,c243,s2886). +registration(r9812,c208,s2886). +registration(r9813,c128,s2886). +registration(r9814,c171,s2886). +registration(r9815,c219,s2887). +registration(r9816,c15,s2887). +registration(r9817,c88,s2887). +registration(r9818,c241,s2888). +registration(r9819,c240,s2888). +registration(r9820,c137,s2888). +registration(r9821,c218,s2889). +registration(r9822,c179,s2889). +registration(r9823,c197,s2889). +registration(r9824,c157,s2889). +registration(r9825,c240,s2889). +registration(r9826,c73,s2890). +registration(r9827,c139,s2890). +registration(r9828,c40,s2890). +registration(r9829,c225,s2890). +registration(r9830,c140,s2891). +registration(r9831,c196,s2891). +registration(r9832,c241,s2891). +registration(r9833,c250,s2892). +registration(r9834,c9,s2892). +registration(r9835,c6,s2892). +registration(r9836,c96,s2892). +registration(r9837,c108,s2893). +registration(r9838,c14,s2893). +registration(r9839,c80,s2893). +registration(r9840,c160,s2894). +registration(r9841,c151,s2894). +registration(r9842,c114,s2894). +registration(r9843,c162,s2895). +registration(r9844,c243,s2895). +registration(r9845,c103,s2895). +registration(r9846,c242,s2896). +registration(r9847,c187,s2896). +registration(r9848,c70,s2896). +registration(r9849,c211,s2897). +registration(r9850,c151,s2897). +registration(r9851,c170,s2897). +registration(r9852,c222,s2897). +registration(r9853,c58,s2898). +registration(r9854,c228,s2898). +registration(r9855,c123,s2898). +registration(r9856,c231,s2899). +registration(r9857,c98,s2899). +registration(r9858,c148,s2899). +registration(r9859,c52,s2900). +registration(r9860,c221,s2900). +registration(r9861,c111,s2900). +registration(r9862,c18,s2901). +registration(r9863,c124,s2901). +registration(r9864,c163,s2901). +registration(r9865,c149,s2902). +registration(r9866,c97,s2902). +registration(r9867,c0,s2902). +registration(r9868,c212,s2902). +registration(r9869,c2,s2903). +registration(r9870,c197,s2903). +registration(r9871,c6,s2903). +registration(r9872,c64,s2904). +registration(r9873,c196,s2904). +registration(r9874,c229,s2904). +registration(r9875,c204,s2904). +registration(r9876,c247,s2905). +registration(r9877,c156,s2905). +registration(r9878,c18,s2905). +registration(r9879,c239,s2906). +registration(r9880,c98,s2906). +registration(r9881,c90,s2906). +registration(r9882,c117,s2906). +registration(r9883,c205,s2907). +registration(r9884,c26,s2907). +registration(r9885,c144,s2907). +registration(r9886,c145,s2908). +registration(r9887,c205,s2908). +registration(r9888,c150,s2908). +registration(r9889,c91,s2909). +registration(r9890,c108,s2909). +registration(r9891,c176,s2909). +registration(r9892,c116,s2910). +registration(r9893,c171,s2910). +registration(r9894,c64,s2910). +registration(r9895,c56,s2911). +registration(r9896,c26,s2911). +registration(r9897,c139,s2911). +registration(r9898,c236,s2911). +registration(r9899,c141,s2912). +registration(r9900,c71,s2912). +registration(r9901,c165,s2912). +registration(r9902,c30,s2912). +registration(r9903,c29,s2913). +registration(r9904,c176,s2913). +registration(r9905,c214,s2913). +registration(r9906,c163,s2914). +registration(r9907,c47,s2914). +registration(r9908,c168,s2914). +registration(r9909,c20,s2915). +registration(r9910,c35,s2915). +registration(r9911,c82,s2915). +registration(r9912,c252,s2916). +registration(r9913,c0,s2916). +registration(r9914,c20,s2916). +registration(r9915,c45,s2917). +registration(r9916,c255,s2917). +registration(r9917,c100,s2917). +registration(r9918,c122,s2917). +registration(r9919,c97,s2918). +registration(r9920,c30,s2918). +registration(r9921,c245,s2918). +registration(r9922,c18,s2919). +registration(r9923,c49,s2919). +registration(r9924,c103,s2919). +registration(r9925,c9,s2920). +registration(r9926,c218,s2920). +registration(r9927,c27,s2920). +registration(r9928,c47,s2921). +registration(r9929,c159,s2921). +registration(r9930,c183,s2921). +registration(r9931,c180,s2922). +registration(r9932,c240,s2922). +registration(r9933,c73,s2922). +registration(r9934,c40,s2922). +registration(r9935,c40,s2923). +registration(r9936,c141,s2923). +registration(r9937,c146,s2923). +registration(r9938,c243,s2924). +registration(r9939,c191,s2924). +registration(r9940,c115,s2924). +registration(r9941,c134,s2925). +registration(r9942,c165,s2925). +registration(r9943,c184,s2925). +registration(r9944,c23,s2925). +registration(r9945,c12,s2926). +registration(r9946,c51,s2926). +registration(r9947,c63,s2926). +registration(r9948,c221,s2927). +registration(r9949,c41,s2927). +registration(r9950,c81,s2927). +registration(r9951,c222,s2927). +registration(r9952,c93,s2928). +registration(r9953,c6,s2928). +registration(r9954,c108,s2928). +registration(r9955,c248,s2928). +registration(r9956,c102,s2929). +registration(r9957,c209,s2929). +registration(r9958,c120,s2929). +registration(r9959,c236,s2930). +registration(r9960,c204,s2930). +registration(r9961,c225,s2930). +registration(r9962,c153,s2931). +registration(r9963,c165,s2931). +registration(r9964,c137,s2931). +registration(r9965,c189,s2932). +registration(r9966,c152,s2932). +registration(r9967,c36,s2932). +registration(r9968,c118,s2932). +registration(r9969,c113,s2933). +registration(r9970,c139,s2933). +registration(r9971,c44,s2933). +registration(r9972,c51,s2934). +registration(r9973,c29,s2934). +registration(r9974,c188,s2934). +registration(r9975,c35,s2934). +registration(r9976,c51,s2935). +registration(r9977,c142,s2935). +registration(r9978,c124,s2935). +registration(r9979,c74,s2936). +registration(r9980,c166,s2936). +registration(r9981,c238,s2936). +registration(r9982,c147,s2937). +registration(r9983,c71,s2937). +registration(r9984,c155,s2937). +registration(r9985,c51,s2937). +registration(r9986,c106,s2938). +registration(r9987,c36,s2938). +registration(r9988,c172,s2938). +registration(r9989,c54,s2939). +registration(r9990,c230,s2939). +registration(r9991,c72,s2939). +registration(r9992,c25,s2939). +registration(r9993,c218,s2940). +registration(r9994,c124,s2940). +registration(r9995,c123,s2940). +registration(r9996,c10,s2941). +registration(r9997,c121,s2941). +registration(r9998,c117,s2941). +registration(r9999,c27,s2942). +registration(r10000,c116,s2942). +registration(r10001,c129,s2942). +registration(r10002,c200,s2942). +registration(r10003,c247,s2943). +registration(r10004,c76,s2943). +registration(r10005,c203,s2943). +registration(r10006,c182,s2943). +registration(r10007,c215,s2944). +registration(r10008,c112,s2944). +registration(r10009,c134,s2944). +registration(r10010,c85,s2944). +registration(r10011,c43,s2945). +registration(r10012,c112,s2945). +registration(r10013,c53,s2945). +registration(r10014,c237,s2945). +registration(r10015,c2,s2946). +registration(r10016,c157,s2946). +registration(r10017,c188,s2946). +registration(r10018,c65,s2946). +registration(r10019,c63,s2947). +registration(r10020,c46,s2947). +registration(r10021,c181,s2947). +registration(r10022,c188,s2948). +registration(r10023,c134,s2948). +registration(r10024,c128,s2948). +registration(r10025,c82,s2948). +registration(r10026,c192,s2949). +registration(r10027,c68,s2949). +registration(r10028,c132,s2949). +registration(r10029,c203,s2949). +registration(r10030,c136,s2950). +registration(r10031,c154,s2950). +registration(r10032,c189,s2950). +registration(r10033,c194,s2951). +registration(r10034,c229,s2951). +registration(r10035,c128,s2951). +registration(r10036,c61,s2952). +registration(r10037,c66,s2952). +registration(r10038,c149,s2952). +registration(r10039,c195,s2953). +registration(r10040,c51,s2953). +registration(r10041,c65,s2953). +registration(r10042,c200,s2954). +registration(r10043,c207,s2954). +registration(r10044,c249,s2954). +registration(r10045,c122,s2954). +registration(r10046,c96,s2955). +registration(r10047,c0,s2955). +registration(r10048,c235,s2955). +registration(r10049,c146,s2955). +registration(r10050,c198,s2956). +registration(r10051,c79,s2956). +registration(r10052,c108,s2956). +registration(r10053,c81,s2956). +registration(r10054,c23,s2957). +registration(r10055,c216,s2957). +registration(r10056,c211,s2957). +registration(r10057,c104,s2957). +registration(r10058,c211,s2958). +registration(r10059,c154,s2958). +registration(r10060,c43,s2958). +registration(r10061,c220,s2958). +registration(r10062,c247,s2959). +registration(r10063,c164,s2959). +registration(r10064,c71,s2959). +registration(r10065,c196,s2960). +registration(r10066,c170,s2960). +registration(r10067,c33,s2960). +registration(r10068,c77,s2961). +registration(r10069,c88,s2961). +registration(r10070,c10,s2961). +registration(r10071,c168,s2961). +registration(r10072,c169,s2962). +registration(r10073,c186,s2962). +registration(r10074,c200,s2962). +registration(r10075,c155,s2963). +registration(r10076,c21,s2963). +registration(r10077,c173,s2963). +registration(r10078,c233,s2963). +registration(r10079,c48,s2964). +registration(r10080,c240,s2964). +registration(r10081,c36,s2964). +registration(r10082,c201,s2965). +registration(r10083,c241,s2965). +registration(r10084,c216,s2965). +registration(r10085,c131,s2966). +registration(r10086,c172,s2966). +registration(r10087,c122,s2966). +registration(r10088,c249,s2966). +registration(r10089,c36,s2967). +registration(r10090,c12,s2967). +registration(r10091,c123,s2967). +registration(r10092,c52,s2968). +registration(r10093,c100,s2968). +registration(r10094,c120,s2968). +registration(r10095,c141,s2969). +registration(r10096,c115,s2969). +registration(r10097,c3,s2969). +registration(r10098,c51,s2970). +registration(r10099,c104,s2970). +registration(r10100,c226,s2970). +registration(r10101,c171,s2971). +registration(r10102,c207,s2971). +registration(r10103,c40,s2971). +registration(r10104,c172,s2972). +registration(r10105,c226,s2972). +registration(r10106,c0,s2972). +registration(r10107,c211,s2973). +registration(r10108,c236,s2973). +registration(r10109,c231,s2973). +registration(r10110,c159,s2974). +registration(r10111,c129,s2974). +registration(r10112,c235,s2974). +registration(r10113,c72,s2974). +registration(r10114,c164,s2975). +registration(r10115,c189,s2975). +registration(r10116,c238,s2975). +registration(r10117,c120,s2975). +registration(r10118,c130,s2975). +registration(r10119,c92,s2976). +registration(r10120,c255,s2976). +registration(r10121,c211,s2976). +registration(r10122,c205,s2976). +registration(r10123,c62,s2977). +registration(r10124,c85,s2977). +registration(r10125,c170,s2977). +registration(r10126,c86,s2977). +registration(r10127,c252,s2978). +registration(r10128,c41,s2978). +registration(r10129,c93,s2978). +registration(r10130,c228,s2979). +registration(r10131,c131,s2979). +registration(r10132,c249,s2979). +registration(r10133,c66,s2980). +registration(r10134,c186,s2980). +registration(r10135,c63,s2980). +registration(r10136,c91,s2981). +registration(r10137,c122,s2981). +registration(r10138,c203,s2981). +registration(r10139,c202,s2982). +registration(r10140,c179,s2982). +registration(r10141,c222,s2982). +registration(r10142,c28,s2983). +registration(r10143,c238,s2983). +registration(r10144,c90,s2983). +registration(r10145,c202,s2984). +registration(r10146,c57,s2984). +registration(r10147,c109,s2984). +registration(r10148,c30,s2984). +registration(r10149,c12,s2985). +registration(r10150,c163,s2985). +registration(r10151,c222,s2985). +registration(r10152,c32,s2986). +registration(r10153,c151,s2986). +registration(r10154,c126,s2986). +registration(r10155,c63,s2986). +registration(r10156,c154,s2987). +registration(r10157,c10,s2987). +registration(r10158,c187,s2987). +registration(r10159,c110,s2988). +registration(r10160,c77,s2988). +registration(r10161,c109,s2988). +registration(r10162,c106,s2988). +registration(r10163,c121,s2989). +registration(r10164,c168,s2989). +registration(r10165,c159,s2989). +registration(r10166,c12,s2990). +registration(r10167,c108,s2990). +registration(r10168,c0,s2990). +registration(r10169,c163,s2991). +registration(r10170,c206,s2991). +registration(r10171,c84,s2991). +registration(r10172,c235,s2992). +registration(r10173,c96,s2992). +registration(r10174,c15,s2992). +registration(r10175,c60,s2992). +registration(r10176,c53,s2993). +registration(r10177,c246,s2993). +registration(r10178,c25,s2993). +registration(r10179,c101,s2993). +registration(r10180,c119,s2994). +registration(r10181,c132,s2994). +registration(r10182,c210,s2994). +registration(r10183,c121,s2995). +registration(r10184,c114,s2995). +registration(r10185,c65,s2995). +registration(r10186,c173,s2996). +registration(r10187,c91,s2996). +registration(r10188,c112,s2996). +registration(r10189,c255,s2996). +registration(r10190,c123,s2997). +registration(r10191,c226,s2997). +registration(r10192,c45,s2997). +registration(r10193,c61,s2998). +registration(r10194,c146,s2998). +registration(r10195,c127,s2998). +registration(r10196,c117,s2999). +registration(r10197,c0,s2999). +registration(r10198,c209,s2999). +registration(r10199,c72,s3000). +registration(r10200,c95,s3000). +registration(r10201,c57,s3000). +registration(r10202,c92,s3000). +registration(r10203,c143,s3001). +registration(r10204,c158,s3001). +registration(r10205,c14,s3001). +registration(r10206,c75,s3001). +registration(r10207,c127,s3002). +registration(r10208,c113,s3002). +registration(r10209,c105,s3002). +registration(r10210,c76,s3003). +registration(r10211,c236,s3003). +registration(r10212,c84,s3003). +registration(r10213,c229,s3003). +registration(r10214,c15,s3004). +registration(r10215,c17,s3004). +registration(r10216,c174,s3004). +registration(r10217,c127,s3004). +registration(r10218,c95,s3005). +registration(r10219,c121,s3005). +registration(r10220,c200,s3005). +registration(r10221,c228,s3006). +registration(r10222,c26,s3006). +registration(r10223,c102,s3006). +registration(r10224,c116,s3007). +registration(r10225,c131,s3007). +registration(r10226,c3,s3007). +registration(r10227,c118,s3007). +registration(r10228,c74,s3008). +registration(r10229,c193,s3008). +registration(r10230,c99,s3008). +registration(r10231,c183,s3009). +registration(r10232,c38,s3009). +registration(r10233,c216,s3009). +registration(r10234,c232,s3010). +registration(r10235,c75,s3010). +registration(r10236,c187,s3010). +registration(r10237,c27,s3011). +registration(r10238,c115,s3011). +registration(r10239,c147,s3011). +registration(r10240,c120,s3011). +registration(r10241,c243,s3012). +registration(r10242,c138,s3012). +registration(r10243,c234,s3012). +registration(r10244,c109,s3012). +registration(r10245,c175,s3013). +registration(r10246,c223,s3013). +registration(r10247,c112,s3013). +registration(r10248,c41,s3013). +registration(r10249,c135,s3013). +registration(r10250,c192,s3014). +registration(r10251,c224,s3014). +registration(r10252,c62,s3014). +registration(r10253,c221,s3015). +registration(r10254,c29,s3015). +registration(r10255,c160,s3015). +registration(r10256,c216,s3015). +registration(r10257,c244,s3016). +registration(r10258,c243,s3016). +registration(r10259,c12,s3016). +registration(r10260,c49,s3017). +registration(r10261,c254,s3017). +registration(r10262,c193,s3017). +registration(r10263,c110,s3018). +registration(r10264,c189,s3018). +registration(r10265,c88,s3018). +registration(r10266,c156,s3018). +registration(r10267,c66,s3019). +registration(r10268,c198,s3019). +registration(r10269,c253,s3019). +registration(r10270,c221,s3020). +registration(r10271,c9,s3020). +registration(r10272,c110,s3020). +registration(r10273,c139,s3021). +registration(r10274,c53,s3021). +registration(r10275,c15,s3021). +registration(r10276,c4,s3022). +registration(r10277,c90,s3022). +registration(r10278,c221,s3022). +registration(r10279,c15,s3022). +registration(r10280,c138,s3023). +registration(r10281,c235,s3023). +registration(r10282,c202,s3023). +registration(r10283,c136,s3024). +registration(r10284,c206,s3024). +registration(r10285,c117,s3024). +registration(r10286,c153,s3024). +registration(r10287,c235,s3025). +registration(r10288,c149,s3025). +registration(r10289,c130,s3025). +registration(r10290,c140,s3026). +registration(r10291,c224,s3026). +registration(r10292,c8,s3026). +registration(r10293,c62,s3027). +registration(r10294,c131,s3027). +registration(r10295,c210,s3027). +registration(r10296,c135,s3027). +registration(r10297,c235,s3027). +registration(r10298,c19,s3028). +registration(r10299,c85,s3028). +registration(r10300,c249,s3028). +registration(r10301,c196,s3029). +registration(r10302,c18,s3029). +registration(r10303,c152,s3029). +registration(r10304,c15,s3030). +registration(r10305,c114,s3030). +registration(r10306,c122,s3030). +registration(r10307,c15,s3031). +registration(r10308,c76,s3031). +registration(r10309,c208,s3031). +registration(r10310,c177,s3032). +registration(r10311,c137,s3032). +registration(r10312,c75,s3032). +registration(r10313,c201,s3032). +registration(r10314,c239,s3033). +registration(r10315,c213,s3033). +registration(r10316,c86,s3033). +registration(r10317,c192,s3033). +registration(r10318,c111,s3034). +registration(r10319,c187,s3034). +registration(r10320,c7,s3034). +registration(r10321,c25,s3035). +registration(r10322,c72,s3035). +registration(r10323,c205,s3035). +registration(r10324,c63,s3036). +registration(r10325,c115,s3036). +registration(r10326,c32,s3036). +registration(r10327,c108,s3037). +registration(r10328,c109,s3037). +registration(r10329,c4,s3037). +registration(r10330,c144,s3037). +registration(r10331,c145,s3038). +registration(r10332,c59,s3038). +registration(r10333,c87,s3038). +registration(r10334,c45,s3038). +registration(r10335,c183,s3039). +registration(r10336,c70,s3039). +registration(r10337,c239,s3039). +registration(r10338,c180,s3039). +registration(r10339,c40,s3040). +registration(r10340,c101,s3040). +registration(r10341,c42,s3040). +registration(r10342,c246,s3041). +registration(r10343,c59,s3041). +registration(r10344,c4,s3041). +registration(r10345,c37,s3042). +registration(r10346,c210,s3042). +registration(r10347,c49,s3042). +registration(r10348,c53,s3043). +registration(r10349,c215,s3043). +registration(r10350,c94,s3043). +registration(r10351,c154,s3044). +registration(r10352,c27,s3044). +registration(r10353,c202,s3044). +registration(r10354,c129,s3045). +registration(r10355,c11,s3045). +registration(r10356,c57,s3045). +registration(r10357,c227,s3046). +registration(r10358,c202,s3046). +registration(r10359,c38,s3046). +registration(r10360,c12,s3046). +registration(r10361,c4,s3047). +registration(r10362,c73,s3047). +registration(r10363,c217,s3047). +registration(r10364,c254,s3048). +registration(r10365,c12,s3048). +registration(r10366,c41,s3048). +registration(r10367,c94,s3049). +registration(r10368,c105,s3049). +registration(r10369,c171,s3049). +registration(r10370,c210,s3049). +registration(r10371,c62,s3050). +registration(r10372,c156,s3050). +registration(r10373,c10,s3050). +registration(r10374,c22,s3050). +registration(r10375,c194,s3051). +registration(r10376,c190,s3051). +registration(r10377,c216,s3051). +registration(r10378,c254,s3052). +registration(r10379,c179,s3052). +registration(r10380,c150,s3052). +registration(r10381,c224,s3053). +registration(r10382,c171,s3053). +registration(r10383,c242,s3053). +registration(r10384,c255,s3054). +registration(r10385,c1,s3054). +registration(r10386,c61,s3054). +registration(r10387,c165,s3055). +registration(r10388,c247,s3055). +registration(r10389,c130,s3055). +registration(r10390,c194,s3056). +registration(r10391,c19,s3056). +registration(r10392,c71,s3056). +registration(r10393,c93,s3056). +registration(r10394,c12,s3057). +registration(r10395,c240,s3057). +registration(r10396,c53,s3057). +registration(r10397,c51,s3058). +registration(r10398,c103,s3058). +registration(r10399,c19,s3058). +registration(r10400,c31,s3058). +registration(r10401,c178,s3059). +registration(r10402,c17,s3059). +registration(r10403,c205,s3059). +registration(r10404,c207,s3059). +registration(r10405,c154,s3060). +registration(r10406,c93,s3060). +registration(r10407,c46,s3060). +registration(r10408,c178,s3061). +registration(r10409,c184,s3061). +registration(r10410,c144,s3061). +registration(r10411,c216,s3062). +registration(r10412,c190,s3062). +registration(r10413,c253,s3062). +registration(r10414,c238,s3063). +registration(r10415,c104,s3063). +registration(r10416,c126,s3063). +registration(r10417,c229,s3064). +registration(r10418,c124,s3064). +registration(r10419,c162,s3064). +registration(r10420,c112,s3064). +registration(r10421,c21,s3065). +registration(r10422,c63,s3065). +registration(r10423,c180,s3065). +registration(r10424,c12,s3065). +registration(r10425,c132,s3066). +registration(r10426,c59,s3066). +registration(r10427,c144,s3066). +registration(r10428,c72,s3067). +registration(r10429,c107,s3067). +registration(r10430,c98,s3067). +registration(r10431,c66,s3067). +registration(r10432,c17,s3067). +registration(r10433,c119,s3068). +registration(r10434,c237,s3068). +registration(r10435,c0,s3068). +registration(r10436,c106,s3069). +registration(r10437,c126,s3069). +registration(r10438,c81,s3069). +registration(r10439,c86,s3069). +registration(r10440,c89,s3070). +registration(r10441,c119,s3070). +registration(r10442,c108,s3070). +registration(r10443,c148,s3070). +registration(r10444,c165,s3071). +registration(r10445,c121,s3071). +registration(r10446,c23,s3071). +registration(r10447,c241,s3071). +registration(r10448,c207,s3072). +registration(r10449,c81,s3072). +registration(r10450,c92,s3072). +registration(r10451,c103,s3072). +registration(r10452,c83,s3073). +registration(r10453,c121,s3073). +registration(r10454,c22,s3073). +registration(r10455,c247,s3074). +registration(r10456,c172,s3074). +registration(r10457,c226,s3074). +registration(r10458,c203,s3075). +registration(r10459,c149,s3075). +registration(r10460,c85,s3075). +registration(r10461,c12,s3075). +registration(r10462,c188,s3076). +registration(r10463,c55,s3076). +registration(r10464,c84,s3076). +registration(r10465,c108,s3077). +registration(r10466,c66,s3077). +registration(r10467,c188,s3077). +registration(r10468,c13,s3077). +registration(r10469,c185,s3078). +registration(r10470,c67,s3078). +registration(r10471,c116,s3078). +registration(r10472,c237,s3079). +registration(r10473,c110,s3079). +registration(r10474,c215,s3079). +registration(r10475,c134,s3080). +registration(r10476,c74,s3080). +registration(r10477,c220,s3080). +registration(r10478,c114,s3080). +registration(r10479,c219,s3081). +registration(r10480,c58,s3081). +registration(r10481,c127,s3081). +registration(r10482,c183,s3082). +registration(r10483,c241,s3082). +registration(r10484,c88,s3082). +registration(r10485,c156,s3083). +registration(r10486,c37,s3083). +registration(r10487,c187,s3083). +registration(r10488,c116,s3084). +registration(r10489,c242,s3084). +registration(r10490,c168,s3084). +registration(r10491,c149,s3085). +registration(r10492,c59,s3085). +registration(r10493,c98,s3085). +registration(r10494,c232,s3086). +registration(r10495,c70,s3086). +registration(r10496,c127,s3086). +registration(r10497,c242,s3087). +registration(r10498,c73,s3087). +registration(r10499,c151,s3087). +registration(r10500,c142,s3088). +registration(r10501,c41,s3088). +registration(r10502,c216,s3088). +registration(r10503,c54,s3089). +registration(r10504,c132,s3089). +registration(r10505,c186,s3089). +registration(r10506,c238,s3089). +registration(r10507,c102,s3090). +registration(r10508,c36,s3090). +registration(r10509,c151,s3090). +registration(r10510,c174,s3090). +registration(r10511,c111,s3090). +registration(r10512,c15,s3091). +registration(r10513,c41,s3091). +registration(r10514,c19,s3091). +registration(r10515,c146,s3092). +registration(r10516,c101,s3092). +registration(r10517,c204,s3092). +registration(r10518,c99,s3093). +registration(r10519,c247,s3093). +registration(r10520,c150,s3093). +registration(r10521,c110,s3093). +registration(r10522,c218,s3094). +registration(r10523,c180,s3094). +registration(r10524,c163,s3094). +registration(r10525,c150,s3095). +registration(r10526,c144,s3095). +registration(r10527,c92,s3095). +registration(r10528,c243,s3096). +registration(r10529,c47,s3096). +registration(r10530,c99,s3096). +registration(r10531,c158,s3096). +registration(r10532,c71,s3097). +registration(r10533,c177,s3097). +registration(r10534,c107,s3097). +registration(r10535,c209,s3098). +registration(r10536,c131,s3098). +registration(r10537,c199,s3098). +registration(r10538,c190,s3099). +registration(r10539,c23,s3099). +registration(r10540,c218,s3099). +registration(r10541,c180,s3100). +registration(r10542,c148,s3100). +registration(r10543,c42,s3100). +registration(r10544,c4,s3100). +registration(r10545,c165,s3101). +registration(r10546,c97,s3101). +registration(r10547,c189,s3101). +registration(r10548,c236,s3102). +registration(r10549,c189,s3102). +registration(r10550,c115,s3102). +registration(r10551,c187,s3102). +registration(r10552,c59,s3103). +registration(r10553,c157,s3103). +registration(r10554,c115,s3103). +registration(r10555,c247,s3104). +registration(r10556,c69,s3104). +registration(r10557,c238,s3104). +registration(r10558,c7,s3104). +registration(r10559,c185,s3105). +registration(r10560,c229,s3105). +registration(r10561,c140,s3105). +registration(r10562,c183,s3106). +registration(r10563,c129,s3106). +registration(r10564,c126,s3106). +registration(r10565,c225,s3106). +registration(r10566,c53,s3107). +registration(r10567,c129,s3107). +registration(r10568,c54,s3107). +registration(r10569,c64,s3107). +registration(r10570,c172,s3108). +registration(r10571,c112,s3108). +registration(r10572,c102,s3108). +registration(r10573,c219,s3108). +registration(r10574,c102,s3109). +registration(r10575,c124,s3109). +registration(r10576,c211,s3109). +registration(r10577,c177,s3110). +registration(r10578,c176,s3110). +registration(r10579,c114,s3110). +registration(r10580,c0,s3111). +registration(r10581,c216,s3111). +registration(r10582,c17,s3111). +registration(r10583,c144,s3112). +registration(r10584,c48,s3112). +registration(r10585,c129,s3112). +registration(r10586,c2,s3113). +registration(r10587,c167,s3113). +registration(r10588,c136,s3113). +registration(r10589,c52,s3114). +registration(r10590,c179,s3114). +registration(r10591,c186,s3114). +registration(r10592,c193,s3114). +registration(r10593,c130,s3115). +registration(r10594,c60,s3115). +registration(r10595,c103,s3115). +registration(r10596,c169,s3115). +registration(r10597,c225,s3115). +registration(r10598,c27,s3116). +registration(r10599,c132,s3116). +registration(r10600,c119,s3116). +registration(r10601,c92,s3116). +registration(r10602,c211,s3117). +registration(r10603,c182,s3117). +registration(r10604,c24,s3117). +registration(r10605,c56,s3117). +registration(r10606,c106,s3118). +registration(r10607,c59,s3118). +registration(r10608,c48,s3118). +registration(r10609,c131,s3119). +registration(r10610,c39,s3119). +registration(r10611,c49,s3119). +registration(r10612,c241,s3120). +registration(r10613,c208,s3120). +registration(r10614,c196,s3120). +registration(r10615,c56,s3120). +registration(r10616,c214,s3121). +registration(r10617,c82,s3121). +registration(r10618,c213,s3121). +registration(r10619,c77,s3122). +registration(r10620,c14,s3122). +registration(r10621,c52,s3122). +registration(r10622,c234,s3123). +registration(r10623,c238,s3123). +registration(r10624,c228,s3123). +registration(r10625,c118,s3123). +registration(r10626,c94,s3124). +registration(r10627,c169,s3124). +registration(r10628,c68,s3124). +registration(r10629,c108,s3124). +registration(r10630,c12,s3125). +registration(r10631,c105,s3125). +registration(r10632,c176,s3125). +registration(r10633,c117,s3126). +registration(r10634,c44,s3126). +registration(r10635,c115,s3126). +registration(r10636,c198,s3126). +registration(r10637,c65,s3127). +registration(r10638,c245,s3127). +registration(r10639,c156,s3127). +registration(r10640,c207,s3127). +registration(r10641,c100,s3128). +registration(r10642,c229,s3128). +registration(r10643,c186,s3128). +registration(r10644,c222,s3129). +registration(r10645,c201,s3129). +registration(r10646,c29,s3129). +registration(r10647,c98,s3130). +registration(r10648,c25,s3130). +registration(r10649,c159,s3130). +registration(r10650,c7,s3130). +registration(r10651,c126,s3131). +registration(r10652,c36,s3131). +registration(r10653,c66,s3131). +registration(r10654,c182,s3132). +registration(r10655,c95,s3132). +registration(r10656,c83,s3132). +registration(r10657,c73,s3133). +registration(r10658,c24,s3133). +registration(r10659,c48,s3133). +registration(r10660,c147,s3134). +registration(r10661,c50,s3134). +registration(r10662,c164,s3134). +registration(r10663,c129,s3135). +registration(r10664,c176,s3135). +registration(r10665,c28,s3135). +registration(r10666,c127,s3135). +registration(r10667,c215,s3136). +registration(r10668,c193,s3136). +registration(r10669,c77,s3136). +registration(r10670,c204,s3137). +registration(r10671,c33,s3137). +registration(r10672,c12,s3137). +registration(r10673,c194,s3138). +registration(r10674,c32,s3138). +registration(r10675,c199,s3138). +registration(r10676,c16,s3139). +registration(r10677,c88,s3139). +registration(r10678,c240,s3139). +registration(r10679,c132,s3140). +registration(r10680,c144,s3140). +registration(r10681,c227,s3140). +registration(r10682,c101,s3141). +registration(r10683,c26,s3141). +registration(r10684,c172,s3141). +registration(r10685,c62,s3141). +registration(r10686,c251,s3141). +registration(r10687,c0,s3142). +registration(r10688,c122,s3142). +registration(r10689,c248,s3142). +registration(r10690,c26,s3143). +registration(r10691,c215,s3143). +registration(r10692,c6,s3143). +registration(r10693,c39,s3144). +registration(r10694,c84,s3144). +registration(r10695,c217,s3144). +registration(r10696,c48,s3145). +registration(r10697,c217,s3145). +registration(r10698,c192,s3145). +registration(r10699,c81,s3146). +registration(r10700,c85,s3146). +registration(r10701,c200,s3146). +registration(r10702,c226,s3147). +registration(r10703,c139,s3147). +registration(r10704,c220,s3147). +registration(r10705,c181,s3147). +registration(r10706,c32,s3148). +registration(r10707,c49,s3148). +registration(r10708,c209,s3148). +registration(r10709,c235,s3149). +registration(r10710,c194,s3149). +registration(r10711,c124,s3149). +registration(r10712,c164,s3150). +registration(r10713,c205,s3150). +registration(r10714,c54,s3150). +registration(r10715,c103,s3150). +registration(r10716,c102,s3151). +registration(r10717,c242,s3151). +registration(r10718,c215,s3151). +registration(r10719,c45,s3152). +registration(r10720,c140,s3152). +registration(r10721,c35,s3152). +registration(r10722,c175,s3153). +registration(r10723,c196,s3153). +registration(r10724,c142,s3153). +registration(r10725,c176,s3154). +registration(r10726,c150,s3154). +registration(r10727,c108,s3154). +registration(r10728,c87,s3154). +registration(r10729,c95,s3155). +registration(r10730,c140,s3155). +registration(r10731,c210,s3155). +registration(r10732,c159,s3155). +registration(r10733,c243,s3156). +registration(r10734,c189,s3156). +registration(r10735,c207,s3156). +registration(r10736,c194,s3156). +registration(r10737,c51,s3157). +registration(r10738,c232,s3157). +registration(r10739,c7,s3157). +registration(r10740,c43,s3158). +registration(r10741,c72,s3158). +registration(r10742,c227,s3158). +registration(r10743,c115,s3158). +registration(r10744,c64,s3159). +registration(r10745,c169,s3159). +registration(r10746,c34,s3159). +registration(r10747,c191,s3159). +registration(r10748,c230,s3160). +registration(r10749,c110,s3160). +registration(r10750,c29,s3160). +registration(r10751,c218,s3161). +registration(r10752,c163,s3161). +registration(r10753,c224,s3161). +registration(r10754,c176,s3162). +registration(r10755,c40,s3162). +registration(r10756,c134,s3162). +registration(r10757,c111,s3163). +registration(r10758,c123,s3163). +registration(r10759,c189,s3163). +registration(r10760,c4,s3164). +registration(r10761,c198,s3164). +registration(r10762,c128,s3164). +registration(r10763,c57,s3164). +registration(r10764,c185,s3165). +registration(r10765,c91,s3165). +registration(r10766,c153,s3165). +registration(r10767,c128,s3165). +registration(r10768,c63,s3166). +registration(r10769,c56,s3166). +registration(r10770,c243,s3166). +registration(r10771,c151,s3166). +registration(r10772,c96,s3167). +registration(r10773,c224,s3167). +registration(r10774,c249,s3167). +registration(r10775,c9,s3167). +registration(r10776,c133,s3168). +registration(r10777,c101,s3168). +registration(r10778,c239,s3168). +registration(r10779,c33,s3168). +registration(r10780,c167,s3169). +registration(r10781,c39,s3169). +registration(r10782,c153,s3169). +registration(r10783,c56,s3169). +registration(r10784,c233,s3170). +registration(r10785,c242,s3170). +registration(r10786,c45,s3170). +registration(r10787,c72,s3171). +registration(r10788,c4,s3171). +registration(r10789,c1,s3171). +registration(r10790,c130,s3172). +registration(r10791,c148,s3172). +registration(r10792,c143,s3172). +registration(r10793,c136,s3173). +registration(r10794,c244,s3173). +registration(r10795,c125,s3173). +registration(r10796,c120,s3173). +registration(r10797,c248,s3174). +registration(r10798,c122,s3174). +registration(r10799,c6,s3174). +registration(r10800,c46,s3174). +registration(r10801,c100,s3175). +registration(r10802,c73,s3175). +registration(r10803,c103,s3175). +registration(r10804,c88,s3176). +registration(r10805,c101,s3176). +registration(r10806,c184,s3176). +registration(r10807,c173,s3176). +registration(r10808,c28,s3177). +registration(r10809,c47,s3177). +registration(r10810,c181,s3177). +registration(r10811,c68,s3178). +registration(r10812,c130,s3178). +registration(r10813,c56,s3178). +registration(r10814,c183,s3179). +registration(r10815,c214,s3179). +registration(r10816,c239,s3179). +registration(r10817,c106,s3180). +registration(r10818,c161,s3180). +registration(r10819,c153,s3180). +registration(r10820,c254,s3181). +registration(r10821,c213,s3181). +registration(r10822,c52,s3181). +registration(r10823,c140,s3181). +registration(r10824,c153,s3182). +registration(r10825,c193,s3182). +registration(r10826,c167,s3182). +registration(r10827,c195,s3183). +registration(r10828,c116,s3183). +registration(r10829,c50,s3183). +registration(r10830,c119,s3184). +registration(r10831,c227,s3184). +registration(r10832,c112,s3184). +registration(r10833,c40,s3185). +registration(r10834,c26,s3185). +registration(r10835,c75,s3185). +registration(r10836,c180,s3186). +registration(r10837,c100,s3186). +registration(r10838,c131,s3186). +registration(r10839,c129,s3187). +registration(r10840,c22,s3187). +registration(r10841,c104,s3187). +registration(r10842,c245,s3187). +registration(r10843,c79,s3188). +registration(r10844,c225,s3188). +registration(r10845,c156,s3188). +registration(r10846,c96,s3189). +registration(r10847,c11,s3189). +registration(r10848,c148,s3189). +registration(r10849,c10,s3190). +registration(r10850,c166,s3190). +registration(r10851,c181,s3190). +registration(r10852,c221,s3190). +registration(r10853,c106,s3191). +registration(r10854,c73,s3191). +registration(r10855,c161,s3191). +registration(r10856,c5,s3192). +registration(r10857,c215,s3192). +registration(r10858,c62,s3192). +registration(r10859,c84,s3193). +registration(r10860,c162,s3193). +registration(r10861,c15,s3193). +registration(r10862,c95,s3194). +registration(r10863,c86,s3194). +registration(r10864,c51,s3194). +registration(r10865,c148,s3195). +registration(r10866,c0,s3195). +registration(r10867,c74,s3195). +registration(r10868,c84,s3196). +registration(r10869,c253,s3196). +registration(r10870,c248,s3196). +registration(r10871,c214,s3197). +registration(r10872,c13,s3197). +registration(r10873,c72,s3197). +registration(r10874,c70,s3198). +registration(r10875,c125,s3198). +registration(r10876,c56,s3198). +registration(r10877,c145,s3199). +registration(r10878,c217,s3199). +registration(r10879,c86,s3199). +registration(r10880,c238,s3200). +registration(r10881,c0,s3200). +registration(r10882,c163,s3200). +registration(r10883,c245,s3200). +registration(r10884,c183,s3201). +registration(r10885,c245,s3201). +registration(r10886,c162,s3201). +registration(r10887,c57,s3201). +registration(r10888,c12,s3202). +registration(r10889,c52,s3202). +registration(r10890,c156,s3202). +registration(r10891,c10,s3202). +registration(r10892,c83,s3203). +registration(r10893,c130,s3203). +registration(r10894,c10,s3203). +registration(r10895,c67,s3204). +registration(r10896,c30,s3204). +registration(r10897,c180,s3204). +registration(r10898,c10,s3205). +registration(r10899,c119,s3205). +registration(r10900,c69,s3205). +registration(r10901,c232,s3206). +registration(r10902,c27,s3206). +registration(r10903,c108,s3206). +registration(r10904,c98,s3207). +registration(r10905,c231,s3207). +registration(r10906,c224,s3207). +registration(r10907,c238,s3208). +registration(r10908,c207,s3208). +registration(r10909,c122,s3208). +registration(r10910,c36,s3209). +registration(r10911,c76,s3209). +registration(r10912,c93,s3209). +registration(r10913,c229,s3209). +registration(r10914,c113,s3210). +registration(r10915,c3,s3210). +registration(r10916,c14,s3210). +registration(r10917,c24,s3211). +registration(r10918,c190,s3211). +registration(r10919,c64,s3211). +registration(r10920,c53,s3211). +registration(r10921,c46,s3211). +registration(r10922,c161,s3212). +registration(r10923,c107,s3212). +registration(r10924,c0,s3212). +registration(r10925,c82,s3212). +registration(r10926,c161,s3213). +registration(r10927,c50,s3213). +registration(r10928,c209,s3213). +registration(r10929,c201,s3214). +registration(r10930,c76,s3214). +registration(r10931,c210,s3214). +registration(r10932,c168,s3214). +registration(r10933,c251,s3214). +registration(r10934,c3,s3215). +registration(r10935,c115,s3215). +registration(r10936,c255,s3215). +registration(r10937,c185,s3215). +registration(r10938,c42,s3216). +registration(r10939,c120,s3216). +registration(r10940,c58,s3216). +registration(r10941,c97,s3217). +registration(r10942,c106,s3217). +registration(r10943,c78,s3217). +registration(r10944,c83,s3218). +registration(r10945,c31,s3218). +registration(r10946,c77,s3218). +registration(r10947,c30,s3219). +registration(r10948,c103,s3219). +registration(r10949,c0,s3219). +registration(r10950,c210,s3220). +registration(r10951,c253,s3220). +registration(r10952,c91,s3220). +registration(r10953,c96,s3221). +registration(r10954,c69,s3221). +registration(r10955,c248,s3221). +registration(r10956,c241,s3222). +registration(r10957,c155,s3222). +registration(r10958,c118,s3222). +registration(r10959,c215,s3222). +registration(r10960,c139,s3222). +registration(r10961,c66,s3223). +registration(r10962,c116,s3223). +registration(r10963,c90,s3223). +registration(r10964,c122,s3224). +registration(r10965,c250,s3224). +registration(r10966,c188,s3224). +registration(r10967,c35,s3224). +registration(r10968,c204,s3225). +registration(r10969,c0,s3225). +registration(r10970,c215,s3225). +registration(r10971,c51,s3226). +registration(r10972,c114,s3226). +registration(r10973,c247,s3226). +registration(r10974,c239,s3227). +registration(r10975,c5,s3227). +registration(r10976,c183,s3227). +registration(r10977,c47,s3228). +registration(r10978,c12,s3228). +registration(r10979,c122,s3228). +registration(r10980,c187,s3229). +registration(r10981,c200,s3229). +registration(r10982,c244,s3229). +registration(r10983,c111,s3230). +registration(r10984,c98,s3230). +registration(r10985,c75,s3230). +registration(r10986,c111,s3231). +registration(r10987,c8,s3231). +registration(r10988,c125,s3231). +registration(r10989,c123,s3232). +registration(r10990,c122,s3232). +registration(r10991,c25,s3232). +registration(r10992,c209,s3232). +registration(r10993,c98,s3233). +registration(r10994,c19,s3233). +registration(r10995,c137,s3233). +registration(r10996,c183,s3234). +registration(r10997,c80,s3234). +registration(r10998,c46,s3234). +registration(r10999,c234,s3234). +registration(r11000,c212,s3235). +registration(r11001,c223,s3235). +registration(r11002,c82,s3235). +registration(r11003,c182,s3236). +registration(r11004,c175,s3236). +registration(r11005,c136,s3236). +registration(r11006,c31,s3236). +registration(r11007,c175,s3237). +registration(r11008,c101,s3237). +registration(r11009,c57,s3237). +registration(r11010,c225,s3237). +registration(r11011,c156,s3238). +registration(r11012,c239,s3238). +registration(r11013,c36,s3238). +registration(r11014,c173,s3238). +registration(r11015,c66,s3239). +registration(r11016,c184,s3239). +registration(r11017,c101,s3239). +registration(r11018,c113,s3240). +registration(r11019,c126,s3240). +registration(r11020,c209,s3240). +registration(r11021,c36,s3241). +registration(r11022,c169,s3241). +registration(r11023,c171,s3241). +registration(r11024,c52,s3242). +registration(r11025,c13,s3242). +registration(r11026,c122,s3242). +registration(r11027,c223,s3243). +registration(r11028,c1,s3243). +registration(r11029,c231,s3243). +registration(r11030,c132,s3244). +registration(r11031,c175,s3244). +registration(r11032,c120,s3244). +registration(r11033,c39,s3245). +registration(r11034,c198,s3245). +registration(r11035,c106,s3245). +registration(r11036,c81,s3246). +registration(r11037,c253,s3246). +registration(r11038,c214,s3246). +registration(r11039,c66,s3246). +registration(r11040,c71,s3247). +registration(r11041,c236,s3247). +registration(r11042,c221,s3247). +registration(r11043,c69,s3247). +registration(r11044,c47,s3247). +registration(r11045,c191,s3248). +registration(r11046,c217,s3248). +registration(r11047,c238,s3248). +registration(r11048,c213,s3249). +registration(r11049,c94,s3249). +registration(r11050,c47,s3249). +registration(r11051,c170,s3249). +registration(r11052,c222,s3250). +registration(r11053,c192,s3250). +registration(r11054,c208,s3250). +registration(r11055,c92,s3250). +registration(r11056,c253,s3251). +registration(r11057,c124,s3251). +registration(r11058,c91,s3251). +registration(r11059,c159,s3252). +registration(r11060,c8,s3252). +registration(r11061,c231,s3252). +registration(r11062,c9,s3253). +registration(r11063,c210,s3253). +registration(r11064,c248,s3253). +registration(r11065,c210,s3254). +registration(r11066,c40,s3254). +registration(r11067,c48,s3254). +registration(r11068,c143,s3255). +registration(r11069,c222,s3255). +registration(r11070,c87,s3255). +registration(r11071,c54,s3256). +registration(r11072,c95,s3256). +registration(r11073,c90,s3256). +registration(r11074,c184,s3257). +registration(r11075,c217,s3257). +registration(r11076,c7,s3257). +registration(r11077,c172,s3257). +registration(r11078,c179,s3258). +registration(r11079,c182,s3258). +registration(r11080,c141,s3258). +registration(r11081,c152,s3259). +registration(r11082,c18,s3259). +registration(r11083,c148,s3259). +registration(r11084,c103,s3260). +registration(r11085,c251,s3260). +registration(r11086,c211,s3260). +registration(r11087,c248,s3260). +registration(r11088,c243,s3261). +registration(r11089,c81,s3261). +registration(r11090,c1,s3261). +registration(r11091,c95,s3262). +registration(r11092,c214,s3262). +registration(r11093,c99,s3262). +registration(r11094,c60,s3263). +registration(r11095,c241,s3263). +registration(r11096,c162,s3263). +registration(r11097,c86,s3264). +registration(r11098,c161,s3264). +registration(r11099,c38,s3264). +registration(r11100,c191,s3265). +registration(r11101,c167,s3265). +registration(r11102,c210,s3265). +registration(r11103,c57,s3266). +registration(r11104,c141,s3266). +registration(r11105,c33,s3266). +registration(r11106,c132,s3267). +registration(r11107,c66,s3267). +registration(r11108,c216,s3267). +registration(r11109,c96,s3268). +registration(r11110,c230,s3268). +registration(r11111,c149,s3268). +registration(r11112,c36,s3269). +registration(r11113,c1,s3269). +registration(r11114,c193,s3269). +registration(r11115,c88,s3270). +registration(r11116,c29,s3270). +registration(r11117,c142,s3270). +registration(r11118,c202,s3271). +registration(r11119,c62,s3271). +registration(r11120,c92,s3271). +registration(r11121,c169,s3272). +registration(r11122,c214,s3272). +registration(r11123,c92,s3272). +registration(r11124,c228,s3272). +registration(r11125,c79,s3273). +registration(r11126,c105,s3273). +registration(r11127,c189,s3273). +registration(r11128,c29,s3273). +registration(r11129,c187,s3274). +registration(r11130,c190,s3274). +registration(r11131,c226,s3274). +registration(r11132,c228,s3275). +registration(r11133,c75,s3275). +registration(r11134,c169,s3275). +registration(r11135,c199,s3276). +registration(r11136,c93,s3276). +registration(r11137,c35,s3276). +registration(r11138,c99,s3276). +registration(r11139,c216,s3277). +registration(r11140,c195,s3277). +registration(r11141,c50,s3277). +registration(r11142,c144,s3278). +registration(r11143,c76,s3278). +registration(r11144,c192,s3278). +registration(r11145,c40,s3279). +registration(r11146,c50,s3279). +registration(r11147,c115,s3279). +registration(r11148,c45,s3280). +registration(r11149,c14,s3280). +registration(r11150,c51,s3280). +registration(r11151,c21,s3281). +registration(r11152,c5,s3281). +registration(r11153,c156,s3281). +registration(r11154,c99,s3282). +registration(r11155,c67,s3282). +registration(r11156,c206,s3282). +registration(r11157,c49,s3283). +registration(r11158,c183,s3283). +registration(r11159,c48,s3283). +registration(r11160,c202,s3284). +registration(r11161,c244,s3284). +registration(r11162,c132,s3284). +registration(r11163,c34,s3285). +registration(r11164,c179,s3285). +registration(r11165,c154,s3285). +registration(r11166,c233,s3285). +registration(r11167,c194,s3286). +registration(r11168,c17,s3286). +registration(r11169,c27,s3286). +registration(r11170,c50,s3286). +registration(r11171,c129,s3287). +registration(r11172,c159,s3287). +registration(r11173,c22,s3287). +registration(r11174,c2,s3287). +registration(r11175,c249,s3288). +registration(r11176,c224,s3288). +registration(r11177,c197,s3288). +registration(r11178,c151,s3288). +registration(r11179,c142,s3289). +registration(r11180,c210,s3289). +registration(r11181,c193,s3289). +registration(r11182,c77,s3290). +registration(r11183,c236,s3290). +registration(r11184,c122,s3290). +registration(r11185,c134,s3290). +registration(r11186,c3,s3290). +registration(r11187,c111,s3291). +registration(r11188,c209,s3291). +registration(r11189,c21,s3291). +registration(r11190,c25,s3292). +registration(r11191,c187,s3292). +registration(r11192,c206,s3292). +registration(r11193,c249,s3293). +registration(r11194,c185,s3293). +registration(r11195,c44,s3293). +registration(r11196,c243,s3294). +registration(r11197,c30,s3294). +registration(r11198,c53,s3294). +registration(r11199,c7,s3295). +registration(r11200,c173,s3295). +registration(r11201,c48,s3295). +registration(r11202,c28,s3296). +registration(r11203,c219,s3296). +registration(r11204,c250,s3296). +registration(r11205,c254,s3297). +registration(r11206,c18,s3297). +registration(r11207,c186,s3297). +registration(r11208,c156,s3297). +registration(r11209,c45,s3297). +registration(r11210,c88,s3298). +registration(r11211,c213,s3298). +registration(r11212,c229,s3298). +registration(r11213,c205,s3298). +registration(r11214,c88,s3299). +registration(r11215,c194,s3299). +registration(r11216,c58,s3299). +registration(r11217,c111,s3300). +registration(r11218,c55,s3300). +registration(r11219,c141,s3300). +registration(r11220,c189,s3301). +registration(r11221,c215,s3301). +registration(r11222,c223,s3301). +registration(r11223,c218,s3302). +registration(r11224,c123,s3302). +registration(r11225,c156,s3302). +registration(r11226,c87,s3303). +registration(r11227,c236,s3303). +registration(r11228,c42,s3303). +registration(r11229,c132,s3303). +registration(r11230,c53,s3304). +registration(r11231,c254,s3304). +registration(r11232,c174,s3304). +registration(r11233,c156,s3304). +registration(r11234,c197,s3304). +registration(r11235,c216,s3305). +registration(r11236,c83,s3305). +registration(r11237,c165,s3305). +registration(r11238,c51,s3306). +registration(r11239,c191,s3306). +registration(r11240,c111,s3306). +registration(r11241,c79,s3307). +registration(r11242,c201,s3307). +registration(r11243,c72,s3307). +registration(r11244,c68,s3307). +registration(r11245,c2,s3308). +registration(r11246,c211,s3308). +registration(r11247,c61,s3308). +registration(r11248,c156,s3309). +registration(r11249,c8,s3309). +registration(r11250,c130,s3309). +registration(r11251,c49,s3309). +registration(r11252,c214,s3310). +registration(r11253,c164,s3310). +registration(r11254,c56,s3310). +registration(r11255,c139,s3311). +registration(r11256,c66,s3311). +registration(r11257,c198,s3311). +registration(r11258,c117,s3311). +registration(r11259,c134,s3312). +registration(r11260,c101,s3312). +registration(r11261,c26,s3312). +registration(r11262,c99,s3312). +registration(r11263,c255,s3313). +registration(r11264,c116,s3313). +registration(r11265,c71,s3313). +registration(r11266,c72,s3313). +registration(r11267,c240,s3314). +registration(r11268,c71,s3314). +registration(r11269,c33,s3314). +registration(r11270,c244,s3315). +registration(r11271,c0,s3315). +registration(r11272,c251,s3315). +registration(r11273,c52,s3316). +registration(r11274,c103,s3316). +registration(r11275,c35,s3316). +registration(r11276,c232,s3317). +registration(r11277,c213,s3317). +registration(r11278,c31,s3317). +registration(r11279,c133,s3318). +registration(r11280,c136,s3318). +registration(r11281,c51,s3318). +registration(r11282,c50,s3319). +registration(r11283,c41,s3319). +registration(r11284,c53,s3319). +registration(r11285,c185,s3320). +registration(r11286,c36,s3320). +registration(r11287,c186,s3320). +registration(r11288,c131,s3320). +registration(r11289,c207,s3321). +registration(r11290,c30,s3321). +registration(r11291,c127,s3321). +registration(r11292,c179,s3322). +registration(r11293,c1,s3322). +registration(r11294,c231,s3322). +registration(r11295,c208,s3323). +registration(r11296,c74,s3323). +registration(r11297,c201,s3323). +registration(r11298,c79,s3324). +registration(r11299,c198,s3324). +registration(r11300,c219,s3324). +registration(r11301,c176,s3324). +registration(r11302,c45,s3324). +registration(r11303,c229,s3325). +registration(r11304,c66,s3325). +registration(r11305,c161,s3325). +registration(r11306,c91,s3326). +registration(r11307,c123,s3326). +registration(r11308,c134,s3326). +registration(r11309,c164,s3327). +registration(r11310,c94,s3327). +registration(r11311,c228,s3327). +registration(r11312,c230,s3327). +registration(r11313,c79,s3328). +registration(r11314,c134,s3328). +registration(r11315,c146,s3328). +registration(r11316,c209,s3328). +registration(r11317,c93,s3329). +registration(r11318,c121,s3329). +registration(r11319,c172,s3329). +registration(r11320,c82,s3329). +registration(r11321,c212,s3330). +registration(r11322,c97,s3330). +registration(r11323,c223,s3330). +registration(r11324,c128,s3331). +registration(r11325,c88,s3331). +registration(r11326,c12,s3331). +registration(r11327,c146,s3332). +registration(r11328,c187,s3332). +registration(r11329,c29,s3332). +registration(r11330,c2,s3332). +registration(r11331,c158,s3333). +registration(r11332,c45,s3333). +registration(r11333,c232,s3333). +registration(r11334,c122,s3334). +registration(r11335,c13,s3334). +registration(r11336,c133,s3334). +registration(r11337,c253,s3335). +registration(r11338,c128,s3335). +registration(r11339,c142,s3335). +registration(r11340,c97,s3335). +registration(r11341,c178,s3336). +registration(r11342,c16,s3336). +registration(r11343,c29,s3336). +registration(r11344,c118,s3337). +registration(r11345,c99,s3337). +registration(r11346,c108,s3337). +registration(r11347,c39,s3338). +registration(r11348,c104,s3338). +registration(r11349,c45,s3338). +registration(r11350,c203,s3339). +registration(r11351,c111,s3339). +registration(r11352,c83,s3339). +registration(r11353,c206,s3339). +registration(r11354,c199,s3340). +registration(r11355,c168,s3340). +registration(r11356,c162,s3340). +registration(r11357,c165,s3340). +registration(r11358,c192,s3340). +registration(r11359,c247,s3341). +registration(r11360,c86,s3341). +registration(r11361,c35,s3341). +registration(r11362,c64,s3342). +registration(r11363,c2,s3342). +registration(r11364,c247,s3342). +registration(r11365,c99,s3343). +registration(r11366,c1,s3343). +registration(r11367,c92,s3343). +registration(r11368,c137,s3344). +registration(r11369,c206,s3344). +registration(r11370,c212,s3344). +registration(r11371,c39,s3345). +registration(r11372,c14,s3345). +registration(r11373,c100,s3345). +registration(r11374,c12,s3346). +registration(r11375,c153,s3346). +registration(r11376,c7,s3346). +registration(r11377,c200,s3347). +registration(r11378,c170,s3347). +registration(r11379,c21,s3347). +registration(r11380,c124,s3348). +registration(r11381,c44,s3348). +registration(r11382,c87,s3348). +registration(r11383,c189,s3349). +registration(r11384,c215,s3349). +registration(r11385,c228,s3349). +registration(r11386,c98,s3349). +registration(r11387,c163,s3350). +registration(r11388,c49,s3350). +registration(r11389,c33,s3350). +registration(r11390,c73,s3351). +registration(r11391,c6,s3351). +registration(r11392,c212,s3351). +registration(r11393,c224,s3352). +registration(r11394,c216,s3352). +registration(r11395,c228,s3352). +registration(r11396,c172,s3353). +registration(r11397,c62,s3353). +registration(r11398,c173,s3353). +registration(r11399,c41,s3354). +registration(r11400,c197,s3354). +registration(r11401,c235,s3354). +registration(r11402,c168,s3355). +registration(r11403,c116,s3355). +registration(r11404,c140,s3355). +registration(r11405,c218,s3356). +registration(r11406,c101,s3356). +registration(r11407,c10,s3356). +registration(r11408,c123,s3357). +registration(r11409,c69,s3357). +registration(r11410,c101,s3357). +registration(r11411,c65,s3358). +registration(r11412,c48,s3358). +registration(r11413,c96,s3358). +registration(r11414,c197,s3358). +registration(r11415,c210,s3359). +registration(r11416,c3,s3359). +registration(r11417,c163,s3359). +registration(r11418,c205,s3360). +registration(r11419,c47,s3360). +registration(r11420,c130,s3360). +registration(r11421,c43,s3361). +registration(r11422,c222,s3361). +registration(r11423,c100,s3361). +registration(r11424,c62,s3362). +registration(r11425,c86,s3362). +registration(r11426,c193,s3362). +registration(r11427,c59,s3363). +registration(r11428,c129,s3363). +registration(r11429,c24,s3363). +registration(r11430,c91,s3363). +registration(r11431,c187,s3364). +registration(r11432,c101,s3364). +registration(r11433,c128,s3364). +registration(r11434,c82,s3365). +registration(r11435,c132,s3365). +registration(r11436,c1,s3365). +registration(r11437,c207,s3365). +registration(r11438,c236,s3366). +registration(r11439,c157,s3366). +registration(r11440,c56,s3366). +registration(r11441,c23,s3367). +registration(r11442,c41,s3367). +registration(r11443,c185,s3367). +registration(r11444,c14,s3368). +registration(r11445,c143,s3368). +registration(r11446,c163,s3368). +registration(r11447,c35,s3369). +registration(r11448,c219,s3369). +registration(r11449,c86,s3369). +registration(r11450,c54,s3369). +registration(r11451,c145,s3369). +registration(r11452,c182,s3370). +registration(r11453,c146,s3370). +registration(r11454,c237,s3370). +registration(r11455,c22,s3370). +registration(r11456,c197,s3371). +registration(r11457,c49,s3371). +registration(r11458,c189,s3371). +registration(r11459,c246,s3372). +registration(r11460,c118,s3372). +registration(r11461,c154,s3372). +registration(r11462,c160,s3372). +registration(r11463,c220,s3373). +registration(r11464,c8,s3373). +registration(r11465,c98,s3373). +registration(r11466,c37,s3374). +registration(r11467,c55,s3374). +registration(r11468,c206,s3374). +registration(r11469,c141,s3374). +registration(r11470,c54,s3375). +registration(r11471,c159,s3375). +registration(r11472,c136,s3375). +registration(r11473,c117,s3375). +registration(r11474,c245,s3376). +registration(r11475,c72,s3376). +registration(r11476,c100,s3376). +registration(r11477,c34,s3377). +registration(r11478,c110,s3377). +registration(r11479,c75,s3377). +registration(r11480,c229,s3377). +registration(r11481,c38,s3378). +registration(r11482,c134,s3378). +registration(r11483,c57,s3378). +registration(r11484,c143,s3378). +registration(r11485,c109,s3379). +registration(r11486,c56,s3379). +registration(r11487,c193,s3379). +registration(r11488,c194,s3379). +registration(r11489,c49,s3380). +registration(r11490,c254,s3380). +registration(r11491,c247,s3380). +registration(r11492,c229,s3381). +registration(r11493,c2,s3381). +registration(r11494,c252,s3381). +registration(r11495,c96,s3382). +registration(r11496,c150,s3382). +registration(r11497,c198,s3382). +registration(r11498,c16,s3382). +registration(r11499,c155,s3383). +registration(r11500,c233,s3383). +registration(r11501,c246,s3383). +registration(r11502,c47,s3384). +registration(r11503,c196,s3384). +registration(r11504,c253,s3384). +registration(r11505,c54,s3384). +registration(r11506,c140,s3385). +registration(r11507,c214,s3385). +registration(r11508,c60,s3385). +registration(r11509,c58,s3385). +registration(r11510,c71,s3386). +registration(r11511,c216,s3386). +registration(r11512,c192,s3386). +registration(r11513,c219,s3386). +registration(r11514,c8,s3387). +registration(r11515,c39,s3387). +registration(r11516,c30,s3387). +registration(r11517,c160,s3388). +registration(r11518,c163,s3388). +registration(r11519,c253,s3388). +registration(r11520,c244,s3389). +registration(r11521,c253,s3389). +registration(r11522,c251,s3389). +registration(r11523,c191,s3389). +registration(r11524,c240,s3390). +registration(r11525,c244,s3390). +registration(r11526,c48,s3390). +registration(r11527,c109,s3391). +registration(r11528,c203,s3391). +registration(r11529,c210,s3391). +registration(r11530,c168,s3391). +registration(r11531,c105,s3392). +registration(r11532,c64,s3392). +registration(r11533,c133,s3392). +registration(r11534,c73,s3392). +registration(r11535,c68,s3393). +registration(r11536,c232,s3393). +registration(r11537,c151,s3393). +registration(r11538,c149,s3394). +registration(r11539,c33,s3394). +registration(r11540,c25,s3394). +registration(r11541,c21,s3394). +registration(r11542,c173,s3395). +registration(r11543,c226,s3395). +registration(r11544,c16,s3395). +registration(r11545,c65,s3396). +registration(r11546,c26,s3396). +registration(r11547,c161,s3396). +registration(r11548,c114,s3397). +registration(r11549,c86,s3397). +registration(r11550,c249,s3397). +registration(r11551,c192,s3397). +registration(r11552,c160,s3398). +registration(r11553,c231,s3398). +registration(r11554,c130,s3398). +registration(r11555,c106,s3398). +registration(r11556,c227,s3399). +registration(r11557,c17,s3399). +registration(r11558,c247,s3399). +registration(r11559,c16,s3400). +registration(r11560,c1,s3400). +registration(r11561,c85,s3400). +registration(r11562,c176,s3400). +registration(r11563,c55,s3401). +registration(r11564,c78,s3401). +registration(r11565,c12,s3401). +registration(r11566,c173,s3402). +registration(r11567,c40,s3402). +registration(r11568,c79,s3402). +registration(r11569,c128,s3402). +registration(r11570,c60,s3403). +registration(r11571,c64,s3403). +registration(r11572,c131,s3403). +registration(r11573,c5,s3403). +registration(r11574,c41,s3404). +registration(r11575,c84,s3404). +registration(r11576,c114,s3404). +registration(r11577,c102,s3404). +registration(r11578,c132,s3405). +registration(r11579,c153,s3405). +registration(r11580,c120,s3405). +registration(r11581,c160,s3406). +registration(r11582,c54,s3406). +registration(r11583,c35,s3406). +registration(r11584,c48,s3407). +registration(r11585,c82,s3407). +registration(r11586,c236,s3407). +registration(r11587,c58,s3408). +registration(r11588,c253,s3408). +registration(r11589,c248,s3408). +registration(r11590,c58,s3409). +registration(r11591,c5,s3409). +registration(r11592,c24,s3409). +registration(r11593,c66,s3409). +registration(r11594,c181,s3410). +registration(r11595,c124,s3410). +registration(r11596,c76,s3410). +registration(r11597,c229,s3410). +registration(r11598,c180,s3411). +registration(r11599,c94,s3411). +registration(r11600,c88,s3411). +registration(r11601,c143,s3412). +registration(r11602,c197,s3412). +registration(r11603,c216,s3412). +registration(r11604,c246,s3412). +registration(r11605,c255,s3412). +registration(r11606,c211,s3413). +registration(r11607,c163,s3413). +registration(r11608,c58,s3413). +registration(r11609,c190,s3414). +registration(r11610,c12,s3414). +registration(r11611,c216,s3414). +registration(r11612,c57,s3414). +registration(r11613,c206,s3415). +registration(r11614,c99,s3415). +registration(r11615,c238,s3415). +registration(r11616,c9,s3416). +registration(r11617,c49,s3416). +registration(r11618,c132,s3416). +registration(r11619,c220,s3417). +registration(r11620,c95,s3417). +registration(r11621,c143,s3417). +registration(r11622,c103,s3417). +registration(r11623,c127,s3418). +registration(r11624,c27,s3418). +registration(r11625,c146,s3418). +registration(r11626,c53,s3419). +registration(r11627,c186,s3419). +registration(r11628,c193,s3419). +registration(r11629,c205,s3420). +registration(r11630,c170,s3420). +registration(r11631,c59,s3420). +registration(r11632,c10,s3421). +registration(r11633,c85,s3421). +registration(r11634,c211,s3421). +registration(r11635,c221,s3421). +registration(r11636,c135,s3422). +registration(r11637,c138,s3422). +registration(r11638,c155,s3422). +registration(r11639,c101,s3422). +registration(r11640,c166,s3423). +registration(r11641,c210,s3423). +registration(r11642,c31,s3423). +registration(r11643,c82,s3423). +registration(r11644,c159,s3424). +registration(r11645,c209,s3424). +registration(r11646,c42,s3424). +registration(r11647,c235,s3425). +registration(r11648,c166,s3425). +registration(r11649,c3,s3425). +registration(r11650,c63,s3426). +registration(r11651,c170,s3426). +registration(r11652,c54,s3426). +registration(r11653,c10,s3427). +registration(r11654,c161,s3427). +registration(r11655,c5,s3427). +registration(r11656,c143,s3427). +registration(r11657,c131,s3428). +registration(r11658,c62,s3428). +registration(r11659,c246,s3428). +registration(r11660,c200,s3429). +registration(r11661,c157,s3429). +registration(r11662,c243,s3429). +registration(r11663,c216,s3429). +registration(r11664,c235,s3430). +registration(r11665,c4,s3430). +registration(r11666,c103,s3430). +registration(r11667,c14,s3431). +registration(r11668,c123,s3431). +registration(r11669,c169,s3431). +registration(r11670,c82,s3432). +registration(r11671,c153,s3432). +registration(r11672,c5,s3432). +registration(r11673,c165,s3433). +registration(r11674,c86,s3433). +registration(r11675,c139,s3433). +registration(r11676,c14,s3434). +registration(r11677,c12,s3434). +registration(r11678,c221,s3434). +registration(r11679,c165,s3435). +registration(r11680,c42,s3435). +registration(r11681,c229,s3435). +registration(r11682,c119,s3435). +registration(r11683,c171,s3436). +registration(r11684,c8,s3436). +registration(r11685,c222,s3436). +registration(r11686,c248,s3436). +registration(r11687,c158,s3437). +registration(r11688,c161,s3437). +registration(r11689,c77,s3437). +registration(r11690,c231,s3438). +registration(r11691,c93,s3438). +registration(r11692,c68,s3438). +registration(r11693,c156,s3438). +registration(r11694,c22,s3439). +registration(r11695,c209,s3439). +registration(r11696,c131,s3439). +registration(r11697,c222,s3439). +registration(r11698,c177,s3440). +registration(r11699,c207,s3440). +registration(r11700,c5,s3440). +registration(r11701,c197,s3441). +registration(r11702,c224,s3441). +registration(r11703,c44,s3441). +registration(r11704,c11,s3442). +registration(r11705,c149,s3442). +registration(r11706,c224,s3442). +registration(r11707,c129,s3443). +registration(r11708,c70,s3443). +registration(r11709,c141,s3443). +registration(r11710,c235,s3443). +registration(r11711,c186,s3444). +registration(r11712,c183,s3444). +registration(r11713,c239,s3444). +registration(r11714,c192,s3445). +registration(r11715,c217,s3445). +registration(r11716,c243,s3445). +registration(r11717,c165,s3446). +registration(r11718,c109,s3446). +registration(r11719,c63,s3446). +registration(r11720,c5,s3446). +registration(r11721,c98,s3447). +registration(r11722,c78,s3447). +registration(r11723,c120,s3447). +registration(r11724,c12,s3448). +registration(r11725,c44,s3448). +registration(r11726,c83,s3448). +registration(r11727,c153,s3449). +registration(r11728,c204,s3449). +registration(r11729,c34,s3449). +registration(r11730,c220,s3450). +registration(r11731,c127,s3450). +registration(r11732,c165,s3450). +registration(r11733,c102,s3451). +registration(r11734,c12,s3451). +registration(r11735,c66,s3451). +registration(r11736,c72,s3451). +registration(r11737,c114,s3452). +registration(r11738,c135,s3452). +registration(r11739,c105,s3452). +registration(r11740,c204,s3453). +registration(r11741,c228,s3453). +registration(r11742,c3,s3453). +registration(r11743,c62,s3453). +registration(r11744,c69,s3453). +registration(r11745,c144,s3454). +registration(r11746,c78,s3454). +registration(r11747,c242,s3454). +registration(r11748,c26,s3454). +registration(r11749,c239,s3454). +registration(r11750,c209,s3455). +registration(r11751,c241,s3455). +registration(r11752,c111,s3455). +registration(r11753,c189,s3455). +registration(r11754,c221,s3456). +registration(r11755,c49,s3456). +registration(r11756,c0,s3456). +registration(r11757,c232,s3457). +registration(r11758,c84,s3457). +registration(r11759,c255,s3457). +registration(r11760,c139,s3458). +registration(r11761,c31,s3458). +registration(r11762,c206,s3458). +registration(r11763,c12,s3459). +registration(r11764,c158,s3459). +registration(r11765,c124,s3459). +registration(r11766,c110,s3460). +registration(r11767,c198,s3460). +registration(r11768,c7,s3460). +registration(r11769,c217,s3461). +registration(r11770,c115,s3461). +registration(r11771,c37,s3461). +registration(r11772,c228,s3462). +registration(r11773,c46,s3462). +registration(r11774,c202,s3462). +registration(r11775,c67,s3462). +registration(r11776,c205,s3463). +registration(r11777,c101,s3463). +registration(r11778,c66,s3463). +registration(r11779,c80,s3463). +registration(r11780,c62,s3464). +registration(r11781,c29,s3464). +registration(r11782,c94,s3464). +registration(r11783,c250,s3464). +registration(r11784,c242,s3465). +registration(r11785,c197,s3465). +registration(r11786,c230,s3465). +registration(r11787,c238,s3466). +registration(r11788,c226,s3466). +registration(r11789,c66,s3466). +registration(r11790,c104,s3467). +registration(r11791,c24,s3467). +registration(r11792,c240,s3467). +registration(r11793,c187,s3468). +registration(r11794,c49,s3468). +registration(r11795,c89,s3468). +registration(r11796,c190,s3469). +registration(r11797,c65,s3469). +registration(r11798,c30,s3469). +registration(r11799,c15,s3469). +registration(r11800,c44,s3470). +registration(r11801,c109,s3470). +registration(r11802,c212,s3470). +registration(r11803,c198,s3471). +registration(r11804,c29,s3471). +registration(r11805,c79,s3471). +registration(r11806,c169,s3471). +registration(r11807,c10,s3472). +registration(r11808,c236,s3472). +registration(r11809,c5,s3472). +registration(r11810,c30,s3473). +registration(r11811,c83,s3473). +registration(r11812,c163,s3473). +registration(r11813,c212,s3473). +registration(r11814,c190,s3474). +registration(r11815,c12,s3474). +registration(r11816,c211,s3474). +registration(r11817,c241,s3475). +registration(r11818,c139,s3475). +registration(r11819,c93,s3475). +registration(r11820,c202,s3476). +registration(r11821,c34,s3476). +registration(r11822,c15,s3476). +registration(r11823,c233,s3476). +registration(r11824,c128,s3476). +registration(r11825,c15,s3477). +registration(r11826,c215,s3477). +registration(r11827,c189,s3477). +registration(r11828,c195,s3477). +registration(r11829,c123,s3478). +registration(r11830,c24,s3478). +registration(r11831,c226,s3478). +registration(r11832,c71,s3479). +registration(r11833,c220,s3479). +registration(r11834,c143,s3479). +registration(r11835,c233,s3479). +registration(r11836,c131,s3480). +registration(r11837,c55,s3480). +registration(r11838,c85,s3480). +registration(r11839,c150,s3480). +registration(r11840,c200,s3481). +registration(r11841,c95,s3481). +registration(r11842,c198,s3481). +registration(r11843,c176,s3482). +registration(r11844,c6,s3482). +registration(r11845,c19,s3482). +registration(r11846,c209,s3483). +registration(r11847,c217,s3483). +registration(r11848,c160,s3483). +registration(r11849,c186,s3484). +registration(r11850,c118,s3484). +registration(r11851,c35,s3484). +registration(r11852,c0,s3485). +registration(r11853,c6,s3485). +registration(r11854,c197,s3485). +registration(r11855,c72,s3486). +registration(r11856,c32,s3486). +registration(r11857,c189,s3486). +registration(r11858,c97,s3487). +registration(r11859,c33,s3487). +registration(r11860,c22,s3487). +registration(r11861,c250,s3487). +registration(r11862,c216,s3488). +registration(r11863,c1,s3488). +registration(r11864,c187,s3488). +registration(r11865,c140,s3489). +registration(r11866,c113,s3489). +registration(r11867,c129,s3489). +registration(r11868,c200,s3489). +registration(r11869,c152,s3490). +registration(r11870,c235,s3490). +registration(r11871,c177,s3490). +registration(r11872,c184,s3491). +registration(r11873,c28,s3491). +registration(r11874,c213,s3491). +registration(r11875,c100,s3491). +registration(r11876,c222,s3492). +registration(r11877,c188,s3492). +registration(r11878,c170,s3492). +registration(r11879,c193,s3493). +registration(r11880,c103,s3493). +registration(r11881,c217,s3493). +registration(r11882,c218,s3494). +registration(r11883,c37,s3494). +registration(r11884,c216,s3494). +registration(r11885,c75,s3495). +registration(r11886,c58,s3495). +registration(r11887,c212,s3495). +registration(r11888,c119,s3495). +registration(r11889,c255,s3496). +registration(r11890,c40,s3496). +registration(r11891,c195,s3496). +registration(r11892,c224,s3497). +registration(r11893,c190,s3497). +registration(r11894,c1,s3497). +registration(r11895,c223,s3498). +registration(r11896,c2,s3498). +registration(r11897,c96,s3498). +registration(r11898,c225,s3498). +registration(r11899,c135,s3498). +registration(r11900,c186,s3499). +registration(r11901,c139,s3499). +registration(r11902,c201,s3499). +registration(r11903,c162,s3500). +registration(r11904,c77,s3500). +registration(r11905,c101,s3500). +registration(r11906,c57,s3501). +registration(r11907,c1,s3501). +registration(r11908,c255,s3501). +registration(r11909,c40,s3501). +registration(r11910,c107,s3502). +registration(r11911,c235,s3502). +registration(r11912,c8,s3502). +registration(r11913,c10,s3503). +registration(r11914,c145,s3503). +registration(r11915,c95,s3503). +registration(r11916,c191,s3504). +registration(r11917,c9,s3504). +registration(r11918,c117,s3504). +registration(r11919,c47,s3505). +registration(r11920,c110,s3505). +registration(r11921,c89,s3505). +registration(r11922,c251,s3505). +registration(r11923,c18,s3506). +registration(r11924,c133,s3506). +registration(r11925,c233,s3506). +registration(r11926,c235,s3507). +registration(r11927,c154,s3507). +registration(r11928,c100,s3507). +registration(r11929,c208,s3508). +registration(r11930,c215,s3508). +registration(r11931,c201,s3508). +registration(r11932,c128,s3508). +registration(r11933,c173,s3509). +registration(r11934,c225,s3509). +registration(r11935,c190,s3509). +registration(r11936,c200,s3510). +registration(r11937,c181,s3510). +registration(r11938,c129,s3510). +registration(r11939,c239,s3511). +registration(r11940,c178,s3511). +registration(r11941,c169,s3511). +registration(r11942,c173,s3511). +registration(r11943,c148,s3512). +registration(r11944,c152,s3512). +registration(r11945,c88,s3512). +registration(r11946,c243,s3513). +registration(r11947,c183,s3513). +registration(r11948,c110,s3513). +registration(r11949,c70,s3514). +registration(r11950,c130,s3514). +registration(r11951,c165,s3514). +registration(r11952,c81,s3515). +registration(r11953,c170,s3515). +registration(r11954,c22,s3515). +registration(r11955,c223,s3516). +registration(r11956,c72,s3516). +registration(r11957,c204,s3516). +registration(r11958,c187,s3516). +registration(r11959,c235,s3517). +registration(r11960,c215,s3517). +registration(r11961,c203,s3517). +registration(r11962,c97,s3518). +registration(r11963,c50,s3518). +registration(r11964,c239,s3518). +registration(r11965,c226,s3519). +registration(r11966,c108,s3519). +registration(r11967,c37,s3519). +registration(r11968,c108,s3520). +registration(r11969,c26,s3520). +registration(r11970,c155,s3520). +registration(r11971,c236,s3521). +registration(r11972,c222,s3521). +registration(r11973,c135,s3521). +registration(r11974,c102,s3521). +registration(r11975,c199,s3522). +registration(r11976,c247,s3522). +registration(r11977,c158,s3522). +registration(r11978,c139,s3523). +registration(r11979,c206,s3523). +registration(r11980,c128,s3523). +registration(r11981,c99,s3523). +registration(r11982,c89,s3524). +registration(r11983,c83,s3524). +registration(r11984,c152,s3524). +registration(r11985,c54,s3524). +registration(r11986,c52,s3524). +registration(r11987,c208,s3525). +registration(r11988,c251,s3525). +registration(r11989,c160,s3525). +registration(r11990,c215,s3526). +registration(r11991,c92,s3526). +registration(r11992,c130,s3526). +registration(r11993,c0,s3527). +registration(r11994,c224,s3527). +registration(r11995,c76,s3527). +registration(r11996,c236,s3528). +registration(r11997,c189,s3528). +registration(r11998,c139,s3528). +registration(r11999,c14,s3529). +registration(r12000,c159,s3529). +registration(r12001,c241,s3529). +registration(r12002,c69,s3530). +registration(r12003,c137,s3530). +registration(r12004,c7,s3530). +registration(r12005,c61,s3531). +registration(r12006,c77,s3531). +registration(r12007,c138,s3531). +registration(r12008,c31,s3532). +registration(r12009,c183,s3532). +registration(r12010,c147,s3532). +registration(r12011,c120,s3533). +registration(r12012,c162,s3533). +registration(r12013,c77,s3533). +registration(r12014,c38,s3534). +registration(r12015,c178,s3534). +registration(r12016,c41,s3534). +registration(r12017,c182,s3534). +registration(r12018,c192,s3535). +registration(r12019,c201,s3535). +registration(r12020,c165,s3535). +registration(r12021,c236,s3536). +registration(r12022,c59,s3536). +registration(r12023,c201,s3536). +registration(r12024,c7,s3537). +registration(r12025,c181,s3537). +registration(r12026,c84,s3537). +registration(r12027,c115,s3538). +registration(r12028,c158,s3538). +registration(r12029,c128,s3538). +registration(r12030,c11,s3538). +registration(r12031,c183,s3539). +registration(r12032,c89,s3539). +registration(r12033,c190,s3539). +registration(r12034,c127,s3539). +registration(r12035,c75,s3540). +registration(r12036,c50,s3540). +registration(r12037,c155,s3540). +registration(r12038,c243,s3540). +registration(r12039,c168,s3541). +registration(r12040,c165,s3541). +registration(r12041,c38,s3541). +registration(r12042,c241,s3542). +registration(r12043,c253,s3542). +registration(r12044,c169,s3542). +registration(r12045,c255,s3543). +registration(r12046,c223,s3543). +registration(r12047,c157,s3543). +registration(r12048,c30,s3544). +registration(r12049,c136,s3544). +registration(r12050,c138,s3544). +registration(r12051,c63,s3544). +registration(r12052,c214,s3545). +registration(r12053,c97,s3545). +registration(r12054,c100,s3545). +registration(r12055,c150,s3546). +registration(r12056,c225,s3546). +registration(r12057,c174,s3546). +registration(r12058,c87,s3547). +registration(r12059,c47,s3547). +registration(r12060,c110,s3547). +registration(r12061,c95,s3547). +registration(r12062,c233,s3548). +registration(r12063,c187,s3548). +registration(r12064,c86,s3548). +registration(r12065,c55,s3549). +registration(r12066,c58,s3549). +registration(r12067,c45,s3549). +registration(r12068,c181,s3550). +registration(r12069,c63,s3550). +registration(r12070,c112,s3550). +registration(r12071,c70,s3550). +registration(r12072,c87,s3551). +registration(r12073,c135,s3551). +registration(r12074,c141,s3551). +registration(r12075,c29,s3551). +registration(r12076,c180,s3552). +registration(r12077,c167,s3552). +registration(r12078,c179,s3552). +registration(r12079,c216,s3552). +registration(r12080,c248,s3552). +registration(r12081,c233,s3553). +registration(r12082,c127,s3553). +registration(r12083,c224,s3553). +registration(r12084,c124,s3554). +registration(r12085,c96,s3554). +registration(r12086,c14,s3554). +registration(r12087,c196,s3555). +registration(r12088,c14,s3555). +registration(r12089,c69,s3555). +registration(r12090,c126,s3555). +registration(r12091,c39,s3556). +registration(r12092,c196,s3556). +registration(r12093,c146,s3556). +registration(r12094,c152,s3557). +registration(r12095,c205,s3557). +registration(r12096,c189,s3557). +registration(r12097,c114,s3558). +registration(r12098,c88,s3558). +registration(r12099,c77,s3558). +registration(r12100,c55,s3559). +registration(r12101,c20,s3559). +registration(r12102,c50,s3559). +registration(r12103,c174,s3560). +registration(r12104,c61,s3560). +registration(r12105,c251,s3560). +registration(r12106,c191,s3561). +registration(r12107,c114,s3561). +registration(r12108,c18,s3561). +registration(r12109,c77,s3562). +registration(r12110,c235,s3562). +registration(r12111,c180,s3562). +registration(r12112,c5,s3563). +registration(r12113,c119,s3563). +registration(r12114,c104,s3563). +registration(r12115,c221,s3564). +registration(r12116,c54,s3564). +registration(r12117,c29,s3564). +registration(r12118,c202,s3564). +registration(r12119,c99,s3565). +registration(r12120,c223,s3565). +registration(r12121,c160,s3565). +registration(r12122,c79,s3566). +registration(r12123,c126,s3566). +registration(r12124,c199,s3566). +registration(r12125,c134,s3567). +registration(r12126,c38,s3567). +registration(r12127,c94,s3567). +registration(r12128,c172,s3567). +registration(r12129,c54,s3568). +registration(r12130,c205,s3568). +registration(r12131,c138,s3568). +registration(r12132,c2,s3569). +registration(r12133,c58,s3569). +registration(r12134,c151,s3569). +registration(r12135,c205,s3569). +registration(r12136,c227,s3570). +registration(r12137,c66,s3570). +registration(r12138,c152,s3570). +registration(r12139,c120,s3571). +registration(r12140,c243,s3571). +registration(r12141,c229,s3571). +registration(r12142,c100,s3572). +registration(r12143,c11,s3572). +registration(r12144,c247,s3572). +registration(r12145,c30,s3573). +registration(r12146,c14,s3573). +registration(r12147,c221,s3573). +registration(r12148,c20,s3574). +registration(r12149,c3,s3574). +registration(r12150,c70,s3574). +registration(r12151,c70,s3575). +registration(r12152,c31,s3575). +registration(r12153,c109,s3575). +registration(r12154,c55,s3575). +registration(r12155,c241,s3576). +registration(r12156,c121,s3576). +registration(r12157,c209,s3576). +registration(r12158,c73,s3576). +registration(r12159,c55,s3577). +registration(r12160,c7,s3577). +registration(r12161,c143,s3577). +registration(r12162,c153,s3578). +registration(r12163,c113,s3578). +registration(r12164,c28,s3578). +registration(r12165,c144,s3578). +registration(r12166,c9,s3578). +registration(r12167,c198,s3579). +registration(r12168,c229,s3579). +registration(r12169,c29,s3579). +registration(r12170,c4,s3579). +registration(r12171,c160,s3580). +registration(r12172,c113,s3580). +registration(r12173,c35,s3580). +registration(r12174,c127,s3580). +registration(r12175,c70,s3581). +registration(r12176,c112,s3581). +registration(r12177,c213,s3581). +registration(r12178,c179,s3581). +registration(r12179,c98,s3582). +registration(r12180,c234,s3582). +registration(r12181,c253,s3582). +registration(r12182,c105,s3583). +registration(r12183,c139,s3583). +registration(r12184,c214,s3583). +registration(r12185,c101,s3584). +registration(r12186,c177,s3584). +registration(r12187,c193,s3584). +registration(r12188,c150,s3584). +registration(r12189,c246,s3585). +registration(r12190,c193,s3585). +registration(r12191,c226,s3585). +registration(r12192,c7,s3586). +registration(r12193,c163,s3586). +registration(r12194,c178,s3586). +registration(r12195,c34,s3587). +registration(r12196,c57,s3587). +registration(r12197,c1,s3587). +registration(r12198,c101,s3587). +registration(r12199,c191,s3588). +registration(r12200,c43,s3588). +registration(r12201,c85,s3588). +registration(r12202,c149,s3588). +registration(r12203,c250,s3589). +registration(r12204,c27,s3589). +registration(r12205,c151,s3589). +registration(r12206,c88,s3590). +registration(r12207,c140,s3590). +registration(r12208,c100,s3590). +registration(r12209,c38,s3591). +registration(r12210,c27,s3591). +registration(r12211,c24,s3591). +registration(r12212,c188,s3591). +registration(r12213,c12,s3592). +registration(r12214,c133,s3592). +registration(r12215,c165,s3592). +registration(r12216,c190,s3592). +registration(r12217,c3,s3593). +registration(r12218,c236,s3593). +registration(r12219,c11,s3593). +registration(r12220,c96,s3593). +registration(r12221,c231,s3594). +registration(r12222,c172,s3594). +registration(r12223,c62,s3594). +registration(r12224,c214,s3595). +registration(r12225,c66,s3595). +registration(r12226,c148,s3595). +registration(r12227,c206,s3595). +registration(r12228,c102,s3596). +registration(r12229,c81,s3596). +registration(r12230,c31,s3596). +registration(r12231,c122,s3597). +registration(r12232,c165,s3597). +registration(r12233,c38,s3597). +registration(r12234,c203,s3597). +registration(r12235,c180,s3598). +registration(r12236,c232,s3598). +registration(r12237,c112,s3598). +registration(r12238,c123,s3599). +registration(r12239,c124,s3599). +registration(r12240,c236,s3599). +registration(r12241,c153,s3600). +registration(r12242,c26,s3600). +registration(r12243,c70,s3600). +registration(r12244,c136,s3601). +registration(r12245,c246,s3601). +registration(r12246,c31,s3601). +registration(r12247,c134,s3602). +registration(r12248,c169,s3602). +registration(r12249,c15,s3602). +registration(r12250,c20,s3602). +registration(r12251,c173,s3603). +registration(r12252,c58,s3603). +registration(r12253,c16,s3603). +registration(r12254,c197,s3603). +registration(r12255,c191,s3604). +registration(r12256,c118,s3604). +registration(r12257,c125,s3604). +registration(r12258,c249,s3605). +registration(r12259,c128,s3605). +registration(r12260,c205,s3605). +registration(r12261,c231,s3605). +registration(r12262,c163,s3606). +registration(r12263,c123,s3606). +registration(r12264,c217,s3606). +registration(r12265,c113,s3606). +registration(r12266,c131,s3607). +registration(r12267,c98,s3607). +registration(r12268,c126,s3607). +registration(r12269,c114,s3607). +registration(r12270,c64,s3608). +registration(r12271,c252,s3608). +registration(r12272,c51,s3608). +registration(r12273,c11,s3608). +registration(r12274,c128,s3609). +registration(r12275,c210,s3609). +registration(r12276,c202,s3609). +registration(r12277,c95,s3610). +registration(r12278,c234,s3610). +registration(r12279,c72,s3610). +registration(r12280,c166,s3611). +registration(r12281,c250,s3611). +registration(r12282,c159,s3611). +registration(r12283,c121,s3612). +registration(r12284,c117,s3612). +registration(r12285,c233,s3612). +registration(r12286,c75,s3613). +registration(r12287,c240,s3613). +registration(r12288,c37,s3613). +registration(r12289,c102,s3614). +registration(r12290,c187,s3614). +registration(r12291,c170,s3614). +registration(r12292,c181,s3615). +registration(r12293,c97,s3615). +registration(r12294,c154,s3615). +registration(r12295,c234,s3616). +registration(r12296,c223,s3616). +registration(r12297,c67,s3616). +registration(r12298,c253,s3617). +registration(r12299,c218,s3617). +registration(r12300,c185,s3617). +registration(r12301,c48,s3617). +registration(r12302,c24,s3618). +registration(r12303,c155,s3618). +registration(r12304,c27,s3618). +registration(r12305,c101,s3619). +registration(r12306,c122,s3619). +registration(r12307,c185,s3619). +registration(r12308,c241,s3619). +registration(r12309,c223,s3619). +registration(r12310,c155,s3620). +registration(r12311,c0,s3620). +registration(r12312,c168,s3620). +registration(r12313,c67,s3621). +registration(r12314,c210,s3621). +registration(r12315,c186,s3621). +registration(r12316,c177,s3621). +registration(r12317,c98,s3622). +registration(r12318,c115,s3622). +registration(r12319,c252,s3622). +registration(r12320,c155,s3622). +registration(r12321,c97,s3623). +registration(r12322,c95,s3623). +registration(r12323,c179,s3623). +registration(r12324,c61,s3624). +registration(r12325,c144,s3624). +registration(r12326,c224,s3624). +registration(r12327,c4,s3625). +registration(r12328,c169,s3625). +registration(r12329,c105,s3625). +registration(r12330,c105,s3626). +registration(r12331,c140,s3626). +registration(r12332,c150,s3626). +registration(r12333,c103,s3627). +registration(r12334,c135,s3627). +registration(r12335,c253,s3627). +registration(r12336,c134,s3627). +registration(r12337,c141,s3628). +registration(r12338,c131,s3628). +registration(r12339,c156,s3628). +registration(r12340,c254,s3628). +registration(r12341,c27,s3629). +registration(r12342,c209,s3629). +registration(r12343,c250,s3629). +registration(r12344,c138,s3629). +registration(r12345,c118,s3630). +registration(r12346,c198,s3630). +registration(r12347,c212,s3630). +registration(r12348,c61,s3631). +registration(r12349,c95,s3631). +registration(r12350,c180,s3631). +registration(r12351,c72,s3632). +registration(r12352,c115,s3632). +registration(r12353,c187,s3632). +registration(r12354,c183,s3633). +registration(r12355,c202,s3633). +registration(r12356,c128,s3633). +registration(r12357,c86,s3633). +registration(r12358,c178,s3633). +registration(r12359,c19,s3634). +registration(r12360,c36,s3634). +registration(r12361,c177,s3634). +registration(r12362,c245,s3634). +registration(r12363,c197,s3635). +registration(r12364,c3,s3635). +registration(r12365,c54,s3635). +registration(r12366,c10,s3636). +registration(r12367,c182,s3636). +registration(r12368,c57,s3636). +registration(r12369,c237,s3636). +registration(r12370,c239,s3637). +registration(r12371,c0,s3637). +registration(r12372,c54,s3637). +registration(r12373,c230,s3638). +registration(r12374,c92,s3638). +registration(r12375,c114,s3638). +registration(r12376,c137,s3639). +registration(r12377,c8,s3639). +registration(r12378,c227,s3639). +registration(r12379,c6,s3639). +registration(r12380,c236,s3640). +registration(r12381,c75,s3640). +registration(r12382,c251,s3640). +registration(r12383,c254,s3640). +registration(r12384,c206,s3641). +registration(r12385,c77,s3641). +registration(r12386,c200,s3641). +registration(r12387,c2,s3641). +registration(r12388,c33,s3642). +registration(r12389,c25,s3642). +registration(r12390,c239,s3642). +registration(r12391,c26,s3642). +registration(r12392,c116,s3642). +registration(r12393,c212,s3643). +registration(r12394,c11,s3643). +registration(r12395,c207,s3643). +registration(r12396,c174,s3644). +registration(r12397,c208,s3644). +registration(r12398,c196,s3644). +registration(r12399,c226,s3644). +registration(r12400,c151,s3645). +registration(r12401,c249,s3645). +registration(r12402,c46,s3645). +registration(r12403,c64,s3646). +registration(r12404,c145,s3646). +registration(r12405,c96,s3646). +registration(r12406,c57,s3647). +registration(r12407,c146,s3647). +registration(r12408,c93,s3647). +registration(r12409,c76,s3648). +registration(r12410,c107,s3648). +registration(r12411,c197,s3648). +registration(r12412,c153,s3649). +registration(r12413,c124,s3649). +registration(r12414,c174,s3649). +registration(r12415,c92,s3650). +registration(r12416,c177,s3650). +registration(r12417,c255,s3650). +registration(r12418,c225,s3651). +registration(r12419,c132,s3651). +registration(r12420,c183,s3651). +registration(r12421,c23,s3651). +registration(r12422,c80,s3652). +registration(r12423,c169,s3652). +registration(r12424,c171,s3652). +registration(r12425,c229,s3652). +registration(r12426,c111,s3653). +registration(r12427,c96,s3653). +registration(r12428,c62,s3653). +registration(r12429,c174,s3653). +registration(r12430,c223,s3654). +registration(r12431,c30,s3654). +registration(r12432,c136,s3654). +registration(r12433,c55,s3655). +registration(r12434,c90,s3655). +registration(r12435,c214,s3655). +registration(r12436,c212,s3655). +registration(r12437,c129,s3656). +registration(r12438,c201,s3656). +registration(r12439,c182,s3656). +registration(r12440,c128,s3656). +registration(r12441,c30,s3657). +registration(r12442,c204,s3657). +registration(r12443,c22,s3657). +registration(r12444,c244,s3658). +registration(r12445,c202,s3658). +registration(r12446,c91,s3658). +registration(r12447,c154,s3658). +registration(r12448,c126,s3659). +registration(r12449,c218,s3659). +registration(r12450,c69,s3659). +registration(r12451,c207,s3660). +registration(r12452,c214,s3660). +registration(r12453,c147,s3660). +registration(r12454,c46,s3660). +registration(r12455,c154,s3661). +registration(r12456,c58,s3661). +registration(r12457,c64,s3661). +registration(r12458,c4,s3661). +registration(r12459,c34,s3662). +registration(r12460,c134,s3662). +registration(r12461,c189,s3662). +registration(r12462,c211,s3663). +registration(r12463,c8,s3663). +registration(r12464,c201,s3663). +registration(r12465,c38,s3664). +registration(r12466,c44,s3664). +registration(r12467,c0,s3664). +registration(r12468,c218,s3665). +registration(r12469,c8,s3665). +registration(r12470,c6,s3665). +registration(r12471,c220,s3666). +registration(r12472,c104,s3666). +registration(r12473,c221,s3666). +registration(r12474,c209,s3666). +registration(r12475,c70,s3667). +registration(r12476,c18,s3667). +registration(r12477,c147,s3667). +registration(r12478,c182,s3667). +registration(r12479,c208,s3668). +registration(r12480,c196,s3668). +registration(r12481,c246,s3668). +registration(r12482,c150,s3668). +registration(r12483,c237,s3669). +registration(r12484,c95,s3669). +registration(r12485,c210,s3669). +registration(r12486,c138,s3669). +registration(r12487,c213,s3670). +registration(r12488,c52,s3670). +registration(r12489,c174,s3670). +registration(r12490,c130,s3671). +registration(r12491,c181,s3671). +registration(r12492,c24,s3671). +registration(r12493,c36,s3672). +registration(r12494,c190,s3672). +registration(r12495,c10,s3672). +registration(r12496,c157,s3673). +registration(r12497,c182,s3673). +registration(r12498,c218,s3673). +registration(r12499,c159,s3674). +registration(r12500,c72,s3674). +registration(r12501,c171,s3674). +registration(r12502,c151,s3675). +registration(r12503,c153,s3675). +registration(r12504,c25,s3675). +registration(r12505,c237,s3675). +registration(r12506,c129,s3676). +registration(r12507,c89,s3676). +registration(r12508,c156,s3676). +registration(r12509,c30,s3677). +registration(r12510,c19,s3677). +registration(r12511,c174,s3677). +registration(r12512,c166,s3677). +registration(r12513,c198,s3678). +registration(r12514,c175,s3678). +registration(r12515,c61,s3678). +registration(r12516,c244,s3679). +registration(r12517,c113,s3679). +registration(r12518,c160,s3679). +registration(r12519,c232,s3679). +registration(r12520,c38,s3680). +registration(r12521,c75,s3680). +registration(r12522,c49,s3680). +registration(r12523,c74,s3681). +registration(r12524,c106,s3681). +registration(r12525,c8,s3681). +registration(r12526,c97,s3682). +registration(r12527,c212,s3682). +registration(r12528,c72,s3682). +registration(r12529,c93,s3683). +registration(r12530,c165,s3683). +registration(r12531,c251,s3683). +registration(r12532,c119,s3683). +registration(r12533,c180,s3684). +registration(r12534,c183,s3684). +registration(r12535,c89,s3684). +registration(r12536,c170,s3684). +registration(r12537,c162,s3685). +registration(r12538,c38,s3685). +registration(r12539,c222,s3685). +registration(r12540,c41,s3686). +registration(r12541,c188,s3686). +registration(r12542,c11,s3686). +registration(r12543,c6,s3686). +registration(r12544,c21,s3687). +registration(r12545,c63,s3687). +registration(r12546,c96,s3687). +registration(r12547,c169,s3687). +registration(r12548,c110,s3688). +registration(r12549,c6,s3688). +registration(r12550,c5,s3688). +registration(r12551,c1,s3688). +registration(r12552,c141,s3688). +registration(r12553,c195,s3689). +registration(r12554,c189,s3689). +registration(r12555,c66,s3689). +registration(r12556,c191,s3689). +registration(r12557,c234,s3690). +registration(r12558,c97,s3690). +registration(r12559,c20,s3690). +registration(r12560,c98,s3691). +registration(r12561,c241,s3691). +registration(r12562,c169,s3691). +registration(r12563,c176,s3692). +registration(r12564,c226,s3692). +registration(r12565,c19,s3692). +registration(r12566,c138,s3693). +registration(r12567,c3,s3693). +registration(r12568,c233,s3693). +registration(r12569,c239,s3693). +registration(r12570,c12,s3694). +registration(r12571,c10,s3694). +registration(r12572,c249,s3694). +registration(r12573,c183,s3695). +registration(r12574,c219,s3695). +registration(r12575,c236,s3695). +registration(r12576,c214,s3696). +registration(r12577,c217,s3696). +registration(r12578,c222,s3696). +registration(r12579,c64,s3697). +registration(r12580,c145,s3697). +registration(r12581,c113,s3697). +registration(r12582,c34,s3698). +registration(r12583,c144,s3698). +registration(r12584,c163,s3698). +registration(r12585,c209,s3698). +registration(r12586,c20,s3698). +registration(r12587,c186,s3699). +registration(r12588,c38,s3699). +registration(r12589,c30,s3699). +registration(r12590,c42,s3699). +registration(r12591,c163,s3700). +registration(r12592,c203,s3700). +registration(r12593,c247,s3700). +registration(r12594,c227,s3701). +registration(r12595,c209,s3701). +registration(r12596,c109,s3701). +registration(r12597,c76,s3702). +registration(r12598,c89,s3702). +registration(r12599,c115,s3702). +registration(r12600,c228,s3703). +registration(r12601,c58,s3703). +registration(r12602,c121,s3703). +registration(r12603,c201,s3703). +registration(r12604,c24,s3703). +registration(r12605,c154,s3704). +registration(r12606,c73,s3704). +registration(r12607,c45,s3704). +registration(r12608,c75,s3705). +registration(r12609,c0,s3705). +registration(r12610,c163,s3705). +registration(r12611,c109,s3706). +registration(r12612,c107,s3706). +registration(r12613,c254,s3706). +registration(r12614,c79,s3706). +registration(r12615,c130,s3707). +registration(r12616,c10,s3707). +registration(r12617,c124,s3707). +registration(r12618,c239,s3708). +registration(r12619,c91,s3708). +registration(r12620,c77,s3708). +registration(r12621,c198,s3709). +registration(r12622,c218,s3709). +registration(r12623,c95,s3709). +registration(r12624,c251,s3710). +registration(r12625,c44,s3710). +registration(r12626,c32,s3710). +registration(r12627,c108,s3711). +registration(r12628,c80,s3711). +registration(r12629,c62,s3711). +registration(r12630,c172,s3712). +registration(r12631,c77,s3712). +registration(r12632,c243,s3712). +registration(r12633,c196,s3713). +registration(r12634,c66,s3713). +registration(r12635,c167,s3713). +registration(r12636,c12,s3713). +registration(r12637,c48,s3714). +registration(r12638,c109,s3714). +registration(r12639,c90,s3714). +registration(r12640,c2,s3714). +registration(r12641,c222,s3714). +registration(r12642,c98,s3715). +registration(r12643,c4,s3715). +registration(r12644,c209,s3715). +registration(r12645,c241,s3715). +registration(r12646,c174,s3716). +registration(r12647,c205,s3716). +registration(r12648,c92,s3716). +registration(r12649,c62,s3716). +registration(r12650,c244,s3717). +registration(r12651,c183,s3717). +registration(r12652,c139,s3717). +registration(r12653,c41,s3718). +registration(r12654,c173,s3718). +registration(r12655,c187,s3718). +registration(r12656,c204,s3719). +registration(r12657,c222,s3719). +registration(r12658,c30,s3719). +registration(r12659,c34,s3720). +registration(r12660,c60,s3720). +registration(r12661,c91,s3720). +registration(r12662,c160,s3720). +registration(r12663,c210,s3721). +registration(r12664,c252,s3721). +registration(r12665,c141,s3721). +registration(r12666,c91,s3722). +registration(r12667,c33,s3722). +registration(r12668,c171,s3722). +registration(r12669,c159,s3723). +registration(r12670,c31,s3723). +registration(r12671,c236,s3723). +registration(r12672,c22,s3724). +registration(r12673,c52,s3724). +registration(r12674,c85,s3724). +registration(r12675,c32,s3724). +registration(r12676,c199,s3725). +registration(r12677,c64,s3725). +registration(r12678,c89,s3725). +registration(r12679,c149,s3726). +registration(r12680,c89,s3726). +registration(r12681,c100,s3726). +registration(r12682,c54,s3727). +registration(r12683,c48,s3727). +registration(r12684,c70,s3727). +registration(r12685,c160,s3728). +registration(r12686,c27,s3728). +registration(r12687,c135,s3728). +registration(r12688,c122,s3728). +registration(r12689,c39,s3728). +registration(r12690,c103,s3729). +registration(r12691,c174,s3729). +registration(r12692,c192,s3729). +registration(r12693,c19,s3730). +registration(r12694,c103,s3730). +registration(r12695,c4,s3730). +registration(r12696,c70,s3730). +registration(r12697,c141,s3731). +registration(r12698,c45,s3731). +registration(r12699,c168,s3731). +registration(r12700,c134,s3731). +registration(r12701,c86,s3731). +registration(r12702,c61,s3732). +registration(r12703,c67,s3732). +registration(r12704,c136,s3732). +registration(r12705,c100,s3733). +registration(r12706,c35,s3733). +registration(r12707,c87,s3733). +registration(r12708,c211,s3733). +registration(r12709,c18,s3734). +registration(r12710,c83,s3734). +registration(r12711,c59,s3734). +registration(r12712,c185,s3734). +registration(r12713,c163,s3735). +registration(r12714,c38,s3735). +registration(r12715,c30,s3735). +registration(r12716,c76,s3736). +registration(r12717,c236,s3736). +registration(r12718,c230,s3736). +registration(r12719,c9,s3737). +registration(r12720,c0,s3737). +registration(r12721,c161,s3737). +registration(r12722,c226,s3738). +registration(r12723,c232,s3738). +registration(r12724,c191,s3738). +registration(r12725,c75,s3738). +registration(r12726,c118,s3739). +registration(r12727,c56,s3739). +registration(r12728,c16,s3739). +registration(r12729,c99,s3740). +registration(r12730,c132,s3740). +registration(r12731,c12,s3740). +registration(r12732,c175,s3741). +registration(r12733,c155,s3741). +registration(r12734,c90,s3741). +registration(r12735,c167,s3742). +registration(r12736,c66,s3742). +registration(r12737,c221,s3742). +registration(r12738,c214,s3742). +registration(r12739,c32,s3743). +registration(r12740,c119,s3743). +registration(r12741,c71,s3743). +registration(r12742,c47,s3744). +registration(r12743,c31,s3744). +registration(r12744,c122,s3744). +registration(r12745,c240,s3744). +registration(r12746,c181,s3745). +registration(r12747,c20,s3745). +registration(r12748,c58,s3745). +registration(r12749,c120,s3745). +registration(r12750,c12,s3746). +registration(r12751,c237,s3746). +registration(r12752,c250,s3746). +registration(r12753,c85,s3747). +registration(r12754,c18,s3747). +registration(r12755,c128,s3747). +registration(r12756,c92,s3748). +registration(r12757,c29,s3748). +registration(r12758,c44,s3748). +registration(r12759,c163,s3749). +registration(r12760,c137,s3749). +registration(r12761,c157,s3749). +registration(r12762,c189,s3750). +registration(r12763,c118,s3750). +registration(r12764,c53,s3750). +registration(r12765,c234,s3751). +registration(r12766,c213,s3751). +registration(r12767,c158,s3751). +registration(r12768,c93,s3752). +registration(r12769,c248,s3752). +registration(r12770,c59,s3752). +registration(r12771,c197,s3753). +registration(r12772,c171,s3753). +registration(r12773,c199,s3753). +registration(r12774,c27,s3754). +registration(r12775,c161,s3754). +registration(r12776,c199,s3754). +registration(r12777,c5,s3755). +registration(r12778,c235,s3755). +registration(r12779,c109,s3755). +registration(r12780,c38,s3756). +registration(r12781,c96,s3756). +registration(r12782,c95,s3756). +registration(r12783,c198,s3756). +registration(r12784,c71,s3757). +registration(r12785,c248,s3757). +registration(r12786,c101,s3757). +registration(r12787,c69,s3757). +registration(r12788,c42,s3758). +registration(r12789,c130,s3758). +registration(r12790,c25,s3758). +registration(r12791,c198,s3759). +registration(r12792,c164,s3759). +registration(r12793,c138,s3759). +registration(r12794,c44,s3760). +registration(r12795,c55,s3760). +registration(r12796,c9,s3760). +registration(r12797,c62,s3760). +registration(r12798,c125,s3761). +registration(r12799,c223,s3761). +registration(r12800,c221,s3761). +registration(r12801,c61,s3762). +registration(r12802,c1,s3762). +registration(r12803,c97,s3762). +registration(r12804,c73,s3762). +registration(r12805,c104,s3763). +registration(r12806,c123,s3763). +registration(r12807,c159,s3763). +registration(r12808,c167,s3763). +registration(r12809,c68,s3763). +registration(r12810,c133,s3764). +registration(r12811,c103,s3764). +registration(r12812,c11,s3764). +registration(r12813,c244,s3764). +registration(r12814,c235,s3765). +registration(r12815,c32,s3765). +registration(r12816,c178,s3765). +registration(r12817,c239,s3765). +registration(r12818,c234,s3766). +registration(r12819,c174,s3766). +registration(r12820,c205,s3766). +registration(r12821,c13,s3767). +registration(r12822,c4,s3767). +registration(r12823,c86,s3767). +registration(r12824,c159,s3767). +registration(r12825,c198,s3768). +registration(r12826,c111,s3768). +registration(r12827,c25,s3768). +registration(r12828,c192,s3769). +registration(r12829,c133,s3769). +registration(r12830,c224,s3769). +registration(r12831,c236,s3770). +registration(r12832,c111,s3770). +registration(r12833,c225,s3770). +registration(r12834,c3,s3771). +registration(r12835,c27,s3771). +registration(r12836,c82,s3771). +registration(r12837,c60,s3771). +registration(r12838,c228,s3772). +registration(r12839,c215,s3772). +registration(r12840,c2,s3772). +registration(r12841,c7,s3773). +registration(r12842,c142,s3773). +registration(r12843,c83,s3773). +registration(r12844,c45,s3773). +registration(r12845,c128,s3773). +registration(r12846,c70,s3774). +registration(r12847,c126,s3774). +registration(r12848,c26,s3774). +registration(r12849,c4,s3774). +registration(r12850,c75,s3775). +registration(r12851,c242,s3775). +registration(r12852,c230,s3775). +registration(r12853,c79,s3776). +registration(r12854,c22,s3776). +registration(r12855,c217,s3776). +registration(r12856,c13,s3777). +registration(r12857,c116,s3777). +registration(r12858,c163,s3777). +registration(r12859,c165,s3778). +registration(r12860,c43,s3778). +registration(r12861,c50,s3778). +registration(r12862,c133,s3779). +registration(r12863,c188,s3779). +registration(r12864,c230,s3779). +registration(r12865,c45,s3780). +registration(r12866,c28,s3780). +registration(r12867,c87,s3780). +registration(r12868,c81,s3780). +registration(r12869,c127,s3781). +registration(r12870,c19,s3781). +registration(r12871,c56,s3781). +registration(r12872,c134,s3782). +registration(r12873,c81,s3782). +registration(r12874,c193,s3782). +registration(r12875,c206,s3783). +registration(r12876,c100,s3783). +registration(r12877,c91,s3783). +registration(r12878,c1,s3784). +registration(r12879,c236,s3784). +registration(r12880,c227,s3784). +registration(r12881,c104,s3785). +registration(r12882,c106,s3785). +registration(r12883,c141,s3785). +registration(r12884,c166,s3785). +registration(r12885,c35,s3786). +registration(r12886,c251,s3786). +registration(r12887,c237,s3786). +registration(r12888,c109,s3787). +registration(r12889,c87,s3787). +registration(r12890,c132,s3787). +registration(r12891,c10,s3788). +registration(r12892,c251,s3788). +registration(r12893,c0,s3788). +registration(r12894,c207,s3789). +registration(r12895,c95,s3789). +registration(r12896,c16,s3789). +registration(r12897,c19,s3789). +registration(r12898,c125,s3790). +registration(r12899,c245,s3790). +registration(r12900,c191,s3790). +registration(r12901,c93,s3790). +registration(r12902,c175,s3790). +registration(r12903,c102,s3791). +registration(r12904,c208,s3791). +registration(r12905,c106,s3791). +registration(r12906,c88,s3792). +registration(r12907,c206,s3792). +registration(r12908,c23,s3792). +registration(r12909,c155,s3792). +registration(r12910,c110,s3793). +registration(r12911,c101,s3793). +registration(r12912,c166,s3793). +registration(r12913,c160,s3794). +registration(r12914,c30,s3794). +registration(r12915,c55,s3794). +registration(r12916,c48,s3794). +registration(r12917,c18,s3795). +registration(r12918,c66,s3795). +registration(r12919,c69,s3795). +registration(r12920,c2,s3795). +registration(r12921,c102,s3796). +registration(r12922,c44,s3796). +registration(r12923,c23,s3796). +registration(r12924,c130,s3797). +registration(r12925,c86,s3797). +registration(r12926,c201,s3797). +registration(r12927,c224,s3797). +registration(r12928,c160,s3798). +registration(r12929,c75,s3798). +registration(r12930,c123,s3798). +registration(r12931,c179,s3798). +registration(r12932,c120,s3798). +registration(r12933,c25,s3799). +registration(r12934,c193,s3799). +registration(r12935,c151,s3799). +registration(r12936,c199,s3800). +registration(r12937,c23,s3800). +registration(r12938,c213,s3800). +registration(r12939,c91,s3800). +registration(r12940,c11,s3801). +registration(r12941,c195,s3801). +registration(r12942,c68,s3801). +registration(r12943,c17,s3802). +registration(r12944,c54,s3802). +registration(r12945,c93,s3802). +registration(r12946,c54,s3803). +registration(r12947,c142,s3803). +registration(r12948,c223,s3803). +registration(r12949,c90,s3804). +registration(r12950,c230,s3804). +registration(r12951,c140,s3804). +registration(r12952,c166,s3805). +registration(r12953,c61,s3805). +registration(r12954,c247,s3805). +registration(r12955,c190,s3806). +registration(r12956,c13,s3806). +registration(r12957,c212,s3806). +registration(r12958,c177,s3807). +registration(r12959,c211,s3807). +registration(r12960,c43,s3807). +registration(r12961,c6,s3807). +registration(r12962,c6,s3808). +registration(r12963,c66,s3808). +registration(r12964,c100,s3808). +registration(r12965,c153,s3809). +registration(r12966,c252,s3809). +registration(r12967,c30,s3809). +registration(r12968,c121,s3810). +registration(r12969,c87,s3810). +registration(r12970,c100,s3810). +registration(r12971,c10,s3811). +registration(r12972,c51,s3811). +registration(r12973,c174,s3811). +registration(r12974,c52,s3811). +registration(r12975,c15,s3812). +registration(r12976,c7,s3812). +registration(r12977,c54,s3812). +registration(r12978,c8,s3813). +registration(r12979,c164,s3813). +registration(r12980,c174,s3813). +registration(r12981,c170,s3813). +registration(r12982,c85,s3814). +registration(r12983,c13,s3814). +registration(r12984,c36,s3814). +registration(r12985,c32,s3815). +registration(r12986,c180,s3815). +registration(r12987,c24,s3815). +registration(r12988,c112,s3815). +registration(r12989,c91,s3816). +registration(r12990,c34,s3816). +registration(r12991,c39,s3816). +registration(r12992,c213,s3817). +registration(r12993,c103,s3817). +registration(r12994,c136,s3817). +registration(r12995,c144,s3818). +registration(r12996,c118,s3818). +registration(r12997,c238,s3818). +registration(r12998,c146,s3819). +registration(r12999,c247,s3819). +registration(r13000,c147,s3819). +registration(r13001,c233,s3820). +registration(r13002,c74,s3820). +registration(r13003,c207,s3820). +registration(r13004,c240,s3821). +registration(r13005,c50,s3821). +registration(r13006,c11,s3821). +registration(r13007,c123,s3822). +registration(r13008,c67,s3822). +registration(r13009,c132,s3822). +registration(r13010,c217,s3823). +registration(r13011,c119,s3823). +registration(r13012,c16,s3823). +registration(r13013,c135,s3824). +registration(r13014,c242,s3824). +registration(r13015,c48,s3824). +registration(r13016,c176,s3825). +registration(r13017,c8,s3825). +registration(r13018,c51,s3825). +registration(r13019,c223,s3826). +registration(r13020,c44,s3826). +registration(r13021,c145,s3826). +registration(r13022,c132,s3827). +registration(r13023,c159,s3827). +registration(r13024,c222,s3827). +registration(r13025,c62,s3828). +registration(r13026,c12,s3828). +registration(r13027,c202,s3828). +registration(r13028,c115,s3829). +registration(r13029,c155,s3829). +registration(r13030,c38,s3829). +registration(r13031,c225,s3830). +registration(r13032,c12,s3830). +registration(r13033,c239,s3830). +registration(r13034,c129,s3830). +registration(r13035,c194,s3830). +registration(r13036,c139,s3831). +registration(r13037,c93,s3831). +registration(r13038,c7,s3831). +registration(r13039,c52,s3832). +registration(r13040,c100,s3832). +registration(r13041,c235,s3832). +registration(r13042,c138,s3833). +registration(r13043,c190,s3833). +registration(r13044,c119,s3833). +registration(r13045,c252,s3833). +registration(r13046,c219,s3834). +registration(r13047,c188,s3834). +registration(r13048,c51,s3834). +registration(r13049,c91,s3835). +registration(r13050,c212,s3835). +registration(r13051,c84,s3835). +registration(r13052,c68,s3836). +registration(r13053,c80,s3836). +registration(r13054,c99,s3836). +registration(r13055,c238,s3836). +registration(r13056,c204,s3837). +registration(r13057,c26,s3837). +registration(r13058,c191,s3837). +registration(r13059,c78,s3837). +registration(r13060,c245,s3837). +registration(r13061,c46,s3838). +registration(r13062,c11,s3838). +registration(r13063,c128,s3838). +registration(r13064,c144,s3839). +registration(r13065,c232,s3839). +registration(r13066,c9,s3839). +registration(r13067,c61,s3840). +registration(r13068,c188,s3840). +registration(r13069,c253,s3840). +registration(r13070,c82,s3841). +registration(r13071,c213,s3841). +registration(r13072,c112,s3841). +registration(r13073,c210,s3841). +registration(r13074,c6,s3842). +registration(r13075,c56,s3842). +registration(r13076,c193,s3842). +registration(r13077,c129,s3843). +registration(r13078,c221,s3843). +registration(r13079,c160,s3843). +registration(r13080,c207,s3844). +registration(r13081,c175,s3844). +registration(r13082,c81,s3844). +registration(r13083,c226,s3845). +registration(r13084,c163,s3845). +registration(r13085,c61,s3845). +registration(r13086,c123,s3846). +registration(r13087,c11,s3846). +registration(r13088,c72,s3846). +registration(r13089,c157,s3846). +registration(r13090,c232,s3847). +registration(r13091,c12,s3847). +registration(r13092,c51,s3847). +registration(r13093,c223,s3847). +registration(r13094,c69,s3848). +registration(r13095,c161,s3848). +registration(r13096,c12,s3848). +registration(r13097,c234,s3848). +registration(r13098,c57,s3849). +registration(r13099,c199,s3849). +registration(r13100,c188,s3849). +registration(r13101,c119,s3849). +registration(r13102,c196,s3849). +registration(r13103,c172,s3850). +registration(r13104,c241,s3850). +registration(r13105,c104,s3850). +registration(r13106,c179,s3851). +registration(r13107,c100,s3851). +registration(r13108,c76,s3851). +registration(r13109,c232,s3852). +registration(r13110,c150,s3852). +registration(r13111,c97,s3852). +registration(r13112,c111,s3853). +registration(r13113,c213,s3853). +registration(r13114,c3,s3853). +registration(r13115,c16,s3854). +registration(r13116,c77,s3854). +registration(r13117,c154,s3854). +registration(r13118,c97,s3855). +registration(r13119,c183,s3855). +registration(r13120,c143,s3855). +registration(r13121,c84,s3856). +registration(r13122,c133,s3856). +registration(r13123,c184,s3856). +registration(r13124,c249,s3857). +registration(r13125,c113,s3857). +registration(r13126,c211,s3857). +registration(r13127,c77,s3858). +registration(r13128,c46,s3858). +registration(r13129,c5,s3858). +registration(r13130,c207,s3858). +registration(r13131,c30,s3859). +registration(r13132,c249,s3859). +registration(r13133,c209,s3859). +registration(r13134,c227,s3860). +registration(r13135,c33,s3860). +registration(r13136,c10,s3860). +registration(r13137,c107,s3861). +registration(r13138,c149,s3861). +registration(r13139,c54,s3861). +registration(r13140,c139,s3862). +registration(r13141,c201,s3862). +registration(r13142,c19,s3862). +registration(r13143,c12,s3863). +registration(r13144,c186,s3863). +registration(r13145,c13,s3863). +registration(r13146,c91,s3863). +registration(r13147,c129,s3864). +registration(r13148,c45,s3864). +registration(r13149,c9,s3864). +registration(r13150,c40,s3865). +registration(r13151,c159,s3865). +registration(r13152,c207,s3865). +registration(r13153,c178,s3865). +registration(r13154,c30,s3866). +registration(r13155,c25,s3866). +registration(r13156,c145,s3866). +registration(r13157,c37,s3867). +registration(r13158,c252,s3867). +registration(r13159,c200,s3867). +registration(r13160,c145,s3868). +registration(r13161,c149,s3868). +registration(r13162,c208,s3868). +registration(r13163,c139,s3869). +registration(r13164,c214,s3869). +registration(r13165,c244,s3869). +registration(r13166,c116,s3869). +registration(r13167,c224,s3870). +registration(r13168,c57,s3870). +registration(r13169,c27,s3870). +registration(r13170,c186,s3871). +registration(r13171,c172,s3871). +registration(r13172,c94,s3871). +registration(r13173,c125,s3872). +registration(r13174,c227,s3872). +registration(r13175,c239,s3872). +registration(r13176,c20,s3873). +registration(r13177,c64,s3873). +registration(r13178,c49,s3873). +registration(r13179,c194,s3874). +registration(r13180,c43,s3874). +registration(r13181,c151,s3874). +registration(r13182,c35,s3875). +registration(r13183,c99,s3875). +registration(r13184,c194,s3875). +registration(r13185,c55,s3876). +registration(r13186,c183,s3876). +registration(r13187,c205,s3876). +registration(r13188,c47,s3877). +registration(r13189,c13,s3877). +registration(r13190,c67,s3877). +registration(r13191,c160,s3878). +registration(r13192,c12,s3878). +registration(r13193,c187,s3878). +registration(r13194,c35,s3879). +registration(r13195,c165,s3879). +registration(r13196,c143,s3879). +registration(r13197,c87,s3880). +registration(r13198,c22,s3880). +registration(r13199,c104,s3880). +registration(r13200,c52,s3881). +registration(r13201,c18,s3881). +registration(r13202,c5,s3881). +registration(r13203,c153,s3882). +registration(r13204,c46,s3882). +registration(r13205,c161,s3882). +registration(r13206,c54,s3883). +registration(r13207,c150,s3883). +registration(r13208,c143,s3883). +registration(r13209,c102,s3883). +registration(r13210,c25,s3884). +registration(r13211,c51,s3884). +registration(r13212,c34,s3884). +registration(r13213,c68,s3885). +registration(r13214,c79,s3885). +registration(r13215,c18,s3885). +registration(r13216,c106,s3886). +registration(r13217,c176,s3886). +registration(r13218,c240,s3886). +registration(r13219,c37,s3887). +registration(r13220,c108,s3887). +registration(r13221,c89,s3887). +registration(r13222,c85,s3887). +registration(r13223,c73,s3888). +registration(r13224,c246,s3888). +registration(r13225,c88,s3888). +registration(r13226,c237,s3888). +registration(r13227,c90,s3889). +registration(r13228,c165,s3889). +registration(r13229,c20,s3889). +registration(r13230,c70,s3890). +registration(r13231,c226,s3890). +registration(r13232,c104,s3890). +registration(r13233,c182,s3890). +registration(r13234,c219,s3891). +registration(r13235,c191,s3891). +registration(r13236,c63,s3891). +registration(r13237,c49,s3892). +registration(r13238,c159,s3892). +registration(r13239,c196,s3892). +registration(r13240,c28,s3892). +registration(r13241,c113,s3893). +registration(r13242,c97,s3893). +registration(r13243,c15,s3893). +registration(r13244,c103,s3894). +registration(r13245,c134,s3894). +registration(r13246,c133,s3894). +registration(r13247,c43,s3895). +registration(r13248,c107,s3895). +registration(r13249,c162,s3895). +registration(r13250,c131,s3896). +registration(r13251,c81,s3896). +registration(r13252,c122,s3896). +registration(r13253,c86,s3896). +registration(r13254,c107,s3897). +registration(r13255,c72,s3897). +registration(r13256,c156,s3897). +registration(r13257,c59,s3898). +registration(r13258,c159,s3898). +registration(r13259,c208,s3898). +registration(r13260,c65,s3899). +registration(r13261,c169,s3899). +registration(r13262,c204,s3899). +registration(r13263,c51,s3899). +registration(r13264,c131,s3900). +registration(r13265,c135,s3900). +registration(r13266,c139,s3900). +registration(r13267,c245,s3901). +registration(r13268,c5,s3901). +registration(r13269,c155,s3901). +registration(r13270,c237,s3902). +registration(r13271,c33,s3902). +registration(r13272,c53,s3902). +registration(r13273,c159,s3903). +registration(r13274,c62,s3903). +registration(r13275,c20,s3903). +registration(r13276,c79,s3904). +registration(r13277,c26,s3904). +registration(r13278,c137,s3904). +registration(r13279,c202,s3905). +registration(r13280,c63,s3905). +registration(r13281,c163,s3905). +registration(r13282,c215,s3906). +registration(r13283,c74,s3906). +registration(r13284,c199,s3906). +registration(r13285,c121,s3907). +registration(r13286,c86,s3907). +registration(r13287,c180,s3907). +registration(r13288,c253,s3907). +registration(r13289,c2,s3908). +registration(r13290,c32,s3908). +registration(r13291,c114,s3908). +registration(r13292,c17,s3909). +registration(r13293,c55,s3909). +registration(r13294,c172,s3909). +registration(r13295,c252,s3910). +registration(r13296,c167,s3910). +registration(r13297,c120,s3910). +registration(r13298,c67,s3911). +registration(r13299,c211,s3911). +registration(r13300,c34,s3911). +registration(r13301,c20,s3911). +registration(r13302,c86,s3912). +registration(r13303,c220,s3912). +registration(r13304,c91,s3912). +registration(r13305,c85,s3912). +registration(r13306,c184,s3913). +registration(r13307,c106,s3913). +registration(r13308,c175,s3913). +registration(r13309,c207,s3914). +registration(r13310,c103,s3914). +registration(r13311,c101,s3914). +registration(r13312,c157,s3915). +registration(r13313,c19,s3915). +registration(r13314,c6,s3915). +registration(r13315,c175,s3915). +registration(r13316,c6,s3916). +registration(r13317,c163,s3916). +registration(r13318,c46,s3916). +registration(r13319,c80,s3917). +registration(r13320,c85,s3917). +registration(r13321,c140,s3917). +registration(r13322,c103,s3918). +registration(r13323,c166,s3918). +registration(r13324,c176,s3918). +registration(r13325,c105,s3919). +registration(r13326,c40,s3919). +registration(r13327,c8,s3919). +registration(r13328,c216,s3920). +registration(r13329,c198,s3920). +registration(r13330,c252,s3920). +registration(r13331,c153,s3921). +registration(r13332,c84,s3921). +registration(r13333,c71,s3921). +registration(r13334,c101,s3921). +registration(r13335,c44,s3922). +registration(r13336,c7,s3922). +registration(r13337,c37,s3922). +registration(r13338,c117,s3923). +registration(r13339,c204,s3923). +registration(r13340,c10,s3923). +registration(r13341,c113,s3924). +registration(r13342,c101,s3924). +registration(r13343,c39,s3924). +registration(r13344,c190,s3924). +registration(r13345,c88,s3925). +registration(r13346,c198,s3925). +registration(r13347,c240,s3925). +registration(r13348,c184,s3926). +registration(r13349,c236,s3926). +registration(r13350,c222,s3926). +registration(r13351,c52,s3927). +registration(r13352,c66,s3927). +registration(r13353,c173,s3927). +registration(r13354,c217,s3928). +registration(r13355,c159,s3928). +registration(r13356,c92,s3928). +registration(r13357,c210,s3928). +registration(r13358,c28,s3929). +registration(r13359,c42,s3929). +registration(r13360,c147,s3929). +registration(r13361,c248,s3930). +registration(r13362,c186,s3930). +registration(r13363,c202,s3930). +registration(r13364,c36,s3931). +registration(r13365,c125,s3931). +registration(r13366,c61,s3931). +registration(r13367,c28,s3931). +registration(r13368,c255,s3932). +registration(r13369,c251,s3932). +registration(r13370,c236,s3932). +registration(r13371,c47,s3932). +registration(r13372,c49,s3933). +registration(r13373,c200,s3933). +registration(r13374,c104,s3933). +registration(r13375,c106,s3933). +registration(r13376,c91,s3934). +registration(r13377,c137,s3934). +registration(r13378,c152,s3934). +registration(r13379,c42,s3935). +registration(r13380,c11,s3935). +registration(r13381,c78,s3935). +registration(r13382,c199,s3935). +registration(r13383,c217,s3935). +registration(r13384,c19,s3936). +registration(r13385,c61,s3936). +registration(r13386,c87,s3936). +registration(r13387,c114,s3937). +registration(r13388,c69,s3937). +registration(r13389,c80,s3937). +registration(r13390,c213,s3938). +registration(r13391,c158,s3938). +registration(r13392,c99,s3938). +registration(r13393,c103,s3938). +registration(r13394,c18,s3939). +registration(r13395,c209,s3939). +registration(r13396,c145,s3939). +registration(r13397,c40,s3940). +registration(r13398,c230,s3940). +registration(r13399,c12,s3940). +registration(r13400,c89,s3941). +registration(r13401,c117,s3941). +registration(r13402,c185,s3941). +registration(r13403,c204,s3942). +registration(r13404,c174,s3942). +registration(r13405,c163,s3942). +registration(r13406,c0,s3942). +registration(r13407,c99,s3942). +registration(r13408,c80,s3943). +registration(r13409,c135,s3943). +registration(r13410,c152,s3943). +registration(r13411,c37,s3943). +registration(r13412,c45,s3944). +registration(r13413,c142,s3944). +registration(r13414,c200,s3944). +registration(r13415,c89,s3945). +registration(r13416,c175,s3945). +registration(r13417,c186,s3945). +registration(r13418,c197,s3946). +registration(r13419,c213,s3946). +registration(r13420,c133,s3946). +registration(r13421,c73,s3946). +registration(r13422,c146,s3947). +registration(r13423,c153,s3947). +registration(r13424,c12,s3947). +registration(r13425,c42,s3948). +registration(r13426,c66,s3948). +registration(r13427,c86,s3948). +registration(r13428,c220,s3949). +registration(r13429,c37,s3949). +registration(r13430,c184,s3949). +registration(r13431,c33,s3949). +registration(r13432,c144,s3950). +registration(r13433,c234,s3950). +registration(r13434,c39,s3950). +registration(r13435,c214,s3951). +registration(r13436,c169,s3951). +registration(r13437,c198,s3951). +registration(r13438,c156,s3952). +registration(r13439,c241,s3952). +registration(r13440,c141,s3952). +registration(r13441,c32,s3952). +registration(r13442,c128,s3953). +registration(r13443,c62,s3953). +registration(r13444,c99,s3953). +registration(r13445,c164,s3954). +registration(r13446,c20,s3954). +registration(r13447,c246,s3954). +registration(r13448,c28,s3955). +registration(r13449,c240,s3955). +registration(r13450,c243,s3955). +registration(r13451,c131,s3956). +registration(r13452,c41,s3956). +registration(r13453,c254,s3956). +registration(r13454,c212,s3957). +registration(r13455,c29,s3957). +registration(r13456,c54,s3957). +registration(r13457,c210,s3958). +registration(r13458,c49,s3958). +registration(r13459,c27,s3958). +registration(r13460,c61,s3959). +registration(r13461,c58,s3959). +registration(r13462,c162,s3959). +registration(r13463,c10,s3960). +registration(r13464,c69,s3960). +registration(r13465,c14,s3960). +registration(r13466,c126,s3960). +registration(r13467,c29,s3961). +registration(r13468,c109,s3961). +registration(r13469,c241,s3961). +registration(r13470,c117,s3962). +registration(r13471,c134,s3962). +registration(r13472,c66,s3962). +registration(r13473,c23,s3963). +registration(r13474,c6,s3963). +registration(r13475,c44,s3963). +registration(r13476,c252,s3964). +registration(r13477,c136,s3964). +registration(r13478,c175,s3964). +registration(r13479,c236,s3965). +registration(r13480,c241,s3965). +registration(r13481,c141,s3965). +registration(r13482,c153,s3966). +registration(r13483,c210,s3966). +registration(r13484,c249,s3966). +registration(r13485,c248,s3967). +registration(r13486,c184,s3967). +registration(r13487,c187,s3967). +registration(r13488,c255,s3967). +registration(r13489,c94,s3968). +registration(r13490,c156,s3968). +registration(r13491,c66,s3968). +registration(r13492,c90,s3969). +registration(r13493,c77,s3969). +registration(r13494,c188,s3969). +registration(r13495,c184,s3970). +registration(r13496,c59,s3970). +registration(r13497,c144,s3970). +registration(r13498,c124,s3970). +registration(r13499,c97,s3971). +registration(r13500,c183,s3971). +registration(r13501,c10,s3971). +registration(r13502,c220,s3972). +registration(r13503,c70,s3972). +registration(r13504,c236,s3972). +registration(r13505,c61,s3972). +registration(r13506,c230,s3973). +registration(r13507,c39,s3973). +registration(r13508,c185,s3973). +registration(r13509,c86,s3974). +registration(r13510,c40,s3974). +registration(r13511,c206,s3974). +registration(r13512,c27,s3975). +registration(r13513,c163,s3975). +registration(r13514,c53,s3975). +registration(r13515,c112,s3976). +registration(r13516,c141,s3976). +registration(r13517,c203,s3976). +registration(r13518,c43,s3976). +registration(r13519,c81,s3977). +registration(r13520,c21,s3977). +registration(r13521,c122,s3977). +registration(r13522,c191,s3978). +registration(r13523,c141,s3978). +registration(r13524,c27,s3978). +registration(r13525,c2,s3978). +registration(r13526,c37,s3979). +registration(r13527,c237,s3979). +registration(r13528,c231,s3979). +registration(r13529,c16,s3980). +registration(r13530,c122,s3980). +registration(r13531,c44,s3980). +registration(r13532,c206,s3981). +registration(r13533,c200,s3981). +registration(r13534,c145,s3981). +registration(r13535,c57,s3981). +registration(r13536,c245,s3981). +registration(r13537,c212,s3982). +registration(r13538,c42,s3982). +registration(r13539,c33,s3982). +registration(r13540,c65,s3982). +registration(r13541,c199,s3983). +registration(r13542,c49,s3983). +registration(r13543,c90,s3983). +registration(r13544,c88,s3984). +registration(r13545,c136,s3984). +registration(r13546,c78,s3984). +registration(r13547,c55,s3985). +registration(r13548,c42,s3985). +registration(r13549,c186,s3985). +registration(r13550,c229,s3986). +registration(r13551,c219,s3986). +registration(r13552,c58,s3986). +registration(r13553,c206,s3987). +registration(r13554,c222,s3987). +registration(r13555,c225,s3987). +registration(r13556,c181,s3988). +registration(r13557,c25,s3988). +registration(r13558,c245,s3988). +registration(r13559,c144,s3989). +registration(r13560,c162,s3989). +registration(r13561,c137,s3989). +registration(r13562,c216,s3990). +registration(r13563,c67,s3990). +registration(r13564,c127,s3990). +registration(r13565,c193,s3990). +registration(r13566,c95,s3991). +registration(r13567,c237,s3991). +registration(r13568,c174,s3991). +registration(r13569,c147,s3992). +registration(r13570,c132,s3992). +registration(r13571,c206,s3992). +registration(r13572,c156,s3992). +registration(r13573,c37,s3993). +registration(r13574,c12,s3993). +registration(r13575,c139,s3993). +registration(r13576,c163,s3994). +registration(r13577,c238,s3994). +registration(r13578,c154,s3994). +registration(r13579,c61,s3995). +registration(r13580,c136,s3995). +registration(r13581,c106,s3995). +registration(r13582,c173,s3996). +registration(r13583,c180,s3996). +registration(r13584,c134,s3996). +registration(r13585,c231,s3997). +registration(r13586,c92,s3997). +registration(r13587,c87,s3997). +registration(r13588,c235,s3998). +registration(r13589,c19,s3998). +registration(r13590,c188,s3998). +registration(r13591,c63,s3998). +registration(r13592,c88,s3999). +registration(r13593,c75,s3999). +registration(r13594,c228,s3999). +registration(r13595,c136,s3999). +registration(r13596,c63,s4000). +registration(r13597,c168,s4000). +registration(r13598,c132,s4000). +registration(r13599,c13,s4001). +registration(r13600,c41,s4001). +registration(r13601,c27,s4001). +registration(r13602,c206,s4002). +registration(r13603,c244,s4002). +registration(r13604,c69,s4002). +registration(r13605,c163,s4003). +registration(r13606,c207,s4003). +registration(r13607,c106,s4003). +registration(r13608,c127,s4004). +registration(r13609,c79,s4004). +registration(r13610,c237,s4004). +registration(r13611,c69,s4005). +registration(r13612,c10,s4005). +registration(r13613,c142,s4005). +registration(r13614,c21,s4005). +registration(r13615,c214,s4006). +registration(r13616,c190,s4006). +registration(r13617,c152,s4006). +registration(r13618,c167,s4007). +registration(r13619,c189,s4007). +registration(r13620,c192,s4007). +registration(r13621,c146,s4007). +registration(r13622,c9,s4008). +registration(r13623,c218,s4008). +registration(r13624,c6,s4008). +registration(r13625,c214,s4009). +registration(r13626,c80,s4009). +registration(r13627,c16,s4009). +registration(r13628,c96,s4010). +registration(r13629,c127,s4010). +registration(r13630,c143,s4010). +registration(r13631,c197,s4010). +registration(r13632,c151,s4011). +registration(r13633,c91,s4011). +registration(r13634,c176,s4011). +registration(r13635,c110,s4011). +registration(r13636,c70,s4012). +registration(r13637,c199,s4012). +registration(r13638,c20,s4012). +registration(r13639,c212,s4013). +registration(r13640,c1,s4013). +registration(r13641,c25,s4013). +registration(r13642,c242,s4013). +registration(r13643,c105,s4014). +registration(r13644,c240,s4014). +registration(r13645,c112,s4014). +registration(r13646,c128,s4015). +registration(r13647,c208,s4015). +registration(r13648,c16,s4015). +registration(r13649,c158,s4016). +registration(r13650,c235,s4016). +registration(r13651,c19,s4016). +registration(r13652,c111,s4017). +registration(r13653,c231,s4017). +registration(r13654,c47,s4017). +registration(r13655,c118,s4018). +registration(r13656,c104,s4018). +registration(r13657,c106,s4018). +registration(r13658,c63,s4019). +registration(r13659,c102,s4019). +registration(r13660,c6,s4019). +registration(r13661,c248,s4020). +registration(r13662,c11,s4020). +registration(r13663,c97,s4020). +registration(r13664,c161,s4021). +registration(r13665,c234,s4021). +registration(r13666,c27,s4021). +registration(r13667,c106,s4022). +registration(r13668,c80,s4022). +registration(r13669,c184,s4022). +registration(r13670,c58,s4023). +registration(r13671,c238,s4023). +registration(r13672,c111,s4023). +registration(r13673,c197,s4024). +registration(r13674,c224,s4024). +registration(r13675,c249,s4024). +registration(r13676,c68,s4024). +registration(r13677,c111,s4025). +registration(r13678,c171,s4025). +registration(r13679,c236,s4025). +registration(r13680,c27,s4025). +registration(r13681,c29,s4026). +registration(r13682,c125,s4026). +registration(r13683,c79,s4026). +registration(r13684,c57,s4026). +registration(r13685,c131,s4027). +registration(r13686,c208,s4027). +registration(r13687,c4,s4027). +registration(r13688,c188,s4027). +registration(r13689,c108,s4028). +registration(r13690,c170,s4028). +registration(r13691,c247,s4028). +registration(r13692,c96,s4028). +registration(r13693,c234,s4029). +registration(r13694,c223,s4029). +registration(r13695,c65,s4029). +registration(r13696,c134,s4029). +registration(r13697,c202,s4030). +registration(r13698,c127,s4030). +registration(r13699,c49,s4030). +registration(r13700,c77,s4031). +registration(r13701,c157,s4031). +registration(r13702,c176,s4031). +registration(r13703,c23,s4032). +registration(r13704,c232,s4032). +registration(r13705,c37,s4032). +registration(r13706,c41,s4033). +registration(r13707,c138,s4033). +registration(r13708,c218,s4033). +registration(r13709,c132,s4034). +registration(r13710,c221,s4034). +registration(r13711,c80,s4034). +registration(r13712,c59,s4035). +registration(r13713,c127,s4035). +registration(r13714,c130,s4035). +registration(r13715,c144,s4035). +registration(r13716,c235,s4035). +registration(r13717,c15,s4036). +registration(r13718,c59,s4036). +registration(r13719,c162,s4036). +registration(r13720,c63,s4037). +registration(r13721,c82,s4037). +registration(r13722,c83,s4037). +registration(r13723,c107,s4037). +registration(r13724,c80,s4038). +registration(r13725,c5,s4038). +registration(r13726,c243,s4038). +registration(r13727,c205,s4039). +registration(r13728,c95,s4039). +registration(r13729,c133,s4039). +registration(r13730,c214,s4040). +registration(r13731,c240,s4040). +registration(r13732,c122,s4040). +registration(r13733,c109,s4040). +registration(r13734,c50,s4041). +registration(r13735,c254,s4041). +registration(r13736,c5,s4041). +registration(r13737,c14,s4041). +registration(r13738,c191,s4042). +registration(r13739,c175,s4042). +registration(r13740,c200,s4042). +registration(r13741,c26,s4042). +registration(r13742,c42,s4043). +registration(r13743,c108,s4043). +registration(r13744,c85,s4043). +registration(r13745,c72,s4044). +registration(r13746,c244,s4044). +registration(r13747,c0,s4044). +registration(r13748,c85,s4044). +registration(r13749,c103,s4045). +registration(r13750,c146,s4045). +registration(r13751,c90,s4045). +registration(r13752,c110,s4045). +registration(r13753,c198,s4046). +registration(r13754,c10,s4046). +registration(r13755,c159,s4046). +registration(r13756,c189,s4046). +registration(r13757,c211,s4047). +registration(r13758,c80,s4047). +registration(r13759,c124,s4047). +registration(r13760,c122,s4047). +registration(r13761,c133,s4048). +registration(r13762,c51,s4048). +registration(r13763,c166,s4048). +registration(r13764,c31,s4049). +registration(r13765,c98,s4049). +registration(r13766,c210,s4049). +registration(r13767,c99,s4049). +registration(r13768,c104,s4050). +registration(r13769,c231,s4050). +registration(r13770,c78,s4050). +registration(r13771,c167,s4051). +registration(r13772,c8,s4051). +registration(r13773,c177,s4051). +registration(r13774,c81,s4051). +registration(r13775,c51,s4052). +registration(r13776,c35,s4052). +registration(r13777,c14,s4052). +registration(r13778,c118,s4052). +registration(r13779,c137,s4053). +registration(r13780,c142,s4053). +registration(r13781,c6,s4053). +registration(r13782,c194,s4053). +registration(r13783,c255,s4054). +registration(r13784,c74,s4054). +registration(r13785,c203,s4054). +registration(r13786,c223,s4054). +registration(r13787,c195,s4055). +registration(r13788,c4,s4055). +registration(r13789,c73,s4055). +registration(r13790,c67,s4056). +registration(r13791,c238,s4056). +registration(r13792,c251,s4056). +registration(r13793,c105,s4057). +registration(r13794,c95,s4057). +registration(r13795,c241,s4057). +registration(r13796,c255,s4058). +registration(r13797,c163,s4058). +registration(r13798,c247,s4058). +registration(r13799,c132,s4058). +registration(r13800,c145,s4059). +registration(r13801,c60,s4059). +registration(r13802,c71,s4059). +registration(r13803,c146,s4060). +registration(r13804,c9,s4060). +registration(r13805,c159,s4060). +registration(r13806,c98,s4061). +registration(r13807,c180,s4061). +registration(r13808,c49,s4061). +registration(r13809,c7,s4061). +registration(r13810,c252,s4062). +registration(r13811,c3,s4062). +registration(r13812,c193,s4062). +registration(r13813,c33,s4063). +registration(r13814,c142,s4063). +registration(r13815,c10,s4063). +registration(r13816,c174,s4064). +registration(r13817,c156,s4064). +registration(r13818,c24,s4064). +registration(r13819,c170,s4064). +registration(r13820,c25,s4065). +registration(r13821,c106,s4065). +registration(r13822,c231,s4065). +registration(r13823,c240,s4066). +registration(r13824,c245,s4066). +registration(r13825,c170,s4066). +registration(r13826,c96,s4067). +registration(r13827,c11,s4067). +registration(r13828,c102,s4067). +registration(r13829,c98,s4068). +registration(r13830,c108,s4068). +registration(r13831,c67,s4068). +registration(r13832,c101,s4069). +registration(r13833,c141,s4069). +registration(r13834,c227,s4069). +registration(r13835,c25,s4069). +registration(r13836,c167,s4070). +registration(r13837,c50,s4070). +registration(r13838,c110,s4070). +registration(r13839,c136,s4071). +registration(r13840,c52,s4071). +registration(r13841,c196,s4071). +registration(r13842,c180,s4071). +registration(r13843,c211,s4072). +registration(r13844,c221,s4072). +registration(r13845,c141,s4072). +registration(r13846,c61,s4072). +registration(r13847,c144,s4073). +registration(r13848,c166,s4073). +registration(r13849,c27,s4073). +registration(r13850,c95,s4073). +registration(r13851,c242,s4074). +registration(r13852,c233,s4074). +registration(r13853,c195,s4074). +registration(r13854,c207,s4075). +registration(r13855,c152,s4075). +registration(r13856,c94,s4075). +registration(r13857,c206,s4076). +registration(r13858,c64,s4076). +registration(r13859,c167,s4076). +registration(r13860,c108,s4077). +registration(r13861,c53,s4077). +registration(r13862,c167,s4077). +registration(r13863,c9,s4077). +registration(r13864,c176,s4078). +registration(r13865,c52,s4078). +registration(r13866,c194,s4078). +registration(r13867,c104,s4079). +registration(r13868,c101,s4079). +registration(r13869,c185,s4079). +registration(r13870,c170,s4080). +registration(r13871,c99,s4080). +registration(r13872,c138,s4080). +registration(r13873,c48,s4080). +registration(r13874,c193,s4081). +registration(r13875,c144,s4081). +registration(r13876,c209,s4081). +registration(r13877,c17,s4082). +registration(r13878,c54,s4082). +registration(r13879,c181,s4082). +registration(r13880,c234,s4083). +registration(r13881,c45,s4083). +registration(r13882,c195,s4083). +registration(r13883,c115,s4084). +registration(r13884,c40,s4084). +registration(r13885,c116,s4084). +registration(r13886,c219,s4085). +registration(r13887,c36,s4085). +registration(r13888,c166,s4085). +registration(r13889,c81,s4086). +registration(r13890,c185,s4086). +registration(r13891,c117,s4086). +registration(r13892,c207,s4087). +registration(r13893,c60,s4087). +registration(r13894,c122,s4087). +registration(r13895,c217,s4088). +registration(r13896,c177,s4088). +registration(r13897,c255,s4088). +registration(r13898,c161,s4089). +registration(r13899,c120,s4089). +registration(r13900,c101,s4089). +registration(r13901,c23,s4090). +registration(r13902,c217,s4090). +registration(r13903,c149,s4090). +registration(r13904,c131,s4091). +registration(r13905,c102,s4091). +registration(r13906,c188,s4091). +registration(r13907,c187,s4091). +registration(r13908,c123,s4092). +registration(r13909,c116,s4092). +registration(r13910,c27,s4092). +registration(r13911,c235,s4093). +registration(r13912,c51,s4093). +registration(r13913,c216,s4093). +registration(r13914,c178,s4094). +registration(r13915,c61,s4094). +registration(r13916,c252,s4094). +registration(r13917,c158,s4095). +registration(r13918,c186,s4095). +registration(r13919,c221,s4095). +registration(r13920,c39,s4095). + + +% :- [evidence_128]. + diff --git a/packages/CLPBN/clpbn/examples/School/school_32.yap b/packages/CLPBN/clpbn/examples/School/school_32.yap new file mode 100644 index 000000000..a948a2e64 --- /dev/null +++ b/packages/CLPBN/clpbn/examples/School/school_32.yap @@ -0,0 +1,1238 @@ +/* +total_professors(32). + +total_courses(64). + +total_students(256). + +*/ + +:- source. + +:- style_check(all). + +:- yap_flag(unknown,error). + +:- yap_flag(write_strings,on). + +:- use_module(library(clpbn)). + +:- [-schema]. + +professor(p0). +professor(p1). +professor(p2). +professor(p3). +professor(p4). +professor(p5). +professor(p6). +professor(p7). +professor(p8). +professor(p9). +professor(p10). +professor(p11). +professor(p12). +professor(p13). +professor(p14). +professor(p15). +professor(p16). +professor(p17). +professor(p18). +professor(p19). +professor(p20). +professor(p21). +professor(p22). +professor(p23). +professor(p24). +professor(p25). +professor(p26). +professor(p27). +professor(p28). +professor(p29). +professor(p30). +professor(p31). + + +course(c0,p24). +course(c1,p7). +course(c2,p16). +course(c3,p27). +course(c4,p25). +course(c5,p6). +course(c6,p28). +course(c7,p1). +course(c8,p29). +course(c9,p23). +course(c10,p17). +course(c11,p16). +course(c12,p11). +course(c13,p28). +course(c14,p13). +course(c15,p7). +course(c16,p21). +course(c17,p15). +course(c18,p8). +course(c19,p30). +course(c20,p1). +course(c21,p23). +course(c22,p11). +course(c23,p9). +course(c24,p0). +course(c25,p30). +course(c26,p15). +course(c27,p4). +course(c28,p26). +course(c29,p29). +course(c30,p31). +course(c31,p19). +course(c32,p5). +course(c33,p14). +course(c34,p14). +course(c35,p25). +course(c36,p21). +course(c37,p10). +course(c38,p2). +course(c39,p20). +course(c40,p3). +course(c41,p18). +course(c42,p9). +course(c43,p20). +course(c44,p17). +course(c45,p19). +course(c46,p6). +course(c47,p4). +course(c48,p12). +course(c49,p10). +course(c50,p2). +course(c51,p22). +course(c52,p31). +course(c53,p24). +course(c54,p0). +course(c55,p5). +course(c56,p22). +course(c57,p13). +course(c58,p18). +course(c59,p12). +course(c60,p27). +course(c61,p3). +course(c62,p8). +course(c63,p26). + + +student(s0). +student(s1). +student(s2). +student(s3). +student(s4). +student(s5). +student(s6). +student(s7). +student(s8). +student(s9). +student(s10). +student(s11). +student(s12). +student(s13). +student(s14). +student(s15). +student(s16). +student(s17). +student(s18). +student(s19). +student(s20). +student(s21). +student(s22). +student(s23). +student(s24). +student(s25). +student(s26). +student(s27). +student(s28). +student(s29). +student(s30). +student(s31). +student(s32). +student(s33). +student(s34). +student(s35). +student(s36). +student(s37). +student(s38). +student(s39). +student(s40). +student(s41). +student(s42). +student(s43). +student(s44). +student(s45). +student(s46). +student(s47). +student(s48). +student(s49). +student(s50). +student(s51). +student(s52). +student(s53). +student(s54). +student(s55). +student(s56). +student(s57). +student(s58). +student(s59). +student(s60). +student(s61). +student(s62). +student(s63). +student(s64). +student(s65). +student(s66). +student(s67). +student(s68). +student(s69). +student(s70). +student(s71). +student(s72). +student(s73). +student(s74). +student(s75). +student(s76). +student(s77). +student(s78). +student(s79). +student(s80). +student(s81). +student(s82). +student(s83). +student(s84). +student(s85). +student(s86). +student(s87). +student(s88). +student(s89). +student(s90). +student(s91). +student(s92). +student(s93). +student(s94). +student(s95). +student(s96). +student(s97). +student(s98). +student(s99). +student(s100). +student(s101). +student(s102). +student(s103). +student(s104). +student(s105). +student(s106). +student(s107). +student(s108). +student(s109). +student(s110). +student(s111). +student(s112). +student(s113). +student(s114). +student(s115). +student(s116). +student(s117). +student(s118). +student(s119). +student(s120). +student(s121). +student(s122). +student(s123). +student(s124). +student(s125). +student(s126). +student(s127). +student(s128). +student(s129). +student(s130). +student(s131). +student(s132). +student(s133). +student(s134). +student(s135). +student(s136). +student(s137). +student(s138). +student(s139). +student(s140). +student(s141). +student(s142). +student(s143). +student(s144). +student(s145). +student(s146). +student(s147). +student(s148). +student(s149). +student(s150). +student(s151). +student(s152). +student(s153). +student(s154). +student(s155). +student(s156). +student(s157). +student(s158). +student(s159). +student(s160). +student(s161). +student(s162). +student(s163). +student(s164). +student(s165). +student(s166). +student(s167). +student(s168). +student(s169). +student(s170). +student(s171). +student(s172). +student(s173). +student(s174). +student(s175). +student(s176). +student(s177). +student(s178). +student(s179). +student(s180). +student(s181). +student(s182). +student(s183). +student(s184). +student(s185). +student(s186). +student(s187). +student(s188). +student(s189). +student(s190). +student(s191). +student(s192). +student(s193). +student(s194). +student(s195). +student(s196). +student(s197). +student(s198). +student(s199). +student(s200). +student(s201). +student(s202). +student(s203). +student(s204). +student(s205). +student(s206). +student(s207). +student(s208). +student(s209). +student(s210). +student(s211). +student(s212). +student(s213). +student(s214). +student(s215). +student(s216). +student(s217). +student(s218). +student(s219). +student(s220). +student(s221). +student(s222). +student(s223). +student(s224). +student(s225). +student(s226). +student(s227). +student(s228). +student(s229). +student(s230). +student(s231). +student(s232). +student(s233). +student(s234). +student(s235). +student(s236). +student(s237). +student(s238). +student(s239). +student(s240). +student(s241). +student(s242). +student(s243). +student(s244). +student(s245). +student(s246). +student(s247). +student(s248). +student(s249). +student(s250). +student(s251). +student(s252). +student(s253). +student(s254). +student(s255). + + +registration(r0,c16,s0). +registration(r1,c10,s0). +registration(r2,c57,s0). +registration(r3,c22,s1). +registration(r4,c55,s1). +registration(r5,c27,s1). +registration(r6,c14,s2). +registration(r7,c52,s2). +registration(r8,c10,s2). +registration(r9,c47,s3). +registration(r10,c16,s3). +registration(r11,c62,s3). +registration(r12,c12,s4). +registration(r13,c11,s4). +registration(r14,c17,s4). +registration(r15,c52,s5). +registration(r16,c1,s5). +registration(r17,c35,s5). +registration(r18,c0,s6). +registration(r19,c7,s6). +registration(r20,c40,s6). +registration(r21,c62,s7). +registration(r22,c16,s7). +registration(r23,c34,s7). +registration(r24,c60,s8). +registration(r25,c39,s8). +registration(r26,c43,s8). +registration(r27,c17,s8). +registration(r28,c55,s9). +registration(r29,c34,s9). +registration(r30,c35,s9). +registration(r31,c48,s10). +registration(r32,c60,s10). +registration(r33,c2,s10). +registration(r34,c54,s11). +registration(r35,c42,s11). +registration(r36,c9,s11). +registration(r37,c11,s11). +registration(r38,c51,s12). +registration(r39,c47,s12). +registration(r40,c4,s12). +registration(r41,c20,s13). +registration(r42,c0,s13). +registration(r43,c9,s13). +registration(r44,c61,s13). +registration(r45,c55,s14). +registration(r46,c5,s14). +registration(r47,c3,s14). +registration(r48,c38,s15). +registration(r49,c1,s15). +registration(r50,c46,s15). +registration(r51,c42,s16). +registration(r52,c27,s16). +registration(r53,c26,s16). +registration(r54,c6,s17). +registration(r55,c27,s17). +registration(r56,c0,s17). +registration(r57,c51,s18). +registration(r58,c63,s18). +registration(r59,c41,s18). +registration(r60,c63,s19). +registration(r61,c18,s19). +registration(r62,c54,s19). +registration(r63,c15,s19). +registration(r64,c3,s20). +registration(r65,c22,s20). +registration(r66,c43,s20). +registration(r67,c17,s21). +registration(r68,c34,s21). +registration(r69,c0,s21). +registration(r70,c42,s22). +registration(r71,c7,s22). +registration(r72,c46,s22). +registration(r73,c52,s23). +registration(r74,c21,s23). +registration(r75,c27,s23). +registration(r76,c60,s23). +registration(r77,c2,s24). +registration(r78,c38,s24). +registration(r79,c32,s24). +registration(r80,c51,s25). +registration(r81,c39,s25). +registration(r82,c49,s25). +registration(r83,c15,s25). +registration(r84,c25,s26). +registration(r85,c59,s26). +registration(r86,c21,s26). +registration(r87,c56,s27). +registration(r88,c43,s27). +registration(r89,c55,s27). +registration(r90,c21,s27). +registration(r91,c57,s28). +registration(r92,c17,s28). +registration(r93,c26,s28). +registration(r94,c53,s29). +registration(r95,c48,s29). +registration(r96,c34,s29). +registration(r97,c50,s29). +registration(r98,c35,s29). +registration(r99,c36,s30). +registration(r100,c48,s30). +registration(r101,c23,s30). +registration(r102,c33,s30). +registration(r103,c28,s31). +registration(r104,c23,s31). +registration(r105,c53,s31). +registration(r106,c32,s32). +registration(r107,c37,s32). +registration(r108,c38,s32). +registration(r109,c27,s32). +registration(r110,c34,s33). +registration(r111,c28,s33). +registration(r112,c43,s33). +registration(r113,c24,s34). +registration(r114,c28,s34). +registration(r115,c45,s34). +registration(r116,c63,s34). +registration(r117,c60,s35). +registration(r118,c9,s35). +registration(r119,c22,s35). +registration(r120,c46,s36). +registration(r121,c44,s36). +registration(r122,c26,s36). +registration(r123,c9,s36). +registration(r124,c62,s37). +registration(r125,c33,s37). +registration(r126,c31,s37). +registration(r127,c6,s37). +registration(r128,c43,s38). +registration(r129,c35,s38). +registration(r130,c56,s38). +registration(r131,c32,s38). +registration(r132,c2,s39). +registration(r133,c56,s39). +registration(r134,c58,s39). +registration(r135,c3,s40). +registration(r136,c29,s40). +registration(r137,c22,s40). +registration(r138,c39,s40). +registration(r139,c32,s41). +registration(r140,c31,s41). +registration(r141,c25,s41). +registration(r142,c36,s42). +registration(r143,c24,s42). +registration(r144,c47,s42). +registration(r145,c15,s43). +registration(r146,c1,s43). +registration(r147,c2,s43). +registration(r148,c37,s44). +registration(r149,c14,s44). +registration(r150,c60,s44). +registration(r151,c62,s45). +registration(r152,c29,s45). +registration(r153,c43,s45). +registration(r154,c46,s45). +registration(r155,c57,s46). +registration(r156,c25,s46). +registration(r157,c46,s46). +registration(r158,c15,s46). +registration(r159,c0,s47). +registration(r160,c33,s47). +registration(r161,c30,s47). +registration(r162,c55,s47). +registration(r163,c43,s48). +registration(r164,c38,s48). +registration(r165,c50,s48). +registration(r166,c51,s49). +registration(r167,c17,s49). +registration(r168,c23,s49). +registration(r169,c18,s50). +registration(r170,c63,s50). +registration(r171,c16,s50). +registration(r172,c60,s51). +registration(r173,c44,s51). +registration(r174,c32,s51). +registration(r175,c59,s52). +registration(r176,c26,s52). +registration(r177,c7,s52). +registration(r178,c42,s52). +registration(r179,c33,s52). +registration(r180,c9,s53). +registration(r181,c5,s53). +registration(r182,c39,s53). +registration(r183,c49,s53). +registration(r184,c50,s54). +registration(r185,c43,s54). +registration(r186,c55,s54). +registration(r187,c14,s55). +registration(r188,c0,s55). +registration(r189,c31,s55). +registration(r190,c47,s55). +registration(r191,c50,s56). +registration(r192,c29,s56). +registration(r193,c42,s56). +registration(r194,c22,s57). +registration(r195,c7,s57). +registration(r196,c59,s57). +registration(r197,c60,s58). +registration(r198,c26,s58). +registration(r199,c23,s58). +registration(r200,c29,s59). +registration(r201,c4,s59). +registration(r202,c38,s59). +registration(r203,c24,s60). +registration(r204,c59,s60). +registration(r205,c9,s60). +registration(r206,c23,s61). +registration(r207,c63,s61). +registration(r208,c22,s61). +registration(r209,c6,s62). +registration(r210,c43,s62). +registration(r211,c30,s62). +registration(r212,c29,s62). +registration(r213,c7,s63). +registration(r214,c19,s63). +registration(r215,c25,s63). +registration(r216,c20,s64). +registration(r217,c19,s64). +registration(r218,c57,s64). +registration(r219,c22,s65). +registration(r220,c55,s65). +registration(r221,c30,s65). +registration(r222,c53,s65). +registration(r223,c32,s66). +registration(r224,c19,s66). +registration(r225,c53,s66). +registration(r226,c53,s67). +registration(r227,c48,s67). +registration(r228,c35,s67). +registration(r229,c15,s68). +registration(r230,c20,s68). +registration(r231,c41,s68). +registration(r232,c49,s69). +registration(r233,c44,s69). +registration(r234,c9,s69). +registration(r235,c30,s70). +registration(r236,c61,s70). +registration(r237,c8,s70). +registration(r238,c31,s71). +registration(r239,c8,s71). +registration(r240,c20,s71). +registration(r241,c18,s71). +registration(r242,c38,s71). +registration(r243,c37,s72). +registration(r244,c0,s72). +registration(r245,c62,s72). +registration(r246,c47,s73). +registration(r247,c53,s73). +registration(r248,c41,s73). +registration(r249,c62,s73). +registration(r250,c16,s74). +registration(r251,c31,s74). +registration(r252,c48,s74). +registration(r253,c11,s74). +registration(r254,c43,s75). +registration(r255,c26,s75). +registration(r256,c22,s75). +registration(r257,c40,s76). +registration(r258,c31,s76). +registration(r259,c2,s76). +registration(r260,c7,s77). +registration(r261,c3,s77). +registration(r262,c63,s77). +registration(r263,c0,s78). +registration(r264,c43,s78). +registration(r265,c57,s78). +registration(r266,c46,s79). +registration(r267,c32,s79). +registration(r268,c1,s79). +registration(r269,c18,s80). +registration(r270,c17,s80). +registration(r271,c14,s80). +registration(r272,c8,s81). +registration(r273,c63,s81). +registration(r274,c56,s81). +registration(r275,c28,s82). +registration(r276,c8,s82). +registration(r277,c9,s82). +registration(r278,c61,s83). +registration(r279,c38,s83). +registration(r280,c60,s83). +registration(r281,c38,s84). +registration(r282,c60,s84). +registration(r283,c63,s84). +registration(r284,c25,s85). +registration(r285,c13,s85). +registration(r286,c20,s85). +registration(r287,c52,s85). +registration(r288,c45,s86). +registration(r289,c17,s86). +registration(r290,c2,s86). +registration(r291,c48,s86). +registration(r292,c0,s86). +registration(r293,c40,s87). +registration(r294,c44,s87). +registration(r295,c41,s87). +registration(r296,c53,s87). +registration(r297,c37,s88). +registration(r298,c47,s88). +registration(r299,c48,s88). +registration(r300,c44,s89). +registration(r301,c32,s89). +registration(r302,c18,s89). +registration(r303,c50,s90). +registration(r304,c26,s90). +registration(r305,c58,s90). +registration(r306,c45,s90). +registration(r307,c0,s91). +registration(r308,c35,s91). +registration(r309,c4,s91). +registration(r310,c4,s92). +registration(r311,c1,s92). +registration(r312,c49,s92). +registration(r313,c42,s92). +registration(r314,c47,s93). +registration(r315,c48,s93). +registration(r316,c17,s93). +registration(r317,c1,s94). +registration(r318,c18,s94). +registration(r319,c35,s94). +registration(r320,c3,s95). +registration(r321,c0,s95). +registration(r322,c38,s95). +registration(r323,c1,s96). +registration(r324,c30,s96). +registration(r325,c52,s96). +registration(r326,c52,s97). +registration(r327,c18,s97). +registration(r328,c55,s97). +registration(r329,c56,s97). +registration(r330,c8,s98). +registration(r331,c41,s98). +registration(r332,c1,s98). +registration(r333,c49,s98). +registration(r334,c35,s99). +registration(r335,c23,s99). +registration(r336,c18,s99). +registration(r337,c36,s100). +registration(r338,c27,s100). +registration(r339,c6,s100). +registration(r340,c7,s101). +registration(r341,c8,s101). +registration(r342,c3,s101). +registration(r343,c35,s101). +registration(r344,c47,s102). +registration(r345,c57,s102). +registration(r346,c20,s102). +registration(r347,c11,s102). +registration(r348,c41,s103). +registration(r349,c4,s103). +registration(r350,c8,s103). +registration(r351,c9,s104). +registration(r352,c37,s104). +registration(r353,c52,s104). +registration(r354,c12,s104). +registration(r355,c13,s105). +registration(r356,c2,s105). +registration(r357,c38,s105). +registration(r358,c44,s106). +registration(r359,c18,s106). +registration(r360,c62,s106). +registration(r361,c2,s107). +registration(r362,c47,s107). +registration(r363,c35,s107). +registration(r364,c29,s108). +registration(r365,c57,s108). +registration(r366,c1,s108). +registration(r367,c43,s108). +registration(r368,c45,s109). +registration(r369,c13,s109). +registration(r370,c29,s109). +registration(r371,c2,s110). +registration(r372,c16,s110). +registration(r373,c19,s110). +registration(r374,c29,s110). +registration(r375,c13,s111). +registration(r376,c1,s111). +registration(r377,c18,s111). +registration(r378,c36,s112). +registration(r379,c42,s112). +registration(r380,c32,s112). +registration(r381,c17,s113). +registration(r382,c35,s113). +registration(r383,c16,s113). +registration(r384,c11,s114). +registration(r385,c50,s114). +registration(r386,c40,s114). +registration(r387,c22,s115). +registration(r388,c31,s115). +registration(r389,c59,s115). +registration(r390,c62,s116). +registration(r391,c1,s116). +registration(r392,c8,s116). +registration(r393,c30,s116). +registration(r394,c23,s117). +registration(r395,c32,s117). +registration(r396,c56,s117). +registration(r397,c12,s117). +registration(r398,c46,s118). +registration(r399,c47,s118). +registration(r400,c25,s118). +registration(r401,c61,s118). +registration(r402,c44,s119). +registration(r403,c49,s119). +registration(r404,c61,s119). +registration(r405,c38,s120). +registration(r406,c8,s120). +registration(r407,c0,s120). +registration(r408,c60,s121). +registration(r409,c45,s121). +registration(r410,c28,s121). +registration(r411,c37,s122). +registration(r412,c4,s122). +registration(r413,c15,s122). +registration(r414,c28,s122). +registration(r415,c4,s123). +registration(r416,c31,s123). +registration(r417,c59,s123). +registration(r418,c42,s124). +registration(r419,c59,s124). +registration(r420,c39,s124). +registration(r421,c21,s125). +registration(r422,c29,s125). +registration(r423,c54,s125). +registration(r424,c28,s126). +registration(r425,c22,s126). +registration(r426,c0,s126). +registration(r427,c61,s127). +registration(r428,c7,s127). +registration(r429,c28,s127). +registration(r430,c1,s128). +registration(r431,c60,s128). +registration(r432,c7,s128). +registration(r433,c52,s129). +registration(r434,c18,s129). +registration(r435,c55,s129). +registration(r436,c4,s130). +registration(r437,c27,s130). +registration(r438,c46,s130). +registration(r439,c39,s130). +registration(r440,c3,s131). +registration(r441,c35,s131). +registration(r442,c29,s131). +registration(r443,c57,s132). +registration(r444,c38,s132). +registration(r445,c34,s132). +registration(r446,c32,s133). +registration(r447,c24,s133). +registration(r448,c1,s133). +registration(r449,c3,s134). +registration(r450,c21,s134). +registration(r451,c25,s134). +registration(r452,c13,s135). +registration(r453,c36,s135). +registration(r454,c35,s135). +registration(r455,c40,s136). +registration(r456,c24,s136). +registration(r457,c5,s136). +registration(r458,c44,s137). +registration(r459,c25,s137). +registration(r460,c2,s137). +registration(r461,c43,s137). +registration(r462,c2,s138). +registration(r463,c19,s138). +registration(r464,c9,s138). +registration(r465,c41,s139). +registration(r466,c46,s139). +registration(r467,c58,s139). +registration(r468,c63,s139). +registration(r469,c22,s140). +registration(r470,c24,s140). +registration(r471,c14,s140). +registration(r472,c37,s140). +registration(r473,c38,s141). +registration(r474,c33,s141). +registration(r475,c9,s141). +registration(r476,c15,s142). +registration(r477,c37,s142). +registration(r478,c26,s142). +registration(r479,c29,s143). +registration(r480,c5,s143). +registration(r481,c42,s143). +registration(r482,c8,s143). +registration(r483,c11,s144). +registration(r484,c29,s144). +registration(r485,c54,s144). +registration(r486,c47,s144). +registration(r487,c54,s145). +registration(r488,c9,s145). +registration(r489,c44,s145). +registration(r490,c60,s146). +registration(r491,c15,s146). +registration(r492,c5,s146). +registration(r493,c39,s147). +registration(r494,c57,s147). +registration(r495,c3,s147). +registration(r496,c41,s147). +registration(r497,c60,s148). +registration(r498,c4,s148). +registration(r499,c39,s148). +registration(r500,c18,s148). +registration(r501,c28,s149). +registration(r502,c18,s149). +registration(r503,c15,s149). +registration(r504,c5,s150). +registration(r505,c29,s150). +registration(r506,c57,s150). +registration(r507,c3,s151). +registration(r508,c35,s151). +registration(r509,c33,s151). +registration(r510,c48,s152). +registration(r511,c41,s152). +registration(r512,c13,s152). +registration(r513,c6,s153). +registration(r514,c42,s153). +registration(r515,c53,s153). +registration(r516,c49,s154). +registration(r517,c19,s154). +registration(r518,c59,s154). +registration(r519,c29,s154). +registration(r520,c40,s155). +registration(r521,c48,s155). +registration(r522,c28,s155). +registration(r523,c34,s156). +registration(r524,c45,s156). +registration(r525,c24,s156). +registration(r526,c28,s156). +registration(r527,c58,s157). +registration(r528,c34,s157). +registration(r529,c1,s157). +registration(r530,c43,s158). +registration(r531,c38,s158). +registration(r532,c57,s158). +registration(r533,c35,s159). +registration(r534,c50,s159). +registration(r535,c60,s159). +registration(r536,c16,s160). +registration(r537,c49,s160). +registration(r538,c47,s160). +registration(r539,c23,s161). +registration(r540,c31,s161). +registration(r541,c27,s161). +registration(r542,c62,s162). +registration(r543,c21,s162). +registration(r544,c23,s162). +registration(r545,c52,s163). +registration(r546,c16,s163). +registration(r547,c58,s163). +registration(r548,c14,s164). +registration(r549,c34,s164). +registration(r550,c16,s164). +registration(r551,c32,s164). +registration(r552,c42,s165). +registration(r553,c18,s165). +registration(r554,c58,s165). +registration(r555,c11,s166). +registration(r556,c18,s166). +registration(r557,c39,s166). +registration(r558,c62,s167). +registration(r559,c24,s167). +registration(r560,c44,s167). +registration(r561,c43,s168). +registration(r562,c60,s168). +registration(r563,c46,s168). +registration(r564,c18,s168). +registration(r565,c17,s169). +registration(r566,c14,s169). +registration(r567,c26,s169). +registration(r568,c59,s170). +registration(r569,c11,s170). +registration(r570,c36,s170). +registration(r571,c15,s170). +registration(r572,c45,s171). +registration(r573,c3,s171). +registration(r574,c48,s171). +registration(r575,c2,s172). +registration(r576,c11,s172). +registration(r577,c9,s172). +registration(r578,c35,s172). +registration(r579,c63,s173). +registration(r580,c46,s173). +registration(r581,c56,s173). +registration(r582,c41,s174). +registration(r583,c44,s174). +registration(r584,c63,s174). +registration(r585,c60,s174). +registration(r586,c38,s175). +registration(r587,c57,s175). +registration(r588,c41,s175). +registration(r589,c13,s175). +registration(r590,c60,s176). +registration(r591,c13,s176). +registration(r592,c29,s176). +registration(r593,c12,s177). +registration(r594,c15,s177). +registration(r595,c33,s177). +registration(r596,c41,s178). +registration(r597,c33,s178). +registration(r598,c34,s178). +registration(r599,c32,s178). +registration(r600,c5,s179). +registration(r601,c14,s179). +registration(r602,c61,s179). +registration(r603,c60,s180). +registration(r604,c58,s180). +registration(r605,c53,s180). +registration(r606,c31,s180). +registration(r607,c51,s181). +registration(r608,c2,s181). +registration(r609,c52,s181). +registration(r610,c63,s181). +registration(r611,c29,s181). +registration(r612,c41,s182). +registration(r613,c19,s182). +registration(r614,c43,s182). +registration(r615,c58,s183). +registration(r616,c16,s183). +registration(r617,c30,s183). +registration(r618,c42,s184). +registration(r619,c63,s184). +registration(r620,c5,s184). +registration(r621,c2,s184). +registration(r622,c30,s185). +registration(r623,c5,s185). +registration(r624,c62,s185). +registration(r625,c8,s186). +registration(r626,c59,s186). +registration(r627,c44,s186). +registration(r628,c33,s187). +registration(r629,c61,s187). +registration(r630,c60,s187). +registration(r631,c38,s188). +registration(r632,c55,s188). +registration(r633,c6,s188). +registration(r634,c1,s189). +registration(r635,c47,s189). +registration(r636,c10,s189). +registration(r637,c52,s190). +registration(r638,c28,s190). +registration(r639,c39,s190). +registration(r640,c42,s191). +registration(r641,c3,s191). +registration(r642,c48,s191). +registration(r643,c44,s192). +registration(r644,c50,s192). +registration(r645,c24,s192). +registration(r646,c24,s193). +registration(r647,c59,s193). +registration(r648,c42,s193). +registration(r649,c6,s194). +registration(r650,c60,s194). +registration(r651,c23,s194). +registration(r652,c3,s195). +registration(r653,c15,s195). +registration(r654,c11,s195). +registration(r655,c45,s196). +registration(r656,c1,s196). +registration(r657,c10,s196). +registration(r658,c51,s197). +registration(r659,c63,s197). +registration(r660,c40,s197). +registration(r661,c7,s198). +registration(r662,c16,s198). +registration(r663,c28,s198). +registration(r664,c8,s199). +registration(r665,c57,s199). +registration(r666,c37,s199). +registration(r667,c4,s200). +registration(r668,c58,s200). +registration(r669,c12,s200). +registration(r670,c39,s200). +registration(r671,c31,s201). +registration(r672,c21,s201). +registration(r673,c50,s201). +registration(r674,c30,s201). +registration(r675,c46,s202). +registration(r676,c12,s202). +registration(r677,c52,s202). +registration(r678,c51,s202). +registration(r679,c63,s203). +registration(r680,c35,s203). +registration(r681,c28,s203). +registration(r682,c51,s203). +registration(r683,c40,s204). +registration(r684,c29,s204). +registration(r685,c1,s204). +registration(r686,c53,s204). +registration(r687,c49,s205). +registration(r688,c7,s205). +registration(r689,c46,s205). +registration(r690,c54,s206). +registration(r691,c36,s206). +registration(r692,c2,s206). +registration(r693,c23,s206). +registration(r694,c14,s207). +registration(r695,c54,s207). +registration(r696,c29,s207). +registration(r697,c50,s208). +registration(r698,c27,s208). +registration(r699,c30,s208). +registration(r700,c59,s209). +registration(r701,c56,s209). +registration(r702,c50,s209). +registration(r703,c17,s210). +registration(r704,c53,s210). +registration(r705,c4,s210). +registration(r706,c53,s211). +registration(r707,c28,s211). +registration(r708,c25,s211). +registration(r709,c15,s211). +registration(r710,c25,s212). +registration(r711,c3,s212). +registration(r712,c30,s212). +registration(r713,c43,s213). +registration(r714,c37,s213). +registration(r715,c16,s213). +registration(r716,c15,s213). +registration(r717,c34,s213). +registration(r718,c46,s214). +registration(r719,c53,s214). +registration(r720,c33,s214). +registration(r721,c22,s215). +registration(r722,c30,s215). +registration(r723,c16,s215). +registration(r724,c20,s216). +registration(r725,c60,s216). +registration(r726,c62,s216). +registration(r727,c25,s216). +registration(r728,c62,s217). +registration(r729,c25,s217). +registration(r730,c40,s217). +registration(r731,c6,s218). +registration(r732,c9,s218). +registration(r733,c18,s218). +registration(r734,c33,s219). +registration(r735,c56,s219). +registration(r736,c63,s219). +registration(r737,c45,s220). +registration(r738,c25,s220). +registration(r739,c62,s220). +registration(r740,c19,s220). +registration(r741,c54,s221). +registration(r742,c24,s221). +registration(r743,c60,s221). +registration(r744,c44,s221). +registration(r745,c8,s222). +registration(r746,c56,s222). +registration(r747,c18,s222). +registration(r748,c43,s223). +registration(r749,c10,s223). +registration(r750,c15,s223). +registration(r751,c17,s223). +registration(r752,c26,s224). +registration(r753,c2,s224). +registration(r754,c6,s224). +registration(r755,c5,s225). +registration(r756,c32,s225). +registration(r757,c23,s225). +registration(r758,c20,s226). +registration(r759,c11,s226). +registration(r760,c2,s226). +registration(r761,c29,s226). +registration(r762,c37,s227). +registration(r763,c12,s227). +registration(r764,c10,s227). +registration(r765,c3,s228). +registration(r766,c47,s228). +registration(r767,c54,s228). +registration(r768,c0,s229). +registration(r769,c10,s229). +registration(r770,c37,s229). +registration(r771,c62,s230). +registration(r772,c19,s230). +registration(r773,c38,s230). +registration(r774,c44,s231). +registration(r775,c25,s231). +registration(r776,c37,s231). +registration(r777,c58,s232). +registration(r778,c42,s232). +registration(r779,c22,s232). +registration(r780,c51,s233). +registration(r781,c8,s233). +registration(r782,c58,s233). +registration(r783,c14,s234). +registration(r784,c0,s234). +registration(r785,c23,s234). +registration(r786,c59,s234). +registration(r787,c5,s235). +registration(r788,c4,s235). +registration(r789,c23,s235). +registration(r790,c21,s236). +registration(r791,c42,s236). +registration(r792,c12,s236). +registration(r793,c57,s237). +registration(r794,c40,s237). +registration(r795,c30,s237). +registration(r796,c26,s238). +registration(r797,c4,s238). +registration(r798,c21,s238). +registration(r799,c8,s239). +registration(r800,c7,s239). +registration(r801,c45,s239). +registration(r802,c47,s239). +registration(r803,c7,s240). +registration(r804,c4,s240). +registration(r805,c0,s240). +registration(r806,c54,s240). +registration(r807,c9,s240). +registration(r808,c11,s241). +registration(r809,c29,s241). +registration(r810,c45,s241). +registration(r811,c58,s241). +registration(r812,c48,s242). +registration(r813,c0,s242). +registration(r814,c51,s242). +registration(r815,c12,s243). +registration(r816,c24,s243). +registration(r817,c59,s243). +registration(r818,c58,s244). +registration(r819,c4,s244). +registration(r820,c52,s244). +registration(r821,c47,s244). +registration(r822,c49,s245). +registration(r823,c43,s245). +registration(r824,c3,s245). +registration(r825,c5,s246). +registration(r826,c44,s246). +registration(r827,c51,s246). +registration(r828,c15,s247). +registration(r829,c58,s247). +registration(r830,c25,s247). +registration(r831,c9,s248). +registration(r832,c23,s248). +registration(r833,c40,s248). +registration(r834,c52,s249). +registration(r835,c59,s249). +registration(r836,c50,s249). +registration(r837,c38,s249). +registration(r838,c10,s250). +registration(r839,c30,s250). +registration(r840,c49,s250). +registration(r841,c34,s251). +registration(r842,c41,s251). +registration(r843,c27,s251). +registration(r844,c34,s252). +registration(r845,c4,s252). +registration(r846,c8,s252). +registration(r847,c23,s253). +registration(r848,c42,s253). +registration(r849,c20,s253). +registration(r850,c30,s254). +registration(r851,c5,s254). +registration(r852,c7,s254). +registration(r853,c61,s254). +registration(r854,c60,s255). +registration(r855,c48,s255). +registration(r856,c0,s255). + + diff --git a/packages/CLPBN/clpbn/examples/School/school_64.yap b/packages/CLPBN/clpbn/examples/School/school_64.yap new file mode 100644 index 000000000..b3084a96e --- /dev/null +++ b/packages/CLPBN/clpbn/examples/School/school_64.yap @@ -0,0 +1,4706 @@ +/* +total_professors(64). + +total_courses(128). + +total_students(1024). + +*/ + +:- source. + +:- style_check(all). + +:- yap_flag(unknown,error). + +:- yap_flag(write_strings,on). + +:- use_module(library(clpbn)). + +:- [-schema]. + +professor(p0). +professor(p1). +professor(p2). +professor(p3). +professor(p4). +professor(p5). +professor(p6). +professor(p7). +professor(p8). +professor(p9). +professor(p10). +professor(p11). +professor(p12). +professor(p13). +professor(p14). +professor(p15). +professor(p16). +professor(p17). +professor(p18). +professor(p19). +professor(p20). +professor(p21). +professor(p22). +professor(p23). +professor(p24). +professor(p25). +professor(p26). +professor(p27). +professor(p28). +professor(p29). +professor(p30). +professor(p31). +professor(p32). +professor(p33). +professor(p34). +professor(p35). +professor(p36). +professor(p37). +professor(p38). +professor(p39). +professor(p40). +professor(p41). +professor(p42). +professor(p43). +professor(p44). +professor(p45). +professor(p46). +professor(p47). +professor(p48). +professor(p49). +professor(p50). +professor(p51). +professor(p52). +professor(p53). +professor(p54). +professor(p55). +professor(p56). +professor(p57). +professor(p58). +professor(p59). +professor(p60). +professor(p61). +professor(p62). +professor(p63). + + +course(c0,p2). +course(c1,p4). +course(c2,p25). +course(c3,p32). +course(c4,p45). +course(c5,p23). +course(c6,p50). +course(c7,p14). +course(c8,p31). +course(c9,p1). +course(c10,p23). +course(c11,p58). +course(c12,p18). +course(c13,p27). +course(c14,p29). +course(c15,p21). +course(c16,p37). +course(c17,p13). +course(c18,p19). +course(c19,p17). +course(c20,p8). +course(c21,p15). +course(c22,p22). +course(c23,p7). +course(c24,p55). +course(c25,p63). +course(c26,p28). +course(c27,p4). +course(c28,p41). +course(c29,p10). +course(c30,p38). +course(c31,p44). +course(c32,p12). +course(c33,p59). +course(c34,p9). +course(c35,p52). +course(c36,p26). +course(c37,p57). +course(c38,p1). +course(c39,p53). +course(c40,p60). +course(c41,p24). +course(c42,p35). +course(c43,p9). +course(c44,p51). +course(c45,p62). +course(c46,p37). +course(c47,p27). +course(c48,p20). +course(c49,p50). +course(c50,p43). +course(c51,p34). +course(c52,p0). +course(c53,p59). +course(c54,p40). +course(c55,p56). +course(c56,p61). +course(c57,p57). +course(c58,p45). +course(c59,p36). +course(c60,p53). +course(c61,p20). +course(c62,p3). +course(c63,p8). +course(c64,p18). +course(c65,p11). +course(c66,p63). +course(c67,p32). +course(c68,p5). +course(c69,p3). +course(c70,p16). +course(c71,p11). +course(c72,p21). +course(c73,p48). +course(c74,p6). +course(c75,p13). +course(c76,p49). +course(c77,p44). +course(c78,p25). +course(c79,p60). +course(c80,p19). +course(c81,p43). +course(c82,p35). +course(c83,p0). +course(c84,p47). +course(c85,p62). +course(c86,p2). +course(c87,p29). +course(c88,p36). +course(c89,p42). +course(c90,p46). +course(c91,p30). +course(c92,p42). +course(c93,p47). +course(c94,p38). +course(c95,p5). +course(c96,p56). +course(c97,p15). +course(c98,p30). +course(c99,p58). +course(c100,p54). +course(c101,p41). +course(c102,p55). +course(c103,p12). +course(c104,p24). +course(c105,p7). +course(c106,p16). +course(c107,p51). +course(c108,p26). +course(c109,p33). +course(c110,p40). +course(c111,p48). +course(c112,p61). +course(c113,p10). +course(c114,p52). +course(c115,p49). +course(c116,p17). +course(c117,p28). +course(c118,p34). +course(c119,p46). +course(c120,p33). +course(c121,p22). +course(c122,p31). +course(c123,p14). +course(c124,p54). +course(c125,p39). +course(c126,p39). +course(c127,p6). + + +student(s0). +student(s1). +student(s2). +student(s3). +student(s4). +student(s5). +student(s6). +student(s7). +student(s8). +student(s9). +student(s10). +student(s11). +student(s12). +student(s13). +student(s14). +student(s15). +student(s16). +student(s17). +student(s18). +student(s19). +student(s20). +student(s21). +student(s22). +student(s23). +student(s24). +student(s25). +student(s26). +student(s27). +student(s28). +student(s29). +student(s30). +student(s31). +student(s32). +student(s33). +student(s34). +student(s35). +student(s36). +student(s37). +student(s38). +student(s39). +student(s40). +student(s41). +student(s42). +student(s43). +student(s44). +student(s45). +student(s46). +student(s47). +student(s48). +student(s49). +student(s50). +student(s51). +student(s52). +student(s53). +student(s54). +student(s55). +student(s56). +student(s57). +student(s58). +student(s59). +student(s60). +student(s61). +student(s62). +student(s63). +student(s64). +student(s65). +student(s66). +student(s67). +student(s68). +student(s69). +student(s70). +student(s71). +student(s72). +student(s73). +student(s74). +student(s75). +student(s76). +student(s77). +student(s78). +student(s79). +student(s80). +student(s81). +student(s82). +student(s83). +student(s84). +student(s85). +student(s86). +student(s87). +student(s88). +student(s89). +student(s90). +student(s91). +student(s92). +student(s93). +student(s94). +student(s95). +student(s96). +student(s97). +student(s98). +student(s99). +student(s100). +student(s101). +student(s102). +student(s103). +student(s104). +student(s105). +student(s106). +student(s107). +student(s108). +student(s109). +student(s110). +student(s111). +student(s112). +student(s113). +student(s114). +student(s115). +student(s116). +student(s117). +student(s118). +student(s119). +student(s120). +student(s121). +student(s122). +student(s123). +student(s124). +student(s125). +student(s126). +student(s127). +student(s128). +student(s129). +student(s130). +student(s131). +student(s132). +student(s133). +student(s134). +student(s135). +student(s136). +student(s137). +student(s138). +student(s139). +student(s140). +student(s141). +student(s142). +student(s143). +student(s144). +student(s145). +student(s146). +student(s147). +student(s148). +student(s149). +student(s150). +student(s151). +student(s152). +student(s153). +student(s154). +student(s155). +student(s156). +student(s157). +student(s158). +student(s159). +student(s160). +student(s161). +student(s162). +student(s163). +student(s164). +student(s165). +student(s166). +student(s167). +student(s168). +student(s169). +student(s170). +student(s171). +student(s172). +student(s173). +student(s174). +student(s175). +student(s176). +student(s177). +student(s178). +student(s179). +student(s180). +student(s181). +student(s182). +student(s183). +student(s184). +student(s185). +student(s186). +student(s187). +student(s188). +student(s189). +student(s190). +student(s191). +student(s192). +student(s193). +student(s194). +student(s195). +student(s196). +student(s197). +student(s198). +student(s199). +student(s200). +student(s201). +student(s202). +student(s203). +student(s204). +student(s205). +student(s206). +student(s207). +student(s208). +student(s209). +student(s210). +student(s211). +student(s212). +student(s213). +student(s214). +student(s215). +student(s216). +student(s217). +student(s218). +student(s219). +student(s220). +student(s221). +student(s222). +student(s223). +student(s224). +student(s225). +student(s226). +student(s227). +student(s228). +student(s229). +student(s230). +student(s231). +student(s232). +student(s233). +student(s234). +student(s235). +student(s236). +student(s237). +student(s238). +student(s239). +student(s240). +student(s241). +student(s242). +student(s243). +student(s244). +student(s245). +student(s246). +student(s247). +student(s248). +student(s249). +student(s250). +student(s251). +student(s252). +student(s253). +student(s254). +student(s255). +student(s256). +student(s257). +student(s258). +student(s259). +student(s260). +student(s261). +student(s262). +student(s263). +student(s264). +student(s265). +student(s266). +student(s267). +student(s268). +student(s269). +student(s270). +student(s271). +student(s272). +student(s273). +student(s274). +student(s275). +student(s276). +student(s277). +student(s278). +student(s279). +student(s280). +student(s281). +student(s282). +student(s283). +student(s284). +student(s285). +student(s286). +student(s287). +student(s288). +student(s289). +student(s290). +student(s291). +student(s292). +student(s293). +student(s294). +student(s295). +student(s296). +student(s297). +student(s298). +student(s299). +student(s300). +student(s301). +student(s302). +student(s303). +student(s304). +student(s305). +student(s306). +student(s307). +student(s308). +student(s309). +student(s310). +student(s311). +student(s312). +student(s313). +student(s314). +student(s315). +student(s316). +student(s317). +student(s318). +student(s319). +student(s320). +student(s321). +student(s322). +student(s323). +student(s324). +student(s325). +student(s326). +student(s327). +student(s328). +student(s329). +student(s330). +student(s331). +student(s332). +student(s333). +student(s334). +student(s335). +student(s336). +student(s337). +student(s338). +student(s339). +student(s340). +student(s341). +student(s342). +student(s343). +student(s344). +student(s345). +student(s346). +student(s347). +student(s348). +student(s349). +student(s350). +student(s351). +student(s352). +student(s353). +student(s354). +student(s355). +student(s356). +student(s357). +student(s358). +student(s359). +student(s360). +student(s361). +student(s362). +student(s363). +student(s364). +student(s365). +student(s366). +student(s367). +student(s368). +student(s369). +student(s370). +student(s371). +student(s372). +student(s373). +student(s374). +student(s375). +student(s376). +student(s377). +student(s378). +student(s379). +student(s380). +student(s381). +student(s382). +student(s383). +student(s384). +student(s385). +student(s386). +student(s387). +student(s388). +student(s389). +student(s390). +student(s391). +student(s392). +student(s393). +student(s394). +student(s395). +student(s396). +student(s397). +student(s398). +student(s399). +student(s400). +student(s401). +student(s402). +student(s403). +student(s404). +student(s405). +student(s406). +student(s407). +student(s408). +student(s409). +student(s410). +student(s411). +student(s412). +student(s413). +student(s414). +student(s415). +student(s416). +student(s417). +student(s418). +student(s419). +student(s420). +student(s421). +student(s422). +student(s423). +student(s424). +student(s425). +student(s426). +student(s427). +student(s428). +student(s429). +student(s430). +student(s431). +student(s432). +student(s433). +student(s434). +student(s435). +student(s436). +student(s437). +student(s438). +student(s439). +student(s440). +student(s441). +student(s442). +student(s443). +student(s444). +student(s445). +student(s446). +student(s447). +student(s448). +student(s449). +student(s450). +student(s451). +student(s452). +student(s453). +student(s454). +student(s455). +student(s456). +student(s457). +student(s458). +student(s459). +student(s460). +student(s461). +student(s462). +student(s463). +student(s464). +student(s465). +student(s466). +student(s467). +student(s468). +student(s469). +student(s470). +student(s471). +student(s472). +student(s473). +student(s474). +student(s475). +student(s476). +student(s477). +student(s478). +student(s479). +student(s480). +student(s481). +student(s482). +student(s483). +student(s484). +student(s485). +student(s486). +student(s487). +student(s488). +student(s489). +student(s490). +student(s491). +student(s492). +student(s493). +student(s494). +student(s495). +student(s496). +student(s497). +student(s498). +student(s499). +student(s500). +student(s501). +student(s502). +student(s503). +student(s504). +student(s505). +student(s506). +student(s507). +student(s508). +student(s509). +student(s510). +student(s511). +student(s512). +student(s513). +student(s514). +student(s515). +student(s516). +student(s517). +student(s518). +student(s519). +student(s520). +student(s521). +student(s522). +student(s523). +student(s524). +student(s525). +student(s526). +student(s527). +student(s528). +student(s529). +student(s530). +student(s531). +student(s532). +student(s533). +student(s534). +student(s535). +student(s536). +student(s537). +student(s538). +student(s539). +student(s540). +student(s541). +student(s542). +student(s543). +student(s544). +student(s545). +student(s546). +student(s547). +student(s548). +student(s549). +student(s550). +student(s551). +student(s552). +student(s553). +student(s554). +student(s555). +student(s556). +student(s557). +student(s558). +student(s559). +student(s560). +student(s561). +student(s562). +student(s563). +student(s564). +student(s565). +student(s566). +student(s567). +student(s568). +student(s569). +student(s570). +student(s571). +student(s572). +student(s573). +student(s574). +student(s575). +student(s576). +student(s577). +student(s578). +student(s579). +student(s580). +student(s581). +student(s582). +student(s583). +student(s584). +student(s585). +student(s586). +student(s587). +student(s588). +student(s589). +student(s590). +student(s591). +student(s592). +student(s593). +student(s594). +student(s595). +student(s596). +student(s597). +student(s598). +student(s599). +student(s600). +student(s601). +student(s602). +student(s603). +student(s604). +student(s605). +student(s606). +student(s607). +student(s608). +student(s609). +student(s610). +student(s611). +student(s612). +student(s613). +student(s614). +student(s615). +student(s616). +student(s617). +student(s618). +student(s619). +student(s620). +student(s621). +student(s622). +student(s623). +student(s624). +student(s625). +student(s626). +student(s627). +student(s628). +student(s629). +student(s630). +student(s631). +student(s632). +student(s633). +student(s634). +student(s635). +student(s636). +student(s637). +student(s638). +student(s639). +student(s640). +student(s641). +student(s642). +student(s643). +student(s644). +student(s645). +student(s646). +student(s647). +student(s648). +student(s649). +student(s650). +student(s651). +student(s652). +student(s653). +student(s654). +student(s655). +student(s656). +student(s657). +student(s658). +student(s659). +student(s660). +student(s661). +student(s662). +student(s663). +student(s664). +student(s665). +student(s666). +student(s667). +student(s668). +student(s669). +student(s670). +student(s671). +student(s672). +student(s673). +student(s674). +student(s675). +student(s676). +student(s677). +student(s678). +student(s679). +student(s680). +student(s681). +student(s682). +student(s683). +student(s684). +student(s685). +student(s686). +student(s687). +student(s688). +student(s689). +student(s690). +student(s691). +student(s692). +student(s693). +student(s694). +student(s695). +student(s696). +student(s697). +student(s698). +student(s699). +student(s700). +student(s701). +student(s702). +student(s703). +student(s704). +student(s705). +student(s706). +student(s707). +student(s708). +student(s709). +student(s710). +student(s711). +student(s712). +student(s713). +student(s714). +student(s715). +student(s716). +student(s717). +student(s718). +student(s719). +student(s720). +student(s721). +student(s722). +student(s723). +student(s724). +student(s725). +student(s726). +student(s727). +student(s728). +student(s729). +student(s730). +student(s731). +student(s732). +student(s733). +student(s734). +student(s735). +student(s736). +student(s737). +student(s738). +student(s739). +student(s740). +student(s741). +student(s742). +student(s743). +student(s744). +student(s745). +student(s746). +student(s747). +student(s748). +student(s749). +student(s750). +student(s751). +student(s752). +student(s753). +student(s754). +student(s755). +student(s756). +student(s757). +student(s758). +student(s759). +student(s760). +student(s761). +student(s762). +student(s763). +student(s764). +student(s765). +student(s766). +student(s767). +student(s768). +student(s769). +student(s770). +student(s771). +student(s772). +student(s773). +student(s774). +student(s775). +student(s776). +student(s777). +student(s778). +student(s779). +student(s780). +student(s781). +student(s782). +student(s783). +student(s784). +student(s785). +student(s786). +student(s787). +student(s788). +student(s789). +student(s790). +student(s791). +student(s792). +student(s793). +student(s794). +student(s795). +student(s796). +student(s797). +student(s798). +student(s799). +student(s800). +student(s801). +student(s802). +student(s803). +student(s804). +student(s805). +student(s806). +student(s807). +student(s808). +student(s809). +student(s810). +student(s811). +student(s812). +student(s813). +student(s814). +student(s815). +student(s816). +student(s817). +student(s818). +student(s819). +student(s820). +student(s821). +student(s822). +student(s823). +student(s824). +student(s825). +student(s826). +student(s827). +student(s828). +student(s829). +student(s830). +student(s831). +student(s832). +student(s833). +student(s834). +student(s835). +student(s836). +student(s837). +student(s838). +student(s839). +student(s840). +student(s841). +student(s842). +student(s843). +student(s844). +student(s845). +student(s846). +student(s847). +student(s848). +student(s849). +student(s850). +student(s851). +student(s852). +student(s853). +student(s854). +student(s855). +student(s856). +student(s857). +student(s858). +student(s859). +student(s860). +student(s861). +student(s862). +student(s863). +student(s864). +student(s865). +student(s866). +student(s867). +student(s868). +student(s869). +student(s870). +student(s871). +student(s872). +student(s873). +student(s874). +student(s875). +student(s876). +student(s877). +student(s878). +student(s879). +student(s880). +student(s881). +student(s882). +student(s883). +student(s884). +student(s885). +student(s886). +student(s887). +student(s888). +student(s889). +student(s890). +student(s891). +student(s892). +student(s893). +student(s894). +student(s895). +student(s896). +student(s897). +student(s898). +student(s899). +student(s900). +student(s901). +student(s902). +student(s903). +student(s904). +student(s905). +student(s906). +student(s907). +student(s908). +student(s909). +student(s910). +student(s911). +student(s912). +student(s913). +student(s914). +student(s915). +student(s916). +student(s917). +student(s918). +student(s919). +student(s920). +student(s921). +student(s922). +student(s923). +student(s924). +student(s925). +student(s926). +student(s927). +student(s928). +student(s929). +student(s930). +student(s931). +student(s932). +student(s933). +student(s934). +student(s935). +student(s936). +student(s937). +student(s938). +student(s939). +student(s940). +student(s941). +student(s942). +student(s943). +student(s944). +student(s945). +student(s946). +student(s947). +student(s948). +student(s949). +student(s950). +student(s951). +student(s952). +student(s953). +student(s954). +student(s955). +student(s956). +student(s957). +student(s958). +student(s959). +student(s960). +student(s961). +student(s962). +student(s963). +student(s964). +student(s965). +student(s966). +student(s967). +student(s968). +student(s969). +student(s970). +student(s971). +student(s972). +student(s973). +student(s974). +student(s975). +student(s976). +student(s977). +student(s978). +student(s979). +student(s980). +student(s981). +student(s982). +student(s983). +student(s984). +student(s985). +student(s986). +student(s987). +student(s988). +student(s989). +student(s990). +student(s991). +student(s992). +student(s993). +student(s994). +student(s995). +student(s996). +student(s997). +student(s998). +student(s999). +student(s1000). +student(s1001). +student(s1002). +student(s1003). +student(s1004). +student(s1005). +student(s1006). +student(s1007). +student(s1008). +student(s1009). +student(s1010). +student(s1011). +student(s1012). +student(s1013). +student(s1014). +student(s1015). +student(s1016). +student(s1017). +student(s1018). +student(s1019). +student(s1020). +student(s1021). +student(s1022). +student(s1023). + + +registration(r0,c65,s0). +registration(r1,c18,s0). +registration(r2,c39,s0). +registration(r3,c89,s1). +registration(r4,c64,s1). +registration(r5,c54,s1). +registration(r6,c1,s1). +registration(r7,c97,s2). +registration(r8,c12,s2). +registration(r9,c38,s2). +registration(r10,c45,s2). +registration(r11,c24,s3). +registration(r12,c28,s3). +registration(r13,c98,s3). +registration(r14,c118,s3). +registration(r15,c72,s4). +registration(r16,c81,s4). +registration(r17,c94,s4). +registration(r18,c11,s4). +registration(r19,c26,s5). +registration(r20,c58,s5). +registration(r21,c25,s5). +registration(r22,c86,s6). +registration(r23,c91,s6). +registration(r24,c57,s6). +registration(r25,c18,s6). +registration(r26,c24,s7). +registration(r27,c67,s7). +registration(r28,c42,s7). +registration(r29,c38,s8). +registration(r30,c42,s8). +registration(r31,c21,s8). +registration(r32,c120,s9). +registration(r33,c33,s9). +registration(r34,c71,s9). +registration(r35,c24,s10). +registration(r36,c76,s10). +registration(r37,c2,s10). +registration(r38,c29,s11). +registration(r39,c94,s11). +registration(r40,c63,s11). +registration(r41,c21,s12). +registration(r42,c39,s12). +registration(r43,c120,s12). +registration(r44,c65,s13). +registration(r45,c70,s13). +registration(r46,c124,s13). +registration(r47,c101,s14). +registration(r48,c18,s14). +registration(r49,c21,s14). +registration(r50,c89,s15). +registration(r51,c115,s15). +registration(r52,c114,s15). +registration(r53,c94,s16). +registration(r54,c56,s16). +registration(r55,c45,s16). +registration(r56,c83,s17). +registration(r57,c126,s17). +registration(r58,c57,s17). +registration(r59,c73,s17). +registration(r60,c41,s18). +registration(r61,c112,s18). +registration(r62,c113,s18). +registration(r63,c51,s19). +registration(r64,c27,s19). +registration(r65,c38,s19). +registration(r66,c11,s19). +registration(r67,c49,s20). +registration(r68,c26,s20). +registration(r69,c6,s20). +registration(r70,c116,s20). +registration(r71,c117,s21). +registration(r72,c21,s21). +registration(r73,c91,s21). +registration(r74,c10,s22). +registration(r75,c53,s22). +registration(r76,c43,s22). +registration(r77,c102,s23). +registration(r78,c113,s23). +registration(r79,c125,s23). +registration(r80,c109,s24). +registration(r81,c80,s24). +registration(r82,c112,s24). +registration(r83,c4,s24). +registration(r84,c59,s24). +registration(r85,c35,s25). +registration(r86,c18,s25). +registration(r87,c73,s25). +registration(r88,c79,s26). +registration(r89,c86,s26). +registration(r90,c33,s26). +registration(r91,c55,s27). +registration(r92,c37,s27). +registration(r93,c31,s27). +registration(r94,c48,s27). +registration(r95,c49,s28). +registration(r96,c13,s28). +registration(r97,c8,s28). +registration(r98,c126,s28). +registration(r99,c119,s28). +registration(r100,c24,s29). +registration(r101,c115,s29). +registration(r102,c73,s29). +registration(r103,c9,s29). +registration(r104,c21,s30). +registration(r105,c71,s30). +registration(r106,c113,s30). +registration(r107,c69,s30). +registration(r108,c86,s31). +registration(r109,c94,s31). +registration(r110,c27,s31). +registration(r111,c104,s32). +registration(r112,c48,s32). +registration(r113,c77,s32). +registration(r114,c54,s32). +registration(r115,c93,s33). +registration(r116,c105,s33). +registration(r117,c11,s33). +registration(r118,c10,s33). +registration(r119,c107,s34). +registration(r120,c121,s34). +registration(r121,c34,s34). +registration(r122,c44,s35). +registration(r123,c105,s35). +registration(r124,c16,s35). +registration(r125,c1,s36). +registration(r126,c107,s36). +registration(r127,c63,s36). +registration(r128,c29,s37). +registration(r129,c99,s37). +registration(r130,c58,s37). +registration(r131,c107,s38). +registration(r132,c18,s38). +registration(r133,c84,s38). +registration(r134,c50,s38). +registration(r135,c11,s39). +registration(r136,c28,s39). +registration(r137,c25,s39). +registration(r138,c39,s39). +registration(r139,c5,s39). +registration(r140,c73,s40). +registration(r141,c99,s40). +registration(r142,c71,s40). +registration(r143,c88,s41). +registration(r144,c55,s41). +registration(r145,c124,s41). +registration(r146,c59,s42). +registration(r147,c33,s42). +registration(r148,c101,s42). +registration(r149,c30,s42). +registration(r150,c29,s43). +registration(r151,c82,s43). +registration(r152,c10,s43). +registration(r153,c45,s44). +registration(r154,c64,s44). +registration(r155,c90,s44). +registration(r156,c113,s45). +registration(r157,c69,s45). +registration(r158,c1,s45). +registration(r159,c74,s46). +registration(r160,c89,s46). +registration(r161,c19,s46). +registration(r162,c109,s47). +registration(r163,c120,s47). +registration(r164,c33,s47). +registration(r165,c93,s48). +registration(r166,c105,s48). +registration(r167,c0,s48). +registration(r168,c31,s49). +registration(r169,c84,s49). +registration(r170,c65,s49). +registration(r171,c104,s49). +registration(r172,c88,s50). +registration(r173,c67,s50). +registration(r174,c64,s50). +registration(r175,c30,s50). +registration(r176,c87,s51). +registration(r177,c32,s51). +registration(r178,c42,s51). +registration(r179,c3,s52). +registration(r180,c56,s52). +registration(r181,c43,s52). +registration(r182,c35,s53). +registration(r183,c75,s53). +registration(r184,c108,s53). +registration(r185,c85,s54). +registration(r186,c63,s54). +registration(r187,c95,s54). +registration(r188,c50,s55). +registration(r189,c5,s55). +registration(r190,c11,s55). +registration(r191,c98,s56). +registration(r192,c122,s56). +registration(r193,c46,s56). +registration(r194,c99,s57). +registration(r195,c75,s57). +registration(r196,c57,s57). +registration(r197,c111,s57). +registration(r198,c16,s58). +registration(r199,c39,s58). +registration(r200,c82,s58). +registration(r201,c117,s59). +registration(r202,c4,s59). +registration(r203,c55,s59). +registration(r204,c13,s60). +registration(r205,c116,s60). +registration(r206,c14,s60). +registration(r207,c64,s61). +registration(r208,c88,s61). +registration(r209,c95,s61). +registration(r210,c65,s62). +registration(r211,c113,s62). +registration(r212,c118,s62). +registration(r213,c88,s62). +registration(r214,c1,s63). +registration(r215,c70,s63). +registration(r216,c102,s63). +registration(r217,c118,s64). +registration(r218,c24,s64). +registration(r219,c61,s64). +registration(r220,c50,s65). +registration(r221,c53,s65). +registration(r222,c27,s65). +registration(r223,c41,s66). +registration(r224,c92,s66). +registration(r225,c112,s66). +registration(r226,c48,s67). +registration(r227,c84,s67). +registration(r228,c14,s67). +registration(r229,c80,s68). +registration(r230,c24,s68). +registration(r231,c16,s68). +registration(r232,c37,s68). +registration(r233,c8,s69). +registration(r234,c106,s69). +registration(r235,c80,s69). +registration(r236,c71,s70). +registration(r237,c17,s70). +registration(r238,c20,s70). +registration(r239,c70,s71). +registration(r240,c43,s71). +registration(r241,c17,s71). +registration(r242,c59,s71). +registration(r243,c10,s72). +registration(r244,c127,s72). +registration(r245,c54,s72). +registration(r246,c10,s73). +registration(r247,c74,s73). +registration(r248,c88,s73). +registration(r249,c112,s74). +registration(r250,c53,s74). +registration(r251,c32,s74). +registration(r252,c31,s74). +registration(r253,c127,s75). +registration(r254,c111,s75). +registration(r255,c34,s75). +registration(r256,c52,s76). +registration(r257,c106,s76). +registration(r258,c46,s76). +registration(r259,c91,s77). +registration(r260,c59,s77). +registration(r261,c95,s77). +registration(r262,c106,s78). +registration(r263,c104,s78). +registration(r264,c44,s78). +registration(r265,c55,s79). +registration(r266,c111,s79). +registration(r267,c113,s79). +registration(r268,c96,s79). +registration(r269,c18,s80). +registration(r270,c44,s80). +registration(r271,c118,s80). +registration(r272,c118,s81). +registration(r273,c35,s81). +registration(r274,c119,s81). +registration(r275,c43,s82). +registration(r276,c55,s82). +registration(r277,c9,s82). +registration(r278,c100,s83). +registration(r279,c17,s83). +registration(r280,c70,s83). +registration(r281,c48,s83). +registration(r282,c57,s84). +registration(r283,c53,s84). +registration(r284,c86,s84). +registration(r285,c69,s85). +registration(r286,c67,s85). +registration(r287,c75,s85). +registration(r288,c93,s86). +registration(r289,c124,s86). +registration(r290,c27,s86). +registration(r291,c80,s86). +registration(r292,c51,s86). +registration(r293,c72,s87). +registration(r294,c94,s87). +registration(r295,c14,s87). +registration(r296,c25,s87). +registration(r297,c73,s88). +registration(r298,c124,s88). +registration(r299,c126,s88). +registration(r300,c77,s89). +registration(r301,c99,s89). +registration(r302,c116,s89). +registration(r303,c24,s89). +registration(r304,c89,s90). +registration(r305,c6,s90). +registration(r306,c17,s90). +registration(r307,c97,s91). +registration(r308,c66,s91). +registration(r309,c45,s91). +registration(r310,c62,s92). +registration(r311,c46,s92). +registration(r312,c114,s92). +registration(r313,c80,s93). +registration(r314,c1,s93). +registration(r315,c107,s93). +registration(r316,c52,s94). +registration(r317,c98,s94). +registration(r318,c24,s94). +registration(r319,c38,s94). +registration(r320,c115,s95). +registration(r321,c26,s95). +registration(r322,c107,s95). +registration(r323,c100,s95). +registration(r324,c19,s96). +registration(r325,c118,s96). +registration(r326,c98,s96). +registration(r327,c38,s97). +registration(r328,c18,s97). +registration(r329,c54,s97). +registration(r330,c82,s97). +registration(r331,c119,s98). +registration(r332,c67,s98). +registration(r333,c90,s98). +registration(r334,c69,s99). +registration(r335,c45,s99). +registration(r336,c97,s99). +registration(r337,c121,s99). +registration(r338,c11,s100). +registration(r339,c55,s100). +registration(r340,c95,s100). +registration(r341,c75,s101). +registration(r342,c11,s101). +registration(r343,c55,s101). +registration(r344,c31,s101). +registration(r345,c117,s102). +registration(r346,c3,s102). +registration(r347,c7,s102). +registration(r348,c60,s102). +registration(r349,c33,s103). +registration(r350,c103,s103). +registration(r351,c31,s103). +registration(r352,c122,s104). +registration(r353,c97,s104). +registration(r354,c113,s104). +registration(r355,c80,s104). +registration(r356,c59,s105). +registration(r357,c32,s105). +registration(r358,c76,s105). +registration(r359,c43,s106). +registration(r360,c70,s106). +registration(r361,c40,s106). +registration(r362,c95,s107). +registration(r363,c9,s107). +registration(r364,c113,s107). +registration(r365,c126,s107). +registration(r366,c19,s108). +registration(r367,c26,s108). +registration(r368,c10,s108). +registration(r369,c114,s109). +registration(r370,c110,s109). +registration(r371,c83,s109). +registration(r372,c55,s110). +registration(r373,c16,s110). +registration(r374,c43,s110). +registration(r375,c103,s111). +registration(r376,c104,s111). +registration(r377,c46,s111). +registration(r378,c90,s112). +registration(r379,c116,s112). +registration(r380,c103,s112). +registration(r381,c72,s113). +registration(r382,c90,s113). +registration(r383,c54,s113). +registration(r384,c43,s114). +registration(r385,c105,s114). +registration(r386,c114,s114). +registration(r387,c46,s115). +registration(r388,c41,s115). +registration(r389,c40,s115). +registration(r390,c73,s115). +registration(r391,c60,s115). +registration(r392,c88,s116). +registration(r393,c62,s116). +registration(r394,c2,s116). +registration(r395,c106,s117). +registration(r396,c105,s117). +registration(r397,c83,s117). +registration(r398,c72,s118). +registration(r399,c18,s118). +registration(r400,c23,s118). +registration(r401,c91,s118). +registration(r402,c69,s119). +registration(r403,c48,s119). +registration(r404,c74,s119). +registration(r405,c60,s120). +registration(r406,c39,s120). +registration(r407,c84,s120). +registration(r408,c124,s121). +registration(r409,c109,s121). +registration(r410,c24,s121). +registration(r411,c41,s121). +registration(r412,c79,s122). +registration(r413,c43,s122). +registration(r414,c46,s122). +registration(r415,c24,s122). +registration(r416,c74,s123). +registration(r417,c64,s123). +registration(r418,c94,s123). +registration(r419,c83,s123). +registration(r420,c33,s124). +registration(r421,c47,s124). +registration(r422,c101,s124). +registration(r423,c47,s125). +registration(r424,c87,s125). +registration(r425,c121,s125). +registration(r426,c76,s126). +registration(r427,c87,s126). +registration(r428,c79,s126). +registration(r429,c105,s127). +registration(r430,c88,s127). +registration(r431,c110,s127). +registration(r432,c26,s128). +registration(r433,c9,s128). +registration(r434,c31,s128). +registration(r435,c104,s129). +registration(r436,c114,s129). +registration(r437,c127,s129). +registration(r438,c116,s130). +registration(r439,c28,s130). +registration(r440,c115,s130). +registration(r441,c82,s130). +registration(r442,c9,s131). +registration(r443,c90,s131). +registration(r444,c76,s131). +registration(r445,c25,s132). +registration(r446,c76,s132). +registration(r447,c42,s132). +registration(r448,c18,s132). +registration(r449,c59,s133). +registration(r450,c127,s133). +registration(r451,c109,s133). +registration(r452,c119,s133). +registration(r453,c1,s134). +registration(r454,c74,s134). +registration(r455,c26,s134). +registration(r456,c26,s135). +registration(r457,c101,s135). +registration(r458,c1,s135). +registration(r459,c2,s135). +registration(r460,c104,s136). +registration(r461,c4,s136). +registration(r462,c72,s136). +registration(r463,c21,s137). +registration(r464,c102,s137). +registration(r465,c57,s137). +registration(r466,c98,s138). +registration(r467,c16,s138). +registration(r468,c66,s138). +registration(r469,c65,s139). +registration(r470,c100,s139). +registration(r471,c46,s139). +registration(r472,c49,s140). +registration(r473,c36,s140). +registration(r474,c118,s140). +registration(r475,c16,s141). +registration(r476,c0,s141). +registration(r477,c98,s141). +registration(r478,c87,s141). +registration(r479,c7,s142). +registration(r480,c6,s142). +registration(r481,c34,s142). +registration(r482,c53,s143). +registration(r483,c94,s143). +registration(r484,c30,s143). +registration(r485,c1,s143). +registration(r486,c116,s144). +registration(r487,c82,s144). +registration(r488,c119,s144). +registration(r489,c90,s144). +registration(r490,c112,s145). +registration(r491,c110,s145). +registration(r492,c55,s145). +registration(r493,c45,s145). +registration(r494,c61,s146). +registration(r495,c116,s146). +registration(r496,c63,s146). +registration(r497,c94,s147). +registration(r498,c63,s147). +registration(r499,c45,s147). +registration(r500,c78,s148). +registration(r501,c93,s148). +registration(r502,c43,s148). +registration(r503,c59,s148). +registration(r504,c104,s149). +registration(r505,c75,s149). +registration(r506,c76,s149). +registration(r507,c67,s150). +registration(r508,c29,s150). +registration(r509,c51,s150). +registration(r510,c34,s150). +registration(r511,c87,s151). +registration(r512,c46,s151). +registration(r513,c54,s151). +registration(r514,c108,s151). +registration(r515,c69,s152). +registration(r516,c41,s152). +registration(r517,c0,s152). +registration(r518,c45,s153). +registration(r519,c8,s153). +registration(r520,c49,s153). +registration(r521,c92,s154). +registration(r522,c0,s154). +registration(r523,c34,s154). +registration(r524,c110,s155). +registration(r525,c115,s155). +registration(r526,c68,s155). +registration(r527,c54,s155). +registration(r528,c65,s156). +registration(r529,c87,s156). +registration(r530,c112,s156). +registration(r531,c31,s157). +registration(r532,c25,s157). +registration(r533,c54,s157). +registration(r534,c69,s157). +registration(r535,c53,s158). +registration(r536,c68,s158). +registration(r537,c30,s158). +registration(r538,c39,s159). +registration(r539,c78,s159). +registration(r540,c110,s159). +registration(r541,c42,s159). +registration(r542,c47,s160). +registration(r543,c81,s160). +registration(r544,c88,s160). +registration(r545,c29,s161). +registration(r546,c45,s161). +registration(r547,c125,s161). +registration(r548,c109,s161). +registration(r549,c113,s162). +registration(r550,c81,s162). +registration(r551,c3,s162). +registration(r552,c107,s162). +registration(r553,c28,s163). +registration(r554,c48,s163). +registration(r555,c53,s163). +registration(r556,c83,s164). +registration(r557,c112,s164). +registration(r558,c100,s164). +registration(r559,c82,s165). +registration(r560,c7,s165). +registration(r561,c104,s165). +registration(r562,c58,s166). +registration(r563,c24,s166). +registration(r564,c87,s166). +registration(r565,c3,s167). +registration(r566,c124,s167). +registration(r567,c55,s167). +registration(r568,c40,s168). +registration(r569,c67,s168). +registration(r570,c85,s168). +registration(r571,c14,s169). +registration(r572,c86,s169). +registration(r573,c95,s169). +registration(r574,c81,s170). +registration(r575,c22,s170). +registration(r576,c24,s170). +registration(r577,c87,s170). +registration(r578,c9,s171). +registration(r579,c25,s171). +registration(r580,c64,s171). +registration(r581,c121,s172). +registration(r582,c99,s172). +registration(r583,c38,s172). +registration(r584,c41,s173). +registration(r585,c117,s173). +registration(r586,c81,s173). +registration(r587,c122,s174). +registration(r588,c93,s174). +registration(r589,c27,s174). +registration(r590,c42,s174). +registration(r591,c10,s175). +registration(r592,c107,s175). +registration(r593,c110,s175). +registration(r594,c4,s176). +registration(r595,c75,s176). +registration(r596,c116,s176). +registration(r597,c33,s176). +registration(r598,c46,s177). +registration(r599,c96,s177). +registration(r600,c73,s177). +registration(r601,c45,s178). +registration(r602,c36,s178). +registration(r603,c82,s178). +registration(r604,c71,s179). +registration(r605,c25,s179). +registration(r606,c106,s179). +registration(r607,c19,s179). +registration(r608,c41,s180). +registration(r609,c72,s180). +registration(r610,c85,s180). +registration(r611,c64,s181). +registration(r612,c67,s181). +registration(r613,c4,s181). +registration(r614,c79,s182). +registration(r615,c115,s182). +registration(r616,c92,s182). +registration(r617,c11,s183). +registration(r618,c81,s183). +registration(r619,c58,s183). +registration(r620,c42,s183). +registration(r621,c46,s184). +registration(r622,c124,s184). +registration(r623,c48,s184). +registration(r624,c73,s185). +registration(r625,c103,s185). +registration(r626,c80,s185). +registration(r627,c123,s186). +registration(r628,c37,s186). +registration(r629,c4,s186). +registration(r630,c69,s187). +registration(r631,c18,s187). +registration(r632,c124,s187). +registration(r633,c76,s188). +registration(r634,c54,s188). +registration(r635,c55,s188). +registration(r636,c65,s189). +registration(r637,c13,s189). +registration(r638,c99,s189). +registration(r639,c75,s190). +registration(r640,c121,s190). +registration(r641,c51,s190). +registration(r642,c119,s191). +registration(r643,c69,s191). +registration(r644,c93,s191). +registration(r645,c13,s192). +registration(r646,c68,s192). +registration(r647,c73,s192). +registration(r648,c20,s192). +registration(r649,c87,s193). +registration(r650,c37,s193). +registration(r651,c61,s193). +registration(r652,c9,s194). +registration(r653,c82,s194). +registration(r654,c55,s194). +registration(r655,c120,s195). +registration(r656,c82,s195). +registration(r657,c92,s195). +registration(r658,c40,s195). +registration(r659,c61,s196). +registration(r660,c64,s196). +registration(r661,c36,s196). +registration(r662,c106,s197). +registration(r663,c19,s197). +registration(r664,c0,s197). +registration(r665,c34,s197). +registration(r666,c86,s198). +registration(r667,c50,s198). +registration(r668,c89,s198). +registration(r669,c10,s198). +registration(r670,c84,s199). +registration(r671,c37,s199). +registration(r672,c126,s199). +registration(r673,c53,s200). +registration(r674,c35,s200). +registration(r675,c114,s200). +registration(r676,c79,s201). +registration(r677,c114,s201). +registration(r678,c2,s201). +registration(r679,c66,s202). +registration(r680,c29,s202). +registration(r681,c101,s202). +registration(r682,c120,s202). +registration(r683,c123,s203). +registration(r684,c22,s203). +registration(r685,c26,s203). +registration(r686,c77,s204). +registration(r687,c24,s204). +registration(r688,c4,s204). +registration(r689,c90,s204). +registration(r690,c125,s205). +registration(r691,c21,s205). +registration(r692,c55,s205). +registration(r693,c90,s206). +registration(r694,c104,s206). +registration(r695,c121,s206). +registration(r696,c107,s207). +registration(r697,c83,s207). +registration(r698,c48,s207). +registration(r699,c78,s207). +registration(r700,c1,s208). +registration(r701,c17,s208). +registration(r702,c87,s208). +registration(r703,c110,s208). +registration(r704,c19,s209). +registration(r705,c76,s209). +registration(r706,c91,s209). +registration(r707,c95,s210). +registration(r708,c56,s210). +registration(r709,c123,s210). +registration(r710,c17,s211). +registration(r711,c112,s211). +registration(r712,c44,s211). +registration(r713,c20,s212). +registration(r714,c86,s212). +registration(r715,c28,s212). +registration(r716,c111,s213). +registration(r717,c126,s213). +registration(r718,c91,s213). +registration(r719,c75,s213). +registration(r720,c23,s214). +registration(r721,c37,s214). +registration(r722,c88,s214). +registration(r723,c108,s214). +registration(r724,c110,s215). +registration(r725,c108,s215). +registration(r726,c75,s215). +registration(r727,c5,s216). +registration(r728,c79,s216). +registration(r729,c6,s216). +registration(r730,c118,s217). +registration(r731,c103,s217). +registration(r732,c59,s217). +registration(r733,c18,s218). +registration(r734,c92,s218). +registration(r735,c73,s218). +registration(r736,c72,s219). +registration(r737,c48,s219). +registration(r738,c83,s219). +registration(r739,c15,s219). +registration(r740,c57,s220). +registration(r741,c104,s220). +registration(r742,c12,s220). +registration(r743,c123,s221). +registration(r744,c56,s221). +registration(r745,c32,s221). +registration(r746,c38,s221). +registration(r747,c30,s222). +registration(r748,c11,s222). +registration(r749,c98,s222). +registration(r750,c74,s222). +registration(r751,c59,s223). +registration(r752,c66,s223). +registration(r753,c72,s223). +registration(r754,c17,s224). +registration(r755,c34,s224). +registration(r756,c107,s224). +registration(r757,c62,s225). +registration(r758,c111,s225). +registration(r759,c97,s225). +registration(r760,c74,s226). +registration(r761,c52,s226). +registration(r762,c116,s226). +registration(r763,c44,s227). +registration(r764,c64,s227). +registration(r765,c0,s227). +registration(r766,c30,s228). +registration(r767,c61,s228). +registration(r768,c73,s228). +registration(r769,c19,s229). +registration(r770,c88,s229). +registration(r771,c0,s229). +registration(r772,c31,s230). +registration(r773,c108,s230). +registration(r774,c71,s230). +registration(r775,c69,s230). +registration(r776,c72,s231). +registration(r777,c53,s231). +registration(r778,c124,s231). +registration(r779,c71,s232). +registration(r780,c37,s232). +registration(r781,c82,s232). +registration(r782,c126,s233). +registration(r783,c37,s233). +registration(r784,c86,s233). +registration(r785,c116,s233). +registration(r786,c109,s234). +registration(r787,c83,s234). +registration(r788,c18,s234). +registration(r789,c106,s235). +registration(r790,c44,s235). +registration(r791,c66,s235). +registration(r792,c76,s235). +registration(r793,c87,s236). +registration(r794,c85,s236). +registration(r795,c117,s236). +registration(r796,c43,s237). +registration(r797,c110,s237). +registration(r798,c15,s237). +registration(r799,c54,s237). +registration(r800,c91,s238). +registration(r801,c27,s238). +registration(r802,c11,s238). +registration(r803,c98,s239). +registration(r804,c10,s239). +registration(r805,c76,s239). +registration(r806,c32,s240). +registration(r807,c106,s240). +registration(r808,c36,s240). +registration(r809,c85,s240). +registration(r810,c75,s241). +registration(r811,c101,s241). +registration(r812,c28,s241). +registration(r813,c115,s242). +registration(r814,c110,s242). +registration(r815,c46,s242). +registration(r816,c26,s242). +registration(r817,c33,s243). +registration(r818,c36,s243). +registration(r819,c84,s243). +registration(r820,c111,s244). +registration(r821,c97,s244). +registration(r822,c88,s244). +registration(r823,c100,s245). +registration(r824,c125,s245). +registration(r825,c29,s245). +registration(r826,c8,s246). +registration(r827,c0,s246). +registration(r828,c40,s246). +registration(r829,c114,s247). +registration(r830,c66,s247). +registration(r831,c109,s247). +registration(r832,c96,s247). +registration(r833,c92,s248). +registration(r834,c47,s248). +registration(r835,c115,s248). +registration(r836,c21,s249). +registration(r837,c27,s249). +registration(r838,c35,s249). +registration(r839,c17,s250). +registration(r840,c78,s250). +registration(r841,c115,s250). +registration(r842,c87,s250). +registration(r843,c64,s251). +registration(r844,c48,s251). +registration(r845,c52,s251). +registration(r846,c53,s252). +registration(r847,c6,s252). +registration(r848,c23,s252). +registration(r849,c120,s252). +registration(r850,c117,s253). +registration(r851,c99,s253). +registration(r852,c88,s253). +registration(r853,c9,s254). +registration(r854,c75,s254). +registration(r855,c56,s254). +registration(r856,c83,s255). +registration(r857,c121,s255). +registration(r858,c74,s255). +registration(r859,c25,s255). +registration(r860,c97,s256). +registration(r861,c77,s256). +registration(r862,c44,s256). +registration(r863,c94,s256). +registration(r864,c109,s257). +registration(r865,c110,s257). +registration(r866,c23,s257). +registration(r867,c46,s258). +registration(r868,c41,s258). +registration(r869,c108,s258). +registration(r870,c31,s258). +registration(r871,c97,s259). +registration(r872,c119,s259). +registration(r873,c17,s259). +registration(r874,c74,s260). +registration(r875,c65,s260). +registration(r876,c35,s260). +registration(r877,c111,s261). +registration(r878,c10,s261). +registration(r879,c71,s261). +registration(r880,c107,s261). +registration(r881,c54,s261). +registration(r882,c37,s262). +registration(r883,c36,s262). +registration(r884,c21,s262). +registration(r885,c17,s262). +registration(r886,c53,s263). +registration(r887,c6,s263). +registration(r888,c93,s263). +registration(r889,c101,s264). +registration(r890,c0,s264). +registration(r891,c67,s264). +registration(r892,c86,s265). +registration(r893,c50,s265). +registration(r894,c59,s265). +registration(r895,c95,s266). +registration(r896,c61,s266). +registration(r897,c48,s266). +registration(r898,c120,s267). +registration(r899,c88,s267). +registration(r900,c52,s267). +registration(r901,c15,s267). +registration(r902,c49,s268). +registration(r903,c38,s268). +registration(r904,c109,s268). +registration(r905,c35,s269). +registration(r906,c74,s269). +registration(r907,c50,s269). +registration(r908,c61,s269). +registration(r909,c3,s269). +registration(r910,c1,s270). +registration(r911,c95,s270). +registration(r912,c124,s270). +registration(r913,c55,s270). +registration(r914,c119,s271). +registration(r915,c6,s271). +registration(r916,c23,s271). +registration(r917,c101,s272). +registration(r918,c126,s272). +registration(r919,c46,s272). +registration(r920,c60,s273). +registration(r921,c78,s273). +registration(r922,c13,s273). +registration(r923,c122,s274). +registration(r924,c50,s274). +registration(r925,c73,s274). +registration(r926,c123,s275). +registration(r927,c33,s275). +registration(r928,c58,s275). +registration(r929,c37,s275). +registration(r930,c114,s276). +registration(r931,c32,s276). +registration(r932,c18,s276). +registration(r933,c88,s276). +registration(r934,c9,s276). +registration(r935,c111,s277). +registration(r936,c63,s277). +registration(r937,c64,s277). +registration(r938,c112,s278). +registration(r939,c19,s278). +registration(r940,c113,s278). +registration(r941,c126,s279). +registration(r942,c27,s279). +registration(r943,c86,s279). +registration(r944,c32,s280). +registration(r945,c23,s280). +registration(r946,c76,s280). +registration(r947,c5,s281). +registration(r948,c48,s281). +registration(r949,c94,s281). +registration(r950,c127,s282). +registration(r951,c82,s282). +registration(r952,c36,s282). +registration(r953,c47,s283). +registration(r954,c72,s283). +registration(r955,c29,s283). +registration(r956,c91,s284). +registration(r957,c96,s284). +registration(r958,c47,s284). +registration(r959,c17,s284). +registration(r960,c76,s285). +registration(r961,c40,s285). +registration(r962,c105,s285). +registration(r963,c9,s286). +registration(r964,c93,s286). +registration(r965,c66,s286). +registration(r966,c72,s286). +registration(r967,c86,s287). +registration(r968,c116,s287). +registration(r969,c8,s287). +registration(r970,c92,s288). +registration(r971,c29,s288). +registration(r972,c75,s288). +registration(r973,c18,s289). +registration(r974,c88,s289). +registration(r975,c61,s289). +registration(r976,c29,s290). +registration(r977,c96,s290). +registration(r978,c0,s290). +registration(r979,c76,s291). +registration(r980,c84,s291). +registration(r981,c91,s291). +registration(r982,c73,s291). +registration(r983,c111,s292). +registration(r984,c13,s292). +registration(r985,c11,s292). +registration(r986,c85,s292). +registration(r987,c121,s293). +registration(r988,c93,s293). +registration(r989,c88,s293). +registration(r990,c119,s294). +registration(r991,c55,s294). +registration(r992,c115,s294). +registration(r993,c76,s295). +registration(r994,c2,s295). +registration(r995,c122,s295). +registration(r996,c90,s296). +registration(r997,c0,s296). +registration(r998,c74,s296). +registration(r999,c31,s297). +registration(r1000,c39,s297). +registration(r1001,c96,s297). +registration(r1002,c79,s297). +registration(r1003,c119,s298). +registration(r1004,c23,s298). +registration(r1005,c84,s298). +registration(r1006,c78,s299). +registration(r1007,c43,s299). +registration(r1008,c83,s299). +registration(r1009,c74,s300). +registration(r1010,c114,s300). +registration(r1011,c90,s300). +registration(r1012,c59,s300). +registration(r1013,c17,s301). +registration(r1014,c55,s301). +registration(r1015,c39,s301). +registration(r1016,c41,s301). +registration(r1017,c124,s302). +registration(r1018,c92,s302). +registration(r1019,c116,s302). +registration(r1020,c83,s302). +registration(r1021,c5,s303). +registration(r1022,c17,s303). +registration(r1023,c38,s303). +registration(r1024,c122,s304). +registration(r1025,c74,s304). +registration(r1026,c31,s304). +registration(r1027,c115,s305). +registration(r1028,c2,s305). +registration(r1029,c93,s305). +registration(r1030,c57,s306). +registration(r1031,c77,s306). +registration(r1032,c49,s306). +registration(r1033,c105,s307). +registration(r1034,c8,s307). +registration(r1035,c17,s307). +registration(r1036,c13,s308). +registration(r1037,c88,s308). +registration(r1038,c38,s308). +registration(r1039,c124,s309). +registration(r1040,c46,s309). +registration(r1041,c108,s309). +registration(r1042,c21,s310). +registration(r1043,c28,s310). +registration(r1044,c120,s310). +registration(r1045,c111,s311). +registration(r1046,c40,s311). +registration(r1047,c101,s311). +registration(r1048,c91,s312). +registration(r1049,c7,s312). +registration(r1050,c52,s312). +registration(r1051,c104,s312). +registration(r1052,c119,s312). +registration(r1053,c112,s313). +registration(r1054,c35,s313). +registration(r1055,c114,s313). +registration(r1056,c75,s314). +registration(r1057,c70,s314). +registration(r1058,c90,s314). +registration(r1059,c9,s315). +registration(r1060,c23,s315). +registration(r1061,c101,s315). +registration(r1062,c0,s316). +registration(r1063,c46,s316). +registration(r1064,c97,s316). +registration(r1065,c10,s317). +registration(r1066,c74,s317). +registration(r1067,c108,s317). +registration(r1068,c115,s318). +registration(r1069,c36,s318). +registration(r1070,c51,s318). +registration(r1071,c43,s319). +registration(r1072,c76,s319). +registration(r1073,c93,s319). +registration(r1074,c14,s320). +registration(r1075,c105,s320). +registration(r1076,c52,s320). +registration(r1077,c119,s320). +registration(r1078,c114,s321). +registration(r1079,c39,s321). +registration(r1080,c91,s321). +registration(r1081,c92,s322). +registration(r1082,c85,s322). +registration(r1083,c51,s322). +registration(r1084,c62,s323). +registration(r1085,c9,s323). +registration(r1086,c96,s323). +registration(r1087,c82,s324). +registration(r1088,c85,s324). +registration(r1089,c99,s324). +registration(r1090,c14,s324). +registration(r1091,c121,s325). +registration(r1092,c105,s325). +registration(r1093,c44,s325). +registration(r1094,c22,s326). +registration(r1095,c27,s326). +registration(r1096,c98,s326). +registration(r1097,c84,s326). +registration(r1098,c80,s327). +registration(r1099,c109,s327). +registration(r1100,c124,s327). +registration(r1101,c82,s328). +registration(r1102,c89,s328). +registration(r1103,c9,s328). +registration(r1104,c20,s328). +registration(r1105,c38,s329). +registration(r1106,c71,s329). +registration(r1107,c67,s329). +registration(r1108,c38,s330). +registration(r1109,c40,s330). +registration(r1110,c43,s330). +registration(r1111,c20,s331). +registration(r1112,c98,s331). +registration(r1113,c7,s331). +registration(r1114,c120,s331). +registration(r1115,c111,s332). +registration(r1116,c32,s332). +registration(r1117,c52,s332). +registration(r1118,c33,s333). +registration(r1119,c64,s333). +registration(r1120,c21,s333). +registration(r1121,c110,s333). +registration(r1122,c117,s334). +registration(r1123,c87,s334). +registration(r1124,c5,s334). +registration(r1125,c126,s334). +registration(r1126,c76,s335). +registration(r1127,c120,s335). +registration(r1128,c104,s335). +registration(r1129,c19,s336). +registration(r1130,c41,s336). +registration(r1131,c65,s336). +registration(r1132,c74,s336). +registration(r1133,c54,s337). +registration(r1134,c4,s337). +registration(r1135,c107,s337). +registration(r1136,c31,s338). +registration(r1137,c105,s338). +registration(r1138,c22,s338). +registration(r1139,c44,s339). +registration(r1140,c45,s339). +registration(r1141,c60,s339). +registration(r1142,c20,s340). +registration(r1143,c33,s340). +registration(r1144,c44,s340). +registration(r1145,c110,s340). +registration(r1146,c11,s341). +registration(r1147,c88,s341). +registration(r1148,c107,s341). +registration(r1149,c19,s342). +registration(r1150,c107,s342). +registration(r1151,c20,s342). +registration(r1152,c73,s343). +registration(r1153,c35,s343). +registration(r1154,c31,s343). +registration(r1155,c63,s344). +registration(r1156,c89,s344). +registration(r1157,c96,s344). +registration(r1158,c2,s344). +registration(r1159,c45,s344). +registration(r1160,c62,s345). +registration(r1161,c38,s345). +registration(r1162,c80,s345). +registration(r1163,c123,s346). +registration(r1164,c100,s346). +registration(r1165,c52,s346). +registration(r1166,c13,s347). +registration(r1167,c93,s347). +registration(r1168,c28,s347). +registration(r1169,c7,s348). +registration(r1170,c13,s348). +registration(r1171,c18,s348). +registration(r1172,c51,s349). +registration(r1173,c92,s349). +registration(r1174,c69,s349). +registration(r1175,c30,s350). +registration(r1176,c92,s350). +registration(r1177,c27,s350). +registration(r1178,c73,s351). +registration(r1179,c94,s351). +registration(r1180,c15,s351). +registration(r1181,c48,s351). +registration(r1182,c20,s352). +registration(r1183,c23,s352). +registration(r1184,c12,s352). +registration(r1185,c6,s352). +registration(r1186,c99,s353). +registration(r1187,c34,s353). +registration(r1188,c18,s353). +registration(r1189,c31,s354). +registration(r1190,c101,s354). +registration(r1191,c100,s354). +registration(r1192,c64,s354). +registration(r1193,c58,s355). +registration(r1194,c21,s355). +registration(r1195,c92,s355). +registration(r1196,c119,s356). +registration(r1197,c121,s356). +registration(r1198,c89,s356). +registration(r1199,c106,s357). +registration(r1200,c89,s357). +registration(r1201,c9,s357). +registration(r1202,c31,s358). +registration(r1203,c78,s358). +registration(r1204,c117,s358). +registration(r1205,c89,s359). +registration(r1206,c72,s359). +registration(r1207,c124,s359). +registration(r1208,c27,s360). +registration(r1209,c19,s360). +registration(r1210,c88,s360). +registration(r1211,c45,s360). +registration(r1212,c76,s360). +registration(r1213,c66,s361). +registration(r1214,c117,s361). +registration(r1215,c36,s361). +registration(r1216,c30,s362). +registration(r1217,c15,s362). +registration(r1218,c47,s362). +registration(r1219,c8,s363). +registration(r1220,c0,s363). +registration(r1221,c61,s363). +registration(r1222,c10,s364). +registration(r1223,c108,s364). +registration(r1224,c70,s364). +registration(r1225,c15,s365). +registration(r1226,c111,s365). +registration(r1227,c115,s365). +registration(r1228,c10,s365). +registration(r1229,c89,s365). +registration(r1230,c28,s366). +registration(r1231,c51,s366). +registration(r1232,c115,s366). +registration(r1233,c104,s367). +registration(r1234,c12,s367). +registration(r1235,c42,s367). +registration(r1236,c57,s368). +registration(r1237,c4,s368). +registration(r1238,c34,s368). +registration(r1239,c35,s368). +registration(r1240,c112,s369). +registration(r1241,c4,s369). +registration(r1242,c66,s369). +registration(r1243,c8,s370). +registration(r1244,c111,s370). +registration(r1245,c54,s370). +registration(r1246,c94,s370). +registration(r1247,c25,s371). +registration(r1248,c105,s371). +registration(r1249,c48,s371). +registration(r1250,c98,s371). +registration(r1251,c102,s372). +registration(r1252,c109,s372). +registration(r1253,c86,s372). +registration(r1254,c2,s373). +registration(r1255,c38,s373). +registration(r1256,c39,s373). +registration(r1257,c71,s374). +registration(r1258,c112,s374). +registration(r1259,c54,s374). +registration(r1260,c59,s375). +registration(r1261,c44,s375). +registration(r1262,c92,s375). +registration(r1263,c75,s376). +registration(r1264,c98,s376). +registration(r1265,c77,s376). +registration(r1266,c104,s376). +registration(r1267,c19,s377). +registration(r1268,c60,s377). +registration(r1269,c92,s377). +registration(r1270,c31,s377). +registration(r1271,c6,s378). +registration(r1272,c119,s378). +registration(r1273,c18,s378). +registration(r1274,c121,s378). +registration(r1275,c38,s379). +registration(r1276,c54,s379). +registration(r1277,c97,s379). +registration(r1278,c24,s380). +registration(r1279,c89,s380). +registration(r1280,c7,s380). +registration(r1281,c100,s380). +registration(r1282,c127,s381). +registration(r1283,c59,s381). +registration(r1284,c46,s381). +registration(r1285,c88,s381). +registration(r1286,c108,s382). +registration(r1287,c113,s382). +registration(r1288,c106,s382). +registration(r1289,c5,s383). +registration(r1290,c72,s383). +registration(r1291,c15,s383). +registration(r1292,c63,s383). +registration(r1293,c12,s384). +registration(r1294,c57,s384). +registration(r1295,c89,s384). +registration(r1296,c58,s385). +registration(r1297,c33,s385). +registration(r1298,c20,s385). +registration(r1299,c28,s386). +registration(r1300,c38,s386). +registration(r1301,c1,s386). +registration(r1302,c60,s387). +registration(r1303,c46,s387). +registration(r1304,c6,s387). +registration(r1305,c115,s387). +registration(r1306,c54,s388). +registration(r1307,c115,s388). +registration(r1308,c27,s388). +registration(r1309,c120,s388). +registration(r1310,c18,s389). +registration(r1311,c4,s389). +registration(r1312,c35,s389). +registration(r1313,c92,s389). +registration(r1314,c12,s390). +registration(r1315,c68,s390). +registration(r1316,c74,s390). +registration(r1317,c94,s391). +registration(r1318,c24,s391). +registration(r1319,c98,s391). +registration(r1320,c98,s392). +registration(r1321,c122,s392). +registration(r1322,c97,s392). +registration(r1323,c105,s393). +registration(r1324,c100,s393). +registration(r1325,c47,s393). +registration(r1326,c35,s394). +registration(r1327,c120,s394). +registration(r1328,c30,s394). +registration(r1329,c49,s395). +registration(r1330,c31,s395). +registration(r1331,c125,s395). +registration(r1332,c89,s396). +registration(r1333,c114,s396). +registration(r1334,c117,s396). +registration(r1335,c91,s397). +registration(r1336,c1,s397). +registration(r1337,c80,s397). +registration(r1338,c15,s398). +registration(r1339,c32,s398). +registration(r1340,c119,s398). +registration(r1341,c32,s399). +registration(r1342,c92,s399). +registration(r1343,c36,s399). +registration(r1344,c64,s400). +registration(r1345,c116,s400). +registration(r1346,c47,s400). +registration(r1347,c11,s400). +registration(r1348,c17,s401). +registration(r1349,c48,s401). +registration(r1350,c9,s401). +registration(r1351,c98,s402). +registration(r1352,c104,s402). +registration(r1353,c85,s402). +registration(r1354,c32,s402). +registration(r1355,c6,s403). +registration(r1356,c114,s403). +registration(r1357,c111,s403). +registration(r1358,c1,s403). +registration(r1359,c122,s403). +registration(r1360,c116,s404). +registration(r1361,c78,s404). +registration(r1362,c26,s404). +registration(r1363,c107,s405). +registration(r1364,c8,s405). +registration(r1365,c51,s405). +registration(r1366,c18,s406). +registration(r1367,c111,s406). +registration(r1368,c68,s406). +registration(r1369,c77,s407). +registration(r1370,c26,s407). +registration(r1371,c0,s407). +registration(r1372,c88,s407). +registration(r1373,c53,s408). +registration(r1374,c35,s408). +registration(r1375,c9,s408). +registration(r1376,c121,s408). +registration(r1377,c63,s409). +registration(r1378,c23,s409). +registration(r1379,c9,s409). +registration(r1380,c89,s409). +registration(r1381,c84,s410). +registration(r1382,c92,s410). +registration(r1383,c74,s410). +registration(r1384,c127,s411). +registration(r1385,c30,s411). +registration(r1386,c29,s411). +registration(r1387,c13,s411). +registration(r1388,c54,s412). +registration(r1389,c45,s412). +registration(r1390,c47,s412). +registration(r1391,c95,s413). +registration(r1392,c83,s413). +registration(r1393,c6,s413). +registration(r1394,c120,s413). +registration(r1395,c80,s413). +registration(r1396,c14,s414). +registration(r1397,c9,s414). +registration(r1398,c18,s414). +registration(r1399,c76,s414). +registration(r1400,c50,s415). +registration(r1401,c107,s415). +registration(r1402,c31,s415). +registration(r1403,c56,s415). +registration(r1404,c115,s416). +registration(r1405,c55,s416). +registration(r1406,c125,s416). +registration(r1407,c73,s416). +registration(r1408,c113,s416). +registration(r1409,c0,s417). +registration(r1410,c58,s417). +registration(r1411,c35,s417). +registration(r1412,c2,s418). +registration(r1413,c38,s418). +registration(r1414,c111,s418). +registration(r1415,c30,s418). +registration(r1416,c105,s419). +registration(r1417,c44,s419). +registration(r1418,c8,s419). +registration(r1419,c28,s420). +registration(r1420,c70,s420). +registration(r1421,c6,s420). +registration(r1422,c102,s420). +registration(r1423,c63,s420). +registration(r1424,c68,s421). +registration(r1425,c8,s421). +registration(r1426,c119,s421). +registration(r1427,c65,s422). +registration(r1428,c78,s422). +registration(r1429,c12,s422). +registration(r1430,c47,s422). +registration(r1431,c19,s423). +registration(r1432,c113,s423). +registration(r1433,c50,s423). +registration(r1434,c73,s424). +registration(r1435,c88,s424). +registration(r1436,c95,s424). +registration(r1437,c104,s424). +registration(r1438,c46,s425). +registration(r1439,c89,s425). +registration(r1440,c4,s425). +registration(r1441,c12,s426). +registration(r1442,c90,s426). +registration(r1443,c117,s426). +registration(r1444,c125,s427). +registration(r1445,c66,s427). +registration(r1446,c96,s427). +registration(r1447,c4,s427). +registration(r1448,c36,s428). +registration(r1449,c71,s428). +registration(r1450,c56,s428). +registration(r1451,c41,s429). +registration(r1452,c5,s429). +registration(r1453,c20,s429). +registration(r1454,c80,s429). +registration(r1455,c104,s430). +registration(r1456,c3,s430). +registration(r1457,c114,s430). +registration(r1458,c75,s431). +registration(r1459,c85,s431). +registration(r1460,c36,s431). +registration(r1461,c127,s432). +registration(r1462,c31,s432). +registration(r1463,c46,s432). +registration(r1464,c113,s433). +registration(r1465,c127,s433). +registration(r1466,c51,s433). +registration(r1467,c88,s434). +registration(r1468,c60,s434). +registration(r1469,c103,s434). +registration(r1470,c15,s434). +registration(r1471,c50,s435). +registration(r1472,c43,s435). +registration(r1473,c25,s435). +registration(r1474,c23,s435). +registration(r1475,c4,s435). +registration(r1476,c10,s436). +registration(r1477,c83,s436). +registration(r1478,c54,s436). +registration(r1479,c91,s437). +registration(r1480,c0,s437). +registration(r1481,c11,s437). +registration(r1482,c56,s438). +registration(r1483,c120,s438). +registration(r1484,c61,s438). +registration(r1485,c114,s439). +registration(r1486,c30,s439). +registration(r1487,c38,s439). +registration(r1488,c13,s440). +registration(r1489,c119,s440). +registration(r1490,c114,s440). +registration(r1491,c30,s441). +registration(r1492,c55,s441). +registration(r1493,c43,s441). +registration(r1494,c48,s442). +registration(r1495,c64,s442). +registration(r1496,c11,s442). +registration(r1497,c53,s442). +registration(r1498,c66,s443). +registration(r1499,c21,s443). +registration(r1500,c62,s443). +registration(r1501,c119,s444). +registration(r1502,c21,s444). +registration(r1503,c114,s444). +registration(r1504,c100,s444). +registration(r1505,c63,s445). +registration(r1506,c51,s445). +registration(r1507,c48,s445). +registration(r1508,c40,s446). +registration(r1509,c14,s446). +registration(r1510,c94,s446). +registration(r1511,c20,s447). +registration(r1512,c125,s447). +registration(r1513,c98,s447). +registration(r1514,c35,s448). +registration(r1515,c89,s448). +registration(r1516,c20,s448). +registration(r1517,c86,s448). +registration(r1518,c79,s449). +registration(r1519,c76,s449). +registration(r1520,c115,s449). +registration(r1521,c66,s449). +registration(r1522,c121,s449). +registration(r1523,c100,s450). +registration(r1524,c22,s450). +registration(r1525,c94,s450). +registration(r1526,c15,s451). +registration(r1527,c64,s451). +registration(r1528,c10,s451). +registration(r1529,c104,s452). +registration(r1530,c10,s452). +registration(r1531,c123,s452). +registration(r1532,c93,s452). +registration(r1533,c75,s453). +registration(r1534,c54,s453). +registration(r1535,c3,s453). +registration(r1536,c60,s454). +registration(r1537,c50,s454). +registration(r1538,c33,s454). +registration(r1539,c0,s454). +registration(r1540,c18,s454). +registration(r1541,c68,s455). +registration(r1542,c31,s455). +registration(r1543,c11,s455). +registration(r1544,c106,s456). +registration(r1545,c77,s456). +registration(r1546,c0,s456). +registration(r1547,c11,s456). +registration(r1548,c49,s457). +registration(r1549,c92,s457). +registration(r1550,c116,s457). +registration(r1551,c113,s458). +registration(r1552,c67,s458). +registration(r1553,c54,s458). +registration(r1554,c58,s459). +registration(r1555,c98,s459). +registration(r1556,c70,s459). +registration(r1557,c105,s459). +registration(r1558,c3,s460). +registration(r1559,c22,s460). +registration(r1560,c126,s460). +registration(r1561,c89,s460). +registration(r1562,c33,s461). +registration(r1563,c2,s461). +registration(r1564,c84,s461). +registration(r1565,c80,s461). +registration(r1566,c5,s462). +registration(r1567,c94,s462). +registration(r1568,c95,s462). +registration(r1569,c82,s463). +registration(r1570,c115,s463). +registration(r1571,c17,s463). +registration(r1572,c73,s464). +registration(r1573,c1,s464). +registration(r1574,c51,s464). +registration(r1575,c100,s464). +registration(r1576,c122,s465). +registration(r1577,c119,s465). +registration(r1578,c96,s465). +registration(r1579,c94,s465). +registration(r1580,c20,s466). +registration(r1581,c103,s466). +registration(r1582,c126,s466). +registration(r1583,c82,s467). +registration(r1584,c64,s467). +registration(r1585,c57,s467). +registration(r1586,c24,s468). +registration(r1587,c5,s468). +registration(r1588,c126,s468). +registration(r1589,c113,s469). +registration(r1590,c100,s469). +registration(r1591,c28,s469). +registration(r1592,c30,s470). +registration(r1593,c92,s470). +registration(r1594,c50,s470). +registration(r1595,c85,s470). +registration(r1596,c122,s471). +registration(r1597,c54,s471). +registration(r1598,c42,s471). +registration(r1599,c23,s471). +registration(r1600,c111,s472). +registration(r1601,c22,s472). +registration(r1602,c118,s472). +registration(r1603,c55,s473). +registration(r1604,c19,s473). +registration(r1605,c16,s473). +registration(r1606,c22,s474). +registration(r1607,c124,s474). +registration(r1608,c127,s474). +registration(r1609,c100,s475). +registration(r1610,c11,s475). +registration(r1611,c23,s475). +registration(r1612,c43,s475). +registration(r1613,c68,s476). +registration(r1614,c44,s476). +registration(r1615,c73,s476). +registration(r1616,c127,s477). +registration(r1617,c29,s477). +registration(r1618,c47,s477). +registration(r1619,c93,s477). +registration(r1620,c46,s478). +registration(r1621,c83,s478). +registration(r1622,c119,s478). +registration(r1623,c10,s478). +registration(r1624,c40,s478). +registration(r1625,c9,s479). +registration(r1626,c55,s479). +registration(r1627,c64,s479). +registration(r1628,c54,s479). +registration(r1629,c114,s480). +registration(r1630,c26,s480). +registration(r1631,c58,s480). +registration(r1632,c44,s480). +registration(r1633,c124,s481). +registration(r1634,c112,s481). +registration(r1635,c17,s481). +registration(r1636,c56,s482). +registration(r1637,c69,s482). +registration(r1638,c0,s482). +registration(r1639,c94,s483). +registration(r1640,c5,s483). +registration(r1641,c12,s483). +registration(r1642,c36,s484). +registration(r1643,c61,s484). +registration(r1644,c8,s484). +registration(r1645,c63,s485). +registration(r1646,c12,s485). +registration(r1647,c75,s485). +registration(r1648,c61,s486). +registration(r1649,c16,s486). +registration(r1650,c117,s486). +registration(r1651,c90,s487). +registration(r1652,c67,s487). +registration(r1653,c46,s487). +registration(r1654,c17,s487). +registration(r1655,c36,s488). +registration(r1656,c78,s488). +registration(r1657,c18,s488). +registration(r1658,c44,s488). +registration(r1659,c18,s489). +registration(r1660,c55,s489). +registration(r1661,c35,s489). +registration(r1662,c92,s489). +registration(r1663,c23,s490). +registration(r1664,c41,s490). +registration(r1665,c38,s490). +registration(r1666,c113,s491). +registration(r1667,c76,s491). +registration(r1668,c112,s491). +registration(r1669,c103,s492). +registration(r1670,c118,s492). +registration(r1671,c25,s492). +registration(r1672,c73,s493). +registration(r1673,c46,s493). +registration(r1674,c68,s493). +registration(r1675,c18,s494). +registration(r1676,c110,s494). +registration(r1677,c95,s494). +registration(r1678,c114,s495). +registration(r1679,c117,s495). +registration(r1680,c3,s495). +registration(r1681,c80,s495). +registration(r1682,c25,s496). +registration(r1683,c122,s496). +registration(r1684,c9,s496). +registration(r1685,c122,s497). +registration(r1686,c61,s497). +registration(r1687,c33,s497). +registration(r1688,c9,s498). +registration(r1689,c33,s498). +registration(r1690,c54,s498). +registration(r1691,c126,s499). +registration(r1692,c121,s499). +registration(r1693,c31,s499). +registration(r1694,c50,s500). +registration(r1695,c73,s500). +registration(r1696,c45,s500). +registration(r1697,c33,s501). +registration(r1698,c102,s501). +registration(r1699,c44,s501). +registration(r1700,c15,s502). +registration(r1701,c61,s502). +registration(r1702,c49,s502). +registration(r1703,c45,s502). +registration(r1704,c19,s503). +registration(r1705,c107,s503). +registration(r1706,c4,s503). +registration(r1707,c14,s503). +registration(r1708,c94,s504). +registration(r1709,c59,s504). +registration(r1710,c89,s504). +registration(r1711,c84,s505). +registration(r1712,c90,s505). +registration(r1713,c20,s505). +registration(r1714,c94,s505). +registration(r1715,c81,s506). +registration(r1716,c126,s506). +registration(r1717,c5,s506). +registration(r1718,c50,s507). +registration(r1719,c21,s507). +registration(r1720,c28,s507). +registration(r1721,c77,s508). +registration(r1722,c91,s508). +registration(r1723,c127,s508). +registration(r1724,c106,s509). +registration(r1725,c50,s509). +registration(r1726,c43,s509). +registration(r1727,c10,s510). +registration(r1728,c45,s510). +registration(r1729,c27,s510). +registration(r1730,c111,s511). +registration(r1731,c30,s511). +registration(r1732,c123,s511). +registration(r1733,c43,s511). +registration(r1734,c100,s512). +registration(r1735,c40,s512). +registration(r1736,c94,s512). +registration(r1737,c16,s512). +registration(r1738,c108,s513). +registration(r1739,c41,s513). +registration(r1740,c82,s513). +registration(r1741,c45,s514). +registration(r1742,c63,s514). +registration(r1743,c37,s514). +registration(r1744,c89,s515). +registration(r1745,c71,s515). +registration(r1746,c26,s515). +registration(r1747,c71,s516). +registration(r1748,c53,s516). +registration(r1749,c22,s516). +registration(r1750,c53,s517). +registration(r1751,c41,s517). +registration(r1752,c56,s517). +registration(r1753,c27,s517). +registration(r1754,c9,s518). +registration(r1755,c97,s518). +registration(r1756,c114,s518). +registration(r1757,c113,s518). +registration(r1758,c64,s519). +registration(r1759,c69,s519). +registration(r1760,c30,s519). +registration(r1761,c93,s520). +registration(r1762,c92,s520). +registration(r1763,c14,s520). +registration(r1764,c54,s520). +registration(r1765,c34,s521). +registration(r1766,c82,s521). +registration(r1767,c42,s521). +registration(r1768,c65,s521). +registration(r1769,c24,s522). +registration(r1770,c44,s522). +registration(r1771,c118,s522). +registration(r1772,c87,s523). +registration(r1773,c68,s523). +registration(r1774,c127,s523). +registration(r1775,c114,s524). +registration(r1776,c120,s524). +registration(r1777,c24,s524). +registration(r1778,c94,s525). +registration(r1779,c112,s525). +registration(r1780,c113,s525). +registration(r1781,c78,s526). +registration(r1782,c95,s526). +registration(r1783,c84,s526). +registration(r1784,c53,s526). +registration(r1785,c87,s527). +registration(r1786,c96,s527). +registration(r1787,c98,s527). +registration(r1788,c122,s528). +registration(r1789,c10,s528). +registration(r1790,c25,s528). +registration(r1791,c112,s529). +registration(r1792,c2,s529). +registration(r1793,c109,s529). +registration(r1794,c96,s530). +registration(r1795,c73,s530). +registration(r1796,c65,s530). +registration(r1797,c32,s530). +registration(r1798,c34,s531). +registration(r1799,c115,s531). +registration(r1800,c112,s531). +registration(r1801,c81,s532). +registration(r1802,c68,s532). +registration(r1803,c71,s532). +registration(r1804,c59,s532). +registration(r1805,c104,s533). +registration(r1806,c30,s533). +registration(r1807,c125,s533). +registration(r1808,c24,s533). +registration(r1809,c35,s533). +registration(r1810,c86,s534). +registration(r1811,c118,s534). +registration(r1812,c18,s534). +registration(r1813,c100,s535). +registration(r1814,c2,s535). +registration(r1815,c69,s535). +registration(r1816,c119,s536). +registration(r1817,c48,s536). +registration(r1818,c102,s536). +registration(r1819,c35,s536). +registration(r1820,c9,s537). +registration(r1821,c103,s537). +registration(r1822,c41,s537). +registration(r1823,c49,s538). +registration(r1824,c11,s538). +registration(r1825,c78,s538). +registration(r1826,c42,s538). +registration(r1827,c35,s539). +registration(r1828,c67,s539). +registration(r1829,c84,s539). +registration(r1830,c74,s539). +registration(r1831,c89,s540). +registration(r1832,c114,s540). +registration(r1833,c46,s540). +registration(r1834,c116,s541). +registration(r1835,c106,s541). +registration(r1836,c58,s541). +registration(r1837,c34,s542). +registration(r1838,c5,s542). +registration(r1839,c66,s542). +registration(r1840,c41,s542). +registration(r1841,c36,s543). +registration(r1842,c93,s543). +registration(r1843,c86,s543). +registration(r1844,c36,s544). +registration(r1845,c111,s544). +registration(r1846,c18,s544). +registration(r1847,c85,s544). +registration(r1848,c66,s545). +registration(r1849,c89,s545). +registration(r1850,c111,s545). +registration(r1851,c50,s545). +registration(r1852,c60,s546). +registration(r1853,c113,s546). +registration(r1854,c87,s546). +registration(r1855,c18,s547). +registration(r1856,c29,s547). +registration(r1857,c121,s547). +registration(r1858,c58,s548). +registration(r1859,c47,s548). +registration(r1860,c48,s548). +registration(r1861,c13,s549). +registration(r1862,c58,s549). +registration(r1863,c41,s549). +registration(r1864,c24,s550). +registration(r1865,c9,s550). +registration(r1866,c77,s550). +registration(r1867,c15,s551). +registration(r1868,c5,s551). +registration(r1869,c79,s551). +registration(r1870,c49,s552). +registration(r1871,c89,s552). +registration(r1872,c41,s552). +registration(r1873,c9,s552). +registration(r1874,c27,s552). +registration(r1875,c38,s553). +registration(r1876,c0,s553). +registration(r1877,c80,s553). +registration(r1878,c127,s554). +registration(r1879,c119,s554). +registration(r1880,c29,s554). +registration(r1881,c86,s554). +registration(r1882,c124,s555). +registration(r1883,c125,s555). +registration(r1884,c52,s555). +registration(r1885,c6,s555). +registration(r1886,c64,s555). +registration(r1887,c102,s556). +registration(r1888,c18,s556). +registration(r1889,c69,s556). +registration(r1890,c126,s557). +registration(r1891,c101,s557). +registration(r1892,c8,s557). +registration(r1893,c18,s558). +registration(r1894,c47,s558). +registration(r1895,c10,s558). +registration(r1896,c90,s559). +registration(r1897,c0,s559). +registration(r1898,c106,s559). +registration(r1899,c8,s560). +registration(r1900,c45,s560). +registration(r1901,c127,s560). +registration(r1902,c124,s561). +registration(r1903,c21,s561). +registration(r1904,c63,s561). +registration(r1905,c24,s561). +registration(r1906,c105,s562). +registration(r1907,c41,s562). +registration(r1908,c69,s562). +registration(r1909,c67,s563). +registration(r1910,c5,s563). +registration(r1911,c98,s563). +registration(r1912,c116,s564). +registration(r1913,c26,s564). +registration(r1914,c127,s564). +registration(r1915,c89,s565). +registration(r1916,c44,s565). +registration(r1917,c52,s565). +registration(r1918,c60,s566). +registration(r1919,c96,s566). +registration(r1920,c35,s566). +registration(r1921,c31,s566). +registration(r1922,c49,s567). +registration(r1923,c74,s567). +registration(r1924,c35,s567). +registration(r1925,c13,s568). +registration(r1926,c115,s568). +registration(r1927,c15,s568). +registration(r1928,c82,s569). +registration(r1929,c50,s569). +registration(r1930,c46,s569). +registration(r1931,c35,s570). +registration(r1932,c89,s570). +registration(r1933,c39,s570). +registration(r1934,c1,s571). +registration(r1935,c124,s571). +registration(r1936,c86,s571). +registration(r1937,c19,s572). +registration(r1938,c22,s572). +registration(r1939,c70,s572). +registration(r1940,c102,s573). +registration(r1941,c96,s573). +registration(r1942,c106,s573). +registration(r1943,c41,s573). +registration(r1944,c24,s574). +registration(r1945,c30,s574). +registration(r1946,c67,s574). +registration(r1947,c20,s575). +registration(r1948,c119,s575). +registration(r1949,c26,s575). +registration(r1950,c61,s576). +registration(r1951,c43,s576). +registration(r1952,c72,s576). +registration(r1953,c79,s576). +registration(r1954,c9,s577). +registration(r1955,c38,s577). +registration(r1956,c125,s577). +registration(r1957,c19,s578). +registration(r1958,c112,s578). +registration(r1959,c103,s578). +registration(r1960,c73,s579). +registration(r1961,c29,s579). +registration(r1962,c98,s579). +registration(r1963,c121,s580). +registration(r1964,c17,s580). +registration(r1965,c19,s580). +registration(r1966,c39,s581). +registration(r1967,c55,s581). +registration(r1968,c21,s581). +registration(r1969,c83,s582). +registration(r1970,c38,s582). +registration(r1971,c29,s582). +registration(r1972,c103,s583). +registration(r1973,c105,s583). +registration(r1974,c26,s583). +registration(r1975,c82,s583). +registration(r1976,c120,s584). +registration(r1977,c4,s584). +registration(r1978,c59,s584). +registration(r1979,c4,s585). +registration(r1980,c74,s585). +registration(r1981,c61,s585). +registration(r1982,c55,s586). +registration(r1983,c9,s586). +registration(r1984,c45,s586). +registration(r1985,c85,s586). +registration(r1986,c45,s587). +registration(r1987,c27,s587). +registration(r1988,c80,s587). +registration(r1989,c110,s587). +registration(r1990,c34,s588). +registration(r1991,c78,s588). +registration(r1992,c108,s588). +registration(r1993,c55,s588). +registration(r1994,c112,s588). +registration(r1995,c75,s589). +registration(r1996,c90,s589). +registration(r1997,c104,s589). +registration(r1998,c20,s589). +registration(r1999,c44,s590). +registration(r2000,c26,s590). +registration(r2001,c95,s590). +registration(r2002,c121,s590). +registration(r2003,c34,s591). +registration(r2004,c27,s591). +registration(r2005,c40,s591). +registration(r2006,c33,s591). +registration(r2007,c70,s592). +registration(r2008,c60,s592). +registration(r2009,c76,s592). +registration(r2010,c65,s593). +registration(r2011,c109,s593). +registration(r2012,c121,s593). +registration(r2013,c49,s594). +registration(r2014,c53,s594). +registration(r2015,c103,s594). +registration(r2016,c80,s594). +registration(r2017,c77,s595). +registration(r2018,c36,s595). +registration(r2019,c101,s595). +registration(r2020,c67,s596). +registration(r2021,c99,s596). +registration(r2022,c82,s596). +registration(r2023,c110,s596). +registration(r2024,c100,s597). +registration(r2025,c30,s597). +registration(r2026,c15,s597). +registration(r2027,c76,s598). +registration(r2028,c42,s598). +registration(r2029,c47,s598). +registration(r2030,c29,s599). +registration(r2031,c113,s599). +registration(r2032,c25,s599). +registration(r2033,c36,s599). +registration(r2034,c124,s600). +registration(r2035,c31,s600). +registration(r2036,c93,s600). +registration(r2037,c2,s601). +registration(r2038,c49,s601). +registration(r2039,c102,s601). +registration(r2040,c73,s602). +registration(r2041,c20,s602). +registration(r2042,c50,s602). +registration(r2043,c22,s602). +registration(r2044,c110,s603). +registration(r2045,c18,s603). +registration(r2046,c118,s603). +registration(r2047,c33,s604). +registration(r2048,c3,s604). +registration(r2049,c88,s604). +registration(r2050,c32,s604). +registration(r2051,c40,s605). +registration(r2052,c53,s605). +registration(r2053,c108,s605). +registration(r2054,c11,s606). +registration(r2055,c85,s606). +registration(r2056,c126,s606). +registration(r2057,c47,s607). +registration(r2058,c95,s607). +registration(r2059,c25,s607). +registration(r2060,c46,s608). +registration(r2061,c86,s608). +registration(r2062,c120,s608). +registration(r2063,c103,s609). +registration(r2064,c68,s609). +registration(r2065,c98,s609). +registration(r2066,c4,s610). +registration(r2067,c62,s610). +registration(r2068,c123,s610). +registration(r2069,c93,s610). +registration(r2070,c59,s611). +registration(r2071,c19,s611). +registration(r2072,c49,s611). +registration(r2073,c60,s612). +registration(r2074,c7,s612). +registration(r2075,c68,s612). +registration(r2076,c114,s613). +registration(r2077,c20,s613). +registration(r2078,c121,s613). +registration(r2079,c60,s613). +registration(r2080,c108,s614). +registration(r2081,c53,s614). +registration(r2082,c89,s614). +registration(r2083,c30,s615). +registration(r2084,c60,s615). +registration(r2085,c88,s615). +registration(r2086,c22,s616). +registration(r2087,c62,s616). +registration(r2088,c84,s616). +registration(r2089,c14,s616). +registration(r2090,c7,s617). +registration(r2091,c52,s617). +registration(r2092,c66,s617). +registration(r2093,c73,s618). +registration(r2094,c16,s618). +registration(r2095,c38,s618). +registration(r2096,c58,s618). +registration(r2097,c34,s619). +registration(r2098,c24,s619). +registration(r2099,c119,s619). +registration(r2100,c46,s619). +registration(r2101,c36,s620). +registration(r2102,c95,s620). +registration(r2103,c74,s620). +registration(r2104,c35,s621). +registration(r2105,c4,s621). +registration(r2106,c92,s621). +registration(r2107,c47,s622). +registration(r2108,c45,s622). +registration(r2109,c70,s622). +registration(r2110,c121,s623). +registration(r2111,c127,s623). +registration(r2112,c2,s623). +registration(r2113,c18,s624). +registration(r2114,c15,s624). +registration(r2115,c114,s624). +registration(r2116,c73,s624). +registration(r2117,c47,s624). +registration(r2118,c64,s625). +registration(r2119,c95,s625). +registration(r2120,c51,s625). +registration(r2121,c19,s625). +registration(r2122,c57,s626). +registration(r2123,c70,s626). +registration(r2124,c46,s626). +registration(r2125,c11,s627). +registration(r2126,c23,s627). +registration(r2127,c14,s627). +registration(r2128,c83,s628). +registration(r2129,c121,s628). +registration(r2130,c120,s628). +registration(r2131,c123,s629). +registration(r2132,c54,s629). +registration(r2133,c66,s629). +registration(r2134,c70,s629). +registration(r2135,c35,s630). +registration(r2136,c15,s630). +registration(r2137,c74,s630). +registration(r2138,c41,s631). +registration(r2139,c6,s631). +registration(r2140,c64,s631). +registration(r2141,c121,s632). +registration(r2142,c115,s632). +registration(r2143,c72,s632). +registration(r2144,c84,s633). +registration(r2145,c108,s633). +registration(r2146,c76,s633). +registration(r2147,c47,s633). +registration(r2148,c9,s634). +registration(r2149,c42,s634). +registration(r2150,c110,s634). +registration(r2151,c37,s634). +registration(r2152,c69,s635). +registration(r2153,c50,s635). +registration(r2154,c108,s635). +registration(r2155,c123,s636). +registration(r2156,c68,s636). +registration(r2157,c40,s636). +registration(r2158,c47,s637). +registration(r2159,c11,s637). +registration(r2160,c28,s637). +registration(r2161,c16,s637). +registration(r2162,c18,s638). +registration(r2163,c91,s638). +registration(r2164,c79,s638). +registration(r2165,c28,s639). +registration(r2166,c119,s639). +registration(r2167,c120,s639). +registration(r2168,c33,s639). +registration(r2169,c44,s640). +registration(r2170,c4,s640). +registration(r2171,c71,s640). +registration(r2172,c121,s641). +registration(r2173,c61,s641). +registration(r2174,c68,s641). +registration(r2175,c9,s642). +registration(r2176,c121,s642). +registration(r2177,c6,s642). +registration(r2178,c18,s643). +registration(r2179,c20,s643). +registration(r2180,c114,s643). +registration(r2181,c37,s643). +registration(r2182,c115,s643). +registration(r2183,c115,s644). +registration(r2184,c107,s644). +registration(r2185,c57,s644). +registration(r2186,c99,s644). +registration(r2187,c78,s645). +registration(r2188,c101,s645). +registration(r2189,c83,s645). +registration(r2190,c27,s646). +registration(r2191,c77,s646). +registration(r2192,c51,s646). +registration(r2193,c11,s646). +registration(r2194,c101,s647). +registration(r2195,c68,s647). +registration(r2196,c0,s647). +registration(r2197,c120,s648). +registration(r2198,c7,s648). +registration(r2199,c93,s648). +registration(r2200,c122,s648). +registration(r2201,c47,s649). +registration(r2202,c126,s649). +registration(r2203,c103,s649). +registration(r2204,c34,s650). +registration(r2205,c52,s650). +registration(r2206,c80,s650). +registration(r2207,c54,s650). +registration(r2208,c41,s651). +registration(r2209,c125,s651). +registration(r2210,c30,s651). +registration(r2211,c82,s652). +registration(r2212,c89,s652). +registration(r2213,c86,s652). +registration(r2214,c27,s653). +registration(r2215,c76,s653). +registration(r2216,c30,s653). +registration(r2217,c37,s654). +registration(r2218,c68,s654). +registration(r2219,c80,s654). +registration(r2220,c0,s655). +registration(r2221,c31,s655). +registration(r2222,c34,s655). +registration(r2223,c68,s655). +registration(r2224,c87,s656). +registration(r2225,c89,s656). +registration(r2226,c23,s656). +registration(r2227,c64,s656). +registration(r2228,c87,s657). +registration(r2229,c45,s657). +registration(r2230,c5,s657). +registration(r2231,c94,s657). +registration(r2232,c121,s658). +registration(r2233,c75,s658). +registration(r2234,c28,s658). +registration(r2235,c23,s658). +registration(r2236,c123,s659). +registration(r2237,c91,s659). +registration(r2238,c96,s659). +registration(r2239,c0,s660). +registration(r2240,c121,s660). +registration(r2241,c44,s660). +registration(r2242,c80,s661). +registration(r2243,c39,s661). +registration(r2244,c94,s661). +registration(r2245,c117,s661). +registration(r2246,c1,s662). +registration(r2247,c17,s662). +registration(r2248,c55,s662). +registration(r2249,c59,s663). +registration(r2250,c124,s663). +registration(r2251,c63,s663). +registration(r2252,c12,s664). +registration(r2253,c55,s664). +registration(r2254,c10,s664). +registration(r2255,c6,s665). +registration(r2256,c127,s665). +registration(r2257,c81,s665). +registration(r2258,c82,s666). +registration(r2259,c63,s666). +registration(r2260,c89,s666). +registration(r2261,c40,s667). +registration(r2262,c24,s667). +registration(r2263,c56,s667). +registration(r2264,c45,s668). +registration(r2265,c81,s668). +registration(r2266,c42,s668). +registration(r2267,c106,s669). +registration(r2268,c31,s669). +registration(r2269,c39,s669). +registration(r2270,c29,s670). +registration(r2271,c54,s670). +registration(r2272,c113,s670). +registration(r2273,c98,s671). +registration(r2274,c46,s671). +registration(r2275,c89,s671). +registration(r2276,c5,s672). +registration(r2277,c8,s672). +registration(r2278,c54,s672). +registration(r2279,c15,s673). +registration(r2280,c6,s673). +registration(r2281,c18,s673). +registration(r2282,c43,s674). +registration(r2283,c116,s674). +registration(r2284,c40,s674). +registration(r2285,c83,s675). +registration(r2286,c64,s675). +registration(r2287,c121,s675). +registration(r2288,c51,s676). +registration(r2289,c24,s676). +registration(r2290,c33,s676). +registration(r2291,c123,s677). +registration(r2292,c6,s677). +registration(r2293,c111,s677). +registration(r2294,c101,s678). +registration(r2295,c90,s678). +registration(r2296,c65,s678). +registration(r2297,c58,s679). +registration(r2298,c42,s679). +registration(r2299,c65,s679). +registration(r2300,c23,s680). +registration(r2301,c119,s680). +registration(r2302,c102,s680). +registration(r2303,c64,s681). +registration(r2304,c19,s681). +registration(r2305,c15,s681). +registration(r2306,c122,s681). +registration(r2307,c108,s682). +registration(r2308,c40,s682). +registration(r2309,c27,s682). +registration(r2310,c105,s682). +registration(r2311,c22,s682). +registration(r2312,c90,s683). +registration(r2313,c108,s683). +registration(r2314,c81,s683). +registration(r2315,c21,s684). +registration(r2316,c91,s684). +registration(r2317,c1,s684). +registration(r2318,c66,s684). +registration(r2319,c27,s685). +registration(r2320,c119,s685). +registration(r2321,c89,s685). +registration(r2322,c94,s685). +registration(r2323,c97,s686). +registration(r2324,c30,s686). +registration(r2325,c46,s686). +registration(r2326,c61,s687). +registration(r2327,c108,s687). +registration(r2328,c68,s687). +registration(r2329,c85,s687). +registration(r2330,c79,s688). +registration(r2331,c31,s688). +registration(r2332,c108,s688). +registration(r2333,c62,s688). +registration(r2334,c105,s689). +registration(r2335,c83,s689). +registration(r2336,c84,s689). +registration(r2337,c37,s690). +registration(r2338,c74,s690). +registration(r2339,c23,s690). +registration(r2340,c113,s691). +registration(r2341,c83,s691). +registration(r2342,c32,s691). +registration(r2343,c53,s691). +registration(r2344,c57,s692). +registration(r2345,c38,s692). +registration(r2346,c22,s692). +registration(r2347,c92,s692). +registration(r2348,c92,s693). +registration(r2349,c26,s693). +registration(r2350,c48,s693). +registration(r2351,c29,s694). +registration(r2352,c86,s694). +registration(r2353,c70,s694). +registration(r2354,c26,s695). +registration(r2355,c50,s695). +registration(r2356,c4,s695). +registration(r2357,c78,s696). +registration(r2358,c7,s696). +registration(r2359,c24,s696). +registration(r2360,c121,s696). +registration(r2361,c49,s697). +registration(r2362,c4,s697). +registration(r2363,c34,s697). +registration(r2364,c72,s698). +registration(r2365,c7,s698). +registration(r2366,c52,s698). +registration(r2367,c16,s699). +registration(r2368,c117,s699). +registration(r2369,c21,s699). +registration(r2370,c49,s700). +registration(r2371,c18,s700). +registration(r2372,c118,s700). +registration(r2373,c82,s700). +registration(r2374,c64,s700). +registration(r2375,c86,s701). +registration(r2376,c1,s701). +registration(r2377,c23,s701). +registration(r2378,c47,s701). +registration(r2379,c53,s702). +registration(r2380,c2,s702). +registration(r2381,c27,s702). +registration(r2382,c62,s702). +registration(r2383,c87,s703). +registration(r2384,c67,s703). +registration(r2385,c4,s703). +registration(r2386,c96,s704). +registration(r2387,c66,s704). +registration(r2388,c8,s704). +registration(r2389,c68,s705). +registration(r2390,c5,s705). +registration(r2391,c10,s705). +registration(r2392,c23,s706). +registration(r2393,c41,s706). +registration(r2394,c13,s706). +registration(r2395,c15,s707). +registration(r2396,c111,s707). +registration(r2397,c36,s707). +registration(r2398,c30,s707). +registration(r2399,c28,s708). +registration(r2400,c57,s708). +registration(r2401,c65,s708). +registration(r2402,c24,s709). +registration(r2403,c103,s709). +registration(r2404,c122,s709). +registration(r2405,c90,s710). +registration(r2406,c59,s710). +registration(r2407,c103,s710). +registration(r2408,c42,s710). +registration(r2409,c54,s711). +registration(r2410,c28,s711). +registration(r2411,c3,s711). +registration(r2412,c44,s712). +registration(r2413,c64,s712). +registration(r2414,c12,s712). +registration(r2415,c124,s713). +registration(r2416,c79,s713). +registration(r2417,c104,s713). +registration(r2418,c5,s714). +registration(r2419,c83,s714). +registration(r2420,c106,s714). +registration(r2421,c3,s715). +registration(r2422,c15,s715). +registration(r2423,c69,s715). +registration(r2424,c31,s716). +registration(r2425,c56,s716). +registration(r2426,c85,s716). +registration(r2427,c0,s717). +registration(r2428,c6,s717). +registration(r2429,c104,s717). +registration(r2430,c57,s717). +registration(r2431,c48,s718). +registration(r2432,c121,s718). +registration(r2433,c41,s718). +registration(r2434,c37,s719). +registration(r2435,c44,s719). +registration(r2436,c51,s719). +registration(r2437,c55,s720). +registration(r2438,c19,s720). +registration(r2439,c65,s720). +registration(r2440,c67,s721). +registration(r2441,c111,s721). +registration(r2442,c32,s721). +registration(r2443,c63,s722). +registration(r2444,c118,s722). +registration(r2445,c49,s722). +registration(r2446,c66,s722). +registration(r2447,c21,s723). +registration(r2448,c43,s723). +registration(r2449,c55,s723). +registration(r2450,c103,s724). +registration(r2451,c70,s724). +registration(r2452,c113,s724). +registration(r2453,c22,s724). +registration(r2454,c110,s725). +registration(r2455,c66,s725). +registration(r2456,c87,s725). +registration(r2457,c107,s726). +registration(r2458,c4,s726). +registration(r2459,c90,s726). +registration(r2460,c74,s727). +registration(r2461,c104,s727). +registration(r2462,c7,s727). +registration(r2463,c126,s728). +registration(r2464,c88,s728). +registration(r2465,c55,s728). +registration(r2466,c76,s728). +registration(r2467,c106,s729). +registration(r2468,c65,s729). +registration(r2469,c27,s729). +registration(r2470,c98,s730). +registration(r2471,c35,s730). +registration(r2472,c108,s730). +registration(r2473,c91,s731). +registration(r2474,c54,s731). +registration(r2475,c18,s731). +registration(r2476,c125,s732). +registration(r2477,c35,s732). +registration(r2478,c12,s732). +registration(r2479,c86,s733). +registration(r2480,c45,s733). +registration(r2481,c115,s733). +registration(r2482,c113,s734). +registration(r2483,c85,s734). +registration(r2484,c13,s734). +registration(r2485,c91,s735). +registration(r2486,c28,s735). +registration(r2487,c36,s735). +registration(r2488,c77,s736). +registration(r2489,c90,s736). +registration(r2490,c114,s736). +registration(r2491,c45,s737). +registration(r2492,c20,s737). +registration(r2493,c4,s737). +registration(r2494,c53,s738). +registration(r2495,c61,s738). +registration(r2496,c89,s738). +registration(r2497,c69,s738). +registration(r2498,c25,s739). +registration(r2499,c48,s739). +registration(r2500,c57,s739). +registration(r2501,c6,s739). +registration(r2502,c109,s740). +registration(r2503,c20,s740). +registration(r2504,c91,s740). +registration(r2505,c120,s741). +registration(r2506,c115,s741). +registration(r2507,c101,s741). +registration(r2508,c64,s742). +registration(r2509,c57,s742). +registration(r2510,c123,s742). +registration(r2511,c102,s742). +registration(r2512,c17,s742). +registration(r2513,c38,s743). +registration(r2514,c69,s743). +registration(r2515,c72,s743). +registration(r2516,c10,s744). +registration(r2517,c102,s744). +registration(r2518,c98,s744). +registration(r2519,c28,s744). +registration(r2520,c58,s745). +registration(r2521,c28,s745). +registration(r2522,c71,s745). +registration(r2523,c34,s746). +registration(r2524,c119,s746). +registration(r2525,c32,s746). +registration(r2526,c7,s747). +registration(r2527,c98,s747). +registration(r2528,c45,s747). +registration(r2529,c41,s748). +registration(r2530,c86,s748). +registration(r2531,c2,s748). +registration(r2532,c41,s749). +registration(r2533,c127,s749). +registration(r2534,c49,s749). +registration(r2535,c29,s749). +registration(r2536,c114,s750). +registration(r2537,c1,s750). +registration(r2538,c94,s750). +registration(r2539,c29,s750). +registration(r2540,c37,s751). +registration(r2541,c99,s751). +registration(r2542,c65,s751). +registration(r2543,c57,s751). +registration(r2544,c119,s752). +registration(r2545,c32,s752). +registration(r2546,c37,s752). +registration(r2547,c82,s752). +registration(r2548,c70,s753). +registration(r2549,c30,s753). +registration(r2550,c124,s753). +registration(r2551,c54,s754). +registration(r2552,c6,s754). +registration(r2553,c76,s754). +registration(r2554,c88,s755). +registration(r2555,c83,s755). +registration(r2556,c115,s755). +registration(r2557,c82,s756). +registration(r2558,c84,s756). +registration(r2559,c115,s756). +registration(r2560,c86,s757). +registration(r2561,c45,s757). +registration(r2562,c79,s757). +registration(r2563,c71,s758). +registration(r2564,c125,s758). +registration(r2565,c12,s758). +registration(r2566,c95,s758). +registration(r2567,c12,s759). +registration(r2568,c32,s759). +registration(r2569,c92,s759). +registration(r2570,c18,s760). +registration(r2571,c49,s760). +registration(r2572,c13,s760). +registration(r2573,c101,s761). +registration(r2574,c28,s761). +registration(r2575,c91,s761). +registration(r2576,c46,s762). +registration(r2577,c5,s762). +registration(r2578,c100,s762). +registration(r2579,c58,s763). +registration(r2580,c73,s763). +registration(r2581,c80,s763). +registration(r2582,c47,s763). +registration(r2583,c20,s763). +registration(r2584,c61,s764). +registration(r2585,c92,s764). +registration(r2586,c21,s764). +registration(r2587,c53,s765). +registration(r2588,c121,s765). +registration(r2589,c19,s765). +registration(r2590,c68,s765). +registration(r2591,c4,s766). +registration(r2592,c84,s766). +registration(r2593,c45,s766). +registration(r2594,c8,s767). +registration(r2595,c27,s767). +registration(r2596,c98,s767). +registration(r2597,c70,s768). +registration(r2598,c81,s768). +registration(r2599,c31,s768). +registration(r2600,c24,s768). +registration(r2601,c24,s769). +registration(r2602,c74,s769). +registration(r2603,c6,s769). +registration(r2604,c99,s769). +registration(r2605,c66,s770). +registration(r2606,c36,s770). +registration(r2607,c76,s770). +registration(r2608,c95,s771). +registration(r2609,c110,s771). +registration(r2610,c40,s771). +registration(r2611,c125,s772). +registration(r2612,c80,s772). +registration(r2613,c92,s772). +registration(r2614,c120,s773). +registration(r2615,c78,s773). +registration(r2616,c15,s773). +registration(r2617,c22,s773). +registration(r2618,c56,s774). +registration(r2619,c22,s774). +registration(r2620,c122,s774). +registration(r2621,c67,s775). +registration(r2622,c45,s775). +registration(r2623,c93,s775). +registration(r2624,c30,s775). +registration(r2625,c111,s776). +registration(r2626,c92,s776). +registration(r2627,c22,s776). +registration(r2628,c60,s776). +registration(r2629,c53,s776). +registration(r2630,c96,s777). +registration(r2631,c121,s777). +registration(r2632,c50,s777). +registration(r2633,c33,s778). +registration(r2634,c10,s778). +registration(r2635,c79,s778). +registration(r2636,c103,s779). +registration(r2637,c6,s779). +registration(r2638,c123,s779). +registration(r2639,c117,s780). +registration(r2640,c71,s780). +registration(r2641,c76,s780). +registration(r2642,c40,s781). +registration(r2643,c4,s781). +registration(r2644,c8,s781). +registration(r2645,c100,s782). +registration(r2646,c94,s782). +registration(r2647,c0,s782). +registration(r2648,c54,s783). +registration(r2649,c1,s783). +registration(r2650,c94,s783). +registration(r2651,c52,s784). +registration(r2652,c10,s784). +registration(r2653,c63,s784). +registration(r2654,c123,s784). +registration(r2655,c105,s785). +registration(r2656,c1,s785). +registration(r2657,c84,s785). +registration(r2658,c30,s785). +registration(r2659,c81,s786). +registration(r2660,c106,s786). +registration(r2661,c3,s786). +registration(r2662,c8,s786). +registration(r2663,c79,s787). +registration(r2664,c91,s787). +registration(r2665,c122,s787). +registration(r2666,c123,s788). +registration(r2667,c84,s788). +registration(r2668,c30,s788). +registration(r2669,c125,s789). +registration(r2670,c27,s789). +registration(r2671,c10,s789). +registration(r2672,c72,s790). +registration(r2673,c51,s790). +registration(r2674,c33,s790). +registration(r2675,c35,s791). +registration(r2676,c118,s791). +registration(r2677,c39,s791). +registration(r2678,c121,s792). +registration(r2679,c44,s792). +registration(r2680,c67,s792). +registration(r2681,c75,s793). +registration(r2682,c16,s793). +registration(r2683,c29,s793). +registration(r2684,c87,s794). +registration(r2685,c64,s794). +registration(r2686,c25,s794). +registration(r2687,c112,s795). +registration(r2688,c115,s795). +registration(r2689,c13,s795). +registration(r2690,c52,s796). +registration(r2691,c67,s796). +registration(r2692,c88,s796). +registration(r2693,c117,s797). +registration(r2694,c122,s797). +registration(r2695,c90,s797). +registration(r2696,c28,s798). +registration(r2697,c22,s798). +registration(r2698,c106,s798). +registration(r2699,c43,s799). +registration(r2700,c42,s799). +registration(r2701,c105,s799). +registration(r2702,c45,s800). +registration(r2703,c30,s800). +registration(r2704,c51,s800). +registration(r2705,c36,s800). +registration(r2706,c55,s801). +registration(r2707,c8,s801). +registration(r2708,c50,s801). +registration(r2709,c103,s802). +registration(r2710,c117,s802). +registration(r2711,c4,s802). +registration(r2712,c122,s803). +registration(r2713,c57,s803). +registration(r2714,c53,s803). +registration(r2715,c117,s803). +registration(r2716,c45,s804). +registration(r2717,c97,s804). +registration(r2718,c50,s804). +registration(r2719,c12,s804). +registration(r2720,c111,s805). +registration(r2721,c83,s805). +registration(r2722,c76,s805). +registration(r2723,c127,s806). +registration(r2724,c99,s806). +registration(r2725,c8,s806). +registration(r2726,c16,s807). +registration(r2727,c87,s807). +registration(r2728,c77,s807). +registration(r2729,c67,s808). +registration(r2730,c65,s808). +registration(r2731,c125,s808). +registration(r2732,c54,s809). +registration(r2733,c83,s809). +registration(r2734,c84,s809). +registration(r2735,c2,s810). +registration(r2736,c15,s810). +registration(r2737,c88,s810). +registration(r2738,c28,s810). +registration(r2739,c119,s811). +registration(r2740,c110,s811). +registration(r2741,c2,s811). +registration(r2742,c96,s811). +registration(r2743,c121,s811). +registration(r2744,c106,s812). +registration(r2745,c38,s812). +registration(r2746,c20,s812). +registration(r2747,c99,s813). +registration(r2748,c55,s813). +registration(r2749,c59,s813). +registration(r2750,c56,s814). +registration(r2751,c68,s814). +registration(r2752,c54,s814). +registration(r2753,c11,s814). +registration(r2754,c28,s815). +registration(r2755,c62,s815). +registration(r2756,c13,s815). +registration(r2757,c22,s815). +registration(r2758,c69,s816). +registration(r2759,c74,s816). +registration(r2760,c13,s816). +registration(r2761,c33,s817). +registration(r2762,c22,s817). +registration(r2763,c80,s817). +registration(r2764,c118,s817). +registration(r2765,c48,s818). +registration(r2766,c123,s818). +registration(r2767,c115,s818). +registration(r2768,c51,s818). +registration(r2769,c58,s819). +registration(r2770,c45,s819). +registration(r2771,c104,s819). +registration(r2772,c87,s820). +registration(r2773,c21,s820). +registration(r2774,c113,s820). +registration(r2775,c126,s821). +registration(r2776,c31,s821). +registration(r2777,c104,s821). +registration(r2778,c99,s821). +registration(r2779,c33,s822). +registration(r2780,c24,s822). +registration(r2781,c1,s822). +registration(r2782,c81,s823). +registration(r2783,c94,s823). +registration(r2784,c47,s823). +registration(r2785,c42,s823). +registration(r2786,c59,s824). +registration(r2787,c34,s824). +registration(r2788,c95,s824). +registration(r2789,c12,s825). +registration(r2790,c83,s825). +registration(r2791,c91,s825). +registration(r2792,c113,s826). +registration(r2793,c97,s826). +registration(r2794,c31,s826). +registration(r2795,c63,s827). +registration(r2796,c46,s827). +registration(r2797,c117,s827). +registration(r2798,c22,s828). +registration(r2799,c61,s828). +registration(r2800,c100,s828). +registration(r2801,c52,s829). +registration(r2802,c57,s829). +registration(r2803,c28,s829). +registration(r2804,c71,s830). +registration(r2805,c54,s830). +registration(r2806,c106,s830). +registration(r2807,c71,s831). +registration(r2808,c50,s831). +registration(r2809,c117,s831). +registration(r2810,c33,s832). +registration(r2811,c20,s832). +registration(r2812,c7,s832). +registration(r2813,c104,s833). +registration(r2814,c0,s833). +registration(r2815,c8,s833). +registration(r2816,c106,s834). +registration(r2817,c117,s834). +registration(r2818,c96,s834). +registration(r2819,c78,s835). +registration(r2820,c3,s835). +registration(r2821,c9,s835). +registration(r2822,c80,s836). +registration(r2823,c50,s836). +registration(r2824,c54,s836). +registration(r2825,c89,s837). +registration(r2826,c1,s837). +registration(r2827,c13,s837). +registration(r2828,c49,s838). +registration(r2829,c112,s838). +registration(r2830,c56,s838). +registration(r2831,c18,s839). +registration(r2832,c34,s839). +registration(r2833,c51,s839). +registration(r2834,c87,s839). +registration(r2835,c5,s840). +registration(r2836,c117,s840). +registration(r2837,c56,s840). +registration(r2838,c6,s841). +registration(r2839,c87,s841). +registration(r2840,c77,s841). +registration(r2841,c29,s842). +registration(r2842,c37,s842). +registration(r2843,c12,s842). +registration(r2844,c102,s843). +registration(r2845,c89,s843). +registration(r2846,c9,s843). +registration(r2847,c59,s844). +registration(r2848,c37,s844). +registration(r2849,c56,s844). +registration(r2850,c74,s845). +registration(r2851,c22,s845). +registration(r2852,c8,s845). +registration(r2853,c95,s845). +registration(r2854,c105,s846). +registration(r2855,c13,s846). +registration(r2856,c23,s846). +registration(r2857,c29,s847). +registration(r2858,c19,s847). +registration(r2859,c33,s847). +registration(r2860,c106,s847). +registration(r2861,c51,s848). +registration(r2862,c119,s848). +registration(r2863,c22,s848). +registration(r2864,c113,s849). +registration(r2865,c58,s849). +registration(r2866,c18,s849). +registration(r2867,c55,s850). +registration(r2868,c40,s850). +registration(r2869,c107,s850). +registration(r2870,c115,s850). +registration(r2871,c22,s850). +registration(r2872,c88,s851). +registration(r2873,c26,s851). +registration(r2874,c118,s851). +registration(r2875,c13,s852). +registration(r2876,c127,s852). +registration(r2877,c121,s852). +registration(r2878,c27,s852). +registration(r2879,c57,s853). +registration(r2880,c125,s853). +registration(r2881,c89,s853). +registration(r2882,c112,s854). +registration(r2883,c29,s854). +registration(r2884,c82,s854). +registration(r2885,c101,s855). +registration(r2886,c81,s855). +registration(r2887,c78,s855). +registration(r2888,c59,s856). +registration(r2889,c43,s856). +registration(r2890,c110,s856). +registration(r2891,c70,s857). +registration(r2892,c88,s857). +registration(r2893,c56,s857). +registration(r2894,c0,s857). +registration(r2895,c8,s858). +registration(r2896,c122,s858). +registration(r2897,c113,s858). +registration(r2898,c44,s858). +registration(r2899,c25,s859). +registration(r2900,c111,s859). +registration(r2901,c26,s859). +registration(r2902,c95,s859). +registration(r2903,c97,s860). +registration(r2904,c64,s860). +registration(r2905,c16,s860). +registration(r2906,c96,s860). +registration(r2907,c99,s861). +registration(r2908,c14,s861). +registration(r2909,c29,s861). +registration(r2910,c125,s861). +registration(r2911,c83,s862). +registration(r2912,c67,s862). +registration(r2913,c50,s862). +registration(r2914,c77,s862). +registration(r2915,c84,s863). +registration(r2916,c85,s863). +registration(r2917,c45,s863). +registration(r2918,c67,s864). +registration(r2919,c114,s864). +registration(r2920,c9,s864). +registration(r2921,c24,s864). +registration(r2922,c18,s865). +registration(r2923,c68,s865). +registration(r2924,c121,s865). +registration(r2925,c64,s866). +registration(r2926,c103,s866). +registration(r2927,c52,s866). +registration(r2928,c82,s867). +registration(r2929,c51,s867). +registration(r2930,c116,s867). +registration(r2931,c56,s867). +registration(r2932,c96,s868). +registration(r2933,c19,s868). +registration(r2934,c5,s868). +registration(r2935,c104,s868). +registration(r2936,c65,s869). +registration(r2937,c45,s869). +registration(r2938,c75,s869). +registration(r2939,c31,s869). +registration(r2940,c56,s870). +registration(r2941,c44,s870). +registration(r2942,c109,s870). +registration(r2943,c102,s871). +registration(r2944,c30,s871). +registration(r2945,c68,s871). +registration(r2946,c122,s871). +registration(r2947,c74,s872). +registration(r2948,c123,s872). +registration(r2949,c76,s872). +registration(r2950,c121,s873). +registration(r2951,c4,s873). +registration(r2952,c40,s873). +registration(r2953,c46,s873). +registration(r2954,c109,s874). +registration(r2955,c126,s874). +registration(r2956,c7,s874). +registration(r2957,c82,s875). +registration(r2958,c53,s875). +registration(r2959,c77,s875). +registration(r2960,c122,s876). +registration(r2961,c20,s876). +registration(r2962,c57,s876). +registration(r2963,c87,s877). +registration(r2964,c47,s877). +registration(r2965,c33,s877). +registration(r2966,c108,s878). +registration(r2967,c88,s878). +registration(r2968,c118,s878). +registration(r2969,c112,s879). +registration(r2970,c109,s879). +registration(r2971,c113,s879). +registration(r2972,c29,s879). +registration(r2973,c56,s880). +registration(r2974,c4,s880). +registration(r2975,c38,s880). +registration(r2976,c121,s881). +registration(r2977,c30,s881). +registration(r2978,c127,s881). +registration(r2979,c119,s881). +registration(r2980,c52,s882). +registration(r2981,c70,s882). +registration(r2982,c100,s882). +registration(r2983,c19,s883). +registration(r2984,c81,s883). +registration(r2985,c122,s883). +registration(r2986,c83,s884). +registration(r2987,c51,s884). +registration(r2988,c38,s884). +registration(r2989,c21,s885). +registration(r2990,c13,s885). +registration(r2991,c111,s885). +registration(r2992,c40,s886). +registration(r2993,c31,s886). +registration(r2994,c83,s886). +registration(r2995,c81,s886). +registration(r2996,c47,s887). +registration(r2997,c81,s887). +registration(r2998,c108,s887). +registration(r2999,c33,s888). +registration(r3000,c1,s888). +registration(r3001,c47,s888). +registration(r3002,c65,s889). +registration(r3003,c33,s889). +registration(r3004,c25,s889). +registration(r3005,c109,s890). +registration(r3006,c50,s890). +registration(r3007,c6,s890). +registration(r3008,c87,s890). +registration(r3009,c23,s891). +registration(r3010,c71,s891). +registration(r3011,c55,s891). +registration(r3012,c87,s892). +registration(r3013,c22,s892). +registration(r3014,c127,s892). +registration(r3015,c46,s893). +registration(r3016,c122,s893). +registration(r3017,c78,s893). +registration(r3018,c112,s894). +registration(r3019,c107,s894). +registration(r3020,c114,s894). +registration(r3021,c50,s894). +registration(r3022,c98,s895). +registration(r3023,c36,s895). +registration(r3024,c50,s895). +registration(r3025,c101,s895). +registration(r3026,c72,s896). +registration(r3027,c26,s896). +registration(r3028,c60,s896). +registration(r3029,c3,s897). +registration(r3030,c28,s897). +registration(r3031,c118,s897). +registration(r3032,c12,s898). +registration(r3033,c114,s898). +registration(r3034,c29,s898). +registration(r3035,c23,s899). +registration(r3036,c62,s899). +registration(r3037,c11,s899). +registration(r3038,c119,s900). +registration(r3039,c77,s900). +registration(r3040,c110,s900). +registration(r3041,c2,s900). +registration(r3042,c39,s901). +registration(r3043,c53,s901). +registration(r3044,c19,s901). +registration(r3045,c92,s902). +registration(r3046,c83,s902). +registration(r3047,c85,s902). +registration(r3048,c89,s902). +registration(r3049,c92,s903). +registration(r3050,c124,s903). +registration(r3051,c74,s903). +registration(r3052,c60,s903). +registration(r3053,c108,s904). +registration(r3054,c120,s904). +registration(r3055,c93,s904). +registration(r3056,c53,s904). +registration(r3057,c95,s905). +registration(r3058,c101,s905). +registration(r3059,c97,s905). +registration(r3060,c100,s906). +registration(r3061,c48,s906). +registration(r3062,c38,s906). +registration(r3063,c102,s906). +registration(r3064,c68,s907). +registration(r3065,c127,s907). +registration(r3066,c23,s907). +registration(r3067,c85,s907). +registration(r3068,c30,s908). +registration(r3069,c47,s908). +registration(r3070,c54,s908). +registration(r3071,c5,s909). +registration(r3072,c36,s909). +registration(r3073,c57,s909). +registration(r3074,c22,s910). +registration(r3075,c118,s910). +registration(r3076,c82,s910). +registration(r3077,c85,s910). +registration(r3078,c98,s911). +registration(r3079,c3,s911). +registration(r3080,c13,s911). +registration(r3081,c51,s912). +registration(r3082,c82,s912). +registration(r3083,c25,s912). +registration(r3084,c24,s912). +registration(r3085,c6,s913). +registration(r3086,c47,s913). +registration(r3087,c110,s913). +registration(r3088,c29,s914). +registration(r3089,c19,s914). +registration(r3090,c104,s914). +registration(r3091,c25,s914). +registration(r3092,c81,s914). +registration(r3093,c11,s915). +registration(r3094,c40,s915). +registration(r3095,c103,s915). +registration(r3096,c123,s915). +registration(r3097,c86,s916). +registration(r3098,c50,s916). +registration(r3099,c74,s916). +registration(r3100,c17,s917). +registration(r3101,c14,s917). +registration(r3102,c116,s917). +registration(r3103,c98,s918). +registration(r3104,c122,s918). +registration(r3105,c63,s918). +registration(r3106,c47,s919). +registration(r3107,c71,s919). +registration(r3108,c118,s919). +registration(r3109,c94,s920). +registration(r3110,c101,s920). +registration(r3111,c115,s920). +registration(r3112,c126,s921). +registration(r3113,c18,s921). +registration(r3114,c29,s921). +registration(r3115,c5,s921). +registration(r3116,c86,s922). +registration(r3117,c64,s922). +registration(r3118,c80,s922). +registration(r3119,c99,s922). +registration(r3120,c62,s923). +registration(r3121,c117,s923). +registration(r3122,c70,s923). +registration(r3123,c65,s924). +registration(r3124,c38,s924). +registration(r3125,c64,s924). +registration(r3126,c7,s925). +registration(r3127,c98,s925). +registration(r3128,c35,s925). +registration(r3129,c7,s926). +registration(r3130,c86,s926). +registration(r3131,c43,s926). +registration(r3132,c62,s927). +registration(r3133,c90,s927). +registration(r3134,c83,s927). +registration(r3135,c42,s928). +registration(r3136,c14,s928). +registration(r3137,c49,s928). +registration(r3138,c19,s928). +registration(r3139,c25,s929). +registration(r3140,c5,s929). +registration(r3141,c89,s929). +registration(r3142,c93,s929). +registration(r3143,c39,s930). +registration(r3144,c29,s930). +registration(r3145,c5,s930). +registration(r3146,c103,s931). +registration(r3147,c32,s931). +registration(r3148,c6,s931). +registration(r3149,c92,s932). +registration(r3150,c82,s932). +registration(r3151,c102,s932). +registration(r3152,c62,s932). +registration(r3153,c5,s933). +registration(r3154,c95,s933). +registration(r3155,c32,s933). +registration(r3156,c79,s934). +registration(r3157,c10,s934). +registration(r3158,c124,s934). +registration(r3159,c2,s935). +registration(r3160,c59,s935). +registration(r3161,c37,s935). +registration(r3162,c76,s936). +registration(r3163,c124,s936). +registration(r3164,c91,s936). +registration(r3165,c66,s937). +registration(r3166,c107,s937). +registration(r3167,c39,s937). +registration(r3168,c4,s937). +registration(r3169,c62,s938). +registration(r3170,c121,s938). +registration(r3171,c52,s938). +registration(r3172,c58,s939). +registration(r3173,c47,s939). +registration(r3174,c90,s939). +registration(r3175,c41,s940). +registration(r3176,c116,s940). +registration(r3177,c25,s940). +registration(r3178,c23,s940). +registration(r3179,c71,s941). +registration(r3180,c60,s941). +registration(r3181,c123,s941). +registration(r3182,c118,s941). +registration(r3183,c120,s942). +registration(r3184,c82,s942). +registration(r3185,c23,s942). +registration(r3186,c64,s943). +registration(r3187,c38,s943). +registration(r3188,c83,s943). +registration(r3189,c76,s944). +registration(r3190,c121,s944). +registration(r3191,c52,s944). +registration(r3192,c50,s944). +registration(r3193,c96,s945). +registration(r3194,c28,s945). +registration(r3195,c2,s945). +registration(r3196,c17,s945). +registration(r3197,c21,s946). +registration(r3198,c42,s946). +registration(r3199,c57,s946). +registration(r3200,c51,s947). +registration(r3201,c122,s947). +registration(r3202,c111,s947). +registration(r3203,c68,s948). +registration(r3204,c66,s948). +registration(r3205,c46,s948). +registration(r3206,c2,s948). +registration(r3207,c85,s949). +registration(r3208,c70,s949). +registration(r3209,c57,s949). +registration(r3210,c112,s950). +registration(r3211,c40,s950). +registration(r3212,c115,s950). +registration(r3213,c16,s950). +registration(r3214,c87,s951). +registration(r3215,c18,s951). +registration(r3216,c34,s951). +registration(r3217,c75,s952). +registration(r3218,c44,s952). +registration(r3219,c5,s952). +registration(r3220,c0,s953). +registration(r3221,c35,s953). +registration(r3222,c11,s953). +registration(r3223,c77,s954). +registration(r3224,c35,s954). +registration(r3225,c106,s954). +registration(r3226,c63,s955). +registration(r3227,c23,s955). +registration(r3228,c52,s955). +registration(r3229,c36,s956). +registration(r3230,c9,s956). +registration(r3231,c75,s956). +registration(r3232,c92,s956). +registration(r3233,c81,s957). +registration(r3234,c36,s957). +registration(r3235,c125,s957). +registration(r3236,c72,s958). +registration(r3237,c114,s958). +registration(r3238,c83,s958). +registration(r3239,c84,s959). +registration(r3240,c29,s959). +registration(r3241,c92,s959). +registration(r3242,c41,s959). +registration(r3243,c108,s960). +registration(r3244,c110,s960). +registration(r3245,c121,s960). +registration(r3246,c17,s961). +registration(r3247,c26,s961). +registration(r3248,c14,s961). +registration(r3249,c24,s962). +registration(r3250,c52,s962). +registration(r3251,c56,s962). +registration(r3252,c9,s962). +registration(r3253,c80,s963). +registration(r3254,c12,s963). +registration(r3255,c78,s963). +registration(r3256,c65,s964). +registration(r3257,c113,s964). +registration(r3258,c80,s964). +registration(r3259,c69,s964). +registration(r3260,c112,s965). +registration(r3261,c15,s965). +registration(r3262,c115,s965). +registration(r3263,c98,s966). +registration(r3264,c19,s966). +registration(r3265,c99,s966). +registration(r3266,c36,s966). +registration(r3267,c31,s967). +registration(r3268,c12,s967). +registration(r3269,c60,s967). +registration(r3270,c115,s968). +registration(r3271,c98,s968). +registration(r3272,c78,s968). +registration(r3273,c91,s969). +registration(r3274,c75,s969). +registration(r3275,c80,s969). +registration(r3276,c65,s969). +registration(r3277,c1,s970). +registration(r3278,c33,s970). +registration(r3279,c10,s970). +registration(r3280,c26,s970). +registration(r3281,c99,s971). +registration(r3282,c42,s971). +registration(r3283,c21,s971). +registration(r3284,c121,s972). +registration(r3285,c85,s972). +registration(r3286,c98,s972). +registration(r3287,c111,s973). +registration(r3288,c49,s973). +registration(r3289,c44,s973). +registration(r3290,c16,s974). +registration(r3291,c0,s974). +registration(r3292,c35,s974). +registration(r3293,c110,s975). +registration(r3294,c20,s975). +registration(r3295,c12,s975). +registration(r3296,c13,s976). +registration(r3297,c29,s976). +registration(r3298,c98,s976). +registration(r3299,c123,s977). +registration(r3300,c96,s977). +registration(r3301,c87,s977). +registration(r3302,c38,s977). +registration(r3303,c10,s977). +registration(r3304,c125,s978). +registration(r3305,c121,s978). +registration(r3306,c1,s978). +registration(r3307,c51,s979). +registration(r3308,c32,s979). +registration(r3309,c26,s979). +registration(r3310,c26,s980). +registration(r3311,c123,s980). +registration(r3312,c115,s980). +registration(r3313,c9,s981). +registration(r3314,c3,s981). +registration(r3315,c102,s981). +registration(r3316,c2,s981). +registration(r3317,c67,s982). +registration(r3318,c15,s982). +registration(r3319,c48,s982). +registration(r3320,c9,s983). +registration(r3321,c81,s983). +registration(r3322,c24,s983). +registration(r3323,c20,s984). +registration(r3324,c28,s984). +registration(r3325,c94,s984). +registration(r3326,c5,s984). +registration(r3327,c41,s984). +registration(r3328,c32,s985). +registration(r3329,c107,s985). +registration(r3330,c88,s985). +registration(r3331,c77,s986). +registration(r3332,c50,s986). +registration(r3333,c81,s986). +registration(r3334,c54,s987). +registration(r3335,c57,s987). +registration(r3336,c72,s987). +registration(r3337,c86,s988). +registration(r3338,c105,s988). +registration(r3339,c58,s988). +registration(r3340,c12,s989). +registration(r3341,c94,s989). +registration(r3342,c21,s989). +registration(r3343,c48,s990). +registration(r3344,c70,s990). +registration(r3345,c123,s990). +registration(r3346,c35,s991). +registration(r3347,c87,s991). +registration(r3348,c67,s991). +registration(r3349,c42,s991). +registration(r3350,c73,s992). +registration(r3351,c69,s992). +registration(r3352,c123,s992). +registration(r3353,c49,s993). +registration(r3354,c88,s993). +registration(r3355,c66,s993). +registration(r3356,c25,s994). +registration(r3357,c84,s994). +registration(r3358,c15,s994). +registration(r3359,c27,s995). +registration(r3360,c63,s995). +registration(r3361,c92,s995). +registration(r3362,c50,s995). +registration(r3363,c75,s995). +registration(r3364,c45,s996). +registration(r3365,c66,s996). +registration(r3366,c33,s996). +registration(r3367,c102,s996). +registration(r3368,c77,s997). +registration(r3369,c44,s997). +registration(r3370,c15,s997). +registration(r3371,c114,s997). +registration(r3372,c54,s997). +registration(r3373,c109,s998). +registration(r3374,c59,s998). +registration(r3375,c15,s998). +registration(r3376,c100,s999). +registration(r3377,c73,s999). +registration(r3378,c122,s999). +registration(r3379,c65,s1000). +registration(r3380,c15,s1000). +registration(r3381,c105,s1000). +registration(r3382,c27,s1000). +registration(r3383,c40,s1001). +registration(r3384,c94,s1001). +registration(r3385,c72,s1001). +registration(r3386,c25,s1001). +registration(r3387,c4,s1002). +registration(r3388,c102,s1002). +registration(r3389,c103,s1002). +registration(r3390,c125,s1003). +registration(r3391,c35,s1003). +registration(r3392,c1,s1003). +registration(r3393,c62,s1003). +registration(r3394,c67,s1004). +registration(r3395,c65,s1004). +registration(r3396,c101,s1004). +registration(r3397,c95,s1004). +registration(r3398,c27,s1005). +registration(r3399,c54,s1005). +registration(r3400,c33,s1005). +registration(r3401,c61,s1006). +registration(r3402,c63,s1006). +registration(r3403,c57,s1006). +registration(r3404,c2,s1007). +registration(r3405,c81,s1007). +registration(r3406,c30,s1007). +registration(r3407,c4,s1008). +registration(r3408,c3,s1008). +registration(r3409,c8,s1008). +registration(r3410,c44,s1008). +registration(r3411,c125,s1009). +registration(r3412,c52,s1009). +registration(r3413,c59,s1009). +registration(r3414,c125,s1010). +registration(r3415,c32,s1010). +registration(r3416,c30,s1010). +registration(r3417,c127,s1010). +registration(r3418,c62,s1011). +registration(r3419,c32,s1011). +registration(r3420,c102,s1011). +registration(r3421,c37,s1012). +registration(r3422,c23,s1012). +registration(r3423,c69,s1012). +registration(r3424,c22,s1013). +registration(r3425,c97,s1013). +registration(r3426,c55,s1013). +registration(r3427,c58,s1014). +registration(r3428,c115,s1014). +registration(r3429,c97,s1014). +registration(r3430,c95,s1015). +registration(r3431,c112,s1015). +registration(r3432,c87,s1015). +registration(r3433,c86,s1016). +registration(r3434,c58,s1016). +registration(r3435,c7,s1016). +registration(r3436,c66,s1017). +registration(r3437,c29,s1017). +registration(r3438,c92,s1017). +registration(r3439,c57,s1018). +registration(r3440,c77,s1018). +registration(r3441,c18,s1018). +registration(r3442,c45,s1018). +registration(r3443,c20,s1019). +registration(r3444,c113,s1019). +registration(r3445,c99,s1019). +registration(r3446,c86,s1019). +registration(r3447,c115,s1020). +registration(r3448,c56,s1020). +registration(r3449,c89,s1020). +registration(r3450,c23,s1020). +registration(r3451,c105,s1021). +registration(r3452,c50,s1021). +registration(r3453,c49,s1021). +registration(r3454,c58,s1022). +registration(r3455,c31,s1022). +registration(r3456,c41,s1022). +registration(r3457,c5,s1023). +registration(r3458,c37,s1023). +registration(r3459,c57,s1023). + + + diff --git a/packages/CLPBN/clpbn/examples/School/tables.yap b/packages/CLPBN/clpbn/examples/School/tables.yap new file mode 100644 index 000000000..21aff50e6 --- /dev/null +++ b/packages/CLPBN/clpbn/examples/School/tables.yap @@ -0,0 +1,45 @@ + +int_table(_, [0.5, + 0.4, + 0.1],[h, m, l]). + +grade_table(I, D, + /* h h h m h l m h m m m l l h l m l l */ + p([a,b,c,d], + [ 0.2, 0.7, 0.85, 0.1, 0.2, 0.5, 0.01, 0.05,0.1 , + 0.6, 0.25, 0.12, 0.3, 0.6,0.35,0.04, 0.15, 0.4 , + 0.15,0.04, 0.02, 0.4,0.15,0.12, 0.5, 0.6, 0.4, + 0.05,0.01, 0.01, 0.2,0.05,0.03, 0.45, 0.2, 0.1 ], [I,D])). + + +/* + A: professor's ability; + B: student's grade (for course registration). +*/ +satisfaction_table(A, G, + /* h a h b h c h d m a m b m c m d l a l b l c l d */ + p([h,m,l], +/*h*/ [0.98, 0.9,0.8 , 0.6, 0.9, 0.4, 0.2, 0.01, 0.5, 0.2, 0.01, 0.01, +/*m*/ 0.01, 0.09,0.15, 0.3,0.05, 0.4, 0.3, 0.04,0.35, 0.3, 0.09, 0.01 , +/*l*/ 0.01, 0.01,0.05, 0.1,0.05, 0.2, 0.5, 0.95,0.15, 0.5, 0.9, 0.98], [A,G])). + + +% The idea is quite simple: +% hs = h -> r = ( 0.9, 0.1, 0) +% hs = m -> r = ( 0.2, 0.6, 0.2) +% hs = l -> r = ( 0, 0.1, 0.9) +% +% add all and divide on the number of elements on the table! +% +rating_prob_table([0.9,0.05,0.01, + 0.09,0.9,0.09, + 0.01,0.05,0.9]). + +abi_table( _, [0.50, 0.40, 0.10]). + + +pop_table(_, [0.9, 0.2, 0.01, + 0.09, 0.6, 0.09, + 0.01, 0.2, 0.9]). + +dif_table( _, [0.25, 0.50, 0.25]). diff --git a/packages/CLPBN/clpbn/examples/cg.yap b/packages/CLPBN/clpbn/examples/cg.yap new file mode 100644 index 000000000..04423248a --- /dev/null +++ b/packages/CLPBN/clpbn/examples/cg.yap @@ -0,0 +1,35 @@ + +% +% adapted from Hendrik Blockeel's ILP04 paper. +% + +:- use_module(library(clpbn)). + +cg(X,1,C):- + father(Y,X), + cg(Y,1,C1),cg(Y,2,C2), + parent_cpt(cg(X,1), C1, C2, C). + +cg(X,2,C):- + mother(Y,X), + cg(Y,1,C1),cg(Y,2,C2), + parent_cpt(cg(X,2), C1, C2, C). + + + +cg(f,X,C) :- + prior_cpt(cg(f,X),C). + +cg(m,X,C) :- + prior_cpt(cg(m,X),C). + + +prior_cpt(CKEY, C) :- + { C = CKEY with p([p,w], [0.5,0.5])}. + +parent_cpt(CKEY, C1, C2, C) :- + { C = CKEY with p([p,w], [ 1,0.5,0.5,0.0, + 0.0,0.5,0.5, 1],[C1,C2])}. + +father(f,s). +mother(m,s). diff --git a/packages/CLPBN/clpbn/examples/sprinkler.yap b/packages/CLPBN/clpbn/examples/sprinkler.yap new file mode 100644 index 000000000..e8cc62742 --- /dev/null +++ b/packages/CLPBN/clpbn/examples/sprinkler.yap @@ -0,0 +1,31 @@ + +:- ensure_loaded(library(clpbn)). + +wet_grass(W) :- + sprinkler(S), + rain(R), + { W = wet with p([f,t], + ([1.0,0.1,0.1,0.01, + 0.0,0.9,0.9,0.99]), + [S,R]) + }. + + +sprinkler(P) :- + cloudy(C), + { P = sprinkler with p([f,t], + [0.5,0.9, + 0.5,0.1], + [C]) + }. + +rain(R) :- + cloudy(C), + { R = rain with p([f,t], [0.8,0.2, + 0.2,0.8], + [C]) }. + +cloudy(C) :- + { C = cloudy with p([f,t],[0.5,0.5],[]) }. + + diff --git a/packages/CLPBN/clpbn/gibbs.yap b/packages/CLPBN/clpbn/gibbs.yap new file mode 100644 index 000000000..ecba78906 --- /dev/null +++ b/packages/CLPBN/clpbn/gibbs.yap @@ -0,0 +1,546 @@ + +% +% each variable is represented by a node in a binary tree. +% each node contains: +% key, +% current_value +% Markov Blanket +% + +:- module(clpbn_gibbs, + [gibbs/3, + check_if_gibbs_done/1, + init_gibbs_solver/4, + run_gibbs_solver/3]). + +:- use_module(library(rbtrees), + [rb_new/1, + rb_insert/4, + rb_lookup/3]). + +:- use_module(library(lists), + [member/2, + append/3, + delete/3, + max_list/2, + sum_list/2]). + +:- use_module(library(ordsets), + [ord_subtract/3]). + +:- use_module(library('clpbn/matrix_cpt_utils'), [ + project_from_CPT/3, + reorder_CPT/5, + multiply_possibly_deterministic_factors/3, + column_from_possibly_deterministic_CPT/3, + normalise_possibly_deterministic_CPT/2, + list_from_CPT/2]). + +:- use_module(library('clpbn/utils'), [ + check_for_hidden_vars/3]). + +:- use_module(library('clpbn/dists'), [ + get_possibly_deterministic_dist_matrix/5, + get_dist_domain_size/2]). + +:- use_module(library('clpbn/topsort'), [ + topsort/2]). + +:- use_module(library('clpbn/display'), [ + clpbn_bind_vals/3]). + +:- use_module(library('clpbn/connected'), + [ + influences/4 + ]). + +:- dynamic gibbs_params/3. + +:- dynamic explicit/1. + +% arguments: +% +% list of output variables +% list of attributed variables +% +gibbs(LVs,Vs0,AllDiffs) :- + init_gibbs_solver(LVs, Vs0, AllDiffs, Vs), + run_gibbs_solver(LVs, LPs, Vs), + clpbn_bind_vals(LVs,LPs,AllDiffs), + clean_up. + +init_gibbs_solver(GoalVs, Vs0, _, Vs) :- + clean_up, + term_variables(GoalVs, LVs), + check_for_hidden_vars(Vs0, Vs0, Vs1), + influences(Vs1, LVs, _, Vs2), + sort(Vs2,Vs). + +run_gibbs_solver(LVs, LPs, Vs) :- + initialise(Vs, Graph, LVs, OutputVars, VarOrder), + process(VarOrder, Graph, OutputVars, Estimates), + sum_up_all(Estimates, LPs), + clean_up. + +initialise(LVs, Graph, GVs, OutputVars, VarOrder) :- + init_keys(Keys0), + gen_keys(LVs, 0, VLen, Keys0, Keys), + functor(Graph,graph,VLen), + graph_representation(LVs, Graph, 0, Keys, TGraph), + compile_graph(Graph), + topsort(TGraph, VarOrder), +%writeln(TGraph:VarOrder), +% show_sorted(VarOrder, Graph), + add_all_output_vars(GVs, Keys, OutputVars). + +init_keys(Keys0) :- + rb_new(Keys0). + +gen_keys([], I, I, Keys, Keys). +gen_keys([V|Vs], I0, If, Keys0, Keys) :- + clpbn:get_atts(V,[evidence(_)]), !, + gen_keys(Vs, I0, If, Keys0, Keys). +gen_keys([V|Vs], I0, If, Keys0, Keys) :- + I is I0+1, + rb_insert(Keys0,V,I,KeysI), + gen_keys(Vs, I, If, KeysI, Keys). + +graph_representation([],_,_,_,[]). +graph_representation([V|Vs], Graph, I0, Keys, TGraph) :- + clpbn:get_atts(V,[evidence(_)]), !, + clpbn:get_atts(V, [dist(Id,Parents)]), + get_possibly_deterministic_dist_matrix(Id, Parents, _, Vals, Table), + get_sizes(Parents, Szs), + length(Vals,Sz), + project_evidence_out([V|Parents],[V|Parents],Table,[Sz|Szs],Variables,NewTable), + % all variables are parents + propagate2parents(Variables, NewTable, Variables, Graph, Keys), + graph_representation(Vs, Graph, I0, Keys, TGraph). +graph_representation([V|Vs], Graph, I0, Keys, [I-IParents|TGraph]) :- + I is I0+1, + clpbn:get_atts(V, [dist(Id,Parents)]), + get_possibly_deterministic_dist_matrix(Id, Parents, _, Vals, Table), + get_sizes(Parents, Szs), + length(Vals,Sz), + project_evidence_out([V|Parents],[V|Parents],Table,[Sz|Szs],Variables,NewTable), + Variables = [V|NewParents], + sort_according_to_indices(NewParents,Keys,SortedNVs,SortedIndices), + reorder_CPT(Variables,NewTable,[V|SortedNVs],NewTable2,_), + add2graph(V, Vals, NewTable2, SortedIndices, Graph, Keys), + propagate2parents(NewParents, NewTable, Variables, Graph,Keys), + parent_indices(NewParents, Keys, IVariables0), + sort(IVariables0, IParents), + arg(I, Graph, var(_,_,_,_,_,_,_,NewTable2,SortedIndices)), + graph_representation(Vs, Graph, I, Keys, TGraph). + +write_pars([]). +write_pars([V|Parents]) :- + clpbn:get_atts(V, [key(K),dist(I,_)]),write(K:I),nl, + write_pars(Parents). + +get_sizes([], []). +get_sizes([V|Parents], [Sz|Szs]) :- + clpbn:get_atts(V, [dist(Id,_)]), + get_dist_domain_size(Id, Sz), + get_sizes(Parents, Szs). + +parent_indices([], _, []). +parent_indices([V|Parents], Keys, [I|IParents]) :- + rb_lookup(V, I, Keys), + parent_indices(Parents, Keys, IParents). + + + +% +% first, remove nodes that have evidence from tables. +% +project_evidence_out([],Deps,Table,_,Deps,Table). +project_evidence_out([V|Parents],Deps,Table,Szs,NewDeps,NewTable) :- + clpbn:get_atts(V,[evidence(_)]), !, + project_from_CPT(V,tab(Table,Deps,Szs),tab(ITable,IDeps,ISzs)), + project_evidence_out(Parents,IDeps,ITable,ISzs,NewDeps,NewTable). +project_evidence_out([_Par|Parents],Deps,Table,Szs,NewDeps,NewTable) :- + project_evidence_out(Parents,Deps,Table,Szs,NewDeps,NewTable). + +propagate2parents([], _, _, _, _). +propagate2parents([V|NewParents], Table, Variables, Graph, Keys) :- + delete(Variables,V,NVs), + sort_according_to_indices(NVs,Keys,SortedNVs,SortedIndices), + reorder_CPT(Variables,Table,[V|SortedNVs],NewTable,_), + add2graph(V, _, NewTable, SortedIndices, Graph, Keys), + propagate2parents(NewParents,Table, Variables, Graph, Keys). + +add2graph(V, Vals, Table, IParents, Graph, Keys) :- + rb_lookup(V, Index, Keys), + (var(Vals) -> true ; length(Vals,Sz)), + arg(Index, Graph, var(V,Index,_,Vals,Sz,VarSlot,_,_,_)), + member(tabular(Table,Index,IParents), VarSlot), !. + +sort_according_to_indices(NVs,Keys,SortedNVs,SortedIndices) :- + vars2indices(NVs,Keys,ToSort), + keysort(ToSort, Sorted), + split_parents(Sorted, SortedNVs,SortedIndices). + +split_parents([], [], []). +split_parents([I-V|Sorted], [V|SortedNVs],[I|SortedIndices]) :- + split_parents(Sorted, SortedNVs, SortedIndices). + + +vars2indices([],_,[]). +vars2indices([V|Parents],Keys,[I-V|IParents]) :- + rb_lookup(V, I, Keys), + vars2indices(Parents,Keys,IParents). + +% +% This is the really cool bit. +% +compile_graph(Graph) :- + Graph =.. [_|VarsInfo], + compile_vars(VarsInfo,Graph). + +compile_vars([],_). +compile_vars([var(_,I,_,Vals,Sz,VarSlot,Parents,_,_)|VarsInfo],Graph) +:- + compile_var(I,Vals,Sz,VarSlot,Parents,Graph), + compile_vars(VarsInfo,Graph). + +compile_var(I,Vals,Sz,VarSlot,Parents,Graph) :- + fetch_all_parents(VarSlot,Graph,[],Parents,[],Sizes), + mult_list(Sizes,1,TotSize), + compile_var(TotSize,I,Vals,Sz,VarSlot,Parents,Sizes,Graph). + +fetch_all_parents([],_,Parents,Parents,Sizes,Sizes) :- !. +fetch_all_parents([tabular(_,_,Ps)|CPTs],Graph,Parents0,ParentsF,Sizes0,SizesF) :- + merge_these_parents(Ps,Graph,Parents0,ParentsI,Sizes0,SizesI), + fetch_all_parents(CPTs,Graph,ParentsI,ParentsF,SizesI,SizesF). + +merge_these_parents([],_,Parents,Parents,Sizes,Sizes). +merge_these_parents([I|Ps],Graph,Parents0,ParentsF,Sizes0,SizesF) :- + member(I,Parents0), !, + merge_these_parents(Ps,Graph,Parents0,ParentsF,Sizes0,SizesF). +merge_these_parents([I|Ps],Graph,Parents0,ParentsF,Sizes0,SizesF) :- + arg(I,Graph,var(_,I,_,Vals,_,_,_,_,_)), + length(Vals, Sz), + add_parent(Parents0,I,ParentsI,Sizes0,Sz,SizesI), + merge_these_parents(Ps,Graph,ParentsI,ParentsF,SizesI,SizesF). + +add_parent([],I,[I],[],Sz,[Sz]). +add_parent([P|Parents0],I,[I,P|Parents0],Sizes0,Sz,[Sz|Sizes0]) :- + P > I, !. +add_parent([P|Parents0],I,[P|ParentsI],[S|Sizes0],Sz,[S|SizesI]) :- + add_parent(Parents0,I,ParentsI,Sizes0,Sz,SizesI). + + +mult_list([],Mult,Mult). +mult_list([Sz|Sizes],Mult0,Mult) :- + MultI is Sz*Mult0, + mult_list(Sizes,MultI,Mult). + +% compile node as set of facts, faster execution +compile_var(TotSize,I,_Vals,Sz,CPTs,Parents,_Sizes,Graph) :- + TotSize < 1024*64, TotSize > 0, !, + multiply_all(I,Parents,CPTs,Sz,Graph). +% do it dynamically +compile_var(_,_,_,_,_,_,_,_). + +multiply_all(I,Parents,CPTs,Sz,Graph) :- + markov_blanket_instance(Parents,Graph,Values), + ( + multiply_all(CPTs,Graph,Probs) + -> + store_mblanket(I,Values,Probs) + ; + throw(error(domain_error(bayesian_domain),gibbs_cpt(I,Parents,Values,Sz))) + ), + fail. +multiply_all(I,_,_,_,_) :- + assert(explicit(I)). + +% note: what matters is how this predicate instantiates the temp +% slot in the graph! +markov_blanket_instance([],_,[]). +markov_blanket_instance([I|Parents],Graph,[Pos|Values]) :- + arg(I,Graph,var(_,I,Pos,Vals,_,_,_,_,_)), + fetch_val(Vals,0,Pos), + markov_blanket_instance(Parents,Graph,Values). + +% backtrack through every value in domain +% +fetch_val([_|_],Pos,Pos). +fetch_val([_|Vals],I0,Pos) :- + I is I0+1, + fetch_val(Vals,I,Pos). + +multiply_all([tabular(Table,_,Parents)|CPTs],Graph,Probs) :- + fetch_parents(Parents, Graph, Vals), + column_from_possibly_deterministic_CPT(Table,Vals,Probs0), + multiply_more(CPTs,Graph,Probs0,Probs). + +fetch_parents([], _, []). +fetch_parents([P|Parents], Graph, [Val|Vals]) :- + arg(P,Graph,var(_,_,Val,_,_,_,_,_,_)), + fetch_parents(Parents, Graph, Vals). + +multiply_more([],_,Probs0,LProbs) :- + normalise_possibly_deterministic_CPT(Probs0, Probs), + list_from_CPT(Probs, LProbs0), + accumulate_up_list(LProbs0, 0.0, LProbs). +multiply_more([tabular(Table,_,Parents)|CPTs],Graph,Probs0,Probs) :- + fetch_parents(Parents, Graph, Vals), + column_from_possibly_deterministic_CPT(Table, Vals, P0), + multiply_possibly_deterministic_factors(Probs0, P0, ProbsI), + multiply_more(CPTs,Graph,ProbsI,Probs). + +accumulate_up_list([], _, []). +accumulate_up_list([P|LProbs], P0, [P1|L]) :- + P1 is P0+P, + accumulate_up_list(LProbs, P1, L). + + +store_mblanket(I,Values,Probs) :- + recordz(mblanket,m(I,Values,Probs),_). + +add_all_output_vars([], _, []). +add_all_output_vars([Vs|LVs], Keys, [Is|OutputVars]) :- + add_output_vars(Vs, Keys, Is), + add_all_output_vars(LVs, Keys, OutputVars). + +add_output_vars([], _, []). +add_output_vars([V|LVs], Keys, [I|OutputVars]) :- + rb_lookup(V, I, Keys), + add_output_vars(LVs, Keys, OutputVars). + +process(VarOrder, Graph, OutputVars, Estimates) :- + gibbs_params(NChains,BurnIn,NSamples), + functor(Graph,_,Len), + init_chains(NChains,VarOrder,Len,Graph,Chains0), + init_estimates(NChains,OutputVars,Graph,Est0), + process_chains(BurnIn,VarOrder,BurnedIn,Chains0,Graph,Len,Est0,_), + process_chains(NSamples,VarOrder,_,BurnedIn,Graph,Len,Est0,Estimates). + +% +% I use an uniform distribution to generate the initial sample. +% +init_chains(0,_,_,_,[]) :- !. +init_chains(I,VarOrder,Len,Graph,[Chain|Chains]) :- + init_chain(VarOrder,Len,Graph,Chain), + I1 is I-1, + init_chains(I1,VarOrder,Len,Graph,Chains). + + +init_chain(VarOrder,Len,Graph,Chain) :- + functor(Chain,sample,Len), + gen_sample(VarOrder,Graph,Chain). + +gen_sample([],_,_) :- !. +gen_sample([I|Vs],Graph,Chain) :- + arg(I,Graph,var(_,I,_,_,Sz,_,_,_,_)), + Pos is integer(random*Sz), + arg(I,Chain,Pos), + gen_sample(Vs,Graph,Chain). + + +init_estimates(0,_,_,[]) :- !. +init_estimates(NChains,OutputVars,Graph,[Est|Est0]) :- + NChainsI is NChains-1, + init_estimate_all_outvs(OutputVars,Graph,Est), + init_estimates(NChainsI,OutputVars,Graph,Est0). + +init_estimate_all_outvs([],_,[]). +init_estimate_all_outvs([Vs|OutputVars],Graph,[E|Est]) :- + init_estimate(Vs, Graph, E), + init_estimate_all_outvs(OutputVars,Graph,Est). + +init_estimate([],_,[]). +init_estimate([V],Graph,[I|E0L]) :- !, + arg(V,Graph,var(_,I,_,_,Sz,_,_,_,_)), + gen_e0(Sz,E0L). +init_estimate(Vs,Graph,me(Is,Mults,Es)) :- + generate_est_mults(Vs, Is, Graph, Mults, Sz), + gen_e0(Sz,Es). + + +generate_est_mults([], [], _, [], 1). +generate_est_mults([V|Vs], [I|Is], Graph, [M0|Mults], M) :- + arg(V,Graph,var(_,I,_,_,Sz,_,_,_,_)), + generate_est_mults(Vs, Is, Graph, Mults, M0), + M is M0*Sz. + +gen_e0(0,[]) :- !. +gen_e0(Sz,[0|E0L]) :- + Sz1 is Sz-1, + gen_e0(Sz1,E0L). + +process_chains(0,_,F,F,_,_,Est,Est) :- !. +process_chains(ToDo,VarOrder,End,Start,Graph,Len,Est0,Estf) :- +%format('ToDo = ~d~n',[ToDo]), + process_chains(Start,VarOrder,Int,Graph,Len,Est0,Esti), +% (ToDo mod 100 =:= 1 -> statistics,cvt2problist(Esti, Probs), Int =[S|_], format('did ~d: ~w~n ~w~n',[ToDo,Probs,S]) ; true), + ToDo1 is ToDo-1, + process_chains(ToDo1,VarOrder,End,Int,Graph,Len,Esti,Estf). + + +process_chains([], _, [], _, _,[],[]). +process_chains([Sample0|Samples0], VarOrder, [Sample|Samples], Graph, SampLen,[E0|E0s],[Ef|Efs]) :- + functor(Sample,sample,SampLen), + do_sample(VarOrder,Sample,Sample0,Graph), +% format('Sample = ~w~n',[Sample]), + update_estimates(E0,Sample,Ef), + process_chains(Samples0, VarOrder, Samples, Graph, SampLen,E0s,Efs). + +do_sample([],_,_,_). +do_sample([I|VarOrder],Sample,Sample0,Graph) :- + do_var(I,Sample,Sample0,Graph), + do_sample(VarOrder,Sample,Sample0,Graph). + +do_var(I,Sample,Sample0,Graph) :- + ( explicit(I) -> + arg(I,Graph,var(_,_,_,_,_,_,Parents,_,_)), + fetch_parents(Parents,I,Sample,Sample0,Args), + recorded(mblanket,m(I,Args,Vals),_) + ; + arg(I,Graph,var(_,_,_,_,_,CPTs,Parents,_,_)), + fetch_parents(Parents,I,Sample,Sample0,Bindings), + multiply_all_in_context(Parents,Bindings,CPTs,Graph,Vals) + ), + X is random, + pick_new_value(Vals,X,0,Val), + arg(I,Sample,Val). + +multiply_all_in_context(Parents,Args,CPTs,Graph,Vals) :- + set_pos(Parents,Args,Graph), + multiply_all(CPTs,Graph,Vals), + assert(mall(Vals)), fail. +multiply_all_in_context(_,_,_,_,Vals) :- + retract(mall(Vals)). + +set_pos([],[],_). +set_pos([I|Is],[Pos|Args],Graph) :- + arg(I,Graph,var(_,I,Pos,_,_,_,_,_,_)), + set_pos(Is,Args,Graph). + +fetch_parents([],_,_,_,[]). +fetch_parents([P|Parents],I,Sample,Sample0,[VP|Args]) :- + arg(P,Sample,VP), + nonvar(VP), !, + fetch_parents(Parents,I,Sample,Sample0,Args). +fetch_parents([P|Parents],I,Sample,Sample0,[VP|Args]) :- + arg(P,Sample0,VP), + fetch_parents(Parents,I,Sample,Sample0,Args). + +pick_new_value([V|Vals],X,I0,Val) :- + ( X < V -> + Val = I0 + ; + I is I0+1, + pick_new_value(Vals,X,I,Val) + ). + +update_estimates([],_,[]). +update_estimates([Est|E0],Sample,[NEst|Ef]) :- + update_estimate(Est,Sample,NEst), + update_estimates(E0,Sample,Ef). + +update_estimate([I|E],Sample,[I|NE]) :- + arg(I,Sample,V), + update_estimate_for_var(V,E,NE). +update_estimate(me(Is,Mult,E),Sample,me(Is,Mult,NE)) :- + get_estimate_pos(Is, Sample, Mult, 0, V), + update_estimate_for_var(V,E,NE). + +get_estimate_pos([], _, [], V, V). +get_estimate_pos([I|Is], Sample, [M|Mult], V0, V) :- + arg(I,Sample,VV), + VI is VV*M+V0, + get_estimate_pos(Is, Sample, Mult, VI, V). + +update_estimate_for_var(V0,[X|T],[X1|NT]) :- + ( V0 == 0 -> + X1 is X+1, + NT = T + ; + V1 is V0-1, + X1 = X, + update_estimate_for_var(V1,T,NT) + ). + + +check_if_gibbs_done(Var) :- + get_atts(Var, [dist(_)]), !. + +clean_up :- + eraseall(mblanket), + fail. +clean_up :- + retractall(explicit(_)), + fail. +clean_up. + +gibbs_params(5,1000,10000). + +cvt2problist([], []). +cvt2problist([[[_|E]]|Est0], [Ps|Probs]) :- + sum_all(E,0,Sum), + do_probs(E,Sum,Ps), + cvt2problist(Est0, Probs) . + +sum_all([],Sum,Sum). +sum_all([E|Es],S0,Sum) :- + SI is S0+E, + sum_all(Es,SI,Sum). + +do_probs([],_,[]). +do_probs([E|Es],Sum,[P|Ps]) :- + P is E/Sum, + do_probs(Es,Sum,Ps). + +show_sorted([], _) :- nl. +show_sorted([I|VarOrder], Graph) :- + arg(I,Graph,var(V,I,_,_,_,_,_,_,_)), + clpbn:get_atts(V,[key(K)]), + format('~w ',[K]), + show_sorted(VarOrder, Graph). + +sum_up_all([[]|_], []). +sum_up_all([[C|MoreC]|Chains], [Dist|Dists]) :- + extract_sums(Chains, CurrentChains, LeftChains), + sum_up([C|CurrentChains], Dist), + sum_up_all([MoreC|LeftChains], Dists). + +extract_sums([], [], []). +extract_sums([[C|Chains]|MoreChains], [C|CurrentChains], [Chains|LeftChains]) :- + extract_sums(MoreChains, CurrentChains, LeftChains). + +sum_up([[_|Counts]|Chains], Dist) :- + add_up(Counts,Chains, Add), + normalise(Add, Dist). +sum_up([me(_,_,Counts)|Chains], Dist) :- + add_up_mes(Counts,Chains, Add), + normalise(Add, Dist). + +add_up(Counts,[],Counts). +add_up(Counts,[[_|Cs]|Chains], Add) :- + sum_lists(Counts, Cs, NCounts), + add_up(NCounts, Chains, Add). + +add_up_mes(Counts,[],Counts). +add_up_mes(Counts,[me(_,_,Cs)|Chains], Add) :- + sum_lists(Counts, Cs, NCounts), + add_up_mes(NCounts, Chains, Add). + +sum_lists([],[],[]). +sum_lists([Count|Counts], [C|Cs], [NC|NCounts]) :- + NC is Count+C, + sum_lists(Counts, Cs, NCounts). + +normalise(Add, Dist) :- + sum_list(Add, Sum), + divide_list(Add, Sum, Dist). + +divide_list([], _, []). +divide_list([C|Add], Sum, [P|Dist]) :- + P is C/Sum, + divide_list(Add, Sum, Dist). + + + diff --git a/packages/CLPBN/clpbn/graphs.yap b/packages/CLPBN/clpbn/graphs.yap new file mode 100644 index 000000000..e481161fb --- /dev/null +++ b/packages/CLPBN/clpbn/graphs.yap @@ -0,0 +1,43 @@ + +% +% Just output a graph with all the variables. +% + +:- module(clpbn2graph, [clpbn2graph/1]). + +:- use_module(library('clpbn/utils'), [ + check_for_hidden_vars/3]). + +:- use_module(library('clpbn/dists'), [ + get_dist/4]). + +:- attribute node/0. + +clpbn2graph(Vs) :- + check_for_hidden_vars(Vs, Vs, NVs), + clpbn2graph2(NVs). + +clpbn2graph2([]). +clpbn2graph2([V|Vs]) :- + put_atts(V,[node]), + clpbn2graph2(Vs). + +% +% what is actually output +% +attribute_goal(V, node(K,Dom,CPT,TVs,Ev)) :- + get_atts(V, [node]), + clpbn:get_atts(V, [key(K),dist(Id,Vs)]), + get_dist(Id,_,Dom,CPT), + translate_vars(Vs,TVs), + ( clpbn:get_atts(V, [evidence(Ev)]) -> true ; true). + +translate_vars([],[]). +translate_vars([V|Vs],[K|Ks]) :- + clpbn:get_atts(V, [key(K)]), + translate_vars(Vs,Ks). + + + + + diff --git a/packages/CLPBN/clpbn/graphviz.yap b/packages/CLPBN/clpbn/graphviz.yap new file mode 100644 index 000000000..2666b59ce --- /dev/null +++ b/packages/CLPBN/clpbn/graphviz.yap @@ -0,0 +1,71 @@ +:- module(clpbn_gviz, [clpbn2gviz/4]). + +clpbn2gviz(Stream, Name, Network, Output) :- + format(Stream, 'digraph ~w { + graph [ rankdir="LR" ];~n',[Name]), + output_vars(Stream, Network), + info_ouput(Stream, Output), + format(Stream, '}~n',[]). + +output_vars(_, []). +output_vars(Stream, [V|Vs]) :- + output_var(Stream, V), + output_vars(Stream, Vs). + +output_var(Stream, V) :- + clpbn:get_atts(V,[key(Key),evidence(_)]), + output_key(Stream,Key), + format(Stream, ' [ shape=box, style=filled, fillcolor=red, fontsize=18.0 ]~n',[]), + fail. +output_var(Stream, V) :- + clpbn:get_atts(V,[key(Key),dist(_,Parents)]), + Parents = [_|_], !, + format(Stream, ' ',[]), + output_parents(Stream, Parents), + format(' -> ',[]), + output_key(Stream,Key), + nl(Stream). +output_var(_, _). + +info_ouput(_, []). +info_ouput(Stream, [V|Output]) :- + clpbn:get_atts(V,[key(Key)]), + output_key(Stream,Key), + format(Stream, ' [ shape=box, style=filled, fillcolor=green, fontsize=18.0 ]~n',[]), + info_ouput(Stream, Output). + + +output_parents(Stream, [V]) :- !, + clpbn:get_atts(V,[key(Key)]), + output_key(Stream,Key). +output_parents(Stream, L) :- + format(Stream,'{ ',[]), + output_parents1(Stream,L), + format(Stream,'}',[]). + +output_parents1(_,[]). +output_parents1(Stream,[V|L]) :- + clpbn:get_atts(V,[key(Key)]), + output_key(Stream,Key), + put_code(Stream, 0' ), + output_parents1(Stream,L). + + +output_key(Stream, Key) :- + output_key(Stream, 0, Key). + +output_key(Stream, _, Key) :- + primitive(Key), !, + write(Stream, Key). +output_key(Stream, I0, Key) :- + Key =.. [Name|Args], + write(Stream, Name), + I is I0+1, + output_key_args(Stream, I, Args). + +output_key_args(_, _, []). +output_key_args(Stream, I, [Arg|Args]) :- + format(Stream, '~*c', [I,0'_]), + output_key(Stream, I, Arg), + output_key_args(Stream, I, Args). + diff --git a/packages/CLPBN/clpbn/hmm.yap b/packages/CLPBN/clpbn/hmm.yap new file mode 100644 index 000000000..9cea42f0e --- /dev/null +++ b/packages/CLPBN/clpbn/hmm.yap @@ -0,0 +1,83 @@ + + +:- module(hmm, [init_hmm/0, + hmm_state/1, + emission/1]). + +:- ensure_loaded(library(clpbn)). + +:- use_module(library(lists), + [nth/3]). + +:- use_module(library(nbhash), + [nb_hash_new/2, + nb_hash_lookup/3, + nb_hash_insert/3 + ]). + +:- ensure_loaded(library(tries)). + +:- meta_predicate hmm_state(:). + +:- dynamic hmm_tabled/1. + +:- attribute emission/1. + +:- ensure_loaded(library('clpbn/viterbi')). + +init_hmm :- +% retractall(hmm_tabled(_)). +% eraseall(hmm_tabled). +% nb_hash_new(hmm_table, 1000000). + trie_open(Trie), nb_setval(trie,Trie). + +hmm_state(Mod:A) :- !, hmm_state(A,Mod). +hmm_state(A) :- prolog_flag(typein_module,Mod), hmm_state(A,Mod). + +hmm_state(Mod:N/A,_) :- !, + hmm_state(N/A,Mod). +hmm_state((A,B),Mod) :- !, + hmm_state(A,Mod), + hmm_state(B,Mod). +hmm_state(N/A,Mod) :- + atom_codes(N,[TC|_]), + atom_codes(T,[TC]), + build_args(A,LArgs,KArgs,First,Last), + Key =.. [T|KArgs], + Head =.. [N|LArgs], + asserta_static( (Mod:Head :- + ( First > 2 -> + Last = Key, ! + ; + nb_getval(trie, Trie), trie_check_entry(Trie, Key, _) + -> + % leave work for solver! + % + Last = Key, ! + ; + % first time we saw this entry + nb_getval(trie, Trie), trie_put_entry(Trie, Key, _), + fail + ) + ) + ). + +build_args(4,[A,B,C,D],[A,B,C],A,D). +build_args(3, [A,B,C], [A,B],A,C). +build_args(2, [A,B], [A],A,B). + +emission(V) :- + put_atts(V,[emission(Prob)]). + +cvt_vals(aminoacids,[a, c, d, e, f, g, h, i, k, l, m, n, p, q, r, s, t, v, w, y]). +cvt_vals(bool,[t,f]). +cvt_vals(dna,[a,c,g,t]). +cvt_vals(rna,[a,c,g,u]). +cvt_vals([A|B],[A|B]). + +% first, try standard representation +find_probs(Logs,Nth,Log) :- + arg(Nth,Logs,Log). + + + diff --git a/packages/CLPBN/clpbn/jt.yap b/packages/CLPBN/clpbn/jt.yap new file mode 100644 index 000000000..bf5aef811 --- /dev/null +++ b/packages/CLPBN/clpbn/jt.yap @@ -0,0 +1,528 @@ + +:- module(jt, [jt/3, + init_jt_solver/4, + run_jt_solver/3]). + + +:- use_module(library(dgraphs), + [dgraph_new/1, + dgraph_add_edges/3, + dgraph_add_vertex/3, + dgraph_add_vertices/3, + dgraph_edges/2, + dgraph_vertices/2, + dgraph_transpose/2, + dgraph_to_ugraph/2, + ugraph_to_dgraph/2, + dgraph_neighbors/3 + ]). + +:- use_module(library(undgraphs), + [undgraph_new/1, + undgraph_add_edge/4, + undgraph_add_edges/3, + undgraph_del_vertex/3, + undgraph_del_vertices/3, + undgraph_vertices/2, + undgraph_edges/2, + undgraph_neighbors/3, + undgraph_edge/3, + dgraph_to_undgraph/2 + ]). + +:- use_module(library(wundgraphs), + [wundgraph_new/1, + wundgraph_max_tree/3, + wundgraph_add_edges/3, + wundgraph_add_vertices/3, + wundgraph_to_undgraph/2 + ]). + +:- use_module(library(rbtrees), + [rb_new/1, + rb_insert/4, + rb_lookup/3]). + +:- use_module(library(ordsets), + [ord_subset/2, + ord_insert/3, + ord_intersection/3, + ord_del_element/3, + ord_memberchk/2]). + +:- use_module(library(lists), + [reverse/2]). + +:- use_module(library('clpbn/aggregates'), + [check_for_agg_vars/2]). + +:- use_module(library('clpbn/dists'), + [get_dist_domain_size/2, + get_dist_domain/2, + get_dist_matrix/5]). + +:- use_module(library('clpbn/matrix_cpt_utils'), + [project_from_CPT/3, + reorder_CPT/5, + unit_CPT/2, + multiply_CPTs/4, + divide_CPTs/3, + normalise_CPT/2, + expand_CPT/4, + get_CPT_sizes/2, + reset_CPT_that_disagrees/5, + sum_out_from_CPT/4, + list_from_CPT/2]). + +:- use_module(library('clpbn/display'), [ + clpbn_bind_vals/3]). + +:- use_module(library('clpbn/connected'), + [ + init_influences/3, + influences/5 + ]). + + +jt([[]],_,_) :- !. +jt(LLVs,Vs0,AllDiffs) :- + init_jt_solver(LLVs, Vs0, AllDiffs, State), + run_jt_solver(LLVs, LLPs, State), + clpbn_bind_vals(LLVs,LLPs,AllDiffs). + + +init_jt_solver(LLVs, Vs0, _, State) :- + check_for_agg_vars(Vs0, Vs1), + init_influences(Vs1, G, RG), + init_jt_solver_for_questions(LLVs, G, RG, State). + +init_jt_solver_for_questions([], _, _, []). +init_jt_solver_for_questions([LLVs|MoreLLVs], G, RG, [state(JTree, Evidence)|State]) :- + influences(LLVs, _, NVs0, G, RG), + sort(NVs0, NVs), + get_graph(NVs, BayesNet, CPTs, Evidence), + build_jt(BayesNet, CPTs, JTree), + init_jt_solver_for_questions(MoreLLVs, G, RG, State). + +run_jt_solver([], [], []). +run_jt_solver([LVs|MoreLVs], [LPs|MorePs], [state(JTree, Evidence)|MoreState]) :- + % JTree is a dgraph + % now our tree has cpts + fill_with_cpts(JTree, NewTree), +% write_tree(NewTree,0), + propagate_evidence(Evidence, NewTree, EvTree), + message_passing(EvTree, MTree), + get_margin(MTree, LVs, LPs), + run_jt_solver(MoreLVs, MorePs, MoreState). + +get_graph(LVs, BayesNet, CPTs, Evidence) :- + run_vars(LVs, Edges, Vertices, CPTs, Evidence), + dgraph_new(V0), + dgraph_add_edges(V0, Edges, V1), + dgraph_add_vertices(V1, Vertices, V2), + dgraph_to_ugraph(V2, BayesNet). + +run_vars([], [], [], [], []). +run_vars([V|LVs], Edges, [V|Vs], [CPTVars-dist([V|Parents],Id)|CPTs], Ev) :- + clpbn:get_atts(V, [dist(Id,Parents)]), + add_evidence_from_vars(V, Ev, Ev0), + sort([V|Parents],CPTVars), + add_edges(Parents, V, Edges, Edges0), + run_vars(LVs, Edges0, Vs, CPTs, Ev0). + +add_evidence_from_vars(V, [e(V,P)|Evs], Evs) :- + clpbn:get_atts(V, [evidence(P)]), !. +add_evidence_from_vars(_, Evs, Evs). + +find_nth0([Id|_], Id, P, P) :- !. +find_nth0([_|D], Id, P0, P) :- + P1 is P0+1, + find_nth0(D, Id, P1, P). + +add_edges([], _, Edges, Edges). +add_edges([P|Parents], V, [V-P|Edges], Edges0) :- + add_edges(Parents, V, Edges, Edges0). + +build_jt(BayesNet, CPTs, Tree) :- + init_undgraph(BayesNet, Moral0), + moralised(BayesNet, Moral0, Markov), + undgraph_vertices(Markov, Vertices), + triangulate(Vertices, Markov, Markov, _, Cliques0), + cliques(Cliques0, EndCliques), + wundgraph_max_tree(EndCliques, J0Tree, _), + root(J0Tree, JTree), + populate(CPTs, JTree, Tree). + +initial_graph(_,Parents, CPTs) :- + test_graph(0, Graph0, CPTs), + dgraph_new(V0), + dgraph_add_edges(V0, Graph0, V1), + % OK, this is a bit silly, I could have written the transposed graph + % from the very beginning. + dgraph_transpose(V1, V2), + dgraph_to_ugraph(V2, Parents). + + +problem_graph([], []). +problem_graph([V|BNet], GraphF) :- + clpbn:get_atts(V, [dist(_,_,Parents)]), + add_parents(Parents, V, Graph0, GraphF), + problem_graph(BNet, Graph0). + +add_parents([], _, Graph, Graph). +add_parents([P|Parents], V, Graph0, [P-V|GraphF]) :- + add_parents(Parents, V, Graph0, GraphF). + + +% From David Page's lectures +test_graph(0, + [1-3,2-3,2-4,5-4,5-7,10-7,10-9,11-9,3-6,4-6,7-8,9-8,6-12,8-12], + [[1]-a, + [2]-b, + [1,2,3]-c, + [2,4,5]-d, + [5]-e, + [3,4,6]-f, + [5,7,10]-g, + [7,8,9]-h, + [9]-i, + [10]-j, + [11]-k, + [6,8,12]-l + ]). +test_graph(1,[a-b,a-c,b-d,c-e,d-f,e-f], + []). + + +init_undgraph(Parents, UndGraph) :- + ugraph_to_dgraph(Parents, DGraph), + dgraph_to_undgraph(DGraph, UndGraph). + +get_par_keys([], []). +get_par_keys([P|Parents],[K|KPars]) :- + clpbn:get_atts(P, [key(K)]), + get_par_kets(Parents,KPars). + +moralised([],Moral,Moral). +moralised([_-KPars|Ks],Moral0,MoralF) :- + add_moral_edges(KPars, Moral0, MoralI), + moralised(Ks,MoralI,MoralF). + +add_moral_edges([], Moral, Moral). +add_moral_edges([_], Moral, Moral). +add_moral_edges([K1,K2|KPars], Moral0, MoralF) :- + undgraph_add_edge(Moral0, K1, K2, MoralI), + add_moral_edges([K1|KPars], MoralI, MoralJ), + add_moral_edges([K2|KPars],MoralJ,MoralF). + +triangulate([], _, Triangulated, Triangulated, []) :- !. +triangulate(Vertices, S0, T0, Tf, Cliques) :- + choose(Vertices, S0, +inf, [], -1, BestVertex, _, Cliques0, Cliques, Edges), + ord_del_element(Vertices, BestVertex, NextVertices), + undgraph_add_edges(T0, Edges, T1), + undgraph_del_vertex(S0, BestVertex, Si), + undgraph_add_edges(Si, Edges, Si2), + triangulate(NextVertices, Si2, T1, Tf, Cliques0). + +choose([], _, _, NewEdges, Best, Best, Clique, Cliques0, [Clique|Cliques0], NewEdges). +choose([V|Vertices], Graph, Score0, _, _, Best, _, Cliques0, Cliques, EdgesF) :- + undgraph_neighbors(V, Graph, Neighbors), + ord_insert(Neighbors, V, PossibleClique), + new_edges(Neighbors, Graph, NewEdges), + ( + % simplicial edge + NewEdges == [] + -> + !, + Best = V, + NewEdges = EdgesF, + length(PossibleClique,L), + Cliques = [L-PossibleClique|Cliques0] + ; +% cliquelength(PossibleClique,1,CL), + length(PossibleClique,CL), + CL < Score0, !, + choose(Vertices,Graph,CL,NewEdges, V, Best, CL-PossibleClique, Cliques0,Cliques,EdgesF) + ). +choose([_|Vertices], Graph, Score0, Edges0, BestSoFar, Best, Clique, Cliques0, Cliques, EdgesF) :- + choose(Vertices,Graph,Score0,Edges0, BestSoFar, Best, Clique, Cliques0,Cliques,EdgesF). + +new_edges([], _, []). +new_edges([N|Neighbors], Graph, NewEdgesF) :- + new_edges(Neighbors,N,Graph,NewEdges0, NewEdgesF), + new_edges(Neighbors, Graph, NewEdges0). + +new_edges([],_,_,NewEdges, NewEdges). +new_edges([N1|Neighbors],N,Graph,NewEdges0, NewEdgesF) :- + undgraph_edge(N, N1, Graph), !, + new_edges(Neighbors,N,Graph,NewEdges0, NewEdgesF). +new_edges([N1|Neighbors],N,Graph,NewEdges0, [N-N1|NewEdgesF]) :- + new_edges(Neighbors,N,Graph,NewEdges0, NewEdgesF). + +cliquelength([],CL,CL). +cliquelength([V|Vs],CL0,CL) :- + clpbn:get_atts(V, [dist(Id,_)]), + get_dist_domain_size(Id, Sz), + CL1 is CL0*Sz, + cliquelength(Vs,CL1,CL). + + +% +% This is simple stuff, I just have to remove cliques that +% are subset of the others. +% +cliques(CliqueList, CliquesF) :- + wundgraph_new(Cliques0), + % first step, order by size, + keysort(CliqueList,Sort), + reverse(Sort, Rev), + get_links(Rev, [], Vertices, [], Edges), + wundgraph_add_vertices(Cliques0, Vertices, CliquesI), + wundgraph_add_edges(CliquesI, Edges, CliquesF). + +% stupid quadratic algorithm, needs to be improved. +get_links([], Vertices, Vertices, Edges, Edges). +get_links([Sz-Clique|Cliques], SoFar, Vertices, Edges0, Edges) :- + add_clique_edges(SoFar, Clique, Sz, Edges0, EdgesI), !, + get_links(Cliques, [Clique|SoFar], Vertices, EdgesI, Edges). +get_links([_|Cliques], SoFar, Vertices, Edges0, Edges) :- + get_links(Cliques, SoFar, Vertices, Edges0, Edges). + +add_clique_edges([], _, _, Edges, Edges). +add_clique_edges([Clique1|Cliques], Clique, Sz, Edges0, EdgesF) :- + ord_intersection(Clique1, Clique, Int), + Int \== Clique, + ( + Int = [] -> + add_clique_edges(Cliques, Clique, Sz, Edges0, EdgesF) + ; + % we connect + length(Int, LSz), + add_clique_edges(Cliques, Clique, Sz, [Clique-(Clique1-LSz)|Edges0], EdgesF) + ). + +root(WTree, JTree) :- + wundgraph_to_undgraph(WTree, Tree), + remove_leaves(Tree, SmallerTree), + undgraph_vertices(SmallerTree, InnerVs), + pick_root(InnerVs, Root), + rb_new(M0), + build_tree(Root, M0, Tree, JTree, _). + +remove_leaves(Tree, SmallerTree) :- + undgraph_vertices(Tree, Vertices), + Vertices = [_,_,_|_], + get_leaves(Vertices, Tree, Leaves), + Leaves = [_|_], !, + undgraph_del_vertices(Tree, Leaves, NTree), + remove_leaves(NTree, SmallerTree). +remove_leaves(Tree, Tree). + +get_leaves([], _, []). +get_leaves([V|Vertices], Tree, [V|Leaves]) :- + undgraph_neighbors(V, Tree, [_]), !, + get_leaves(Vertices, Tree, Leaves). +get_leaves([_|Vertices], Tree, Leaves) :- + get_leaves(Vertices, Tree, Leaves). + +pick_root([V|_],V). + +direct_edges([], _, [], []) :- !. +direct_edges([], NewVs, RemEdges, Directed) :- + direct_edges(RemEdges, NewVs, [], Directed). +direct_edges([V1-V2|Edges], NewVs0, RemEdges, [V1-V2|Directed]) :- + ord_memberchk(V1, NewVs0), !, + ord_insert(NewVs0, V2, NewVs), + direct_edges(Edges, NewVs, RemEdges, Directed). +direct_edges([V1-V2|Edges], NewVs0, RemEdges, [V2-V1|Directed]) :- + ord_memberchk(V2, NewVs0), !, + ord_insert(NewVs0, V1, NewVs), + direct_edges(Edges, NewVs, RemEdges, Directed). +direct_edges([Edge|Edges], NewVs, RemEdges, Directed) :- + direct_edges(Edges, NewVs, [Edge|RemEdges], Directed). + + +populate(CPTs, JTree, NewJTree) :- + keysort(CPTs, KCPTs), + populate_cliques(JTree, KCPTs, NewJTree, []). + +populate_cliques(tree(Clique,Kids), CPTs, tree(Clique-MyCPTs,NewKids), RemCPTs) :- + get_cpts(CPTs, Clique, MyCPTs, MoreCPTs), + populate_trees_with_cliques(Kids, MoreCPTs, NewKids, RemCPTs). + +populate_trees_with_cliques([], MoreCPTs, [], MoreCPTs). +populate_trees_with_cliques([Node|Kids], MoreCPTs, [NewNode|NewKids], RemCPts) :- + populate_cliques(Node, MoreCPTs, NewNode, ExtraCPTs), + populate_trees_with_cliques(Kids, ExtraCPTs, NewKids, RemCPts). + + +get_cpts([], _, [], []). +get_cpts([CPT|CPts], [], [], [CPT|CPts]) :- !. +get_cpts([[I|MCPT]-Info|CPTs], [J|Clique], MyCPTs, MoreCPTs) :- + compare(C,I,J), + ( C == < -> + % our CPT cannot be a part of the clique. + MoreCPTs = [[I|MCPT]-Info|LeftoverCPTs], + get_cpts(CPTs, [J|Clique], MyCPTs, LeftoverCPTs) + ; + C == = -> + % our CPT cannot be a part of the clique. + get_cpt(MCPT, Clique, I, Info, MyCPTs, MyCPTs0, MoreCPTs, MoreCPTs0), + get_cpts(CPTs, [J|Clique], MyCPTs0, MoreCPTs0) + ; + % the first element in our CPT may not be in a clique + get_cpts([[I|MCPT]-Info|CPTs], Clique, MyCPTs, MoreCPTs) + ). + +get_cpt(MCPT, Clique, I, Info, [[I|MCPT]-Info|MyCPTs], MyCPTs, MoreCPTs, MoreCPTs) :- + ord_subset(MCPT, Clique), !. +get_cpt(MCPT, _, I, Info, MyCPTs, MyCPTs, [[I|MCPT]-Info|MoreCPTs], MoreCPTs). + + +translate_edges([], [], []). +translate_edges([E1-E2|Edges], [(E1-A)-(E2-B)|NEdges], [E1-A,E2-B|Vs]) :- + translate_edges(Edges, NEdges, Vs). + +match_vs(_,[]). +match_vs([K-A|Cls],[K1-B|KVs]) :- + compare(C, K, K1), + (C == = -> + A = B, + match_vs([K-A|Cls], KVs) + ; + C = < -> + match_vs(Cls,[K1-B|KVs]) + ; + match_vs([K-A|Cls],KVs) + ). + +fill_with_cpts(tree(Clique-Dists,Leafs), tree(Clique-NewDists,NewLeafs)) :- + compile_cpts(Dists, Clique, NewDists), + fill_tree_with_cpts(Leafs, NewLeafs). + + +fill_tree_with_cpts([], []). +fill_tree_with_cpts([L|Leafs], [NL|NewLeafs]) :- + fill_with_cpts(L, NL), + fill_tree_with_cpts(Leafs, NewLeafs). + +transform([], []). +transform([Clique-Dists|Nodes],[Clique-NewDist|NewNodes]) :- + compile_cpts(Dists, Clique, NewDist), + transform(Nodes, NewNodes). + +compile_cpts([Vs-dist(OVs,Id)|Dists], Clique, TAB) :- + OVs = [_|Ps], !, + get_dist_matrix(Id, Ps, _, _, TAB0), + reorder_CPT(OVs, TAB0, Vs, TAB1, Sz1), + multiply_dists(Dists,Vs,TAB1,Sz1,Vars2,ITAB), + expand_CPT(ITAB,Vars2,Clique,TAB). +compile_cpts([], [V|Clique], TAB) :- + unit_CPT(V, CPT0), + expand_CPT(CPT0, [V], [V|Clique], TAB). + +multiply_dists([],Vs,TAB,_,Vs,TAB). +multiply_dists([Vs-dist(OVs,Id)|Dists],MVs,TAB2,Sz2,FVars,FTAB) :- + OVs = [_|Ps], + get_dist_matrix(Id, Ps, _, _, TAB0), + reorder_CPT(OVs, TAB0, Vs, TAB1, Sz1), + multiply_CPTs(tab(TAB1,Vs,Sz1),tab(TAB2,MVs,Sz2),tab(TAB3,NVs,Sz),_), + multiply_dists(Dists,NVs,TAB3,Sz,FVars,FTAB). + +build_tree(Root, Leafs, WTree, tree(Root,Leaves), NewLeafs) :- + rb_insert(Leafs, Root, [], Leafs0), + undgraph_neighbors(Root, WTree, Children), + build_trees(Children, Leafs0, WTree, Leaves, NewLeafs). + +build_trees( [], Leafs, _, [], Leafs). +build_trees([V|Children], Leafs, WTree, NLeaves, NewLeafs) :- + % back pointer + rb_lookup(V, _, Leafs), !, + build_trees(Children, Leafs, WTree, NLeaves, NewLeafs). +build_trees([V|Children], Leafs, WTree, [VT|NLeaves], NewLeafs) :- + build_tree(V, Leafs, WTree, VT, Leafs1), + build_trees(Children, Leafs1, WTree, NLeaves, NewLeafs). + + +propagate_evidence([], NewTree, NewTree). +propagate_evidence([e(V,P)|Evs], Tree0, NewTree) :- + add_evidence_to_matrix(Tree0, V, P, Tree1), !, + propagate_evidence(Evs, Tree1, NewTree). + +add_evidence_to_matrix(tree(Clique-Dist,Kids), V, P, tree(Clique-NDist,Kids)) :- + ord_memberchk(V, Clique), !, + reset_CPT_that_disagrees(Dist, Clique, V, P, NDist). +add_evidence_to_matrix(tree(C,Kids), V, P, tree(C,NKids)) :- + add_evidence_to_kids(Kids, V, P, NKids). + +add_evidence_to_kids([K|Kids], V, P, [NK|Kids]) :- + add_evidence_to_matrix(K, V, P, NK), !. +add_evidence_to_kids([K|Kids], V, P, [K|NNKids]) :- + add_evidence_to_kids(Kids, V, P, NNKids). + +message_passing(tree(Clique-Dist,Kids), tree(Clique-NDist,NKids)) :- + get_CPT_sizes(Dist, Sizes), + upward(Kids, Clique, tab(Dist, Clique, Sizes), IKids, ITab, 1), + ITab = tab(NDist, _, _), + nb_setval(cnt,0), + downward(IKids, Clique, ITab, NKids). + +upward([], _, Dist, [], Dist, _). +upward([tree(Clique1-Dist1,DistKids)|Kids], Clique, Tab, [tree(Clique1-(NewDist1,EDist1),NDistKids)|NKids], NewTab, Lev) :- + get_CPT_sizes(Dist1, Sizes1), + Lev1 is Lev+1, + upward(DistKids, Clique1, tab(Dist1,Clique1,Sizes1), NDistKids, NewTab1, Lev1), + NewTab1 = tab(NewDist1,_,_), + ord_intersection(Clique1, Clique, Int), + sum_out_from_CPT(Int, NewDist1, Clique1, Tab1), + multiply_CPTs(Tab, Tab1, ITab, EDist1), + upward(Kids, Clique, ITab, NKids, NewTab, Lev). + +downward([], _, _, []). +downward([tree(Clique1-(Dist1,Msg1),DistKids)|Kids], Clique, Tab, [tree(Clique1-NDist1,NDistKids)|NKids]) :- + get_CPT_sizes(Dist1, Sizes1), + ord_intersection(Clique1, Clique, Int), + Tab = tab(Dist,_,_), + divide_CPTs(Dist, Msg1, Div), + sum_out_from_CPT(Int, Div, Clique, STab), + multiply_CPTs(STab, tab(Dist1, Clique1, Sizes1), NewTab, _), + NewTab = tab(NDist1,_,_), + downward(DistKids, Clique1, NewTab, NDistKids), + downward(Kids, Clique, Tab, NKids). + + +get_margin(NewTree, LVs0, LPs) :- + sort(LVs0, LVs), + find_clique(NewTree, LVs, Clique, Dist), + sum_out_from_CPT(LVs, Dist, Clique, tab(TAB,_,_)), + reorder_CPT(LVs, TAB, LVs0, NTAB, _), + normalise_CPT(NTAB, Ps), + list_from_CPT(Ps, LPs). + +find_clique(tree(Clique-Dist,_), LVs, Clique, Dist) :- + ord_subset(LVs, Clique), !. +find_clique(tree(_,Kids), LVs, Clique, Dist) :- + find_clique_from_kids(Kids, LVs, Clique, Dist). + +find_clique_from_kids([K|_], LVs, Clique, Dist) :- + find_clique(K, LVs, Clique, Dist), !. +find_clique_from_kids([_|Kids], LVs, Clique, Dist) :- + find_clique_from_kids(Kids, LVs, Clique, Dist). + + +write_tree(tree(Clique-(Dist,_),Leaves), I0) :- !, + matrix:matrix_to_list(Dist,L), + format('~*c ~w:~w~n',[I0,0' ,Clique,L]), + I is I0+2, + write_subtree(Leaves, I). +write_tree(tree(Clique-Dist,Leaves), I0) :- + matrix:matrix_to_list(Dist,L), + format('~*c ~w:~w~n',[I0,0' ,Clique, L]), + I is I0+2, + write_subtree(Leaves, I). + +write_subtree([], _). +write_subtree([Tree|Leaves], I) :- + write_tree(Tree, I), + write_subtree(Leaves, I). + diff --git a/packages/CLPBN/clpbn/matrix_cpt_utils.yap b/packages/CLPBN/clpbn/matrix_cpt_utils.yap new file mode 100644 index 000000000..053ec4595 --- /dev/null +++ b/packages/CLPBN/clpbn/matrix_cpt_utils.yap @@ -0,0 +1,267 @@ +:- module(clpbn_matrix_utils, + [init_CPT/2, + project_from_CPT/3, + reorder_CPT/5, + get_CPT_sizes/2, + normalise_CPT/2, + multiply_CPTs/4, + divide_CPTs/3, + expand_CPT/4, + reset_CPT_that_disagrees/5, + unit_CPT/2, + sum_out_from_CPT/4, + list_from_CPT/2, + multiply_factors/3, + normalise_possibly_deterministic_CPT/2, + column_from_possibly_deterministic_CPT/3, + multiply_possibly_deterministic_factors/3, + random_CPT/2, + uniform_CPT/2, + uniform_CPT_as_list/2, + normalise_CPT_on_lines/3]). + +:- use_module(dists, + [get_dist_domain_size/2, + get_dist_domain/2]). + +:- use_module(library(matrix), + [matrix_new/4, + matrix_new_set/4, + matrix_select/4, + matrix_dims/2, + matrix_size/2, + matrix_shuffle/3, + matrix_expand/3, + matrix_op/4, + matrix_dims/2, + matrix_sum/2, + matrix_sum_logs_out/3, + matrix_sum_logs_out_several/3, + matrix_op_to_all/4, + matrix_to_exps2/1, + matrix_to_logs/1, + matrix_set_all_that_disagree/5, + matrix_to_list/2, + matrix_agg_lines/3, + matrix_agg_cols/3, + matrix_op_to_lines/4, + matrix_column/3]). + +init_CPT(List, Sizes, TAB) :- + matrix_new(floats, Sizes, List, TAB), + matrix_to_logs(TAB). + +init_possibly_deterministic_CPT(List, Sizes, TAB) :- + matrix_new(floats, Sizes, List, TAB). + +project_from_CPT(V,tab(Table,Deps,_),tab(NewTable,NDeps,NSzs)) :- + evidence(V,Pos), !, + vnth(Deps, 0, V, N, NDeps), + matrix_select(Table, N, Pos, NewTable), + matrix_dims(NewTable, NSzs). +project_from_CPT(V,tab(Table,Deps,_),tab(NewTable,NDeps,NSzs)) :- + vnth(Deps, 0, V, N, NDeps), + matrix_sum_logs_out(Table, N, NewTable), + matrix_dims(NewTable, NSzs). + +evidence(V, Pos) :- + clpbn:get_atts(V, [evidence(Pos)]). + +vnth([V1|Deps], N, V, N, Deps) :- + V == V1, !. +vnth([V1|Deps], N0, V, N, [V1|NDeps]) :- + N1 is N0+1, + vnth(Deps, N1, V, N, NDeps). + +reorder_CPT(Vs0,T0,Vs,TF,Sizes) :- + var(Vs), !, + order_vec(Vs0,Vs,Map), + ( + Vs == Vs0 + -> + TF = T0 + ; + matrix_shuffle(T0,Map,TF) + ), + matrix_dims(TF, Sizes). +reorder_CPT(Vs0,T0,Vs,TF,Sizes) :- + mapping(Vs0,Vs,Map), + ( + Vs == Vs0 + -> + TF = T0 + ; + matrix_shuffle(T0,Map,TF) + ), + matrix_dims(TF, Sizes). + +order_vec(Vs0,Vs,Map) :- + add_indices(Vs0,0,Is), + keysort(Is,NIs), + get_els(NIs, Vs, Map). + +add_indices([],_,[]). +add_indices([V|Vs0],I0,[V-I0|Is]) :- + I is I0+1, + add_indices(Vs0,I,Is). + +get_els([], [], []). +get_els([V-I|NIs], [V|Vs], [I|Map]) :- + get_els(NIs, Vs, Map). + +mapping(Vs0,Vs,Map) :- + add_indices(Vs0,0,I1s), + add_indices( Vs,I2s), + keysort(I1s,Ks), + keysort(I2s,Ks), + split_map(I2s, Map). + +add_indices([],[]). +add_indices([V|Vs0],[V-_|I1s]) :- + add_indices(Vs0,I1s). + +split_map([], []). +split_map([_-M|Is], [M|Map]) :- + split_map(Is, Map). + +divide_CPTs(Tab1, Tab2, OT) :- + matrix_op(Tab1,Tab2,-,OT). + +multiply_CPTs(tab(Tab1, Deps1, Sz1), tab(Tab2, Deps2, Sz2), tab(OT, NDeps, NSz), NTab2) :- + expand_tabs(Deps1, Sz1, Deps2, Sz2, Map1, Map2, NDeps), + matrix_expand_compact(Tab1, Map1, NTab1), + matrix_expand_compact(Tab2, Map2, NTab2), + matrix_op(NTab1,NTab2,+,OT), + matrix_dims(OT,NSz). + + +expand_tabs([], [], [], [], [], [], []). +expand_tabs([V1|Deps1], [S1|Sz1], [], [], [0|Map1], [S1|Map2], [V1|NDeps]) :- + expand_tabs(Deps1, Sz1, [], [], Map1, Map2, NDeps). +expand_tabs([], [], [V2|Deps2], [S2|Sz2], [S2|Map1], [0|Map2], [V2|NDeps]) :- + expand_tabs([], [], Deps2, Sz2, Map1, Map2, NDeps). +expand_tabs([V1|Deps1], [S1|Sz1], [V2|Deps2], [S2|Sz2], Map1, Map2, NDeps) :- + compare(C,V1,V2), + (C == = -> + NDeps = [V1|MDeps], + Map1 = [0|M1], + Map2 = [0|M2], + NDeps = [V1|MDeps], + expand_tabs(Deps1, Sz1, Deps2, Sz2, M1, M2, MDeps) + ; + C == < -> + NDeps = [V1|MDeps], + Map1 = [0|M1], + Map2 = [S1|M2], + NDeps = [V1|MDeps], + expand_tabs(Deps1, Sz1, [V2|Deps2], [S2|Sz2], M1, M2, MDeps) + ; + NDeps = [V2|MDeps], + Map1 = [S2|M1], + Map2 = [0|M2], + NDeps = [V2|MDeps], + expand_tabs([V1|Deps1], [S1|Sz1], Deps2, Sz2, M1, M2, MDeps) + ). + +normalise_CPT(MAT,NMAT) :- + matrix_to_exps2(MAT), + matrix_sum(MAT, Sum), + matrix_op_to_all(MAT, /, Sum, NMAT). + +list_from_CPT(MAT, List) :- + matrix_to_list(MAT, List). + +expand_CPT(MAT0, Dims0, DimsNew, MAT) :- + generate_map(DimsNew, Dims0, Map), + matrix_expand(MAT0, Map, MAT). + +generate_map([], [], []). +generate_map([V|DimsNew], [V0|Dims0], [0|Map]) :- V == V0, !, + generate_map(DimsNew, Dims0, Map). +generate_map([V|DimsNew], Dims0, [Sz|Map]) :- + clpbn:get_atts(V, [dist(Id,_)]), + get_dist_domain_size(Id, Sz), + generate_map(DimsNew, Dims0, Map). + +unit_CPT(V,CPT) :- + clpbn:get_atts(V, [dist(Id,_)]), + get_dist_domain_size(Id, Sz), + matrix_new_set(floats,[Sz],1.0,CPT). + +reset_CPT_that_disagrees(CPT, Vars, V, Pos, NCPT) :- + vnth(Vars, 0, V, Dim, _), + matrix_set_all_that_disagree(CPT, Dim, Pos, -inf, NCPT). + +sum_out_from_CPT(Vs,Table,Deps,tab(NewTable,Vs,Sz)) :- + conversion_matrix(Vs, Deps, Conv), + matrix_sum_logs_out_several(Table, Conv, NewTable), + matrix_dims(NewTable, Sz). + +conversion_matrix([], [], []). +conversion_matrix([], [_|Deps], [1|Conv]) :- + conversion_matrix([], Deps, Conv). +conversion_matrix([V|Vs], [V1|Deps], [0|Conv]) :- V==V1, !, + conversion_matrix(Vs, Deps, Conv). +conversion_matrix([V|Vs], [_|Deps], [1|Conv]) :- + conversion_matrix([V|Vs], Deps, Conv). + +get_CPT_sizes(CPT, Sizes) :- + matrix_dims(CPT, Sizes). + +matrix_expand_compact(M0,Zeros,M0) :- + zero_map(Zeros), !. +matrix_expand_compact(M0,Map,M) :- + matrix_expand(M0, Map, M). + +zero_map([]). +zero_map([0|Zeros]) :- + zero_map(Zeros). + +col_from_CPT(CPT, Parents, Column) :- + matrix_col(CPT, Parents, Column), + matrix_to_logs(Column). + +column_from_possibly_deterministic_CPT(CPT, Parents, Column) :- + matrix_column(CPT, Parents, Column). + +multiply_factors(F1, F2, F) :- + matrix_op(F1,F2,+,F). + +multiply_possibly_deterministic_factors(F1, F2, F) :- + matrix_op(F1,F2,*,F). + +normalise_possibly_deterministic_CPT(MAT,NMAT) :- + matrix_agg_lines(MAT, +, Sum), + matrix_op_to_lines(MAT, Sum, /, NMAT). + +random_CPT(Dims, M) :- + mult_all(Dims,1,Size), + generate_random_entries(Size, Randoms), + matrix_new(floats, Dims, Randoms, M1), + normalise_possibly_deterministic_CPT(M1, M). + +mult_all([],Size,Size). +mult_all([D|Dims],Size0,Size) :- + Size1 is Size0*D, + mult_all(Dims,Size1,Size). + +generate_random_entries(0, []) :- !. +generate_random_entries(Size, [R|Randoms]) :- + R is random, + Size1 is Size-1, + generate_random_entries(Size1, Randoms). + +uniform_CPT_as_list(Dims, L) :- + uniform_CPT(Dims, M), + matrix_to_list(M, L). + +uniform_CPT(Dims, M) :- + matrix_new_set(floats,Dims,1.0,M1), + normalise_possibly_deterministic_CPT(M1, M). + +normalise_CPT_on_lines(MAT0, MAT2, L1) :- + matrix_agg_cols(MAT0, +, MAT1), + matrix_sum(MAT1, SUM), + matrix_op_to_all(MAT1, /, SUM, MAT2), + matrix:matrix_to_list(MAT2,L1). + diff --git a/packages/CLPBN/clpbn/table.yap b/packages/CLPBN/clpbn/table.yap new file mode 100644 index 000000000..e265058b2 --- /dev/null +++ b/packages/CLPBN/clpbn/table.yap @@ -0,0 +1,223 @@ +/* + Deterministcally table a predicate of the form + K -> RV + + where the K are the first N-1 arguments. + + Note that this does not include support for backtracking +*/ + +:- module(clpbn_table, + [clpbn_table/1, + clpbn_tabled_clause/2, + clpbn_tabled_abolish/1, + clpbn_tabled_asserta/1, + clpbn_tabled_assertz/1, + clpbn_tabled_asserta/2, + clpbn_tabled_assertz/2, + clpbn_tabled_dynamic/1, + clpbn_tabled_number_of_clauses/2, + clpbn_reset_tables/0, + clpbn_reset_tables/1, + clpbn_is_tabled/1 + ]). + +:- use_module(library(bhash), + [b_hash_new/2, + b_hash_lookup/3, + b_hash_insert/3]). + +:- meta_predicate clpbn_table(:), + clpbn_tabled_clause(:.?), + clpbn_tabled_abolish(:), + clpbn_tabled_asserta(:), + clpbn_tabled_assertz(:), + clpbn_tabled_asserta(:,-), + clpbn_tabled_assertz(:,-), + clpbn_tabled_number_of_clauses(:,-), + clpbn_is_tabled(:). + +:- dynamic clpbn_table/3. + +:- initialization(init). + +init :- + clpbn_reset_tables. + +clpbn_reset_tables :- + clpbn_reset_tables(1024). + +clpbn_reset_tables(Sz) :- + b_hash_new(Tab, Sz), + nb_setval(clpbn_tables, Tab). + +clpbn_table(M:X) :- !, + clpbn_table(X,M). +clpbn_table(X) :- + prolog_load_context(module, M), + clpbn_table(X,M). + +clpbn_table(M:X,_) :- !, + clpbn_table(X,M). +clpbn_table((P1,P2),M) :- !, + clpbn_table(P1,M), + clpbn_table(P2,M). +clpbn_table(F/N,M) :- + functor(S,F,N), + S =.. L0, + take_tail(L0, V, L1, V1, L2), + Key =.. L1, + atom_concat(F, '___tabled', NF), + L2 = [_|Args], + S1 =.. [NF|Args], + L0 = [_|OArgs], + S2 =.. [NF|OArgs], + asserta(clpbn_table(S, M, S2)), + assert((M:S :- nb_getval(clpbn_tables, Tab), ( b_hash_lookup(Key, V1, Tab) -> true ; M:S1, b_hash_insert(Tab, Key, V1) ; true), ( nonvar(V) -> clpbn_evidence:put_evidence(V, V1) ; V = V1 ), ! ) ). + +take_tail([V], V, [], V1, [V1]) :- !. +take_tail([A|L0], V, [A|L1], V1, [A|L2]) :- + take_tail(L0, V, L1, V1, L2). + +user:term_expansion((P :- Gs), NC) :- + clpbn_table(P, M, NP), + prolog_load_context(module, M), !, + assert(M:(NP :- Gs)), + NC = (:-true). + +in_table(K, V) :- + nb_getval(clpbn_tables, Tab), + b_hash_lookup(K, V, Tab). + +store_in_table(K, V) :- + nb_getval(clpbn_tables, Tab), + b_hash_insert(Tab, K, V). + +clpbn_tabled_clause(M:Head, Body) :- !, + clpbn_tabled_clause(Head, M, Body). +clpbn_tabled_clause(Head, Body) :- + prolog_load_context(module, M), + clpbn_tabled_clause(Head, M, Body). + +clpbn_tabled_clause(M:Head, _, Body) :- !, + clpbn_tabled_clause(Head, M, Body). +clpbn_tabled_clause(Head, M, Body) :- + clpbn_table(Head, M, THead), + clause(M:THead, Body). + + +clpbn_tabled_assertz(M:Clause) :- !, + clpbn_tabled_assertz2(Clause, M). +clpbn_tabled_assertz(Clause) :- + prolog_load_context(module, M), + clpbn_tabled_assertz2(Clause, M). + +clpbn_tabled_assertz2(M:Clause, _) :- !, + clpbn_tabled_assertz2(Clause, M). +clpbn_tabled_assertz2((Head:-Body), M) :- !, + clpbn_table(Head, M, THead), + assertz(M:(THead :- Body)). +clpbn_tabled_assertz2(Head, M) :- + clpbn_table(Head, M, THead), + assertz(THead). + +clpbn_tabled_assertz(M:Clause, Ref) :- !, + clpbn_tabled_assertz2(Clause, M, Ref). +clpbn_tabled_assertz(Clause, Ref) :- + prolog_load_context(module, M), + clpbn_tabled_assertz2(Clause, M, Ref). + +clpbn_tabled_assertz2(M:Clause, _, Ref) :- !, + clpbn_tabled_assertz2(Clause, M, Ref). +clpbn_tabled_assertz2((Head:-Body), M, Ref) :- !, + clpbn_table(Head, M, THead), + assertz(M:(THead :- Body), Ref). +clpbn_tabled_assertz2(Head, M, Ref) :- + clpbn_table(Head, M, THead, Ref), + assertz(THead). + + +clpbn_tabled_asserta(M:Clause) :- !, + clpbn_tabled_asserta2(Clause, M). +clpbn_tabled_asserta(Clause) :- + prolog_load_context(module, M), + clpbn_tabled_asserta2(Clause, M). + +clpbn_tabled_asserta2(M:Clause, _) :- !, + clpbn_tabled_asserta2(Clause, M). +clpbn_tabled_asserta2((Head:-Body), M) :- !, + clpbn_table(Head, M, THead), + asserta(M:(THead :- Body)). +clpbn_tabled_asserta2(Head, M) :- + clpbn_table(Head, M, THead), + asserta(THead). + +clpbn_tabled_asserta(M:Clause, Ref) :- !, + clpbn_tabled_asserta2(Clause, M, Ref). +clpbn_tabled_asserta(Clause, Ref) :- + prolog_load_context(module, M), + clpbn_tabled_asserta2(Clause, M, Ref). + +clpbn_tabled_asserta2(M:Clause, _, Ref) :- !, + clpbn_tabled_asserta2(Clause, M, Ref). +clpbn_tabled_asserta2((Head:-Body), M, Ref) :- !, + clpbn_table(Head, M, THead), + asserta(M:(THead :- Body), Ref). +clpbn_tabled_asserta2(Head, M, Ref) :- + clpbn_table(Head, M, THead, Ref), + asserta(THead). + + +clpbn_tabled_abolish(M:Clause) :- !, + clpbn_tabled_abolish(Clause, M). +clpbn_tabled_abolish(Clause) :- + prolog_load_context(module, M), + clpbn_tabled_abolish(Clause, M). + +clpbn_tabled_abolish(M:Clause, _) :- !, + clpbn_tabled_abolish(Clause, M). +clpbn_tabled_abolish(N/A, M) :- + functor(Head, N, A), + clpbn_table(Head, M, THead), + functor(THead, TN, A), + abolish(M:TN/A). + +clpbn_tabled_dynamic(M:Clause) :- !, + clpbn_tabled_dynamic(Clause, M). +clpbn_tabled_dynamic(Clause) :- + prolog_load_context(module, M), + clpbn_tabled_dynamic(Clause, M). + +clpbn_tabled_dynamic(M:Clause, _) :- !, + clpbn_tabled_dynamic(Clause, M). +clpbn_tabled_dynamic(N/A, M) :- + functor(Head, N, A), + clpbn_table(Head, M, THead), + functor(THead, TN, A), + dynamic(M:TN/A). + +clpbn_tabled_number_of_clauses(M:Clause, N) :- !, + clpbn_tabled_number_of_clauses(Clause, M, N). +clpbn_tabled_number_of_clauses(Clause, N) :- + prolog_load_context(module, M), + clpbn_tabled_number_of_clauses(Clause, M, N). + +clpbn_tabled_number_of_clauses(M:Clause, _, N) :- !, + clpbn_tabled_number_of_clauses(Clause, M, N). +clpbn_tabled_number_of_clauses(Head, M, N) :- + clpbn_table(Head, M, THead), + predicate_property(M:THead,number_of_clauses(N)). + + +clpbn_is_tabled(M:Clause) :- !, + clpbn_is_tabled(Clause, M). +clpbn_is_tabled(Clause) :- + prolog_load_context(module, M), + clpbn_is_tabled(Clause, M). + +clpbn_is_tabled(M:Clause, _) :- !, + clpbn_is_tabled(Clause, M). +clpbn_is_tabled(Head, M) :- + clpbn_table(Head, M, _). + + diff --git a/packages/CLPBN/clpbn/topsort.yap b/packages/CLPBN/clpbn/topsort.yap new file mode 100644 index 000000000..9c40f9ad9 --- /dev/null +++ b/packages/CLPBN/clpbn/topsort.yap @@ -0,0 +1,34 @@ + +:- module(topsort, [topsort/2]). + +:- use_module(library(dgraphs), + [dgraph_new/1, + dgraph_add_edges/3, + dgraph_add_vertices/3, + dgraph_top_sort/2]). + +/* simple implementation of a topological sorting algorithm */ +/* graph is as Node-[Parents] */ + +topsort(Graph0, Sorted) :- + mkedge_list(Graph0, EdgeList, []), + mkvertices_list(Graph0, VList, []), + dgraph_new(DGraph0), + dgraph_add_vertices(DGraph0, VList, DGraph1), + dgraph_add_edges(DGraph1, EdgeList, DGraph2), + dgraph_top_sort(DGraph2, Sorted). + +mkvertices_list([]) --> []. +mkvertices_list([V-_|More]) --> [V], + mkvertices_list(More). + +mkedge_list([]) --> []. +mkedge_list([V-Parents|More]) --> + add_edges(Parents, V), + mkedge_list(More). + +add_edges([], _V) --> []. +add_edges([P|Parents], V) --> [P-V], + add_edges(Parents, V). + + diff --git a/packages/CLPBN/clpbn/utils.yap b/packages/CLPBN/clpbn/utils.yap new file mode 100644 index 000000000..67f7cfe15 --- /dev/null +++ b/packages/CLPBN/clpbn/utils.yap @@ -0,0 +1,116 @@ +:- module(clpbn_utils, [ + clpbn_not_var_member/2, + clpbn_var_member/2, + check_for_hidden_vars/3, + sort_vars_by_key/3, + sort_vars_by_key_and_parents/3]). + +% +% It may happen that variables from a previous query may still be around. +% and be used in the next evaluation, so we cannot trust the list of *new* +% variables. +% +check_for_hidden_vars([], _, []). +check_for_hidden_vars([V|Vs], AllVs0, [V|NVs]) :- + check_for_extra_variables(V,AllVs0, AllVs, Vs, IVs), + check_for_hidden_vars(IVs, AllVs, NVs). + +check_for_extra_variables(V,AllVs0, AllVs, Vs, IVs) :- + var(V), + clpbn:get_atts(V, [dist(_,[V1|LV])]), !, + add_old_variables([V1|LV], AllVs0, AllVs, Vs, IVs). +check_for_extra_variables(_,AllVs, AllVs, Vs, Vs). + +add_old_variables([], AllVs, AllVs, Vs, Vs). +add_old_variables([V1|LV], AllVs0, AllVs, Vs, IVs) :- + clpbn_not_var_member(AllVs0, V1), !, + add_old_variables(LV, [V1|AllVs0], AllVs, [V1|Vs], IVs). +add_old_variables([_|LV], AllVs0, AllVs, Vs, IVs) :- + add_old_variables(LV, AllVs0, AllVs, Vs, IVs). + +clpbn_var_member([V1|_], V) :- V1 == V, !. +clpbn_var_member([_|Vs], V) :- + clpbn_var_member(Vs, V). + +clpbn_not_var_member([], _). +clpbn_not_var_member([V1|Vs], V) :- V1 \== V, + clpbn_not_var_member(Vs, V). + + +sort_vars_by_key(AVars, SortedAVars, UnifiableVars) :- + get_keys(AVars, KeysVars), + msort(KeysVars, KVars), + merge_same_key(KVars, SortedAVars, [], UnifiableVars). + +get_keys([], []). +get_keys([V|AVars], [K-V|KeysVars]) :- + clpbn:get_atts(V, [key(K)]), !, + get_keys(AVars, KeysVars). +get_keys([_|AVars], KeysVars) :- % may be non-CLPBN vars. + get_keys(AVars, KeysVars). + +merge_same_key([], [], _, []). +merge_same_key([K1-V1,K2-V2|Vs], SortedAVars, Ks, UnifiableVars) :- + K1 == K2, !, + (clpbn:get_atts(V1, [evidence(E)]) + -> + clpbn:put_atts(V2, [evidence(E)]) + ; + clpbn:get_atts(V2, [evidence(E)]) + -> + clpbn:put_atts(V1, [evidence(E)]) + ; + true + ), +% V1 = V2, + attributes:fast_unify_attributed(V1,V2), + merge_same_key([K1-V1|Vs], SortedAVars, Ks, UnifiableVars). +merge_same_key([K1-V1,K2-V2|Vs], [V1|SortedAVars], Ks, [K1|UnifiableVars]) :- + (in_keys(K1, Ks) ; \+ \+ K1 == K2), !, + add_to_keys(K1, Ks, NKs), + merge_same_key([K2-V2|Vs], SortedAVars, NKs, UnifiableVars). +merge_same_key([K-V|Vs], [V|SortedAVars], Ks, UnifiableVars) :- + add_to_keys(K, Ks, NKs), + merge_same_key(Vs, SortedAVars, NKs, UnifiableVars). + +in_keys(K1,[K|_]) :- \+ \+ K1 = K, !. +in_keys(K1,[_|Ks]) :- + in_keys(K1,Ks). + +add_to_keys(K1, Ks, Ks) :- ground(K1), !. +add_to_keys(K1, Ks, [K1|Ks]). + +sort_vars_by_key_and_parents(AVars, SortedAVars, UnifiableVars) :- + get_keys_and_parents(AVars, KeysVars), + keysort(KeysVars, KVars), + merge_same_key(KVars, SortedAVars, [], UnifiableVars). + +get_keys_and_parents([], []). +get_keys_and_parents([V|AVars], [K-V|KeysVarsF]) :- + clpbn:get_atts(V, [key(K),dist(Id,Parents)]), !, + add_parents(Parents,V,Id,KeysVarsF,KeysVars0), + get_keys_and_parents(AVars, KeysVars0). +get_keys_and_parents([_|AVars], KeysVars) :- % may be non-CLPBN vars. + get_keys_and_parents(AVars, KeysVars). + +add_parents(Parents,_,_,KeyVars,KeyVars) :- + all_vars(Parents), !. +add_parents(Parents,V,Id,KeyVarsF,KeyVars0) :- + transform_parents(Parents,NParents,KeyVarsF,KeyVars0), + clpbn:put_atts(V, [dist(Id,NParents)]). + + +all_vars([]). +all_vars([P|Parents]) :- + var(P), + all_vars(Parents). + + +transform_parents([],[],KeyVars,KeyVars). +transform_parents([P|Parents0],[P|NParents],KeyVarsF,KeyVars0) :- + var(P), !, + transform_parents(Parents0,NParents,KeyVarsF,KeyVars0). +transform_parents([P|Parents0],[V|NParents],[P-V|KeyVarsF],KeyVars0) :- + transform_parents(Parents0,NParents,KeyVarsF,KeyVars0). + + diff --git a/packages/CLPBN/clpbn/vel.yap b/packages/CLPBN/clpbn/vel.yap new file mode 100644 index 000000000..8f14ee3e8 --- /dev/null +++ b/packages/CLPBN/clpbn/vel.yap @@ -0,0 +1,274 @@ +/*********************************** + + Variable Elimination in Prolog + + How to do it + + + Three steps: + build the graph: + - for all variables, find out + all tables they connect to; + multiply their size + order by size + +*********************************/ + +:- module(clpbn_vel, [vel/3, + check_if_vel_done/1, + init_vel_solver/4, + run_vel_solver/3]). + +:- attribute size/1, all_diffs/1. + +:- use_module(library(ordsets), + [ord_union/3, + ord_member/2]). + +:- use_module(library('clpbn/xbif'), [clpbn2xbif/3]). + +:- use_module(library('clpbn/graphviz'), [clpbn2gviz/4]). + +:- use_module(library('clpbn/dists'), + [ + dist/4, + get_dist_domain_size/2, + get_dist_matrix/5]). + +:- use_module(library('clpbn/utils'), [ + clpbn_not_var_member/2]). + +:- use_module(library('clpbn/display'), [ + clpbn_bind_vals/3]). + +:- use_module(library('clpbn/connected'), + [ + init_influences/3, + influences/5 + ]). + +:- use_module(library('clpbn/matrix_cpt_utils'), + [project_from_CPT/3, + reorder_CPT/5, + multiply_CPTs/4, + normalise_CPT/2, + sum_out_from_CPT/4, + list_from_CPT/2]). + +:- use_module(library(lists), + [ + append/3 + ]). + +:- use_module(library('clpbn/aggregates'), + [check_for_agg_vars/2]). + + +check_if_vel_done(Var) :- + get_atts(Var, [size(_)]), !. + +% +% implementation of the well known variable elimination algorithm +% +vel([[]],_,_) :- !. +vel([LVs],Vs0,AllDiffs) :- + init_vel_solver([LVs], Vs0, AllDiffs, State), + % variable elimination proper + run_vel_solver([LVs], [LPs], State), + % bind Probs back to variables so that they can be output. + clpbn_bind_vals([LVs],[LPs],AllDiffs). + +init_vel_solver(Qs, Vs0, _, LVis) :- + check_for_agg_vars(Vs0, Vs1), + % LVi will have a list of CLPBN variables + % Tables0 will have the full data on each variable + init_influences(Vs1, G, RG), + init_vel_solver_for_questions(Qs, G, RG, _, LVis). + +init_vel_solver_for_questions([], _, _, [], []). +init_vel_solver_for_questions([Vs|MVs], G, RG, [NVs|MNVs0], [NVs|LVis]) :- + influences(Vs, _, NVs0, G, RG), + sort(NVs0, NVs), +%clpbn_gviz:clpbn2gviz(user_error, test, NVs, Vs), + init_vel_solver_for_questions(MVs, G, RG, MNVs0, LVis). + +% use a findall to recover space without needing for GC +run_vel_solver(LVs, LPs, LNVs) :- + findall(Ps, solve_vel(LVs, LNVs, Ps), LPs). + +solve_vel([LVs|_], [NVs0|_], Ps) :- + length(NVs0, L), (L > 64 -> clpbn_gviz:clpbn2gviz(user_error,sort,NVs0,LVs) ; true ), + find_all_clpbn_vars(NVs0, NVs0, LV0, LVi, Tables0), + sort(LV0, LV), + % construct the graph + find_all_table_deps(Tables0, LV), + process(LVi, LVs, tab(Dist,_,_)), + % move from potentials back to probabilities + normalise_CPT(Dist,MPs), + list_from_CPT(MPs, Ps). +solve_vel([_|MoreLVs], [_|MoreLVis], Ps) :- + solve_vel(MoreLVs, MoreLVis, Ps). + + + +keys([],[]). +keys([V|NVs0],[K:E|Ks]) :- + clpbn:get_atts(V,[key(K),evidence(E)]), !, + keys(NVs0,Ks). +keys([V|NVs0],[K|Ks]) :- + clpbn:get_atts(V,[key(K)]), + keys(NVs0,Ks). + +% +% just get a list of variables plus associated tables +% +find_all_clpbn_vars([], _, [], [], []) :- !. +find_all_clpbn_vars([V|Vs], NVs0, [Var|LV], ProcessedVars, [table(I,Table,Parents,Sizes)|Tables]) :- + var_with_deps(V, NVs0, Table, Parents, Sizes, Ev, Vals), !, + % variables with evidence should not be processed. + (var(Ev) -> + Var = var(V,I,Sz,Vals,Parents,Ev,_,_), + vel_get_dist_size(V,Sz), + ProcessedVars = [Var|ProcessedVars0] + ; + ProcessedVars = ProcessedVars0 + ), + find_all_clpbn_vars(Vs, NVs0, LV, ProcessedVars0, Tables). + +var_with_deps(V, NVs0, Table, Deps, Sizes, Ev, Vals) :- + clpbn:get_atts(V, [dist(Id,Parents)]), + get_dist_matrix(Id,Parents,_,Vals,TAB0), + ( + clpbn:get_atts(V, [evidence(Ev)]) + -> + true + ; + true + ), !, + % set CPT in canonical form + reorder_CPT([V|Parents],TAB0,Deps0,TAB1,Sizes1), + % remove evidence. + simplify_evidence(Deps0, NVs0, TAB1, Deps0, Sizes1, Table, Deps, Sizes). + +find_all_table_deps(Tables0, LV) :- + find_dep_graph(Tables0, DepGraph0), + sort(DepGraph0, DepGraph), + add_table_deps_to_variables(LV, DepGraph). + +find_dep_graph([], []) :- !. +find_dep_graph([table(I,Tab,Deps,Sizes)|Tables], DepGraph) :- + add_table_deps(Deps, I, Deps, Tab, Sizes, DepGraph0, DepGraph), + find_dep_graph(Tables, DepGraph0). + +add_table_deps([], _, _, _, _, DepGraph, DepGraph). +add_table_deps([V|Deps], I, Deps0, Table, Sizes, DepGraph0, [V-tab(Table,Deps0,Sizes)|DepGraph]) :- + add_table_deps(Deps, I, Deps0, Table, Sizes, DepGraph0, DepGraph). + +add_table_deps_to_variables([], []). +add_table_deps_to_variables([var(V,_,_,_,_,_,Deps,K)|LV], DepGraph) :- + steal_deps_for_variable(DepGraph, V, NDepGraph, Deps), + compute_size(Deps,[],K), +% ( clpbn:get_atts(V,[key(Key)]) -> format('~w:~w~n',[Key,K]) ; true), + add_table_deps_to_variables(LV, NDepGraph). + +steal_deps_for_variable([V-Info|DepGraph], V0, NDepGraph, [Info|Deps]) :- + V == V0, !, + steal_deps_for_variable(DepGraph, V0, NDepGraph, Deps). +steal_deps_for_variable(DepGraph, _, DepGraph, []). + +compute_size([],Vs,K) :- + % use sizes now +% length(Vs,K). + multiply_sizes(Vs,1,K). +compute_size([tab(_,Vs,_)|Tabs],Vs0,K) :- + ord_union(Vs,Vs0,VsI), + compute_size(Tabs,VsI,K). + +multiply_sizes([],K,K). +multiply_sizes([V|Vs],K0,K) :- + vel_get_dist_size(V, Sz), + KI is K0*Sz, + multiply_sizes(Vs,KI,K). + +process(LV0, InputVs, Out) :- + find_best(LV0, V0, -1, V, WorkTables, LVI, InputVs), + V \== V0, !, +% format('1 ~w: ~w~n',[V,WorkTables]), + multiply_tables(WorkTables, tab(Tab0,Deps0,_)), + reorder_CPT(Deps0,Tab0,Deps,Tab,Sizes), + Table = tab(Tab,Deps,Sizes), +% format('2 ~w: ~w~n',[V,Table]), + project_from_CPT(V,Table,NewTable), +% format('3 ~w: ~w~n',[V,NewTable]), + include(LVI,NewTable,V,LV2), + process(LV2, InputVs, Out). +process(LV0, _, Out) :- + fetch_tables(LV0, WorkTables), + multiply_tables(WorkTables, Out). + + +find_best([], V, _TF, V, _, [], _). +%:- +% clpbn:get_atts(V,[key(K)]), writeln(chosen:K:_TF). +% root_with_single_child +%find_best([var(V,I,_,_,[],Ev,[Dep],K)|LV], _, _, V, [Dep], LVF, Inputs) :- !. +find_best([var(V,I,Sz,Vals,Parents,Ev,Deps,K)|LV], _, Threshold, VF, NWorktables, LVF, Inputs) :- + ( K < Threshold ; Threshold < 0), + clpbn_not_var_member(Inputs, V), !, + find_best(LV, V, K, VF, WorkTables,LV0, Inputs), + (V == VF -> + LVF = LV0, Deps = NWorktables + ; + LVF = [var(V,I,Sz,Vals,Parents,Ev,Deps,K)|LV0], WorkTables = NWorktables + ). +find_best([V|LV], V0, Threshold, VF, WorkTables, [V|LVF], Inputs) :- + find_best(LV, V0, Threshold, VF, WorkTables, LVF, Inputs). + +multiply_tables([Table], Table) :- !. %, Table = tab(T,D,S),matrix:matrix_to_list(T,L),writeln(D:S:L). +multiply_tables([TAB1, TAB2| Tables], Out) :- +%TAB1 = tab(T,_,_),matrix:matrix_to_list(T,L),writeln(doing:L), + multiply_CPTs(TAB1, TAB2, TAB, _), + multiply_tables([TAB| Tables], Out). + + +simplify_evidence([], _, Table, Deps, Sizes, Table, Deps, Sizes). +simplify_evidence([V|VDeps], NVs0, Table0, Deps0, Sizes0, Table, Deps, Sizes) :- + clpbn:get_atts(V, [evidence(_)]), !, + project_from_CPT(V,tab(Table0,Deps0,Sizes0),tab(NewTable,Deps1,Sizes1)), + simplify_evidence(VDeps, NVs0, NewTable, Deps1, Sizes1, Table, Deps, Sizes). +simplify_evidence([V|VDeps], NVs0, Table0, Deps0, Sizes0, Table, Deps, Sizes) :- + ord_member(V, NVs0), !, + simplify_evidence(VDeps, NVs0, Table0, Deps0, Sizes0, Table, Deps, Sizes). +simplify_evidence([V|VDeps], NVs0, Table0, Deps0, Sizes0, Table, Deps, Sizes) :- + project_from_CPT(V,tab(Table0,Deps0,Sizes0),tab(NewTable,Deps1,Sizes1)), + simplify_evidence(VDeps, NVs0, NewTable, Deps1, Sizes1, Table, Deps, Sizes). + +fetch_tables([], []). +fetch_tables([var(_,_,_,_,_,_,Deps,_)|LV0], Tables) :- + append(Deps,Tables0,Tables), + fetch_tables(LV0, Tables0). + + +include([],_,_,[]). +include([var(V,P,VSz,D,Parents,Ev,Tabs,Est)|LV],tab(T,Vs,Sz),V1,[var(V,P,VSz,D,Parents,Ev,Tabs,Est)|NLV]) :- + clpbn_not_var_member(Vs,V), !, + include(LV,tab(T,Vs,Sz),V1,NLV). +include([var(V,P,VSz,D,Parents,Ev,Tabs,_)|LV],Table,NV,[var(V,P,VSz,D,Parents,Ev,NTabs,NEst)|NLV]) :- + update_tables(Tabs,NTabs,Table,NV), + compute_size(NTabs, [], NEst), + include(LV,Table,NV,NLV). + +update_tables([],[Table],Table,_). +update_tables([tab(Tab0,Vs,Sz)|Tabs],[tab(Tab0,Vs,Sz)|NTabs],Table,V) :- + clpbn_not_var_member(Vs,V), !, + update_tables(Tabs,NTabs,Table,V). +update_tables([_|Tabs],NTabs,Table,V) :- + update_tables(Tabs,NTabs,Table,V). + +vel_get_dist_size(V,Sz) :- + get_atts(V, [size(Sz)]), !. +vel_get_dist_size(V,Sz) :- + clpbn:get_atts(V,dist(Id,_)), !, + get_dist_domain_size(Id,Sz), + put_atts(V, [size(Sz)]). + diff --git a/packages/CLPBN/clpbn/viterbi.yap b/packages/CLPBN/clpbn/viterbi.yap new file mode 100644 index 000000000..1dc1037f5 --- /dev/null +++ b/packages/CLPBN/clpbn/viterbi.yap @@ -0,0 +1,235 @@ + +%:- style_check(all). + +:- module(viterbi, [viterbi/4]). + +:- use_module(library(lists), + [nth/3, + member/2]). + +:- use_module(library(assoc)). + +:- use_module(library(dgraphs)). + +:- use_module(library(matrix)). + +:- use_module(library(clpbn), []). + +:- ensure_loaded(library('clpbn/hmm')). + +:- use_module(library('clpbn/dists'), [ + get_dist_params/2]). + +:- meta_predicate viterbi(:,:,+,-). + + +viterbi(Start,End,String,Trace) :- + init_hmm, + Start, + mk_graph(NOfNodes, Map, ViterbiCode), + compile_trace(String, Emissions), + get_id(Start, Map, SI), + get_id(End, Map, EI), + % add a random symbol in front (for the c/1 state). + compiled_viterbi(NOfNodes, SI, ViterbiCode, Emissions, Dump, L), + backtrace(Dump, EI, Map, L, Trace). + +state_from_goal(_:Start,S) :- + state_from_goal(Start,S). +state_from_goal(Start,S) :- + functor(Start, N, Ar), + % get rid of position and random var + NAr is Ar-2, + functor(S, N, NAr). + + +mk_graph(NOfNodes, Map, ViterbiCode) :- + attributes:all_attvars(Vars0), + empty_assoc(KeyMap0), + get_graph(Vars0, Nodes, Edges, KeyMap0, KeyMap), + dgraph_new(G0), + dgraph_add_vertices(G0, Nodes, G1), + dgraph_add_edges(G1, Edges, G2), + dgraph_top_sort(G2, SortedNodes), + compile_viterbi(SortedNodes, KeyMap, NOfNodes, Map, ViterbiCode). + +get_graph([V|Vs], [NKey|Keys], EdgesF, KeyMap0, KeyMap) :- + clpbn:get_atts(V,[key(Key), dist(Id,Parents)]), + ( Key =.. [N,2|More] ; Key = s(0), N=s, More=[] ), !, + NKey =.. [N|More], + fetch_edges(Parents, NKey, EdgesF, Edges0, PKeys), + get_emission(V, Key, EmissionProb), + put_assoc(NKey,KeyMap0,nodeinfo(_,Id,EmissionProb,PKeys),KeyMapI), + get_graph(Vs, Keys, Edges0, KeyMapI, KeyMap). +get_graph([_|Vs], Keys, Edges, KeyMap0, KeyMap) :- + get_graph(Vs, Keys, Edges, KeyMap0, KeyMap). +get_graph([], [], [], KeyMap, KeyMap). + +get_emission(V, Key, EmissionProbs) :- + hmm:get_atts(V,[emission(_)]), !, + user:emission_cpt(Key, EmissionProbs). +get_emission(_, _, []). + +fetch_edges([V|Parents], Key0, EdgesF, Edges0, [Slice-AKey|PKeys]) :- + var(V), !, + clpbn:get_atts(V,[key(Key)]), + abstract_key(Key, AKey, Slice), + ( + Slice < 3 + -> + EdgesF = [Key0-AKey|EdgesI] + ; + EdgesF = EdgesI + ), + fetch_edges(Parents, Key0, EdgesI, Edges0, PKeys). +fetch_edges([Key|Parents], Key0, EdgesF, Edges0, [Slice-AKey|PKeys]) :- + abstract_key(Key, AKey, Slice), + ( + Slice < 3 + -> + EdgesF = [Key0-AKey|EdgesI] + ; + EdgesF = EdgesI + ), + fetch_edges(Parents, Key0, EdgesI, Edges0, PKeys). +fetch_edges([], _, Edges, Edges, []). + +abstract_key(Key, NKey, Slice) :- + Key =.. [N,Slice|More], + NKey =.. [N|More]. + + +compile_viterbi(Keys, KeyMap, Nodes, Map, ViterbiCode) :- + enum_keys(Keys, KeyMap, 0, Nodes, Map), + compile_keys(Keys, KeyMap, ViterbiCode). + +% just enumerate keys +enum_keys([], _, I, I, []). +enum_keys([Key|Keys], KeyMap, I0, Nodes, [I0-Key|Map]) :- + get_assoc(Key,KeyMap,nodeinfo(I0,_,_,_)), + I is I0+1, + enum_keys(Keys, KeyMap, I, Nodes, Map). + +compile_keys([Key|Keys], KeyMap, ViterbiCodeF) :- + get_assoc(Key,KeyMap,nodeinfo(IKey,Id,Emission,PKeys)), + compile_emission(Emission,IKey,ViterbiCodeF,ViterbiCodeI), + get_dist_params(Id,Probs), + compile_propagation(PKeys,Probs,IKey,KeyMap,ViterbiCodeI,ViterbiCode0), + compile_keys(Keys, KeyMap, ViterbiCode0). +compile_keys([], _, []). + + +% add a random symbol to the end. +compile_emission([],_) --> !, []. +compile_emission(EmissionTerm,IKey) --> [emit(IKey,EmissionTerm)]. + +compile_propagation([],[],_,_) --> []. +compile_propagation([0-PKey|Ps], [Prob|Probs], IKey, KeyMap) --> + [prop_same(IKey,Parent,Prob)], + { get_assoc(PKey,KeyMap,nodeinfo(Parent,_,_,_)) }, + compile_propagation(Ps, Probs, IKey, KeyMap). +compile_propagation([2-PKey|Ps], [Prob|Probs], IKey, KeyMap) --> + [prop_same(IKey,Parent,Prob)], + { get_assoc(PKey,KeyMap,nodeinfo(Parent,_,_,_)) }, + compile_propagation(Ps, Probs, IKey, KeyMap). +compile_propagation([3-PKey|Ps], [Prob|Probs], IKey, KeyMap) --> + [prop_next(IKey,Parent,Prob)], + { get_assoc(PKey,KeyMap,nodeinfo(Parent,_,_,_)) }, + compile_propagation(Ps, Probs, IKey, KeyMap). + +get_id(_:S, Map, SI) :- !, + get_id(S, Map, SI). +get_id(S, Map, SI) :- + functor(S,N,A), + A2 is A-2, + functor(S2,N,A2), + once(member(SI-S2,Map)). + +compile_trace(Trace, Emissions) :- + user:hmm_domain(Domain), + (atom(Domain) -> + hmm:cvt_vals(Domain, Vals) + ; + Vals = Domain + ), + compile_trace(Trace, Vals, Emissions). + +compile_trace([], _, []). +compile_trace([El|Trace], Vals, [N|Emissions]) :- + once(nth(N, Vals, El)), + compile_trace(Trace, Vals, Emissions). + +compiled_viterbi(Nodes, S, Commands, Input, Trace, L) :- + length(Input,L), + prolog_flag(min_tagged_integer, Min), + matrix_new_set(ints,[Nodes], Min, Current), + matrix_new_set(ints,[Nodes], Min, Next), + L1 is L+1, + matrix_new(ints,[L1,Nodes], Trace), + matrix_set(Current, [S], 0), + run_commands(Input, Commands, 0, Current, Next, Trace, Min). + + +run_commands([], _, _, _, _, _, _). +run_commands([E|Input], Commands, I, Current, Next, Trace, Min) :- + run_code(Commands, E, I, Current, Next, Trace), + matrix_get(Current, [32], M10), + matrix_get(Current, [34], C), + matrix_set_all(Current,Min), + I1 is I+1, + run_commands(Input, Commands, I1, Next, Current, Trace, Min). + +run_code([], _, _, _, _, Trace). +run_code([Inst|Input], E, I, Current, Next, Trace) :- + run_inst(Inst, E, I, Current, Next, Trace) , + run_code(Input, E, I, Current, Next, Trace). + +run_inst(emit(Id,T), E, _SP, Current, _, Trace) :- + arg(E,T,P), + matrix_add(Current, [Id], P). +run_inst(prop_same(I,P,Prob), _, SP, Current, _, Trace) :- + matrix_get(Current, [I], PI), + NP is PI+Prob, + matrix_get(Current, [P], P0), + (NP > P0 -> + matrix_set(Current, [P], NP), + matrix_set(Trace, [SP,P], I) + ; + true + ). +run_inst(prop_next(I,P,Prob), _, SP, Current, Next, Trace) :- + matrix_get(Current, [I], PI), + NP is PI+Prob, + matrix_get(Next, [P], P0), + (NP > P0 -> + matrix_set(Next, [P], NP), + SP1 is SP+1, + IN is -I, + matrix_set(Trace, [SP1,P], IN) + ; + true + ). + +backtrace(Dump, EI, Map, L, Trace) :- + L1 is L-1, + Pos = [L1,EI], + matrix_get(Dump,Pos,Next), + trace(L1,Next,Dump,Map,[],Trace). + +trace(0,0,_,_,Trace,Trace) :- !. +trace(L1,Next,Dump,Map,Trace0,Trace) :- + (Next < 0 -> + NL is L1-1, + P is -Next + ; + NL = L1, + P = Next + ), + once(member(P-AKey,Map)), + AKey=..[N|Args], + Key=..[N,NL|Args], + matrix_get(Dump,[NL,P],New), + trace(NL,New,Dump,Map,[Key|Trace0],Trace). + + + diff --git a/packages/CLPBN/clpbn/xbif.yap b/packages/CLPBN/clpbn/xbif.yap new file mode 100644 index 000000000..df010c6bf --- /dev/null +++ b/packages/CLPBN/clpbn/xbif.yap @@ -0,0 +1,119 @@ +% +% XMLBIF support for CLP(BN) +% + +:- module(xbif, [clpbn2xbif/3]). + +:- use_module(library('clpbn/dists'), [ + get_dist_domain/2]). + +clpbn2xbif(Stream, Name, Network) :- + format(Stream, ' + + + + + + + + + + + + + + + + + + + +]> + + + +~w + +',[Name]), + output_vars(Stream, Network), + output_dists(Stream, Network), + format(Stream, ' + +',[]). + +output_vars(_, []). +output_vars(Stream, [V|Vs]) :- + output_var(Stream, V), + output_vars(Stream, Vs). + +output_var(Stream, V) :- + clpbn:get_atts(V,[key(Key),dist(Id,_)]), + get_dist_domain(Id, Domain), + format(Stream, ' + ',[]), + output_key(Stream,Key), + format('~n',[]), + output_domain(Stream, Domain), + format(Stream, '~n~n',[]). + +output_domain(_, []). +output_domain(Stream, [El|Domain]) :- + format(Stream, ' ~q~n',[El]), + output_domain(Stream, Domain). + +output_dists(_, []). +output_dists(Stream, [V|Network]) :- + output_dist(Stream, V), + output_dists(Stream, Network). + + +output_dist(Stream, V) :- + clpbn:get_atts(V,[key(Key),dist(_,CPT,Parents)]), + format(Stream, ' + ',[]), + output_key(Stream, Key), + format('~n',[]), + output_parents(Stream,Parents), + output_cpt(Stream,CPT), + format(Stream, '~n~n',[]). + +output_parents(_,[]). +output_parents(Stream,[P1|Ps]) :- + clpbn:get_atts(P1,[key(Key)]), + format(Stream, '',[]), + output_key(Stream,Key), + format('~n',[]), + output_parents(Stream,Ps). + +output_cpt(Stream,CPT) :- + format(Stream, ' ', []), + output_els(Stream, CPT), + format(Stream, '
~n', []). + +output_els(_, []). +output_els(Stream, [El|Els]) :- + format(Stream,'~f ',[El]), + output_els(Stream, Els). + +output_key(Stream, Key) :- + output_key(Stream, 0, Key). + +output_key(Stream, _, Key) :- + primitive(Key), !, + write(Stream, Key). +output_key(Stream, I0, Key) :- + Key =.. [Name|Args], + write(Stream, Name), + I is I0+1, + output_key_args(Stream, I, Args). + +output_key_args(_, _, []). +output_key_args(Stream, I, [Arg|Args]) :- + format(Stream, '~*c', [I,0'_]), + output_key(Stream, I, Arg), + output_key_args(Stream, I, Args). + diff --git a/packages/CLPBN/learning/aleph_params.yap b/packages/CLPBN/learning/aleph_params.yap new file mode 100644 index 000000000..c27844e22 --- /dev/null +++ b/packages/CLPBN/learning/aleph_params.yap @@ -0,0 +1,306 @@ +% +% Interface the Aleph ILP system to CLP(BN) +% +% Relies on the Aleph cost function. +% It assumes Aleph work as usual, but some variables are of type random. +% +:- module(clpbn_aleph, + [init_clpbn_cost/0, + random_type/2]). + +:- dynamic rt/2, inited/1. + +:- use_module(library('clpbn'), + [{}/1, + clpbn_flag/2, + clpbn_flag/3, + set_clpbn_flag/2]). + +:- use_module(library('clpbn/learning/em')). + +:- use_module(library('clpbn/matrix_cpt_utils'), + [uniform_CPT_as_list/2]). + +:- use_module(library('clpbn/dists'), + [reset_all_dists/0, + get_dist_key/2, + get_dist_params/2 + ]). + +:- use_module(library('clpbn/table'), + [clpbn_tabled_abolish/1, + clpbn_tabled_asserta/1, + clpbn_tabled_asserta/2, + clpbn_tabled_assertz/1, + clpbn_tabled_clause/2, + clpbn_tabled_number_of_clauses/2, + clpbn_is_tabled/1, + clpbn_tabled_dynamic/1]). + +% +% Tell Aleph not to use default solver during saturation +% +% all work will be done by EM +:- set_clpbn_flag(solver,none). + +% +% This is the Aleph interface +% examples are stored as example(Id, Type, Example) +% CPT domains are stored as random_type(KeySkeleton, ListOfValues). +% + +:- use_module(library(lists),[append/3]). + +:- multifile user:cost/3. + +% handle uninstantiated examples as hidden variables. +:- user:set(skolem_examples, false). + +% avoid doing CLP(BN) stuff except at start +:- user:set(sat_start_hook, clpbn_aleph:disable_solver). +:- user:set(sat_stop_hook, clpbn_aleph:enable_solver). + +:- user:set(reduce_start_hook, clpbn_aleph:disable_solver). +:- user:set(reduce_stop_hook, clpbn_aleph:enable_solver). + +:- user:set(record_testclause_hook, clpbn_aleph:do_nothing). + +:- user:set(newbest_hook, clpbn_aleph:store_theory). + +disable_solver(_) :- + clpbn_flag(solver, Old, none), + nb_setval(old_clpbn_solver, Old). +disable_solver(_,_) :- + clpbn_flag(solver, Old, none), + nb_setval(old_clpbn_solver, Old). + +enable_solver :- + nb_getval(old_clpbn_solver, Old), + set_clpbn_flag(solver, Old). +enable_solver(_,_) :- + nb_getval(old_clpbn_solver, Old), + set_clpbn_flag(solver, Old). + +do_nothing(_). + +% backup current best theory in DB. +store_theory(_,_,_) :- + eraseall(best_theory), + fail. +store_theory(_,(H:-_),_) :- + clpbn_is_tabled(user:H), !, + store_tabled_theory(H). +store_theory(_,(H:-_),_) :- + store_theory(H). + +store_tabled_theory(H) :- + clpbn_tabled_clause(user:H,B), + add_correct_cpt(B,NB), + store_cl((H:-NB)), + fail. +store_tabled_theory(_). + +store_theory(H) :- + clause(user:H,B), + add_correct_cpt(B,NB), + store_cl((H:-NB)), + fail. +store_theory(_). + +add_correct_cpt((G,B),(G,NB)) :- !, + add_correct_cpt(B,NB). +add_correct_cpt((clpbn:{V = K with Tab }), ({V = K with NTab})) :- + correct_tab(Tab,K,NTab). +add_correct_cpt(({V = K with Tab }), ({V = K with NTab})) :- + correct_tab(Tab,K,NTab). + +correct_tab(p(Vs,_),K,p(Vs,TDist)) :- + get_dist_key(Id, K), + get_dist_params(Id, TDist). +correct_tab(p(Vs,_,Ps),K,p(Vs,TDist,Ps)) :- + get_dist_key(Id, K), + get_dist_params(Id, TDist). + +store_cl(Cl) :- + recordz(best_theory, Cl, _). + + +:- user:set(best_clause_hook, clpbn_aleph:add_new_clause). + +add_new_clause(_,(_ :- true),_,_) :- !. +add_new_clause(_,(H :- B),_,_) :- + user:db_usage, + user:db_dynamic, + domain(H, K, V, D), + rewrite_body(B, IB, Vs, _, ( !, { V = K with p(D, CPTList, Vs) })), + % need to remember which CPT we want + get_dist_key(Id, K), + get_dist_params(Id, CPTList), + ( + clpbn_is_tabled(user:H) + -> + clpbn_tabled_asserta(user:(H :- IB)) + ; + asserta(user:(H :- IB)) + ), + user:setting(verbosity,V), + ( V >= 1 -> + user:p_message('CLP(BN) Theory'), + functor(H,N,Ar), listing(user:N/Ar) + ; + true + ). + + +% user-defined cost function, Aleph knows about this (and only about this). +user:cost((H :- B),Inf,Score) :- !, + domain(H, K, V, D), + check_info(Inf), + rewrite_body(B, IB, Vs, Ds, ( !, { V = K with p(D, CPTList, Vs) })), + uniform_cpt([D|Ds], CPTList), + ( + clpbn_is_tabled(user:H) + -> + clpbn_tabled_asserta(user:(H :- IB), R) + ; + asserta(user:(H :- IB), R) + ), + ( + cpt_score(Score0) + -> + erase(R), + Score is -Score0 + ; + % illegal clause, just get out of here. + erase(R), + fail + ). +user:cost(H,_Inf,Score) :- !, + init_clpbn_cost(H, Score0), + Score is -Score0. + +% this is here so that Aleph will actually compute coverage. Aleph computes +% coverage only if cost actually checks Inf. +check_info(_). + +init_clpbn_cost(_, Score) :- + inited(Score), !. +init_clpbn_cost(H, Score) :- + functor(H,N,A), + % get rid of Aleph crap + ( + clpbn_is_tabled(user:H) + -> + clpbn_tabled_abolish(user:N/A), + clpbn_tabled_dynamic(user:N/A) + ; + abolish(user:N/A), + % make it easy to add and remove clauses. + dynamic(user:N/A) + ), + domain(H, K, V, D), + uniform_cpt([D], CPTList), + % This will be the default cause, called when the other rules fail. + ( + clpbn_is_tabled(user:H) + -> + clpbn_tabled_assertz(user:(H :- !, { V = K with p(D, CPTList) })) + ; + assert(user:(H :- !, { V = K with p(D, CPTList) })) + ), + cpt_score(Score), + assert(inited(Score)). + +% receives H, and generates a key K, a random variable RV, and a domain D. +domain(H, K, RV, D) :- + functor(H,Name,Arity), + functor(Pred,Name,Arity), + ( + recorded(aleph,modeh(_,Pred),_) + -> + true + ; + user:'$aleph_global'(modeh,modeh(_,Pred)) + ), + arg(Arity,Pred,+RType), + rt(RType,D), !, + key_from_head(H,K,RV). +domain(H, K, V, D) :- + current_predicate(_,user:domain(_)), + key_from_head(H,K,V), + user:domain(K,D). + +key_from_head(H,K,V) :- + H =.. [Name|Args], + ( + clpbn_is_tabled(user:H) + -> + clpbn_tabled_number_of_clauses(user:H,NClauses) + ; + predicate_property(user:H,number_of_clauses(NClauses)) + ), + atomic_concat(Name,NClauses,NName), + append(H0L,[V],Args), + K =.. [NName|H0L]. + +% transforms_body into something that is going to be called +% receives G0, and generates a list of goals, a list of variables, and a list of domains. +% receives also a Tail with the constraint to append at the end. +rewrite_body((A,B), (user:NA,NB), [V|Vs], [D|Ds], Tail) :- + rewrite_goal(A, V, D, NA), !, + rewrite_body(B, NB, Vs, Ds, Tail). +rewrite_body((A,B), (user:A,NB), Vs, Ds, Tail) :- + rewrite_body(B,NB, Vs, Ds, Tail). +rewrite_body(A,(user:NA,Tail), [V], [D], Tail) :- + rewrite_goal(A, V, D, NA), !. +rewrite_body(A, (user:A,Tail), [], [], Tail). + +% so they need not be rewritten. +rewrite_goal(A,V,D,NA) :- + functor(A,Name,Arity), + functor(Pred,Name,Arity), + ( + recorded(aleph,modeb(_,Pred),_) + -> + true + ; + user:'$aleph_global'(modeb,modeb(_,Pred)) + ), + arg(Arity,Pred,-RType), + rt(RType,D), !, + A =.. [Name|Args], + replace_last_var(Args,V,NArgs), + NA =.. [Name|NArgs]. + +replace_last_var([_],V,[V]) :- !. +replace_last_var([A|Args],V,[A|NArgs]) :- + replace_last_var(Args,V,NArgs). + + +% +% This is the key +% +cpt_score(Lik) :- + findall(user:Ex, user:example(_,pos,Ex), Exs), + clpbn_flag(solver, Solver), + clpbn_flag(em_solver, EMSolver), + set_clpbn_flag(solver, EMSolver), + reset_all_dists, + em(Exs, 0.01, 10, _Tables, Lik), + set_clpbn_flag(solver, Solver). + +complete_clpbn_cost(_AlephClause). + +random_type(A,B) :- + assert(rt(A,B)). + + +uniform_cpt(Ds, CPTList) :- + lengths(Ds, Ls), + uniform_CPT_as_list(Ls, CPTList). + +lengths([], []). +lengths([D|Ds], [L|Ls]) :- + length(D, L), + lengths(Ds, Ls). + diff --git a/packages/CLPBN/learning/bnt_parms.yap b/packages/CLPBN/learning/bnt_parms.yap new file mode 100644 index 000000000..d3e8d9734 --- /dev/null +++ b/packages/CLPBN/learning/bnt_parms.yap @@ -0,0 +1,121 @@ +% +% Learn parameters using the BNT toolkit +% + +:- yap_flag(unknown,error). + +:- style_check(all). + +:- module(bnt_parameters, [learn_parameters/2]). + +:- use_module(library('clpbn'), [ + clpbn_flag/3]). + +:- use_module(library('clpbn/bnt'), [ + create_bnt_graph/2]). + +:- use_module(library('clpbn/display'), [ + clpbn_bind_vals/3]). + +:- use_module(library('clpbn/dists'), [ + get_dist_domain/2 + ]). + +:- use_module(library(matlab), [matlab_initialized_cells/4, + matlab_call/2, + matlab_get_variable/2 + ]). + +:- dynamic bnt_em_max_iter/1. +bnt_em_max_iter(10). + + +% syntactic sugar for matlab_call. +:- op(800,yfx,<--). + +G <-- Y :- + matlab_call(Y,G). + + +learn_parameters(Items, Tables) :- + run_all(Items), + clpbn_flag(solver, OldSolver, bnt), + clpbn_flag(bnt_model, Old, tied), + attributes:all_attvars(AVars), + % sort and incorporte evidence + clpbn_vars(AVars, AllVars), + length(AllVars,NVars), + create_bnt_graph(AllVars, Reps), + mk_sample(AllVars,NVars,EvVars), + bnt_learn_parameters(NVars,EvVars), + get_parameters(Reps, Tables), + clpbn_flag(solver, bnt, OldSolver), + clpbn_flag(bnt_model, tied, Old). + +run_all([]). +run_all([G|Gs]) :- + call(user:G), + run_all(Gs). + +clpbn_vars(Vs,BVars) :- + get_clpbn_vars(Vs,CVs), + keysort(CVs,KVs), + merge_vars(KVs,BVars). + +get_clpbn_vars([],[]). +get_clpbn_vars([V|GVars],[K-V|CLPBNGVars]) :- + clpbn:get_atts(V, [key(K)]), !, + get_clpbn_vars(GVars,CLPBNGVars). +get_clpbn_vars([_|GVars],CLPBNGVars) :- + get_clpbn_vars(GVars,CLPBNGVars). + +merge_vars([],[]). +merge_vars([K-V|KVs],[V|BVars]) :- + get_var_has_same_key(KVs,K,V,KVs0), + merge_vars(KVs0,BVars). + +get_var_has_same_key([K-V|KVs],K,V,KVs0) :- !, + get_var_has_same_key(KVs,K,V,KVs0). +get_var_has_same_key(KVs,_,_,KVs). + + +mk_sample(AllVars,NVars, LL) :- + add2sample(AllVars, LN), + length(LN,LL), + matlab_initialized_cells( NVars, 1, LN, sample). + +add2sample([], []). +add2sample([V|Vs],[val(VId,1,Val)|Vals]) :- + clpbn:get_atts(V, [evidence(Ev),dist(Id,_)]), !, + bnt:get_atts(V,[bnt_id(VId)]), + get_dist_domain(Id, Domain), + evidence_val(Ev,1,Domain,Val), + add2sample(Vs, Vals). +add2sample([_V|Vs],Vals) :- + add2sample(Vs, Vals). + +evidence_val(Ev,Val,[Ev|_],Val) :- !. +evidence_val(Ev,I0,[_|Domain],Val) :- + I1 is I0+1, + evidence_val(Ev,I1,Domain,Val). + +bnt_learn_parameters(_,_) :- + engine <-- jtree_inf_engine(bnet), +% engine <-- var_elim_inf_engine(bnet), +% engine <-- gibbs_sampling_inf_engine(bnet), +% engine <-- belprop_inf_engine(bnet), +% engine <-- pearl_inf_engine(bnet), + bnt_em_max_iter(MaxIters), + [new_bnet, trace] <-- learn_params_em(engine, sample, MaxIters). + + +get_parameters([],[]). +get_parameters([Rep-v(_,_,_)|Reps],[CPT|CPTs]) :- + get_new_table(Rep,CPT), + get_parameters(Reps,CPTs). + +get_new_table(Rep,CPT) :- + s <-- struct(new_bnet.'CPD'({Rep})), + matlab_get_variable( s.'CPT', CPT). + + diff --git a/packages/CLPBN/learning/em.yap b/packages/CLPBN/learning/em.yap new file mode 100644 index 000000000..e72998959 --- /dev/null +++ b/packages/CLPBN/learning/em.yap @@ -0,0 +1,229 @@ +% +% The world famous EM algorithm, in a nutshell +% + +:- module(clpbn_em, [em/5]). + +:- use_module(library(lists), + [append/3]). + +:- use_module(library(clpbn), + [clpbn_init_solver/5, + clpbn_run_solver/4, + clpbn_flag/2]). + +:- use_module(library('clpbn/dists'), + [get_dist_domain_size/2, + empty_dist/2, + dist_new_table/2, + get_dist_key/2, + randomise_all_dists/0, + uniformise_all_dists/0]). + +:- use_module(library('clpbn/connected'), + [clpbn_subgraphs/2]). + +:- use_module(library('clpbn/learning/learn_utils'), + [run_all/1, + clpbn_vars/2, + normalise_counts/2, + compute_likelihood/3, + soften_sample/2]). + +:- use_module(library(lists), + [member/2]). + +:- use_module(library(matrix), + [matrix_add/3, + matrix_to_list/2]). + +:- use_module(library(rbtrees), + [rb_new/1, + rb_insert/4, + rb_lookup/3]). + +:- use_module(library('clpbn/utils'), + [ + check_for_hidden_vars/3, + sort_vars_by_key/3]). + +:- meta_predicate em(:,+,+,-,-), init_em(:,-). + +em(Items, MaxError, MaxIts, Tables, Likelihood) :- + catch(init_em(Items, State),Error,handle_em(Error)), + em_loop(0, 0.0, State, MaxError, MaxIts, Likelihood, Tables), + assert(em_found(Tables, Likelihood)), + fail. +% get rid of new random variables the easy way :) +em(_, _, _, Tables, Likelihood) :- + retract(em_found(Tables, Likelihood)). + + +handle_em(error(repeated_parents)) :- + assert(em_found(_, -inf)), + fail. + + + +% This gets you an initial configuration. If there is a lot of evidence +% tables may be filled in close to optimal, otherwise they may be +% close to uniform. +% it also gets you a run for random variables + +% state collects all Info we need for the EM algorithm +% it includes the list of variables without evidence, +% the list of distributions for which we want to compute parameters, +% and more detailed info on distributions, namely with a list of all instances for the distribution. +init_em(Items, state( AllDists, AllDistInstances, MargVars, SolverVars)) :- + run_all(Items), +% randomise_all_dists, + uniformise_all_dists, + attributes:all_attvars(AllVars0), + sort_vars_by_key(AllVars0,AllVars,[]), + % remove variables that do not have to do with this query. +% check_for_hidden_vars(AllVars1, AllVars1, AllVars), + different_dists(AllVars, AllDists, AllDistInstances, MargVars), + clpbn_flag(em_solver, Solver), + clpbn_init_solver(Solver, MargVars, AllVars, _, SolverVars). + +% loop for as long as you want. +em_loop(Its, Likelihood0, State, MaxError, MaxIts, LikelihoodF, FTables) :- + estimate(State, LPs), + maximise(State, Tables, LPs, Likelihood), +% writeln(Likelihood:Its:Likelihood0:Tables), + ( + ( + abs((Likelihood - Likelihood0)/Likelihood) < MaxError + ; + Its == MaxIts + ) + -> + ltables(Tables, FTables), + LikelihoodF = Likelihood + ; + Its1 is Its+1, + em_loop(Its1, Likelihood, State, MaxError, MaxIts, LikelihoodF, FTables) + ). + +ltables([], []). +ltables([Id-T|Tables], [Key-LTable|FTables]) :- + matrix_to_list(T,LTable), + get_dist_key(Id, Key), + ltables(Tables, FTables). + + + +% collect the different dists we are going to learn next. +different_dists(AllVars, AllDists, AllInfo, MargVars) :- + all_dists(AllVars, Dists0), + sort(Dists0, Dists1), + group(Dists1, AllDists, AllInfo, MargVars0, []), + sort(MargVars0, MargVars). + +all_dists([], []). +all_dists([V|AllVars], [i(Id, [V|Parents], Cases, Hiddens)|Dists]) :- + clpbn:get_atts(V, [dist(Id,Parents)]), + sort([V|Parents], Sorted), + length(Sorted, LengSorted), + length(Parents, LengParents), + ( + LengParents+1 =:= LengSorted + -> + true + ; + throw(error(repeated_parents)) + ), + generate_hidden_cases([V|Parents], CompactCases, Hiddens), + uncompact_cases(CompactCases, Cases), + all_dists(AllVars, Dists). + +generate_hidden_cases([], [], []). +generate_hidden_cases([V|Parents], [P|Cases], Hiddens) :- + clpbn:get_atts(V, [evidence(P)]), !, + generate_hidden_cases(Parents, Cases, Hiddens). +generate_hidden_cases([V|Parents], [Cases|MoreCases], [V|Hiddens]) :- + clpbn:get_atts(V, [dist(Id,_)]), + get_dist_domain_size(Id, Sz), + gen_cases(0, Sz, Cases), + generate_hidden_cases(Parents, MoreCases, Hiddens). + +gen_cases(Sz, Sz, []) :- !. +gen_cases(I, Sz, [I|Cases]) :- + I1 is I+1, + gen_cases(I1, Sz, Cases). + +uncompact_cases(CompactCases, Cases) :- + findall(Case, is_case(CompactCases, Case), Cases). + +is_case([], []). +is_case([A|CompactCases], [A|Case]) :- + integer(A), !, + is_case(CompactCases, Case). +is_case([L|CompactCases], [C|Case]) :- + member(C, L), + is_case(CompactCases, Case). + +group([], [], []) --> []. +group([i(Id,Ps,Cs,[])|Dists1], [Id|Ids], [Id-[i(Id,Ps,Cs,[])|Extra]|AllInfo]) --> !, + same_id(Dists1, Id, Extra, Rest), + group(Rest, Ids, AllInfo). +group([i(Id,Ps,Cs,Hs)|Dists1], [Id|Ids], [Id-[i(Id,Ps,Cs,Hs)|Extra]|AllInfo]) --> + [Hs], + same_id(Dists1, Id, Extra, Rest), + group(Rest, Ids, AllInfo). + +same_id([i(Id,Vs,Cases,[])|Dists1], Id, [i(Id, Vs, Cases, [])|Extra], Rest) --> !, + same_id(Dists1, Id, Extra, Rest). +same_id([i(Id,Vs,Cases,Hs)|Dists1], Id, [i(Id, Vs, Cases, Hs)|Extra], Rest) --> !, + [Hs], + same_id(Dists1, Id, Extra, Rest). +same_id(Dists, _, [], Dists) --> []. + + +compact_mvars([], []). +compact_mvars([X1,X2|MargVars], CMVars) :- X1 == X2, !, + compact_mvars([X2|MargVars], CMVars). +compact_mvars([X|MargVars], [X|CMVars]) :- !, + compact_mvars(MargVars, CMVars). + +estimate(state(_, _, Margs, SolverState), LPs) :- + clpbn_flag(em_solver, Solver), + clpbn_run_solver(Solver, Margs, LPs, SolverState). + +maximise(state(_,DistInstances,MargVars,_), Tables, LPs, Likelihood) :- + rb_new(MDistTable0), + create_mdist_table(MargVars, LPs, MDistTable0, MDistTable), + compute_parameters(DistInstances, Tables, MDistTable, 0.0, Likelihood, LPs:MargVars). + +create_mdist_table([],[],MDistTable,MDistTable). +create_mdist_table([Vs|MargVars],[Ps|LPs],MDistTable0,MDistTable) :- + rb_insert(MDistTable0, Vs, Ps, MDistTableI), + create_mdist_table(MargVars, LPs, MDistTableI ,MDistTable). + +compute_parameters([], [], _, Lik, Lik, _). +compute_parameters([Id-Samples|Dists], [Id-NewTable|Tables], MDistTable, Lik0, Lik, LPs:MargVars) :- + empty_dist(Id, Table0), + add_samples(Samples, Table0, MDistTable), + soften_sample(Table0, SoftenedTable), + matrix:matrix_sum(Table0,TotM), + normalise_counts(SoftenedTable, NewTable), + compute_likelihood(Table0, NewTable, DeltaLik), + dist_new_table(Id, NewTable), + NewLik is Lik0+DeltaLik, + compute_parameters(Dists, Tables, MDistTable, NewLik, Lik, LPs:MargVars). + +add_samples([], _, _). +add_samples([i(_,_,[Case],[])|Samples], Table, MDistTable) :- !, + matrix_add(Table,Case,1.0), + add_samples(Samples, Table, MDistTable). +add_samples([i(_,_,Cases,Hiddens)|Samples], Table, MDistTable) :- + rb_lookup(Hiddens, Ps, MDistTable), + run_sample(Cases, Ps, Table), + add_samples(Samples, Table, MDistTable). + +run_sample([], [], _). +run_sample([C|Cases], [P|Ps], Table) :- + matrix_add(Table, C, P), + run_sample(Cases, Ps, Table). + + diff --git a/packages/CLPBN/learning/example/school_params.yap b/packages/CLPBN/learning/example/school_params.yap new file mode 100644 index 000000000..30fbdc513 --- /dev/null +++ b/packages/CLPBN/learning/example/school_params.yap @@ -0,0 +1,46 @@ +% learn distribution for school database. + +% we do not consider the aggregates yet. + +:- [pos:train]. + +:- ['~/Yap/work/CLPBN/clpbn/examples/School/school_32']. + +:- ['~/Yap/work/CLPBN/learning/em']. + +main :- + findall(X,goal(X),L), + em(L,0.01,10,CPTs,Lik), + writeln(Lik:CPTs). + +% +% change to 0.05, 0.1, 0.2 to make things simpler/harder +% +missing(0.3). + +% miss 30% of the examples. +goal(professor_ability(P,V)) :- + pos:professor_ability(P,V1), + missing(X), + ( random > X -> V = V1 ; true). +% miss 10% of the examples. +goal(professor_popularity(P,V)) :- + pos:professor_popularity(P,V1), + missing(X), + ( random > X -> V = V1 ; true). +goal(registration_grade(P,V)) :- + pos:registration_grade(P,V1), + missing(X), + ( random > X -> V = V1 ; true). +goal(student_intelligence(P,V)) :- + pos:student_intelligence(P,V1), + missing(X), + ( random > X -> V = V1 ; true). +goal(course_difficulty(P,V)) :- + pos:course_difficulty(P,V1), + missing(X), + ( random > X -> V = V1 ; true). +goal(registration_satisfaction(P,V)) :- + pos:registration_satisfaction(P,V1), + missing(X), + ( random > X -> V = V1 ; true). diff --git a/packages/CLPBN/learning/example/train.yap b/packages/CLPBN/learning/example/train.yap new file mode 100644 index 000000000..f6dda7aef --- /dev/null +++ b/packages/CLPBN/learning/example/train.yap @@ -0,0 +1,2433 @@ + + +professor_ability(p0,h). +professor_ability(p1,h). +professor_ability(p2,m). +professor_ability(p3,m). +professor_ability(p4,h). +professor_ability(p5,h). +professor_ability(p6,l). +professor_ability(p7,l). +professor_ability(p8,m). +professor_ability(p9,h). +professor_ability(p10,m). +professor_ability(p11,h). +professor_ability(p12,h). +professor_ability(p13,m). +professor_ability(p14,m). +professor_ability(p15,m). +professor_ability(p16,m). +professor_ability(p17,m). +professor_ability(p18,l). +professor_ability(p19,h). +professor_ability(p20,h). +professor_ability(p21,h). +professor_ability(p22,m). +professor_ability(p23,m). +professor_ability(p24,l). +professor_ability(p25,m). +professor_ability(p26,h). +professor_ability(p27,h). +professor_ability(p28,h). +professor_ability(p29,m). +professor_ability(p30,m). +professor_ability(p31,h). + + +course_difficulty(c0,h). +course_difficulty(c1,m). +course_difficulty(c2,l). +course_difficulty(c3,m). +course_difficulty(c4,m). +course_difficulty(c5,l). +course_difficulty(c6,m). +course_difficulty(c7,h). +course_difficulty(c8,h). +course_difficulty(c9,l). +course_difficulty(c10,m). +course_difficulty(c11,m). +course_difficulty(c12,m). +course_difficulty(c13,h). +course_difficulty(c14,m). +course_difficulty(c15,h). +course_difficulty(c16,l). +course_difficulty(c17,h). +course_difficulty(c18,m). +course_difficulty(c19,l). +course_difficulty(c20,m). +course_difficulty(c21,h). +course_difficulty(c22,m). +course_difficulty(c23,m). +course_difficulty(c24,h). +course_difficulty(c25,m). +course_difficulty(c26,l). +course_difficulty(c27,h). +course_difficulty(c28,m). +course_difficulty(c29,m). +course_difficulty(c30,m). +course_difficulty(c31,m). +course_difficulty(c32,l). +course_difficulty(c33,m). +course_difficulty(c34,l). +course_difficulty(c35,h). +course_difficulty(c36,h). +course_difficulty(c37,m). +course_difficulty(c38,m). +course_difficulty(c39,m). +course_difficulty(c40,h). +course_difficulty(c41,m). +course_difficulty(c42,h). +course_difficulty(c43,m). +course_difficulty(c44,m). +course_difficulty(c45,m). +course_difficulty(c46,m). +course_difficulty(c47,m). +course_difficulty(c48,m). +course_difficulty(c49,l). +course_difficulty(c50,m). +course_difficulty(c51,h). +course_difficulty(c52,h). +course_difficulty(c53,h). +course_difficulty(c54,m). +course_difficulty(c55,h). +course_difficulty(c56,m). +course_difficulty(c57,m). +course_difficulty(c58,h). +course_difficulty(c59,m). +course_difficulty(c60,h). +course_difficulty(c61,m). +course_difficulty(c62,l). +course_difficulty(c63,l). + + +student_intelligence(s0,l). +student_intelligence(s1,l). +student_intelligence(s2,h). +student_intelligence(s3,h). +student_intelligence(s4,h). +student_intelligence(s5,h). +student_intelligence(s6,m). +student_intelligence(s7,h). +student_intelligence(s8,h). +student_intelligence(s9,m). +student_intelligence(s10,m). +student_intelligence(s11,m). +student_intelligence(s12,h). +student_intelligence(s13,h). +student_intelligence(s14,h). +student_intelligence(s15,m). +student_intelligence(s16,h). +student_intelligence(s17,m). +student_intelligence(s18,m). +student_intelligence(s19,h). +student_intelligence(s20,m). +student_intelligence(s21,h). +student_intelligence(s22,h). +student_intelligence(s23,h). +student_intelligence(s24,m). +student_intelligence(s25,h). +student_intelligence(s26,m). +student_intelligence(s27,m). +student_intelligence(s28,m). +student_intelligence(s29,m). +student_intelligence(s30,h). +student_intelligence(s31,m). +student_intelligence(s32,m). +student_intelligence(s33,h). +student_intelligence(s34,l). +student_intelligence(s35,m). +student_intelligence(s36,l). +student_intelligence(s37,m). +student_intelligence(s38,h). +student_intelligence(s39,h). +student_intelligence(s40,h). +student_intelligence(s41,m). +student_intelligence(s42,m). +student_intelligence(s43,h). +student_intelligence(s44,h). +student_intelligence(s45,h). +student_intelligence(s46,l). +student_intelligence(s47,h). +student_intelligence(s48,m). +student_intelligence(s49,m). +student_intelligence(s50,h). +student_intelligence(s51,m). +student_intelligence(s52,m). +student_intelligence(s53,m). +student_intelligence(s54,h). +student_intelligence(s55,h). +student_intelligence(s56,l). +student_intelligence(s57,m). +student_intelligence(s58,h). +student_intelligence(s59,m). +student_intelligence(s60,m). +student_intelligence(s61,h). +student_intelligence(s62,m). +student_intelligence(s63,h). +student_intelligence(s64,l). +student_intelligence(s65,m). +student_intelligence(s66,h). +student_intelligence(s67,m). +student_intelligence(s68,h). +student_intelligence(s69,h). +student_intelligence(s70,l). +student_intelligence(s71,m). +student_intelligence(s72,h). +student_intelligence(s73,m). +student_intelligence(s74,h). +student_intelligence(s75,h). +student_intelligence(s76,h). +student_intelligence(s77,h). +student_intelligence(s78,h). +student_intelligence(s79,m). +student_intelligence(s80,m). +student_intelligence(s81,l). +student_intelligence(s82,h). +student_intelligence(s83,h). +student_intelligence(s84,m). +student_intelligence(s85,h). +student_intelligence(s86,m). +student_intelligence(s87,h). +student_intelligence(s88,h). +student_intelligence(s89,m). +student_intelligence(s90,h). +student_intelligence(s91,m). +student_intelligence(s92,h). +student_intelligence(s93,l). +student_intelligence(s94,l). +student_intelligence(s95,h). +student_intelligence(s96,m). +student_intelligence(s97,h). +student_intelligence(s98,h). +student_intelligence(s99,l). +student_intelligence(s100,h). +student_intelligence(s101,h). +student_intelligence(s102,m). +student_intelligence(s103,h). +student_intelligence(s104,l). +student_intelligence(s105,m). +student_intelligence(s106,h). +student_intelligence(s107,l). +student_intelligence(s108,m). +student_intelligence(s109,m). +student_intelligence(s110,m). +student_intelligence(s111,h). +student_intelligence(s112,m). +student_intelligence(s113,h). +student_intelligence(s114,m). +student_intelligence(s115,h). +student_intelligence(s116,m). +student_intelligence(s117,m). +student_intelligence(s118,m). +student_intelligence(s119,h). +student_intelligence(s120,h). +student_intelligence(s121,h). +student_intelligence(s122,m). +student_intelligence(s123,m). +student_intelligence(s124,h). +student_intelligence(s125,m). +student_intelligence(s126,m). +student_intelligence(s127,m). +student_intelligence(s128,m). +student_intelligence(s129,h). +student_intelligence(s130,m). +student_intelligence(s131,h). +student_intelligence(s132,h). +student_intelligence(s133,h). +student_intelligence(s134,h). +student_intelligence(s135,h). +student_intelligence(s136,m). +student_intelligence(s137,m). +student_intelligence(s138,l). +student_intelligence(s139,h). +student_intelligence(s140,h). +student_intelligence(s141,m). +student_intelligence(s142,m). +student_intelligence(s143,h). +student_intelligence(s144,h). +student_intelligence(s145,h). +student_intelligence(s146,m). +student_intelligence(s147,m). +student_intelligence(s148,m). +student_intelligence(s149,h). +student_intelligence(s150,l). +student_intelligence(s151,h). +student_intelligence(s152,h). +student_intelligence(s153,m). +student_intelligence(s154,m). +student_intelligence(s155,h). +student_intelligence(s156,m). +student_intelligence(s157,m). +student_intelligence(s158,h). +student_intelligence(s159,h). +student_intelligence(s160,m). +student_intelligence(s161,m). +student_intelligence(s162,h). +student_intelligence(s163,m). +student_intelligence(s164,m). +student_intelligence(s165,m). +student_intelligence(s166,m). +student_intelligence(s167,h). +student_intelligence(s168,h). +student_intelligence(s169,m). +student_intelligence(s170,m). +student_intelligence(s171,m). +student_intelligence(s172,h). +student_intelligence(s173,h). +student_intelligence(s174,h). +student_intelligence(s175,m). +student_intelligence(s176,m). +student_intelligence(s177,m). +student_intelligence(s178,h). +student_intelligence(s179,m). +student_intelligence(s180,m). +student_intelligence(s181,h). +student_intelligence(s182,m). +student_intelligence(s183,h). +student_intelligence(s184,h). +student_intelligence(s185,m). +student_intelligence(s186,m). +student_intelligence(s187,m). +student_intelligence(s188,h). +student_intelligence(s189,m). +student_intelligence(s190,h). +student_intelligence(s191,l). +student_intelligence(s192,h). +student_intelligence(s193,m). +student_intelligence(s194,m). +student_intelligence(s195,m). +student_intelligence(s196,h). +student_intelligence(s197,h). +student_intelligence(s198,h). +student_intelligence(s199,m). +student_intelligence(s200,h). +student_intelligence(s201,l). +student_intelligence(s202,h). +student_intelligence(s203,m). +student_intelligence(s204,h). +student_intelligence(s205,h). +student_intelligence(s206,h). +student_intelligence(s207,h). +student_intelligence(s208,m). +student_intelligence(s209,h). +student_intelligence(s210,m). +student_intelligence(s211,m). +student_intelligence(s212,m). +student_intelligence(s213,h). +student_intelligence(s214,h). +student_intelligence(s215,m). +student_intelligence(s216,h). +student_intelligence(s217,m). +student_intelligence(s218,h). +student_intelligence(s219,h). +student_intelligence(s220,h). +student_intelligence(s221,h). +student_intelligence(s222,h). +student_intelligence(s223,m). +student_intelligence(s224,l). +student_intelligence(s225,l). +student_intelligence(s226,m). +student_intelligence(s227,h). +student_intelligence(s228,h). +student_intelligence(s229,m). +student_intelligence(s230,m). +student_intelligence(s231,h). +student_intelligence(s232,m). +student_intelligence(s233,h). +student_intelligence(s234,l). +student_intelligence(s235,h). +student_intelligence(s236,h). +student_intelligence(s237,h). +student_intelligence(s238,h). +student_intelligence(s239,h). +student_intelligence(s240,h). +student_intelligence(s241,m). +student_intelligence(s242,l). +student_intelligence(s243,h). +student_intelligence(s244,h). +student_intelligence(s245,l). +student_intelligence(s246,m). +student_intelligence(s247,h). +student_intelligence(s248,m). +student_intelligence(s249,h). +student_intelligence(s250,m). +student_intelligence(s251,h). +student_intelligence(s252,m). +student_intelligence(s253,m). +student_intelligence(s254,m). +student_intelligence(s255,m). + + +professor_popularity(p0,h). +professor_popularity(p1,h). +professor_popularity(p2,l). +professor_popularity(p3,h). +professor_popularity(p4,h). +professor_popularity(p5,h). +professor_popularity(p6,l). +professor_popularity(p7,l). +professor_popularity(p8,m). +professor_popularity(p9,h). +professor_popularity(p10,l). +professor_popularity(p11,h). +professor_popularity(p12,h). +professor_popularity(p13,l). +professor_popularity(p14,m). +professor_popularity(p15,h). +professor_popularity(p16,m). +professor_popularity(p17,h). +professor_popularity(p18,l). +professor_popularity(p19,h). +professor_popularity(p20,h). +professor_popularity(p21,h). +professor_popularity(p22,h). +professor_popularity(p23,l). +professor_popularity(p24,l). +professor_popularity(p25,l). +professor_popularity(p26,m). +professor_popularity(p27,h). +professor_popularity(p28,h). +professor_popularity(p29,l). +professor_popularity(p30,m). +professor_popularity(p31,h). + + +registration_grade(r0,a). +registration_grade(r1,c). +registration_grade(r2,c). +registration_grade(r3,c). +registration_grade(r4,c). +registration_grade(r5,c). +registration_grade(r6,a). +registration_grade(r7,a). +registration_grade(r8,b). +registration_grade(r9,a). +registration_grade(r10,a). +registration_grade(r11,a). +registration_grade(r12,a). +registration_grade(r13,a). +registration_grade(r14,b). +registration_grade(r15,b). +registration_grade(r16,a). +registration_grade(r17,b). +registration_grade(r18,c). +registration_grade(r19,c). +registration_grade(r20,c). +registration_grade(r21,a). +registration_grade(r22,a). +registration_grade(r23,b). +registration_grade(r24,b). +registration_grade(r25,a). +registration_grade(r26,a). +registration_grade(r27,b). +registration_grade(r28,c). +registration_grade(r29,b). +registration_grade(r30,c). +registration_grade(r31,b). +registration_grade(r32,c). +registration_grade(r33,a). +registration_grade(r34,c). +registration_grade(r35,c). +registration_grade(r36,a). +registration_grade(r37,a). +registration_grade(r38,c). +registration_grade(r39,a). +registration_grade(r40,a). +registration_grade(r41,c). +registration_grade(r42,b). +registration_grade(r43,a). +registration_grade(r44,a). +registration_grade(r45,a). +registration_grade(r46,a). +registration_grade(r47,b). +registration_grade(r48,b). +registration_grade(r49,b). +registration_grade(r50,b). +registration_grade(r51,b). +registration_grade(r52,b). +registration_grade(r53,a). +registration_grade(r54,b). +registration_grade(r55,a). +registration_grade(r56,c). +registration_grade(r57,c). +registration_grade(r58,a). +registration_grade(r59,c). +registration_grade(r60,a). +registration_grade(r61,a). +registration_grade(r62,a). +registration_grade(r63,b). +registration_grade(r64,b). +registration_grade(r65,b). +registration_grade(r66,b). +registration_grade(r67,b). +registration_grade(r68,a). +registration_grade(r69,b). +registration_grade(r70,c). +registration_grade(r71,b). +registration_grade(r72,a). +registration_grade(r73,b). +registration_grade(r74,a). +registration_grade(r75,b). +registration_grade(r76,c). +registration_grade(r77,a). +registration_grade(r78,b). +registration_grade(r79,a). +registration_grade(r80,b). +registration_grade(r81,b). +registration_grade(r82,a). +registration_grade(r83,a). +registration_grade(r84,c). +registration_grade(r85,b). +registration_grade(r86,b). +registration_grade(r87,b). +registration_grade(r88,c). +registration_grade(r89,c). +registration_grade(r90,c). +registration_grade(r91,a). +registration_grade(r92,d). +registration_grade(r93,b). +registration_grade(r94,c). +registration_grade(r95,b). +registration_grade(r96,a). +registration_grade(r97,a). +registration_grade(r98,b). +registration_grade(r99,b). +registration_grade(r100,a). +registration_grade(r101,a). +registration_grade(r102,a). +registration_grade(r103,b). +registration_grade(r104,b). +registration_grade(r105,c). +registration_grade(r106,b). +registration_grade(r107,b). +registration_grade(r108,b). +registration_grade(r109,b). +registration_grade(r110,a). +registration_grade(r111,a). +registration_grade(r112,a). +registration_grade(r113,c). +registration_grade(r114,c). +registration_grade(r115,d). +registration_grade(r116,b). +registration_grade(r117,c). +registration_grade(r118,a). +registration_grade(r119,b). +registration_grade(r120,b). +registration_grade(r121,c). +registration_grade(r122,b). +registration_grade(r123,a). +registration_grade(r124,a). +registration_grade(r125,b). +registration_grade(r126,b). +registration_grade(r127,b). +registration_grade(r128,a). +registration_grade(r129,c). +registration_grade(r130,a). +registration_grade(r131,a). +registration_grade(r132,b). +registration_grade(r133,a). +registration_grade(r134,a). +registration_grade(r135,b). +registration_grade(r136,a). +registration_grade(r137,b). +registration_grade(r138,a). +registration_grade(r139,a). +registration_grade(r140,a). +registration_grade(r141,b). +registration_grade(r142,b). +registration_grade(r143,b). +registration_grade(r144,c). +registration_grade(r145,b). +registration_grade(r146,a). +registration_grade(r147,a). +registration_grade(r148,a). +registration_grade(r149,a). +registration_grade(r150,b). +registration_grade(r151,a). +registration_grade(r152,a). +registration_grade(r153,b). +registration_grade(r154,a). +registration_grade(r155,c). +registration_grade(r156,b). +registration_grade(r157,b). +registration_grade(r158,c). +registration_grade(r159,b). +registration_grade(r160,a). +registration_grade(r161,a). +registration_grade(r162,b). +registration_grade(r163,a). +registration_grade(r164,b). +registration_grade(r165,b). +registration_grade(r166,c). +registration_grade(r167,a). +registration_grade(r168,a). +registration_grade(r169,a). +registration_grade(r170,a). +registration_grade(r171,a). +registration_grade(r172,c). +registration_grade(r173,b). +registration_grade(r174,a). +registration_grade(r175,b). +registration_grade(r176,b). +registration_grade(r177,c). +registration_grade(r178,b). +registration_grade(r179,d). +registration_grade(r180,c). +registration_grade(r181,a). +registration_grade(r182,b). +registration_grade(r183,a). +registration_grade(r184,a). +registration_grade(r185,b). +registration_grade(r186,c). +registration_grade(r187,a). +registration_grade(r188,a). +registration_grade(r189,a). +registration_grade(r190,a). +registration_grade(r191,b). +registration_grade(r192,b). +registration_grade(r193,c). +registration_grade(r194,b). +registration_grade(r195,c). +registration_grade(r196,b). +registration_grade(r197,a). +registration_grade(r198,a). +registration_grade(r199,b). +registration_grade(r200,b). +registration_grade(r201,c). +registration_grade(r202,a). +registration_grade(r203,a). +registration_grade(r204,b). +registration_grade(r205,a). +registration_grade(r206,a). +registration_grade(r207,a). +registration_grade(r208,c). +registration_grade(r209,b). +registration_grade(r210,a). +registration_grade(r211,d). +registration_grade(r212,b). +registration_grade(r213,b). +registration_grade(r214,a). +registration_grade(r215,a). +registration_grade(r216,b). +registration_grade(r217,a). +registration_grade(r218,b). +registration_grade(r219,a). +registration_grade(r220,a). +registration_grade(r221,b). +registration_grade(r222,c). +registration_grade(r223,a). +registration_grade(r224,b). +registration_grade(r225,b). +registration_grade(r226,d). +registration_grade(r227,b). +registration_grade(r228,c). +registration_grade(r229,b). +registration_grade(r230,a). +registration_grade(r231,c). +registration_grade(r232,a). +registration_grade(r233,b). +registration_grade(r234,b). +registration_grade(r235,c). +registration_grade(r236,b). +registration_grade(r237,c). +registration_grade(r238,d). +registration_grade(r239,b). +registration_grade(r240,b). +registration_grade(r241,a). +registration_grade(r242,b). +registration_grade(r243,a). +registration_grade(r244,b). +registration_grade(r245,a). +registration_grade(r246,b). +registration_grade(r247,c). +registration_grade(r248,b). +registration_grade(r249,a). +registration_grade(r250,a). +registration_grade(r251,a). +registration_grade(r252,b). +registration_grade(r253,a). +registration_grade(r254,b). +registration_grade(r255,a). +registration_grade(r256,a). +registration_grade(r257,b). +registration_grade(r258,a). +registration_grade(r259,a). +registration_grade(r260,b). +registration_grade(r261,a). +registration_grade(r262,a). +registration_grade(r263,a). +registration_grade(r264,c). +registration_grade(r265,a). +registration_grade(r266,a). +registration_grade(r267,a). +registration_grade(r268,c). +registration_grade(r269,a). +registration_grade(r270,c). +registration_grade(r271,b). +registration_grade(r272,c). +registration_grade(r273,b). +registration_grade(r274,c). +registration_grade(r275,a). +registration_grade(r276,a). +registration_grade(r277,a). +registration_grade(r278,a). +registration_grade(r279,a). +registration_grade(r280,b). +registration_grade(r281,b). +registration_grade(r282,d). +registration_grade(r283,a). +registration_grade(r284,b). +registration_grade(r285,b). +registration_grade(r286,a). +registration_grade(r287,b). +registration_grade(r288,b). +registration_grade(r289,d). +registration_grade(r290,b). +registration_grade(r291,c). +registration_grade(r292,b). +registration_grade(r293,a). +registration_grade(r294,a). +registration_grade(r295,a). +registration_grade(r296,b). +registration_grade(r297,a). +registration_grade(r298,a). +registration_grade(r299,a). +registration_grade(r300,b). +registration_grade(r301,b). +registration_grade(r302,b). +registration_grade(r303,a). +registration_grade(r304,a). +registration_grade(r305,b). +registration_grade(r306,b). +registration_grade(r307,c). +registration_grade(r308,c). +registration_grade(r309,c). +registration_grade(r310,a). +registration_grade(r311,a). +registration_grade(r312,a). +registration_grade(r313,a). +registration_grade(r314,c). +registration_grade(r315,c). +registration_grade(r316,c). +registration_grade(r317,c). +registration_grade(r318,c). +registration_grade(r319,c). +registration_grade(r320,b). +registration_grade(r321,b). +registration_grade(r322,a). +registration_grade(r323,c). +registration_grade(r324,b). +registration_grade(r325,b). +registration_grade(r326,a). +registration_grade(r327,c). +registration_grade(r328,b). +registration_grade(r329,a). +registration_grade(r330,b). +registration_grade(r331,a). +registration_grade(r332,a). +registration_grade(r333,a). +registration_grade(r334,c). +registration_grade(r335,d). +registration_grade(r336,b). +registration_grade(r337,b). +registration_grade(r338,b). +registration_grade(r339,a). +registration_grade(r340,b). +registration_grade(r341,b). +registration_grade(r342,b). +registration_grade(r343,a). +registration_grade(r344,c). +registration_grade(r345,b). +registration_grade(r346,b). +registration_grade(r347,b). +registration_grade(r348,a). +registration_grade(r349,a). +registration_grade(r350,b). +registration_grade(r351,b). +registration_grade(r352,d). +registration_grade(r353,c). +registration_grade(r354,c). +registration_grade(r355,c). +registration_grade(r356,b). +registration_grade(r357,b). +registration_grade(r358,a). +registration_grade(r359,a). +registration_grade(r360,a). +registration_grade(r361,b). +registration_grade(r362,c). +registration_grade(r363,c). +registration_grade(r364,b). +registration_grade(r365,b). +registration_grade(r366,b). +registration_grade(r367,b). +registration_grade(r368,a). +registration_grade(r369,c). +registration_grade(r370,b). +registration_grade(r371,a). +registration_grade(r372,a). +registration_grade(r373,a). +registration_grade(r374,b). +registration_grade(r375,b). +registration_grade(r376,a). +registration_grade(r377,a). +registration_grade(r378,a). +registration_grade(r379,c). +registration_grade(r380,a). +registration_grade(r381,c). +registration_grade(r382,a). +registration_grade(r383,a). +registration_grade(r384,b). +registration_grade(r385,b). +registration_grade(r386,d). +registration_grade(r387,a). +registration_grade(r388,a). +registration_grade(r389,a). +registration_grade(r390,a). +registration_grade(r391,b). +registration_grade(r392,b). +registration_grade(r393,b). +registration_grade(r394,c). +registration_grade(r395,b). +registration_grade(r396,b). +registration_grade(r397,a). +registration_grade(r398,b). +registration_grade(r399,c). +registration_grade(r400,a). +registration_grade(r401,c). +registration_grade(r402,a). +registration_grade(r403,a). +registration_grade(r404,a). +registration_grade(r405,a). +registration_grade(r406,a). +registration_grade(r407,b). +registration_grade(r408,a). +registration_grade(r409,a). +registration_grade(r410,b). +registration_grade(r411,b). +registration_grade(r412,a). +registration_grade(r413,a). +registration_grade(r414,a). +registration_grade(r415,b). +registration_grade(r416,b). +registration_grade(r417,d). +registration_grade(r418,a). +registration_grade(r419,a). +registration_grade(r420,a). +registration_grade(r421,c). +registration_grade(r422,b). +registration_grade(r423,b). +registration_grade(r424,a). +registration_grade(r425,b). +registration_grade(r426,c). +registration_grade(r427,c). +registration_grade(r428,c). +registration_grade(r429,c). +registration_grade(r430,b). +registration_grade(r431,d). +registration_grade(r432,c). +registration_grade(r433,a). +registration_grade(r434,a). +registration_grade(r435,c). +registration_grade(r436,a). +registration_grade(r437,c). +registration_grade(r438,b). +registration_grade(r439,b). +registration_grade(r440,c). +registration_grade(r441,a). +registration_grade(r442,c). +registration_grade(r443,a). +registration_grade(r444,a). +registration_grade(r445,a). +registration_grade(r446,a). +registration_grade(r447,d). +registration_grade(r448,c). +registration_grade(r449,b). +registration_grade(r450,a). +registration_grade(r451,a). +registration_grade(r452,b). +registration_grade(r453,d). +registration_grade(r454,d). +registration_grade(r455,c). +registration_grade(r456,c). +registration_grade(r457,a). +registration_grade(r458,b). +registration_grade(r459,b). +registration_grade(r460,a). +registration_grade(r461,b). +registration_grade(r462,a). +registration_grade(r463,d). +registration_grade(r464,a). +registration_grade(r465,a). +registration_grade(r466,b). +registration_grade(r467,b). +registration_grade(r468,a). +registration_grade(r469,a). +registration_grade(r470,c). +registration_grade(r471,b). +registration_grade(r472,a). +registration_grade(r473,c). +registration_grade(r474,b). +registration_grade(r475,a). +registration_grade(r476,c). +registration_grade(r477,b). +registration_grade(r478,a). +registration_grade(r479,b). +registration_grade(r480,a). +registration_grade(r481,b). +registration_grade(r482,b). +registration_grade(r483,a). +registration_grade(r484,a). +registration_grade(r485,a). +registration_grade(r486,a). +registration_grade(r487,a). +registration_grade(r488,a). +registration_grade(r489,b). +registration_grade(r490,c). +registration_grade(r491,c). +registration_grade(r492,b). +registration_grade(r493,a). +registration_grade(r494,b). +registration_grade(r495,b). +registration_grade(r496,a). +registration_grade(r497,c). +registration_grade(r498,b). +registration_grade(r499,c). +registration_grade(r500,b). +registration_grade(r501,a). +registration_grade(r502,a). +registration_grade(r503,c). +registration_grade(r504,b). +registration_grade(r505,c). +registration_grade(r506,c). +registration_grade(r507,a). +registration_grade(r508,c). +registration_grade(r509,b). +registration_grade(r510,a). +registration_grade(r511,c). +registration_grade(r512,b). +registration_grade(r513,b). +registration_grade(r514,c). +registration_grade(r515,c). +registration_grade(r516,a). +registration_grade(r517,b). +registration_grade(r518,a). +registration_grade(r519,a). +registration_grade(r520,b). +registration_grade(r521,a). +registration_grade(r522,b). +registration_grade(r523,a). +registration_grade(r524,b). +registration_grade(r525,c). +registration_grade(r526,c). +registration_grade(r527,c). +registration_grade(r528,a). +registration_grade(r529,b). +registration_grade(r530,a). +registration_grade(r531,b). +registration_grade(r532,a). +registration_grade(r533,a). +registration_grade(r534,b). +registration_grade(r535,c). +registration_grade(r536,a). +registration_grade(r537,a). +registration_grade(r538,a). +registration_grade(r539,b). +registration_grade(r540,b). +registration_grade(r541,c). +registration_grade(r542,a). +registration_grade(r543,a). +registration_grade(r544,b). +registration_grade(r545,a). +registration_grade(r546,b). +registration_grade(r547,c). +registration_grade(r548,c). +registration_grade(r549,b). +registration_grade(r550,a). +registration_grade(r551,a). +registration_grade(r552,c). +registration_grade(r553,b). +registration_grade(r554,b). +registration_grade(r555,b). +registration_grade(r556,a). +registration_grade(r557,a). +registration_grade(r558,a). +registration_grade(r559,b). +registration_grade(r560,b). +registration_grade(r561,a). +registration_grade(r562,a). +registration_grade(r563,a). +registration_grade(r564,b). +registration_grade(r565,d). +registration_grade(r566,c). +registration_grade(r567,a). +registration_grade(r568,a). +registration_grade(r569,a). +registration_grade(r570,c). +registration_grade(r571,c). +registration_grade(r572,b). +registration_grade(r573,a). +registration_grade(r574,c). +registration_grade(r575,a). +registration_grade(r576,a). +registration_grade(r577,a). +registration_grade(r578,b). +registration_grade(r579,a). +registration_grade(r580,b). +registration_grade(r581,a). +registration_grade(r582,a). +registration_grade(r583,a). +registration_grade(r584,a). +registration_grade(r585,c). +registration_grade(r586,b). +registration_grade(r587,c). +registration_grade(r588,c). +registration_grade(r589,c). +registration_grade(r590,b). +registration_grade(r591,c). +registration_grade(r592,b). +registration_grade(r593,b). +registration_grade(r594,c). +registration_grade(r595,b). +registration_grade(r596,a). +registration_grade(r597,a). +registration_grade(r598,a). +registration_grade(r599,a). +registration_grade(r600,a). +registration_grade(r601,b). +registration_grade(r602,a). +registration_grade(r603,d). +registration_grade(r604,c). +registration_grade(r605,a). +registration_grade(r606,a). +registration_grade(r607,b). +registration_grade(r608,a). +registration_grade(r609,b). +registration_grade(r610,a). +registration_grade(r611,a). +registration_grade(r612,c). +registration_grade(r613,a). +registration_grade(r614,d). +registration_grade(r615,b). +registration_grade(r616,a). +registration_grade(r617,a). +registration_grade(r618,b). +registration_grade(r619,a). +registration_grade(r620,a). +registration_grade(r621,a). +registration_grade(r622,b). +registration_grade(r623,b). +registration_grade(r624,a). +registration_grade(r625,c). +registration_grade(r626,a). +registration_grade(r627,b). +registration_grade(r628,a). +registration_grade(r629,b). +registration_grade(r630,c). +registration_grade(r631,a). +registration_grade(r632,a). +registration_grade(r633,b). +registration_grade(r634,b). +registration_grade(r635,b). +registration_grade(r636,d). +registration_grade(r637,c). +registration_grade(r638,a). +registration_grade(r639,b). +registration_grade(r640,c). +registration_grade(r641,c). +registration_grade(r642,c). +registration_grade(r643,a). +registration_grade(r644,a). +registration_grade(r645,b). +registration_grade(r646,b). +registration_grade(r647,b). +registration_grade(r648,a). +registration_grade(r649,b). +registration_grade(r650,c). +registration_grade(r651,b). +registration_grade(r652,b). +registration_grade(r653,b). +registration_grade(r654,b). +registration_grade(r655,a). +registration_grade(r656,b). +registration_grade(r657,a). +registration_grade(r658,a). +registration_grade(r659,a). +registration_grade(r660,a). +registration_grade(r661,c). +registration_grade(r662,a). +registration_grade(r663,a). +registration_grade(r664,c). +registration_grade(r665,a). +registration_grade(r666,b). +registration_grade(r667,b). +registration_grade(r668,d). +registration_grade(r669,b). +registration_grade(r670,a). +registration_grade(r671,c). +registration_grade(r672,c). +registration_grade(r673,a). +registration_grade(r674,a). +registration_grade(r675,b). +registration_grade(r676,a). +registration_grade(r677,a). +registration_grade(r678,a). +registration_grade(r679,a). +registration_grade(r680,c). +registration_grade(r681,b). +registration_grade(r682,a). +registration_grade(r683,b). +registration_grade(r684,b). +registration_grade(r685,a). +registration_grade(r686,b). +registration_grade(r687,a). +registration_grade(r688,c). +registration_grade(r689,b). +registration_grade(r690,a). +registration_grade(r691,c). +registration_grade(r692,a). +registration_grade(r693,b). +registration_grade(r694,a). +registration_grade(r695,a). +registration_grade(r696,a). +registration_grade(r697,c). +registration_grade(r698,b). +registration_grade(r699,a). +registration_grade(r700,a). +registration_grade(r701,a). +registration_grade(r702,a). +registration_grade(r703,c). +registration_grade(r704,c). +registration_grade(r705,b). +registration_grade(r706,b). +registration_grade(r707,a). +registration_grade(r708,b). +registration_grade(r709,b). +registration_grade(r710,b). +registration_grade(r711,b). +registration_grade(r712,c). +registration_grade(r713,a). +registration_grade(r714,b). +registration_grade(r715,a). +registration_grade(r716,a). +registration_grade(r717,a). +registration_grade(r718,a). +registration_grade(r719,c). +registration_grade(r720,a). +registration_grade(r721,b). +registration_grade(r722,b). +registration_grade(r723,b). +registration_grade(r724,a). +registration_grade(r725,c). +registration_grade(r726,a). +registration_grade(r727,a). +registration_grade(r728,b). +registration_grade(r729,b). +registration_grade(r730,c). +registration_grade(r731,a). +registration_grade(r732,a). +registration_grade(r733,a). +registration_grade(r734,b). +registration_grade(r735,b). +registration_grade(r736,a). +registration_grade(r737,b). +registration_grade(r738,b). +registration_grade(r739,a). +registration_grade(r740,a). +registration_grade(r741,a). +registration_grade(r742,d). +registration_grade(r743,d). +registration_grade(r744,a). +registration_grade(r745,b). +registration_grade(r746,a). +registration_grade(r747,a). +registration_grade(r748,b). +registration_grade(r749,c). +registration_grade(r750,a). +registration_grade(r751,c). +registration_grade(r752,b). +registration_grade(r753,c). +registration_grade(r754,c). +registration_grade(r755,c). +registration_grade(r756,b). +registration_grade(r757,c). +registration_grade(r758,b). +registration_grade(r759,b). +registration_grade(r760,a). +registration_grade(r761,a). +registration_grade(r762,b). +registration_grade(r763,a). +registration_grade(r764,a). +registration_grade(r765,a). +registration_grade(r766,c). +registration_grade(r767,c). +registration_grade(r768,c). +registration_grade(r769,c). +registration_grade(r770,b). +registration_grade(r771,b). +registration_grade(r772,a). +registration_grade(r773,b). +registration_grade(r774,b). +registration_grade(r775,a). +registration_grade(r776,a). +registration_grade(r777,c). +registration_grade(r778,c). +registration_grade(r779,b). +registration_grade(r780,a). +registration_grade(r781,b). +registration_grade(r782,a). +registration_grade(r783,c). +registration_grade(r784,c). +registration_grade(r785,c). +registration_grade(r786,c). +registration_grade(r787,a). +registration_grade(r788,a). +registration_grade(r789,c). +registration_grade(r790,b). +registration_grade(r791,b). +registration_grade(r792,a). +registration_grade(r793,a). +registration_grade(r794,b). +registration_grade(r795,a). +registration_grade(r796,a). +registration_grade(r797,a). +registration_grade(r798,b). +registration_grade(r799,c). +registration_grade(r800,b). +registration_grade(r801,b). +registration_grade(r802,a). +registration_grade(r803,b). +registration_grade(r804,a). +registration_grade(r805,b). +registration_grade(r806,a). +registration_grade(r807,a). +registration_grade(r808,b). +registration_grade(r809,c). +registration_grade(r810,b). +registration_grade(r811,d). +registration_grade(r812,c). +registration_grade(r813,c). +registration_grade(r814,c). +registration_grade(r815,c). +registration_grade(r816,b). +registration_grade(r817,a). +registration_grade(r818,b). +registration_grade(r819,b). +registration_grade(r820,d). +registration_grade(r821,b). +registration_grade(r822,a). +registration_grade(r823,a). +registration_grade(r824,c). +registration_grade(r825,b). +registration_grade(r826,b). +registration_grade(r827,c). +registration_grade(r828,b). +registration_grade(r829,b). +registration_grade(r830,a). +registration_grade(r831,a). +registration_grade(r832,b). +registration_grade(r833,b). +registration_grade(r834,b). +registration_grade(r835,a). +registration_grade(r836,a). +registration_grade(r837,c). +registration_grade(r838,c). +registration_grade(r839,b). +registration_grade(r840,b). +registration_grade(r841,a). +registration_grade(r842,a). +registration_grade(r843,b). +registration_grade(r844,a). +registration_grade(r845,c). +registration_grade(r846,b). +registration_grade(r847,b). +registration_grade(r848,c). +registration_grade(r849,b). +registration_grade(r850,b). +registration_grade(r851,b). +registration_grade(r852,c). +registration_grade(r853,b). +registration_grade(r854,c). +registration_grade(r855,d). +registration_grade(r856,c). + +registration_satisfaction(r0,h). +registration_satisfaction(r1,l). +registration_satisfaction(r2,h). +registration_satisfaction(r3,m). +registration_satisfaction(r4,h). +registration_satisfaction(r5,h). +registration_satisfaction(r6,h). +registration_satisfaction(r7,h). +registration_satisfaction(r8,l). +registration_satisfaction(r9,h). +registration_satisfaction(r10,h). +registration_satisfaction(r11,h). +registration_satisfaction(r12,h). +registration_satisfaction(r13,h). +registration_satisfaction(r14,m). +registration_satisfaction(r15,h). +registration_satisfaction(r16,h). +registration_satisfaction(r17,l). +registration_satisfaction(r18,l). +registration_satisfaction(r19,m). +registration_satisfaction(r20,h). +registration_satisfaction(r21,h). +registration_satisfaction(r22,h). +registration_satisfaction(r23,m). +registration_satisfaction(r24,h). +registration_satisfaction(r25,h). +registration_satisfaction(r26,h). +registration_satisfaction(r27,h). +registration_satisfaction(r28,h). +registration_satisfaction(r29,h). +registration_satisfaction(r30,l). +registration_satisfaction(r31,h). +registration_satisfaction(r32,m). +registration_satisfaction(r33,h). +registration_satisfaction(r34,h). +registration_satisfaction(r35,h). +registration_satisfaction(r36,m). +registration_satisfaction(r37,h). +registration_satisfaction(r38,h). +registration_satisfaction(r39,h). +registration_satisfaction(r40,h). +registration_satisfaction(r41,h). +registration_satisfaction(r42,l). +registration_satisfaction(r43,h). +registration_satisfaction(r44,h). +registration_satisfaction(r45,h). +registration_satisfaction(r46,m). +registration_satisfaction(r47,h). +registration_satisfaction(r48,h). +registration_satisfaction(r49,h). +registration_satisfaction(r50,h). +registration_satisfaction(r51,h). +registration_satisfaction(r52,h). +registration_satisfaction(r53,h). +registration_satisfaction(r54,h). +registration_satisfaction(r55,h). +registration_satisfaction(r56,l). +registration_satisfaction(r57,h). +registration_satisfaction(r58,h). +registration_satisfaction(r59,l). +registration_satisfaction(r60,h). +registration_satisfaction(r61,h). +registration_satisfaction(r62,h). +registration_satisfaction(r63,h). +registration_satisfaction(r64,h). +registration_satisfaction(r65,h). +registration_satisfaction(r66,h). +registration_satisfaction(r67,m). +registration_satisfaction(r68,h). +registration_satisfaction(r69,m). +registration_satisfaction(r70,h). +registration_satisfaction(r71,h). +registration_satisfaction(r72,l). +registration_satisfaction(r73,h). +registration_satisfaction(r74,h). +registration_satisfaction(r75,h). +registration_satisfaction(r76,h). +registration_satisfaction(r77,h). +registration_satisfaction(r78,m). +registration_satisfaction(r79,h). +registration_satisfaction(r80,h). +registration_satisfaction(r81,h). +registration_satisfaction(r82,l). +registration_satisfaction(r83,m). +registration_satisfaction(r84,m). +registration_satisfaction(r85,h). +registration_satisfaction(r86,m). +registration_satisfaction(r87,m). +registration_satisfaction(r88,h). +registration_satisfaction(r89,h). +registration_satisfaction(r90,m). +registration_satisfaction(r91,h). +registration_satisfaction(r92,l). +registration_satisfaction(r93,h). +registration_satisfaction(r94,l). +registration_satisfaction(r95,h). +registration_satisfaction(r96,h). +registration_satisfaction(r97,h). +registration_satisfaction(r98,h). +registration_satisfaction(r99,h). +registration_satisfaction(r100,h). +registration_satisfaction(r101,h). +registration_satisfaction(r102,h). +registration_satisfaction(r103,h). +registration_satisfaction(r104,h). +registration_satisfaction(r105,l). +registration_satisfaction(r106,h). +registration_satisfaction(r107,l). +registration_satisfaction(r108,l). +registration_satisfaction(r109,h). +registration_satisfaction(r110,h). +registration_satisfaction(r111,h). +registration_satisfaction(r112,h). +registration_satisfaction(r113,h). +registration_satisfaction(r114,m). +registration_satisfaction(r115,l). +registration_satisfaction(r116,h). +registration_satisfaction(r117,h). +registration_satisfaction(r118,h). +registration_satisfaction(r119,h). +registration_satisfaction(r120,l). +registration_satisfaction(r121,h). +registration_satisfaction(r122,h). +registration_satisfaction(r123,l). +registration_satisfaction(r124,h). +registration_satisfaction(r125,m). +registration_satisfaction(r126,h). +registration_satisfaction(r127,h). +registration_satisfaction(r128,h). +registration_satisfaction(r129,h). +registration_satisfaction(r130,h). +registration_satisfaction(r131,h). +registration_satisfaction(r132,m). +registration_satisfaction(r133,h). +registration_satisfaction(r134,m). +registration_satisfaction(r135,h). +registration_satisfaction(r136,h). +registration_satisfaction(r137,h). +registration_satisfaction(r138,h). +registration_satisfaction(r139,h). +registration_satisfaction(r140,h). +registration_satisfaction(r141,l). +registration_satisfaction(r142,h). +registration_satisfaction(r143,h). +registration_satisfaction(r144,h). +registration_satisfaction(r145,l). +registration_satisfaction(r146,h). +registration_satisfaction(r147,l). +registration_satisfaction(r148,m). +registration_satisfaction(r149,h). +registration_satisfaction(r150,h). +registration_satisfaction(r151,h). +registration_satisfaction(r152,h). +registration_satisfaction(r153,h). +registration_satisfaction(r154,m). +registration_satisfaction(r155,m). +registration_satisfaction(r156,h). +registration_satisfaction(r157,m). +registration_satisfaction(r158,l). +registration_satisfaction(r159,m). +registration_satisfaction(r160,h). +registration_satisfaction(r161,h). +registration_satisfaction(r162,m). +registration_satisfaction(r163,h). +registration_satisfaction(r164,m). +registration_satisfaction(r165,m). +registration_satisfaction(r166,l). +registration_satisfaction(r167,h). +registration_satisfaction(r168,h). +registration_satisfaction(r169,h). +registration_satisfaction(r170,h). +registration_satisfaction(r171,h). +registration_satisfaction(r172,h). +registration_satisfaction(r173,h). +registration_satisfaction(r174,h). +registration_satisfaction(r175,h). +registration_satisfaction(r176,h). +registration_satisfaction(r177,h). +registration_satisfaction(r178,h). +registration_satisfaction(r179,l). +registration_satisfaction(r180,h). +registration_satisfaction(r181,m). +registration_satisfaction(r182,h). +registration_satisfaction(r183,l). +registration_satisfaction(r184,h). +registration_satisfaction(r185,h). +registration_satisfaction(r186,h). +registration_satisfaction(r187,h). +registration_satisfaction(r188,m). +registration_satisfaction(r189,h). +registration_satisfaction(r190,h). +registration_satisfaction(r191,h). +registration_satisfaction(r192,m). +registration_satisfaction(r193,h). +registration_satisfaction(r194,h). +registration_satisfaction(r195,h). +registration_satisfaction(r196,h). +registration_satisfaction(r197,h). +registration_satisfaction(r198,h). +registration_satisfaction(r199,h). +registration_satisfaction(r200,m). +registration_satisfaction(r201,h). +registration_satisfaction(r202,h). +registration_satisfaction(r203,h). +registration_satisfaction(r204,h). +registration_satisfaction(r205,h). +registration_satisfaction(r206,h). +registration_satisfaction(r207,h). +registration_satisfaction(r208,h). +registration_satisfaction(r209,h). +registration_satisfaction(r210,h). +registration_satisfaction(r211,m). +registration_satisfaction(r212,h). +registration_satisfaction(r213,h). +registration_satisfaction(r214,h). +registration_satisfaction(r215,h). +registration_satisfaction(r216,h). +registration_satisfaction(r217,h). +registration_satisfaction(r218,m). +registration_satisfaction(r219,h). +registration_satisfaction(r220,h). +registration_satisfaction(r221,m). +registration_satisfaction(r222,l). +registration_satisfaction(r223,h). +registration_satisfaction(r224,h). +registration_satisfaction(r225,l). +registration_satisfaction(r226,l). +registration_satisfaction(r227,h). +registration_satisfaction(r228,l). +registration_satisfaction(r229,l). +registration_satisfaction(r230,h). +registration_satisfaction(r231,l). +registration_satisfaction(r232,h). +registration_satisfaction(r233,m). +registration_satisfaction(r234,l). +registration_satisfaction(r235,h). +registration_satisfaction(r236,l). +registration_satisfaction(r237,m). +registration_satisfaction(r238,m). +registration_satisfaction(r239,m). +registration_satisfaction(r240,h). +registration_satisfaction(r241,h). +registration_satisfaction(r242,m). +registration_satisfaction(r243,h). +registration_satisfaction(r244,m). +registration_satisfaction(r245,h). +registration_satisfaction(r246,h). +registration_satisfaction(r247,l). +registration_satisfaction(r248,l). +registration_satisfaction(r249,h). +registration_satisfaction(r250,h). +registration_satisfaction(r251,h). +registration_satisfaction(r252,h). +registration_satisfaction(r253,h). +registration_satisfaction(r254,h). +registration_satisfaction(r255,h). +registration_satisfaction(r256,h). +registration_satisfaction(r257,m). +registration_satisfaction(r258,h). +registration_satisfaction(r259,h). +registration_satisfaction(r260,h). +registration_satisfaction(r261,h). +registration_satisfaction(r262,h). +registration_satisfaction(r263,m). +registration_satisfaction(r264,h). +registration_satisfaction(r265,h). +registration_satisfaction(r266,l). +registration_satisfaction(r267,h). +registration_satisfaction(r268,l). +registration_satisfaction(r269,h). +registration_satisfaction(r270,l). +registration_satisfaction(r271,h). +registration_satisfaction(r272,l). +registration_satisfaction(r273,h). +registration_satisfaction(r274,h). +registration_satisfaction(r275,h). +registration_satisfaction(r276,h). +registration_satisfaction(r277,h). +registration_satisfaction(r278,h). +registration_satisfaction(r279,h). +registration_satisfaction(r280,h). +registration_satisfaction(r281,m). +registration_satisfaction(r282,h). +registration_satisfaction(r283,h). +registration_satisfaction(r284,m). +registration_satisfaction(r285,m). +registration_satisfaction(r286,h). +registration_satisfaction(r287,h). +registration_satisfaction(r288,h). +registration_satisfaction(r289,l). +registration_satisfaction(r290,m). +registration_satisfaction(r291,h). +registration_satisfaction(r292,m). +registration_satisfaction(r293,h). +registration_satisfaction(r294,h). +registration_satisfaction(r295,m). +registration_satisfaction(r296,l). +registration_satisfaction(r297,h). +registration_satisfaction(r298,h). +registration_satisfaction(r299,h). +registration_satisfaction(r300,l). +registration_satisfaction(r301,h). +registration_satisfaction(r302,m). +registration_satisfaction(r303,h). +registration_satisfaction(r304,h). +registration_satisfaction(r305,l). +registration_satisfaction(r306,h). +registration_satisfaction(r307,l). +registration_satisfaction(r308,l). +registration_satisfaction(r309,m). +registration_satisfaction(r310,h). +registration_satisfaction(r311,l). +registration_satisfaction(r312,h). +registration_satisfaction(r313,h). +registration_satisfaction(r314,h). +registration_satisfaction(r315,h). +registration_satisfaction(r316,l). +registration_satisfaction(r317,l). +registration_satisfaction(r318,h). +registration_satisfaction(r319,m). +registration_satisfaction(r320,h). +registration_satisfaction(r321,l). +registration_satisfaction(r322,h). +registration_satisfaction(r323,l). +registration_satisfaction(r324,h). +registration_satisfaction(r325,h). +registration_satisfaction(r326,h). +registration_satisfaction(r327,m). +registration_satisfaction(r328,h). +registration_satisfaction(r329,h). +registration_satisfaction(r330,l). +registration_satisfaction(r331,h). +registration_satisfaction(r332,l). +registration_satisfaction(r333,h). +registration_satisfaction(r334,h). +registration_satisfaction(r335,h). +registration_satisfaction(r336,m). +registration_satisfaction(r337,h). +registration_satisfaction(r338,h). +registration_satisfaction(r339,h). +registration_satisfaction(r340,h). +registration_satisfaction(r341,l). +registration_satisfaction(r342,h). +registration_satisfaction(r343,h). +registration_satisfaction(r344,h). +registration_satisfaction(r345,m). +registration_satisfaction(r346,h). +registration_satisfaction(r347,m). +registration_satisfaction(r348,m). +registration_satisfaction(r349,h). +registration_satisfaction(r350,m). +registration_satisfaction(r351,h). +registration_satisfaction(r352,l). +registration_satisfaction(r353,h). +registration_satisfaction(r354,h). +registration_satisfaction(r355,h). +registration_satisfaction(r356,m). +registration_satisfaction(r357,m). +registration_satisfaction(r358,h). +registration_satisfaction(r359,l). +registration_satisfaction(r360,h). +registration_satisfaction(r361,m). +registration_satisfaction(r362,h). +registration_satisfaction(r363,l). +registration_satisfaction(r364,h). +registration_satisfaction(r365,m). +registration_satisfaction(r366,h). +registration_satisfaction(r367,h). +registration_satisfaction(r368,h). +registration_satisfaction(r369,h). +registration_satisfaction(r370,h). +registration_satisfaction(r371,h). +registration_satisfaction(r372,h). +registration_satisfaction(r373,h). +registration_satisfaction(r374,l). +registration_satisfaction(r375,h). +registration_satisfaction(r376,m). +registration_satisfaction(r377,h). +registration_satisfaction(r378,h). +registration_satisfaction(r379,h). +registration_satisfaction(r380,h). +registration_satisfaction(r381,m). +registration_satisfaction(r382,h). +registration_satisfaction(r383,h). +registration_satisfaction(r384,m). +registration_satisfaction(r385,m). +registration_satisfaction(r386,l). +registration_satisfaction(r387,h). +registration_satisfaction(r388,h). +registration_satisfaction(r389,h). +registration_satisfaction(r390,h). +registration_satisfaction(r391,l). +registration_satisfaction(r392,h). +registration_satisfaction(r393,h). +registration_satisfaction(r394,h). +registration_satisfaction(r395,h). +registration_satisfaction(r396,h). +registration_satisfaction(r397,h). +registration_satisfaction(r398,l). +registration_satisfaction(r399,h). +registration_satisfaction(r400,h). +registration_satisfaction(r401,l). +registration_satisfaction(r402,h). +registration_satisfaction(r403,h). +registration_satisfaction(r404,h). +registration_satisfaction(r405,h). +registration_satisfaction(r406,h). +registration_satisfaction(r407,h). +registration_satisfaction(r408,h). +registration_satisfaction(r409,h). +registration_satisfaction(r410,h). +registration_satisfaction(r411,l). +registration_satisfaction(r412,h). +registration_satisfaction(r413,l). +registration_satisfaction(r414,h). +registration_satisfaction(r415,m). +registration_satisfaction(r416,h). +registration_satisfaction(r417,h). +registration_satisfaction(r418,h). +registration_satisfaction(r419,h). +registration_satisfaction(r420,h). +registration_satisfaction(r421,h). +registration_satisfaction(r422,m). +registration_satisfaction(r423,h). +registration_satisfaction(r424,h). +registration_satisfaction(r425,h). +registration_satisfaction(r426,l). +registration_satisfaction(r427,h). +registration_satisfaction(r428,h). +registration_satisfaction(r429,h). +registration_satisfaction(r430,l). +registration_satisfaction(r431,m). +registration_satisfaction(r432,h). +registration_satisfaction(r433,h). +registration_satisfaction(r434,h). +registration_satisfaction(r435,m). +registration_satisfaction(r436,h). +registration_satisfaction(r437,h). +registration_satisfaction(r438,l). +registration_satisfaction(r439,h). +registration_satisfaction(r440,h). +registration_satisfaction(r441,h). +registration_satisfaction(r442,m). +registration_satisfaction(r443,h). +registration_satisfaction(r444,h). +registration_satisfaction(r445,h). +registration_satisfaction(r446,h). +registration_satisfaction(r447,m). +registration_satisfaction(r448,l). +registration_satisfaction(r449,h). +registration_satisfaction(r450,h). +registration_satisfaction(r451,h). +registration_satisfaction(r452,h). +registration_satisfaction(r453,h). +registration_satisfaction(r454,l). +registration_satisfaction(r455,m). +registration_satisfaction(r456,h). +registration_satisfaction(r457,h). +registration_satisfaction(r458,m). +registration_satisfaction(r459,m). +registration_satisfaction(r460,l). +registration_satisfaction(r461,h). +registration_satisfaction(r462,h). +registration_satisfaction(r463,l). +registration_satisfaction(r464,h). +registration_satisfaction(r465,h). +registration_satisfaction(r466,l). +registration_satisfaction(r467,h). +registration_satisfaction(r468,h). +registration_satisfaction(r469,h). +registration_satisfaction(r470,h). +registration_satisfaction(r471,h). +registration_satisfaction(r472,h). +registration_satisfaction(r473,l). +registration_satisfaction(r474,m). +registration_satisfaction(r475,h). +registration_satisfaction(r476,l). +registration_satisfaction(r477,m). +registration_satisfaction(r478,h). +registration_satisfaction(r479,l). +registration_satisfaction(r480,h). +registration_satisfaction(r481,m). +registration_satisfaction(r482,h). +registration_satisfaction(r483,h). +registration_satisfaction(r484,m). +registration_satisfaction(r485,h). +registration_satisfaction(r486,h). +registration_satisfaction(r487,h). +registration_satisfaction(r488,l). +registration_satisfaction(r489,m). +registration_satisfaction(r490,m). +registration_satisfaction(r491,l). +registration_satisfaction(r492,h). +registration_satisfaction(r493,h). +registration_satisfaction(r494,m). +registration_satisfaction(r495,h). +registration_satisfaction(r496,h). +registration_satisfaction(r497,h). +registration_satisfaction(r498,l). +registration_satisfaction(r499,h). +registration_satisfaction(r500,m). +registration_satisfaction(r501,h). +registration_satisfaction(r502,h). +registration_satisfaction(r503,l). +registration_satisfaction(r504,m). +registration_satisfaction(r505,h). +registration_satisfaction(r506,h). +registration_satisfaction(r507,h). +registration_satisfaction(r508,l). +registration_satisfaction(r509,m). +registration_satisfaction(r510,h). +registration_satisfaction(r511,l). +registration_satisfaction(r512,h). +registration_satisfaction(r513,h). +registration_satisfaction(r514,h). +registration_satisfaction(r515,l). +registration_satisfaction(r516,h). +registration_satisfaction(r517,m). +registration_satisfaction(r518,h). +registration_satisfaction(r519,h). +registration_satisfaction(r520,h). +registration_satisfaction(r521,h). +registration_satisfaction(r522,h). +registration_satisfaction(r523,h). +registration_satisfaction(r524,h). +registration_satisfaction(r525,l). +registration_satisfaction(r526,h). +registration_satisfaction(r527,l). +registration_satisfaction(r528,h). +registration_satisfaction(r529,h). +registration_satisfaction(r530,h). +registration_satisfaction(r531,m). +registration_satisfaction(r532,h). +registration_satisfaction(r533,h). +registration_satisfaction(r534,l). +registration_satisfaction(r535,m). +registration_satisfaction(r536,h). +registration_satisfaction(r537,h). +registration_satisfaction(r538,h). +registration_satisfaction(r539,h). +registration_satisfaction(r540,m). +registration_satisfaction(r541,h). +registration_satisfaction(r542,h). +registration_satisfaction(r543,h). +registration_satisfaction(r544,h). +registration_satisfaction(r545,h). +registration_satisfaction(r546,h). +registration_satisfaction(r547,l). +registration_satisfaction(r548,h). +registration_satisfaction(r549,h). +registration_satisfaction(r550,h). +registration_satisfaction(r551,h). +registration_satisfaction(r552,m). +registration_satisfaction(r553,m). +registration_satisfaction(r554,l). +registration_satisfaction(r555,m). +registration_satisfaction(r556,h). +registration_satisfaction(r557,h). +registration_satisfaction(r558,h). +registration_satisfaction(r559,h). +registration_satisfaction(r560,h). +registration_satisfaction(r561,h). +registration_satisfaction(r562,h). +registration_satisfaction(r563,m). +registration_satisfaction(r564,h). +registration_satisfaction(r565,l). +registration_satisfaction(r566,l). +registration_satisfaction(r567,h). +registration_satisfaction(r568,h). +registration_satisfaction(r569,h). +registration_satisfaction(r570,h). +registration_satisfaction(r571,l). +registration_satisfaction(r572,m). +registration_satisfaction(r573,h). +registration_satisfaction(r574,m). +registration_satisfaction(r575,h). +registration_satisfaction(r576,h). +registration_satisfaction(r577,h). +registration_satisfaction(r578,l). +registration_satisfaction(r579,h). +registration_satisfaction(r580,m). +registration_satisfaction(r581,h). +registration_satisfaction(r582,h). +registration_satisfaction(r583,h). +registration_satisfaction(r584,h). +registration_satisfaction(r585,h). +registration_satisfaction(r586,m). +registration_satisfaction(r587,m). +registration_satisfaction(r588,l). +registration_satisfaction(r589,l). +registration_satisfaction(r590,h). +registration_satisfaction(r591,h). +registration_satisfaction(r592,h). +registration_satisfaction(r593,h). +registration_satisfaction(r594,l). +registration_satisfaction(r595,m). +registration_satisfaction(r596,h). +registration_satisfaction(r597,h). +registration_satisfaction(r598,h). +registration_satisfaction(r599,h). +registration_satisfaction(r600,m). +registration_satisfaction(r601,m). +registration_satisfaction(r602,h). +registration_satisfaction(r603,h). +registration_satisfaction(r604,l). +registration_satisfaction(r605,h). +registration_satisfaction(r606,h). +registration_satisfaction(r607,l). +registration_satisfaction(r608,h). +registration_satisfaction(r609,h). +registration_satisfaction(r610,h). +registration_satisfaction(r611,h). +registration_satisfaction(r612,l). +registration_satisfaction(r613,h). +registration_satisfaction(r614,m). +registration_satisfaction(r615,l). +registration_satisfaction(r616,h). +registration_satisfaction(r617,h). +registration_satisfaction(r618,h). +registration_satisfaction(r619,h). +registration_satisfaction(r620,h). +registration_satisfaction(r621,h). +registration_satisfaction(r622,h). +registration_satisfaction(r623,l). +registration_satisfaction(r624,m). +registration_satisfaction(r625,l). +registration_satisfaction(r626,h). +registration_satisfaction(r627,h). +registration_satisfaction(r628,h). +registration_satisfaction(r629,h). +registration_satisfaction(r630,h). +registration_satisfaction(r631,h). +registration_satisfaction(r632,h). +registration_satisfaction(r633,h). +registration_satisfaction(r634,h). +registration_satisfaction(r635,m). +registration_satisfaction(r636,l). +registration_satisfaction(r637,m). +registration_satisfaction(r638,h). +registration_satisfaction(r639,h). +registration_satisfaction(r640,h). +registration_satisfaction(r641,h). +registration_satisfaction(r642,h). +registration_satisfaction(r643,h). +registration_satisfaction(r644,h). +registration_satisfaction(r645,h). +registration_satisfaction(r646,h). +registration_satisfaction(r647,h). +registration_satisfaction(r648,h). +registration_satisfaction(r649,h). +registration_satisfaction(r650,h). +registration_satisfaction(r651,h). +registration_satisfaction(r652,m). +registration_satisfaction(r653,l). +registration_satisfaction(r654,h). +registration_satisfaction(r655,h). +registration_satisfaction(r656,m). +registration_satisfaction(r657,h). +registration_satisfaction(r658,h). +registration_satisfaction(r659,h). +registration_satisfaction(r660,h). +registration_satisfaction(r661,h). +registration_satisfaction(r662,h). +registration_satisfaction(r663,h). +registration_satisfaction(r664,l). +registration_satisfaction(r665,h). +registration_satisfaction(r666,l). +registration_satisfaction(r667,h). +registration_satisfaction(r668,l). +registration_satisfaction(r669,h). +registration_satisfaction(r670,h). +registration_satisfaction(r671,h). +registration_satisfaction(r672,l). +registration_satisfaction(r673,l). +registration_satisfaction(r674,h). +registration_satisfaction(r675,l). +registration_satisfaction(r676,h). +registration_satisfaction(r677,h). +registration_satisfaction(r678,h). +registration_satisfaction(r679,h). +registration_satisfaction(r680,m). +registration_satisfaction(r681,h). +registration_satisfaction(r682,h). +registration_satisfaction(r683,h). +registration_satisfaction(r684,m). +registration_satisfaction(r685,h). +registration_satisfaction(r686,h). +registration_satisfaction(r687,l). +registration_satisfaction(r688,h). +registration_satisfaction(r689,m). +registration_satisfaction(r690,h). +registration_satisfaction(r691,h). +registration_satisfaction(r692,h). +registration_satisfaction(r693,h). +registration_satisfaction(r694,h). +registration_satisfaction(r695,h). +registration_satisfaction(r696,h). +registration_satisfaction(r697,m). +registration_satisfaction(r698,h). +registration_satisfaction(r699,h). +registration_satisfaction(r700,h). +registration_satisfaction(r701,h). +registration_satisfaction(r702,h). +registration_satisfaction(r703,l). +registration_satisfaction(r704,l). +registration_satisfaction(r705,l). +registration_satisfaction(r706,m). +registration_satisfaction(r707,h). +registration_satisfaction(r708,l). +registration_satisfaction(r709,m). +registration_satisfaction(r710,l). +registration_satisfaction(r711,h). +registration_satisfaction(r712,h). +registration_satisfaction(r713,h). +registration_satisfaction(r714,m). +registration_satisfaction(r715,h). +registration_satisfaction(r716,h). +registration_satisfaction(r717,h). +registration_satisfaction(r718,l). +registration_satisfaction(r719,l). +registration_satisfaction(r720,h). +registration_satisfaction(r721,h). +registration_satisfaction(r722,h). +registration_satisfaction(r723,h). +registration_satisfaction(r724,h). +registration_satisfaction(r725,h). +registration_satisfaction(r726,h). +registration_satisfaction(r727,h). +registration_satisfaction(r728,m). +registration_satisfaction(r729,h). +registration_satisfaction(r730,h). +registration_satisfaction(r731,h). +registration_satisfaction(r732,h). +registration_satisfaction(r733,h). +registration_satisfaction(r734,h). +registration_satisfaction(r735,h). +registration_satisfaction(r736,h). +registration_satisfaction(r737,h). +registration_satisfaction(r738,h). +registration_satisfaction(r739,h). +registration_satisfaction(r740,h). +registration_satisfaction(r741,h). +registration_satisfaction(r742,h). +registration_satisfaction(r743,h). +registration_satisfaction(r744,h). +registration_satisfaction(r745,m). +registration_satisfaction(r746,h). +registration_satisfaction(r747,h). +registration_satisfaction(r748,h). +registration_satisfaction(r749,m). +registration_satisfaction(r750,h). +registration_satisfaction(r751,h). +registration_satisfaction(r752,m). +registration_satisfaction(r753,m). +registration_satisfaction(r754,h). +registration_satisfaction(r755,l). +registration_satisfaction(r756,h). +registration_satisfaction(r757,h). +registration_satisfaction(r758,h). +registration_satisfaction(r759,l). +registration_satisfaction(r760,h). +registration_satisfaction(r761,h). +registration_satisfaction(r762,m). +registration_satisfaction(r763,h). +registration_satisfaction(r764,h). +registration_satisfaction(r765,h). +registration_satisfaction(r766,h). +registration_satisfaction(r767,h). +registration_satisfaction(r768,l). +registration_satisfaction(r769,l). +registration_satisfaction(r770,m). +registration_satisfaction(r771,m). +registration_satisfaction(r772,h). +registration_satisfaction(r773,m). +registration_satisfaction(r774,h). +registration_satisfaction(r775,h). +registration_satisfaction(r776,h). +registration_satisfaction(r777,l). +registration_satisfaction(r778,h). +registration_satisfaction(r779,h). +registration_satisfaction(r780,h). +registration_satisfaction(r781,m). +registration_satisfaction(r782,m). +registration_satisfaction(r783,m). +registration_satisfaction(r784,l). +registration_satisfaction(r785,l). +registration_satisfaction(r786,h). +registration_satisfaction(r787,h). +registration_satisfaction(r788,h). +registration_satisfaction(r789,h). +registration_satisfaction(r790,h). +registration_satisfaction(r791,h). +registration_satisfaction(r792,h). +registration_satisfaction(r793,m). +registration_satisfaction(r794,l). +registration_satisfaction(r795,h). +registration_satisfaction(r796,h). +registration_satisfaction(r797,h). +registration_satisfaction(r798,m). +registration_satisfaction(r799,m). +registration_satisfaction(r800,m). +registration_satisfaction(r801,h). +registration_satisfaction(r802,h). +registration_satisfaction(r803,h). +registration_satisfaction(r804,h). +registration_satisfaction(r805,h). +registration_satisfaction(r806,h). +registration_satisfaction(r807,l). +registration_satisfaction(r808,m). +registration_satisfaction(r809,l). +registration_satisfaction(r810,h). +registration_satisfaction(r811,l). +registration_satisfaction(r812,h). +registration_satisfaction(r813,m). +registration_satisfaction(r814,l). +registration_satisfaction(r815,h). +registration_satisfaction(r816,h). +registration_satisfaction(r817,h). +registration_satisfaction(r818,l). +registration_satisfaction(r819,h). +registration_satisfaction(r820,h). +registration_satisfaction(r821,m). +registration_satisfaction(r822,m). +registration_satisfaction(r823,h). +registration_satisfaction(r824,m). +registration_satisfaction(r825,l). +registration_satisfaction(r826,l). +registration_satisfaction(r827,l). +registration_satisfaction(r828,m). +registration_satisfaction(r829,l). +registration_satisfaction(r830,h). +registration_satisfaction(r831,h). +registration_satisfaction(r832,m). +registration_satisfaction(r833,h). +registration_satisfaction(r834,h). +registration_satisfaction(r835,h). +registration_satisfaction(r836,h). +registration_satisfaction(r837,h). +registration_satisfaction(r838,l). +registration_satisfaction(r839,m). +registration_satisfaction(r840,m). +registration_satisfaction(r841,h). +registration_satisfaction(r842,h). +registration_satisfaction(r843,h). +registration_satisfaction(r844,h). +registration_satisfaction(r845,l). +registration_satisfaction(r846,l). +registration_satisfaction(r847,h). +registration_satisfaction(r848,l). +registration_satisfaction(r849,h). +registration_satisfaction(r850,h). +registration_satisfaction(r851,h). +registration_satisfaction(r852,h). +registration_satisfaction(r853,h). +registration_satisfaction(r854,m). +registration_satisfaction(r855,h). +registration_satisfaction(r856,l). + + +course_rating(c0,m). +course_rating(c1,l). +course_rating(c2,m). +course_rating(c3,h). +course_rating(c4,h). +course_rating(c5,m). +course_rating(c6,h). +course_rating(c7,h). +course_rating(c8,m). +course_rating(c9,m). +course_rating(c10,m). +course_rating(c11,h). +course_rating(c12,m). +course_rating(c13,h). +course_rating(c14,h). +course_rating(c15,m). +course_rating(c16,h). +course_rating(c17,m). +course_rating(c18,h). +course_rating(c19,h). +course_rating(c20,h). +course_rating(c21,m). +course_rating(c22,h). +course_rating(c23,h). +course_rating(c24,m). +course_rating(c25,h). +course_rating(c26,m). +course_rating(c27,h). +course_rating(c28,m). +course_rating(c29,m). +course_rating(c30,h). +course_rating(c31,h). +course_rating(c32,h). +course_rating(c33,m). +course_rating(c34,h). +course_rating(c35,m). +course_rating(c36,h). +course_rating(c37,m). +course_rating(c38,m). +course_rating(c39,h). +course_rating(c40,m). +course_rating(c41,m). +course_rating(c42,h). +course_rating(c43,h). +course_rating(c44,h). +course_rating(c45,h). +course_rating(c46,l). +course_rating(c47,h). +course_rating(c48,h). +course_rating(c49,m). +course_rating(c50,l). +course_rating(c51,m). +course_rating(c52,h). +course_rating(c53,l). +course_rating(c54,h). +course_rating(c55,h). +course_rating(c56,h). +course_rating(c57,h). +course_rating(c58,l). +course_rating(c59,h). +course_rating(c60,h). +course_rating(c61,h). +course_rating(c62,h). +course_rating(c63,h). + + +student_ranking(s0,b). +student_ranking(s1,c). +student_ranking(s2,a). +student_ranking(s3,a). +student_ranking(s4,a). +student_ranking(s5,b). +student_ranking(s6,c). +student_ranking(s7,a). +student_ranking(s8,a). +student_ranking(s9,c). +student_ranking(s10,b). +student_ranking(s11,b). +student_ranking(s12,b). +student_ranking(s13,b). +student_ranking(s14,a). +student_ranking(s15,c). +student_ranking(s16,b). +student_ranking(s17,c). +student_ranking(s18,b). +student_ranking(s19,a). +student_ranking(s20,b). +student_ranking(s21,b). +student_ranking(s22,b). +student_ranking(s23,b). +student_ranking(s24,a). +student_ranking(s25,a). +student_ranking(s26,b). +student_ranking(s27,c). +student_ranking(s28,b). +student_ranking(s29,b). +student_ranking(s30,a). +student_ranking(s31,b). +student_ranking(s32,b). +student_ranking(s33,a). +student_ranking(s34,c). +student_ranking(s35,b). +student_ranking(s36,b). +student_ranking(s37,b). +student_ranking(s38,a). +student_ranking(s39,a). +student_ranking(s40,a). +student_ranking(s41,b). +student_ranking(s42,b). +student_ranking(s43,a). +student_ranking(s44,a). +student_ranking(s45,a). +student_ranking(s46,c). +student_ranking(s47,a). +student_ranking(s48,b). +student_ranking(s49,b). +student_ranking(s50,a). +student_ranking(s51,b). +student_ranking(s52,c). +student_ranking(s53,b). +student_ranking(s54,b). +student_ranking(s55,a). +student_ranking(s56,b). +student_ranking(s57,b). +student_ranking(s58,a). +student_ranking(s59,b). +student_ranking(s60,a). +student_ranking(s61,b). +student_ranking(s62,b). +student_ranking(s63,a). +student_ranking(s64,b). +student_ranking(s65,b). +student_ranking(s66,b). +student_ranking(s67,c). +student_ranking(s68,b). +student_ranking(s69,b). +student_ranking(s70,c). +student_ranking(s71,c). +student_ranking(s72,a). +student_ranking(s73,b). +student_ranking(s74,a). +student_ranking(s75,b). +student_ranking(s76,b). +student_ranking(s77,a). +student_ranking(s78,b). +student_ranking(s79,b). +student_ranking(s80,b). +student_ranking(s81,b). +student_ranking(s82,a). +student_ranking(s83,a). +student_ranking(s84,b). +student_ranking(s85,a). +student_ranking(s86,c). +student_ranking(s87,a). +student_ranking(s88,a). +student_ranking(s89,b). +student_ranking(s90,a). +student_ranking(s91,c). +student_ranking(s92,a). +student_ranking(s93,c). +student_ranking(s94,c). +student_ranking(s95,b). +student_ranking(s96,b). +student_ranking(s97,b). +student_ranking(s98,a). +student_ranking(s99,b). +student_ranking(s100,b). +student_ranking(s101,b). +student_ranking(s102,a). +student_ranking(s103,a). +student_ranking(s104,c). +student_ranking(s105,b). +student_ranking(s106,a). +student_ranking(s107,c). +student_ranking(s108,b). +student_ranking(s109,b). +student_ranking(s110,b). +student_ranking(s111,a). +student_ranking(s112,b). +student_ranking(s113,b). +student_ranking(s114,c). +student_ranking(s115,a). +student_ranking(s116,b). +student_ranking(s117,b). +student_ranking(s118,b). +student_ranking(s119,a). +student_ranking(s120,a). +student_ranking(s121,a). +student_ranking(s122,a). +student_ranking(s123,c). +student_ranking(s124,a). +student_ranking(s125,b). +student_ranking(s126,b). +student_ranking(s127,c). +student_ranking(s128,c). +student_ranking(s129,b). +student_ranking(s130,b). +student_ranking(s131,b). +student_ranking(s132,a). +student_ranking(s133,c). +student_ranking(s134,a). +student_ranking(s135,c). +student_ranking(s136,b). +student_ranking(s137,b). +student_ranking(s138,b). +student_ranking(s139,a). +student_ranking(s140,b). +student_ranking(s141,b). +student_ranking(s142,b). +student_ranking(s143,c). +student_ranking(s144,a). +student_ranking(s145,a). +student_ranking(s146,c). +student_ranking(s147,b). +student_ranking(s148,c). +student_ranking(s149,b). +student_ranking(s150,c). +student_ranking(s151,b). +student_ranking(s152,a). +student_ranking(s153,c). +student_ranking(s154,a). +student_ranking(s155,b). +student_ranking(s156,b). +student_ranking(s157,b). +student_ranking(s158,a). +student_ranking(s159,b). +student_ranking(s160,a). +student_ranking(s161,b). +student_ranking(s162,a). +student_ranking(s163,b). +student_ranking(s164,b). +student_ranking(s165,b). +student_ranking(s166,b). +student_ranking(s167,b). +student_ranking(s168,a). +student_ranking(s169,c). +student_ranking(s170,b). +student_ranking(s171,b). +student_ranking(s172,a). +student_ranking(s173,a). +student_ranking(s174,a). +student_ranking(s175,c). +student_ranking(s176,b). +student_ranking(s177,b). +student_ranking(s178,a). +student_ranking(s179,a). +student_ranking(s180,b). +student_ranking(s181,a). +student_ranking(s182,b). +student_ranking(s183,a). +student_ranking(s184,a). +student_ranking(s185,b). +student_ranking(s186,b). +student_ranking(s187,b). +student_ranking(s188,a). +student_ranking(s189,c). +student_ranking(s190,b). +student_ranking(s191,c). +student_ranking(s192,a). +student_ranking(s193,b). +student_ranking(s194,b). +student_ranking(s195,c). +student_ranking(s196,a). +student_ranking(s197,a). +student_ranking(s198,b). +student_ranking(s199,b). +student_ranking(s200,b). +student_ranking(s201,b). +student_ranking(s202,a). +student_ranking(s203,b). +student_ranking(s204,b). +student_ranking(s205,b). +student_ranking(s206,b). +student_ranking(s207,a). +student_ranking(s208,b). +student_ranking(s209,a). +student_ranking(s210,c). +student_ranking(s211,b). +student_ranking(s212,a). +student_ranking(s213,a). +student_ranking(s214,b). +student_ranking(s215,b). +student_ranking(s216,b). +student_ranking(s217,b). +student_ranking(s218,a). +student_ranking(s219,b). +student_ranking(s220,a). +student_ranking(s221,c). +student_ranking(s222,a). +student_ranking(s223,b). +student_ranking(s224,c). +student_ranking(s225,c). +student_ranking(s226,a). +student_ranking(s227,a). +student_ranking(s228,b). +student_ranking(s229,c). +student_ranking(s230,b). +student_ranking(s231,a). +student_ranking(s232,c). +student_ranking(s233,b). +student_ranking(s234,c). +student_ranking(s235,b). +student_ranking(s236,b). +student_ranking(s237,a). +student_ranking(s238,a). +student_ranking(s239,b). +student_ranking(s240,a). +student_ranking(s241,b). +student_ranking(s242,c). +student_ranking(s243,b). +student_ranking(s244,c). +student_ranking(s245,b). +student_ranking(s246,b). +student_ranking(s247,b). +student_ranking(s248,b). +student_ranking(s249,b). +student_ranking(s250,c). +student_ranking(s251,a). +student_ranking(s252,b). +student_ranking(s253,b). +student_ranking(s254,b). +student_ranking(s255,c). diff --git a/packages/CLPBN/learning/learn_utils.yap b/packages/CLPBN/learning/learn_utils.yap new file mode 100644 index 000000000..c5c45a368 --- /dev/null +++ b/packages/CLPBN/learning/learn_utils.yap @@ -0,0 +1,100 @@ +% +% Utilities for learning +% + +:- module(clpbn_learn_utils, [run_all/1, + clpbn_vars/2, + normalise_counts/2, + compute_likelihood/3, + soften_sample/2, + soften_sample/3]). + +:- use_module(library(clpbn), + [clpbn_flag/2]). + +:- use_module(library('clpbn/table'), + [clpbn_reset_tables/0]). + +:- use_module(library(matrix), + [matrix_agg_lines/3, + matrix_op_to_lines/4, + matrix_agg_cols/3, + matrix_op_to_cols/4, + matrix_to_logs/2, + matrix_op/4, + matrix_sum/2, + matrix_to_list/2, + matrix_op_to_all/4]). + +:- meta_predicate run_all(:). + +run_all([]). +run_all([G|Gs]) :- + call(G), + run_all(Gs). +run_all(M:Gs) :- + clpbn_reset_tables, + run_all(Gs,M). + +run_all([],_). +run_all([G|Gs],M) :- + ( call(M:G) -> true ; writeln(bad:M:G), break), + run_all(Gs,M). + +clpbn_vars(Vs,BVars) :- + get_clpbn_vars(Vs,CVs), + keysort(CVs,KVs), + merge_vars(KVs,BVars). + +get_clpbn_vars([],[]). +get_clpbn_vars([V|GVars],[K-V|CLPBNGVars]) :- + clpbn:get_atts(V, [key(K)]), !, + get_clpbn_vars(GVars,CLPBNGVars). +get_clpbn_vars([_|GVars],CLPBNGVars) :- + get_clpbn_vars(GVars,CLPBNGVars). + +merge_vars([],[]). +merge_vars([K-V|KVs],[V|BVars]) :- + get_var_has_same_key(KVs,K,V,KVs0), + merge_vars(KVs0,BVars). + +get_var_has_same_key([K-V|KVs],K,V,KVs0) :- !, + get_var_has_same_key(KVs,K,V,KVs0). +get_var_has_same_key(KVs,_,_,KVs). + +soften_sample(T0,T) :- + clpbn_flag(parameter_softening, Soften), + soften_sample(Soften, T0, T). + +soften_sample(no,T,T). +soften_sample(m_estimate(M), T0, T) :- + matrix_agg_cols(T0,+,Cols), + matrix_op_to_all(Cols, *, M, R), + matrix_op_to_cols(T0,R,+,T). +soften_sample(auto_m, T0,T) :- + matrix_agg_cols(T0,+,Cols), + matrix_sum(Cols,TotM), + M is sqrt(TotM), + matrix_op_to_all(Cols, *, M, R), + matrix_op_to_cols(T0,R,+,T). +soften_sample(laplace,T0,T) :- + matrix_op_to_all(T0, +, 1, T). + + +normalise_counts(MAT,NMAT) :- + matrix_agg_lines(MAT, +, Sum), + matrix_op_to_lines(MAT, Sum, /, NMAT). + +compute_likelihood(Table0, NewTable, DeltaLik) :- + matrix_to_logs(NewTable, Logs), + matrix_to_list(Table0,L1), + matrix_to_list(Logs,L2), + sum_prods(L1,L2,0,DeltaLik). + +sum_prods([],[],DeltaLik,DeltaLik). +sum_prods([0.0|L1],[_|L2],DeltaLik0,DeltaLik) :- !, + sum_prods(L1,L2,DeltaLik0,DeltaLik). +sum_prods([Count|L1],[Log|L2],DeltaLik0,DeltaLik) :- !, + DeltaLik1 is DeltaLik0+Count*Log, + sum_prods(L1,L2,DeltaLik1,DeltaLik). + diff --git a/packages/CLPBN/learning/mle.yap b/packages/CLPBN/learning/mle.yap new file mode 100644 index 000000000..ce6cd0132 --- /dev/null +++ b/packages/CLPBN/learning/mle.yap @@ -0,0 +1,113 @@ +% +% Maximum likelihood estimator and friends. +% +% +% This assumes we have a single big example. +% + +:- module(clpbn_mle, [learn_parameters/2, + learn_parameters/3, + parameters_from_evidence/3]). + +:- use_module(library('clpbn')). + +:- use_module(library('clpbn/learning/learn_utils'), + [run_all/1, + clpbn_vars/2, + normalise_counts/2, + soften_table/2, + normalise_counts/2]). + +:- use_module(library('clpbn/dists'), + [empty_dist/2, + dist_new_table/2]). + +:- use_module(library(matrix), + [matrix_inc/2]). + + +learn_parameters(Items, Tables) :- + learn_parameters(Items, Tables, []). + +% +% full evidence learning +% +learn_parameters(Items, Tables, Extras) :- + run_all(Items), + attributes:all_attvars(AVars), + % sort and incorporate evidence + clpbn_vars(AVars, AllVars), + mk_sample(AllVars, Sample), + compute_tables(Extras, Sample, Tables). + +parameters_from_evidence(AllVars, Sample, Extras) :- + mk_sample_from_evidence(AllVars, Sample), + compute_tables(Extras, Sample, Tables). + +mk_sample_from_evidence(AllVars, SortedSample) :- + add_evidence2sample(AllVars, Sample), + msort(Sample, SortedSample). + +mk_sample(AllVars, SortedSample) :- + add2sample(AllVars, Sample), + msort(Sample, SortedSample). + +% +% assumes we have full data, meaning evidence for every variable +% +add2sample([], []). +add2sample([V|Vs],[val(Id,[Ev|EParents])|Vals]) :- + clpbn:get_atts(V, [evidence(Ev),dist(Id,Parents)]), + get_eparents(Parents, EParents), + add2sample(Vs, Vals). + +get_eparents([P|Parents], [E|EParents]) :- + clpbn:get_atts(P, [evidence(E)]), + get_eparents(Parents, EParents). +get_eparents([], []). + + +% +% assumes we ignore variables without evidence or without evidence +% on a parent! +% +add_evidence2sample([], []). +add_evidence2sample([V|Vs],[val(Id,[Ev|EParents])|Vals]) :- + clpbn:get_atts(V, [evidence(Ev),dist(Id,Parents)]), + get_eveparents(Parents, EParents), !, + add_evidence2sample(Vs, Vals). +add_evidence2sample([_|Vs],Vals) :- + add_evidence2sample(Vs, Vals). + +get_eveparents([P|Parents], [E|EParents]) :- + clpbn:get_atts(P, [evidence(E)]), + get_eparents(Parents, EParents). +get_eveparents([], []). + + +compute_tables(Parameters, Sample, NewTables) :- + estimator(Sample, Tables), + add_priors(Parameters, Tables, NewTables). + +estimator([], []). +estimator([val(Id,Sample)|Samples], [NewDist|Tables]) :- + empty_dist(Id, NewTable), + id_samples(Id, Samples, IdSamples, MoreSamples), + mle([Sample|IdSamples], NewTable), + soften_table(NewTable, SoftenedTable), + normalise_counts(SoftenedTable, NewDist), + % replace matrix in distribution + dist_new_table(Id, NewDist), + estimator(MoreSamples, Tables). + + +id_samples(_, [], [], []). +id_samples(Id, [val(Id,Sample)|Samples], [Sample|IdSamples], MoreSamples) :- !, + id_samples(Id, Samples, IdSamples, MoreSamples). +id_samples(_, Samples, [], Samples). + +mle([Sample|IdSamples], Table) :- + matrix_inc(Table, Sample), + mle(IdSamples, Table). +mle([], _). + diff --git a/packages/MYDDAS/myddas.h b/packages/MYDDAS/myddas.h new file mode 100644 index 000000000..7487dfa8d --- /dev/null +++ b/packages/MYDDAS/myddas.h @@ -0,0 +1,159 @@ +#ifndef __MYDDAS_H__ +#define __MYDDAS_H__ + +#include "config.h" +#include + +#ifdef MYDDAS_ODBC +#include +#endif + +#ifdef MYDDAS_MYSQL +#include +#endif + +/* MYDDAS TYPES */ +/* sizeof(MyddasPointer) Equal to the size of a integer on the given architecture */ +/* sizeof(MyddasInt32) = 4 (Always) */ +/* sizeof(MyddasUInt32) = 4 (Always) */ + +#if SIZEOF_INT_P==4 + +# if SIZEOF_INT==4 +/* */ typedef int MyddasInt; +/* */ typedef unsigned int MyddasUInt; +/* */ typedef unsigned int MyddasPointer; +/* */ typedef int MyddasInt32; +/* */ typedef unsigned int MyddasUInt32; +# elif SIZEOF_LONG_INT==4 +/* */ typedef long int MyddasInt; +/* */ typedef unsigned long int MyddasUInt; +/* */ typedef unsigned long int MyddasPointer; +/* */ typedef long int MyddasInt32; +/* */ typedef unsigned long int MyddasUInt32; +# else +# error MYDDAS require integer types of the same size as a pointer +# endif + +# if SIZEOF_SHORT_INT==2 +/* */ typedef short int MyddasSInt; +/* */ typedef unsigned short int MyddasUSInt; +# else +# error MYDDAS requires integer types half the size of a pointer +# endif + +# if SIZEOF_LONG_INT==8 +/* */ typedef long int MyddasLInt; +/* */ typedef unsigned long int MyddasULInt; +# elif SIZEOF_LONG_LONG_INT==8 +/* */ typedef long long int MyddasLInt; +/* */ typedef unsigned long long int MyddasULInt; +# else +# error MYDDAS requires integer types double the size of a pointer +# endif + +#elif SIZEOF_INT_P==8 + +# if SIZEOF_INT==8 +/* */ typedef int MyddasInt; +/* */ typedef unsigned int MyddasUInt; +/* */ typedef int MyddasLInt; +/* */ typedef unsigned int MyddasULInt; +/* */ typedef unsigned int MyddasPointer; +# elif SIZEOF_LONG_INT==8 +/* */ typedef long int MyddasInt; +/* */ typedef unsigned long int MyddasUInt; +/* */ typedef int MyddasLInt; +/* */ typedef unsigned int MyddasULInt; +/* */ typedef unsigned long int MyddasPointer; +# elif SIZEOF_LONG_LONG_INT==8 +/* */ typedef long long int MyddasInt; +/* */ typedef unsigned long long int MyddasUInt; +/* */ typedef int MyddasLInt; +/* */ typedef unsigned int MyddasULInt; +/* */ typedef unsigned long long int MyddasPointer; +# else +# error MYDDAS requires integer types of the same size as a pointer +# endif + +# if SIZEOF_SHORT_INT==4 +/* */ typedef short int MyddasSInt; +/* */ typedef unsigned short int MyddasUSInt; +/* */ typedef short int MyddasInt32; +/* */ typedef unsigned short int MyddasUInt32; +# elif SIZEOF_INT==4 +/* */ typedef int MyddasSInt; +/* */ typedef unsigned int MyddasUSInt; +/* */ typedef int MyddasInt32; +/* */ typedef unsigned int MyddasUInt32; +# else +# error MYDDAS requires integer types half the size of a pointer +# endif + +#else +# error MYDDAS requires pointers of size 4 or 8 +#endif + + + + +/* Passar para o myddas_statictics.h ???????? */ +#ifdef MYDDAS_STATS +#include +#include +#endif + +typedef struct myddas_global *MYDDAS_GLOBAL; +typedef struct myddas_util_query *MYDDAS_UTIL_QUERY; +typedef struct myddas_list_connection *MYDDAS_UTIL_CONNECTION; +typedef struct myddas_list_preds *MYDDAS_UTIL_PREDICATE; + +#ifdef MYDDAS_STATS +typedef struct myddas_stats_time_struct *MYDDAS_STATS_TIME; +typedef struct myddas_global_stats *MYDDAS_GLOBAL_STATS; +typedef struct myddas_stats_struct *MYDDAS_STATS_STRUCT; +#endif + +#ifdef DEBUG +#define MYDDAS_MALLOC(POINTER,TYPE) \ + { \ + POINTER = (TYPE *) malloc(sizeof(TYPE)); \ + Yap_REGS.MYDDAS_GLOBAL_POINTER->memory_allocated+=sizeof(TYPE); \ + /*printf ("MALLOC %p %s %d\n",POINTER,__FILE__,__LINE__);*/ \ + Yap_REGS.MYDDAS_GLOBAL_POINTER->malloc_called++; \ + } +#else +#define MYDDAS_MALLOC(POINTER,TYPE) \ + { \ + POINTER = (TYPE *) malloc(sizeof(TYPE)); \ + } +#endif + +#ifdef DEBUG +#define MYDDAS_FREE(POINTER,TYPE) \ + { \ + Yap_REGS.MYDDAS_GLOBAL_POINTER->memory_freed+=sizeof(TYPE); \ + Yap_REGS.MYDDAS_GLOBAL_POINTER->free_called++; \ + /*printf ("FREE %p %s %d\n",POINTER,__FILE__,__LINE__);*/ \ + free(POINTER); \ + } +#else +#define MYDDAS_FREE(POINTER,TYPE) \ + { \ + free(POINTER); \ + } +#endif + +#ifdef DEBUG +#define MYDDAS_MEMORY_MALLOC_NR(NUMBER) \ + NUMBER = Yap_REGS.MYDDAS_GLOBAL_POINTER->malloc_called; +#define MYDDAS_MEMORY_MALLOC_SIZE(NUMBER) \ + NUMBER = Yap_REGS.MYDDAS_GLOBAL_POINTER->memory_allocated; +#define MYDDAS_MEMORY_FREE_NR(NUMBER) \ + NUMBER = Yap_REGS.MYDDAS_GLOBAL_POINTER->free_called; +#define MYDDAS_MEMORY_FREE_SIZE(NUMBER) \ + NUMBER = Yap_REGS.MYDDAS_GLOBAL_POINTER->memory_freed; +#endif + + +#endif /*__MYDDAS_H__*/ diff --git a/packages/MYDDAS/myddas_initialization.c b/packages/MYDDAS/myddas_initialization.c new file mode 100644 index 000000000..035b1fa76 --- /dev/null +++ b/packages/MYDDAS/myddas_initialization.c @@ -0,0 +1,112 @@ +#if defined MYDDAS_ODBC || defined MYDDAS_MYSQL + +#include "Yap.h" +#include +#include +#include "myddas.h" +#include "myddas_structs.h" +#ifdef MYDDAS_STATS +#include "myddas_statistics.h" +#endif + +MYDDAS_GLOBAL +myddas_init_initialize_myddas(void){ + MYDDAS_GLOBAL global = NULL; + + /* We cannot call MYDDAS_MALLOC were because the global + register isn't yet initialized */ + global = (MYDDAS_GLOBAL) malloc (sizeof(struct myddas_global)); +#ifdef DEBUG + printf ("MALLOC %p %s %d\n",global,__FILE__,__LINE__); +#endif + global->myddas_top_connections = NULL; +#ifdef MYDDAS_TOP_LEVEL + global->myddas_top_level_connection = NULL; +#endif +#ifdef MYDDAS_STATS + global->myddas_statistics = (MYDDAS_GLOBAL_STATS) malloc (sizeof(struct myddas_global_stats)); +#ifdef DEBUG + printf ("MALLOC %p %s %d\n",global->myddas_statistics,__FILE__,__LINE__); +#endif + global->myddas_statistics->stats = NULL; +#endif + +#ifdef DEBUG + /* We first malloc for this struct and the stats struct */ +#ifdef MYDDAS_STATS + global->malloc_called = 2; + global->memory_allocated = sizeof(struct myddas_global) + sizeof(struct myddas_global_stats); +#else + global->malloc_called = 1; + global->memory_allocated = sizeof(struct myddas_global); +#endif /* MYDDAS_STATS */ + global->free_called = 0; + global->memory_freed = 0; +#endif + + return global; +} + +/* Inserts the new node on the front of the list */ +MYDDAS_UTIL_CONNECTION +myddas_init_initialize_connection(void *conn,void *enviromment, + MYDDAS_UTIL_CONNECTION next){ + + MYDDAS_UTIL_CONNECTION new = NULL; + MYDDAS_MALLOC(new,struct myddas_list_connection); + + if (new == NULL) + { + return NULL; + } + new->predicates=NULL; + new->connection=conn; + new->odbc_enviromment=enviromment; + + /* It saves n queries, doing at once n+1 queries */ + new->total_number_queries=0; //Default + new->actual_number_queries=0; + new->queries = NULL; + + /* List integrity */ + new->next=next; + new->previous=NULL; + /* If there's already at least one node + on the list */ + if (next != NULL) + next->previous=new; + +#ifdef MYDDAS_STATS + new->stats = NULL; + new->stats = myddas_stats_initialize_connection_stats(); +#endif + return new; +} + +MYDDAS_UTIL_PREDICATE +myddas_init_initialize_predicate(char *pred_name, int pred_arity, + char *pred_module, MYDDAS_UTIL_PREDICATE next){ + + MYDDAS_UTIL_PREDICATE new = NULL; + MYDDAS_MALLOC(new,struct myddas_list_preds); + + if (new == NULL) + { + return NULL; + } + new->pred_name=pred_name; + new->pred_arity=pred_arity; + new->pred_module=pred_module; + + /* List integrity */ + new->next=next; + new->previous=NULL; + /* If there's already at least one node + on the list */ + if (next != NULL) + next->previous=new; + + return new; +} + +#endif diff --git a/packages/MYDDAS/myddas_mysql.c b/packages/MYDDAS/myddas_mysql.c new file mode 100755 index 000000000..68ad84e09 --- /dev/null +++ b/packages/MYDDAS/myddas_mysql.c @@ -0,0 +1,725 @@ +/************************************************************************* +* * +* YAP Prolog * +* * +* Yap Prolog was developed at NCCUP - Universidade do Porto * +* * +* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 * +* * +************************************************************************** +* * +* File: myddas_mysql.c * +* Last rev: 22/03/05 * +* mods: * +* comments: Predicates for comunicating with a mysql database system * +* * +*************************************************************************/ + +#if defined MYDDAS_MYSQL + +#include +#include +#include +#include +#include "Yap.h" +#include "Yatom.h" +#include "cut_c.h" +#include "myddas.h" +#ifdef MYDDAS_STATS +#include "myddas_structs.h" +#include "myddas_statistics.h" +#endif +#include "myddas_wkb2prolog.h" + +#define IS_SQL_INT(FIELD) FIELD == FIELD_TYPE_INT24 || \ + FIELD == FIELD_TYPE_LONG || \ + FIELD == FIELD_TYPE_LONGLONG || \ + FIELD == FIELD_TYPE_SHORT || \ + FIELD == FIELD_TYPE_TINY + +#define IS_SQL_FLOAT(FIELD) FIELD == FIELD_TYPE_DECIMAL || \ + FIELD == FIELD_TYPE_DOUBLE || \ + FIELD == FIELD_TYPE_FLOAT + +#define IS_SQL_GEOMETRY(FIELD) FIELD == FIELD_TYPE_GEOMETRY + +static Int null_id = 0; + +STATIC_PROTO(Int c_db_my_connect,(void)); +STATIC_PROTO(Int c_db_my_disconnect,(void)); +STATIC_PROTO(Int c_db_my_number_of_fields,(void)); +STATIC_PROTO(Int c_db_my_get_attributes_types,(void)); +STATIC_PROTO(Int c_db_my_query,(void)); +STATIC_PROTO(Int c_db_my_table_write,(void)); +STATIC_PROTO(Int c_db_my_row,(void)); +STATIC_PROTO(Int c_db_my_row_cut,(void)); +STATIC_PROTO(Int c_db_my_get_fields_properties,(void)); +STATIC_PROTO(Int c_db_my_get_next_result_set,(void)); +STATIC_PROTO(Int c_db_my_get_database,(void)); +STATIC_PROTO(Int c_db_my_change_database,(void)); + +void Yap_InitMYDDAS_MySQLPreds(void) +{ + /* db_connect: Host x User x Passwd x Database x Connection x ERROR_CODE */ + Yap_InitCPred("c_db_my_connect", 7, c_db_my_connect, 0); + + /* db_number_of_fields: Relation x Connection x NumberOfFields */ + Yap_InitCPred("c_db_my_number_of_fields",3, c_db_my_number_of_fields, 0); + + /* db_get_attributes_types: Relation x TypesList */ + Yap_InitCPred("c_db_my_get_attributes_types", 3, c_db_my_get_attributes_types, 0); + + /* db_query: SQLQuery x ResultSet x Connection */ + Yap_InitCPred("c_db_my_query", 5, c_db_my_query, 0); + + /* db_disconnect: Connection */ + Yap_InitCPred("c_db_my_disconnect", 1,c_db_my_disconnect, 0); + + /* db_table_write: Result Set */ + Yap_InitCPred("c_db_my_table_write", 1, c_db_my_table_write, 0); + + /* db_get_fields_properties: PredName x Connnection x PropertiesList*/ + Yap_InitCPred("c_db_my_get_fields_properties",3,c_db_my_get_fields_properties,0); + + + Yap_InitCPred("c_db_my_get_next_result_set",2,c_db_my_get_next_result_set,0); + + /* c_db_my_get_database: Connnection x DataBaseName */ + Yap_InitCPred("c_db_my_get_database",2,c_db_my_get_database,0); + + /* c_db_my_change_database: Connnection x DataBaseName */ + Yap_InitCPred("c_db_my_change_database",2,c_db_my_change_database,0); + + +} + +void Yap_InitBackMYDDAS_MySQLPreds(void) +{ + /* db_row: ResultSet x Arity x ListOfArgs */ + Yap_InitCPredBackCut("c_db_my_row", 3, sizeof(Int), + c_db_my_row, + c_db_my_row, + c_db_my_row_cut, 0); + +} + +static Int +c_db_my_connect(void) { + Term arg_host = Deref(ARG1); + Term arg_user = Deref(ARG2); + Term arg_passwd = Deref(ARG3); + Term arg_database = Deref(ARG4); + Term arg_port = Deref(ARG5); + Term arg_socket = Deref(ARG6); + Term arg_conn = Deref(ARG7); + + MYSQL *conn; + + MYDDAS_UTIL_CONNECTION new = NULL; + + char *host = AtomName(AtomOfTerm(arg_host)); + char *user = AtomName(AtomOfTerm(arg_user)); + char *passwd = AtomName(AtomOfTerm(arg_passwd)); + char *database = AtomName(AtomOfTerm(arg_database)); + Int port = IntegerOfTerm(arg_port); + + char *socket; + if (IsNonVarTerm(arg_socket)) + socket = AtomName(AtomOfTerm(arg_socket)); + else + socket = NULL; + + conn = mysql_init(NULL); + if (conn == NULL) { +#ifdef DEBUG + printf("ERROR: ** c_db_my_connect ** error on init\n"); +#endif + return FALSE; + } + + if (mysql_real_connect(conn, host, user, passwd, database, port, socket, CLIENT_MULTI_STATEMENTS) == NULL) { +#ifdef DEBUG + printf("ERROR: ** c_db_my_connect ** error on connect\n"); +#endif + return FALSE; + } + + if (!Yap_unify(arg_conn, MkIntegerTerm((Int)conn))) + return FALSE; + else + { + /* Criar um novo no na lista de ligacoes*/ + new = myddas_util_add_connection(conn,NULL); + + if (new == NULL){ +#ifdef DEBUG + printf("ERROR: ** c_db_my_connect ** Error allocating memory\n"); +#endif + return FALSE; + } + return TRUE; + } +} + +/* db_query: SQLQuery x ResultSet x Connection */ +static Int +c_db_my_query(void) { + Term arg_sql_query = Deref(ARG1); + Term arg_result_set = Deref(ARG2); + Term arg_conn = Deref(ARG3); + Term arg_mode = Deref(ARG4); + Term arg_arity = Deref(ARG5); + + char *sql = AtomName(AtomOfTerm(arg_sql_query)); + char *mode = AtomName(AtomOfTerm(arg_mode)); + MYSQL *conn = (MYSQL *) (IntegerOfTerm(arg_conn)); + + MYSQL_RES *res_set; + + MyddasInt length=strlen(sql); + +#ifdef MYDDAS_STATS + MYDDAS_UTIL_CONNECTION node = myddas_util_search_connection(conn); + MyddasULInt count = 0; + + /* Count the number of querys made to the server */ + MyddasULInt number_querys; + MYDDAS_STATS_CON_GET_NUMBER_QUERIES_MADE(node,number_querys); + MYDDAS_STATS_CON_SET_NUMBER_QUERIES_MADE(node,++number_querys); + MYDDAS_STATS_CON_GET_NUMBER_QUERIES_MADE_COUNT(node,count); + MYDDAS_STATS_CON_SET_NUMBER_QUERIES_MADE_COUNT(node,++count); + + /* Measure time spent by the MySQL Server + processing the SQL Query */ + MYDDAS_STATS_TIME start,end,total_time,diff; + start = myddas_stats_walltime(); +#endif + + /* Send query to server and process it */ + if (mysql_real_query(conn, sql, length) != 0) + { +#ifdef DEBUG + printf("ERROR: **c_db_my_query** Error on query! %s\n",sql); +#endif + return FALSE; + } + +#ifdef MYDDAS_STATS + /* Measure time spent by the MySQL Server + processing the SQL Query */ + end = myddas_stats_walltime(); + + MYDDAS_STATS_INITIALIZE_TIME_STRUCT(diff,time_copy); + myddas_stats_subtract_time(diff,end,start); + diff = myddas_stats_time_copy_to_final(diff); + + MYDDAS_FREE(end,struct myddas_stats_time_struct); + MYDDAS_FREE(start,struct myddas_stats_time_struct); + + MYDDAS_STATS_CON_GET_TOTAL_TIME_DBSERVER(node,total_time); + /* Automacally updates the MYDDAS_STRUCTURE */ + myddas_stats_add_time(total_time,diff,total_time); + MYDDAS_STATS_CON_GET_TOTAL_TIME_DBSERVER_COUNT(node,count); + MYDDAS_STATS_CON_SET_TOTAL_TIME_DBSERVER_COUNT(node,++count); + + MYDDAS_STATS_TIME time = NULL; + MYDDAS_STATS_CON_GET_LAST_TIME_DBSERVER(node,time); + myddas_stats_move_time(diff,time); + MYDDAS_STATS_CON_GET_LAST_TIME_DBSERVER_COUNT(node,count); + MYDDAS_STATS_CON_SET_LAST_TIME_DBSERVER_COUNT(node,++count); +#endif + + /* guardar os tuplos do lado do cliente */ + if (strcmp(mode,"store_result")!=0) //True + res_set = mysql_use_result(conn); + else{ + +#ifdef MYDDAS_STATS + /* Measure time spent by the MySQL Server + transferring the result of the last query + back to the client */ + start = myddas_stats_walltime(); +#endif + res_set = mysql_store_result(conn); +#ifdef MYDDAS_STATS + /* Measure time spent by the MySQL Server + transferring the result of the last query + back to the client */ + end = myddas_stats_walltime(); + + MYDDAS_STATS_INITIALIZE_TIME_STRUCT(diff,time_copy); + myddas_stats_subtract_time(diff,end,start); + diff = myddas_stats_time_copy_to_final(diff); + + MYDDAS_FREE(end,struct myddas_stats_time_struct); + MYDDAS_FREE(start,struct myddas_stats_time_struct); + + MYDDAS_STATS_CON_GET_TOTAL_TIME_TRANSFERING(node,total_time); + /* Automacally updates the MYDDAS_STRUCTURE */ + myddas_stats_add_time(total_time,diff,total_time); + MYDDAS_STATS_CON_GET_TOTAL_TIME_TRANSFERING_COUNT(node,count); + MYDDAS_STATS_CON_SET_TOTAL_TIME_TRANSFERING_COUNT(node,++count); + + time = NULL; + MYDDAS_STATS_CON_GET_LAST_TIME_TRANSFERING(node,time); + MYDDAS_STATS_CON_GET_LAST_TIME_TRANSFERING_COUNT(node,count); + MYDDAS_STATS_CON_SET_LAST_TIME_TRANSFERING_COUNT(node,++count); + myddas_stats_move_time(diff,time); + + /* Measure the number of Rows returned from the server */ + if (res_set != NULL) + { + /* With an INSERT statement, mysql_(use or store)_result() + returns a NULL pointer*/ + + /* This is only works if we use mysql_store_result */ + MyddasUInt numberRows = mysql_num_rows(res_set); + MyddasUInt rows; + + MYDDAS_STATS_CON_GET_TOTAL_ROWS(node,rows); + numberRows = numberRows + rows; + MYDDAS_STATS_CON_SET_TOTAL_ROWS(node,numberRows); + MYDDAS_STATS_CON_GET_TOTAL_ROWS_COUNT(node,count); + MYDDAS_STATS_CON_SET_TOTAL_ROWS_COUNT(node,++count); + + /* Calculate the ammount of data sent by the server */ + MyddasUInt total,number_fields = mysql_num_fields(res_set); + MYSQL_ROW row; + MyddasULInt i; + total=0; + while ((row = mysql_fetch_row(res_set)) != NULL){ + mysql_field_seek(res_set,0); + + for(i=0;i TypesList */ +static Int +c_db_my_get_attributes_types(void) { + Term arg_relation = Deref(ARG1); + Term arg_conn = Deref(ARG2); + Term arg_types_list = Deref(ARG3); + + char *relation = AtomName(AtomOfTerm(arg_relation)); + MYSQL *conn = (MYSQL *) IntegerOfTerm(arg_conn); + char sql[256]; + + MYSQL_RES *res_set; + MYSQL_ROW row; + Term head, list; + + sprintf(sql,"DESCRIBE `%s`",relation); + + Int length = strlen(sql); + + /* executar a query SQL */ + if (mysql_real_query(conn, sql, length) != 0) + { +#ifdef DEBUG + printf("Erro na query! %s\n",sql); +#endif + return FALSE; + } + /* guardar os tuplos do lado do cliente */ + if ((res_set = mysql_store_result(conn)) == NULL) + { +#ifdef DEBUG + printf("Query vazia!\n"); +#endif + return FALSE; + } + + list = arg_types_list; + + while ((row = mysql_fetch_row(res_set)) != NULL) + { + head = HeadOfTerm(list); + Yap_unify(head, MkAtomTerm(Yap_LookupAtom(row[0]))); + list = TailOfTerm(list); + head = HeadOfTerm(list); + list = TailOfTerm(list); + + if (strncmp(row[1], "smallint",8) == 0 || strncmp(row[1],"int",3) == 0 || + strncmp(row[1], "mediumint",9) == 0 || strncmp(row[1], "tinyint",7) == 0 || + strncmp(row[1], "bigint",6) == 0 || strcmp(row[1], "year") == 0) + Yap_unify(head, MkAtomTerm(Yap_LookupAtom("integer"))); + else if (strcmp(row[1], "float") == 0 || strncmp(row[1], "double",6) == 0 + || strcmp(row[1], "real") == 0) + Yap_unify(head, MkAtomTerm(Yap_LookupAtom("real"))); + else Yap_unify(head, MkAtomTerm(Yap_LookupAtom("string"))); + } + + mysql_free_result(res_set); + return TRUE; + +} + +/* db_disconnect */ +static Int +c_db_my_disconnect(void) { + Term arg_conn = Deref(ARG1); + + MYSQL *conn = (MYSQL *) IntegerOfTerm(arg_conn); + + if ((myddas_util_search_connection(conn)) != NULL) + { + myddas_util_delete_connection(conn); + mysql_close(conn); + return TRUE; + } + else + { + return FALSE; + } +} + +/* db_table_write: Result Set */ +static Int +c_db_my_table_write(void) { + Term arg_res_set = Deref(ARG1); + + MYSQL_RES *res_set = (MYSQL_RES *) IntegerOfTerm(arg_res_set); + + myddas_util_table_write(res_set); + mysql_free_result(res_set); + + return TRUE; +} + +static Int +c_db_my_row_cut(void) { + MYSQL_RES *mysql_res=NULL; + + mysql_res = (MYSQL_RES *) IntegerOfTerm(EXTRA_CBACK_CUT_ARG(Term,1)); + mysql_free_result(mysql_res); + return TRUE; +} + +/* db_row: ResultSet x Arity_ListOfArgs x ListOfArgs -> */ +static Int +c_db_my_row(void) { +#ifdef MYDDAS_STATS +/* Measure time used by the */ +/* c_db_my_row function */ + MYDDAS_STATS_TIME start,end,total_time,diff; + MyddasULInt count = 0; + start = myddas_stats_walltime(); +#endif + Term arg_result_set = Deref(ARG1); + Term arg_arity = Deref(ARG2); + Term arg_list_args = Deref(ARG3); + + MYSQL_RES *res_set = (MYSQL_RES *) IntegerOfTerm(arg_result_set); + EXTRA_CBACK_ARG(3,1)=(CELL) MkIntegerTerm((Int)res_set); + MYSQL_ROW row; + MYSQL_FIELD *field; + + + Term head, list, null_atom[1]; + Int i, arity; + + arity = IntegerOfTerm(arg_arity); + + while(TRUE) + { + if ((row = mysql_fetch_row(res_set)) != NULL) + { + mysql_field_seek(res_set,0); + list = arg_list_args; + + for (i = 0; i < arity; i++) + { + /* Aqui serão feitas as conversões de tipos de dados */ + field = mysql_fetch_field(res_set); + head = HeadOfTerm(list); + list = TailOfTerm(list); + + if (row[i] == NULL) + { + null_atom[0] = MkIntegerTerm(null_id++); + + if (!Yap_unify(head, Yap_MkApplTerm(Yap_MkFunctor(Yap_LookupAtom("null"),1),1,null_atom))) + continue; + } + else + { + if (IS_SQL_INT(field->type)) + { + if (!Yap_unify(head, MkIntegerTerm(atoi(row[i])))) + continue; + } + else if (IS_SQL_FLOAT(field->type)) + { + if (!Yap_unify(head, MkFloatTerm(atof(row[i])))) + continue; + } + else if (IS_SQL_GEOMETRY(field->type)) + { + if (!Yap_unify(head, wkb2prolog(row[i]))) + continue; + } + else + { + if (!Yap_unify(head, MkAtomTerm(Yap_LookupAtom(row[i])))) + continue; + } + } + } +#ifdef MYDDAS_STATS + end = myddas_stats_walltime(); + + MYDDAS_STATS_INITIALIZE_TIME_STRUCT(diff,time_copy); + myddas_stats_subtract_time(diff,end,start); + diff = myddas_stats_time_copy_to_final(diff); + + MYDDAS_FREE(end,struct myddas_stats_time_struct); + MYDDAS_FREE(start,struct myddas_stats_time_struct); + + MYDDAS_STATS_GET_DB_ROW_FUNCTION(total_time); + myddas_stats_add_time(total_time,diff,total_time); + MYDDAS_STATS_GET_DB_ROW_FUNCTION_COUNT(count); + MYDDAS_STATS_SET_DB_ROW_FUNCTION_COUNT(++count); + + MYDDAS_FREE(diff,struct myddas_stats_time_struct); +#endif /* MYDDAS_STATS */ + return TRUE; + } + else + { + mysql_free_result(res_set); +#ifdef MYDDAS_STATS + end = myddas_stats_walltime(); + + MYDDAS_STATS_INITIALIZE_TIME_STRUCT(diff,time_copy); + myddas_stats_subtract_time(diff,end,start); + diff = myddas_stats_time_copy_to_final(diff); + + MYDDAS_FREE(end,struct myddas_stats_time_struct); + MYDDAS_FREE(start,struct myddas_stats_time_struct); + + MYDDAS_STATS_GET_DB_ROW_FUNCTION(total_time); + myddas_stats_add_time(total_time,diff,total_time); + MYDDAS_STATS_GET_DB_ROW_FUNCTION_COUNT(count); + MYDDAS_STATS_SET_DB_ROW_FUNCTION_COUNT(++count); + + MYDDAS_FREE(diff,struct myddas_stats_time_struct); +#endif /* MYDDAS_STATS */ + cut_fail(); /* This macro already does a return FALSE */ + } + + } + +} + +static Int +c_db_my_get_fields_properties(void) { + Term nome_relacao = Deref(ARG1); + Term arg_conn = Deref(ARG2); + Term fields_properties_list = Deref(ARG3); + Term head, list; + + char *relacao = AtomName(AtomOfTerm(nome_relacao)); + char sql[256]; + Int num_fields,i; + MYSQL_FIELD *fields; + MYSQL_RES *res_set; + MYSQL *conn = (MYSQL *) (IntegerOfTerm(arg_conn)); + + + /* LIMIT 0 -> We only need the meta information about the fields + to know their properties, we don't need the results of the + query*/ + sprintf (sql,"SELECT * FROM `%s` LIMIT 0",relacao); + + Int length=strlen(sql); + + /* executar a query SQL */ + if (mysql_real_query(conn, sql, length) != 0) + { +#ifdef DEBUG + printf("Erro na query! %s\n",sql); +#endif + return FALSE; + } + + Functor functor = Yap_MkFunctor(Yap_LookupAtom("property"),4); + + Term properties[4]; + + + /* guardar os tuplos do lado do cliente */ + /* nao precisamos do resultado, mas apenas no res_set */ + /* para obter a informação através do mysql_fetch_fields*/ + res_set = mysql_store_result(conn); + + num_fields = mysql_num_fields(res_set); + fields = mysql_fetch_fields(res_set); + + list = fields_properties_list; + + + + for (i=0;idb)))) + return FALSE; + + return TRUE; + +} + +static Int +c_db_my_change_database(void) { + Term arg_con = Deref(ARG1); + Term arg_database = Deref(ARG2); + + MYSQL *con = (MYSQL *) (IntegerOfTerm(arg_con)); + char *database = AtomName(AtomOfTerm(arg_database)); + + if (mysql_select_db(con,database)!=0) + return FALSE; + + return TRUE; +} + +#endif /* MYDDAS_MYSQL */ diff --git a/packages/MYDDAS/myddas_odbc.c b/packages/MYDDAS/myddas_odbc.c new file mode 100755 index 000000000..7ba61db9b --- /dev/null +++ b/packages/MYDDAS/myddas_odbc.c @@ -0,0 +1,745 @@ +/************************************************************************* +* * +* YAP Prolog * +* * +* Yap Prolog was developed at NCCUP - Universidade do Porto * +* * +* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 * +* * +************************************************************************** +* * +* File: myddas_odbc.c * +* Last rev: 22/03/05 * +* mods: * +* comments: Predicates for comunicating with ODBC drivers * +* * +*************************************************************************/ + +#if defined MYDDAS_ODBC && defined CUT_C + +#include +#include +#include +#include "Yap.h" +#include "Yatom.h" +#include "myddas.h" +#include "cut_c.h" +#include +#include + +static Int null_id = 0; + +STATIC_PROTO(Int c_db_odbc_connect,(void)); +STATIC_PROTO(Int c_db_odbc_disconnect,(void)); +STATIC_PROTO(Int c_db_odbc_number_of_fields,(void)); +STATIC_PROTO(Int c_db_odbc_get_attributes_types,(void)); +STATIC_PROTO(Int c_db_odbc_query,(void)); +STATIC_PROTO(Int c_db_odbc_row,(void)); +STATIC_PROTO(Int c_db_odbc_row_cut,(void)); +STATIC_PROTO(Int c_db_odbc_get_fields_properties,(void)); +STATIC_PROTO(Int c_db_odbc_number_of_fields_in_query,(void)); + + +#define SQLALLOCHANDLE(A,B,C,print) \ +{ \ + SQLRETURN retcode; \ + retcode = SQLAllocHandle(A,B,C); \ + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) \ + { \ + printf("erro no SQLAllocHandle(ENV) %s\n",print); \ + return FALSE; \ + } \ +} + +#define SQLSETENVATTR(A,B,C,D,print) \ +{ \ + SQLRETURN retcode; \ + retcode = SQLSetEnvAttr(A,B,C,D); \ + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) \ + { \ + printf("erro no SQLSetEnvAttr %s\n",print); \ + return FALSE; \ + } \ +} + +#define SQLCONNECT(A,B,C,D,E,F,G,print) \ +{ \ + SQLRETURN retcode; \ + retcode = SQLConnect(A,B,C,D,E,F,G); \ + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) \ + { \ + printf("erro no SQLConnect %s\n",print); \ + return FALSE; \ + } \ +} + +#define SQLEXECDIRECT(A,B,C,print) \ +{ \ + SQLRETURN retcode; \ + retcode = SQLExecDirect(A,B,C); \ + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) \ + { \ + printf("erro no SQLExecDirect %s \n",print); \ + return FALSE; \ + } \ +} + +#define SQLDESCRIBECOL(A,B,C,D,E,F,G,H,I,print) \ +{ \ + SQLRETURN retcode; \ + retcode = SQLDescribeCol(A,B,C,D,E,F,G,H,I); \ + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) \ + { \ + printf("erro no SQLDescribeCol %s\n",print); \ + return FALSE; \ + } \ +} + +#define SQLSETCONNECTATTR(A,B,C,D,print) \ +{ \ + SQLRETURN retcode; \ + retcode = SQLSetConnectAttr(A,B,C,D); \ + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) \ + { \ + printf("erro no SQLSetConnectAttr %s\n",print); \ + return FALSE; \ + } \ +} + +#define SQLBINDCOL(A,B,C,D,E,F,print) \ +{ \ + SQLRETURN retcode; \ + retcode = SQLBindCol(A,B,C,D,E,F); \ + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) \ + { \ + printf("erro no SQLbindCol %s\n",print); \ + return FALSE; \ + } \ +} + +#define SQLFREESTMT(A,B,print) \ +{ \ + SQLRETURN retcode; \ + retcode = SQLFreeStmt(A,B); \ + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) \ + { \ + printf("erro no SQLFreeStmt %s\n",print); \ + return FALSE; \ + } \ +} + +#define SQLNUMRESULTCOLS(A,B,print) \ +{ \ + SQLRETURN retcode; \ + retcode = SQLNumResultCols(A,B); \ + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) \ + { \ + printf("erro no SQLNumResultCols %s\n",print); \ + return FALSE; \ + } \ +} + + +#define SQLCLOSECURSOR(A,print) \ +{ \ + SQLRETURN retcode; \ + retcode = SQLCloseCursor(A); \ + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) \ + { \ + printf("erro no SQLCloseCursor %s\n",print); \ + return FALSE; \ + } \ +} + +/* no db_odbc_row não é utilizada esta macro*/ +#define SQLFETCH(A,print) \ +{ \ + SQLRETURN retcode; \ + retcode = SQLFetch(A); \ + if (retcode == SQL_NO_DATA) \ + break; \ + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) \ + { \ + printf("erro no SQLFETCH %s\n",print); \ + return FALSE; \ + } \ +} + +#define SQLGETDATA(A,B,C,D,E,F,print) \ +{ \ + SQLRETURN retcode; \ + retcode = SQLGetData(A,B,C,D,E,F); \ + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) \ + { \ + printf("erro no SQLgetdata %s\n",print); \ + return FALSE; \ + } \ +} + +#define SQLDISCONNECT(A,print) \ +{ \ + SQLRETURN retcode; \ + retcode = SQLDisconnect(A); \ + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) \ + { \ + printf("erro no SQLDisconnect %s\n",print); \ + return FALSE; \ + } \ +} + +#define SQLFREEHANDLE(A,B,print) \ +{ \ + SQLRETURN retcode; \ + retcode = SQLFreeHandle(A,B); \ + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) \ + { \ + printf("erro no SQLFreeHandle %s\n",print); \ + return FALSE; \ + } \ +} + +#define SQLPRIMARYKEYS(A,B,C,D,E,F,G,print) \ +{ \ + SQLRETURN retcode; \ + retcode = SQLPrimaryKeys(A,B,C,D,E,F,G); \ + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) \ + { \ + printf("erro no SQLPrimaryKeys %s\n",print); \ + return FALSE; \ + } \ +} + +#define SQLGETTYPEINFO(A,B,print) \ +{ \ + SQLRETURN retcode; \ + retcode = SQLGetTypeInfo(A,B); \ + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) \ + { \ + printf("erro no SQLGetTypeInfo %s\n",print); \ + return FALSE; \ + } \ +} + +#define SQLCOLATTRIBUTE(A,B,C,D,E,F,G,print) \ +{ \ + SQLRETURN retcode; \ + retcode = SQLColAttribute(A,B,C,D,E,F,G); \ + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) \ + { \ + printf("erro no SQLColAttribute %s\n",print); \ + return FALSE; \ + } \ +} + + + +/* Verificar tipo de dados*/ +#define IS_SQL_INT(FIELD) FIELD == SQL_DECIMAL || \ + FIELD == SQL_NUMERIC || \ + FIELD == SQL_SMALLINT || \ + FIELD == SQL_INTEGER || \ + FIELD == SQL_TINYINT || \ + FIELD == SQL_BIGINT + +#define IS_SQL_FLOAT(FIELD) FIELD == SQL_FLOAT || \ + FIELD == SQL_DOUBLE || \ + FIELD == SQL_REAL + + + + +static Int +c_db_odbc_connect(void) { + Term arg_driver = Deref(ARG1); + Term arg_user = Deref(ARG2); + Term arg_passwd = Deref(ARG3); + Term arg_conn = Deref(ARG4); + + MYDDAS_UTIL_CONNECTION new = NULL; + + char *driver = AtomName(AtomOfTerm(arg_driver)); + char *user = AtomName(AtomOfTerm(arg_user)); + char *passwd = AtomName(AtomOfTerm(arg_passwd)); + + SQLHENV henv; + SQLHDBC hdbc; + + /*Allocate environment handle */ + SQLALLOCHANDLE(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &henv, "connect"); + /* Set the ODBC version environment attribute */ + SQLSETENVATTR(henv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)SQL_OV_ODBC3, 0, "connect"); + /* Allocate connection handle */ + SQLALLOCHANDLE(SQL_HANDLE_DBC, henv, &hdbc, "connect"); + /* Set login timeout to 6 seconds. */ + SQLSETCONNECTATTR(hdbc, SQL_LOGIN_TIMEOUT,(SQLPOINTER) 6, 0, "connect"); + /* Connect to data source */ + SQLCONNECT(hdbc, + (SQLCHAR*) driver, SQL_NTS, + (SQLCHAR*) user, SQL_NTS, + (SQLCHAR*) passwd, SQL_NTS, "connect"); + + if (!Yap_unify(arg_conn, MkIntegerTerm((Int)(hdbc)))) + return FALSE; + else + { + /* Criar um novo no na lista de ligacoes*/ + //new = add_connection(&TOP,hdbc,henv); + new = myddas_util_add_connection(hdbc,henv); + if (new == NULL){ + printf("Erro ao alocar memoria para lista\n"); + return FALSE; + } + return TRUE; + } +} + +/* db_query: SQLQuery x ResultSet x Arity x BindList x Connection */ +static Int +c_db_odbc_query(void) { + Term arg_sql_query = Deref(ARG1); + Term arg_result_set = Deref(ARG2); + Term arg_arity = Deref(ARG3); + Term arg_bind_list = Deref(ARG4); + Term arg_conn = Deref(ARG5); + + SQLCHAR *sql = AtomName(AtomOfTerm(arg_sql_query)); + + + SQLHDBC hdbc =(SQLHDBC) (IntegerOfTerm(arg_conn)); + SQLHSTMT hstmt; + SQLSMALLINT type; + + /*Allocate an handle for the query*/ + SQLALLOCHANDLE(SQL_HANDLE_STMT, hdbc, &hstmt, "db_query"); + /* Executes the query*/ + SQLEXECDIRECT(hstmt,sql,SQL_NTS, "db_query"); + + Int arity; + Int i; + + if (IsNonVarTerm(arg_arity)){ + arity = IntegerOfTerm(arg_arity); + + + char *bind_space=NULL; + + //const Int functor_arity=3; + const Short functor_arity=3; + Functor functor = Yap_MkFunctor(Yap_LookupAtom("bind"),functor_arity); + Term properties[functor_arity]; + + Term head,list=arg_bind_list; + + SQLUINTEGER ColumnSizePtr; + SQLINTEGER *data_info=NULL; + + for (i=1;i<=arity;i++) + { + head = HeadOfTerm(list); + list = TailOfTerm(list); + + SQLDESCRIBECOL(hstmt,i,NULL,0,NULL,&type,&ColumnSizePtr,NULL,NULL,"db_query"); + + /* +1 because of '\0' */ + bind_space = malloc(sizeof(char)*(ColumnSizePtr+1)); + data_info = malloc(sizeof(SQLINTEGER)); + SQLBINDCOL(hstmt,i,SQL_C_CHAR,bind_space,(ColumnSizePtr+1),data_info,"db_query"); + + properties[0] = MkIntegerTerm((Int)bind_space); + properties[2] = MkIntegerTerm((Int)data_info); + + if (IS_SQL_INT(type)) + properties[1]=MkAtomTerm(Yap_LookupAtom("integer")); + else if (IS_SQL_FLOAT(type)) + properties[1]=MkAtomTerm(Yap_LookupAtom("real")); + else + properties[1]=MkAtomTerm(Yap_LookupAtom("string")); + + Yap_unify(head,Yap_MkApplTerm(functor,functor_arity,properties)); + continue; + + } + } + + if (!Yap_unify(arg_result_set, MkIntegerTerm((Int) hstmt))) + { + SQLCLOSECURSOR(hstmt,"db_query"); + SQLFREESTMT(hstmt,SQL_CLOSE,"db_query"); + return FALSE; + } + return TRUE; +} + +static Int +c_db_odbc_number_of_fields(void) { + Term arg_relation = Deref(ARG1); + Term arg_conn = Deref(ARG2); + Term arg_fields = Deref(ARG3); + + + char *relation = AtomName(AtomOfTerm(arg_relation)); + + SQLHDBC hdbc =(SQLHDBC) (IntegerOfTerm(arg_conn)); + SQLHSTMT hstmt; + + char sql[256]; + SQLSMALLINT number_fields; + + sprintf(sql,"DESCRIBE %s",relation); + + SQLALLOCHANDLE(SQL_HANDLE_STMT, hdbc, &hstmt, "db_number_of_fields"); + SQLEXECDIRECT(hstmt,sql,SQL_NTS, "db_number_of_fields"); + + /* Calcula o numero de campos*/ + number_fields=0; + while(TRUE) { + SQLFETCH(hstmt,"db_number_of_fields"); + number_fields++; + } + + SQLCLOSECURSOR(hstmt,"db_number_of_fields"); + SQLFREESTMT(hstmt,SQL_CLOSE,"db_number_of_fields"); + + if (!Yap_unify(arg_fields, MkIntegerTerm(number_fields))) + return FALSE; + return TRUE; +} + + +/* db_get_attributes_types: RelName x Connection -> TypesList */ +static Int +c_db_odbc_get_attributes_types(void) { + Term arg_relation = Deref(ARG1); + Term arg_conn = Deref(ARG2); + Term arg_types_list = Deref(ARG3); + + char *relation = AtomName(AtomOfTerm(arg_relation)); + SQLHDBC hdbc =(SQLHDBC) (IntegerOfTerm(arg_conn)); + SQLHSTMT hstmt; + + char sql[256]; + Term head, list; + list = arg_types_list; + + sprintf(sql,"DESCRIBE %s",relation); + + SQLALLOCHANDLE(SQL_HANDLE_STMT, hdbc, &hstmt, "db_get_attributes_types"); + SQLEXECDIRECT(hstmt,sql,SQL_NTS, "db_get_attributes_types"); + + while (TRUE) + { + SQLFETCH(hstmt, "db_get_attributes_types"); + + /* Tentar fazer de uma maneira que a gente consiga calcular o tamanho que o + nome do campo vai ocupar, assim podemos alocar memoria dinamicamente*/ + sql[0]='\0'; + SQLGETDATA(hstmt, 1, SQL_C_CHAR, sql, 256, NULL, "db_get_attributes_types"); + + head = HeadOfTerm(list); + Yap_unify(head, MkAtomTerm(Yap_LookupAtom(sql))); + list = TailOfTerm(list); + head = HeadOfTerm(list); + list = TailOfTerm(list); + + sql[0]='\0'; + SQLGETDATA(hstmt, 2, SQL_C_CHAR, sql, 256, NULL, "db_get_attributes_types"); + + if (strncmp(sql, "smallint",8) == 0 || strncmp(sql,"int",3) == 0 || + strncmp(sql, "mediumint",9) == 0 || strncmp(sql, "tinyint",7) == 0 || + strncmp(sql, "bigint",6) == 0 || strcmp(sql, "year") == 0) + Yap_unify(head, MkAtomTerm(Yap_LookupAtom("integer"))); + else + if (strcmp(sql, "float") == 0 || strncmp(sql, "double",6) == 0 + || strcmp(sql, "real") == 0) + Yap_unify(head, MkAtomTerm(Yap_LookupAtom("real"))); + else + Yap_unify(head, MkAtomTerm(Yap_LookupAtom("string"))); + } + + SQLCLOSECURSOR(hstmt,"db_get_attributes_types"); + SQLFREESTMT(hstmt,SQL_CLOSE, "db_get_attributes_types"); + return TRUE; +} + +/* db_disconnect */ +static Int +c_db_odbc_disconnect(void) { + Term arg_conn = Deref(ARG1); + + SQLHDBC conn = (SQLHDBC) (IntegerOfTerm(arg_conn)); + SQLHENV henv = myddas_util_get_odbc_enviromment(conn); + + if ((myddas_util_search_connection(conn)) != NULL) + { + myddas_util_delete_connection(conn); + /* More information about this process on + msdn.microsoft.com*/ + SQLDISCONNECT(conn,"db_disconnect"); + SQLFREEHANDLE(SQL_HANDLE_DBC,conn,"db_disconnect"); + SQLFREEHANDLE(SQL_HANDLE_ENV,henv,"db_disconnect"); + + return TRUE; + } + else + return FALSE; +} + +static Int +c_db_odbc_row_cut(void) { + + SQLHSTMT hstmt = (SQLHSTMT) IntegerOfTerm(EXTRA_CBACK_CUT_ARG(Term,1)); + + SQLCLOSECURSOR(hstmt,"db_row_cut"); + SQLFREESTMT(hstmt,SQL_CLOSE,"db_row_cut"); + + return TRUE; +} + +/* db_row: ResultSet x BindList x ListOfArgs -> */ +static Int +c_db_odbc_row(void) { + Term arg_result_set = Deref(ARG1); + Term arg_bind_list = Deref(ARG2); + Term arg_list_args = Deref(ARG3); + + SQLHSTMT hstmt = (SQLHSTMT) IntegerOfTerm(arg_result_set); + + /* EXTRA_CBACK_ARG(ARIDADE,LOCAL_ONDE_COLOCAR_VALOR)*/ + EXTRA_CBACK_ARG(3,1)=(CELL) MkIntegerTerm((Int)hstmt); + + Term head, list, null_atom[1]; + Term head_bind, list_bind; + + SQLRETURN retcode = SQLFetch(hstmt); + if (retcode == SQL_NO_DATA) + { + SQLCLOSECURSOR(hstmt,"db_row"); + SQLFREESTMT(hstmt,SQL_CLOSE,"db_row"); + + cut_fail(); + return FALSE; + } + if (retcode != SQL_SUCCESS && retcode != SQL_SUCCESS_WITH_INFO) + { + printf("erro no SQLFETCH number of fields\n"); + return FALSE; + } + + char *bind_value=NULL; + Term type; + + list = arg_list_args; + list_bind = arg_bind_list; + SQLINTEGER *data_info=NULL; + + while (IsPairTerm(list_bind)) + { + head = HeadOfTerm(list); + list = TailOfTerm(list); + + head_bind = HeadOfTerm(list_bind); + list_bind = TailOfTerm(list_bind); + + bind_value = (char *)IntegerOfTerm(ArgOfTerm(1,head_bind)); + type = ArgOfTerm(2,head_bind); + data_info = (SQLINTEGER *)IntegerOfTerm(ArgOfTerm(3,head_bind)); + + if ((*data_info) == SQL_NULL_DATA){ + null_atom[0] = MkIntegerTerm(null_id++); + if (!Yap_unify(head, Yap_MkApplTerm(Yap_MkFunctor(Yap_LookupAtom("null"),1),1,null_atom))) + continue; + } + else + { + + if (!strcmp(AtomName(AtomOfTerm(type)),"integer")) + { + if (!Yap_unify(head, MkIntegerTerm(atoi(bind_value)))) + continue; + } + else if (!strcmp(AtomName(AtomOfTerm(type)),"real")) + { + if (!Yap_unify(head, MkFloatTerm(atof(bind_value)))) + continue; + } + else if (!strcmp(AtomName(AtomOfTerm(type)),"string")) + { + if (!Yap_unify(head, MkAtomTerm(Yap_LookupAtom(bind_value)))) + continue; + } + } + } + return TRUE; +} + + +/* Mudar esta funcao de forma a nao fazer a consulta, pois + no predicate db_sql_selet vai fazer duas vezes a mesma consutla*/ +static Int +c_db_odbc_number_of_fields_in_query(void) { + Term arg_query = Deref(ARG1); + Term arg_conn = Deref(ARG2); + Term arg_fields = Deref(ARG3); + + char *sql = AtomName(AtomOfTerm(arg_query)); + + SQLHDBC hdbc =(SQLHDBC) (IntegerOfTerm(arg_conn)); + SQLHSTMT hstmt; + SQLSMALLINT number_cols=0; + + SQLALLOCHANDLE(SQL_HANDLE_STMT, hdbc, &hstmt, + "db_number_of_fields_in_query"); + SQLEXECDIRECT(hstmt,sql,SQL_NTS, + "db_number_of_fields_in_query"); + + SQLNUMRESULTCOLS(hstmt,&number_cols, + "db_number_of_fields_in_query"); + + if (!Yap_unify(arg_fields, MkIntegerTerm(number_cols))){ + return FALSE; + } + + SQLCLOSECURSOR(hstmt,"db_number_of_fields_in_query"); + SQLFREESTMT(hstmt,SQL_CLOSE, "db_number_of_fields_in_query"); + + return TRUE; +} + +static Int +c_db_odbc_get_fields_properties(void) { + Term nome_relacao = Deref(ARG1); + Term arg_conn = Deref(ARG2); + Term fields_properties_list = Deref(ARG3); + Term head, list; + + char *relacao = AtomName(AtomOfTerm(nome_relacao)); + char sql[256]; + char name[200]; + Int i; + + + SQLSMALLINT num_fields=0; + SQLSMALLINT NullablePtr=0; + SQLSMALLINT AutoIncrementPointer=0; + SQLHSTMT hstmt,hstmt2; + SQLHDBC hdbc =(SQLHDBC) (IntegerOfTerm(arg_conn)); + + + /* LIMIT 0 -> We don't need the results of the query, + only the information about the fields of the relation*/ + sprintf (sql,"SELECT * FROM `%s` LIMIT 0",relacao); + + /*Allocate an handle for the query*/ + SQLALLOCHANDLE(SQL_HANDLE_STMT, hdbc, &hstmt, "db_get_fields_properties"); + /* Executes the query*/ + SQLEXECDIRECT(hstmt,sql,SQL_NTS, "db_get_fields_properties"); + + Functor functor = Yap_MkFunctor(Yap_LookupAtom("property"),4); + Term properties[4]; + + SQLNUMRESULTCOLS(hstmt,&num_fields, + "db_get_fields_properties"); + + list = fields_properties_list; + + SQLSMALLINT bind_prim_key; + //por causa de as rows em odbc começam em 1 :) + Short *null=malloc(sizeof(Short)*(1+num_fields)); + + SQLALLOCHANDLE(SQL_HANDLE_STMT, hdbc, &hstmt2, "db_get_fields_properties"); + /* Executes the query*/ + SQLPRIMARYKEYS(hstmt2,NULL,0,NULL,0,relacao,SQL_NTS, "db_get_fields_properties"); + /* Associates bind value for the 5 column*/ + SQLBINDCOL(hstmt2,5,SQL_C_SSHORT,&bind_prim_key,sizeof(SQLSMALLINT),NULL, + "db_get_fields_properties"); + + while(1) + { + SQLFETCH(hstmt2,"db_get_fields_properties"); + null[bind_prim_key]=1; + } + + SQLCLOSECURSOR(hstmt2,"db_get_fields_properties"); + SQLFREESTMT(hstmt2,SQL_CLOSE,"db_get_fields_properties"); + + for (i=1;i<=num_fields;i++) + { + head = HeadOfTerm(list); + name[0]='\0'; + SQLDESCRIBECOL(hstmt,i,name,200,NULL,NULL,NULL,NULL,&NullablePtr, + "db_get_fields_properties"); + + SQLCOLATTRIBUTE(hstmt,i,SQL_DESC_AUTO_UNIQUE_VALUE,NULL,0,NULL,&AutoIncrementPointer, + "db_get_fields_properties"); + + properties[0] = MkAtomTerm(Yap_LookupAtom(name)); + + + if (NullablePtr & SQL_NULLABLE) + properties[1] = MkIntegerTerm(1); //Can't be NULL + else + properties[1] = MkIntegerTerm(0); + + if (null[i] == 1) + properties[2] = MkIntegerTerm(1); //It''s a primary key + else + properties[2] = MkIntegerTerm(0); + + if (AutoIncrementPointer & SQL_TRUE) + properties[3] = MkIntegerTerm(1); //It's auto_incremented field + else + properties[3] = MkIntegerTerm(0); + + + list = TailOfTerm(list); + if (!Yap_unify(head, Yap_MkApplTerm(functor,4,properties))){ + return FALSE; + } + } + + SQLCLOSECURSOR(hstmt,"db_get_fields_properties"); + SQLFREESTMT(hstmt,SQL_CLOSE,"db_get_fields_properties"); + + return TRUE; +} + + + +void Yap_InitMYDDAS_ODBCPreds(void) +{ + /* db_connect: Host x User x Passwd x Database x Connection */ + Yap_InitCPred("c_db_odbc_connect", 4, c_db_odbc_connect, 0); + + /* db_number_of_fields: Relation x Connection x NumberOfFields */ + Yap_InitCPred("c_db_odbc_number_of_fields",3, c_db_odbc_number_of_fields, 0); + + /* db_number_of_fields_in_query: SQLQuery x Connection x NumberOfFields */ + Yap_InitCPred("c_db_odbc_number_of_fields_in_query",3, c_db_odbc_number_of_fields_in_query, 0); + + /* db_get_attributes_types: Relation x TypesList */ + Yap_InitCPred("c_db_odbc_get_attributes_types", 3, c_db_odbc_get_attributes_types, 0); + + /* db_query: SQLQuery x ResultSet x Connection */ + Yap_InitCPred("c_db_odbc_query", 5, c_db_odbc_query, 0); + + /* db_disconnect: Connection */ + Yap_InitCPred("c_db_odbc_disconnect", 1,c_db_odbc_disconnect, 0); + + /* db_get_fields_properties: PredName x Connnection x PropertiesList */ + Yap_InitCPred("c_db_odbc_get_fields_properties",3,c_db_odbc_get_fields_properties,0); + +} + + +void Yap_InitBackMYDDAS_ODBCPreds(void) +{ + + /* db_row: ResultSet x ListOfArgs */ + Yap_InitCPredBackCut("c_db_odbc_row", 3, sizeof(Int), + c_db_odbc_row, + c_db_odbc_row, + c_db_odbc_row_cut, 0); + +} + +#endif /*MYDDAS_ODBC*/ diff --git a/packages/MYDDAS/myddas_shared.c b/packages/MYDDAS/myddas_shared.c new file mode 100644 index 000000000..f35c52211 --- /dev/null +++ b/packages/MYDDAS/myddas_shared.c @@ -0,0 +1,700 @@ +/************************************************************************* +* * +* YAP Prolog * +* * +* Yap Prolog was developed at NCCUP - Universidade do Porto * +* * +* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 * +* * +************************************************************************** +* * +* File: myddas_shared.c * +* Last rev: 22/03/05 * +* mods: * +* comments: Predicates for maintaining MYDDAS * +* * +*************************************************************************/ + +#if defined MYDDAS_MYSQL || defined MYDDAS_ODBC + +#include "Yap.h" +#include "Yatom.h" +#include "cut_c.h" +#include "myddas.h" +#include +#include "myddas_structs.h" +#ifdef MYDDAS_STATS +#include "myddas_statistics.h" +#endif + +STATIC_PROTO(Int c_db_initialize_myddas,(void)); +STATIC_PROTO(Int c_db_connection_type,(void)); +STATIC_PROTO(Int c_db_add_preds,(void)); +STATIC_PROTO(Int c_db_preds_conn_start ,(void)); +STATIC_PROTO(Int c_db_preds_conn_continue ,(void)); +STATIC_PROTO(Int c_db_connection_start ,(void)); +STATIC_PROTO(Int c_db_connection_continue ,(void)); +STATIC_PROTO(Int c_db_check_if_exists_pred,(void)); +STATIC_PROTO(Int c_db_delete_predicate,(void)); +STATIC_PROTO(Int c_db_multi_queries_number,(void)); +#ifdef MYDDAS_STATS +STATIC_PROTO(Int c_db_stats,(void)); +STATIC_PROTO(Int c_db_stats_walltime,(void)); +STATIC_PROTO(Int c_db_stats_translate,(void)); +STATIC_PROTO(Int c_db_stats_time,(void)); +#endif +#ifdef DEBUG +STATIC_PROTO(Int c_db_check,(void)); +#endif + +void Yap_InitMYDDAS_SharedPreds(void) +{ + /* c_db_initialize_myddas */ + Yap_InitCPred("c_db_initialize_myddas",0,c_db_initialize_myddas, 0); + + /* c_db_connection_type: Connection x Type */ + Yap_InitCPred("c_db_connection_type",2,c_db_connection_type, 0); + + /* CORRECT THIS: db_add_preds : PredName * Arity * Connection */ + Yap_InitCPred("c_db_add_preds",4,c_db_add_preds, 0); + + /* c_db_check_if_exists_pred : PredName * Arity * Connection */ + Yap_InitCPred("c_db_check_if_exists_pred",3,c_db_check_if_exists_pred, 0); + + /* c_db_delete_pred : Module * PredName * Arity */ + Yap_InitCPred("c_db_delete_predicate",3,c_db_delete_predicate, 0); + + /* c_db_delete_pred : Module * PredName * Arity */ + Yap_InitCPred("c_db_multi_queries_number",2,c_db_multi_queries_number, 0); + +#ifdef MYDDAS_STATS + /* c_db_stats: Connection * Stats */ + Yap_InitCPred("c_db_stats",2, c_db_stats, 0); + + /* c_db_stats_walltime */ + Yap_InitCPred("c_db_stats_walltime",1, c_db_stats_walltime, 0); + + /* c_db_stats_translate */ + Yap_InitCPred("c_db_stats_translate",2,c_db_stats_translate, 0); + + /* c_db_stats_time */ + Yap_InitCPred("c_db_stats_time",2,c_db_stats_time, 0); +#endif + +#ifdef DEBUG + Yap_InitCPred("c_db_check",0, c_db_check, 0); +#endif +} + +void Yap_InitBackMYDDAS_SharedPreds(void) +{ + /* Gives all the predicates associated to a given connection */ + Yap_InitCPredBack("c_db_preds_conn", 4, sizeof(Int), + c_db_preds_conn_start, + c_db_preds_conn_continue, 0); + /* Gives all the connections stored on the MYDDAS Structure*/ + Yap_InitCPredBack("c_db_connection", 1, sizeof(Int), + c_db_connection_start, + c_db_connection_continue, 0); + + +} + +/* Initialize all of the MYDDAS global structures */ +static Int +c_db_initialize_myddas(void){ + Yap_REGS.MYDDAS_GLOBAL_POINTER = myddas_init_initialize_myddas(); +#ifdef MYDDAS_STATS + Yap_REGS.MYDDAS_GLOBAL_POINTER = myddas_stats_initialize_global_stats(Yap_REGS.MYDDAS_GLOBAL_POINTER); +#endif /* MYDDAS_STATS */ + return TRUE; +} + + +/* Gives the type of a given connection, + in other words, type will be mysql or odbc + + NOTE: In order to use this predicate, the connection*/ +/* c_db_connection_type: +Connection * ?Type */ +static Int +c_db_connection_type (void){ + Term arg_con = Deref(ARG1); + Term arg_type = Deref(ARG2); + + Int *con = (Int *) IntegerOfTerm(arg_con); + Int type = myddas_util_connection_type(con); + + if (type == 1) /* MYSQL Connection */ + Yap_unify(arg_type, MkAtomTerm(Yap_LookupAtom("mysql"))); + else if (type ==2) /* ODBC Connection */ + Yap_unify(arg_type, MkAtomTerm(Yap_LookupAtom("odbc"))); + else /* Not a valid connection*/ + return FALSE; + + return TRUE; +} + +/* db_add_preds: PredName * Arity * Module * Connection*/ +static Int +c_db_add_preds (void){ + Term arg_nome = Deref(ARG1); + Term arg_aridade = Deref(ARG2); + Term arg_module = Deref(ARG3); + Term arg_conn = Deref(ARG4); + +/* PredEntry *pe; */ +/* pe = RepPredProp(PredPropByFunc(FunctorOfTerm(arg_pred),arg_module)); */ + + + char *nome = AtomName(AtomOfTerm(arg_nome)); + char *module = AtomName(AtomOfTerm(arg_module)); + Int aridade = IntegerOfTerm(arg_aridade); + Int *conn = (Int *) IntegerOfTerm(arg_conn); + + if (myddas_util_add_predicate(nome,aridade,module,conn) == NULL) + { +#ifdef DEBUG + printf ("ERROR : Could not add Predicate: Line: %d File: %s\n",__LINE__,__FILE__); +#endif + return FALSE; + } + + return TRUE; +} + + +static Int +c_db_check_if_exists_pred (void){ + Term arg_nome = Deref(ARG1); + Term arg_aridade = Deref(ARG2); + Term arg_module = Deref(ARG3); + + + char *nome = AtomName(AtomOfTerm(arg_nome)); + char *module = AtomName(AtomOfTerm(arg_module)); + Int aridade = IntegerOfTerm(arg_aridade); + + if (myddas_util_search_predicate(nome,aridade,module) == NULL) + return FALSE; + else + return TRUE; +} + + +static Int +c_db_delete_predicate(void){ + Term arg_module = Deref(ARG1); + Term arg_name = Deref(ARG2); + Term arg_arity = Deref(ARG3); + + char *module = AtomName(AtomOfTerm(arg_module)); + char *name = AtomName(AtomOfTerm(arg_name)); + Int arity = IntegerOfTerm(arg_arity); + + MYDDAS_UTIL_PREDICATE predicate = + myddas_util_search_predicate(name,arity,module); + if (predicate == NULL) + return FALSE; + + myddas_util_delete_predicate(predicate); + + return TRUE; +} + + +static Int +c_db_multi_queries_number(void){ + Term arg_conn = Deref(ARG1); + Term arg_number = Deref(ARG2); + + Int *conn = (Int *) IntegerOfTerm(arg_conn); + MYDDAS_UTIL_CONNECTION node = + myddas_util_search_connection(conn); + + if (node == NULL) + return FALSE; + + if (IsVarTerm(arg_number)){ + Yap_unify(arg_number,MkIntegerTerm(((Int)myddas_util_get_total_multi_queries_number(node))+1)); + } + else { + Int number = IntegerOfTerm(arg_number); + number--; + myddas_util_set_total_multi_queries_number(node,number); + } + + return TRUE; + +} + +static Int +c_db_connection_start(void){ + + MYDDAS_UTIL_CONNECTION node = + Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_top_connections; + + EXTRA_CBACK_ARG(1,1)=(CELL) MkIntegerTerm((Int)node); + + return (c_db_connection_continue()); +} + +static Int +c_db_connection_continue(void){ + Term arg_conn = Deref(ARG1); + + MYDDAS_UTIL_CONNECTION node; + node = (MYDDAS_UTIL_CONNECTION) IntegerOfTerm(EXTRA_CBACK_ARG(1,1)); + + /* There is no connections */ + if (node == NULL) + { + cut_fail(); + return FALSE; + } + + Yap_unify(arg_conn, MkIntegerTerm((Int)(node->connection))); + EXTRA_CBACK_ARG(1,1)=(CELL) MkIntegerTerm((Int)(node->next)); + + return TRUE; + +} + +/* db_preds_conn : Connection(+) * Pred_name(-) * Pred_arity */ +static Int +c_db_preds_conn_start (void){ + Term arg_conn = Deref(ARG1); + + Int *conn = (Int *) IntegerOfTerm(arg_conn); + MYDDAS_UTIL_CONNECTION node = + myddas_util_search_connection(conn); + + /* Caso a ligacao já tenha sido apagada*/ + if (node == NULL) + { + cut_fail(); + return FALSE; + } + + void *pointer = myddas_util_get_list_pred(node); + EXTRA_CBACK_ARG(4,1)=(CELL) MkIntegerTerm((Int)pointer); + + return (c_db_preds_conn_continue()); +} + +/* db_preds_conn : Connection(+) * Pred_name(-) * Pred_arity*/ +static Int +c_db_preds_conn_continue (void){ + Term module = Deref(ARG2); + Term name = Deref(ARG3); + Term arity = Deref(ARG4); + + void *pointer; + pointer = (void *) IntegerOfTerm(EXTRA_CBACK_ARG(4,1)); + + if (pointer != NULL) + { + EXTRA_CBACK_ARG(4,1)=(CELL) MkIntegerTerm((Int)myddas_util_get_pred_next(pointer)); + + if (!Yap_unify(module, MkAtomTerm(Yap_LookupAtom(myddas_util_get_pred_module(pointer))))){ + return FALSE; + } + if (!Yap_unify(name,MkAtomTerm(Yap_LookupAtom(myddas_util_get_pred_name(pointer))))){ + return FALSE; + } + if (!Yap_unify(arity, MkIntegerTerm((Int)myddas_util_get_pred_arity(pointer)))){ + return FALSE; + } + return TRUE; + } + else + { + cut_fail(); + return FALSE; + } +} + + + +#ifdef DEBUG +static Int +c_db_check(void){ + check_int(); + return TRUE; +} +#endif /*DEBUG*/ + +#ifdef MYDDAS_STATS + +static Int +c_db_stats_walltime(void){ + Term arg_time = Deref(ARG1); + +#ifdef DEBUG + if (IsVarTerm(arg_time)){ +#endif + Yap_unify(arg_time,MkIntegerTerm((Int)myddas_stats_walltime())); + return TRUE; +#ifdef DEBUG + } + else{ + printf ("ERROR: c_db_stats_walltime got a variable\n"); + return FALSE; + } +#endif +} + +static Int +c_db_stats_translate(void){ + Term arg_start = Deref(ARG1); + Term arg_end = Deref(ARG2); + + MYDDAS_STATS_TIME start; + MYDDAS_STATS_TIME end; + + MYDDAS_STATS_TIME total_time,diff; + +#ifdef DEBUG + //Both args must be instanciated + if (IsNonVarTerm(arg_start) && IsNonVarTerm(arg_end)){ +#endif + start = (MYDDAS_STATS_TIME) IntegerOfTerm(arg_start); + end = (MYDDAS_STATS_TIME) IntegerOfTerm(arg_end); + + MYDDAS_STATS_GET_TRANSLATE(total_time); + + MYDDAS_STATS_INITIALIZE_TIME_STRUCT(diff,time_copy); + myddas_stats_subtract_time(diff,end,start); + + diff = myddas_stats_time_copy_to_final(diff); + myddas_stats_add_time(total_time,diff,total_time); + MyddasULInt count; + MYDDAS_STATS_GET_TRANSLATE_COUNT(count); + MYDDAS_STATS_SET_TRANSLATE_COUNT(++count); + + MYDDAS_FREE(diff,struct myddas_stats_time_struct); + MYDDAS_FREE(start, struct myddas_stats_time_struct); + MYDDAS_FREE(end, struct myddas_stats_time_struct); + + return TRUE; +#ifdef DEBUG + } + else{ + printf ("ERROR: c_db_stats_translate got a variable\n"); + return FALSE; + } +#endif +} + +static Int +c_db_stats_time(void){ + Term arg_reference = Deref(ARG1); + Term arg_time = Deref(ARG2); + + Term final_term; + + MYDDAS_STATS_STRUCT struc = (MYDDAS_STATS_STRUCT)IntegerOfTerm(arg_reference); + Functor functor_count = Yap_MkFunctor(Yap_LookupAtom("count"),1); + Term count_number[1]; + Functor unit; + Term number[1]; + + switch(struc->type){ + + case integer: + { + Functor functor = Yap_MkFunctor(Yap_LookupAtom("myddas_integer"),2); + Term integer_number[1]; + MyddasULInt integer; + + unit = Yap_MkFunctor(Yap_LookupAtom("number"),1); + integer = struc->u.integer.integer; + number[0] = MkIntegerTerm(integer); + integer_number[0] = Yap_MkApplTerm(unit,1,number);; + + count_number[0] = MkIntegerTerm(struc->count); + integer_number[1] = Yap_MkApplTerm(functor_count,1,count_number); + final_term = Yap_MkApplTerm(functor,2,integer_number); + break; + } + + case time_str: + { + MYDDAS_STATS_TIME time = struc->u.time_str.time_str; + + Functor functor = Yap_MkFunctor(Yap_LookupAtom("myddas_time"),6); + Term time_numbers[6]; + MyddasUInt time_number; + + unit = Yap_MkFunctor(Yap_LookupAtom("hours"),1); + time_number = MYDDAS_STATS_TIME_HOURS(time); + number[0] = MkIntegerTerm(time_number); + time_numbers[0] = Yap_MkApplTerm(unit,1,number);; + + unit = Yap_MkFunctor(Yap_LookupAtom("minutes"),1); + time_number = MYDDAS_STATS_TIME_MINUTES(time); + number[0] = MkIntegerTerm(time_number); + time_numbers[1] = Yap_MkApplTerm(unit,1,number);; + + unit = Yap_MkFunctor(Yap_LookupAtom("seconds"),1); + time_number = MYDDAS_STATS_TIME_SECONDS(time); + number[0] = MkIntegerTerm(time_number); + time_numbers[2] = Yap_MkApplTerm(unit,1,number);; + + unit = Yap_MkFunctor(Yap_LookupAtom("miliseconds"),1); + time_number = MYDDAS_STATS_TIME_MILISECONDS(time); + number[0] = MkIntegerTerm(time_number); + time_numbers[3] = Yap_MkApplTerm(unit,1,number);; + + unit = Yap_MkFunctor(Yap_LookupAtom("microseconds"),1); + time_number = MYDDAS_STATS_TIME_MICROSECONDS(time); + number[0] = MkIntegerTerm(time_number); + time_numbers[4] = Yap_MkApplTerm(unit,1,number);; + + count_number[0] = MkIntegerTerm(struc->count); + time_numbers[5] = Yap_MkApplTerm(functor_count,1,count_number); + final_term = Yap_MkApplTerm(functor,6,time_numbers); + break; + } + + default: +#ifdef DEBUG + printf ("ERROR: c_db_stats_time unknow option\n"); +#endif + return FALSE; + break; + } + + if (!Yap_unify(arg_time,final_term )){ + return FALSE; + } + + return TRUE; +} + +//Returns the stats of this module in a list +static Int +c_db_stats(void) { + Term arg_conn = Deref(ARG1); + Term arg_list = Deref(ARG2); + + MyddasPointer *conn = (MyddasPointer *) (IntegerOfTerm(arg_conn)); + + // TODO + if (get_myddas_top() == 0 ){ /* We want all the statistics */ + return FALSE; + } + + MYDDAS_STATS_STRUCT str; + MYDDAS_UTIL_CONNECTION + node = myddas_util_search_connection(conn); + Term head, list; + list = arg_list; + +#ifdef DEBUG + MYDDAS_STATS_TIME time = NULL; +#endif + //[Index 1] -> Total Number of Rows by connection + //Total number of Rows returned by the server + //WARNING: only works with store_result + head = HeadOfTerm(list); + list = TailOfTerm(list); + str = myddas_stats_get_stat(node->stats,5); + Yap_unify(head, MkIntegerTerm((MyddasInt)str)); +#ifdef DEBUG + MyddasUInt number = 0; + + MYDDAS_STATS_CON_GET_TOTAL_ROWS(node,number); + printf ("Total Number of Rows returned from the Server\n"); + printf ("%lu\n\n",(unsigned long)number); +#endif + + //[Index 2] -> Total of Time Spent by the DB Server + // processing all the SQL Querys + head = HeadOfTerm(list); + list = TailOfTerm(list); + + str = myddas_stats_get_stat(node->stats,1); + Yap_unify(head, MkIntegerTerm((MyddasInt)str)); +#ifdef DEBUG + MYDDAS_STATS_CON_GET_TOTAL_TIME_DBSERVER(node,time); + printf ("Reference to time Spent by the Server, on all the SQL Querys\n"); + MYDDAS_STATS_PRINT_TIME_STRUCT(time); + printf ("\n\n"); +#endif + + //[Index 3] -> Total of Time Spent by the DB Server + // processing a the last SQL Query + head = HeadOfTerm(list); + list = TailOfTerm(list); + + str = myddas_stats_get_stat(node->stats,2); + Yap_unify(head, MkIntegerTerm((MyddasInt)str)); +#ifdef DEBUG + MYDDAS_STATS_CON_GET_LAST_TIME_DBSERVER(node,time); + printf ("Reference to time Spent by the Server, on the last SQL Query\n"); + MYDDAS_STATS_PRINT_TIME_STRUCT(time); + printf ("\n\n"); +#endif + + //[Index 4] -> Total of Time Spent by the DB Server + // transfering all the results of the SQL Querys + head = HeadOfTerm(list); + list = TailOfTerm(list); + + str = myddas_stats_get_stat(node->stats,3); + Yap_unify(head, MkIntegerTerm((MyddasInt)str)); +#ifdef DEBUG + MYDDAS_STATS_CON_GET_TOTAL_TIME_TRANSFERING(node,time); + printf ("Refence to time Spent by the Server, transfering all the results SQL Query\n"); + MYDDAS_STATS_PRINT_TIME_STRUCT(time); + printf ("\n\n"); +#endif + + //[Index 5] -> Total of Time Spent by the DB Server + // transfering the result of the last SQL Query + head = HeadOfTerm(list); + list = TailOfTerm(list); + + str = myddas_stats_get_stat(node->stats,4); + Yap_unify(head, MkIntegerTerm((MyddasInt)str)); +#ifdef DEBUG + MYDDAS_STATS_CON_GET_LAST_TIME_TRANSFERING(node,time); + printf ("Reference to time Spent by the Server, transfering the result of the last SQL Query\n"); + MYDDAS_STATS_PRINT_TIME_STRUCT(time); + printf ("\n\n"); +#endif + + //[Index 6] -> Total of Time Spent by the + // db_row_function + head = HeadOfTerm(list); + list = TailOfTerm(list); + + str = myddas_stats_get_stat(Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_statistics->stats,1); + + Yap_unify(head, MkIntegerTerm((MyddasInt)str)); +#ifdef DEBUG + MYDDAS_STATS_GET_DB_ROW_FUNCTION(time); + printf ("Reference to time Spent by the db_row_function\n"); + MYDDAS_STATS_PRINT_TIME_STRUCT(time); + printf ("\n\n"); +#endif + + //[Index 7] -> Total of Bytes Transfered by the + // DB Server on all SQL Querys + head = HeadOfTerm(list); + list = TailOfTerm(list); + + str = myddas_stats_get_stat(node->stats,6); + Yap_unify(head, MkIntegerTerm((MyddasPointer)str)); +#ifdef DEBUG + MYDDAS_STATS_CON_GET_TOTAL_BYTES_TRANSFERING_FROM_DBSERVER(node,number); + printf ("Bytes Transfered by the DB Server from all querys\n"); + printf ("%llu\n\n",(MyddasULInt)number); +#endif + + //[Index 8] -> Total of Bytes Transfered by the + // DB Server on the last SQL Query + head = HeadOfTerm(list); + list = TailOfTerm(list); + + str = myddas_stats_get_stat(node->stats,7); + Yap_unify(head, MkIntegerTerm((MyddasPointer)str)); +#ifdef DEBUG + MYDDAS_STATS_CON_GET_LAST_BYTES_TRANSFERING_FROM_DBSERVER(node,number); + printf ("Bytes Transfered by the DB Server on the last query\n"); + printf ("%llu\n\n",(MyddasULInt)number); +#endif + //[Index 9] -> Number of querys made to the DBserver + head = HeadOfTerm(list); + list = TailOfTerm(list); + + str = myddas_stats_get_stat(node->stats,8); + Yap_unify(head, MkIntegerTerm((MyddasPointer)str)); +#ifdef DEBUG + MYDDAS_STATS_CON_GET_NUMBER_QUERIES_MADE(node,number); + printf ("Number of Querys made to the server\n"); + printf ("%llu\n\n",(MyddasULInt)number); +#endif + + //[Index 10] -> Total of Time Spent by the + // translate predicate + head = HeadOfTerm(list); + list = TailOfTerm(list); + + str = myddas_stats_get_stat(Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_statistics->stats,2); + Yap_unify(head, MkIntegerTerm((Int)str)); + +#ifdef DEBUG + MYDDAS_STATS_GET_TRANSLATE(time); + printf ("Reference to time Spent by the translate predicate\n"); + MYDDAS_STATS_PRINT_TIME_STRUCT(time); + printf ("\n\n"); +#endif + + /* Memory management */ +#ifdef DEBUG + MyddasULInt nr; + MYDDAS_MEMORY_MALLOC_NR(nr); + printf ("Number of times malloc was called in MYDDAS: %lu \n",nr); + MYDDAS_MEMORY_FREE_NR(nr); + printf ("Number of times free was called in MYDDAS : %lu \n",nr); + + MYDDAS_MEMORY_MALLOC_SIZE(nr); + printf ("Total memory allocated in MYDDAS: %lu \n",nr); + MYDDAS_MEMORY_FREE_SIZE(nr); + printf ("Total memory freed in MYDDAS : %lu \n",nr); +#endif + + return TRUE; +} + +#endif /* MYDDAS_STATS */ + + +/* Function to delete all the temporary tables */ +/* from the mysql server */ +void Yap_MYDDAS_delete_all_myddas_structs(void) +{ + + /* NAO ESQUECER DE FAZER ISTO TB PARA O DB_CLOSE*/ + MYDDAS_GLOBAL global = + Yap_REGS.MYDDAS_GLOBAL_POINTER; + + /* In case that the MYDDAS module isn't loaded */ + if (global == NULL) + return; + + MYDDAS_UTIL_CONNECTION connections = + global->myddas_top_connections; + + /* Delete all connections */ + for(;connections!=NULL;connections=connections->next) + myddas_util_delete_connection(connections->connection); + +#ifdef MYDDAS_STATS + myddas_stats_delete_stats_list(global->myddas_statistics->stats); + MYDDAS_FREE(global->myddas_statistics,struct myddas_global_stats); +#endif + + MYDDAS_FREE(global,struct myddas_global); + +#ifdef DEBUG + MyddasULInt nr; + MYDDAS_MEMORY_MALLOC_NR(nr); + printf ("Number of times malloc was called in MYDDAS: %lu \n",nr); + MYDDAS_MEMORY_FREE_NR(nr); + printf ("Number of times free was called in MYDDAS : %lu \n",nr); + + MYDDAS_MEMORY_MALLOC_SIZE(nr); + printf ("Total memory allocated in MYDDAS: %lu \n",nr); + MYDDAS_MEMORY_FREE_SIZE(nr); + printf ("Total memory freed in MYDDAS : %lu \n",nr); +#endif + +} + + + + + +#endif /*CUT_C && (MYDDAS_MYSQL || MYDDAS_ODBC)*/ diff --git a/packages/MYDDAS/myddas_statistics.c b/packages/MYDDAS/myddas_statistics.c new file mode 100644 index 000000000..2269d0812 --- /dev/null +++ b/packages/MYDDAS/myddas_statistics.c @@ -0,0 +1,356 @@ +#include "myddas_structs.h" +#include "myddas_statistics.h" +#include "Yap.h" +#include +#include + +#if defined MYDDAS_STATS + + + +/* Documentation: Time Units +------------------------------------------------------------------------ +*****| Second(s) | MiliSeconds(ms) | MicroSeconds(us) | NanoSecond(ns) | +-----|-----------|-----------------|------------------|----------------| + s | 1 | 0.001 | 0.000001 | 1e-9 | + ms | 1000 | 1 | 0.001 | 0.000001 | + us | 10000000 | 1000 | 1 | 0.001 | + ns |1000000000 | 1000000 | 1000 | 1 | +------------------------------------------------------------------------ + +------ + +The struct timeval structure represents an elapsed time. It is +declared in `sys/time.h' and has the following members: + +long int tv_sec -> This represents the number of whole seconds of + elapsed time. + +long int tv_usec -> This is the rest of the elapsed time (a fraction + of a second), represented as the number of microseconds. It is + always less than one million. + + +------ + +The struct timespec structure represents an elapsed time. It is +declared in `time.h' and has the following members: + +long int tv_sec -> This represents the number of whole seconds of + elapsed time. + +long int tv_nsec -> This is the rest of the elapsed time (a fraction + of a second), represented as the number of nanoseconds. It is + always less than one billion. + +----- + + The gettimeofday() function shall obtain the current time, + expressed as seconds and microseconds since the Epoch, and store + it in the timeval structure pointed to by tp. The resolution of + the system clock is unspecified. + + If tzp is not a null pointer, the behavior is unspecified. + +*/ + +static void +myddas_stats_time_subtract (unsigned long *, unsigned long *, MYDDAS_STATS_TIME, MYDDAS_STATS_TIME); +static void +myddas_stats_add_seconds_time(MYDDAS_STATS_TIME,unsigned long, unsigned long); +static void +myddas_stats_integrity_of_time(MYDDAS_STATS_TIME); + +/* Be shore to delete MYDDAS_STATS_TIME structure */ +MYDDAS_STATS_TIME +myddas_stats_walltime(void) { + + MYDDAS_STATS_TIME myddas_time = NULL; + MYDDAS_MALLOC(myddas_time,struct myddas_stats_time_struct); + myddas_time->type = time_copy; + + struct timeval *time = NULL; + MYDDAS_MALLOC(time,struct timeval); + + gettimeofday(time,NULL); + + myddas_time->u.time_copy.tv_sec = time->tv_sec; + myddas_time->u.time_copy.tv_usec = time->tv_usec; + + MYDDAS_FREE(time,struct timeval); + + return myddas_time; +} + +void +myddas_stats_add_time(MYDDAS_STATS_TIME sum, MYDDAS_STATS_TIME time1,MYDDAS_STATS_TIME time2){ + + if (sum->type == time_final){ + sum->u.time_final.microseconds = + time1->u.time_final.microseconds + + time2->u.time_final.microseconds; + sum->u.time_final.miliseconds = + time1->u.time_final.miliseconds + + time2->u.time_final.miliseconds; + sum->u.time_final.seconds = + time1->u.time_final.seconds + + time2->u.time_final.seconds; + sum->u.time_final.minutes = + time1->u.time_final.minutes + + time2->u.time_final.minutes; + sum->u.time_final.hours = + time1->u.time_final.hours + + time2->u.time_final.hours; + } else { + sum->u.time_copy.tv_sec = + time1->u.time_copy.tv_sec + + time2->u.time_copy.tv_sec; + sum->u.time_copy.tv_usec = + time1->u.time_copy.tv_usec + + time2->u.time_copy.tv_usec; + } + + myddas_stats_integrity_of_time(sum); +} + + +void +myddas_stats_subtract_time(MYDDAS_STATS_TIME result, MYDDAS_STATS_TIME t1,MYDDAS_STATS_TIME t2){ + + if (result->type == time_copy){ + + unsigned long sec; + unsigned long usec; + myddas_stats_time_subtract(&sec,&usec,t1,t2); + + result->u.time_copy.tv_sec = sec; + result->u.time_copy.tv_usec = usec; + + } else { + + } + +} + +void +myddas_stats_move_time(MYDDAS_STATS_TIME from, + MYDDAS_STATS_TIME to) +{ + if (from->type == time_copy) + { + to->type = time_copy; + to->u.time_copy.tv_sec = from->u.time_copy.tv_sec; + to->u.time_copy.tv_usec = from->u.time_copy.tv_usec; + } + else if (from->type == time_final) + { + to->u.time_final.hours = from->u.time_final.hours; + to->u.time_final.minutes = from->u.time_final.minutes; + to->u.time_final.seconds = from->u.time_final.seconds; + to->u.time_final.miliseconds = from->u.time_final.miliseconds; + to->u.time_final.microseconds = from->u.time_final.microseconds; + } + MYDDAS_FREE(from,struct myddas_stats_time_struct); +} + +MYDDAS_STATS_TIME +myddas_stats_time_copy_to_final(MYDDAS_STATS_TIME t_copy){ + + MYDDAS_STATS_TIME t_final; + MYDDAS_STATS_INITIALIZE_TIME_STRUCT(t_final,time_final); + + myddas_stats_add_seconds_time(t_final, + t_copy->u.time_copy.tv_sec, + t_copy->u.time_copy.tv_usec); + + MYDDAS_FREE(t_copy,struct myddas_stats_time_struct); + return t_final; +} + +static void +myddas_stats_add_seconds_time(MYDDAS_STATS_TIME myddas_time, + unsigned long sec, + unsigned long usec){ + + short hours = sec / 3600; + sec %= 3600; + short minutes = sec / 60; + sec %= 60; + short milisec = usec / 1000; + usec %= 1000; + + myddas_time->u.time_final.microseconds += usec ; + myddas_time->u.time_final.miliseconds += milisec; + myddas_time->u.time_final.seconds += sec ; + myddas_time->u.time_final.minutes += minutes ; + myddas_time->u.time_final.hours += hours; + + myddas_stats_integrity_of_time(myddas_time); +} + + +static void +myddas_stats_time_subtract(unsigned long *sec,unsigned long *usec, + MYDDAS_STATS_TIME start, MYDDAS_STATS_TIME end){ + + /* Perform the carry for the later subtraction by updating y. */ + if (start->u.time_copy.tv_usec < end->u.time_copy.tv_usec) { + int nsec = (end->u.time_copy.tv_usec - start->u.time_copy.tv_usec) / 1000000 + 1; + end->u.time_copy.tv_usec -= 1000000 * nsec; + end->u.time_copy.tv_sec += nsec; + } + if (start->u.time_copy.tv_usec - end->u.time_copy.tv_usec > 1000000) { + int nsec = (start->u.time_copy.tv_usec - end->u.time_copy.tv_usec) / 1000000; + end->u.time_copy.tv_usec += 1000000 * nsec; + end->u.time_copy.tv_sec -= nsec; + } + + /* Compute the time remaining to wait. + tv_usec is certainly positive. */ + *sec = start->u.time_copy.tv_sec - end->u.time_copy.tv_sec; + *usec = start->u.time_copy.tv_usec - end->u.time_copy.tv_usec; +} + +static void +myddas_stats_integrity_of_time(MYDDAS_STATS_TIME myddas_time){ + + if (myddas_time->u.time_final.microseconds > 999) + { + myddas_time->u.time_final.microseconds -= 1000; + myddas_time->u.time_final.miliseconds++; + } + if (myddas_time->u.time_final.miliseconds > 999) + { + myddas_time->u.time_final.miliseconds -= 1000; + myddas_time->u.time_final.seconds++; + } + + if (myddas_time->u.time_final.seconds > 59) + { + myddas_time->u.time_final.seconds -= 60; + myddas_time->u.time_final.minutes++; + } + + if (myddas_time->u.time_final.minutes > 59) + { + myddas_time->u.time_final.minutes -= 60; + myddas_time->u.time_final.hours++; + } +} + +MYDDAS_GLOBAL +myddas_stats_initialize_global_stats(MYDDAS_GLOBAL global){ + + MYDDAS_STATS_STRUCT stats = NULL; + + short i; + + /* For the time statistics */ + /* + Stats [1] - Total Time spent on the db_row function + Stats [2] - Total Time spent on the translate/3 predicate + */ + + /* First */ + stats = myddas_stats_initialize_stat(stats,time_str); + (global->myddas_statistics)->stats = stats; + for(i=0;i<1;i++){ + myddas_stats_initialize_stat(stats,time_str); + } + + return global; +} + +MYDDAS_STATS_STRUCT +myddas_stats_initialize_connection_stats(){ + /* + Stats [1] - Total of Time Spent by the DB Server processing all the SQL Querys + Stats [2] - Total of Time Spent by the DB Server processing the last SQL Query + Stats [3] - Total of Time Spent by the DB Server transfering all the results of the SQL Querys + Stats [4] - Total of Time Spent by the DB Server transfering the result of the last SQL Query + + Stats [5] - Total number of Rows returned by the server + Stats [6] - Total of Bytes Transfered by the DB Server on all SQL Querys + Stats [7] - Total of Bytes Transfered by the DB Server on the last SQL Query + Stats [8] - Number of querys made to the DBserver + */ + + short i; + MYDDAS_STATS_STRUCT new = NULL ; + MYDDAS_STATS_STRUCT first; + /* For the time statistics */ + + /* First */ + new = myddas_stats_initialize_stat(new,time_str); + first = new; + for(i=0;i<3;i++){ + new = myddas_stats_initialize_stat(new,time_str); + } + + /* For number statistics*/ + for (i=0;i<4;i++){ + new = myddas_stats_initialize_stat(new,integer); + } + + return first; +} + +MYDDAS_STATS_STRUCT +myddas_stats_initialize_stat(MYDDAS_STATS_STRUCT stat,int type){ + + MYDDAS_STATS_STRUCT temp_str = stat; + + if (stat == NULL){ + MYDDAS_MALLOC(stat,struct myddas_stats_struct); + temp_str = stat; + } else { + for (;temp_str->nxt != NULL;temp_str = temp_str->nxt); + MYDDAS_MALLOC(temp_str->nxt,struct myddas_stats_struct); + temp_str = temp_str->nxt; + } + + if (type == time_str){ + MYDDAS_STATS_INITIALIZE_TIME_STRUCT(temp_str->u.time_str.time_str,time_final); + } else { + temp_str->u.integer.integer = 0; + } + temp_str->type = type; + temp_str->count = 0; + temp_str->nxt = NULL; + return temp_str; +} + +MYDDAS_STATS_STRUCT +myddas_stats_get_stat(MYDDAS_STATS_STRUCT stat,int index){ + + MYDDAS_STATS_STRUCT temp = stat; + + for (;index>1;index--){ + temp = temp->nxt; + } + return temp; +} + +void +myddas_stats_delete_stats_list(MYDDAS_STATS_STRUCT list){ + + MYDDAS_STATS_STRUCT to_delete = list; + + for (;to_delete!=NULL;){ + list = list->nxt; + + + if (to_delete->type == time_str){ + MYDDAS_FREE(to_delete->u.time_str.time_str,struct myddas_stats_time_struct); + } + + MYDDAS_FREE(to_delete,struct myddas_stats_struct); + + to_delete = list; + } + +} + + +#endif /* MYDDAS_STATS || MYDDAS_TOP_LEVEL */ + diff --git a/packages/MYDDAS/myddas_statistics.h b/packages/MYDDAS/myddas_statistics.h new file mode 100644 index 000000000..a4a0a1591 --- /dev/null +++ b/packages/MYDDAS/myddas_statistics.h @@ -0,0 +1,135 @@ +#ifndef __MYDDAS_STATISTICS_H__ +#define __MYDDAS_STATISTICS_H__ + +#ifdef MYDDAS_STATS + +#define MYDDAS_STATS_TIME_HOURS(TIME) TIME->u.time_final.hours; +#define MYDDAS_STATS_TIME_MINUTES(TIME) TIME->u.time_final.minutes; +#define MYDDAS_STATS_TIME_SECONDS(TIME) TIME->u.time_final.seconds; +#define MYDDAS_STATS_TIME_MILISECONDS(TIME) TIME->u.time_final.miliseconds; +#define MYDDAS_STATS_TIME_MICROSECONDS(TIME) TIME->u.time_final.microseconds; + +#ifdef DEBUG +#define MYDDAS_STATS_PRINT_TIME_STRUCT(TIME) \ + if (TIME->type == time_final) { \ + printf ("%d Hours, %d Minutes, %d Seconds, %d Miliseconds, %d Microseconds", \ + TIME->u.time_final.hours, \ + TIME->u.time_final.minutes, \ + TIME->u.time_final.seconds, \ + TIME->u.time_final.miliseconds, \ + TIME->u.time_final.microseconds); \ + } else { \ + printf ("%lu Seconds, %lu Microseconds", \ + TIME->u.time_copy.tv_sec, \ + TIME->u.time_copy.tv_usec); \ + } +#endif + +#define MYDDAS_STATS_INITIALIZE_TIME_STRUCT(TIME,TYPE) \ + MYDDAS_MALLOC(TIME,struct myddas_stats_time_struct); \ + \ + if (TYPE == time_copy){ \ + TIME->type = TYPE; \ + TIME->u.time_copy.tv_sec = 0; \ + TIME->u.time_copy.tv_usec = 0; \ + } else { \ + TIME->type = TYPE; \ + TIME->u.time_final.hours = 0; \ + TIME->u.time_final.minutes = 0; \ + TIME->u.time_final.seconds = 0; \ + TIME->u.time_final.miliseconds = 0; \ + TIME->u.time_final.microseconds = 0; \ + } + +#define MYDDAS_STATS_CON_GET_TOTAL_TIME_DBSERVER(NODE,TIME) \ + TIME = myddas_stats_get_stat(NODE->stats,1)->u.time_str.time_str; +#define MYDDAS_STATS_CON_GET_TOTAL_TIME_DBSERVER_COUNT(NODE,COUNT) \ + COUNT = myddas_stats_get_stat(NODE->stats,1)->count; +#define MYDDAS_STATS_CON_SET_TOTAL_TIME_DBSERVER_COUNT(NODE,COUNT) \ + myddas_stats_get_stat(NODE->stats,1)->count = COUNT; + +#define MYDDAS_STATS_CON_GET_LAST_TIME_DBSERVER(NODE,TIME) \ + TIME = myddas_stats_get_stat(NODE->stats,2)->u.time_str.time_str; +#define MYDDAS_STATS_CON_GET_LAST_TIME_DBSERVER_COUNT(NODE,COUNT) \ + COUNT = myddas_stats_get_stat(NODE->stats,2)->count; +#define MYDDAS_STATS_CON_SET_LAST_TIME_DBSERVER_COUNT(NODE,COUNT) \ + myddas_stats_get_stat(NODE->stats,2)->count = COUNT; + +#define MYDDAS_STATS_CON_GET_TOTAL_TIME_TRANSFERING(NODE,TIME) \ + TIME = myddas_stats_get_stat(NODE->stats,3)->u.time_str.time_str; +#define MYDDAS_STATS_CON_GET_TOTAL_TIME_TRANSFERING_COUNT(NODE,COUNT) \ + COUNT = myddas_stats_get_stat(NODE->stats,3)->count; +#define MYDDAS_STATS_CON_SET_TOTAL_TIME_TRANSFERING_COUNT(NODE,COUNT) \ + myddas_stats_get_stat(NODE->stats,3)->count = COUNT; + +#define MYDDAS_STATS_CON_GET_LAST_TIME_TRANSFERING(NODE,TIME) \ + TIME = myddas_stats_get_stat(NODE->stats,4)->u.time_str.time_str; +#define MYDDAS_STATS_CON_GET_LAST_TIME_TRANSFERING_COUNT(NODE,COUNT) \ + COUNT = myddas_stats_get_stat(NODE->stats,4)->count; +#define MYDDAS_STATS_CON_SET_LAST_TIME_TRANSFERING_COUNT(NODE,COUNT) \ + myddas_stats_get_stat(NODE->stats,4)->count = COUNT; + + +#define MYDDAS_STATS_CON_GET_TOTAL_ROWS(NODE,NUMBER) \ + NUMBER = myddas_stats_get_stat(NODE->stats,5)->u.integer.integer; +#define MYDDAS_STATS_CON_SET_TOTAL_ROWS(NODE,NUMBER) \ + myddas_stats_get_stat(NODE->stats,5)->u.integer.integer = NUMBER; +#define MYDDAS_STATS_CON_GET_TOTAL_ROWS_COUNT(NODE,COUNT) \ + COUNT = myddas_stats_get_stat(NODE->stats,5)->count; +#define MYDDAS_STATS_CON_SET_TOTAL_ROWS_COUNT(NODE,COUNT) \ + myddas_stats_get_stat(NODE->stats,5)->count = COUNT; + + +#define MYDDAS_STATS_CON_GET_TOTAL_BYTES_TRANSFERING_FROM_DBSERVER(NODE,NUMBER) \ + NUMBER = myddas_stats_get_stat(NODE->stats,6)->u.integer.integer; +#define MYDDAS_STATS_CON_SET_TOTAL_BYTES_TRANSFERING_FROM_DBSERVER(NODE,NUMBER) \ + myddas_stats_get_stat(NODE->stats,6)->u.integer.integer = NUMBER; +#define MYDDAS_STATS_CON_GET_TOTAL_BYTES_TRANSFERING_FROM_DBSERVER_COUNT(NODE,COUNT) \ + COUNT = myddas_stats_get_stat(NODE->stats,6)->count; +#define MYDDAS_STATS_CON_SET_TOTAL_BYTES_TRANSFERING_FROM_DBSERVER_COUNT(NODE,COUNT) \ + myddas_stats_get_stat(NODE->stats,6)->count = COUNT; + +#define MYDDAS_STATS_CON_GET_LAST_BYTES_TRANSFERING_FROM_DBSERVER(NODE,NUMBER) \ + NUMBER = myddas_stats_get_stat(NODE->stats,7)->u.integer.integer; +#define MYDDAS_STATS_CON_SET_LAST_BYTES_TRANSFERING_FROM_DBSERVER(NODE,NUMBER) \ + myddas_stats_get_stat(NODE->stats,7)->u.integer.integer = NUMBER; +#define MYDDAS_STATS_CON_GET_LAST_BYTES_TRANSFERING_FROM_DBSERVER_COUNT(NODE,COUNT) \ + COUNT = myddas_stats_get_stat(NODE->stats,7)->count; +#define MYDDAS_STATS_CON_SET_LAST_BYTES_TRANSFERING_FROM_DBSERVER_COUNT(NODE,COUNT) \ + myddas_stats_get_stat(NODE->stats,7)->count = COUNT; + +#define MYDDAS_STATS_CON_GET_NUMBER_QUERIES_MADE(NODE,NUMBER) \ + NUMBER = myddas_stats_get_stat(NODE->stats,8)->u.integer.integer; +#define MYDDAS_STATS_CON_SET_NUMBER_QUERIES_MADE(NODE,NUMBER) \ + myddas_stats_get_stat(NODE->stats,8)->u.integer.integer = NUMBER; +#define MYDDAS_STATS_CON_GET_NUMBER_QUERIES_MADE_COUNT(NODE,COUNT) \ + COUNT = myddas_stats_get_stat(NODE->stats,8)->count; +#define MYDDAS_STATS_CON_SET_NUMBER_QUERIES_MADE_COUNT(NODE,COUNT) \ + myddas_stats_get_stat(NODE->stats,8)->count = COUNT; + +#define MYDDAS_STATS_GET_DB_ROW_FUNCTION(TIME) \ + TIME = myddas_stats_get_stat(Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_statistics->stats,1)->u.time_str.time_str; +#define MYDDAS_STATS_GET_DB_ROW_FUNCTION_COUNT(COUNT) \ + COUNT = myddas_stats_get_stat(Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_statistics->stats,1)->count; +#define MYDDAS_STATS_SET_DB_ROW_FUNCTION_COUNT(COUNT) \ + myddas_stats_get_stat(Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_statistics->stats,1)->count = COUNT; + +#define MYDDAS_STATS_GET_TRANSLATE(TIME) \ + TIME = myddas_stats_get_stat(Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_statistics->stats,2)->u.time_str.time_str; +#define MYDDAS_STATS_GET_TRANSLATE_COUNT(COUNT) \ + COUNT = myddas_stats_get_stat(Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_statistics->stats,2)->count; +#define MYDDAS_STATS_SET_TRANSLATE_COUNT(COUNT) \ + myddas_stats_get_stat(Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_statistics->stats,2)->count = COUNT; + +MYDDAS_STATS_TIME myddas_stats_walltime(void); +void myddas_stats_add_time(MYDDAS_STATS_TIME, MYDDAS_STATS_TIME,MYDDAS_STATS_TIME); +void myddas_stats_subtract_time(MYDDAS_STATS_TIME, MYDDAS_STATS_TIME,MYDDAS_STATS_TIME); +void myddas_stats_move_time(MYDDAS_STATS_TIME,MYDDAS_STATS_TIME); +MYDDAS_STATS_TIME myddas_stats_time_copy_to_final(MYDDAS_STATS_TIME); + +/* Related to the statistics linked list */ +MYDDAS_STATS_STRUCT myddas_stats_initialize_stat(MYDDAS_STATS_STRUCT,int); +MYDDAS_STATS_STRUCT myddas_stats_get_stat(MYDDAS_STATS_STRUCT,int); +#endif /* MYDDAS_STATS */ + +#endif diff --git a/packages/MYDDAS/myddas_statistics_structs.h b/packages/MYDDAS/myddas_statistics_structs.h new file mode 100644 index 000000000..45da12996 --- /dev/null +++ b/packages/MYDDAS/myddas_statistics_structs.h @@ -0,0 +1,50 @@ +#ifndef __MYDDAS_STATISTICS_STRUCTS_H__ +#define __MYDDAS_STATISTICS_STRUCTS_H__ + +#ifdef MYDDAS_STATS + +/* This strucuture holds some global statistics*/ +struct myddas_global_stats { + MYDDAS_STATS_STRUCT stats; +}; + +/* Structure to hold any kind of statistics */ +struct myddas_stats_struct{ + enum {time_str, + integer} type; + union { + struct { + MYDDAS_STATS_TIME time_str; + } time_str; + struct { + MyddasULInt integer; + } integer; + } u; + MyddasULInt count; + MYDDAS_STATS_STRUCT nxt; +}; + +/* Time structure for the MYDDAS Interface */ +struct myddas_stats_time_struct{ + enum {time_copy, + time_final} type; + + union { + struct { + unsigned long tv_sec; + unsigned long tv_usec; + } time_copy; + struct { + MyddasUSInt hours; + MyddasUSInt minutes; //Max 59 + MyddasUSInt seconds; //Max 59 + MyddasUSInt miliseconds; //Max 999 + MyddasUSInt microseconds; //Max 999 + } time_final; + } u; +}; + + +#endif /* MYDDAS_STATS */ + +#endif diff --git a/packages/MYDDAS/myddas_structs.h b/packages/MYDDAS/myddas_structs.h new file mode 100644 index 000000000..1fc81e2a8 --- /dev/null +++ b/packages/MYDDAS/myddas_structs.h @@ -0,0 +1,67 @@ +#ifndef __MYDDAS_STRUCTS_H__ +#define __MYDDAS_STRUCTS_H__ + +#include "myddas.h" +#ifdef MYDDAS_STATS +#include "myddas_statistics_structs.h" +#endif + +struct myddas_global { + MYDDAS_UTIL_CONNECTION myddas_top_connections; +#ifdef MYDDAS_TOP_LEVEL + MYDDAS_UTIL_CONNECTION myddas_top_level_connection; +#endif +#ifdef MYDDAS_STATS + MYDDAS_GLOBAL_STATS myddas_statistics; +#endif +#ifdef DEBUG + /* Number times malloc was called */ + MyddasULInt malloc_called; + /* Memory allocated by MYDDAS */ + MyddasULInt memory_allocated; + + /* Number times free was called */ + MyddasULInt free_called; + /* Memory freed by MYDDAS */ + MyddasULInt memory_freed; +#endif +}; + +struct myddas_list_preds { + char *pred_module; + char *pred_name; + short pred_arity; + //void *pe; + MYDDAS_UTIL_PREDICATE next; + MYDDAS_UTIL_PREDICATE previous; +}; + +struct myddas_list_connection { + void *connection; + + /*If variable env is NULL, then it's a + MySQL connection, if not then it as the pointer + to the ODBC enviromment variable */ + void *odbc_enviromment; + +#ifdef MYDDAS_STATS + MYDDAS_STATS_STRUCT stats; +#endif + MYDDAS_UTIL_PREDICATE predicates; + + /* Multi Queries Section */ + unsigned long total_number_queries; + unsigned long actual_number_queries; + MYDDAS_UTIL_QUERY *queries; + + /* List Integrety */ + MYDDAS_UTIL_CONNECTION next; + MYDDAS_UTIL_CONNECTION previous; +}; + +struct myddas_util_query{ + char *query; + MYDDAS_UTIL_QUERY next; +}; + +#endif diff --git a/packages/MYDDAS/myddas_top_level.c b/packages/MYDDAS/myddas_top_level.c new file mode 100644 index 000000000..588ec106d --- /dev/null +++ b/packages/MYDDAS/myddas_top_level.c @@ -0,0 +1,93 @@ +/************************************************************************* +* * +* YAP Prolog * +* * +* Yap Prolog was developed at NCCUP - Universidade do Porto * +* * +* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-1997 * +* * +************************************************************************** +* * +* File: myddas_top_level.c * +* Last rev: 27/01/06 * +* mods: * +* comments: Top Level of the MYDDAS Interface * +* * +*************************************************************************/ + +#if defined MYDDAS_TOP_LEVEL && defined MYDDAS_MYSQL + +#include "Yap.h" +#include "Yatom.h" +#include "myddas.h" +#include "myddas_structs.h" +#include "myddas_statistics.h" +#include +#include +#include +#include + +#if defined HAVE_LIBREADLINE +#include +#include +#endif +#include + + +STATIC_PROTO(Int c_db_tl_readline,(void)); + + +void Yap_InitMYDDAS_TopLevelPreds(void) +{ + /* c_db_readline: +Prompt x -Line */ + Yap_InitCPred("c_db_tl_readline", 2, c_db_tl_readline, SafePredFlag|SyncPredFlag|HiddenPredFlag); + +} + + +typedef struct { + const char *name; /* User printable name of the function. */ + char cmd_char; /* msql command character */ + Int (*func)(char *str,char *); /* Function to call to do the job. */ + //bool takes_params; /* Max parameters for command */ + const char *doc; /* Documentation for this function. */ +} COMMANDS; + + +static Int +c_db_tl_readline(void) { + Term arg_prompt = Deref(ARG1); + Term arg_line = Deref(ARG2); + + char *prompt = AtomName(AtomOfTerm(arg_prompt)); + char *line; + + while (strlen(line = readline(prompt)) == 0) { + free(line); + } + add_history(line); + + Term line_read = MkAtomTerm(Yap_LookupAtom(line)); + free(line); + + if (!Yap_unify(arg_line,line_read)) + return FALSE; + return TRUE; + +} + +static void +myddas_top_level_print_time(MYDDAS_STATS_TIME time){ + + //TODO test for big queries, and see the output of mysql + printf("("); + + printf("%d",time->u.time_final.seconds); + //MiliSeconds 2 decimal points + printf(".%d",time->u.time_final.miliseconds/10); + printf (" sec)"); +} + +#endif + + diff --git a/packages/MYDDAS/myddas_util.c b/packages/MYDDAS/myddas_util.c new file mode 100755 index 000000000..3d482a55c --- /dev/null +++ b/packages/MYDDAS/myddas_util.c @@ -0,0 +1,399 @@ +#if defined MYDDAS_ODBC || defined MYDDAS_MYSQL + +#include "Yap.h" +#include +#include +#include "cut_c.h" +#include "myddas.h" +#include "myddas_structs.h" +#ifdef MYDDAS_STATS +#include "myddas_statistics.h" +#endif +#ifdef MYDDAS_ODBC +#include +#endif /*MYDDAS_ODBC*/ +#ifdef MYDDAS_MYSQL +#include +#endif /*MYDDAS_MYSQL*/ + + + +/* Search for the predicate in the given predicate list*/ +static MYDDAS_UTIL_PREDICATE +myddas_util_find_predicate(char *, Int , char *, MYDDAS_UTIL_PREDICATE); +/* Deletes a predicate list */ +static void +myddas_util_delete_predicate_list(MYDDAS_UTIL_PREDICATE); + +/* Prints a error message */ +static void +myddas_util_error_message(char *,Int,char *); + + +#ifdef MYDDAS_MYSQL +/* Auxilary function to table_write*/ +static void +n_print(Int , char ); +#endif + +/* Type: MYSQL->1 ODBC->2*/ +Short +myddas_util_connection_type(void *con){ + + MYDDAS_UTIL_CONNECTION con_node = + myddas_util_search_connection(con); + + if (con_node == NULL) + return 0; + + if (con_node->odbc_enviromment != NULL) /* ODBC */ + return 2; + else + return 1; +} + + +MYDDAS_UTIL_PREDICATE +myddas_util_search_predicate(char *pred_name, Int pred_arity, + char *pred_module){ + MYDDAS_UTIL_PREDICATE pred=NULL; + MYDDAS_UTIL_CONNECTION top = Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_top_connections; + + for (;top!=NULL;top=top->next) + { + if ((pred=myddas_util_find_predicate(pred_name,pred_arity,pred_module,top->predicates))) + return pred; + } + return NULL; +} + +/* When using this function, we must guarante that this predicate + it's unique */ +MYDDAS_UTIL_CONNECTION +myddas_util_add_predicate(char *pred_name, Int pred_arity, + char *pred_module, void *con){ + + MYDDAS_UTIL_CONNECTION node_con = + myddas_util_search_connection(con); + + MYDDAS_UTIL_PREDICATE new = + myddas_init_initialize_predicate(pred_name,pred_arity,pred_module,node_con->predicates); + + if (new == NULL) + { + myddas_util_error_message("Could not initialize predicate node",__LINE__,__FILE__); + return NULL; + } + + node_con->predicates=new; + return node_con; +} + +void +myddas_util_delete_predicate(MYDDAS_UTIL_PREDICATE to_delete){ + + if (to_delete->next != NULL) + to_delete->next->previous = to_delete->previous; + if (to_delete->previous != NULL) + to_delete->previous->next = to_delete->next; + else //First predicate of the predicate list + { + MYDDAS_UTIL_CONNECTION con_node = Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_top_connections; + for(;con_node != NULL; con_node = con_node->next) + if (con_node->predicates == to_delete) + break; + con_node->predicates = to_delete->next; + } + MYDDAS_FREE(to_delete,struct myddas_list_preds); +} + +void +myddas_util_delete_connection(void *conn){ + + MYDDAS_UTIL_CONNECTION to_delete = myddas_util_search_connection(conn); + + if (to_delete == NULL) + return; + else + { + /* Removes the predicates list */ + myddas_util_delete_predicate_list(to_delete->predicates); + +#ifdef MYDDAS_STATS + /* Removes the stats list */ + myddas_stats_delete_stats_list(to_delete->stats); +#endif + /* List Integrety */ + /* Is the last element of the list */ + if ((to_delete->next) != NULL) + to_delete->next->previous = to_delete->previous; + + /* Is the first element of the list */ + if (to_delete == (Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_top_connections)) + Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_top_connections = to_delete->next; + else + to_delete->previous->next=to_delete->next; + + MYDDAS_FREE(to_delete,struct myddas_list_connection); + return; + } +} + +MYDDAS_UTIL_CONNECTION +myddas_util_search_connection(void *conn){ + MYDDAS_UTIL_CONNECTION list = Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_top_connections; + +#ifdef MYDDAS_STATS + if (conn == 0) { /* We want all the statistics */ + return list; + } +#endif + + for (;list!=NULL;list=list->next) + if (list->connection == conn) + return list; + return NULL; +} + +MYDDAS_UTIL_CONNECTION +myddas_util_add_connection(void *conn, void *enviromment){ + + MYDDAS_UTIL_CONNECTION node=NULL; + MYDDAS_UTIL_CONNECTION temp=NULL; + + if ((node = myddas_util_search_connection(conn)) != NULL) + { + return node; + } + //put the new connection node on the top of the list + temp = myddas_init_initialize_connection(conn,enviromment,Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_top_connections); + if (temp == NULL) + { +#ifdef DEBUG + myddas_util_error_message("Could not initialize connection node",__LINE__,__FILE__); +#endif + return NULL; + } + Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_top_connections = temp; + return Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_top_connections; +} + +#ifdef MYDDAS_ODBC +/* This function searches the MYDDAS list for odbc connections + If there isn't any, it returns NULL. This is a nice way to know + if there is any odbc connections left on the list*/ +SQLHENV +myddas_util_get_odbc_enviromment(SQLHDBC connection){ + MYDDAS_UTIL_CONNECTION top = Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_top_connections; + + for (;top != NULL;top=top->next) + if (top->connection == ((void *)connection)) + return top->odbc_enviromment; + + return NULL; +} +#endif + +UInt +myddas_util_get_total_multi_queries_number(MYDDAS_UTIL_CONNECTION con){ + return con->total_number_queries; +} + +void +myddas_util_set_total_multi_queries_number(MYDDAS_UTIL_CONNECTION con, + UInt number){ + con->total_number_queries = number; +} + +#ifdef MYDDAS_MYSQL +/* Auxilary function to table_write*/ +static void +n_print(Int n, char c) +{ + for(;n>0;n--) printf("%c",c); +} +#endif + +static +void myddas_util_error_message(char *message ,Int line,char *file){ +#ifdef DEBUG + printf ("ERROR: %s at line %d in file %s\n",message,(int)line,file); +#else + printf ("ERROR: %s\n",message); +#endif +} + +static MYDDAS_UTIL_PREDICATE +myddas_util_find_predicate(char *pred_name, Int pred_arity, + char *pred_module, MYDDAS_UTIL_PREDICATE list){ + + for(;list != NULL ; list = list->next) + if (pred_arity == list->pred_arity && + !strcmp(pred_name,list->pred_name) && + !strcmp(pred_module,list->pred_module)) + return list; + + return NULL; +} + +static void +myddas_util_delete_predicate_list(MYDDAS_UTIL_PREDICATE preds_list){ + MYDDAS_UTIL_PREDICATE to_delete = NULL; + + for (;preds_list != NULL;) + { + to_delete = preds_list; + preds_list = preds_list->next; + + MYDDAS_FREE(to_delete,struct myddas_list_preds); + } + return; +} + +#ifdef MYDDAS_MYSQL +void +myddas_util_table_write(MYSQL_RES *res_set){ + + MYSQL_ROW row; + MYSQL_FIELD *fields; + Int i,f; + + if (mysql_num_rows(res_set) == 0) + { + printf ("Empty Set\n"); + return; + } + + f = mysql_num_fields(res_set); + + fields = mysql_fetch_field(res_set); + for(i=0;ifields[i].max_length) fields[i].max_length=strlen(fields[i].name); + n_print(fields[i].max_length+2,'-'); + } + printf("+\n"); + + for(i=0;imyddas_top_connections; +} + +void * +myddas_util_get_pred_next(void *pointer){ + MYDDAS_UTIL_PREDICATE temp = (MYDDAS_UTIL_PREDICATE) pointer; + return (void *) (temp->next); +} + +MyddasInt +myddas_util_get_pred_arity(void *pointer){ + MYDDAS_UTIL_PREDICATE temp = (MYDDAS_UTIL_PREDICATE) pointer; + return temp->pred_arity; +} + +char * +myddas_util_get_pred_name(void *pointer){ + MYDDAS_UTIL_PREDICATE temp = (MYDDAS_UTIL_PREDICATE) pointer; + return temp->pred_name; +} + +char * +myddas_util_get_pred_module(void *pointer){ + MYDDAS_UTIL_PREDICATE temp = (MYDDAS_UTIL_PREDICATE) pointer; + return temp->pred_module; +} + +void * +myddas_util_get_list_pred(MYDDAS_UTIL_CONNECTION node){ + return (void *)(node->predicates); +} + +#ifdef DEBUG +void check_int(){ + Int i; + MYDDAS_UTIL_PREDICATE pred = NULL; + MYDDAS_UTIL_CONNECTION top = Yap_REGS.MYDDAS_GLOBAL_POINTER->myddas_top_connections; + for (i=1 ; top!=NULL ; top=top->next) + { + printf ("***************\n"); + printf ("===== top =====\n"); + printf ("======= %p =====\n",top); + printf ("CONN: = %p =====\n",top->connection); + printf ("ENV : = %p =====\n",top->odbc_enviromment); + printf ("PRED: = %p =====\n",top->predicates); + printf ("======= %p =====\n",top->previous); + printf ("======= %p =====\n",top->next); + if (top->predicates != NULL) + { + printf ("\t******\n"); + printf ("\t===== PREDICADOS =====\n"); + for (pred = top->predicates ; pred != NULL ; pred = pred->next) + { + printf ("\t--------------\n"); + printf ("\t===== %p =====\n",pred); + printf ("\t===== %s =====\n",pred->pred_name); + printf ("\t===== %d =====\n",pred->pred_arity); + printf ("\t===== %s =====\n",pred->pred_module); + printf ("\t===== %p =====\n",pred->previous); + printf ("\t===== %p =====\n",pred->next); + } + } + + } + + return; +} +#endif + + +#endif /*defined MYDDAS_ODBC || defined MYDDAS_MYSQL*/ + + diff --git a/packages/MYDDAS/myddas_wkb.h b/packages/MYDDAS/myddas_wkb.h new file mode 100644 index 000000000..3ecfa04f3 --- /dev/null +++ b/packages/MYDDAS/myddas_wkb.h @@ -0,0 +1,25 @@ +#ifndef MYDDAS_WKB_H_ +#define MYDDAS_WKB_H_ + +typedef char byte; + +typedef unsigned int uint32; + +#define WKBXDR 0 +#define WKBNDR 1 + +#define WKBMINTYPE 1 + +#define WKBPOINT 1 +#define WKBLINESTRING 2 +#define WKBPOLYGON 3 +#define WKBMULTIPOINT 4 +#define WKBMULTILINESTRING 5 +#define WKBMULTIPOLYGON 6 +#define WKBGEOMETRYCOLLECTION 7 + +#define WKBMAXTYPE 7 + +#define WKBGEOMETRY 0 + +#endif /* MYDDAS_WKB_H_ */ diff --git a/packages/MYDDAS/myddas_wkb2prolog.c b/packages/MYDDAS/myddas_wkb2prolog.c new file mode 100644 index 000000000..f18bf8015 --- /dev/null +++ b/packages/MYDDAS/myddas_wkb2prolog.c @@ -0,0 +1,380 @@ +#if defined MYDDAS_MYSQL + +#include +#include +#include "Yap.h" +#include +#include "myddas_wkb.h" +#include "myddas_wkb2prolog.h" + +static void readswap4(uint32 *buf); +static void readswap8(double *buf); + +static byte get_hostbyteorder(void); +static byte get_inbyteorder(void); +static uint32 get_wkbType(void); +static Term get_point(char *functor); +static Term get_linestring(char *functor); +static Term get_polygon(char *functor); +static Term get_geometry(uint32 type); + +static int swaporder; +static byte inbyteorder, hostbyteorder; +static byte *cursor; + +Term wkb2prolog(char *wkb) { + uint32 type; + + cursor = wkb; + + /*ignore the SRID 4 bytes*/ + cursor += 4; + + /*byteorder*/ + hostbyteorder = get_hostbyteorder(); + inbyteorder = get_inbyteorder(); + + swaporder = 0; + if ( hostbyteorder != inbyteorder ) + swaporder = 1; + + type = get_wkbType(); + + return get_geometry(type); +} + +static byte get_hostbyteorder(void){ + uint16_t host = 5; + uint16_t net; + + net = htons(host); + if ( net == host ) + return(WKBXDR); + else + return(WKBNDR); +} + +static byte get_inbyteorder(void){ + byte b = cursor[0]; + + if (b != WKBNDR && b != WKBXDR) { + fprintf(stderr, "Unknown byteorder: %d\n",b); + exit(0); + } + + cursor++; + + return(b); +} + +static uint32 get_wkbType(void){ + uint32 u; + + /* read the type */ + readswap4(&u); + + if (u > WKBMAXTYPE || u < WKBMINTYPE) { + fprintf(stderr, "Unknown type: %d\n",u); + exit(0); + } + + return(u); +} + +static void readswap4(uint32 *buf){ + ((byte *) buf)[0] = cursor[0]; + ((byte *) buf)[1] = cursor[1]; + ((byte *) buf)[2] = cursor[2]; + ((byte *) buf)[3] = cursor[3]; + + if ( swaporder ) { + if ( inbyteorder == WKBXDR ) { + *buf = (uint32)ntohl((u_long)*buf); + } else { + byte u[4]; + + u[0] = ((byte *) buf)[3]; + u[1] = ((byte *) buf)[2]; + u[2] = ((byte *) buf)[1]; + u[3] = ((byte *) buf)[0]; + ((byte *) buf)[0] = u[0]; + ((byte *) buf)[1] = u[1]; + ((byte *) buf)[2] = u[2]; + ((byte *) buf)[3] = u[3]; + } + } + + cursor += 4; +} + +static void readswap8(double *buf) { + ((byte *) buf)[0] = cursor[0]; + ((byte *) buf)[1] = cursor[1]; + ((byte *) buf)[2] = cursor[2]; + ((byte *) buf)[3] = cursor[3]; + ((byte *) buf)[4] = cursor[4]; + ((byte *) buf)[5] = cursor[5]; + ((byte *) buf)[6] = cursor[6]; + ((byte *) buf)[7] = cursor[7]; + + if ( swaporder ) { + if ( inbyteorder == WKBXDR ) { + u_long u[2]; + + u[0] = ((u_long *) buf)[0]; + u[1] = ((u_long *) buf)[1]; + ((u_long *) buf)[1] = ntohl(u[0]); + ((u_long *) buf)[0] = ntohl(u[1]); + } else { + byte u[8]; + + u[0] = ((byte *) buf)[7]; + u[1] = ((byte *) buf)[6]; + u[2] = ((byte *) buf)[5]; + u[3] = ((byte *) buf)[4]; + u[4] = ((byte *) buf)[3]; + u[5] = ((byte *) buf)[2]; + u[6] = ((byte *) buf)[1]; + u[7] = ((byte *) buf)[0]; + ((byte *) buf)[0] = u[0]; + ((byte *) buf)[1] = u[1]; + ((byte *) buf)[2] = u[2]; + ((byte *) buf)[3] = u[3]; + ((byte *) buf)[4] = u[4]; + ((byte *) buf)[5] = u[5]; + ((byte *) buf)[6] = u[6]; + ((byte *) buf)[7] = u[7]; + } + } + + cursor += 8; +} + +static Term get_point(char *func){ + Term args[2]; + Functor functor; + double d; + + if(func == NULL) + /*functor "," => (_,_)*/ + functor = Yap_MkFunctor(Yap_LookupAtom(","), 2); + else + functor = Yap_MkFunctor(Yap_LookupAtom(func), 2); + + /* read the X */ + readswap8(&d); + args[0] = MkFloatTerm(d); + + /* read the Y */ + readswap8(&d); + args[1] = MkFloatTerm(d); + + return Yap_MkApplTerm(functor, 2, args); +} + +static Term get_linestring(char *func){ + Term *c_list; + Term list; + Functor functor; + uint32 n; + int i; + + /* read the number of vertices */ + readswap4(&n); + + /* space for arguments */ + c_list = (Term *) calloc(sizeof(Term),n); + + for ( i = 0; i < n; i++) { + c_list[i] = get_point(NULL); + } + + list = MkAtomTerm(Yap_LookupAtom("[]")); + for (i = n - 1; i >= 0; i--) { + list = MkPairTerm(c_list[i],list); + } + + if(func == NULL) + return list; + else{ + functor = Yap_MkFunctor(Yap_LookupAtom(func), 1); + return Yap_MkApplTerm(functor, 1, &list); + } +} + +static Term get_polygon(char *func){ + uint32 r; + int i; + Functor functor; + Term *c_list; + Term list; + + /* read the number of rings */ + readswap4(&r); + + /* space for rings */ + c_list = (Term *) calloc(sizeof(Term),r); + + for ( i = 0; i < r; i++ ) { + c_list[i] = get_linestring(NULL); + } + + list = MkAtomTerm(Yap_LookupAtom("[]")); + for (i = r - 1; i >= 0; i--) { + list = MkPairTerm(c_list[i],list); + } + + if(func == NULL) + return list; + else{ + functor = Yap_MkFunctor(Yap_LookupAtom("polygon"), 1); + return Yap_MkApplTerm(functor, 1, &list); + } +} + +static Term get_geometry(uint32 type){ + switch(type) { + case WKBPOINT: + return get_point("point"); + case WKBLINESTRING: + return get_linestring("linestring"); + case WKBPOLYGON: + return get_polygon("polygon"); + case WKBMULTIPOINT: + { + byte b; + uint32 n, u; + int i; + Functor functor; + Term *c_list; + Term list; + + + /* read the number of points */ + readswap4(&n); + + /* space for points */ + c_list = (Term *) calloc(sizeof(Term),n); + + for ( i = 0; i < n; i++ ) { + /* read (and ignore) the byteorder and type */ + b = get_inbyteorder(); + u = get_wkbType(); + + c_list[i] = get_point(NULL); + } + + list = MkAtomTerm(Yap_LookupAtom("[]")); + for (i = n - 1; i >= 0; i--) { + list = MkPairTerm(c_list[i],list); + } + + functor = Yap_MkFunctor(Yap_LookupAtom("multipoint"), 1); + + return Yap_MkApplTerm(functor, 1, &list); + + } + case WKBMULTILINESTRING: + { + byte b; + uint32 n, u; + int i; + Functor functor; + Term *c_list; + Term list; + + + /* read the number of polygons */ + readswap4(&n); + + /* space for polygons*/ + c_list = (Term *) calloc(sizeof(Term),n); + + for ( i = 0; i < n; i++ ) { + /* read (and ignore) the byteorder and type */ + b = get_inbyteorder(); + u = get_wkbType(); + + c_list[i] = get_linestring(NULL); + } + + list = MkAtomTerm(Yap_LookupAtom("[]")); + for (i = n - 1; i >= 0; i--) { + list = MkPairTerm(c_list[i],list); + } + + functor = Yap_MkFunctor(Yap_LookupAtom("multilinestring"), 1); + + return Yap_MkApplTerm(functor, 1, &list); + + } + case WKBMULTIPOLYGON: + { + byte b; + uint32 n, u; + int i; + Functor functor; + Term *c_list; + Term list; + + + /* read the number of polygons */ + readswap4(&n); + + /* space for polygons*/ + c_list = (Term *) calloc(sizeof(Term),n); + + for ( i = 0; i < n; i++ ) { + /* read (and ignore) the byteorder and type */ + b = get_inbyteorder(); + u = get_wkbType(); + + c_list[i] = get_polygon(NULL); + } + + list = MkAtomTerm(Yap_LookupAtom("[]")); + for (i = n - 1; i >= 0; i--) { + list = MkPairTerm(c_list[i],list); + } + + functor = Yap_MkFunctor(Yap_LookupAtom("multipolygon"), 1); + + return Yap_MkApplTerm(functor, 1, &list); + + } + case WKBGEOMETRYCOLLECTION: + { + byte b; + uint32 n; + int i; + Functor functor; + Term *c_list; + Term list; + + /* read the number of geometries */ + readswap4(&n); + + /* space for geometries*/ + c_list = (Term *) calloc(sizeof(Term),n); + + + for ( i = 0; i < n; i++ ) { + b = get_inbyteorder(); + c_list[i] = get_geometry(get_wkbType()); + } + + list = MkAtomTerm(Yap_LookupAtom("[]")); + for (i = n - 1; i >= 0; i--) { + list = MkPairTerm(c_list[i],list); + } + + functor = Yap_MkFunctor(Yap_LookupAtom("geometrycollection"), 1); + + return Yap_MkApplTerm(functor, 1, &list); + } + } + + return MkAtomTerm(Yap_LookupAtom("[]")); +} + +#endif /*MYDDAS_MYSQL*/ diff --git a/packages/MYDDAS/myddas_wkb2prolog.h b/packages/MYDDAS/myddas_wkb2prolog.h new file mode 100644 index 000000000..b6a399085 --- /dev/null +++ b/packages/MYDDAS/myddas_wkb2prolog.h @@ -0,0 +1,6 @@ +#ifndef MYDDAS_WKB2PROLOG_H_ +# define MYDDAS_WKB2PROLOG_H_ + +Term wkb2prolog(char *wkb) ; + +#endif /* !MYDDAS_WKB2PROLOG_H_ */ diff --git a/packages/ProbLog/Makefile.in b/packages/ProbLog/Makefile.in new file mode 100644 index 000000000..007bf5c25 --- /dev/null +++ b/packages/ProbLog/Makefile.in @@ -0,0 +1,14 @@ +default: + @(cd simplecudd; \ + echo Making simplecudd...; \ + make) + pwd + cp simplecudd/ProblogBDD . + +clean: + @(cd simplecudd; \ + echo Cleaning simplecudd...; \ + make clean; \ + cd ..) + rm -rf ProblogBDD output queries + \ No newline at end of file diff --git a/packages/ProbLog/README b/packages/ProbLog/README new file mode 100644 index 000000000..0b1a06a03 --- /dev/null +++ b/packages/ProbLog/README @@ -0,0 +1,7 @@ +To compile ProbLog call + make +To clean the directory call + make clean + +The make file will recursively call the make file of SimpleCudd and Cudd. +And it will finally copy the binary executable ProblogBDD to the main directory. \ No newline at end of file diff --git a/packages/ProbLog/examples/graph.pl b/packages/ProbLog/examples/graph.pl new file mode 100644 index 000000000..cd3a4dfe8 --- /dev/null +++ b/packages/ProbLog/examples/graph.pl @@ -0,0 +1,86 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% ProbLog program describing a probabilistic graph +% (running example from ProbLog presentations) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +:- use_module('../problog'). + +%%%% +% background knowledge +%%%% +% definition of acyclic path using list of visited nodes +path(X,Y) :- path(X,Y,[X],_). + +path(X,X,A,A). +path(X,Y,A,R) :- + X\==Y, + edge(X,Z), + absent(Z,A), + path(Z,Y,[Z|A],R). + +% using directed edges in both directions +edge(X,Y) :- dir_edge(Y,X). +edge(X,Y) :- dir_edge(X,Y). + +% checking whether node hasn't been visited before +absent(_,[]). +absent(X,[Y|Z]):-X \= Y, absent(X,Z). + +%%%% +% probabilistic facts +%%%% +0.9::dir_edge(1,2). +0.8::dir_edge(2,3). +0.6::dir_edge(3,4). +0.7::dir_edge(1,6). +0.5::dir_edge(2,6). +0.4::dir_edge(6,5). +0.7::dir_edge(5,3). +0.2::dir_edge(5,4). + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% example queries about path(1,4) +% +%%% explanation probability (and facts involved) +% ?- problog_max(path(1,4),Prob,FactsUsed). +% FactsUsed = [dir_edge(1,2),dir_edge(2,3),dir_edge(3,4)], +% Prob = 0.432 ? +% yes +%%% success probability +% ?- problog_exact(path(1,4),Prob,Status). +% 8 proofs +% Prob = 0.53864, +% Status = ok ? +% yes +%%% lower bound using 4 best proofs +% ?- problog_kbest(path(1,4),4,Prob,Status). +% 4 proofs +% Prob = 0.517344, +% Status = ok ? +% yes +%%% approximation using monte carlo, to reach 95%-confidence interval width 0.01 +% ?- problog_montecarlo(path(1,4),0.01,Prob). +% Prob = 0.537525 ? +% yes +%%% upper and lower bound using iterative deepening, final interval width 0.01 +% ?- problog_delta(path(1,4),0.01,Bound_low,Bound_up,Status). +% Bound_low = 0.5354096, +% Bound_up = 0.53864, +% Status = ok ? +% yes +%%% upper and lower bound obtained cutting the sld tree at probability 0.1 for each branch +% ?- problog_threshold(path(1,4),0.1,Bound_low,Bound_up,Status). +% 4 proofs +% Bound_low = 0.517344, +% Bound_up = 0.563728, +% Status = ok ? +% yes +%%% lower bound obtained cutting the sld tree at probability 0.2 for each branch +% ?- problog_low(path(1,4),0.2,Bound_low,Status). +% 1 proofs +% Bound_low = 0.432, +% Status = ok ? +% yes +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% diff --git a/packages/ProbLog/examples/learn_graph.pl b/packages/ProbLog/examples/learn_graph.pl new file mode 100644 index 000000000..86436d624 --- /dev/null +++ b/packages/ProbLog/examples/learn_graph.pl @@ -0,0 +1,96 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% ProbLog program describing a probabilistic graph +% (running example from ProbLog presentations) +% +% example for parameter learning with LeProbLog +% +% training and test examples are included at the end of the file +% +% query ?- do_learning(20). +% will run 20 iterations of learning with default settings +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +:- use_module('../learning'). + +%%%% +% background knowledge +%%%% +% definition of acyclic path using list of visited nodes +path(X,Y) :- path(X,Y,[X],_). + +path(X,X,A,A). +path(X,Y,A,R) :- + X\==Y, + edge(X,Z), + absent(Z,A), + path(Z,Y,[Z|A],R). + +% using directed edges in both directions +edge(X,Y) :- dir_edge(Y,X). +edge(X,Y) :- dir_edge(X,Y). + +% checking whether node hasn't been visited before +absent(_,[]). +absent(X,[Y|Z]):-X \= Y, absent(X,Z). + +%%%% +% probabilistic facts +% - probability represented by t/1 term means learnable parameter +% - argument of t/1 is real value (used to compare against in evaluation when known), use t(_) if unknown +%%%% +t(0.9)::dir_edge(1,2). +t(0.8)::dir_edge(2,3). +t(0.6)::dir_edge(3,4). +t(0.7)::dir_edge(1,6). +t(0.5)::dir_edge(2,6). +t(0.4)::dir_edge(6,5). +t(0.7)::dir_edge(5,3). +t(0.2)::dir_edge(5,4). + +%%%%%%%%%%%%%% +% training examples of form example(ID,Query,DesiredProbability) +%%%%%%%%%%%%%% + +example(1,path(1,2),0.94). +example(2,path(1,3),0.81). +example(3,path(1,4),0.54). +example(4,path(1,5),0.70). +example(5,path(1,6),0.87). +example(6,path(2,3),0.85). +example(7,path(2,4),0.57). +example(8,path(2,5),0.72). +example(9,path(2,6),0.86). +example(10,path(3,4),0.66). +example(11,path(3,5),0.80). +example(12,path(3,6),0.75). +example(13,path(4,5),0.57). +example(14,path(4,6),0.51). +example(15,path(5,6),0.69). +% some examples for learning from proofs: +example(16,(dir_edge(2,3),dir_edge(2,6),dir_edge(6,5),dir_edge(5,4)),0.032). +example(17,(dir_edge(1,6),dir_edge(2,6),dir_edge(2,3),dir_edge(3,4)),0.168). +example(18,(dir_edge(5,3),dir_edge(5,4)),0.14). +example(19,(dir_edge(2,6),dir_edge(6,5)),0.2). +example(20,(dir_edge(1,2),dir_edge(2,3),dir_edge(3,4)),0.432). + +%%%%%%%%%%%%%% +% test examples of form test_example(ID,Query,DesiredProbability) +% note: ID namespace is shared with training example IDs +%%%%%%%%%%%%%% + +test_example(21,path(2,1),0.94). +test_example(22,path(3,1),0.81). +test_example(23,path(4,1),0.54). +test_example(24,path(5,1),0.70). +test_example(25,path(6,1),0.87). +test_example(26,path(3,2),0.85). +test_example(27,path(4,2),0.57). +test_example(28,path(5,2),0.72). +test_example(29,path(6,2),0.86). +test_example(30,path(4,3),0.66). +test_example(31,path(5,3),0.80). +test_example(32,path(6,3),0.75). +test_example(33,path(5,4),0.57). +test_example(34,path(6,4),0.51). +test_example(35,path(6,5),0.69). + diff --git a/packages/ProbLog/learning.yap b/packages/ProbLog/learning.yap new file mode 100644 index 000000000..92de9c0c9 --- /dev/null +++ b/packages/ProbLog/learning.yap @@ -0,0 +1,1147 @@ +%%% -*- Mode: Prolog; -*- + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% Parameter Learning for ProbLog +% +% 27.10.2008 +% bernd.gutmann@cs.kuleuven.be +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +:- module(learning,[do_learning/1, + do_learning/2, + set_learning_flag/2, + save_model/1, + problog_help/0, + set_problog_flag/2, + problog_flag/2, + problog_flags/0 + ]). + +% switch on all the checks to reduce bug searching time +:- style_check(all). +:- yap_flag(unknown,error). + +% load modules from the YAP library +:- use_module(library(lists)). +:- use_module(library(random),[random/1]). +:- use_module(library(system),[file_exists/1, + file_property/2, + delete_file/1, + make_directory/1, + shell/1, + shell/2]). + +% load our own modules +:- use_module('learning/logger'). +:- use_module(problog). + +% used to indicate the state of the system +:- dynamic values_correct/0. +:- dynamic learning_initialized/0. +:- dynamic current_iteration/1. +:- dynamic example_count/1. +:- dynamic query_probability_intern/2. +:- dynamic query_gradient_intern/3. +:- dynamic last_mse/1. + +% used to identify queries which have identical proofs +:- dynamic query_is_similar/2. +:- dynamic query_md5/2. + +% used by set_learning_flag +:- dynamic init_method/5. +:- dynamic rebuild_bdds/1. +:- dynamic rebuild_bdds_it/1. +:- dynamic reuse_initialized_bdds/1. +:- dynamic learning_rate/1. +:- dynamic probability_initializer/3. +:- dynamic check_duplicate_bdds/1. +:- dynamic output_directory/1. +:- dynamic query_directory/1. +:- dynamic log_frequency/1. +:- dynamic alpha/1. +:- dynamic sigmoid_slope/1. + + +%========================================================================== +%= You can set some flags and parameters +%= +%= init_method/5 specifies which ProbLog inference mechanism is used +%= to answer queries +%= +%= +%= if rebuild_bdds(true) is set, the bdds are rebuild after +%= each N iterations for rebuild_bdds_it(N) +%= +%= if reuse_initialized_bdds(true) is set, the bdds which are on the +%= harddrive from the previous run of LeProbLog are reused. +%= do not use this, when you changed the init method in the meantime +%= +%========================================================================== +set_learning_flag(init_method,(Query,Probability,BDDFile,ProbFile,Call)) :- + retractall(init_method(_,_,_,_,_)), + assert(init_method(Query,Probability,BDDFile,ProbFile,Call)). + +set_learning_flag(rebuild_bdds,Flag) :- + (Flag=true;Flag=false), + retractall(rebuild_bdds(_)), + assert(rebuild_bdds(Flag)). + +set_learning_flag(rebuild_bdds_it,Flag) :- + integer(Flag), + retractall(rebuild_bdds_it(_)), + assert(rebuild_bdds_it(Flag)). + + +set_learning_flag(reuse_initialized_bdds,Flag) :- + (Flag=true;Flag=false), + retractall(reuse_initialized_bdds(_)), + assert(reuse_initialized_bdds(Flag)). + +set_learning_flag(learning_rate,V) :- + (V=examples -> true;(number(V),V>=0)), + retractall(learning_rate(_)), + assert(learning_rate(V)). + +set_learning_flag(probability_initializer,(FactID,Probability,Query)) :- + var(FactID), + var(Probability), + callable(Query), + retractall(probability_initializer(_,_,_)), + assert(probability_initializer(FactID,Probability,Query)). + +set_learning_flag(check_duplicate_bdds,Flag) :- + (Flag=true;Flag=false), + retractall(check_duplicate_bdds(_)), + assert(check_duplicate_bdds(Flag)). + +set_learning_flag(output_directory,Directory) :- + ( + file_exists(Directory) + -> + file_property(Directory,type(directory)); + make_directory(Directory) + ), + + atomic_concat([Directory,'/'],Path), + atomic_concat([Directory,'/log.dat'],Logfile), + + retractall(output_directory(_)), + assert(output_directory(Path)), + logger_set_filename(Logfile), + set_problog_flag(dir,Directory). + +set_learning_flag(query_directory,Directory) :- + ( + file_exists(Directory) + -> + file_property(Directory,type(directory)); + make_directory(Directory) + ), + + atomic_concat([Directory,'/'],Path), + retractall(query_directory(_)), + assert(query_directory(Path)). + +set_learning_flag(log_frequency,Frequency) :- + integer(Frequency), + Frequency>=0, + retractall(log_frequency(_)), + assert(log_frequency(Frequency)). + +set_learning_flag(alpha,Alpha) :- + number(Alpha), + retractall(alpha(_)), + assert(alpha(Alpha)). +set_learning_flag(sigmoid_slope,Slope) :- + number(Slope), + Slope>0, + retractall(sigmoid_slope(_)), + assert(sigmoid_slope(Slope)). + + +%======================================================================== +%= store the facts with the learned probabilities to a file +%= if F is a variable, a filename based on the current iteration is used +%= +%======================================================================== +save_model(F) :- + ( + var(F) + -> + ( + current_iteration(Iteration), + output_directory(Directory), + atomic_concat([Directory,'factprobs_',Iteration,'.pl'],F) + );true + ), + export_facts(F). + +%======================================================================== +%= store the probabilities for all training and test examples +%= if F is a variable, a filename based on the current iteration is used +%= +%======================================================================== +save_predictions(F) :- + update_values, + + current_iteration(Iteration), + + ( + var(F) + -> + ( + current_iteration(Iteration), + output_directory(Directory), + atomic_concat([Directory,'predictions_',Iteration,'.pl'],F) + );true + ), + + open(F,'append',Handle), + format(Handle,"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n",[]), + format(Handle,"% Iteration, train/test, QueryID, Query, GroundTruth, Prediction %\n",[]), + format(Handle,"%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%\n",[]), + !, + + ( % go over all training examples + current_predicate(user:example/3), + user:example(Query_ID,Query,TrueQueryProb), + query_probability(Query_ID,LearnedQueryProb), + + format(Handle,'ex(~q,train,~q,~q,~10f,~10f).\n', + [Iteration,Query_ID,Query,TrueQueryProb,LearnedQueryProb]), + + fail; % go to next training example + true + ), + + ( % go over all test examples + current_predicate(user:test_example/3), + user:test_example(Query_ID,Query,TrueQueryProb), + query_probability(Query_ID,LearnedQueryProb), + + format(Handle,'ex(~q,test,~q,~q,~10f,~10f).\n', + [Iteration,Query_ID,Query,TrueQueryProb,LearnedQueryProb]), + + fail; % go to next test example + true + ), + format(Handle,'~3n',[]), + close(Handle). + + + +%======================================================================== +%= find out whether some example IDs are used more than once +%= if so, complain and stop +%= +%======================================================================== + +check_examples :- + ( + ( + (current_predicate(user:example/3),user:example(ID,_,_), \+ atomic(ID)) ; + (current_predicate(user:test_example/3),user:test_example(ID,_,_), \+ atomic(ID)) + ) + -> + ( + format(user_error,'The example id of example ~q is not atomic (e.g foo42, 23, bar, ...).~n',[ID]), + throw(error(examples)) + ); true + ), + + ( + ( + (current_predicate(user:example/3),user:example(ID,_,P), (\+ number(P); P>1 ; P<0)); + (current_predicate(user:test_example/3),user:test_example(ID,_,P), (\+ number(P) ; P>1 ; P<0)) + ) + -> + ( + format(user_error,'The example ~q does not have a valid probaility value (~q).~n',[ID,P]), + throw(error(examples)) + ); true + ), + + + ( + ( + ( + current_predicate(user:example/3), + user:example(ID,QueryA,_), + user:example(ID,QueryB,_), + QueryA \= QueryB + ) ; + + ( + current_predicate(user:test_example/3), + user:test_example(ID,QueryA,_), + user:test_example(ID,QueryB,_), + QueryA \= QueryB + ); + + ( + current_predicate(user:example/3), + current_predicate(user:test_example/3), + user:example(ID,QueryA,_), + user:test_example(ID,QueryB,_), + QueryA \= QueryB + ) + ) + -> + ( + format(user_error,'The example id ~q is used several times.~n',[ID]), + throw(error(examples)) + ); true + ). + + + + + + +%======================================================================== +%= initialize everything and perform Iterations times gradient descent +%= can be called several times +%= if it is called with an epsilon parameter, it stops when the change +%= in the MSE is smaller than epsilon +%======================================================================== + +do_learning(Iterations) :- + integer(Iterations), + + ( + current_predicate(user:example/3) + -> + true; + format(user_error,'~n~nWarning: No training examples specified !!!~n~n',[]) + ), + + do_learning_intern(Iterations,-1). + +do_learning(Iterations,Epsilon) :- + integer(Iterations), + float(Epsilon), + + Iterations>0, + Epsilon>0.0, + + ( + current_predicate(user:example/3) + -> + true; + format(user_error,'~n~nWarning: No training examples specified !!!~n~n',[]) + ), + + do_learning_intern(Iterations,Epsilon). + + + + + + + +do_learning_intern(Iterations,Epsilon) :- + ( + Iterations=0 + -> + true; + ( + Iterations>0, + + % nothing will happen, if we're already initialized + init_learning, + current_iteration(OldIteration), + !, + retractall(current_iteration(_)), + !, + CurrentIteration is OldIteration+1, + assert(current_iteration(CurrentIteration)), + EndIteration is OldIteration+Iterations, + + format(' Iteration ~d of ~d~n',[CurrentIteration,EndIteration]), + logger_set_variable(iteration,CurrentIteration), + + logger_start_timer(duration), + gradient_descent, + + ( + (rebuild_bdds(true),rebuild_bdds_it(BDDFreq),0 =:= CurrentIteration mod BDDFreq) + -> + ( + once(delete_all_queries), + once(init_queries) + ); true + ), + + + mse_trainingset, + mse_testset, + + ( + last_mse(Last_MSE) + -> + ( + retractall(last_mse(_)), + logger_get_variable(mse_trainingset,Current_MSE), + assert(last_mse(Current_MSE)), + !, + MSE_Diff is abs(Last_MSE-Current_MSE) + ); ( + logger_get_variable(mse_trainingset,Current_MSE), + assert(last_mse(Current_MSE)), + MSE_Diff is Epsilon+1 + ) + ), + + !, + logger_stop_timer(duration), + once(ground_truth_difference), + + logger_write_data, + + + log_frequency(Log_Frequency), + + ( + ( Log_Frequency=0; 0 =:= CurrentIteration mod Log_Frequency) + -> + ( + save_predictions(_X), + save_model(_Y) + ); + true + ), + RemainingIterations is Iterations-1, + + ( + MSE_Diff>Epsilon + -> + do_learning_intern(RemainingIterations,Epsilon); + true + ) + ) + ). + + + +%======================================================================== +%= find proofs and build bdds for all training and test examples +%= +%= +%======================================================================== + +init_learning :- + ( + learning_initialized + -> + true; + ( + + check_examples, + + + format('Delete previous logs (if existing) from output directory~2n',[]), + empty_output_directory, + + format('Initializing everything~n',[]), + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % Delete the BDDs from the previous run if they should + % not be reused + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + ( + (reuse_initialized_bdds(false);rebuild_bdds(true)) + -> + delete_all_queries; + true + ), + + + logger_write_header, + logger_start_timer(duration), + logger_set_variable(iteration,0), + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % start count examples + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + bb_put(training_examples,0), + ( % go over all training examples + current_predicate(user:example/3), + user:example(_,_,_), + bb_get(training_examples, OldCounter), + NewCounter is OldCounter+1, + bb_put(training_examples,NewCounter), + fail; + true + ), + + bb_put(test_examples,0), + ( % go over all test examples + current_predicate(user:test_example/3), + user:test_example(_,_,_), + bb_get(test_examples, OldCounter), + NewCounter is OldCounter+1, + bb_put(test_examples,NewCounter), + fail; + true + ), + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % stop count examples + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + !, + + bb_delete(training_examples,TrainingExampleCount), + bb_delete(test_examples,TestExampleCount), + + assert(example_count(TrainingExampleCount)), + + ( + learning_rate(examples) + -> + set_learning_flag(learning_rate,TrainingExampleCount); + true + ), + learning_rate(Learning_Rate), + format('~q training examples found.~n~q test examples found.~nlearning rate=~f~n~n', + [TrainingExampleCount,TestExampleCount,Learning_Rate]), + format('Generate BDDs for all queries in the training and test set~n',[]), + initialize_fact_probabilities, + init_queries, + + format('All Queries have been generated~n',[]), + + mse_trainingset, + mse_testset, + !, + logger_stop_timer(duration), + + ground_truth_difference, + + logger_write_data, + assert(current_iteration(0)), + assert(learning_initialized), + save_model(_),save_predictions(_) + + ) + ). + +%======================================================================== +%= +%= +%= +%======================================================================== + + + +delete_all_queries :- + query_directory(Directory), + atomic_concat(['rm -f ',Directory,'query_*'],Command), + (shell(Command) -> true; true), + retractall(query_is_similar(_,_)), + retractall(query_md5(_,_)). + +empty_output_directory :- + output_directory(Directory), + atomic_concat(['rm -f ',Directory,'log.dat ', + Directory,'factprobs_*.pl ', + Directory,'predictions_*.pl'],Command), + (shell(Command) -> true; true). + +%======================================================================== +%= This predicate goes over all training and test examples, +%= calls the inference method of ProbLog and stores the resulting +%= BDDs +%======================================================================== + + +init_queries :- + + ( % go over all training examples + current_predicate(user:example/3), + user:example(ID,Query,Prob), + format('~n~n training example ~q: ~q~n',[ID,Query]), + flush_output(user), + init_one_query(ID,Query), + fail; %go to next training example + + true + ), + + ( % go over all test examples + current_predicate(user:test_example/3), + user:test_example(ID,Query,Prob), + format('~n~n test example ~q: ~q~n',[ID,Query]), + flush_output(user), + init_one_query(ID,Query), + fail; % go to next test example + + true + ). + +init_one_query(QueryID,Query) :- + output_directory(Output_Directory), + query_directory(Query_Directory), + + atomic_concat([Query_Directory,'query_',QueryID],Filename), + atomic_concat([Output_Directory,'input.txt'],Filename2), + atomic_concat([Output_Directory,'tmp_md5'],Filename3), + + ( + file_exists(Filename) + -> + format('Reuse existing BDD ~q~n~n',[Filename]); + ( + init_method(Query,_Prob,Filename,Filename2,InitCall), + once(call(InitCall)), + delete_file(Filename2) + ) + ), + + + ( + check_duplicate_bdds(true) + -> + ( + % calculate the md5sum of the bdd script file + atomic_concat(['cat ',Filename,' | md5sum | sed "s/ .*$/\')./" | sed "s/^/md5(\'/"> ',Filename3],MD5Command), + + (shell(MD5Command,0) -> true; throw(error("Something wrong with calculating the MD5 value"))), + + open(Filename3, read, Handle), + read(Handle,md5(Query_MD5)), + close(Handle), + + delete_file(Filename3), + + % Does another query exists which already has this MD5? + ( + query_md5(OtherQueryID,Query_MD5) + -> + % yippie! we can save a lot of work + ( + assert(query_is_similar(QueryID,OtherQueryID)), + format('~q is similar to ~q~2n', [QueryID,OtherQueryID]) + ); assert(query_md5(QueryID,Query_MD5)) + ) + ); + + true + ). + + +%======================================================================== +%= set all unknown fact probabilities to random values +%= +%= +%======================================================================== + +initialize_fact_probabilities :- + ( % go over all tunable facts + tunable_fact(FactID,_), + + probability_initializer(FactID,Probability,Query), + once(call(Query)), + set_fact_probability(FactID,Probability), + + + fail; % go to next tunable fact + + true + ). + +random_probability(_FactID,Probability) :- + % use probs around 0.5 to not confuse k-best search + random(Random), + Probability is 0.5+(Random-0.5)/100. + + + + + +%======================================================================== +%= updates all values of query_probability/2 and query_gradient/3 +%= should be called always before these predicates are accessed +%= if the old values are still valid, nothing happens +%======================================================================== + +update_values :- + values_correct, + !. + +update_values :- + \+ values_correct, + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % delete old values + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + once(retractall(query_probability_intern(_,_))), + once(retractall(query_gradient_intern(_,_,_))), + + + output_directory(Directory), + atomic_concat(Directory,'input.txt',Input_Filename), + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % start write current probabilities to file + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + open(Input_Filename,'write',Handle), + + ( % go over all tunable facts + get_fact_probability(ID,Prob), + inv_sigmoid(Prob,Value), + format(Handle,'@x~q~n~10f~n',[ID,Value]), + + fail; % go to next tunable fact + true + ), + + close(Handle), + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % stop write current probabilities to file + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + !, + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % start update values for all training examples + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + ( % go over all training examples + current_predicate(user:example/3), + user:example(QueryID,_Query,_QueryProb), + once(call_bdd_tool(QueryID,'.')), + fail; % go to next training example + true + ), + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % stop update values for all training examples + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + !, + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % start update values for all test examples + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + ( % go over all training examples + current_predicate(user:test_example/3), + user:test_example(QueryID,_Query,_QueryProb), + once(call_bdd_tool(QueryID,'+')), + fail; % go to next training example + true + ), + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % stop update values for all test examples + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + !, + + nl, + + delete_file(Input_Filename), + assert(values_correct). + + +%======================================================================== +%= +%= +%= +%======================================================================== + + +call_bdd_tool(QueryID,Symbol) :- + output_directory(Output_Directory), + query_directory(Query_Directory), + ( + query_is_similar(QueryID,_) + -> + % we don't have to evaluate the BDD + write('#'); + ( + sigmoid_slope(Slope), + problog_dir(PD), + atomic_concat([PD, + '/ProblogBDD -i "', + Output_Directory, + 'input.txt', + '" -l "', + Query_Directory, + 'query_', + QueryID, + '" -m g -id ', + QueryID, + ' -sl ',Slope, + ' > "', + Output_Directory, + 'values.pl"'],Command), + shell(Command,Error), + ( + Error = 2 + -> + throw(error('SimpleCUDD has been interrupted.')); + true + ), + ( + Error \= 0 + -> + throw(bdd_error(QueryID,Error)); + true + ), + atomic_concat([Output_Directory,'values.pl'],Values_Filename), + once(my_load(Values_Filename)), + delete_file(Values_Filename), + write(Symbol) + ) + ), + flush_output(user). + + +%======================================================================== +%= +%= +%= +%======================================================================== + +my_load(File) :- + see(File), + read(X), + my_load_intern(X), + seen. +my_load_intern(end_of_file) :- + !. +my_load_intern(query_probability(QueryID,Prob)) :- + !, + assert(query_probability_intern(QueryID,Prob)), + read(X2), + my_load_intern(X2). +my_load_intern(query_gradient(QueryID,XFactID,Value)) :- + !, + atomic_concat(x,StringFactID,XFactID), + atom_number(StringFactID,FactID), + assert(query_gradient_intern(QueryID,FactID,Value)), + read(X2), + my_load_intern(X2). +my_load_intern(X) :- + format(user_error,'Unknown atom ~q in results file.~n',[X]), + read(X2), + my_load_intern(X2). + + +%======================================================================== +%= +%= +%= +%======================================================================== +query_probability(QueryID,Prob) :- + ( + query_probability_intern(QueryID,Prob) + -> + true; + ( + query_is_similar(QueryID,OtherQueryID), + query_probability_intern(OtherQueryID,Prob) + ) + ). +query_gradient(QueryID,Fact,Value) :- + ( + query_gradient_intern(QueryID,Fact,Value) + -> + true; + ( + query_is_similar(QueryID,OtherQueryID), + query_gradient_intern(OtherQueryID,Fact,Value) + ) + ). + +%======================================================================== +%= +%= +%= +%======================================================================== + + +ground_truth_difference :- + findall(Diff,(tunable_fact(FactID,GroundTruth), + \+ var(GroundTruth), + get_fact_probability(FactID,Prob), + Diff is abs(GroundTruth-Prob)),AllDiffs), + + % if no ground truth was specified for facts + % set everything to zero + ( + AllDiffs=[] + -> + ( + MinDiff=0.0, + MaxDiff=0.0, + DiffMean=0.0 + ) ; ( + length(AllDiffs,Len), + sum_list(AllDiffs,AllDiffsSum), + min_list(AllDiffs,MinDiff), + max_list(AllDiffs,MaxDiff), + + DiffMean is AllDiffsSum/Len + ) + ), + + logger_set_variable(ground_truth_diff,DiffMean), + logger_set_variable(ground_truth_mindiff,MinDiff), + logger_set_variable(ground_truth_maxdiff,MaxDiff). + +%======================================================================== +%= Calculates the mse of training and test data +%= +%= -Float +%======================================================================== + +% calculate the mse of the training data +mse_trainingset :- + ( + current_predicate(user:example/3) + -> + ( + update_values, + findall(SquaredError, + (user:example(QueryID,_Query,QueryProb), + query_probability(QueryID,CurrentProb), + SquaredError is (CurrentProb-QueryProb)**2), + AllSquaredErrors), + + length(AllSquaredErrors,Length), + sum_list(AllSquaredErrors,SumAllSquaredErrors), + min_list(AllSquaredErrors,MinError), + max_list(AllSquaredErrors,MaxError), + MSE is SumAllSquaredErrors/Length, + + logger_set_variable(mse_trainingset,MSE), + logger_set_variable(mse_min_trainingset,MinError), + logger_set_variable(mse_max_trainingset,MaxError) + ); true + ). + + + +mse_testset :- + ( + current_predicate(user:test_example/3) + -> + ( + update_values, + findall(SquaredError, + (user:test_example(QueryID,_Query,QueryProb), + query_probability(QueryID,CurrentProb), + SquaredError is (CurrentProb-QueryProb)**2), + AllSquaredErrors), + + length(AllSquaredErrors,Length), + sum_list(AllSquaredErrors,SumAllSquaredErrors), + min_list(AllSquaredErrors,MinError), + max_list(AllSquaredErrors,MaxError), + MSE is SumAllSquaredErrors/Length, + + logger_set_variable(mse_testset,MSE), + logger_set_variable(mse_min_testset,MinError), + logger_set_variable(mse_max_testset,MaxError) + ); true + ). + + + + +%======================================================================== +%= Calculates the sigmoid function respectivly the inverse of it +%= warning: applying inv_sigmoid to 0.0 or 1.0 will yield +/-inf +%= +%= +Float, -Float +%======================================================================== + +sigmoid(T,Sig) :- + sigmoid_slope(Slope), + Sig is 1/(1+exp(-T*Slope)). + +inv_sigmoid(T,InvSig) :- + sigmoid_slope(Slope), + InvSig is -log(1/T-1)/Slope. + + +%======================================================================== +%= this functions truncates probabilities too close to 1.0 or 0.0 +%= the reason is, applying the inverse sigmoid function would yield +/- inf +%= for such extreme values +%= +%= +Float, -Float +%======================================================================== + +secure_probability(Prob,Prob_Secure) :- + TMP is max(0.00001,Prob), + Prob_Secure is min(0.99999,TMP). + + + +%======================================================================== +%= Perform one iteration of gradient descent +%= +%= assumes that everything is initialized, if the current values +%= of query_probability/2 and query_gradient/3 are not up to date +%= they will be recalculated +%= finally, the values_correct/0 is retracted to signal that the +%= probabilities of the examples have to be recalculated +%======================================================================== + + +gradient_descent :- + update_values, + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % start set gradient to zero + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + ( % go over all tunable facts + + tunable_fact(FactID,_), + bb_put(FactID,0.0), + fail; % go to next tunable fact + + true + ), + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % stop gradient to zero + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + !, + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % start calculate gradient + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + alpha(Alpha), + example_count(ExampleCount), + ( % go over all training examples + current_predicate(user:example/3), + user:example(QueryID,_Query,QueryProb), + query_probability(QueryID,BDDProb), + ( + QueryProb=:=0.0 + -> + Y2=Alpha; + Y2=1.0 + ), + Y is Y2*2/ExampleCount * (BDDProb-QueryProb), + + + ( % go over all tunable facts + + tunable_fact(FactID,_), + ( + query_gradient(QueryID,FactID,GradValue) + -> + true; + GradValue=0.0 + ), + bb_get(FactID,OldValue), + NewValue is OldValue + Y*GradValue, + bb_put(FactID,NewValue), + fail; % go to next fact + + true + ), + fail; % go to next training example + + true + ), + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % stop calculate gradient + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + !, + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % start statistics on gradient + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + findall(V,(tunable_fact(FactID,_),bb_get(FactID,V)),GradientValues), + + sum_list(GradientValues,GradSum), + max_list(GradientValues,GradMax), + min_list(GradientValues,GradMin), + length(GradientValues,GradLength), + GradMean is GradSum/GradLength, + + logger_set_variable(gradient_mean,GradMean), + logger_set_variable(gradient_min,GradMin), + logger_set_variable(gradient_max,GradMax), + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % stop statistics on gradient + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % start add gradient to current probabilities + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + learning_rate(LearningRate), + + ( % go over all tunable facts + + tunable_fact(FactID,_), + get_fact_probability(FactID,OldProbability), + bb_delete(FactID,GradValue), + + inv_sigmoid(OldProbability,OldValue), + NewValue is OldValue -LearningRate*GradValue, + sigmoid(NewValue,NewProbability), + + % Prevent "inf" by using values too close to 1.0 + secure_probability(NewProbability,NewProbabilityS), + set_fact_probability(FactID,NewProbabilityS), + + fail; % go to next tunable fact + + true + ), + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + % stop add gradient to current probabilities + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + !, + + % we're done, mark old values as incorrect + retractall(values_correct). + + +%======================================================================== +%= initialize the logger module and set the flags for learning +%= +%======================================================================== + + +global_initialize :- + set_learning_flag(output_directory,'./output'), + set_learning_flag(query_directory,'./queries'), + set_learning_flag(log_frequency,5), + set_learning_flag(rebuild_bdds,false), + set_learning_flag(rebuild_bdds_it,1), + set_learning_flag(reuse_initialized_bdds,false), + set_learning_flag(learning_rate,examples), + set_learning_flag(check_duplicate_bdds,true), + set_learning_flag(probability_initializer,(FactID,P,random_probability(FactID,P))), + set_learning_flag(alpha,1.0), + set_learning_flag(sigmoid_slope,1.0), % 1.0 gives standard sigmoid + set_learning_flag(init_method,(Query,Probability,BDDFile,ProbFile, + problog_kbest_save(Query,10,Probability,_Status,BDDFile,ProbFile))), + + logger_define_variable(iteration, int), + logger_define_variable(duration,time), + logger_define_variable(mse_trainingset,float), + logger_define_variable(mse_min_trainingset,float), + logger_define_variable(mse_max_trainingset,float), + logger_define_variable(mse_testset,float), + logger_define_variable(mse_min_testset,float), + logger_define_variable(mse_max_testset,float), + logger_define_variable(gradient_mean,float), + logger_define_variable(gradient_min,float), + logger_define_variable(gradient_max,float), + logger_define_variable(ground_truth_diff,float), + logger_define_variable(ground_truth_mindiff,float), + logger_define_variable(ground_truth_maxdiff,float). + +%======================================================================== +%= +%= +%======================================================================== + +:- initialization(global_initialize). diff --git a/packages/ProbLog/learning/logger.yap b/packages/ProbLog/learning/logger.yap new file mode 100644 index 000000000..ecd97c948 --- /dev/null +++ b/packages/ProbLog/learning/logger.yap @@ -0,0 +1,311 @@ +%%% -*- Mode: Prolog; -*- + + +:- module(logger,[logger_define_variable/2, + logger_define_variables/2, + logger_set_filename/1, + logger_set_delimiter/1, + logger_set_variable/2, + logger_set_variable_again/2, + logger_get_variable/2, + logger_start_timer/1, + logger_stop_timer/1, + logger_write_data/0, + logger_write_header/0]). + +:- use_module(library(system),[datime/1,mktime/2]). +:- use_module(library(lists),[append/3,member/2]). + +:- yap_flag(unknown,error). +:- style_check(single_var). + +:- bb_put(logger_filename,'out.dat'). +:- bb_put(logger_delimiter,';'). +:- bb_put(logger_variables,[]). + + +%======================================================================== +%= Defines a new variable, possible types are: int, float and time +%= +%= +Name, +Type +%======================================================================== + +logger_define_variable(Name,int) :- + !, + is_variable_already_defined(Name), + bb_delete(logger_variables,OldVariables), + append(OldVariables,[(Name,int)],NewVariables), + bb_put(logger_variables,NewVariables), + atom_concat(logger_data_,Name,Key), + bb_put(Key,null). +logger_define_variable(Name,float) :- + !, + is_variable_already_defined(Name), + bb_delete(logger_variables,OldVariables), + append(OldVariables,[(Name,float)],NewVariables), + bb_put(logger_variables,NewVariables), + atom_concat(logger_data_,Name,Key), + bb_put(Key,null). +logger_define_variable(Name,time) :- + !, + is_variable_already_defined(Name), + bb_delete(logger_variables,OldVariables), + append(OldVariables,[(Name,time)],NewVariables), + bb_put(logger_variables,NewVariables), + atom_concat(logger_data_,Name,Key), + atom_concat(logger_start_time_,Name,Key2), + bb_put(Key,null), + bb_put(Key2,null). +logger_define_variable(Name,Unknown) :- + is_variable_already_defined(Name), + write('logger_define_variable, unknown type '), + write(Unknown), + write(' for variable '), + write(Name), + nl, + fail. + +is_variable_already_defined(Name) :- + bb_get(logger_variables,Variables), + member((Name,_),Variables),!, + write('logger_define_variable, Variable '), + write(Name), + write(' is already defined!\n'), + fail; + true. + +%======================================================================== +%= +%= +%= +ListOfNames, +Type +%======================================================================== + +logger_define_variables([],_). +logger_define_variables([H|T],Type) :- + logger_define_variable(H,Type), + logger_define_variables(T,Type). + +%======================================================================== +%= Set the filename, to which the output should be appended +%= +%= +Name +%======================================================================== + +logger_set_filename(Name) :- + bb_put(logger_filename,Name). + +%======================================================================== +%= Set the delimiter for the fields +%= +%= +Delimiter +%======================================================================== + +logger_set_delimiter(Delimiter) :- + bb_put(logger_delimiter,Delimiter). +%======================================================================== +%= Set the value of the variable name. If the value is already set or +%= if the variable does not exists, an error will be displayed and the +%= Prolog will be halted. +%= +%= +Name, +Value +%======================================================================== + +logger_set_variable(Name,Value) :- + atom_concat(logger_data_,Name,Key), + ( + bb_get(Key,null) + -> + ( + bb_put(Key,Value) + );( + bb_get(Key,_) + -> + ( + write('logger_set_variable, Variable '), + write(Name), + write(' is already set'), + nl, + fail + ) ; ( + write('logger_set_variable, unknown variable '), + write(Name), + nl, + fail + ) + ) + ),!. + +%======================================================================== +%= Set the value of the variable name. If the value is already set or +%= the old value is overwritten. If the variable does not exists, an +%= error will be displayed and the Prolog will be halted. +%= +%= +Name, +Value +%======================================================================== + +logger_set_variable_again(Name,Value) :- + atom_concat(logger_data_,Name,Key), + ( + bb_get(Key,_) + -> + ( + bb_put(Key,Value) + );( + write('logger_set_variable, unknown variable '), + write(Name), + nl, + fail + ) + ),!. + + +logger_variable_is_set(Name) :- + atom_concat(logger_data_,Name,Key), + bb_get(Key,X), + X \= null. + +%======================================================================== +%= Get the value of the variable name. If the value is not yet set or +%= if the variable does not exists, an error will be displayed and the +%= Prolog will be halted. +%= +%= +Name, +Value +%======================================================================== + +logger_get_variable(Name,Value) :- + atom_concat(logger_data_,Name,Key), + ( + bb_get(Key,null) + -> + ( + write('logger_get_variable, Variable '), + write(Name), + write(' is not yet set'), + nl, + fail + );( + bb_get(Key,Value) + ; + ( + write('logger_set_variable, unknown variable '), + write(Name), + nl, + fail + ) + ) + ),!. +%======================================================================== +%= +%= +%= +Name +%======================================================================== + +logger_start_timer(Name) :- + atom_concat(logger_start_time_,Name,Key), + ( + bb_get(Key,null) + -> + ( + statistics(walltime,[StartTime,_]), + bb_put(Key,StartTime) + );( + bb_get(Key,_) + -> + ( + write('logger_start_timer, timer '), + write(Name), + write(' is already started'), + nl, + fail + );( + write('logger_start_timer, timer '), + write(Name), + write(' is not defined'), + nl, + fail + ) + ) + ),!. + + +logger_stop_timer(Name) :- + atom_concat(logger_start_time_,Name,Key), + + bb_delete(Key,StartTime), + statistics(walltime,[StopTime,_]), + + bb_put(Key,null), + + Duration is StopTime-StartTime, + + ( + logger_variable_is_set(Name) + -> + ( + logger_get_variable(Name,OldDuration), + NewDuration is Duration+OldDuration, + logger_set_variable_again(Name,NewDuration) + ); logger_set_variable(Name,Duration) + ),!. + +%======================================================================== +%= write a new line to the log file, which contains all the +%= values of the variables. afterwards, reset all variables to null. +%= +%======================================================================== + +logger_write_data :- + bb_get(logger_filename,FName), + bb_get(logger_variables,Variables), + open(FName,'append',Handle), + logger_write_data_intern(Variables,Handle), + close(Handle), + + % reset variables + findall(_,(member((Name,_),Variables),atom_concat(logger_data_,Name,Key),bb_put(Key,null)),_), + findall(_,(member((Name,time),Variables),atom_concat(logger_start_time_,Name,Key2),bb_put(Key2,null)),_). + +logger_write_data_intern([],_). +logger_write_data_intern([(Name,_Type)],Handle) :- + variablevalue_with_nullcheck(Name,Value), + write(Handle,Value), + write(Handle,'\n'). +logger_write_data_intern([(Name,_Type),Next|T],Handle) :- + variablevalue_with_nullcheck(Name,Value), + bb_get(logger_delimiter,D), + write(Handle,Value), + write(Handle,D), + logger_write_data_intern([Next|T],Handle). + +variablevalue_with_nullcheck(Name,Result) :- + atom_concat(logger_data_,Name,Key), + bb_get(Key,Value), + ( + Value=null + -> + Result = '' ; + Result=Value + ). +%======================================================================== +%= +%= +%= +%======================================================================== + +logger_write_header :- + bb_get(logger_filename,FName), + bb_get(logger_variables,Variables), + open(FName,'append',Handle), + write(Handle,'# '), + logger_write_header_intern(Variables,Handle), + write(Handle,'\n'), + close(Handle). + +logger_write_header_intern([],_). +logger_write_header_intern([(Name,_Type)],Handle) :- + write(Handle,Name). +logger_write_header_intern([(Name,_Type),Next|T],Handle) :- + bb_get(logger_delimiter,D), + write(Handle,Name), + write(Handle,D), + logger_write_header_intern([Next|T],Handle). diff --git a/packages/ProbLog/problog.yap b/packages/ProbLog/problog.yap new file mode 100644 index 000000000..fc79568d1 --- /dev/null +++ b/packages/ProbLog/problog.yap @@ -0,0 +1,958 @@ +%%% -*- Mode: Prolog; -*- +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% ProbLog inference +% +% assumes probabilistic facts as Prob::Fact and clauses in normal Prolog format +% +% provides following inference modes (16/12/2008): +% - approximation with interval width Delta (IJCAI07): problog_delta(+Query,+Delta,-Low,-High,-Status) +% - bounds based on single probability threshold: problog_threshold(+Query,+Threshold,-Low,-High,-Status) +% - as above, but lower bound only: problog_low(+Query,+Threshold,-Low,-Status) +% - lower bound based on K most likely proofs: problog_kbest(+Query,+K,-Low,-Status) +% - explanation probability (ECML07): problog_max(+Query,-Prob,-FactsUsed) +% - exact probability: problog_exact(+Query,-Prob,-Status) +% - sampling: problog_montecarlo(+Query,+Delta,-Prob) +% +% +% angelika.kimmig@cs.kuleuven.be +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +:- module(problog, [problog_delta/5, + problog_threshold/5, + problog_low/4, + problog_kbest/4, + problog_kbest_save/6, + problog_max/3, + problog_exact/3, + problog_montecarlo/3, + get_fact_probability/2, + set_fact_probability/2, + get_fact/2, + tunable_fact/2, + export_facts/1, + problog_help/0, + problog_dir/1, + set_problog_flag/2, + problog_flag/2, + problog_flags/0]). + +:- style_check(all). +:- yap_flag(unknown,error). + +% problog related modules +:- use_module('problog/flags',[set_problog_flag/2, + problog_flag/2, + problog_flags/0]). + +:- use_module('problog/print', [print_sep_line/0, + print_inference/2]). + +:- use_module('problog/tptree',[init_ptree/1, + delete_ptree/1, + insert_ptree/2, + count_ptree/2, + prune_check_ptree/2, + merge_ptree/3, + bdd_ptree_map/4, + bdd_ptree/3]). + +% general yap modules +:- ensure_loaded(library(lists)). +:- ensure_loaded(library(terms)). +:- ensure_loaded(library(random)). +:- ensure_loaded(library(system)). +:- ensure_loaded(library(rbtrees)). + +% op attaching probabilities to facts +:- op( 550, yfx, :: ). + +%%%%%%%%%%%%%%%%%%%%%%%% +% control predicates on various levels +%%%%%%%%%%%%%%%%%%%%%%%% + +% global over all inference methods, internal use only +:- dynamic problog_predicate/2. +% global over all inference methods, exported +:- dynamic tunable_fact/2. +:- dynamic problog_dir/1. +% global, manipulated via problog_control/2 +:- dynamic up/0. +:- dynamic limit/0. +:- dynamic mc/0. +:- dynamic remember/0. +% local to problog_delta +:- dynamic low/2. +:- dynamic up/2. +:- dynamic stopDiff/1. +% local to problog_kbest +:- dynamic current_kbest/3. +% local to problog_max +:- dynamic max_probability/1. +:- dynamic max_proof/1. +% local to problog_montecarlo +:- dynamic mc_prob/1. + +% directory where ProblogBDD executable is located +% automatically set during loading -- assumes it is in same place as this file (problog.yap) +:- getcwd(PD),retractall(problog_dir(_)),assert(problog_dir(PD)). + +%%%%%%%%%%%%%%%%%%%%%%%% +% help +%%%%%%%%%%%%%%%%%%%%%%%% + +problog_help :- + format('~2nProbLog inference currently offers the following inference methods:~n',[]), + show_inference, + format('~2nThe following global parameters are available:~n',[]), + problog_flags, + print_sep_line, + format('~n use problog_help/0 to display this information~n',[]), + format('~n use problog_flags/0 to display current parameter values~2n',[]), + print_sep_line, + nl, + flush_output. + +show_inference :- + format('~n',[]), + print_sep_line, + print_inference(call,description), + print_sep_line, + print_inference('problog_delta(+Query,+Delta,-Low,-High,-Status)','approximation with interval width Delta (IJCAI07)'), + print_inference('problog_threshold(+Query,+Threshold,-Low,-High,-Status)','bounds based on single probability threshold'), + print_inference('problog_low(+Query,+Threshold,-Low,-Status)','lower bound based on single probability threshold'), + print_inference('problog_kbest(+Query,+K,-Low,-Status)','lower bound based on K most likely proofs'), + print_inference('problog_max(+Query,-Prob,-FactsUsed)','explanation probability (ECML07)'), + print_inference('problog_exact(+Query,-Prob,-Status)','exact probability'), + print_inference('problog_montecarlo(+Query,+Delta,-Prob)','sampling with 95\%-confidence-interval-width Delta'), + print_sep_line. + +%%%%%%%%%%%%%%%%%%%%%%%% +% initialization of global parameters +%%%%%%%%%%%%%%%%%%%%%%%% + +init_global_params :- + set_problog_flag(bdd_time,60), + set_problog_flag(first_threshold,0.1), + L is 10**(-30), + set_problog_flag(last_threshold,L), + set_problog_flag(id_stepsize,0.5), + set_problog_flag(prunecheck,off), + set_problog_flag(maxsteps,1000), + set_problog_flag(mc_batchsize,1000), + set_problog_flag(mc_logfile,'log.txt'), + set_problog_flag(bdd_file,example_bdd), + set_problog_flag(dir,output), + set_problog_flag(save_bdd,false), +% problog_flags, + print_sep_line, + format('~n use problog_help/0 for information~n',[]), + format('~n use problog_flags/0 to display current parameter values~2n',[]), + print_sep_line, + nl, + flush_output. + +% parameter initialization to be called after returning to user's directory: +:- initialization(init_global_params). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% internal control flags +% if on +% - up: collect stopped derivations to build upper bound +% - limit: iterative deepening reached limit -> should go to next level +% - mc: using problog_montecarlo, i.e. proving with current sample instead of full program +% - remember: save BDD files containing script, params and mapping +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +problog_control(on,X) :- + call(X),!. +problog_control(on,X) :- + assert(X). +problog_control(off,X) :- + retractall(X). +problog_control(check,X) :- + call(X). + +:- problog_control(off,up). +:- problog_control(off,mc). +:- problog_control(off,limit). +:- problog_control(off,remember). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% nice user syntax Prob::Fact +% automatic translation to internal hardware access format +% +% probabilities =1 are dropped -> normal Prolog fact +% +% internal fact representation +% - prefixes predicate name with problog_ +% - adds unique ID as first argument +% - adds logarithm of probability as last argument +% - keeps original arguments in between +% +% for each predicate appearing as probabilistic fact, wrapper clause is introduced: +% - head is most general instance of original fact +% - body is corresponding version of internal fact plus call to add_to_proof/2 to update current state during proving +% example: edge(A,B) :- problog_edge(ID,A,B,LogProb), add_to_proof(ID,LogProb). +% +% dynamic predicate problog_predicate(Name,Arity) keeps track of predicates that already have wrapper clause +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +user:term_expansion(_P::( _Goal :- _Body ), _Error) :- + throw(error('we do not support this (yet?)!')). + +user:term_expansion(P::Goal,Goal) :- + P \= t(_), + P =:= 1, + !. + +user:term_expansion(P::Goal, problog:ProbFact) :- + functor(Goal, Name, Arity), + atomic_concat([problog_,Name],ProblogName), + Goal =.. [Name|Args], + append(Args,[LProb],L1), + probclause_id(IDName), + term_variables(Goal,GVars), + (GVars=[] -> ID=IDName; ID=..[IDName|GVars]), + ProbFact =.. [ProblogName,ID|L1], + (P = t(TrueProb) -> + assert(tunable_fact(ID,TrueProb)), + LProb is log(0.5) + ; + LProb is log(P) + ), + problog_predicate(Name, Arity, ProblogName). + +% introduce wrapper clause if predicate seen first time +problog_predicate(Name, Arity, _) :- + problog_predicate(Name, Arity), !. +problog_predicate(Name, Arity, ProblogName) :- + functor(OriginalGoal, Name, Arity), + OriginalGoal =.. [_|Args], + append(Args,[Prob],L1), + ProbFact =.. [ProblogName,ID|L1], + prolog_load_context(module,Mod), + assert((Mod:OriginalGoal :- ProbFact, add_to_proof(ID,Prob))), + assert(problog_predicate(Name, Arity)), + ArityPlus2 is Arity+2, + dynamic(problog:ProblogName/ArityPlus2). + +% generate next global identifier +probclause_id(ID) :- + nb_getval(probclause_counter,ID), !, + C1 is ID+1, + nb_setval(probclause_counter,C1), !. +probclause_id(0) :- + nb_setval(probclause_counter,1). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% access/update the probability of ID's fact +% hardware-access version: naively scan all problog-predicates +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +get_fact_probability(ID,Prob) :- + get_internal_fact(ID,ProblogTerm,_ProblogName,ProblogArity), + arg(ProblogArity,ProblogTerm,Log), + Prob is exp(Log). +set_fact_probability(ID,Prob) :- + get_internal_fact(ID,ProblogTerm,ProblogName,ProblogArity), + retract(ProblogTerm), + ProblogTerm =.. [ProblogName|ProblogTermArgs], + nth(ProblogArity,ProblogTermArgs,_,KeepArgs), + NewLogProb is log(Prob), + nth(ProblogArity,NewProblogTermArgs,NewLogProb,KeepArgs), + NewProblogTerm =.. [ProblogName|NewProblogTermArgs], + assert(NewProblogTerm). + +get_internal_fact(ID,ProblogTerm,ProblogName,ProblogArity) :- + problog_predicate(Name,Arity), + atomic_concat([problog_,Name],ProblogName), + ProblogArity is Arity+2, + functor(ProblogTerm,ProblogName,ProblogArity), + arg(1,ProblogTerm,ID), + call(ProblogTerm). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% writing those facts with learnable parameters to File +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +export_facts(File) :- + tell(File), + export_facts, + flush_output, + told. +export_facts :- + tunable_fact(ID,_), + once(write_tunable_fact(ID)), + fail. +export_facts. + +write_tunable_fact(ID) :- + get_internal_fact(ID,ProblogTerm,ProblogName,ProblogArity), + ProblogTerm =.. [_Functor,ID|Args], + atomic_concat('problog_',OutsideFunctor,ProblogName), + Last is ProblogArity-1, + nth(Last,Args,LogProb,OutsideArgs), + OutsideTerm =.. [OutsideFunctor|OutsideArgs], + Prob is exp(LogProb), + format('~w :: ~q.~n',[Prob,OutsideTerm]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% recover fact for given id +% list version not exported (yet?) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +get_fact(ID,OutsideTerm) :- + get_internal_fact(ID,ProblogTerm,ProblogName,ProblogArity), + ProblogTerm =.. [_Functor,ID|Args], + atomic_concat('problog_',OutsideFunctor,ProblogName), + Last is ProblogArity-1, + nth(Last,Args,_LogProb,OutsideArgs), + OutsideTerm =.. [OutsideFunctor|OutsideArgs]. + +get_fact_list([],[]). +get_fact_list([ID|IDs],[Fact|Facts]) :- + get_fact(ID,Fact), + get_fact_list(IDs,Facts). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% ProbLog inference, core methods +% +% state of proving saved in two backtrackable global variables +% - problog_current_proof holds list of IDs of clauses used +% - problog_probability holds the sum of their log probabilities +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +% called "inside" probabilistic facts to update current state of proving: +% if number of steps exceeded, fail +% if fact used before, succeed and keep status as is +% if not prunable, calculate probability and +% if threshold exceeded, add stopped derivation to upper bound and fail +% else update state and succeed +add_to_proof(ID,Prob) :- + montecarlo_check(ID), + b_getval(problog_steps,MaxSteps), + b_getval(problog_probability, CurrentP), + nb_getval(problog_threshold, CurrentThreshold), + b_getval(problog_current_proof, IDs), + ( MaxSteps =< 0 -> + fail + ; + ( memberchk(ID, IDs) -> + true + ; + \+ prune_check([ID|IDs],1), + multiply_probabilities(CurrentP, Prob, NProb), + ( NProb < CurrentThreshold -> + upper_bound([ID|IDs]), + fail + ; + b_setval(problog_probability, NProb), + b_setval(problog_current_proof, [ID|IDs]) + ) + ), + Steps is MaxSteps-1, + b_setval(problog_steps,Steps) + ). + +% if in monte carlo mode, check array to see if fact can be used +montecarlo_check(ID) :- + ( + problog_control(check,mc) + -> + ( + array_element(mc_sample,ID,V), + ( + V == 1 -> true + ; + V == 2 -> fail + ; + new_sample(ID) + ) + ) + ; + true + ). + +new_sample(ID) :- + get_fact_probability(ID,Prob), + random(R), + R=1 -> don't need []=true-case for tries +upper_bound(List) :- + problog_control(on,limit), + problog_control(check,up), + reverse(List,R), + (prune_check(R,2) -> true; insert_ptree(R,2)). + +multiply_probabilities(CurrentLogP, LogProb, NLogProb) :- + NLogProb is CurrentLogP+LogProb. + +% this is called by all inference methods before the actual ProbLog goal +% to set up environment for proving +init_problog(Threshold) :- + LT is log(Threshold), + b_setval(problog_probability, 0.0), + b_setval(problog_current_proof, []), + nb_setval(problog_threshold, LT), + problog_flag(maxsteps,MaxS), + b_setval(problog_steps, MaxS), + problog_control(off,limit). + +% idea: proofs that are refinements of known proof can be pruned as they don't add probability mass +% note that current ptree implementation doesn't provide the check as there's no efficient method known so far... +prune_check(Proof,TreeID) :- + problog_flag(prunecheck,on), + prune_check_ptree(Proof,TreeID). + +% to call a ProbLog goal, patch all subgoals with the user's module context +% (as logical part is there, but probabilistic part in problog) +problog_call(Goal) :- + yap_flag(typein_module,Module), + put_module(Goal,Module,ModGoal), + call(ModGoal). + +put_module((Mod:Goal,Rest),Module,(Mod:Goal,Transformed)) :- + !, + put_module(Rest,Module,Transformed). +put_module((Goal,Rest),Module,(Module:Goal,Transformed)) :- + !, + put_module(Rest,Module,Transformed). +put_module((Mod:Goal),_Module,(Mod:Goal)) :- + !. +put_module(Goal,Module,Module:Goal). + +% end of core + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% evaluating a DNF given as trie using BDD +% input: ID of trie to be used +% output: probability and status (to catch potential failures/timeouts from outside) +% +% with internal BDD timeout (set using problog flag bdd_time) +% +% bdd_ptree/3 constructs files for ProblogBDD from the trie +% +% if calling ProblogBDD doesn't exit successfully, status will be timeout +% +% writes number of proofs in trie and BDD time to standard user output +% +% if remember is on, input files for ProblogBDD will be saved +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +eval_dnf(ID,Prob,Status) :- + ((ID = 1, problog_flag(save_bdd,true)) -> problog_control(on,remember); problog_control(off,remember)), + count_ptree(ID,NX), + format(user,'~w proofs~n',[NX]), + problog_flag(dir,DirFlag), + problog_flag(bdd_file,BDDFileFlag), + atomic_concat([DirFlag,BDDFileFlag],BDDFile), + problog_flag(bdd_par_file,BDDParFileFlag), + atomic_concat([DirFlag,BDDParFileFlag],BDDParFile), + (problog_control(check,remember) -> + bdd_ptree_map(ID,BDDFile,BDDParFile,Mapping), + atomic_concat([DirFlag,'save_map'],MapFile), + tell(MapFile), + format('mapping(~q).~n',[Mapping]), + flush_output, + told + ; + bdd_ptree(ID,BDDFile,BDDParFile) + ), + problog_flag(bdd_time,BDDTime), + problog_flag(bdd_result,ResultFileFlag), + atomic_concat([DirFlag,ResultFileFlag],ResultFile), + problog_dir(PD), + atomic_concat([PD,'/ProblogBDD -l ',BDDFile,' -i ',BDDParFile,' -m p -t ', BDDTime,' > ', ResultFile],Command), + statistics(walltime,_), + shell(Command,Return), + ( + Return =\= 0 + -> + Status = timeout + ; + ( + statistics(walltime,[_,E3]), + format(user,'~w ms BDD processing~n',[E3]), + see(ResultFile), + read(probability(Prob)), + seen, + delete_file(ResultFile), + Status = ok + ) + ), + (problog_control(check,remember) -> + atomic_concat([DirFlag,'save_script'],SaveBDDFile), + rename_file(BDDFile,SaveBDDFile), + atomic_concat([DirFlag,'save_params'],SaveBDDParFile), + rename_file(BDDParFile,SaveBDDParFile) + ; + true + ), + problog_control(off,remember). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% different inference methods +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% approximate inference: bounds based on single probability threshold +% problog_threshold(+Goal,+Threshold,-LowerBound,-UpperBound,-Status) +% +% use backtracking over problog_call to get all solutions +% +% trie 1 collects proofs, trie 2 collects stopped derivations, trie 3 is used to unit them for the upper bound +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +problog_threshold(Goal, Threshold, _, _, _) :- + problog_control(on,up), + init_problog_threshold(Threshold), + problog_call(Goal), + add_solution, + fail. +problog_threshold(_, _, LP, UP, Status) :- + compute_bounds(LP, UP, Status). + +init_problog_threshold(Threshold) :- + init_ptree(1), + init_ptree(2), + init_problog(Threshold). + +add_solution :- + b_getval(problog_current_proof, IDs), + (IDs == [] -> R = true ; reverse(IDs,R)), + insert_ptree(R,1). + +compute_bounds(LP, UP, Status) :- + eval_dnf(1,LP,StatusLow), + (StatusLow \== ok -> + Status = StatusLow + ; + merge_ptree(1,2,3), + eval_dnf(3,UP,Status)), + delete_ptree(1), + delete_ptree(2), + delete_ptree(3). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% approximate inference: lower bound based on all proofs above probability threshold +% problog_low(+Goal,+Threshold,-LowerBound,-Status) +% +% same as problog_threshold/5, but lower bound only (no stopped derivations stored) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +problog_low(Goal, Threshold, _, _) :- + problog_control(off,up), + init_problog_low(Threshold), + problog_call(Goal), + add_solution, + fail. +problog_low(_, _, LP, Status) :- + eval_dnf(1,LP,Status), + delete_ptree(1). + +init_problog_low(Threshold) :- + init_ptree(1), + init_problog(Threshold). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% approximate inference: bounds by iterative deepening up to interval width Delta +% problog_delta(+Goal,+Delta,-LowerBound,-UpperBound,-Status) +% +% wraps iterative deepening around problog_threshold, i.e. +% - starts with threshold given by first_threshold flag +% - if Up-Low >= Delta, multiply threshold by factor given in id_stepsize flag and iterate +% (does not use problog_threshold as trie 1 is kept over entire search) +% +% local dynamic predicates low/2, up/2, stopDiff/1 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +problog_delta(Goal, Delta, Low, Up, Status) :- + problog_control(on,up), + problog_flag(first_threshold,InitT), + init_problog_delta(InitT,Delta), + problog_delta_id(Goal,Status), + delete_ptree(1), + delete_ptree(2), + (retract(low(_,Low)) -> true; true), + (retract(up(_,Up)) -> true; true). + + +init_problog_delta(Threshold,Delta) :- + retractall(low(_,_)), + retractall(up(_,_)), + retractall(stopDiff(_)), + init_ptree(1), + init_ptree(2), + assert(low(0,0.0)), + assert(up(0,1.0)), + assert(stopDiff(Delta)), + init_problog(Threshold). + +problog_delta_id(Goal, _) :- + problog_call(Goal), + add_solution, % reused from problog_threshold + fail. +problog_delta_id(Goal, Status) :- + evaluateStep(Ans,StatusE), + problog_flag(last_threshold_log,Stop), + nb_getval(problog_threshold,Min), + (StatusE \== ok -> + Status = StatusE + ; + ( + Ans = 1 -> + Status = ok + ; + Min =< Stop -> + Status = stopreached + ; + problog_control(check,limit) -> + problog_control(off,limit), + problog_flag(id_stepsize_log,Step), + New is Min+Step, + nb_setval(problog_threshold,New), + problog_delta_id(Goal, Status) + ; + true + )). + +% call the dnf evaluation where needed +evaluateStep(Ans,Status) :- once(evalStep(Ans,Status)). + +evalStep(Ans,Status) :- + stopDiff(Delta), + count_ptree(1,NProofs), + count_ptree(2,NCands), + format(user,'~w proofs, ~w stopped derivations~n',[NProofs,NCands]), + flush_output(user), + eval_lower(NProofs,Low,StatusLow), + (StatusLow \== ok -> + Status = StatusLow + ; + up(_,OUP), + IntDiff is OUP-Low, + ((IntDiff < Delta; IntDiff =:= 0) -> + Up=OUP, StatusUp = ok + ; + eval_upper(NCands,Up,StatusUp), + delete_ptree(2), + init_ptree(2), + delete_ptree(3) + ), + (StatusUp \== ok -> + Status = StatusUp + ; + Diff is Up-Low, + format(user,'difference: ~6f~n',[Diff]), + flush_output(user), + ((Diff < Delta; Diff =:= 0) -> Ans = 1; Ans = 0), + Status = ok)). + +% no need to re-evaluate if no new proofs found on this level +eval_lower(N,P,ok) :- + low(N,P). +% evaluate if there are proofs +eval_lower(N,P,Status) :- + N > 0, + low(OldN,_), + N \= OldN, + eval_dnf(1,P,Status), + (Status = ok -> + retract(low(_,_)), + assert(low(N,P)), + format(user,'lower bound: ~6f~n',[P]), + flush_output(user) + ; + true). + +% if no stopped derivations, up=low +eval_upper(0,P,ok) :- + retractall(up(_,_)), + low(N,P), + assert(up(N,P)). +% else merge proofs and stopped derivations to get upper bound +% in case of timeout or other problems, skip and use bound from last level +eval_upper(N,UpP,ok) :- + N > 0, + merge_ptree(1,2,3), + eval_dnf(3,UpP,StatusUp), + (StatusUp = ok -> + retract(up(_,_)), + assert(up(N,UpP)) + ; + format(user,'~w - continue using old up~n',[StatusUp]), + flush_output(user), + up(_,UpP)). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% explanation probability - returns list of facts used or constant 'unprovable' as third argument +% problog_max(+Goal,-Prob,-Facts) +% +% uses iterative deepening with samw parameters as bounding algorithm +% threshold gets adapted whenever better proof is found +% +% uses local dynamic predicates max_probability/1 and max_proof/1 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +problog_max(Goal, Prob, Facts) :- + problog_control(off,up), + problog_flag(first_threshold,InitT), + init_problog_max(InitT), + problog_max_id(Goal, Prob, FactIDs), + ( FactIDs == unprovable -> Facts = unprovable; + get_fact_list(FactIDs,Facts)). + +init_problog_max(Threshold) :- + retractall(max_probability(_)), + retractall(max_proof(_)), + assert(max_probability(-999999)), + assert(max_proof(unprovable)), + init_problog(Threshold). + +update_max :- + b_getval(problog_probability,CurrP), + max_probability(MaxP), + (CurrP =< MaxP -> + fail + ; + b_getval(problog_current_proof, IDs), + reverse(IDs,R), + retractall(max_proof(_)), + assert(max_proof(R)), + nb_setval(problog_threshold, CurrP), + retractall(max_probability(_)), + assert(max_probability(CurrP))). + +problog_max_id(Goal, _Prob, _Clauses) :- + problog_call(Goal), + update_max, + fail. +problog_max_id(Goal, Prob, Clauses) :- + max_probability(MaxP), + nb_getval(problog_threshold, LT), + problog_flag(last_threshold_log,ToSmall), + ((MaxP >= LT ; \+ problog_control(check,limit); LT < ToSmall) -> + max_proof(Clauses), + Prob is exp(MaxP) + ; + problog_flag(id_stepsize_log,Step), + NewLT is LT+Step, + nb_setval(problog_threshold, NewLT), + problog_control(off,limit), + problog_max_id(Goal, Prob, Clauses)). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% lower bound using k best proofs +% problog_kbest(+Goal,+K,-Prob,-Status) +% +% does iterative deepening search similar to problog_max, but for k(>=1) most likely proofs +% afterwards uses BDD evaluation to calculate probability (also for k=1 -> uniform treatment in learning) +% +% uses dynamic local predicate current_kbest/3 to collect proofs, +% only builds trie at the end (as probabilities of single proofs are important here) +% +% note: >k proofs will be used if the one at position k shares its probability with others, +% as all proofs with that probability will be included +% +% version with _save at the end renames files for ProblogBDD to keep them +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +problog_kbest_save(Goal, K, Prob, Status, BDDFile, ParamFile) :- + problog_kbest(Goal, K, Prob, Status), + ( Status=ok -> + problog_flag(bdd_file,InternBDDFlag), + problog_flag(bdd_par_file,InternParFlag), + problog_flag(dir,DirFlag), + atomic_concat([DirFlag,InternBDDFlag],InternBDD), + atomic_concat([DirFlag,InternParFlag],InternPar), + rename_file(InternBDD,BDDFile), + rename_file(InternPar,ParamFile) + ; + true). + +problog_kbest(Goal, K, Prob, Status) :- + problog_control(off,up), + problog_flag(first_threshold,InitT), + init_problog_kbest(InitT), + problog_kbest_id(Goal, K), + retract(current_kbest(_,ListFound,_NumFound)), + build_prefixtree(ListFound), + eval_dnf(1,Prob,Status), + delete_ptree(1). + +init_problog_kbest(Threshold) :- + retractall(current_kbest(_,_,_)), + assert(current_kbest(-999999,[],0)), %(log-threshold,proofs,num_proofs) + init_ptree(1), + init_problog(Threshold). + +problog_kbest_id(Goal, K) :- + problog_call(Goal), + update_kbest(K), + fail. +problog_kbest_id(Goal, K) :- + current_kbest(CurrentBorder,_,Found), + nb_getval(problog_threshold, Min), + problog_flag(last_threshold_log,ToSmall), + ((Found>=K ; \+ problog_control(check,limit) ; Min < CurrentBorder ; Min < ToSmall) -> + true + ; + problog_flag(id_stepsize_log,Step), + NewLT is Min+Step, + nb_setval(problog_threshold, NewLT), + problog_control(off,limit), + problog_kbest_id(Goal, K)). + +update_kbest(K) :- + b_getval(problog_probability,NewLogProb), + current_kbest(LogThreshold,_,_), + (NewLogProb>=LogThreshold -> + b_getval(problog_current_proof,RevProof), + reverse(RevProof,Proof), + update_current_kbest(K,NewLogProb,Proof) + ; + fail). + +update_current_kbest(_,NewLogProb,Cl) :- + current_kbest(_,List,_), + memberchk(NewLogProb-Cl,List), + !. +update_current_kbest(K,NewLogProb,Cl) :- + retract(current_kbest(OldThres,List,Length)), + sorted_insert(NewLogProb-Cl,List,NewList), + NewLength is Length+1, + (NewLength < K -> + assert(current_kbest(OldThres,NewList,NewLength)) + ; + (NewLength>K -> + First is NewLength-K+1, + cutoff(NewList,NewLength,First,FinalList,FinalLength) + ; FinalList=NewList, FinalLength=NewLength), + FinalList=[NewThres-_|_], + nb_setval(problog_threshold,NewThres), + assert(current_kbest(NewThres,FinalList,FinalLength))). + +sorted_insert(A,[],[A]). +sorted_insert(A-LA,[B1-LB1|B], [A-LA,B1-LB1|B] ) :- + A =< B1. +sorted_insert(A-LA,[B1-LB1|B], [B1-LB1|C] ) :- + A > B1, + sorted_insert(A-LA,B,C). + +% keeps all entries with lowest probability, even if implying a total of more than k +cutoff(List,Len,1,List,Len) :- !. +cutoff([P-L|List],Length,First,[P-L|List],Length) :- + nth(First,[P-L|List],PF-_), + PF=:=P, + !. +cutoff([_|List],Length,First,NewList,NewLength) :- + NextFirst is First-1, + NextLength is Length-1, + cutoff(List,NextLength,NextFirst,NewList,NewLength). + +build_prefixtree([]). +build_prefixtree([_-[]|_List]) :- + !, + insert_ptree(true,1). +build_prefixtree([_-L|List]) :- + insert_ptree(L,1), + build_prefixtree(List). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% exact probability +% problog_exact(+Goal,-Prob,-Status) +% +% using all proofs = using all proofs with probability > 0 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +problog_exact(Goal,Prob,Status) :- + problog_low(Goal,0,Prob,Status). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% probability by sampling: +% running another N samples until 95percentCI-width Next is PositiveSoFar+1; Next=PositiveSoFar), + Prob is Next/SamplesNew, + Epsilon is 2*sqrt(Prob*(1-Prob)/SamplesNew), + Low is Prob-Epsilon, + High is Prob+Epsilon, + Diff is 2*Epsilon, + statistics(walltime,[T2,_]), + Time is (T2-InitialTime)/1000, + count_ptree(1,CacheSize), + format('~n~w samples~nestimated probability ~w~n95 percent confidence interval [~w,~w]~n',[SamplesNew,Prob,Low,High]), + open(File,append,Log), + format(Log,'~w ~8f ~8f ~8f ~8f ~3f ~w ~w~n',[SamplesNew,Prob,Low,High,Diff,Time,CacheSize,Next]), + close(Log), + ((Diff format('Runtime ~w sec~2n',[Time]),assert(mc_prob(Prob)) + ; + montecarlo(Goal,Delta,K,SamplesNew,File,Next,InitialTime)). + +% continue until next K samples done +montecarlo(Goal,Delta,K,SamplesSoFar,File,PositiveSoFar,InitialTime) :- + SamplesNew is SamplesSoFar+1, + copy_term(Goal,GoalC), + (mc_prove(GoalC) -> Next is PositiveSoFar+1; Next=PositiveSoFar), + montecarlo(Goal,Delta,K,SamplesNew,File,Next,InitialTime). + +mc_prove(A) :- !, + (get_some_proof(A) -> + clean_sample + ; + clean_sample,fail + ). + +clean_sample :- + reset_static_array(mc_sample), + fail. +clean_sample. + +% find new proof +get_some_proof(Goal) :- + init_problog(0), + problog_call(Goal), + b_getval(problog_current_proof,Used), + (Used == [] -> Proof=true; reverse(Used,Proof)), + insert_ptree(Proof,1). + diff --git a/packages/ProbLog/problog/flags.yap b/packages/ProbLog/problog/flags.yap new file mode 100644 index 000000000..024c837c0 --- /dev/null +++ b/packages/ProbLog/problog/flags.yap @@ -0,0 +1,284 @@ +%%% -*- Mode: Prolog; -*- + +:- module(flags, [set_problog_flag/2, + problog_flag/2, + problog_flags/0]). + +:- style_check(all). +:- yap_flag(unknown,error). + +:- use_module(print, [print_param/4, + print_sep_line/0]). + +:- ensure_loaded(library(system)). + +:- dynamic bdd_time/1, first_threshold/1, last_threshold/1, id_stepsize/1, prunecheck/1, maxsteps/1, mc_batchsize/1, mc_logfile/1, bdd_file/1, bdd_par_file/1, bdd_result/1, work_dir/1, save_bdd/1. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% global parameters that can be set using set_problog_flag/2 +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +problog_flag(Flag,Option) :- + get_problog_flag(Flag,Option). +get_problog_flag(bdd_time,X) :- + bdd_time(X). +get_problog_flag(first_threshold,X) :- + first_threshold(X). +get_problog_flag(last_threshold,X) :- + last_threshold(L), + X is exp(L). +get_problog_flag(last_threshold_log,X) :- + last_threshold(X). +get_problog_flag(id_stepsize,X) :- + id_stepsize(L), + X is exp(L). +get_problog_flag(id_stepsize_log,X) :- + id_stepsize(X). +get_problog_flag(prunecheck,X) :- + prunecheck(X). +get_problog_flag(maxsteps,X) :- + maxsteps(X). +get_problog_flag(mc_batchsize,X) :- + mc_batchsize(X). +get_problog_flag(mc_logfile,X) :- + mc_logfile(X). +get_problog_flag(bdd_file,X) :- + bdd_file(X). +get_problog_flag(bdd_par_file,X) :- + bdd_par_file(X). +get_problog_flag(bdd_result,X) :- + bdd_result(X). +get_problog_flag(dir,X) :- + work_dir(X). +get_problog_flag(save_bdd,X) :- + save_bdd(X). + +%%%%%%%%%%%% +% BDD timeout in seconds, used as option in BDD tool +%%%%%%%%%%%% + +set_problog_flag(bdd_time,X) :- + (\+ integer(X); X<0), + !, + format(user,'\% ERROR: value must be positive integer!~n',[]), + flush_output(user), + fail. +set_problog_flag(bdd_time,X) :- + retractall(bdd_time(_)), + assert(bdd_time(X)). + + +%%%%%%%%%%%% +% iterative deepening on minimal probabilities (delta, max, kbest): +% - first threshold (not in log-space as only used to retrieve argument for init_threshold/1, which is also used with user-supplied argument) +% - last threshold to ensure termination in case infinite search space (saved in log-space for easy comparison with current values during search) +% - factor used to decrease threshold for next level, NewMin=Factor*OldMin (saved in log-space) +%%%%%%%%%%%% + +set_problog_flag(first_threshold,X) :- + (\+ number(X); X<0 ; X>1), + !, + format(user,'\% ERROR: value must be in [0,1]!~n',[]), + flush_output(user), + fail. +set_problog_flag(first_threshold,X) :- + retractall(first_threshold(_)), + assert(first_threshold(X)). + +set_problog_flag(last_threshold,X) :- + (\+ number(X); X<0 ; X>1), + !, + format(user,'\% ERROR: value must be in [0,1]!~n',[]), + flush_output(user), + fail. +set_problog_flag(last_threshold,X) :- + retractall(last_threshold(_)), + L is log(X), + assert(last_threshold(L)). + +set_problog_flag(id_stepsize,X) :- + (\+ number(X); X=<0 ; X>=1), + !, + format(user,'\% ERROR: value must be in ]0,1[!~n',[]), + flush_output(user), + fail. +set_problog_flag(id_stepsize,X) :- + retractall(id_stepsize(_)), + L is log(X), + assert(id_stepsize(L)). + + +%%%%%%%%%%%% +% prune check stops derivations if they use a superset of facts already known to form a proof +% (very) costly test, can be switched on/off here +%%%%%%%%%%%% + +set_problog_flag(prunecheck,on) :- + !, + format(user,'WARNING: prune check not implemented, will fail~n',[]), + flush_output(user), + retractall(prunecheck(_)), + assert(prunecheck(on)). +set_problog_flag(prunecheck,off) :- + !, + retractall(prunecheck(_)), + assert(prunecheck(off)). +set_problog_flag(prunecheck,_) :- + format(user,'\% ERROR: value must be \'on\' or \'off\'!~n',[]), + flush_output(user), + fail. + +%%%%%%%%%%%% +% max number of calls to probabilistic facts per derivation (to ensure termination) +%%%%%%%%%%%% + +set_problog_flag(maxsteps,X) :- + (\+ integer(X); X<0), + !, + format(user,'\% ERROR: value must be positive integer!~n',[]), + flush_output(user), + fail. +set_problog_flag(maxsteps,X) :- + retractall(maxsteps(_)), + assert(maxsteps(X)). + + +%%%%%%%%%%%% +% montecarlo: recalculate current approximation after N samples +%%%%%%%%%%%% + +set_problog_flag(mc_batchsize,X) :- + (\+ integer(X); X<0), + !, + format(user,'\% ERROR: value must be positive integer!~n',[]), + flush_output(user), + fail. +set_problog_flag(mc_batchsize,X) :- + retractall(mc_batchsize(_)), + assert(mc_batchsize(X)). + +%%%%%%%%%%%% +% montecarlo: write log to this file +%%%%%%%%%%%% + +set_problog_flag(mc_logfile,X) :- + \+ atom(X), + !, + format(user,'\% ERROR: value must be atom!~n',[]), + flush_output(user), + fail. +set_problog_flag(mc_logfile,X) :- + retractall(mc_logfile(_)), + assert(mc_logfile(X)). + +%%%%%%%%%%%% +% files to write BDD script and pars +% bdd_file overwrites bdd_par_file with matching extended name +% if different name wanted, respect order when setting +%%%%%%%%%%%% + +set_problog_flag(bdd_file,X) :- + \+ atom(X), + !, + format(user,'\% ERROR: value must be atom!~n',[]), + flush_output(user), + fail. +set_problog_flag(bdd_file,X) :- + retractall(bdd_file(_)), + atomic_concat(X,'_probs',Y), + set_problog_flag(bdd_par_file,Y), + atomic_concat(X,'_res',Z), + set_problog_flag(bdd_result,Z), + assert(bdd_file(X)). +set_problog_flag(bdd_par_file,X) :- + \+ atom(X), + !, + format(user,'\% ERROR: value must be atom!~n',[]), + flush_output(user), + fail. +set_problog_flag(bdd_par_file,X) :- + retractall(bdd_par_file(_)), + assert(bdd_par_file(X)). +set_problog_flag(bdd_result,X) :- + \+ atom(X), + !, + format(user,'\% ERROR: value must be atom!~n',[]), + flush_output(user), + fail. +set_problog_flag(bdd_result,X) :- + retractall(bdd_result(_)), + assert(bdd_result(X)). + +%%%%%%%%%%%% +% working directory: all the temporary and output files will be located there +%%%%%%%%%%%% +set_problog_flag(dir,X) :- + \+ atom(X), + !, + format(user,'\% ERROR: value must be atom!~n',[]), + flush_output(user), + fail. +set_problog_flag(dir,X) :- + retractall(work_dir(_)), + atomic_concat([X,'/'],D), + atomic_concat(['mkdir ',D],Mkdir), + (file_exists(X) -> true; shell(Mkdir)), + assert(work_dir(D)). + +%%%%%%%%%%%% +% save BDD information for the (last) lower bound BDD used during inference +% produces three files named save_script, save_params, save_map +% located in the directory given by problog_flag dir +%%%%%%%%%%%% + +set_problog_flag(save_bdd,true) :- + !, + retractall(save_bdd(_)), + assert(save_bdd(true)). +set_problog_flag(save_bdd,false) :- + !, + retractall(save_bdd(_)), + assert(save_bdd(false)). +set_problog_flag(save_bdd,_) :- + format(user,'\% ERROR: value must be \'true\' or \'false\'!~n',[]), + flush_output(user), + fail. + + +%%%%%%%%%%%%%%%%%%%%%%%% +% show values +%%%%%%%%%%%%%%%%%%%%%%%% + +problog_flags :- + format('~n',[]), + print_sep_line, + format('problog flags: use set_problog_flag(Flag,Option) to change, problog_flag(Flag,Option) to view~n',[]), + print_sep_line, + print_param(description,value,flag,option), + print_sep_line, + problog_flag(bdd_time,StopBDD), + print_param('BDD computation timeout in seconds',StopBDD,'bdd_time','positive integer'), + problog_flag(first_threshold,First), + print_param('starting threshold iterative deepening',First,'first_threshold','0 =< Option =< 1'), + problog_flag(last_threshold,Last), + print_param('stopping threshold iterative deepening',Last,'last_threshold','0 =< Option =< 1'), + problog_flag(id_stepsize,Decrease), + print_param('threshold shrinking factor iterative deepening',Decrease,'id_stepsize','0 < Option < 1'), + problog_flag(prunecheck,Check), + print_param('stop derivations including all facts of known proof',Check,'prunecheck','on/off'), + problog_flag(maxsteps,Steps), + print_param('max. number of prob. steps per derivation',Steps,'maxsteps','positive integer'), + problog_flag(mc_batchsize,MCBatch), + print_param('number of samples before update in montecarlo',MCBatch,'mc_batchsize','positive integer'), + problog_flag(mc_logfile,MCFile), + print_param('logfile for montecarlo',MCFile,'mc_logfile','atom'), + problog_flag(bdd_file,BDDFile), + print_param('file for BDD script',BDDFile,'bdd_file','atom'), + problog_flag(dir,WorkDir), + print_param('directory for files',WorkDir,'dir','atom'), + problog_flag(save_bdd,Save), + print_param('save BDD files for (last) lower bound',Save,'save_bdd','true/false'), + print_sep_line, + format('~n',[]), + flush_output. + diff --git a/packages/ProbLog/problog/print.yap b/packages/ProbLog/problog/print.yap new file mode 100644 index 000000000..a475ce29a --- /dev/null +++ b/packages/ProbLog/problog/print.yap @@ -0,0 +1,24 @@ +%%% -*- Mode: Prolog; -*- +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% printing functions used for problog_help and problog_flags +% collected here to have formatting at one place +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +:- module(print, [print_param/4, + print_sep_line/0, + print_inference/2]). + +print_param(Keyword,Value,Function,Legal) :- + format(user,'~w~55+~q~15+~w~30+~w~25+~n',[Keyword,Value,Function,Legal]). +print_sep_line :- + sep_line(125). +sep_line(0) :- + !, + format('~n',[]). +sep_line(N) :- + format('-',[]), + NN is N-1, + sep_line(NN). + +print_inference(Call,Description) :- + format(user,'~w~65+~w~60+~n',[Call,Description]). diff --git a/packages/ProbLog/problog/tptree.yap b/packages/ProbLog/problog/tptree.yap new file mode 100644 index 000000000..a4fc28ee5 --- /dev/null +++ b/packages/ProbLog/problog/tptree.yap @@ -0,0 +1,500 @@ +%%% -*- Mode: Prolog; -*- + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% prefix-trees for managing a DNF +% remembers shortest prefix of a conjunction only (i.e. a*b+a*b*c results in a*b only, but b*a+a*b*c is not reduced) +% children are sorted, but branches aren't (to speed up search while keeping structure sharing from proof procedure) +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +:- module(ptree,[init_ptree/1, + delete_ptree/1, + rename_ptree/2, + member_ptree/2, + enum_member_ptree/2, + insert_ptree/2, + delete_ptree/2, + edges_ptree/2, + count_ptree/2, + prune_check_ptree/2, + empty_ptree/1, + merge_ptree/3, + bdd_ptree/3, + bdd_ptree_map/4 + ]). + +:- use_module(library(tries), + [ + trie_open/1, + trie_close/1, + trie_stats/4, + trie_check_entry/3, + trie_get_entry/2, + trie_put_entry/3, + trie_remove_entry/1, + trie_usage/4, + trie_dup/2, + trie_join/2, + trie_traverse/2 + ]). + +:- use_module(library(ordsets), + [ + ord_subset/2 + ]). + +:- style_check(all). +:- yap_flag(unknown,error). + +:- use_module(flags,[problog_flag/2]). +:- ensure_loaded(library(lists)). +:- ensure_loaded(library(system)). + +% name lexicon external - internal +sym(1,tree1) :- !. +sym(2,tree2) :- !. +sym(3,tree3) :- !. +sym(N,AN) :- atomic_concat([tree,N],AN). + +%%%%%%%%%%%%%%%%%%%%%%%% +% ptree basics +%%%%%%%%%%%%%%%%%%%%%%%% + +init_ptree(ID) :- + sym(ID,Sym), + trie_open(Trie), + nb_setval(Sym, Trie). + +delete_ptree(ID) :- + sym(ID,Sym), + nb_getval(Sym, Trie), !, + trie_close(Trie), + trie_open(NewTrie), + nb_setval(Sym, NewTrie). +delete_ptree(_). + +rename_ptree(OldID,NewID) :- + sym(OldID,OldSym), + sym(NewID,NewSym), + nb_getval(OldSym, Trie), + nb_set_shared_val(NewSym, Trie). + +empty_ptree(ID) :- + sym(ID,Sym), + nb_getval(Sym, Trie), + trie_usage(Trie, 0, 0, 0). + + +%%%%%%%%%%%%%%%%%%%%%%%% +% member +%%%%%%%%%%%%%%%%%%%%%%%% + +% non-backtrackable (to check) +member_ptree(List,ID) :- + sym(ID,Sym), + nb_getval(Sym, Trie), + trie_check_entry(Trie, List, _). + +% backtrackable (to list) +enum_member_ptree(ID,List) :- + sym(ID,Sym), + nb_getval(Sym, Tree), + trie_path(Tree, List). + +trie_path(Tree, List) :- + trie_traverse(Tree,Ref), + trie_get_entry(Ref, List). + +%%%%%%%%%%%%%%%%%%%%%%%% +% insert conjunction +%%%%%%%%%%%%%%%%%%%%%%%% +insert_ptree(true,ID) :- + sym(ID,Sym), + !, + nb_getval(Sym, Trie), + trie_close(Trie), + trie_open(NTrie), + trie_put_entry(NTrie, true, _). +insert_ptree(List,ID) :- + sym(ID,Sym), + nb_getval(Sym, Trie), + trie_put_entry(Trie, List, _). + +%%%%%%%%%%%%%%%%%%%%%%%% +% delete conjunction +%%%%%%%%%%%%%%%%%%%%%%%% +delete_ptree(List,ID) :- + sym(ID,Sym), + nb_getval(Sym, Trie), + trie_check_entry(Trie, List, Ref), + trie_remove_entry(Ref). + + +%%%%%%%% +% return list -Edges of all edge labels in ptree +% doesn't use any heuristic to order those for the BDD +% (automatic reordering has to do the job) +%%%%%%%%% +edges_ptree(ID,[]) :- + empty_ptree(ID), + !. +edges_ptree(ID,[]) :- + sym(ID,Sym), + nb_getval(Sym, Trie), + trie_check_entry(Trie, true, _), + !. +edges_ptree(ID,Edges) :- + sym(ID,Sym), + nb_getval(Sym, Trie), + setof(X, trie_literal(Trie, X), Edges). + +trie_literal(Trie, X) :- + trie_traverse(Trie,Ref), + trie_get_entry(Ref, List), + member(X, List). + +%%%%%%%% +% number of conjunctions in the tree +%%%%%%%%% + +count_ptree(ID,N) :- + sym(ID,Sym), + nb_getval(Sym, Trie), + trie_usage(Trie, N, _, _). + +%%%%%%%% +% check whether some branch of ptree is a subset of conjunction List +% useful for pruning the search for proofs (optional due to time overhead) +% currently not implemented, just fails +%%%%%%% + +prune_check_ptree(_List,_TreeID) :- + format(user,'FAIL: prune check currently not supported~n',[]), + flush_output(user), + fail. + +%%%%%%%%%%%%% +% merge two ptrees +% - take care not to loose proper prefixes that are proofs! +%%%%%%%%%%%%%%% + +merge_ptree(ID1,_,ID3) :- + sym(ID1,Sym1), + sym(ID3,Sym3), + nb_getval(Sym1, T1), + trie_check_entry(T1, true, _), + !, + trie_open(T3), + trie_put_entry(T3, true, _), + nb_setval(Sym3, T3). +merge_ptree(_,ID2,ID3) :- + sym(ID2,Sym2), + sym(ID3,Sym3), + nb_getval(Sym2, T2), + trie_check_entry(T2, true, _), + !, + trie_open(T3), + trie_put_entry(T3, true, _), + nb_setval(Sym3, T3). +merge_ptree(ID1,ID2,ID3) :- + sym(ID1,Sym1), + sym(ID2,Sym2), + sym(ID3,Sym3), + nb_getval(Sym1, T1), + nb_getval(Sym2, T2), + trie_dup(T1, T3), + trie_join(T3,T2), + nb_setval(Sym3, T3). + + +%%%%%%%%%%%%%%%%%%%%%%%% +% write BDD info for given ptree to file +% - initializes leaf BDDs (=variables) first +% - then compresses ptree to exploit subtree sharing +% - bdd_pt/1 does the work on the structure itself +%%%%%%%%%%%%%%%%%%%%%%%% + +bdd_ptree(ID,FileBDD,FileParam) :- + bdd_ptree_script(ID,FileBDD,FileParam), + eraseall(map). + +% version returning variable mapping +bdd_ptree_map(ID,FileBDD,FileParam,Mapping) :- + bdd_ptree_script(ID,FileBDD,FileParam), + findall(X,recorded(map,X,_),Map), + add_probs(Map,Mapping), + eraseall(map). + +add_probs([],[]). +add_probs([m(A,Name)|Map],[m(A,Name,Prob)|Mapping]) :- + problog:get_fact_probability(A,Prob), + add_probs(Map,Mapping). + +% number of variables may be to high: +% counted on trie, but conversion to old tree representation +% transforms A*B+A to A (prefix-test) +bdd_ptree_script(ID,FileBDD,FileParam) :- + edges_ptree(ID,Edges), + tell(FileParam), + bdd_vars_script(Edges), + flush_output, + told, + length(Edges,VarCount), + assert(c_num(1)), + bdd_pt(ID,CT), + c_num(NN), + IntermediateSteps is NN-1, + tell(FileBDD), + format('@BDD1~n~w~n~w~n~w~n',[VarCount,0,IntermediateSteps]), + output_compressed_script(CT), + told, + retractall(c_num(_)), + retractall(compression(_,_)). + +% write parameter file by iterating over all var/not(var) occuring in the tree +bdd_vars_script(Edges) :- + bdd_vars_script(Edges,0). +bdd_vars_script([],_). +bdd_vars_script([A|B],N) :- + problog:get_fact_probability(A,P), + get_var_name(A,NameA), + format('@~w~n~12f~n',[NameA,P]), + NN is N+1, + bdd_vars_script(B,NN). + +%%%%%%%%%%%%%%%%%%%%%%%% +% find top level symbol for script +%%%%%%%%%%%%%%%%%%%%%%%% + +% special cases: variable-free formulae +bdd_pt(ID,false) :- + empty_ptree(ID), + !, + once(retractall(c_num(_))), + once(assert(c_num(2))). +bdd_pt(ID,true) :- + sym(ID,Sym), + nb_getval(Sym, Trie), + trie_check_entry(Trie, true, _), + !, + once(retractall(c_num(_))), + once(assert(c_num(2))). + +% general case: transform trie to nested tree structure for compression +bdd_pt(ID,CT) :- + sym(ID,Sym), + nb_getval(Sym, Trie), + trie_to_tree(Trie, Tree), + compress_pt(Tree,CT). + +trie_to_tree(Trie, Tree) :- + findall(Path,trie_path(Trie, Path), Paths), + add_trees(Paths, [], Tree). + +add_trees([], Tree, Tree). +add_trees([List|Paths], Tree0, Tree) :- + ins_pt(List, Tree0, TreeI), + add_trees(Paths, TreeI, Tree). + +ins_pt([],_T,[]) :- !. +ins_pt([A|B],[s(A1,AT)|OldT],NewT) :- + compare(Comp, A1, A), + (Comp == = -> + (AT == [] -> + NewT=[s(A1,AT)|OldT] + ; + NewT = [s(A1,NewAT)|OldT], + ins_pt(B, AT, NewAT)) + ; + Comp == > -> + NewT = [s(A1,AT)|Tree], + ins_pt([A|B], OldT, Tree) + ; + NewT = [s(A,BTree),s(A1,AT)|OldT], + ins_pt(B,[],BTree) + ). +ins_pt([A|B],[],[s(A,NewAT)]) :- + ins_pt(B,[],NewAT). + +%%%%%%%%%%%% +% BDD compression: alternates and- and or-levels to build BDD bottom-up +% each sub-BDD will be either a conjunction of a one-node BDD with some BDD or a disjunction of BDDs +% uses the internal database to temporarily store a map of components +%%%%%%%%%%%% + +% T is completely compressed and contains single variable +% i.e. T of form x12 +compress_pt(T,TT) :- + atom(T), + test_var_name(T), + !, + get_next_name(TT), + assertz(compression(TT,[T])). +% T is completely compressed and contains subtrees +% i.e. T of form 'L56' +compress_pt(T,T) :- + atom(T). +% T not yet compressed +% i.e. T is a tree-term (nested list & s/2 structure) +% -> execute one layer of compression, then check again +compress_pt(T,CT) :- + \+ atom(T), + and_or_compression(T,IT), + compress_pt(IT,CT). + +% transform tree-term T into tree-term CT where last two layers have been processed +% i.e. introduce names for subparts (-> Map) and replace (all occurrenes of) subparts by this names +and_or_compression(T,CT) :- + and_comp(T,AT), + or_comp(AT,CT). + +% replace leaves that are single child by variable representing father-AND-child +and_comp(T,AT) :- + all_leaves_pt(T,Leaves), + compression_mapping(Leaves,Map), + replace_pt(T,Map,AT). + +% replace list of siblings by variable representing their disjunction +or_comp(T,AT) :- + all_leaflists_pt(T,Leaves), + compression_mapping(Leaves,Map), + replace_pt(T,Map,AT). + +all_leaves_pt(T,L) :- + all(X,some_leaf_pt(T,X),L). + +some_leaf_pt([s(A,[])|_],s(A,[])). +some_leaf_pt([s(A,L)|_],s(A,L)) :- + atom(L). +some_leaf_pt([s(_,L)|_],X) :- + some_leaf_pt(L,X). +some_leaf_pt([_|L],X) :- + some_leaf_pt(L,X). + +all_leaflists_pt(L,[L]) :- + atomlist(L),!. +all_leaflists_pt(T,L) :- + all(X,some_leaflist_pt(T,X),L),!. +all_leaflists_pt(_,[]). + +some_leaflist_pt([s(_,L)|_],L) :- + atomlist(L). +some_leaflist_pt([s(_,L)|_],X) :- + some_leaflist_pt(L,X). +some_leaflist_pt([_|L],X) :- + some_leaflist_pt(L,X). + +atomlist([]). +atomlist([A|B]) :- + atom(A), + atomlist(B). + +% for each subtree that will be compressed, add its name +% only introduce 'L'-based names when subtree composes elements, store these in compression/2 for printing the script +compression_mapping([],[]). +compression_mapping([First|B],[N-First|BB]) :- + ( + First = s(A,[]) % subtree is literal -> use variable's name x17 from map + -> + recorded(map,m(A,N),_) + ; + (First = s(A,L),atom(L)) % subtree is node with single completely reduced child -> use next 'L'-based name + -> (get_next_name(N), + assertz(compression(N,s(A,L)))) + ; + (First = [L],atom(L)) % subtree is an OR with a single completely reduced element -> use element's name + -> N=L + ; + (atomlist(First), % subtree is an OR with only (>1) completely reduced elements -> use next 'L'-based name + get_next_name(N), + assertz(compression(N,First))) + ), + compression_mapping(B,BB). + + + +% replace_pt(+T,+Map,-NT) +% given the tree-term T and the Map of Name-Subtree entries, replace each occurence of Subtree in T with Name -> result NT +replace_pt(T,[],T). +replace_pt([],_,[]). +replace_pt(L,M,R) :- + atomlist(L), + member(R-L,M), + !. +replace_pt([L|LL],[M|MM],R) :- + replace_pt_list([L|LL],[M|MM],R). + +replace_pt_list([T|Tree],[M|Map],[C|Compr]) :- + replace_pt_single(T,[M|Map],C), + replace_pt_list(Tree,[M|Map],Compr). +replace_pt_list([],_,[]). + +replace_pt_single(s(A,T),[M|Map],Res) :- + atomlist(T), + member(Res-s(A,T),[M|Map]), + !. +replace_pt_single(s(A,T),[M|Map],s(A,Res)) :- + atomlist(T), + member(Res-T,[M|Map]), + !. +replace_pt_single(s(A,T),[M|Map],Res) :- + member(Res-s(A,T),[M|Map]), + !. +replace_pt_single(s(A,T),[M|Map],s(A,TT)) :- + replace_pt_list(T,[M|Map],TT). +replace_pt_single(A,_,A) :- + atom(A). + +%%%%%%%%%%%% +% output for script +% input argument is compressed tree, i.e. true/false or name assigned in last compression step +%%%%%%%%%%%% +output_compressed_script(false) :- + !, + format('L1 = FALSE~nL1~n',[]). +output_compressed_script(true) :- + !, + format('L1 = TRUE~nL1~n',[]). +% for each name-subtree pair, write corresponding line to script, e.g. L17 = x4 * L16 +% stop after writing definition of root (last entry in compression/2), add it's name to mark end of script +output_compressed_script(T) :- + once(retract(compression(Short,Long))), + (T = Short -> + format('~w = ',[Short]), + format_compression_script(Long), + format('~w~n',[Short]) + ; + format('~w = ',[Short]), + format_compression_script(Long), + output_compressed_script(T)). + +format_compression_script(s(A,B)) :- + recorded(map,m(A,C),_), + format('~w * ~w~n',[C,B]). +format_compression_script([A]) :- + format('~w~n',[A]). +format_compression_script([A,B|C]) :- + format('~w + ',[A]), + format_compression_script([B|C]). + +%%%%%%%%%%%%%%%%%%%%%%%% +% auxiliaries for translation to BDD +%%%%%%%%%%%%%%%%%%%%%%%% + +% prefix the current counter with "L" +get_next_name(Name) :- + retract(c_num(N)), + NN is N+1, + assert(c_num(NN)), + atomic_concat('L',N,Name). + +% create BDD-var as fact id prefixed by x +% learning.yap relies on this format! +% when changing, also adapt test_var_name/1 below +get_var_name(A,NameA) :- + atomic_concat([x,A],NameA), + recorda(map,m(A,NameA),_). + +% test used by base case of compression mapping to detect single-variable tree +% has to match above naming scheme +test_var_name(T) :- + atomic_concat(x,_,T). \ No newline at end of file diff --git a/packages/ProbLog/simplecudd/Example.c b/packages/ProbLog/simplecudd/Example.c new file mode 100644 index 000000000..c0dab075f --- /dev/null +++ b/packages/ProbLog/simplecudd/Example.c @@ -0,0 +1,281 @@ +/******************************************************************************\ +* * +* SimpleCUDD library (www.cs.kuleuven.be/~theo/tools/simplecudd.html) * +* SimpleCUDD was developed at Katholieke Universiteit Leuven(www.kuleuven.be) * +* * +* Copyright T. Mantadelis and Katholieke Universiteit Leuven 2008 * +* * +* Author: Theofrastos Mantadelis * +* File: Example.c * +* * +******************************************************************************** +* * +* The "Artistic License" * +* * +* Preamble * +* * +* The intent of this document is to state the conditions under which a * +* Package may be copied, such that the Copyright Holder maintains some * +* semblance of artistic control over the development of the package, * +* while giving the users of the package the right to use and distribute * +* the Package in a more-or-less customary fashion, plus the right to make * +* reasonable modifications. * +* * +* Definitions: * +* * +* "Package" refers to the collection of files distributed by the * +* Copyright Holder, and derivatives of that collection of files * +* created through textual modification. * +* * +* "Standard Version" refers to such a Package if it has not been * +* modified, or has been modified in accordance with the wishes * +* of the Copyright Holder as specified below. * +* * +* "Copyright Holder" is whoever is named in the copyright or * +* copyrights for the package. * +* * +* "You" is you, if you're thinking about copying or distributing * +* this Package. * +* * +* "Reasonable copying fee" is whatever you can justify on the * +* basis of media cost, duplication charges, time of people involved, * +* and so on. (You will not be required to justify it to the * +* Copyright Holder, but only to the computing community at large * +* as a market that must bear the fee.) * +* * +* "Freely Available" means that no fee is charged for the item * +* itself, though there may be fees involved in handling the item. * +* It also means that recipients of the item may redistribute it * +* under the same conditions they received it. * +* * +* 1. You may make and give away verbatim copies of the source form of the * +* Standard Version of this Package without restriction, provided that you * +* duplicate all of the original copyright notices and associated disclaimers. * +* * +* 2. You may apply bug fixes, portability fixes and other modifications * +* derived from the Public Domain or from the Copyright Holder. A Package * +* modified in such a way shall still be considered the Standard Version. * +* * +* 3. You may otherwise modify your copy of this Package in any way, provided * +* that you insert a prominent notice in each changed file stating how and * +* when you changed that file, and provided that you do at least ONE of the * +* following: * +* * +* a) place your modifications in the Public Domain or otherwise make them * +* Freely Available, such as by posting said modifications to Usenet or * +* an equivalent medium, or placing the modifications on a major archive * +* site such as uunet.uu.net, or by allowing the Copyright Holder to include * +* your modifications in the Standard Version of the Package. * +* * +* b) use the modified Package only within your corporation or organization. * +* * +* c) rename any non-standard executables so the names do not conflict * +* with standard executables, which must also be provided, and provide * +* a separate manual page for each non-standard executable that clearly * +* documents how it differs from the Standard Version. * +* * +* d) make other distribution arrangements with the Copyright Holder. * +* * +* 4. You may distribute the programs of this Package in object code or * +* executable form, provided that you do at least ONE of the following: * +* * +* a) distribute a Standard Version of the executables and library files, * +* together with instructions (in the manual page or equivalent) on where * +* to get the Standard Version. * +* * +* b) accompany the distribution with the machine-readable source of * +* the Package with your modifications. * +* * +* c) give non-standard executables non-standard names, and clearly * +* document the differences in manual pages (or equivalent), together * +* with instructions on where to get the Standard Version. * +* * +* d) make other distribution arrangements with the Copyright Holder. * +* * +* 5. You may charge a reasonable copying fee for any distribution of this * +* Package. You may charge any fee you choose for support of this * +* Package. You may not charge a fee for this Package itself. However, * +* you may distribute this Package in aggregate with other (possibly * +* commercial) programs as part of a larger (possibly commercial) software * +* distribution provided that you do not advertise this Package as a * +* product of your own. You may embed this Package's interpreter within * +* an executable of yours (by linking); this shall be construed as a mere * +* form of aggregation, provided that the complete Standard Version of the * +* interpreter is so embedded. * +* * +* 6. The scripts and library files supplied as input to or produced as * +* output from the programs of this Package do not automatically fall * +* under the copyright of this Package, but belong to whoever generated * +* them, and may be sold commercially, and may be aggregated with this * +* Package. If such scripts or library files are aggregated with this * +* Package via the so-called "undump" or "unexec" methods of producing a * +* binary executable image, then distribution of such an image shall * +* neither be construed as a distribution of this Package nor shall it * +* fall under the restrictions of Paragraphs 3 and 4, provided that you do * +* not represent such an executable image as a Standard Version of this * +* Package. * +* * +* 7. C subroutines (or comparably compiled subroutines in other * +* languages) supplied by you and linked into this Package in order to * +* emulate subroutines and variables of the language defined by this * +* Package shall not be considered part of this Package, but are the * +* equivalent of input as in Paragraph 6, provided these subroutines do * +* not change the language in any way that would cause it to fail the * +* regression tests for the language. * +* * +* 8. Aggregation of this Package with a commercial distribution is always * +* permitted provided that the use of this Package is embedded; that is, * +* when no overt attempt is made to make this Package's interfaces visible * +* to the end user of the commercial distribution. Such use shall not be * +* construed as a distribution of this Package. * +* * +* 9. The name of the Copyright Holder may not be used to endorse or promote * +* products derived from this software without specific prior written * +* permission. * +* * +* 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * +* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * +* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * +* * +* The End * +* * +\******************************************************************************/ + + +#include "simplecudd.h" + +typedef struct _extmanager { + DdManager *manager; + DdNode *t, *f; + hisqueue *his; + namedvars varmap; +} extmanager; + +void DFS(extmanager MyManager, DdNode *Current); +int compexpand(extmanager MyManager, DdNode *Current, extmanager MyManager2, DdNode *Current2); +int bufstrcat(char *targetstr, int targetmem, const char *srcstr); +void getalltruepaths(extmanager MyManager, DdNode *Current, const char *startpath, const char *prevvar); + +int main(int argc, char **arg) { + extmanager MyManager; + DdNode *bdd; + bddfileheader fileheader; + int code; + char yn; + code = -1; + if (argc != 2) { + fprintf(stderr, "\nUsage: %s [filename]\nGenerates and traverses a BDD from file\n", arg[0]); + fprintf(stderr, "\nUsage: %s -online\nGenerates and traverses a BDD online mode\n", arg[0]); + return code; + } + RAPIDLOADON; + if (strcmp("-online", arg[1]) == 0) { + MyManager.manager = simpleBDDinit(0); + MyManager.t = HIGH(MyManager.manager); + MyManager.f = LOW(MyManager.manager); + MyManager.varmap = InitNamedVars(1, 0); + bdd = OnlineGenerateBDD(MyManager.manager, &MyManager.varmap); + } else { + fileheader = ReadFileHeader(arg[1]); + switch(fileheader.filetype) { + case BDDFILE_SCRIPT: + MyManager.manager = simpleBDDinit(fileheader.varcnt); + MyManager.t = HIGH(MyManager.manager); + MyManager.f = LOW(MyManager.manager); + MyManager.varmap = InitNamedVars(fileheader.varcnt, fileheader.varstart); + bdd = FileGenerateBDD(MyManager.manager, MyManager.varmap, fileheader); + break; + case BDDFILE_NODEDUMP: + MyManager.manager = simpleBDDinit(fileheader.varcnt); + MyManager.t = HIGH(MyManager.manager); + MyManager.f = LOW(MyManager.manager); + MyManager.varmap = InitNamedVars(fileheader.varcnt, fileheader.varstart); + bdd = LoadNodeDump(MyManager.manager, MyManager.varmap, fileheader.inputfile); + break; + default: + fprintf(stderr, "Error: not a valid file format to load.\n"); + return code; + break; + } + } + if (bdd != NULL) { + printf("Do you want to load parameter values from testdata.txt [y]? "); yn = getchar(); getchar(); + if (yn == 'y') LoadVariableData(MyManager.varmap, "testdata.txt"); + code = 0; + MyManager.his = InitHistory(GetVarCount(MyManager.manager)); + if (strcmp("-online", arg[1]) != 0) { + DFS(MyManager, bdd); + printf("Do you need an export [y]? "); yn = getchar(); getchar(); + if (yn == 'y') simpleNamedBDDtoDot(MyManager.manager, MyManager.varmap, bdd, "SimpleCUDDExport.dot"); + printf("Do you want a save [y]? "); yn = getchar(); getchar(); + if (yn == 'y') SaveNodeDump(MyManager.manager, MyManager.varmap, bdd, "SimpleCUDDSave.sav"); + printf("Do you want to see all true paths [y]? "); yn = getchar(); getchar(); + if (yn == 'y') { + ReInitHistory(MyManager.his, GetVarCount(MyManager.manager)); + getalltruepaths(MyManager, bdd, "", ""); + } + } else { + onlinetraverse(MyManager.manager, MyManager.varmap, MyManager.his, bdd); + } + } + if (MyManager.manager != NULL) KillBDD(MyManager.manager); + return code; +} + +void DFS(extmanager MyManager, DdNode *Current) { + DdNode *h, *l; + hisnode *Found; + char *curnode; + curnode = GetNodeVarNameDisp(MyManager.manager, MyManager.varmap, Current); + if (GetIndex(Current) < MyManager.varmap.varcnt) { + printf("%s(%f,%i,%s)\n", curnode, MyManager.varmap.dvalue[GetIndex(Current)], MyManager.varmap.ivalue[GetIndex(Current)], MyManager.varmap.dynvalue[GetIndex(Current)]); + } else { + printf("%s\n", curnode); + } + if ((Current != MyManager.t) && (Current != MyManager.f) && + ((Found = GetNode(MyManager.his, MyManager.varmap.varstart, Current)) == NULL)) { + l = LowNodeOf(MyManager.manager, Current); + h = HighNodeOf(MyManager.manager, Current); + printf("l(%s)->", curnode); + DFS(MyManager, l); + printf("h(%s)->", curnode); + DFS(MyManager, h); + AddNode(MyManager.his, MyManager.varmap.varstart, Current, 0.0, 0, NULL); + } +} + +void getalltruepaths(extmanager MyManager, DdNode *Current, const char *startpath, const char *prevvar) { + DdNode *h, *l; + char *curnode, *curpath; + int pathmaxsize = 1024; + curpath = (char *) malloc(sizeof(char) * pathmaxsize); + curpath[0] = '\0'; + pathmaxsize = bufstrcat(curpath, pathmaxsize, startpath); + pathmaxsize = bufstrcat(curpath, pathmaxsize, prevvar); + pathmaxsize = bufstrcat(curpath, pathmaxsize, "*"); + curnode = GetNodeVarNameDisp(MyManager.manager, MyManager.varmap, Current); + if (Current == MyManager.t) { + printf("%s\n", curpath); + } else if (Current != MyManager.f) { + h = HighNodeOf(MyManager.manager, Current); + if (h != MyManager.f) { + getalltruepaths(MyManager, h, curpath, curnode); + } + l = LowNodeOf(MyManager.manager, Current); + if (l != MyManager.f) { + pathmaxsize = bufstrcat(curpath, pathmaxsize, "~"); + getalltruepaths(MyManager, l, curpath, curnode); + } + } + free(curpath); +} + +int bufstrcat(char *targetstr, int targetmem, const char *srcstr) { + int strinc = strlen(srcstr), strsize = strlen(targetstr); + while ((strsize + strinc) > (targetmem - 1)) { + targetmem *= 2; + targetstr = (char *) realloc(targetstr, sizeof(char) * targetmem); + } + strcat(targetstr, srcstr); + return targetmem; +} diff --git a/packages/ProbLog/simplecudd/LICENCE b/packages/ProbLog/simplecudd/LICENCE new file mode 100644 index 000000000..5f221241e --- /dev/null +++ b/packages/ProbLog/simplecudd/LICENCE @@ -0,0 +1,131 @@ + + + + + The "Artistic License" + + Preamble + +The intent of this document is to state the conditions under which a +Package may be copied, such that the Copyright Holder maintains some +semblance of artistic control over the development of the package, +while giving the users of the package the right to use and distribute +the Package in a more-or-less customary fashion, plus the right to make +reasonable modifications. + +Definitions: + + "Package" refers to the collection of files distributed by the + Copyright Holder, and derivatives of that collection of files + created through textual modification. + + "Standard Version" refers to such a Package if it has not been + modified, or has been modified in accordance with the wishes + of the Copyright Holder as specified below. + + "Copyright Holder" is whoever is named in the copyright or + copyrights for the package. + + "You" is you, if you're thinking about copying or distributing + this Package. + + "Reasonable copying fee" is whatever you can justify on the + basis of media cost, duplication charges, time of people involved, + and so on. (You will not be required to justify it to the + Copyright Holder, but only to the computing community at large + as a market that must bear the fee.) + + "Freely Available" means that no fee is charged for the item + itself, though there may be fees involved in handling the item. + It also means that recipients of the item may redistribute it + under the same conditions they received it. + +1. You may make and give away verbatim copies of the source form of the +Standard Version of this Package without restriction, provided that you +duplicate all of the original copyright notices and associated disclaimers. + +2. You may apply bug fixes, portability fixes and other modifications +derived from the Public Domain or from the Copyright Holder. A Package +modified in such a way shall still be considered the Standard Version. + +3. You may otherwise modify your copy of this Package in any way, provided +that you insert a prominent notice in each changed file stating how and +when you changed that file, and provided that you do at least ONE of the +following: + + a) place your modifications in the Public Domain or otherwise make them + Freely Available, such as by posting said modifications to Usenet or + an equivalent medium, or placing the modifications on a major archive + site such as uunet.uu.net, or by allowing the Copyright Holder to include + your modifications in the Standard Version of the Package. + + b) use the modified Package only within your corporation or organization. + + c) rename any non-standard executables so the names do not conflict + with standard executables, which must also be provided, and provide + a separate manual page for each non-standard executable that clearly + documents how it differs from the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +4. You may distribute the programs of this Package in object code or +executable form, provided that you do at least ONE of the following: + + a) distribute a Standard Version of the executables and library files, + together with instructions (in the manual page or equivalent) on where + to get the Standard Version. + + b) accompany the distribution with the machine-readable source of + the Package with your modifications. + + c) give non-standard executables non-standard names, and clearly + document the differences in manual pages (or equivalent), together + with instructions on where to get the Standard Version. + + d) make other distribution arrangements with the Copyright Holder. + +5. You may charge a reasonable copying fee for any distribution of this +Package. You may charge any fee you choose for support of this +Package. You may not charge a fee for this Package itself. However, +you may distribute this Package in aggregate with other (possibly +commercial) programs as part of a larger (possibly commercial) software +distribution provided that you do not advertise this Package as a +product of your own. You may embed this Package's interpreter within +an executable of yours (by linking); this shall be construed as a mere +form of aggregation, provided that the complete Standard Version of the +interpreter is so embedded. + +6. The scripts and library files supplied as input to or produced as +output from the programs of this Package do not automatically fall +under the copyright of this Package, but belong to whoever generated +them, and may be sold commercially, and may be aggregated with this +Package. If such scripts or library files are aggregated with this +Package via the so-called "undump" or "unexec" methods of producing a +binary executable image, then distribution of such an image shall +neither be construed as a distribution of this Package nor shall it +fall under the restrictions of Paragraphs 3 and 4, provided that you do +not represent such an executable image as a Standard Version of this +Package. + +7. C subroutines (or comparably compiled subroutines in other +languages) supplied by you and linked into this Package in order to +emulate subroutines and variables of the language defined by this +Package shall not be considered part of this Package, but are the +equivalent of input as in Paragraph 6, provided these subroutines do +not change the language in any way that would cause it to fail the +regression tests for the language. + +8. Aggregation of this Package with a commercial distribution is always +permitted provided that the use of this Package is embedded; that is, +when no overt attempt is made to make this Package's interfaces visible +to the end user of the commercial distribution. Such use shall not be +construed as a distribution of this Package. + +9. The name of the Copyright Holder may not be used to endorse or promote +products derived from this software without specific prior written permission. + +10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED +WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + + The End diff --git a/packages/ProbLog/simplecudd/Makefile.in b/packages/ProbLog/simplecudd/Makefile.in new file mode 100644 index 000000000..287f91715 --- /dev/null +++ b/packages/ProbLog/simplecudd/Makefile.in @@ -0,0 +1,34 @@ +CUDD = cudd-2.4.1 +DYNAMIC = +FLAGS = +INCLUDE = -I $(CUDD)/include +LINKFLAGS = -lm +LINKLIBS = $(CUDD)/cudd/libcudd.a $(CUDD)/mtr/libmtr.a $(CUDD)/st/libst.a $(CUDD)/util/libutil.a $(CUDD)/epd/libepd.a + +default: makecudd example problog + +example: Example.o simplecudd.o general.o + @echo Making Example... + @echo Copyright T. Mantadelis and Katholieke Universiteit Leuven 2008 + gcc Example.o simplecudd.o general.o $(LINKLIBS) $(LINKFLAGS) -o Example + +problog: ProblogBDD.o simplecudd.o general.o + @echo Making ProblogBDD... + @echo Copyright T. Mantadelis, A. Kimmig, B. Gutmann and Katholieke Universiteit Leuven 2008 + gcc ProblogBDD.o simplecudd.o general.o $(LINKLIBS) $(LINKFLAGS) -o ProblogBDD + +makecudd: + @(cd $(CUDD); \ + echo Making cudd...; \ + make) + +%.o : %.c + gcc $(FLAGS) $(INCLUDE) $(DYNAMIC) -c $< + +clean: cleancudd + rm -f *.o ProblogBDD Example + +cleancudd: + @(cd $(CUDD); \ + echo Cleaning cudd...; \ + make clean) diff --git a/packages/ProbLog/simplecudd/ProblogBDD.c b/packages/ProbLog/simplecudd/ProblogBDD.c new file mode 100644 index 000000000..687216e20 --- /dev/null +++ b/packages/ProbLog/simplecudd/ProblogBDD.c @@ -0,0 +1,670 @@ +/******************************************************************************\ +* * +* SimpleCUDD library (www.cs.kuleuven.be/~theo/tools/simplecudd.html) * +* SimpleCUDD was developed at Katholieke Universiteit Leuven(www.kuleuven.be) * +* * +* Copyright T. Mantadelis, A. Kimmig, B. Gutmann * +* and Katholieke Universiteit Leuven 2008 * +* * +* Author: Theofrastos Mantadelis, Angelika Kimmig, Bernd Gutmann * +* File: ProblogBDD.c * +* * +******************************************************************************** +* * +* The "Artistic License" * +* * +* Preamble * +* * +* The intent of this document is to state the conditions under which a * +* Package may be copied, such that the Copyright Holder maintains some * +* semblance of artistic control over the development of the package, * +* while giving the users of the package the right to use and distribute * +* the Package in a more-or-less customary fashion, plus the right to make * +* reasonable modifications. * +* * +* Definitions: * +* * +* "Package" refers to the collection of files distributed by the * +* Copyright Holder, and derivatives of that collection of files * +* created through textual modification. * +* * +* "Standard Version" refers to such a Package if it has not been * +* modified, or has been modified in accordance with the wishes * +* of the Copyright Holder as specified below. * +* * +* "Copyright Holder" is whoever is named in the copyright or * +* copyrights for the package. * +* * +* "You" is you, if you're thinking about copying or distributing * +* this Package. * +* * +* "Reasonable copying fee" is whatever you can justify on the * +* basis of media cost, duplication charges, time of people involved, * +* and so on. (You will not be required to justify it to the * +* Copyright Holder, but only to the computing community at large * +* as a market that must bear the fee.) * +* * +* "Freely Available" means that no fee is charged for the item * +* itself, though there may be fees involved in handling the item. * +* It also means that recipients of the item may redistribute it * +* under the same conditions they received it. * +* * +* 1. You may make and give away verbatim copies of the source form of the * +* Standard Version of this Package without restriction, provided that you * +* duplicate all of the original copyright notices and associated disclaimers. * +* * +* 2. You may apply bug fixes, portability fixes and other modifications * +* derived from the Public Domain or from the Copyright Holder. A Package * +* modified in such a way shall still be considered the Standard Version. * +* * +* 3. You may otherwise modify your copy of this Package in any way, provided * +* that you insert a prominent notice in each changed file stating how and * +* when you changed that file, and provided that you do at least ONE of the * +* following: * +* * +* a) place your modifications in the Public Domain or otherwise make them * +* Freely Available, such as by posting said modifications to Usenet or * +* an equivalent medium, or placing the modifications on a major archive * +* site such as uunet.uu.net, or by allowing the Copyright Holder to include * +* your modifications in the Standard Version of the Package. * +* * +* b) use the modified Package only within your corporation or organization. * +* * +* c) rename any non-standard executables so the names do not conflict * +* with standard executables, which must also be provided, and provide * +* a separate manual page for each non-standard executable that clearly * +* documents how it differs from the Standard Version. * +* * +* d) make other distribution arrangements with the Copyright Holder. * +* * +* 4. You may distribute the programs of this Package in object code or * +* executable form, provided that you do at least ONE of the following: * +* * +* a) distribute a Standard Version of the executables and library files, * +* together with instructions (in the manual page or equivalent) on where * +* to get the Standard Version. * +* * +* b) accompany the distribution with the machine-readable source of * +* the Package with your modifications. * +* * +* c) give non-standard executables non-standard names, and clearly * +* document the differences in manual pages (or equivalent), together * +* with instructions on where to get the Standard Version. * +* * +* d) make other distribution arrangements with the Copyright Holder. * +* * +* 5. You may charge a reasonable copying fee for any distribution of this * +* Package. You may charge any fee you choose for support of this * +* Package. You may not charge a fee for this Package itself. However, * +* you may distribute this Package in aggregate with other (possibly * +* commercial) programs as part of a larger (possibly commercial) software * +* distribution provided that you do not advertise this Package as a * +* product of your own. You may embed this Package's interpreter within * +* an executable of yours (by linking); this shall be construed as a mere * +* form of aggregation, provided that the complete Standard Version of the * +* interpreter is so embedded. * +* * +* 6. The scripts and library files supplied as input to or produced as * +* output from the programs of this Package do not automatically fall * +* under the copyright of this Package, but belong to whoever generated * +* them, and may be sold commercially, and may be aggregated with this * +* Package. If such scripts or library files are aggregated with this * +* Package via the so-called "undump" or "unexec" methods of producing a * +* binary executable image, then distribution of such an image shall * +* neither be construed as a distribution of this Package nor shall it * +* fall under the restrictions of Paragraphs 3 and 4, provided that you do * +* not represent such an executable image as a Standard Version of this * +* Package. * +* * +* 7. C subroutines (or comparably compiled subroutines in other * +* languages) supplied by you and linked into this Package in order to * +* emulate subroutines and variables of the language defined by this * +* Package shall not be considered part of this Package, but are the * +* equivalent of input as in Paragraph 6, provided these subroutines do * +* not change the language in any way that would cause it to fail the * +* regression tests for the language. * +* * +* 8. Aggregation of this Package with a commercial distribution is always * +* permitted provided that the use of this Package is embedded; that is, * +* when no overt attempt is made to make this Package's interfaces visible * +* to the end user of the commercial distribution. Such use shall not be * +* construed as a distribution of this Package. * +* * +* 9. The name of the Copyright Holder may not be used to endorse or promote * +* products derived from this software without specific prior written * +* permission. * +* * +* 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * +* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * +* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * +* * +* The End * +* * +\******************************************************************************/ + + +#include "simplecudd.h" +#include + +typedef struct _parameters { + int loadfile; + int savedfile; + int exportfile; + int inputfile; + int debug; + int errorcnt; + int *error; + int method; + int queryid; + int timeout; + double sigmoid_slope; + int online; + int maxbufsize; + char *ppid; +} parameters; + +typedef struct _gradientpair { + double probability; + double gradient; +} gradientpair; + +typedef struct _extmanager { + DdManager *manager; + DdNode *t, *f; + hisqueue *his; + namedvars varmap; +} extmanager; + +int argtype(const char *arg); +void printhelp(int argc, char **arg); +parameters loadparam(int argc, char **arg); +parameters params; + +void handler(int num); +void pidhandler(int num); +void termhandler(int num); + +double sigmoid(double x, double slope); +void myexpand(extmanager MyManager, DdNode *Current); +double CalcProbability(extmanager MyManager, DdNode *Current); +double CalcProbabilitySigmoid(extmanager MyManager, DdNode *Current); +gradientpair CalcGradient(extmanager MyManager, DdNode *Current, int TargetVar, char *TargetPattern); +int patterncalculated(char *pattern, extmanager MyManager, int loc); +char * extractpattern(char *thestr); + +int main(int argc, char **arg) { + extmanager MyManager; + DdNode *bdd; + bddfileheader fileheader; + int i, ivarcnt, code; + gradientpair tvalue; + double probability = -1.0; + char *varpattern; + varpattern = NULL; + code = -1; + params = loadparam(argc, arg); + + if (params.errorcnt > 0) { + printhelp(argc, arg); + for (i = 0; i < params.errorcnt; i++) { + fprintf(stderr, "Error: not known or error at parameter %s.\n", arg[params.error[i]]); + } + return -1; + } + + if (params.online == 0 && params.loadfile == -1) { + printhelp(argc, arg); + fprintf(stderr, "Error: you must specify a loading file.\n"); + return -1; + } + + if (params.method != 0 && arg[params.method][0] != 'g' && arg[params.method][0] != 'p' && arg[params.method][0] != 'o') { + printhelp(argc, arg); + fprintf(stderr, "Error: you must choose a calculation method beetween [p]robability, [g]radient, [o]nline.\n"); + return -1; + } + + if (params.debug) DEBUGON; + RAPIDLOADON; + SETMAXBUFSIZE(params.maxbufsize); + + signal(SIGINT, termhandler); + if (params.ppid != NULL) { + signal(SIGALRM, pidhandler); + alarm(5); + } else { + signal(SIGALRM, handler); + alarm(params.timeout); + } + if (params.online) { + MyManager.manager = simpleBDDinit(0); + MyManager.t = HIGH(MyManager.manager); + MyManager.f = LOW(MyManager.manager); + MyManager.varmap = InitNamedVars(1, 0); + bdd = OnlineGenerateBDD(MyManager.manager, &MyManager.varmap); + ivarcnt = GetVarCount(MyManager.manager); + } else { + fileheader = ReadFileHeader(arg[params.loadfile]); + switch(fileheader.filetype) { + case BDDFILE_SCRIPT: + if (params.inputfile == -1) { + printhelp(argc, arg); + fprintf(stderr, "Error: an input file is necessary for this type of loading file.\n"); + return -1; + } + MyManager.manager = simpleBDDinit(fileheader.varcnt); + MyManager.t = HIGH(MyManager.manager); + MyManager.f = LOW(MyManager.manager); + MyManager.varmap = InitNamedVars(fileheader.varcnt, fileheader.varstart); + bdd = FileGenerateBDD(MyManager.manager, MyManager.varmap, fileheader); + ivarcnt = fileheader.varcnt; + break; + case BDDFILE_NODEDUMP: + if (params.inputfile == -1) { + printhelp(argc, arg); + fprintf(stderr, "Error: an input file is necessary for this type of loading file.\n"); + return -1; + } + MyManager.manager = simpleBDDinit(fileheader.varcnt); + MyManager.t = HIGH(MyManager.manager); + MyManager.f = LOW(MyManager.manager); + MyManager.varmap = InitNamedVars(fileheader.varcnt, fileheader.varstart); + bdd = LoadNodeDump(MyManager.manager, MyManager.varmap, fileheader.inputfile); + ivarcnt = fileheader.varcnt; + break; + default: + fprintf(stderr, "Error: not a valid file format to load.\n"); + return -1; + break; + } + } + alarm(0); + + // problem specifics + + if (bdd != NULL) { + ivarcnt = RepairVarcnt(&MyManager.varmap); + code = 0; + if (params.inputfile != -1) { + if (LoadVariableData(MyManager.varmap, arg[params.inputfile]) == -1) return -1; + if (!all_loaded(MyManager.varmap, 1)) return -1; + } + MyManager.his = InitHistory(ivarcnt); + if (params.method != 0) { + switch(arg[params.method][0]) { + case 'g': + for (i = 0; i < MyManager.varmap.varcnt; i++) { + if (MyManager.varmap.vars[i] != NULL) { + varpattern = extractpattern(MyManager.varmap.vars[i]); + if ((varpattern == NULL) || (!patterncalculated(varpattern, MyManager, i))) { + tvalue = CalcGradient(MyManager, bdd, i + MyManager.varmap.varstart, varpattern); + probability = tvalue.probability; + double factor = sigmoid(MyManager.varmap.dvalue[i], params.sigmoid_slope) * (1 - sigmoid(MyManager.varmap.dvalue[i], params.sigmoid_slope)) * params.sigmoid_slope; + if (varpattern == NULL) { + printf("query_gradient(%s,%s,%1.12f).\n", arg[params.queryid], MyManager.varmap.vars[i], tvalue.gradient * factor); + } else { + varpattern[strlen(varpattern) - 2] = '\0'; + printf("query_gradient(%s,%s,%1.12f).\n", arg[params.queryid], varpattern, tvalue.gradient * factor); + } + ReInitHistory(MyManager.his, MyManager.varmap.varcnt); + } + if (varpattern != NULL) free(varpattern); + } else { + fprintf(stderr, "Error: no variable name given for parameter.\n"); + } + } + if (probability < 0.0) { + // no nodes, so we have to calculate probability ourself + tvalue = CalcGradient(MyManager, bdd, 0 + MyManager.varmap.varstart, NULL); + probability = tvalue.probability; + } + printf("query_probability(%s,%1.12f).\n", arg[params.queryid], probability); + break; + case 'p': + printf("probability(%1.12f).\n", CalcProbability(MyManager, bdd)); + break; + case 'o': + onlinetraverse(MyManager.manager, MyManager.varmap, MyManager.his, bdd); + break; + default: + myexpand(MyManager, bdd); + break; + } + } else { + myexpand(MyManager, bdd); + } + if (params.savedfile > -1) SaveNodeDump(MyManager.manager, MyManager.varmap, bdd, arg[params.savedfile]); + if (params.exportfile > -1) simpleNamedBDDtoDot(MyManager.manager, MyManager.varmap, bdd, arg[params.exportfile]); + ReInitHistory(MyManager.his, MyManager.varmap.varcnt); + free(MyManager.his); + } + if (MyManager.manager != NULL) { + KillBDD(MyManager.manager); + free(MyManager.varmap.dvalue); + free(MyManager.varmap.ivalue); + free(MyManager.varmap.dynvalue); + for (i = 0; i < MyManager.varmap.varcnt; i++) + free(MyManager.varmap.vars[i]); + free(MyManager.varmap.vars); + } + if (params.error != NULL) free(params.error); + + return code; + +} + +/* Shell Parameters handling */ + +int argtype(const char *arg) { + if (strcmp(arg, "-l") == 0 || strcmp(arg, "--load") == 0) return 0; + if (strcmp(arg, "-e") == 0 || strcmp(arg, "--export") == 0) return 2; + if (strcmp(arg, "-m") == 0 || strcmp(arg, "--method") == 0) return 3; + if (strcmp(arg, "-i") == 0 || strcmp(arg, "--input") == 0) return 4; + if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) return 5; + if (strcmp(arg, "-d") == 0 || strcmp(arg, "--debug") == 0) return 6; + if (strcmp(arg, "-id") == 0 || strcmp(arg, "--queryid") == 0) return 7; + if (strcmp(arg, "-t") == 0 || strcmp(arg, "--timeout") == 0) return 8; + if (strcmp(arg, "-sd") == 0 || strcmp(arg, "--savedump") == 0) return 9; + if (strcmp(arg, "-sl") == 0 || strcmp(arg, "--slope") == 0) return 10; + if (strcmp(arg, "-o") == 0 || strcmp(arg, "--online") == 0) return 11; + if (strcmp(arg, "-bs") == 0 || strcmp(arg, "--bufsize") == 0) return 12; + if (strcmp(arg, "-pid") == 0 || strcmp(arg, "--pid") == 0) return 13; + return -1; +} + +void printhelp(int argc, char **arg) { + fprintf(stderr, "\nUsage: %s -l [filename] -i [filename] -o (-s(d) [filename] -e [filename] -m [method] -id [queryid] -sl [double]) (-t [seconds] -d -h)\n", arg[0]); + fprintf(stderr, "Generates and traverses a BDD\nMandatory parameters:\n"); + fprintf(stderr, "\t-l [filename]\t->\tfilename to load supports two formats:\n\t\t\t\t\t\t1. script with generation instructions\n\t\t\t\t\t\t2. node dump saved file\n"); + fprintf(stderr, "\t-i [filename]\t->\tfilename to input problem specifics (mandatory with file formats 1, 2)\n"); + fprintf(stderr, "\t-o\t\t->\tgenerates the BDD in online mode instead from a file can be used instead of -l\n"); + fprintf(stderr, "Optional parameters:\n"); + fprintf(stderr, "\t-sd [filename]\t->\tfilename to save generated BDD in node dump format (fast loading, traverse valid only)\n"); + fprintf(stderr, "\t-e [filename]\t->\tfilename to export generated BDD in dot format\n"); + fprintf(stderr, "\t-m [method]\t->\tthe calculation method to be used: none(default), [p]robability, [g]radient, [o]nline\n"); + fprintf(stderr, "\t-id [queryid]\t->\tthe queries identity name (used by gradient) default: %s\n", arg[0]); + fprintf(stderr, "\t-sl [double]\t->\tthe sigmoid slope (used by gradient) default: 1.0\n"); + fprintf(stderr, "Extra parameters:\n"); + fprintf(stderr, "\t-t [seconds]\t->\tthe seconds (int) for BDD generation timeout default 0 = no timeout\n"); + fprintf(stderr, "\t-pid [pid]\t->\ta process id (int) to check for termination default 0 = no process to check works only under POSIX OS\n"); + fprintf(stderr, "\t-bs [bytes]\t->\tthe bytes (int) to use as a maximum buffer size to read files default 0 = no max\n"); + fprintf(stderr, "\t-d\t\t->\tRun in debug mode (gives extra messages in stderr)\n"); + fprintf(stderr, "\t-h\t\t->\tHelp (displays this message)\n\n"); + fprintf(stderr, "Example: %s -l testbdd -i input.txt -m g -id testbdd\n", arg[0]); +} + +parameters loadparam(int argc, char **arg) { + int i; + parameters params; + params.loadfile = -1; + params.savedfile = -1; + params.exportfile = -1; + params.method = 0; + params.inputfile = -1; + params.debug = 0; + params.errorcnt = 0; + params.queryid = 0; + params.timeout = 0; + params.sigmoid_slope = 1.0; + params.online = 0; + params.maxbufsize = 0; + params.ppid = NULL; + params.error = (int *) malloc(argc * sizeof(int)); + for (i = 1; i < argc; i++) { + switch(argtype(arg[i])) { + case 0: + if (argc > i + 1) { + i++; + params.loadfile = i; + } else { + params.error[params.errorcnt] = i; + params.errorcnt++; + } + break; + case 2: + if (argc > i + 1) { + i++; + params.exportfile = i; + } else { + params.error[params.errorcnt] = i; + params.errorcnt++; + } + break; + case 3: + if (argc > i + 1) { + i++; + params.method = i; + } else { + params.error[params.errorcnt] = i; + params.errorcnt++; + } + break; + case 4: + if (argc > i + 1) { + i++; + params.inputfile = i; + } else { + params.error[params.errorcnt] = i; + params.errorcnt++; + } + break; + case 5: + printhelp(argc, arg); + break; + case 6: + params.debug = 1; + break; + case 7: + if (argc > i + 1) { + i++; + params.queryid = i; + } else { + params.error[params.errorcnt] = i; + params.errorcnt++; + } + break; + case 8: + if ((argc > i + 1) && (IsPosNumber(arg[i + 1]))) { + i++; + params.timeout = atoi(arg[i]); + } else { + params.error[params.errorcnt] = i; + params.errorcnt++; + } + break; + case 9: + if (argc > i + 1) { + i++; + params.savedfile = i; + } else { + params.error[params.errorcnt] = i; + params.errorcnt++; + } + break; + case 10: + if ((argc > i + 1) && (IsRealNumber(arg[i + 1]))) { + i++; + params.sigmoid_slope = atof(arg[i]); + } else { + params.error[params.errorcnt] = i; + params.errorcnt++; + } + break; + case 11: + params.online = 1; + break; + case 12: + if ((argc > i + 1) && (IsPosNumber(arg[i + 1]))) { + i++; + params.maxbufsize = atoi(arg[i]); + } else { + params.error[params.errorcnt] = i; + params.errorcnt++; + } + break; + case 13: + if ((argc > i + 1) && (IsPosNumber(arg[i + 1]))) { + i++; + params.ppid = (char *) malloc(sizeof(char) * (strlen(arg[i]) + 1)); + strcpy(params.ppid, arg[i]); + } else { + params.error[params.errorcnt] = i; + params.errorcnt++; + } + break; + default: + params.error[params.errorcnt] = i; + params.errorcnt++; + break; + } + } + return params; +} + +/* Error Handlers */ + +void handler(int num) { + fprintf(stderr, "Error: Timeout %i exceeded.\n", params.timeout); + exit(-1); +} + +void pidhandler(int num) { + char *s; + if (params.timeout > 0) { + params.timeout -= 5; + if (params.timeout <= 0) { + fprintf(stderr, "Error: Timeout exceeded.\n"); + exit(-1); + } + } + s = (char *) malloc(sizeof(char) * (19 + strlen(params.ppid))); + strcpy(s, "ps "); strcat(s, params.ppid); strcat(s, " >/dev/null"); + if (system(s) != 0) exit(4); + signal(SIGALRM, pidhandler); + alarm(5); + free(s); +} + +void termhandler(int num) { + exit(3); +} + +/* General Functions */ + +double sigmoid(double x, double slope) { + return 1 / (1 + exp(-x * slope)); +} + +/* Debugging traverse function */ + +void myexpand(extmanager MyManager, DdNode *Current) { + DdNode *h, *l; + hisnode *Found; + char *curnode; + curnode = GetNodeVarNameDisp(MyManager.manager, MyManager.varmap, Current); + printf("%s\n", curnode); + if ((Current != MyManager.t) && (Current != MyManager.f) && + ((Found = GetNode(MyManager.his, MyManager.varmap.varstart, Current)) == NULL)) { + l = LowNodeOf(MyManager.manager, Current); + h = HighNodeOf(MyManager.manager, Current); + printf("l(%s)->", curnode); + myexpand(MyManager, l); + printf("h(%s)->", curnode); + myexpand(MyManager, h); + AddNode(MyManager.his, MyManager.varmap.varstart, Current, 0.0, 0, NULL); + } +} + +/* Angelikas Algorithm */ + +double CalcProbability(extmanager MyManager, DdNode *Current) { + DdNode *h, *l; + hisnode *Found; + char *curnode; + double lvalue, hvalue, tvalue; + if (params.debug) { + curnode = GetNodeVarNameDisp(MyManager.manager, MyManager.varmap, Current); + fprintf(stderr, "%s\n", curnode); + } + if (Current == MyManager.t) return 1.0; + if (Current == MyManager.f) return 0.0; + if ((Found = GetNode(MyManager.his, MyManager.varmap.varstart, Current)) != NULL) return Found->dvalue; + l = LowNodeOf(MyManager.manager, Current); + h = HighNodeOf(MyManager.manager, Current); + if (params.debug) fprintf(stderr, "l(%s)->", curnode); + lvalue = CalcProbability(MyManager, l); + if (params.debug) fprintf(stderr, "h(%s)->", curnode); + hvalue = CalcProbability(MyManager, h); + tvalue = MyManager.varmap.dvalue[GetIndex(Current) - MyManager.varmap.varstart]; + tvalue = tvalue * hvalue + lvalue * (1.0 - tvalue); + AddNode(MyManager.his, MyManager.varmap.varstart, Current, tvalue, 0, NULL); + return tvalue; +} + +/* Bernds Algorithm */ + +gradientpair CalcGradient(extmanager MyManager, DdNode *Current, int TargetVar, char *TargetPattern) { + DdNode *h, *l; + hisnode *Found; + char *curnode; + gradientpair lvalue, hvalue, tvalue; + double this_probability; + double *gradient; + if (params.debug) { + curnode = GetNodeVarNameDisp(MyManager.manager, MyManager.varmap, Current); + fprintf(stderr, "%s\n", curnode); + } + if (Current == MyManager.t) { + tvalue.probability = 1.0; + tvalue.gradient = 0.0; + return tvalue; + } + if (Current == MyManager.f) { + tvalue.probability = 0.0; + tvalue.gradient = 0.0; + return tvalue; + } + if ((Found = GetNode(MyManager.his, MyManager.varmap.varstart, Current)) != NULL) { + tvalue.probability = Found->dvalue; + tvalue.gradient = *((double *) Found->dynvalue); + return tvalue; + } + l = LowNodeOf(MyManager.manager, Current); + h = HighNodeOf(MyManager.manager, Current); + if (params.debug) fprintf(stderr, "l(%s)->", curnode); + lvalue = CalcGradient(MyManager, l, TargetVar, TargetPattern); + if (params.debug) fprintf(stderr, "h(%s)->", curnode); + hvalue = CalcGradient(MyManager, h, TargetVar, TargetPattern); + this_probability = sigmoid(MyManager.varmap.dvalue[GetIndex(Current) - MyManager.varmap.varstart], params.sigmoid_slope); + tvalue.probability = this_probability * hvalue.probability + (1 - this_probability) * lvalue.probability; + tvalue.gradient = this_probability * hvalue.gradient + (1 - this_probability) * lvalue.gradient; + if ((GetIndex(Current) == TargetVar) || + ((TargetPattern != NULL) && patternmatch(TargetPattern, MyManager.varmap.vars[GetIndex(Current)]))) { + tvalue.gradient += hvalue.probability - lvalue.probability; + } + gradient = (double *) malloc(sizeof(double)); + *gradient = tvalue.gradient; + AddNode(MyManager.his, MyManager.varmap.varstart, Current, tvalue.probability, 0, gradient); + return tvalue; +} + +char * extractpattern(char *thestr) { + char *p; + int i = 0, sl = strlen(thestr); + while((thestr[i] != '_') && (i < sl)) i++; + if (i == sl) return NULL; + i++; + p = (char *) malloc(sizeof(char) * (i + 2)); + strncpy(p, thestr, i); + p[i] = '*'; + p[i + 1] = '\0'; + return p; +} + +int patterncalculated(char *pattern, extmanager MyManager, int loc) { + int i; + if (pattern == NULL) return 0; + for (i = loc - 1; i > -1; i--) + if (patternmatch(pattern, MyManager.varmap.vars[i])) return 1; + return 0; +} diff --git a/packages/ProbLog/simplecudd/SimpleCUDD.pl b/packages/ProbLog/simplecudd/SimpleCUDD.pl new file mode 100644 index 000000000..9fe1ecfb0 --- /dev/null +++ b/packages/ProbLog/simplecudd/SimpleCUDD.pl @@ -0,0 +1,141 @@ +:-use_module(library(system)). +%:-use_module(library(clib)). + +bdd_init(FDO, FDI, PID):- + exec('/home/theo/BDDs/SimpleCUDD/Version4/Example -online', [pipe(FDO), pipe(FDI), std], PID). + %process_create('/home/theo/BDDs/SimpleCUDD/Version3/Example', ['-online'], [stdin(pipe(FDI)), stdout(pipe(FDO)), process(PID)]). + +bdd_commit(FDO, LINE):- + write(FDO, LINE), + write(FDO, '\n'). + +bdd_kill(FDO, FDI, PID, S):- + bdd_commit(FDO, '@e'), + wait(PID, S), + %process_wait(PID, S), + close(FDO), + close(FDI). + +bdd_line([], X, _, L):- + atomic(X), + X \= [], + (bdd_curinter(N) -> + retract(bdd_curinter(N)) + ; + N = 1 + ), + M is N + 1, + assert(bdd_curinter(M)), + atomic_concat(['L', N, '=', X], L). + +bdd_line(L, X, O, NL):- + atomic(X), + X \= [], + atom(L), + L \= [], + atomic_concat([L, O, X], NL). + +bdd_line(L, [], _, L):-!. + +bdd_line(L, [X|T], O, R):- + bdd_line(L, X, O, NL), + bdd_line(NL, T, O, R). + +bdd_AND(L, X, NL):- + bdd_line(L, X, '*', NL). +bdd_OR(L, X, NL):- + bdd_line(L, X, '+', NL). +bdd_XOR(L, X, NL):- + bdd_line(L, X, '#', NL). +bdd_NAND(L, X, NL):- + bdd_line(L, X, '~*', NL). +bdd_NOR(L, X, NL):- + bdd_line(L, X, '~+', NL). +bdd_XNOR(L, X, NL):- + bdd_line(L, X, '~#', NL). + +bdd_not(X, NX):- + atomic(X), + atomic_concat(['~', X], NX). + +bdd_laststep(L):- + bdd_curinter(N), + M is N - 1, + atomic_concat(['L', M], L), + !. + +bdd_nextDFS(FDO):- + bdd_commit(FDO, '@n'). + +bdd_nextBFS(FDO):- + bdd_commit(FDO, '@n,BFS'). + +bdd_current(FDO, FDI, N, Qcnt):- + bdd_commit(FDO, '@c'), + read(FDI, F), + assert(F), + bdd_temp_value(N, Qcnt), + retract(F). + +bdd_highnodeof(FDO, FDI, H):- + bdd_commit(FDO, '@h'), + read(FDI, F), + assert(F), + bdd_temp_value(H), + retract(F). + +bdd_lownodeof(FDO, FDI, L):- + bdd_commit(FDO, '@l'), + read(FDI, F), + assert(F), + bdd_temp_value(L), + retract(F). + +bdd_nodevaluesof(FDO, FDI, N, V):- + atomic_concat(['@v,', N], Q), + bdd_commit(FDO, Q), + read(FDI, F), + assert(F), + bdd_temp_value(V), + retract(F). +/* +bdd_addnodetohis(FDO, N, [D, I, Dyn]):- + atomic_concat(['@a,', N, ',', D, ',', I, ',', Dyn], Q), + bdd_commit(FDO, Q). + +bdd_getnodefromhis(FDO, FDI, N, V):- + atomic_concat(['@g,', N], Q), + bdd_commit(FDO, Q), + read(FDI, F), + assert(F), + bdd_temp_value(V), + retract(F). +*/ + +runme:- + bdd_init(FDO, FDI, PID), + bdd_AND([], ['A', 'B', 'C', 'D', 'E'], L1), + bdd_laststep(L1S), + bdd_commit(FDO, L1), + bdd_AND([], ['A', 'F', 'G', '~B'], L2), + bdd_laststep(L2S), + bdd_commit(FDO, L2), + bdd_AND([], ['A', 'F', 'G', '~C'], L3), + bdd_laststep(L3S), + bdd_commit(FDO, L3), + bdd_OR([], [L1S, L2S, L3S], L4), + bdd_laststep(L4S), + bdd_commit(FDO, L4), + bdd_commit(FDO, L4S), + + repeat, + bdd_current(FDO, FDI, N, I), + write(1),nl, + bdd_nodevaluesof(FDO, FDI, N, V), + write(N), write(' ('), write(V), write(')'), nl, + bdd_next(FDO), + I = 0, (N = 'TRUE' ; N = 'FALSE'), + + bdd_kill(FDO, FDI, PID, S), + write('BDD terminated with state: '), write(S), nl. + diff --git a/packages/ProbLog/simplecudd/general.c b/packages/ProbLog/simplecudd/general.c new file mode 100644 index 000000000..64a7f88e1 --- /dev/null +++ b/packages/ProbLog/simplecudd/general.c @@ -0,0 +1,234 @@ +/******************************************************************************\ +* * +* SimpleCUDD library (www.cs.kuleuven.be/~theo/tools/simplecudd.html) * +* SimpleCUDD was developed at Katholieke Universiteit Leuven(www.kuleuven.be) * +* * +* Copyright T. Mantadelis and Katholieke Universiteit Leuven 2008 * +* * +* Author: Theofrastos Mantadelis * +* File: general.c * +* * +******************************************************************************** +* * +* The "Artistic License" * +* * +* Preamble * +* * +* The intent of this document is to state the conditions under which a * +* Package may be copied, such that the Copyright Holder maintains some * +* semblance of artistic control over the development of the package, * +* while giving the users of the package the right to use and distribute * +* the Package in a more-or-less customary fashion, plus the right to make * +* reasonable modifications. * +* * +* Definitions: * +* * +* "Package" refers to the collection of files distributed by the * +* Copyright Holder, and derivatives of that collection of files * +* created through textual modification. * +* * +* "Standard Version" refers to such a Package if it has not been * +* modified, or has been modified in accordance with the wishes * +* of the Copyright Holder as specified below. * +* * +* "Copyright Holder" is whoever is named in the copyright or * +* copyrights for the package. * +* * +* "You" is you, if you're thinking about copying or distributing * +* this Package. * +* * +* "Reasonable copying fee" is whatever you can justify on the * +* basis of media cost, duplication charges, time of people involved, * +* and so on. (You will not be required to justify it to the * +* Copyright Holder, but only to the computing community at large * +* as a market that must bear the fee.) * +* * +* "Freely Available" means that no fee is charged for the item * +* itself, though there may be fees involved in handling the item. * +* It also means that recipients of the item may redistribute it * +* under the same conditions they received it. * +* * +* 1. You may make and give away verbatim copies of the source form of the * +* Standard Version of this Package without restriction, provided that you * +* duplicate all of the original copyright notices and associated disclaimers. * +* * +* 2. You may apply bug fixes, portability fixes and other modifications * +* derived from the Public Domain or from the Copyright Holder. A Package * +* modified in such a way shall still be considered the Standard Version. * +* * +* 3. You may otherwise modify your copy of this Package in any way, provided * +* that you insert a prominent notice in each changed file stating how and * +* when you changed that file, and provided that you do at least ONE of the * +* following: * +* * +* a) place your modifications in the Public Domain or otherwise make them * +* Freely Available, such as by posting said modifications to Usenet or * +* an equivalent medium, or placing the modifications on a major archive * +* site such as uunet.uu.net, or by allowing the Copyright Holder to include * +* your modifications in the Standard Version of the Package. * +* * +* b) use the modified Package only within your corporation or organization. * +* * +* c) rename any non-standard executables so the names do not conflict * +* with standard executables, which must also be provided, and provide * +* a separate manual page for each non-standard executable that clearly * +* documents how it differs from the Standard Version. * +* * +* d) make other distribution arrangements with the Copyright Holder. * +* * +* 4. You may distribute the programs of this Package in object code or * +* executable form, provided that you do at least ONE of the following: * +* * +* a) distribute a Standard Version of the executables and library files, * +* together with instructions (in the manual page or equivalent) on where * +* to get the Standard Version. * +* * +* b) accompany the distribution with the machine-readable source of * +* the Package with your modifications. * +* * +* c) give non-standard executables non-standard names, and clearly * +* document the differences in manual pages (or equivalent), together * +* with instructions on where to get the Standard Version. * +* * +* d) make other distribution arrangements with the Copyright Holder. * +* * +* 5. You may charge a reasonable copying fee for any distribution of this * +* Package. You may charge any fee you choose for support of this * +* Package. You may not charge a fee for this Package itself. However, * +* you may distribute this Package in aggregate with other (possibly * +* commercial) programs as part of a larger (possibly commercial) software * +* distribution provided that you do not advertise this Package as a * +* product of your own. You may embed this Package's interpreter within * +* an executable of yours (by linking); this shall be construed as a mere * +* form of aggregation, provided that the complete Standard Version of the * +* interpreter is so embedded. * +* * +* 6. The scripts and library files supplied as input to or produced as * +* output from the programs of this Package do not automatically fall * +* under the copyright of this Package, but belong to whoever generated * +* them, and may be sold commercially, and may be aggregated with this * +* Package. If such scripts or library files are aggregated with this * +* Package via the so-called "undump" or "unexec" methods of producing a * +* binary executable image, then distribution of such an image shall * +* neither be construed as a distribution of this Package nor shall it * +* fall under the restrictions of Paragraphs 3 and 4, provided that you do * +* not represent such an executable image as a Standard Version of this * +* Package. * +* * +* 7. C subroutines (or comparably compiled subroutines in other * +* languages) supplied by you and linked into this Package in order to * +* emulate subroutines and variables of the language defined by this * +* Package shall not be considered part of this Package, but are the * +* equivalent of input as in Paragraph 6, provided these subroutines do * +* not change the language in any way that would cause it to fail the * +* regression tests for the language. * +* * +* 8. Aggregation of this Package with a commercial distribution is always * +* permitted provided that the use of this Package is embedded; that is, * +* when no overt attempt is made to make this Package's interfaces visible * +* to the end user of the commercial distribution. Such use shall not be * +* construed as a distribution of this Package. * +* * +* 9. The name of the Copyright Holder may not be used to endorse or promote * +* products derived from this software without specific prior written * +* permission. * +* * +* 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * +* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * +* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * +* * +* The End * +* * +\******************************************************************************/ + + +#include "general.h" + +/* Number Handling */ + +int IsRealNumber(char *c) { + int i, l; + l = strlen(c); + if (l <= 0) return 0; + if (l == 1) return IsNumberDigit(c[0]); + for(i = 1; i < strlen(c); i++) { + if (c[i] == '.') return IsPosNumber(&c[i + 1]); + if (!IsNumberDigit(c[i])) return 0; + } + return (IsNumberDigit(c[0]) || IsSignDigit(c[0])); +} + +int IsPosNumber(const char *c) { + int i, l; + l = strlen(c); + if (l <= 0) return 0; + for(i = 0; i < strlen(c); i++) { + if (!IsNumberDigit(c[i])) return 0; + } + return 1; +} + +int IsNumber(const char *c) { + int i, l; + l = strlen(c); + if (l <= 0) return 0; + if (l == 1) return IsNumberDigit(c[0]); + for(i = 1; i < strlen(c); i++) { + if (!IsNumberDigit(c[i])) return 0; + } + return (IsNumberDigit(c[0]) || IsSignDigit(c[0])); +} + +/* File Handling */ + +char * freadstr(FILE *fd, const char *separators) { + char *str; + int buf, icur = 0, max = 10; + str = (char *) malloc(sizeof(char) * max); + str[0] = '\0'; + do { + if ((buf = fgetc(fd)) != EOF) { + if (icur == (max - 1)) { + max = max * 2; + str = (char *) realloc(str, sizeof(char) * max); + } + if (!CharIn((char) buf, separators)) { + str[icur] = (char) buf; + icur++; + str[icur] = '\0'; + } + } + } while(!CharIn(buf, separators) && !feof(fd)); + return str; +} + +int CharIn(const char c, const char *in) { + int i; + for (i = 0; i < strlen(in); i++) + if (c == in[i]) return 1; + return 0; +} + +/* string handling */ + +int patternmatch(char *pattern, char *thestr) { + int i, j = -1, pl = strlen(pattern), sl = strlen(thestr); + for(i = 0; i < pl; i++) { + if (pattern[i] == '*') { + do { + i++; + if (i == pl) return 1; + } while(pattern[i] == '*'); + do { + j++; + if (j >= sl) return 0; + if ((thestr[j] == pattern[i]) && patternmatch(pattern + i, thestr + j)) return 1; + } while(1); + } else { + j++; + if (j >= sl) return 0; + if (pattern[i] != thestr[j]) return 0; + } + } + return (pl == sl); +} diff --git a/packages/ProbLog/simplecudd/general.h b/packages/ProbLog/simplecudd/general.h new file mode 100644 index 000000000..4441ed623 --- /dev/null +++ b/packages/ProbLog/simplecudd/general.h @@ -0,0 +1,159 @@ +/******************************************************************************\ +* * +* SimpleCUDD library (www.cs.kuleuven.be/~theo/tools/simplecudd.html) * +* SimpleCUDD was developed at Katholieke Universiteit Leuven(www.kuleuven.be) * +* * +* Copyright T. Mantadelis and Katholieke Universiteit Leuven 2008 * +* * +* Author: Theofrastos Mantadelis * +* File: general.h * +* * +******************************************************************************** +* * +* The "Artistic License" * +* * +* Preamble * +* * +* The intent of this document is to state the conditions under which a * +* Package may be copied, such that the Copyright Holder maintains some * +* semblance of artistic control over the development of the package, * +* while giving the users of the package the right to use and distribute * +* the Package in a more-or-less customary fashion, plus the right to make * +* reasonable modifications. * +* * +* Definitions: * +* * +* "Package" refers to the collection of files distributed by the * +* Copyright Holder, and derivatives of that collection of files * +* created through textual modification. * +* * +* "Standard Version" refers to such a Package if it has not been * +* modified, or has been modified in accordance with the wishes * +* of the Copyright Holder as specified below. * +* * +* "Copyright Holder" is whoever is named in the copyright or * +* copyrights for the package. * +* * +* "You" is you, if you're thinking about copying or distributing * +* this Package. * +* * +* "Reasonable copying fee" is whatever you can justify on the * +* basis of media cost, duplication charges, time of people involved, * +* and so on. (You will not be required to justify it to the * +* Copyright Holder, but only to the computing community at large * +* as a market that must bear the fee.) * +* * +* "Freely Available" means that no fee is charged for the item * +* itself, though there may be fees involved in handling the item. * +* It also means that recipients of the item may redistribute it * +* under the same conditions they received it. * +* * +* 1. You may make and give away verbatim copies of the source form of the * +* Standard Version of this Package without restriction, provided that you * +* duplicate all of the original copyright notices and associated disclaimers. * +* * +* 2. You may apply bug fixes, portability fixes and other modifications * +* derived from the Public Domain or from the Copyright Holder. A Package * +* modified in such a way shall still be considered the Standard Version. * +* * +* 3. You may otherwise modify your copy of this Package in any way, provided * +* that you insert a prominent notice in each changed file stating how and * +* when you changed that file, and provided that you do at least ONE of the * +* following: * +* * +* a) place your modifications in the Public Domain or otherwise make them * +* Freely Available, such as by posting said modifications to Usenet or * +* an equivalent medium, or placing the modifications on a major archive * +* site such as uunet.uu.net, or by allowing the Copyright Holder to include * +* your modifications in the Standard Version of the Package. * +* * +* b) use the modified Package only within your corporation or organization. * +* * +* c) rename any non-standard executables so the names do not conflict * +* with standard executables, which must also be provided, and provide * +* a separate manual page for each non-standard executable that clearly * +* documents how it differs from the Standard Version. * +* * +* d) make other distribution arrangements with the Copyright Holder. * +* * +* 4. You may distribute the programs of this Package in object code or * +* executable form, provided that you do at least ONE of the following: * +* * +* a) distribute a Standard Version of the executables and library files, * +* together with instructions (in the manual page or equivalent) on where * +* to get the Standard Version. * +* * +* b) accompany the distribution with the machine-readable source of * +* the Package with your modifications. * +* * +* c) give non-standard executables non-standard names, and clearly * +* document the differences in manual pages (or equivalent), together * +* with instructions on where to get the Standard Version. * +* * +* d) make other distribution arrangements with the Copyright Holder. * +* * +* 5. You may charge a reasonable copying fee for any distribution of this * +* Package. You may charge any fee you choose for support of this * +* Package. You may not charge a fee for this Package itself. However, * +* you may distribute this Package in aggregate with other (possibly * +* commercial) programs as part of a larger (possibly commercial) software * +* distribution provided that you do not advertise this Package as a * +* product of your own. You may embed this Package's interpreter within * +* an executable of yours (by linking); this shall be construed as a mere * +* form of aggregation, provided that the complete Standard Version of the * +* interpreter is so embedded. * +* * +* 6. The scripts and library files supplied as input to or produced as * +* output from the programs of this Package do not automatically fall * +* under the copyright of this Package, but belong to whoever generated * +* them, and may be sold commercially, and may be aggregated with this * +* Package. If such scripts or library files are aggregated with this * +* Package via the so-called "undump" or "unexec" methods of producing a * +* binary executable image, then distribution of such an image shall * +* neither be construed as a distribution of this Package nor shall it * +* fall under the restrictions of Paragraphs 3 and 4, provided that you do * +* not represent such an executable image as a Standard Version of this * +* Package. * +* * +* 7. C subroutines (or comparably compiled subroutines in other * +* languages) supplied by you and linked into this Package in order to * +* emulate subroutines and variables of the language defined by this * +* Package shall not be considered part of this Package, but are the * +* equivalent of input as in Paragraph 6, provided these subroutines do * +* not change the language in any way that would cause it to fail the * +* regression tests for the language. * +* * +* 8. Aggregation of this Package with a commercial distribution is always * +* permitted provided that the use of this Package is embedded; that is, * +* when no overt attempt is made to make this Package's interfaces visible * +* to the end user of the commercial distribution. Such use shall not be * +* construed as a distribution of this Package. * +* * +* 9. The name of the Copyright Holder may not be used to endorse or promote * +* products derived from this software without specific prior written * +* permission. * +* * +* 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * +* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * +* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * +* * +* The End * +* * +\******************************************************************************/ + + +#include +#include +#include + +#define IsNumberDigit(c) ('0' <= c && c <= '9') +#define IsSignDigit(c) (c == '+' || c == '-') +#define isOperator(x) (x == '+' || x == '*' || x == '#' || x == '=') +#define freadline(fd) freadstr(fd, "\n"); + +int IsRealNumber(char *c); +int IsPosNumber(const char *c); +int IsNumber(const char *c); +char * freadstr(FILE *fd, const char *separators); +int CharIn(const char c, const char *in); +int patternmatch(char *pattern, char *thestr); diff --git a/packages/ProbLog/simplecudd/simplecudd.c b/packages/ProbLog/simplecudd/simplecudd.c new file mode 100644 index 000000000..6ee290377 --- /dev/null +++ b/packages/ProbLog/simplecudd/simplecudd.c @@ -0,0 +1,1620 @@ +/******************************************************************************\ +* * +* SimpleCUDD library (www.cs.kuleuven.be/~theo/tools/simplecudd.html) * +* SimpleCUDD was developed at Katholieke Universiteit Leuven(www.kuleuven.be) * +* * +* Copyright T. Mantadelis and Katholieke Universiteit Leuven 2008 * +* * +* Author: Theofrastos Mantadelis * +* File: simplecudd.c * +* * +******************************************************************************** +* * +* The "Artistic License" * +* * +* Preamble * +* * +* The intent of this document is to state the conditions under which a * +* Package may be copied, such that the Copyright Holder maintains some * +* semblance of artistic control over the development of the package, * +* while giving the users of the package the right to use and distribute * +* the Package in a more-or-less customary fashion, plus the right to make * +* reasonable modifications. * +* * +* Definitions: * +* * +* "Package" refers to the collection of files distributed by the * +* Copyright Holder, and derivatives of that collection of files * +* created through textual modification. * +* * +* "Standard Version" refers to such a Package if it has not been * +* modified, or has been modified in accordance with the wishes * +* of the Copyright Holder as specified below. * +* * +* "Copyright Holder" is whoever is named in the copyright or * +* copyrights for the package. * +* * +* "You" is you, if you're thinking about copying or distributing * +* this Package. * +* * +* "Reasonable copying fee" is whatever you can justify on the * +* basis of media cost, duplication charges, time of people involved, * +* and so on. (You will not be required to justify it to the * +* Copyright Holder, but only to the computing community at large * +* as a market that must bear the fee.) * +* * +* "Freely Available" means that no fee is charged for the item * +* itself, though there may be fees involved in handling the item. * +* It also means that recipients of the item may redistribute it * +* under the same conditions they received it. * +* * +* 1. You may make and give away verbatim copies of the source form of the * +* Standard Version of this Package without restriction, provided that you * +* duplicate all of the original copyright notices and associated disclaimers. * +* * +* 2. You may apply bug fixes, portability fixes and other modifications * +* derived from the Public Domain or from the Copyright Holder. A Package * +* modified in such a way shall still be considered the Standard Version. * +* * +* 3. You may otherwise modify your copy of this Package in any way, provided * +* that you insert a prominent notice in each changed file stating how and * +* when you changed that file, and provided that you do at least ONE of the * +* following: * +* * +* a) place your modifications in the Public Domain or otherwise make them * +* Freely Available, such as by posting said modifications to Usenet or * +* an equivalent medium, or placing the modifications on a major archive * +* site such as uunet.uu.net, or by allowing the Copyright Holder to include * +* your modifications in the Standard Version of the Package. * +* * +* b) use the modified Package only within your corporation or organization. * +* * +* c) rename any non-standard executables so the names do not conflict * +* with standard executables, which must also be provided, and provide * +* a separate manual page for each non-standard executable that clearly * +* documents how it differs from the Standard Version. * +* * +* d) make other distribution arrangements with the Copyright Holder. * +* * +* 4. You may distribute the programs of this Package in object code or * +* executable form, provided that you do at least ONE of the following: * +* * +* a) distribute a Standard Version of the executables and library files, * +* together with instructions (in the manual page or equivalent) on where * +* to get the Standard Version. * +* * +* b) accompany the distribution with the machine-readable source of * +* the Package with your modifications. * +* * +* c) give non-standard executables non-standard names, and clearly * +* document the differences in manual pages (or equivalent), together * +* with instructions on where to get the Standard Version. * +* * +* d) make other distribution arrangements with the Copyright Holder. * +* * +* 5. You may charge a reasonable copying fee for any distribution of this * +* Package. You may charge any fee you choose for support of this * +* Package. You may not charge a fee for this Package itself. However, * +* you may distribute this Package in aggregate with other (possibly * +* commercial) programs as part of a larger (possibly commercial) software * +* distribution provided that you do not advertise this Package as a * +* product of your own. You may embed this Package's interpreter within * +* an executable of yours (by linking); this shall be construed as a mere * +* form of aggregation, provided that the complete Standard Version of the * +* interpreter is so embedded. * +* * +* 6. The scripts and library files supplied as input to or produced as * +* output from the programs of this Package do not automatically fall * +* under the copyright of this Package, but belong to whoever generated * +* them, and may be sold commercially, and may be aggregated with this * +* Package. If such scripts or library files are aggregated with this * +* Package via the so-called "undump" or "unexec" methods of producing a * +* binary executable image, then distribution of such an image shall * +* neither be construed as a distribution of this Package nor shall it * +* fall under the restrictions of Paragraphs 3 and 4, provided that you do * +* not represent such an executable image as a Standard Version of this * +* Package. * +* * +* 7. C subroutines (or comparably compiled subroutines in other * +* languages) supplied by you and linked into this Package in order to * +* emulate subroutines and variables of the language defined by this * +* Package shall not be considered part of this Package, but are the * +* equivalent of input as in Paragraph 6, provided these subroutines do * +* not change the language in any way that would cause it to fail the * +* regression tests for the language. * +* * +* 8. Aggregation of this Package with a commercial distribution is always * +* permitted provided that the use of this Package is embedded; that is, * +* when no overt attempt is made to make this Package's interfaces visible * +* to the end user of the commercial distribution. Such use shall not be * +* construed as a distribution of this Package. * +* * +* 9. The name of the Copyright Holder may not be used to endorse or promote * +* products derived from this software without specific prior written * +* permission. * +* * +* 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * +* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * +* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * +* * +* The End * +* * +\******************************************************************************/ + + +#include "simplecudd.h" + +/* BDD manager initialization */ + +int _debug = 0; +int _RapidLoad = 0; +int _maxbufsize = 0; + +DdManager* simpleBDDinit(int varcnt) { + DdManager *temp; + temp = Cudd_Init(varcnt, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0); + Cudd_AutodynEnable(temp, CUDD_REORDER_GROUP_SIFT); + Cudd_SetMaxCacheHard(temp, 1024*1024*1024); + Cudd_SetLooseUpTo(temp, 1024*1024*512); + if (_debug) Cudd_EnableReorderingReporting(temp); + return temp; +} + +/* BDD tree travesrsing */ + +DdNode* HighNodeOf(DdManager *manager, DdNode *node) { + DdNode *tmp; + if (IsHigh(manager, node)) return HIGH(manager); + if (IsLow(manager, node)) return LOW(manager); + tmp = Cudd_Regular(node); + if (Cudd_IsComplement(node)) return NOT(tmp->type.kids.T); + return tmp->type.kids.T; +} + +DdNode* LowNodeOf(DdManager *manager, DdNode *node) { + DdNode *tmp; + if (IsHigh(manager, node)) return HIGH(manager); + if (IsLow(manager, node)) return LOW(manager); + tmp = Cudd_Regular(node); + if (Cudd_IsComplement(node)) return NOT(tmp->type.kids.E); + return tmp->type.kids.E; +} + +/* BDD tree generation */ + +DdNode* D_BDDAnd(DdManager *manager, DdNode *bdd1, DdNode *bdd2) { + DdNode *tmp; + tmp = Cudd_bddAnd(manager, bdd1, bdd2); + Cudd_Ref(tmp); + Cudd_RecursiveDeref(manager, bdd2); + return tmp; +} + +DdNode* D_BDDNand(DdManager *manager, DdNode *bdd1, DdNode *bdd2) { + DdNode *tmp; + tmp = Cudd_bddNand(manager, bdd1, bdd2); + Cudd_Ref(tmp); + Cudd_RecursiveDeref(manager, bdd2); + return tmp; +} + +DdNode* D_BDDOr(DdManager *manager, DdNode *bdd1, DdNode *bdd2) { + DdNode *tmp; + tmp = Cudd_bddOr(manager, bdd1, bdd2); + Cudd_Ref(tmp); + Cudd_RecursiveDeref(manager, bdd2); + return tmp; +} + +DdNode* D_BDDNor(DdManager *manager, DdNode *bdd1, DdNode *bdd2) { + DdNode *tmp; + tmp = Cudd_bddNor(manager, bdd1, bdd2); + Cudd_Ref(tmp); + Cudd_RecursiveDeref(manager, bdd2); + return tmp; +} + +DdNode* D_BDDXor(DdManager *manager, DdNode *bdd1, DdNode *bdd2) { + DdNode *tmp; + tmp = Cudd_bddXor(manager, bdd1, bdd2); + Cudd_Ref(tmp); + Cudd_RecursiveDeref(manager, bdd2); + return tmp; +} + +DdNode* D_BDDXnor(DdManager *manager, DdNode *bdd1, DdNode *bdd2) { + DdNode *tmp; + tmp = Cudd_bddXnor(manager, bdd1, bdd2); + Cudd_Ref(tmp); + Cudd_RecursiveDeref(manager, bdd2); + return tmp; +} + +/* file manipulation */ + +bddfileheader ReadFileHeader(char *filename) { + bddfileheader temp; + char *header; + temp.inputfile = NULL; + temp.version = 0; + temp.varcnt = 0; + temp.varstart = 0; + temp.intercnt = 0; + temp.filetype = BDDFILE_OTHER; + if ((temp.inputfile = fopen(filename, "r")) == NULL) { + perror(filename); + temp.filetype = BDDFILE_ERROR; + return temp; + } + // Read file header + if (!feof(temp.inputfile)) { + header = freadline(temp.inputfile); + temp.version = CheckFileVersion(header); + if (temp.version > -1) temp.filetype = (strlen(header) == 5) * BDDFILE_SCRIPT + (strlen(header) == 7) * BDDFILE_NODEDUMP; + free(header); + switch (temp.filetype) { + case BDDFILE_SCRIPT: + switch (temp.version) { + case 1: + fscanf(temp.inputfile, "%i\n", &temp.varcnt); + fscanf(temp.inputfile, "%i\n", &temp.varstart); + fscanf(temp.inputfile, "%i\n", &temp.intercnt); + break; + default: + fclose(temp.inputfile); + temp.inputfile = NULL; + break; + } + break; + case BDDFILE_NODEDUMP: + switch (temp.version) { + case 1: + fscanf(temp.inputfile, "%i\n", &temp.varcnt); + fscanf(temp.inputfile, "%i\n", &temp.varstart); + break; + default: + fclose(temp.inputfile); + temp.inputfile = NULL; + break; + } + break; + case BDDFILE_OTHER: + fclose(temp.inputfile); + temp.inputfile = NULL; + break; + default: + fclose(temp.inputfile); + temp.inputfile = NULL; + break; + } + } + return temp; +} + +int CheckFileVersion(const char *version) { + if (strlen(version) < 5) return -1; + if (strlen(version) == 5 && version[0] == '@' && version[1] == 'B' && version[2] == 'D' && version[3] == 'D') return atoi(version + 4); + if (strlen(version) == 7 && version[0] == '@' && version[1] == 'N' && version[2] == 'O' && version[3] == 'D' + && version[4] == 'E' && version[5] == 'S') return atoi(version + 6); + return -1; +} + +int simpleBDDtoDot(DdManager *manager, DdNode *bdd, char *filename) { + DdNode *f[1]; + int ret; + FILE *fd; + f[0] = Cudd_BddToAdd(manager, bdd); + fd = fopen(filename, "w"); + if (fd == NULL) { + perror(filename); + return -1; + } + ret = Cudd_DumpDot(manager, 1, f, NULL, NULL, fd); + fclose(fd); + return ret; +} + +int simpleNamedBDDtoDot(DdManager *manager, namedvars varmap, DdNode *bdd, char *filename) { + DdNode *f[1]; + int ret; + FILE *fd; + f[0] = Cudd_BddToAdd(manager, bdd); + fd = fopen(filename, "w"); + if (fd == NULL) { + perror(filename); + return -1; + } + ret = Cudd_DumpDot(manager, 1, f, varmap.vars, NULL, fd); + fclose(fd); + return ret; +} + +int SaveNodeDump(DdManager *manager, namedvars varmap, DdNode *bdd, char *filename) { + hisqueue *Nodes; + FILE *outputfile; + int i; + if ((outputfile = fopen(filename, "w")) == NULL) { + perror(filename); + return -1; + } + fprintf(outputfile, "%s\n%i\n%i\n", "@NODES1", varmap.varcnt, varmap.varstart); + Nodes = InitHistory(varmap.varcnt); + for (i = 0; i < varmap.varcnt; i++) + fprintf(outputfile, "%s\t%i\n", varmap.vars[i], Cudd_ReadPerm(manager, i)); + if (bdd == HIGH(manager)) fprintf(outputfile, "TRUE\t0\tTRUE\t0\tTRUE\t0\n"); + else if (bdd == LOW(manager)) fprintf(outputfile, "FALSE\t0\tFALSE\t0\tFALSE\t0\n"); + else SaveExpand(manager, varmap, Nodes, bdd, outputfile); + ReInitHistory(Nodes, varmap.varcnt); + free(Nodes); + fclose(outputfile); + return 0; +} + +void SaveExpand(DdManager *manager, namedvars varmap, hisqueue *Nodes, DdNode *Current, FILE *outputfile) { + DdNode *h, *l; + hisnode *Found; + char *curnode; + int inode; + if (Current != HIGH(manager) && Current != LOW(manager)) { + if ((Found = GetNode(Nodes, varmap.varstart, Current)) == NULL) { + AddNode(Nodes, varmap.varstart, Current, 0.0, 0, NULL); + Found = GetNode(Nodes, varmap.varstart, Current); + } + if (!(Found->ivalue)) { + Found->ivalue = 1; + curnode = GetNodeVarNameDisp(manager, varmap, Current); + inode = GetNodeIndex(Nodes, varmap.varstart, Current); + fprintf(outputfile, "%s\t%i\t", curnode, inode); + h = HighNodeOf(manager, Current); + if (h == HIGH(manager)) { + fprintf(outputfile, "TRUE\t0\t"); + } else if (h == LOW(manager)) { + fprintf(outputfile, "FALSE\t0\t"); + } else { + if (GetNode(Nodes, varmap.varstart, h) == NULL) AddNode(Nodes, varmap.varstart, h, 0.0, 0, NULL); + curnode = GetNodeVarNameDisp(manager, varmap, h); + inode = GetNodeIndex(Nodes, varmap.varstart, h); + fprintf(outputfile, "%s\t%i\t", curnode, inode); + } + l = LowNodeOf(manager, Current); + if (l == HIGH(manager)) { + fprintf(outputfile, "TRUE\t0\n"); + } else if (l == LOW(manager)) { + fprintf(outputfile, "FALSE\t0\n"); + } else { + if (GetNode(Nodes, varmap.varstart, l) == NULL) AddNode(Nodes, varmap.varstart, l, 0.0, 0, NULL); + curnode = GetNodeVarNameDisp(manager, varmap, l); + inode = GetNodeIndex(Nodes, varmap.varstart, l); + fprintf(outputfile, "%s\t%i\n", curnode, inode); + } + SaveExpand(manager, varmap, Nodes, l, outputfile); + SaveExpand(manager, varmap, Nodes, h, outputfile); + } + } +} + +DdNode * LoadNodeDump(DdManager *manager, namedvars varmap, FILE *inputfile) { + hisqueue *Nodes; + nodeline temp; + DdNode *ret; + int i, pos, *perm; + char *varnam; + perm = (int *) malloc(sizeof(int) * varmap.varcnt); + Nodes = InitHistory(varmap.varcnt); + for (i = 0; i < varmap.varcnt; i++) { + varnam = freadstr(inputfile, "\t"); + pos = atoi(freadstr(inputfile, "\n")); + AddNamedVarAt(varmap, varnam, pos); + perm[pos] = pos; + } + temp.varname = freadstr(inputfile, "\t"); + fscanf(inputfile, "%i\t", &temp.nodenum); + temp.truevar = freadstr(inputfile, "\t"); + fscanf(inputfile, "%i\t", &temp.truenode); + temp.falsevar = freadstr(inputfile, "\t"); + fscanf(inputfile, "%i\n", &temp.falsenode); + ret = LoadNodeRec(manager, varmap, Nodes, inputfile, temp); + free(temp.varname); + free(temp.truevar); + free(temp.falsevar); + fclose(inputfile); + ReInitHistory(Nodes, varmap.varcnt); + free(Nodes); + Cudd_Ref(ret); + Cudd_ShuffleHeap(manager, perm); + for (i = 0; i < varmap.varcnt; i++) varmap.ivalue[i] = 0; + return ret; +} + +DdNode * LoadNodeRec(DdManager *manager, namedvars varmap, hisqueue *Nodes, FILE *inputfile, nodeline current) { + nodeline temp; + DdNode *newnode, *truenode, *falsenode; + int index; + newnode = GetIfExists(manager, varmap, Nodes, current.varname, current.nodenum); + if (newnode != NULL) return newnode; + falsenode = GetIfExists(manager, varmap, Nodes, current.falsevar, current.falsenode); + if (falsenode == NULL) { + temp.varname = freadstr(inputfile, "\t"); + fscanf(inputfile, "%i\t", &temp.nodenum); + temp.truevar = freadstr(inputfile, "\t"); + fscanf(inputfile, "%i\t", &temp.truenode); + temp.falsevar = freadstr(inputfile, "\t"); + fscanf(inputfile, "%i\n", &temp.falsenode); + falsenode = LoadNodeRec(manager, varmap, Nodes, inputfile, temp); + free(temp.varname); + free(temp.truevar); + free(temp.falsevar); + } + truenode = GetIfExists(manager, varmap, Nodes, current.truevar, current.truenode); + if (truenode == NULL) { + temp.varname = freadstr(inputfile, "\t"); + fscanf(inputfile, "%i\t", &temp.nodenum); + temp.truevar = freadstr(inputfile, "\t"); + fscanf(inputfile, "%i\t", &temp.truenode); + temp.falsevar = freadstr(inputfile, "\t"); + fscanf(inputfile, "%i\n", &temp.falsenode); + truenode = LoadNodeRec(manager, varmap, Nodes, inputfile, temp); + free(temp.varname); + free(temp.truevar); + free(temp.falsevar); + } + index = GetNamedVarIndex(varmap, current.varname); + if (!varmap.ivalue[index]) { + varmap.ivalue[index] = 1; + newnode = GetVar(manager, varmap.varstart + index); + //Cudd_RecursiveDeref(manager, newnode->type.kids.T); + //Cudd_RecursiveDeref(manager, newnode->type.kids.E); + newnode->type.kids.T = Cudd_NotCond(truenode, Cudd_IsComplement(truenode)); + newnode->type.kids.E = Cudd_NotCond(falsenode, Cudd_IsComplement(truenode)); + Cudd_Ref(newnode->type.kids.T); + Cudd_Ref(newnode->type.kids.E); + Cudd_Ref(newnode); + } else { + if (_RapidLoad == 1) { + newnode = cuddAllocNode(manager); + if (newnode != NULL) { + newnode->index = varmap.varstart + index; + newnode->type.kids.T = Cudd_NotCond(truenode, Cudd_IsComplement(truenode)); + newnode->type.kids.E = Cudd_NotCond(falsenode, Cudd_IsComplement(truenode)); + Cudd_Ref(newnode->type.kids.T); + Cudd_Ref(newnode->type.kids.E); + Cudd_Ref(newnode); + } + } else { + newnode = cuddUniqueInter(manager, varmap.varstart + index, Cudd_NotCond(truenode, Cudd_IsComplement(truenode)), Cudd_NotCond(falsenode, Cudd_IsComplement(truenode))); + if (newnode != NULL) { + Cudd_Ref(newnode); + } else { + newnode = cuddAllocNode(manager); + if (newnode != NULL) { + newnode->index = varmap.varstart + index; + newnode->type.kids.T = Cudd_NotCond(truenode, Cudd_IsComplement(truenode)); + newnode->type.kids.E = Cudd_NotCond(falsenode, Cudd_IsComplement(truenode)); + Cudd_Ref(newnode->type.kids.T); + Cudd_Ref(newnode->type.kids.E); + Cudd_Ref(newnode); + } + } + } + } + if (newnode != NULL) { + Nodes[index].thenode[current.nodenum].key = Cudd_NotCond(newnode, Cudd_IsComplement(truenode)); + return Cudd_NotCond(newnode, Cudd_IsComplement(truenode)); + } + return NULL; +} + +DdNode * GetIfExists(DdManager *manager, namedvars varmap, hisqueue *Nodes, char *varname, int nodenum) { + int index; + if (strcmp(varname, "TRUE") == 0) return HIGH(manager); + if (strcmp(varname, "FALSE") == 0) return LOW(manager); + index = GetNamedVarIndex(varmap, varname); + if (index == -1 * varmap.varcnt) { + fprintf(stderr, "Error: more variables requested than initialized.\n"); + exit(-1); + } + if ((index < 0) || (index == 0 && varmap.vars[0] == NULL)) { + index = AddNamedVar(varmap, varname); + } + ExpandNodes(Nodes, index, nodenum); + if (Nodes[index].thenode[nodenum].key != NULL) return Nodes[index].thenode[nodenum].key; + return NULL; +} + +void ExpandNodes(hisqueue *Nodes, int index, int nodenum) { + int i; + if (Nodes[index].cnt > nodenum) return; + Nodes[index].thenode = (hisnode *) realloc(Nodes[index].thenode, (nodenum + 1) * sizeof(hisnode)); + for (i = Nodes[index].cnt; i < nodenum + 1; i++) { + Nodes[index].thenode[i].key = NULL; + Nodes[index].thenode[i].ivalue = 0; + Nodes[index].thenode[i].dvalue = 0.0; + Nodes[index].thenode[i].dynvalue = NULL; + } + Nodes[index].cnt = nodenum + 1; +} + +int LoadVariableData(namedvars varmap, char *filename) { + FILE *data; + char *dataread, buf, *varname, *dynvalue; + double dvalue = 0.0; + int icur = 0, maxbufsize = 10, hasvar = 0, index = -1, idat = 0, ivalue = 0; + dynvalue = NULL; + if ((data = fopen(filename, "r")) == NULL) { + perror("fopen"); + return -1; + } + dataread = (char *) malloc(sizeof(char) * maxbufsize); + while(!feof(data)) { + fread(&buf, 1, 1, data); + if (buf == '\n') { + dataread[icur] = '\0'; + icur = 0; + buf = ' '; + if (dataread[0] == '@') { + if (hasvar) { + for (index = 0; index < varmap.varcnt; index++) { + if (patternmatch(varname, varmap.vars[index])) { + varmap.loaded[index] = 1; + varmap.dvalue[index] = dvalue; + varmap.ivalue[index] = ivalue; + if (varmap.dynvalue[index] != NULL) { + free(varmap.dynvalue[index]); + varmap.dynvalue[index] = NULL; + } + if (dynvalue != NULL) { + varmap.dynvalue[index] = (void *) malloc(sizeof(char) * (strlen(dynvalue) + 1)); + strcpy(varmap.dynvalue[index], dynvalue); + } + } + } + dvalue = 0.0; + ivalue = 0; + if (dynvalue != NULL) { + free(dynvalue); + dynvalue = NULL; + } + free(varname); + } + varname = (char *) malloc(sizeof(char) * strlen(dataread)); + strcpy(varname, dataread + 1); + hasvar = 1; + idat = 0; + } else { + if (hasvar >= 0) { + switch(idat) { + case 0: + if (IsRealNumber(dataread)) dvalue = atof(dataread); + else { + fprintf(stderr, "Error at file: %s. Variable: %s can't have non real value: %s.\n", filename, varname, dataread); + fclose(data); + free(varname); + free(dataread); + return -2; + } + idat++; + break; + case 1: + if (IsNumber(dataread)) ivalue = atoi(dataread); + else { + fprintf(stderr, "Error at file: %s. Variable: %s can't have non integer value: %s.\n", filename, varname, dataread); + fclose(data); + free(varname); + free(dataread); + return -2; + } + idat++; + break; + case 2: + dynvalue = malloc(sizeof(char) * (strlen(dataread) + 1)); + strcpy(dynvalue, dataread); + break; + } + } + } + } else { + dataread[icur] = buf; + icur++; + if (icur == _maxbufsize) { + fprintf(stderr, "Error: Maximum buffer size(%i) exceeded.\n", _maxbufsize); + fclose(data); + free(varname); + free(dataread); + return -2; + } + while (icur > maxbufsize - 1) { + maxbufsize *= 2; + dataread = (char *) realloc(dataread, sizeof(char) * maxbufsize); + } + } + } + if (hasvar) { + for (index = 0; index < varmap.varcnt; index++) { + if (patternmatch(varname, varmap.vars[index])) { + varmap.loaded[index] = 1; + varmap.dvalue[index] = dvalue; + varmap.ivalue[index] = ivalue; + if (dynvalue != NULL) { + varmap.dynvalue[index] = (void *) malloc(sizeof(char) * (strlen(dynvalue) + 1)); + strcpy(varmap.dynvalue[index], dynvalue); + } + } + } + if (dynvalue != NULL) { + free(dynvalue); + dynvalue = NULL; + } + free(varname); + } + fclose(data); + free(dataread); + return 0; +} + +/* Queue for node storing to avoid loops */ + +hisqueue* InitHistory(int varcnt) { + int i; + hisqueue *HisQueue; + HisQueue = (hisqueue *) malloc(sizeof(hisqueue) * varcnt); + for (i = 0; i < varcnt; i++) { + HisQueue[i].thenode = NULL; + HisQueue[i].cnt = 0; + } + return HisQueue; +} + +void ReInitHistory(hisqueue *HisQueue, int varcnt) { + int i, j; + for (i = 0; i < varcnt; i++) { + if (HisQueue[i].thenode != NULL) { + for (j = 0; j < HisQueue[i].cnt; j++) + if (HisQueue[i].thenode[j].dynvalue != NULL) free(HisQueue[i].thenode[j].dynvalue); + free(HisQueue[i].thenode); + HisQueue[i].thenode = NULL; + } + HisQueue[i].cnt = 0; + } +} + +void AddNode(hisqueue *HisQueue, int varstart, DdNode *node, double dvalue, int ivalue, void *dynvalue) { + int index = GetIndex(node) - varstart; + HisQueue[index].thenode = (hisnode *) realloc(HisQueue[index].thenode, (HisQueue[index].cnt + 1) * sizeof(hisnode)); + HisQueue[index].thenode[HisQueue[index].cnt].key = node; + HisQueue[index].thenode[HisQueue[index].cnt].dvalue = dvalue; + HisQueue[index].thenode[HisQueue[index].cnt].ivalue = ivalue; + HisQueue[index].thenode[HisQueue[index].cnt].dynvalue = dynvalue; + HisQueue[index].cnt += 1; +} + +hisnode* GetNode(hisqueue *HisQueue, int varstart, DdNode *node) { + int i; + int index = GetIndex(node) - varstart; + for(i = 0; i < HisQueue[index].cnt; i++) { + if (HisQueue[index].thenode[i].key == node) return &(HisQueue[index].thenode[i]); + } + return NULL; +} + +int GetNodeIndex(hisqueue *HisQueue, int varstart, DdNode *node) { + int i; + int index = GetIndex(node) - varstart; + for(i = 0; i < HisQueue[index].cnt; i++) { + if (HisQueue[index].thenode[i].key == node) return i; + } + return -1; +} + +/* Named variables */ + +namedvars InitNamedVars(int varcnt, int varstart) { + namedvars temp; + int i; + temp.varcnt = varcnt; + temp.varstart = varstart; + temp.vars = (char **) malloc(sizeof(char *) * varcnt); + temp.loaded = (int *) malloc(sizeof(int) * varcnt); + temp.dvalue = (double *) malloc(sizeof(double) * varcnt); + temp.ivalue = (int *) malloc(sizeof(int) * varcnt); + temp.dynvalue = (void **) malloc(sizeof(int) * varcnt); + for (i = 0; i < varcnt; i++) { + temp.vars[i] = NULL; + temp.loaded[i] = 0; + temp.dvalue[i] = 0.0; + temp.ivalue[i] = 0; + temp.dynvalue[i] = NULL; + } + return temp; +} + +void EnlargeNamedVars(namedvars *varmap, int newvarcnt) { + int i; + varmap->vars = (char **) realloc(varmap->vars, sizeof(char *) * newvarcnt); + varmap->loaded = (int *) realloc(varmap->loaded, sizeof(int) * newvarcnt); + varmap->dvalue = (double *) realloc(varmap->dvalue, sizeof(double) * newvarcnt); + varmap->ivalue = (int *) realloc(varmap->ivalue, sizeof(int) * newvarcnt); + varmap->dynvalue = (void **) realloc(varmap->dynvalue, sizeof(int) * newvarcnt); + for (i = varmap->varcnt; i < newvarcnt; i++) { + varmap->vars[i] = NULL; + varmap->loaded[i] = 0; + varmap->dvalue[i] = 0.0; + varmap->ivalue[i] = 0; + varmap->dynvalue[i] = NULL; + } + varmap->varcnt = newvarcnt; +} + +int AddNamedVarAt(namedvars varmap, const char *varname, int index) { + if (varmap.varcnt > index) { + varmap.vars[index] = (char *) malloc(sizeof(char) * (strlen(varname) + 1)); + strcpy(varmap.vars[index], varname); + return index; + } + return -1; +} + +int AddNamedVar(namedvars varmap, const char *varname) { + int index = GetNamedVarIndex(varmap, varname); + if (index == -1 * varmap.varcnt) { + return -1; + } else if ((index < 0) || (index == 0 && varmap.vars[0] == NULL)) { + index *= -1; + varmap.vars[index] = (char *) malloc(sizeof(char) * (strlen(varname) + 1)); + strcpy(varmap.vars[index], varname); + } + return index; +} + +void SetNamedVarValuesAt(namedvars varmap, int index, double dvalue, int ivalue, void *dynvalue) { + varmap.dvalue[index] = dvalue; + varmap.ivalue[index] = ivalue; + varmap.dynvalue[index] = dynvalue; +} + +int SetNamedVarValues(namedvars varmap, const char *varname, double dvalue, int ivalue, void *dynvalue) { + int index = GetNamedVarIndex(varmap, varname); + if (index == -1 * varmap.varcnt) { + return -1; + } else if ((index < 0) || (index == 0 && varmap.vars[0] == NULL)) { + index *= -1; + varmap.vars[index] = (char *) malloc(sizeof(char) * (strlen(varname) + 1)); + strcpy(varmap.vars[index], varname); + varmap.dvalue[index] = dvalue; + varmap.ivalue[index] = ivalue; + varmap.dynvalue[index] = dynvalue; + } else { + varmap.dvalue[index] = dvalue; + varmap.ivalue[index] = ivalue; + varmap.dynvalue[index] = dynvalue; + } + return index; +} + +int GetNamedVarIndex(const namedvars varmap, const char *varname) { + int i; + for (i = 0; i < varmap.varcnt; i++) { + if (varmap.vars[i] == NULL) return -1 * i; + if (strcmp(varmap.vars[i], varname) == 0) return i; + } + return -1 * varmap.varcnt; +} + +char* GetNodeVarName(DdManager *manager, namedvars varmap, DdNode *node) { + if (node == NULL) return NULL; + if (node == HIGH(manager)) return "true"; + if (node == LOW(manager)) return "false"; + return varmap.vars[GetIndex(node) - varmap.varstart]; +} + +char* GetNodeVarNameDisp(DdManager *manager, namedvars varmap, DdNode *node) { + if (HIGH(manager) == node) return "TRUE"; + if (LOW(manager) == node) return "FALSE"; + if (NULL == node) return "(null)"; + return varmap.vars[GetIndex(node) - varmap.varstart]; +} + +int RepairVarcnt(namedvars *varmap) { + while (varmap->vars[varmap->varcnt - 1] == NULL) + varmap->varcnt--; + return varmap->varcnt; +} + +int all_loaded(namedvars varmap, int disp) { + int i, res = 1; + for (i = 0; i < varmap.varcnt; i++) { + if (varmap.loaded[i] == 0) { + res = 0; + if (disp) fprintf(stderr, "The variable: %s was not loaded with values.\n", varmap.vars[i]); else return 0; + } + } + return res; +} + +/* Parser */ + +DdNode* FileGenerateBDD(DdManager *manager, namedvars varmap, bddfileheader fileheader) { + int icomment, maxlinesize, icur, iline, curinter, iequal; + DdNode *Line, **inter; + char buf, *inputline, *filename; + bddfileheader interfileheader; + // Initialization of intermediate steps + inter = (DdNode **) malloc(sizeof(DdNode *) * fileheader.intercnt); + for (icur = 0; icur < fileheader.intercnt; icur++) inter[icur] = NULL; + // Read file data + interfileheader.inputfile = NULL; + filename = NULL; // For nested files + iequal = 0; // Flag for encountered = sign + icur = 0; // Pointer for inputline buffer location + iline = 5; // Current file line (first after header) + icomment = 0; // Flag for comments + maxlinesize = 80; // inputline starting buffer size + inputline = (char *) malloc(sizeof(char) * maxlinesize); + while(!feof(fileheader.inputfile)) { + fread(&buf, 1, 1, fileheader.inputfile); + if (buf == ';' || buf == '%' || buf == '$') icomment = 1; + if (buf == '\n') { + if (icomment) icomment = 0; + if (iequal > 1) { + fprintf(stderr, "Error at line: %i. Line contains more than 1 equal(=) signs.\n", iline); + fclose(fileheader.inputfile); + free(inter); + free(inputline); + return NULL; + } else iequal = 0; + if (icur > 0) { + inputline[icur] = '\0'; + if (inputline[0] != 'L') { + fprintf(stderr, "Error at line: %i. Intermediate results should start with L.\n", iline); + fclose(fileheader.inputfile); + free(inter); + free(inputline); + return NULL; + } + curinter = getInterBDD(inputline); + if (curinter == -1) { + if (inputline[0] == 'L' && IsPosNumber(inputline + 1)) { + curinter = atoi(inputline + 1) - 1; + if (curinter > -1 && curinter < fileheader.intercnt && inter[curinter] != NULL) { + if (_debug) fprintf(stderr, "Returned: %s\n", inputline); + fclose(fileheader.inputfile); + Line = inter[curinter]; + free(inter); + free(inputline); + return Line; + } else { + fprintf(stderr, "Error at line: %i. Return result asked doesn't exist.\n", iline); + fclose(fileheader.inputfile); + free(inter); + free(inputline); + return NULL; + } + } else { + fprintf(stderr, "Error at line: %i. Invalid intermediate result format.\n", iline); + fclose(fileheader.inputfile); + free(inter); + free(inputline); + return NULL; + } + } else if (curinter > -1 && curinter < fileheader.intercnt && inter[curinter] == NULL) { + if (_debug) fprintf(stderr, "%i %s\n", curinter, inputline); + filename = getFileName(inputline); + if (filename == NULL) { + Line = LineParser(manager, varmap, inter, fileheader.intercnt, inputline, iline); + } else { + interfileheader = ReadFileHeader(filename); + if (interfileheader.inputfile == NULL) { + //Line = simpleBDDload(manager, &varmap, filename); + Line = NULL; + } else { + Line = FileGenerateBDD(manager, varmap, interfileheader); + } + if (Line == NULL) fprintf(stderr, "Error at line: %i. Error in nested BDD file: %s.\n", iline, filename); + free(filename); + filename = NULL; + interfileheader.inputfile = NULL; + } + if (Line == NULL) { + fclose(fileheader.inputfile); + free(inter); + free(inputline); + return NULL; + } + inter[curinter] = Line; + icur = 0; + } else if (curinter > -1 && curinter < fileheader.intercnt && inter[curinter] != NULL) { + fprintf(stderr, "Error at line: %i. Intermediate results can't be overwritten.\n", iline); + fclose(fileheader.inputfile); + free(inter); + free(inputline); + return NULL; + } else { + fprintf(stderr, "Error at line: %i. Intermediate result asked doesn't exist.\n", iline); + fclose(fileheader.inputfile); + free(inter); + free(inputline); + return NULL; + } + } + iline++; + } else if (buf != ' ' && buf != '\t' && !icomment) { + if (buf == '=') iequal++; + inputline[icur] = buf; + icur += 1; + if (icur == _maxbufsize) { + fprintf(stderr, "Error: Maximum buffer size(%i) exceeded.\n", _maxbufsize); + fclose(fileheader.inputfile); + free(inter); + free(inputline); + return NULL; + } + while (icur > maxlinesize - 1) { + maxlinesize *= 2; + inputline = (char *) realloc(inputline, sizeof(char) * maxlinesize); + } + } + } + fprintf(stderr, "Error, file either doesn't end with a blank line or no return result was asked.\n"); + fclose(fileheader.inputfile); + free(inter); + free(inputline); + return NULL; +} + +int getInterBDD(char *function) { + int i, ret; + char *inter; + for (i = 0; i < strlen(function); i++) { + if (function[i] == '=') { + inter = (char *) malloc(sizeof(char) * i); + strncpy(inter, function + 1, i - 1); + inter[i - 1] = '\0'; + if (IsPosNumber(inter)) { + ret = atoi(inter) - 1; + free(inter); + return ret; + } else { + free(inter); + return -1; + } + } + } + return -1; +} + +char* getFileName(const char *function) { + int i = 0; + char *filename; + while(function[i] != '=' && (i + 1) < strlen(function)) i++; + if ((i + 1) < strlen(function)) { + i++; + if (function[i] == '<' && function[strlen(function) - 1] == '>') { + filename = (char *) malloc(sizeof(char) * strlen(function) - i); + strcpy(filename, function + i + 1); + filename[strlen(function) - i - 2] = '\0'; + return filename; + } + } + return NULL; +} + +DdNode* LineParser(DdManager *manager, namedvars varmap, DdNode **inter, int maxinter, char *function, int iline) { + int istart, iend, ilength, i, symbol, ivar, inegvar, inegoper, iconst; + long startAt, endAt; + double secs; + DdNode *bdd; + char *term, curoper; + bdd = HIGH(manager); + Cudd_Ref(bdd); + term = NULL; + ivar = -1; + curoper = '*'; + istart = -1; + iend = strlen(function) - 1; + ilength = -1; + symbol = -1; + inegvar = 0; + inegoper = 0; + iconst = 0; + for (i = strlen(function) - 1; i > -1; i--) { + if (symbol == -1 && isOperator(function[i])) { + symbol = i; + istart = i + 1; + ilength = iend - i; + iend = i - 1; + if (ilength > 0 && !(ilength == 1 && function[istart] == '~')) { + term = (char *) malloc(sizeof(char) * (ilength + 1)); + strncpy(term, function + istart, ilength); + term[ilength] = '\0'; + } else { + fprintf(stderr, "Line Parser Error at line: %i. An operator was encounter with no term at its right side.\n", iline); + free(term); + return NULL; + } + } + if (symbol != -1) { + if (term[0] == '~') inegvar = 1; else inegvar = 0; + if (term[0 + inegvar] != 'L') { + // Term is a variable + if (strcmp(term + inegvar, "TRUE") == 0) { + iconst = 1; + } else if (strcmp(term + inegvar, "FALSE") == 0) { + iconst = 1; + inegvar = 1; + } else { + iconst = 0; + ivar = AddNamedVar(varmap, term + inegvar); + if (ivar == -1) { + fprintf(stderr, "Line Parser Error at line: %i. More BDD variables than the reserved term: %s.\n", iline, term); + free(term); + return NULL; + } + } + if (_debug) fprintf(stderr, "%s\n", term); + if (_debug && !iconst) fprintf(stderr, "PNZ1:%.0f P1:%.0f S1:%i PNZ2:%.0f P2:%.0f S2:%i\n", + Cudd_CountPathsToNonZero(bdd), + Cudd_CountPath(bdd), + Cudd_DagSize(bdd), + Cudd_CountPathsToNonZero(GetVar(manager, ivar + varmap.varstart)), + Cudd_CountPath(GetVar(manager, ivar + varmap.varstart)), + Cudd_DagSize(GetVar(manager, ivar + varmap.varstart)) ); + startAt = clock(); + if (!iconst) { + if (inegvar) bdd = BDD_Operator(manager, NOT(GetVar(manager, ivar + varmap.varstart)), bdd, curoper, inegoper); + else bdd = BDD_Operator(manager, GetVar(manager, ivar + varmap.varstart), bdd, curoper, inegoper); + } else { + switch(curoper) { + case '+': + if (inegvar ^ inegoper) ; else { + bdd = HIGH(manager); + Cudd_Ref(bdd); + } + break; + case '*': + if (inegvar ^ inegoper) { + bdd = LOW(manager); + Cudd_Ref(bdd); + } + break; + case '#': + if (inegvar ^ inegoper) ; else bdd = NOT(bdd); + break; + } + } + endAt = clock(); + secs = ((double) (endAt - startAt)) / ((double) CLOCKS_PER_SEC); + if (_debug) fprintf(stderr, "term: %s of line: %i took: %i\n", term, iline, endAt - startAt); + //if ((endAt - startAt) > 10000000) Cudd_AutodynDisable(manager); + if (bdd == NULL) { + fprintf(stderr, "Line Parser Error at line: %i. Error using operator %c on term: %s.\n", iline, curoper, term); + free(term); + return NULL; + } + } else { + // Term is an intermediate result + if (IsPosNumber(term + inegvar + 1)) ivar = atoi(term + inegvar + 1) - 1; else { + fprintf(stderr, "Line Parser Error at line: %i. Invalid intermediate result format term: %s.\n", iline, term); + free(term); + return NULL; + } + if (ivar < 0 || ivar > maxinter || inter[ivar] == NULL) { + fprintf(stderr, "Line Parser Error at line: %i. Usage of undeclared intermediate result term: %s.\n", iline, term); + free(term); + return NULL; + } + if (_debug) fprintf(stderr, "%s\n", term); + if (_debug) fprintf(stderr, "PNZ1:%.0f P1:%.0f S1:%i PNZ2:%.0f P2:%.0f S2:%i\n", + Cudd_CountPathsToNonZero(bdd), + Cudd_CountPath(bdd), + Cudd_DagSize(bdd), + Cudd_CountPathsToNonZero(inter[ivar]), + Cudd_CountPath(inter[ivar]), + Cudd_DagSize(inter[ivar]) ); + startAt = clock(); + if (inegvar) bdd = BDD_Operator(manager, NOT(inter[ivar]), bdd, curoper, inegoper); + else bdd = BDD_Operator(manager, inter[ivar], bdd, curoper, inegoper); + endAt = clock(); + secs = ((double) (endAt - startAt)) / ((double) CLOCKS_PER_SEC); + if (_debug) fprintf(stderr, "term: %s of line: %i took: %i\n", term, iline, endAt - startAt); + //if ((endAt - startAt) > 10000000) Cudd_AutodynDisable(manager); + if (bdd == NULL) { + fprintf(stderr, "Line Parser Error at line: %i. Error using operator %c on term: %s.\n", iline, curoper, term); + free(term); + return NULL; + } + } + free(term); + term = NULL; + curoper = function[symbol]; + if (curoper == '=') return bdd; + if (function[symbol - 1] == '~') { + inegoper = 1; + i--; + iend--; + } else { + inegoper = 0; + } + symbol = -1; + } + } + return NULL; +} + +DdNode* BDD_Operator(DdManager *manager, DdNode *bdd1, DdNode *bdd2, char Operator, int inegoper) { + switch (Operator) { + case '+': + if (inegoper) return D_BDDNor(manager, bdd1, bdd2); + else return D_BDDOr(manager, bdd1, bdd2); + break; + case '*': + if (inegoper) return D_BDDNand(manager, bdd1, bdd2); + else return D_BDDAnd(manager, bdd1, bdd2); + break; + case '#': + if (inegoper) return D_BDDXnor(manager, bdd1, bdd2); + else return D_BDDXor(manager, bdd1, bdd2); + break; + default: + return NULL; + break; + } +} + +DdNode* OnlineGenerateBDD(DdManager *manager, namedvars *varmap) { + int icomment, maxlinesize, icur, iline, curinter, iequal, iinters, itmp, i; + DdNode *Line, **inter; + char buf, *inputline, *filename; + bddfileheader interfileheader; + // Initialization of intermediate steps + iinters = 1; + inter = (DdNode **) malloc(sizeof(DdNode *) * iinters); + for (icur = 0; icur < iinters; icur++) inter[icur] = NULL; + // Read file data + interfileheader.inputfile = NULL; + filename = NULL; // For nested files + iequal = 0; // Flag for encountered = sign + icur = 0; // Pointer for inputline buffer location + iline = 1; // Current file line (first after header) + icomment = 0; // Flag for comments + maxlinesize = 80; // inputline starting buffer size + inputline = (char *) malloc(sizeof(char) * maxlinesize); + + do { + buf = fgetc(stdin); + if (buf == ';' || buf == '%' || buf == '$') icomment = 1; + if (buf == '\n') { + if (icomment) icomment = 0; + if (iequal > 1) { + fprintf(stderr, "Error at line: %i. Line contains more than 1 equal(=) signs.\n", iline); + free(inter); + free(inputline); + return NULL; + } else iequal = 0; + if (icur > 0) { + inputline[icur] = '\0'; + if (inputline[0] == '@') { + if (inputline[1] == 'e') { + free(inter); + free(inputline); + exit(0); + } else { + itmp = GetParam(inputline, 1); + if (itmp > varmap->varcnt) + EnlargeNamedVars(varmap, itmp); + itmp = GetParam(inputline, 2); + if (itmp > iinters) { + inter = (DdNode **) realloc(inter, sizeof(DdNode *) * itmp); + for (i = iinters; i < itmp; i++) inter[i] = NULL; + iinters = itmp; + } + } + icur = 0; + } else { + if (inputline[0] != 'L') { + fprintf(stderr, "Error at line: %i. Intermediate results should start with L.\n", iline); + free(inter); + free(inputline); + return NULL; + } + curinter = getInterBDD(inputline); + if (curinter == -1) { + if (inputline[0] == 'L' && IsPosNumber(inputline + 1)) { + curinter = atoi(inputline + 1) - 1; + if (curinter > -1 && curinter < iinters && inter[curinter] != NULL) { + if (_debug) fprintf(stderr, "Returned: %s\n", inputline); + Line = inter[curinter]; + free(inter); + free(inputline); + return Line; + } else { + fprintf(stderr, "Error at line: %i. Return result asked doesn't exist.\n", iline); + free(inter); + free(inputline); + return NULL; + } + } else { + fprintf(stderr, "Error at line: %i. Invalid intermediate result format.\n", iline); + free(inter); + free(inputline); + return NULL; + } + } else if (curinter > -1) { + if (curinter >= iinters) { + inter = (DdNode **) realloc(inter, sizeof(DdNode *) * (curinter + 1)); + for (i = iinters; i < curinter + 1; i++) inter[i] = NULL; + iinters = curinter + 1; + } + if (inter[curinter] == NULL) { + if (_debug) fprintf(stderr, "%i %s\n", curinter, inputline); + filename = getFileName(inputline); + if (filename == NULL) { + Line = OnlineLineParser(manager, varmap, inter, iinters, inputline, iline); + } else { + interfileheader = ReadFileHeader(filename); + if (interfileheader.inputfile == NULL) { + //Line = simpleBDDload(manager, varmap, filename); + Line = NULL; + } else { + Line = FileGenerateBDD(manager, *varmap, interfileheader); + } + if (Line == NULL) fprintf(stderr, "Error at line: %i. Error in nested BDD file: %s.\n", iline, filename); + free(filename); + filename = NULL; + interfileheader.inputfile = NULL; + } + if (Line == NULL) { + free(inter); + free(inputline); + return NULL; + } + inter[curinter] = Line; + icur = 0; + } else if (inter[curinter] != NULL) { + fprintf(stderr, "Error at line: %i. Intermediate results can't be overwritten.\n", iline); + free(inter); + free(inputline); + return NULL; + } + } else { + fprintf(stderr, "Error at line: %i. Intermediate result asked doesn't exist.\n", iline); + free(inter); + free(inputline); + return NULL; + } + } + } + iline++; + } else if (buf != ' ' && buf != '\t' && !icomment) { + if (buf == '=') iequal++; + inputline[icur] = buf; + icur += 1; + if (icur == _maxbufsize) { + fprintf(stderr, "Error: Maximum buffer size(%i) exceeded.\n", _maxbufsize); + free(inter); + free(inputline); + return NULL; + } + while (icur > maxlinesize - 1) { + maxlinesize *= 2; + inputline = (char *) realloc(inputline, sizeof(char) * maxlinesize); + } + } + } while(1); + fprintf(stderr, "Error, file either doesn't end with a blank line or no return result was asked.\n"); + free(inter); + free(inputline); + return NULL; +} + +DdNode* OnlineLineParser(DdManager *manager, namedvars *varmap, DdNode **inter, int maxinter, char *function, int iline) { + int istart, iend, ilength, i, symbol, ivar, inegvar, inegoper, iconst; + long startAt, endAt; + double secs; + DdNode *bdd; + char *term, curoper; + bdd = HIGH(manager); + Cudd_Ref(bdd); + term = NULL; + ivar = -1; + curoper = '*'; + istart = -1; + iend = strlen(function) - 1; + ilength = -1; + symbol = -1; + inegvar = 0; + inegoper = 0; + iconst = 0; + for (i = strlen(function) - 1; i > -1; i--) { + if (symbol == -1 && isOperator(function[i])) { + symbol = i; + istart = i + 1; + ilength = iend - i; + iend = i - 1; + if (ilength > 0 && !(ilength == 1 && function[istart] == '~')) { + term = (char *) malloc(sizeof(char) * (ilength + 1)); + strncpy(term, function + istart, ilength); + term[ilength] = '\0'; + } else { + fprintf(stderr, "Line Parser Error at line: %i. An operator was encounter with no term at its right side.\n", iline); + free(term); + return NULL; + } + } + if (symbol != -1) { + if (term[0] == '~') inegvar = 1; else inegvar = 0; + if (term[0 + inegvar] != 'L') { + // Term is a variable + if (strcmp(term + inegvar, "TRUE") == 0) { + iconst = 1; + } else if (strcmp(term + inegvar, "FALSE") == 0) { + iconst = 1; + inegvar = 1; + } else { + iconst = 0; + ivar = AddNamedVar(*varmap, term + inegvar); + if (ivar == -1) { + EnlargeNamedVars(varmap, varmap->varcnt + 1); + ivar = AddNamedVar(*varmap, term + inegvar); + } + if (ivar == -1) { + fprintf(stderr, "Line Parser Error at line: %i. More BDD variables than the reserved term: %s.\n", iline, term); + free(term); + return NULL; + } + } + if (_debug) fprintf(stderr, "%s\n", term); + if (_debug && !iconst) fprintf(stderr, "PNZ1:%.0f P1:%.0f S1:%i PNZ2:%.0f P2:%.0f S2:%i\n", + Cudd_CountPathsToNonZero(bdd), + Cudd_CountPath(bdd), + Cudd_DagSize(bdd), + Cudd_CountPathsToNonZero(GetVar(manager, ivar + varmap->varstart)), + Cudd_CountPath(GetVar(manager, ivar + varmap->varstart)), + Cudd_DagSize(GetVar(manager, ivar + varmap->varstart)) ); + startAt = clock(); + if (!iconst) { + if (inegvar) bdd = BDD_Operator(manager, NOT(GetVar(manager, ivar + varmap->varstart)), bdd, curoper, inegoper); + else bdd = BDD_Operator(manager, GetVar(manager, ivar + varmap->varstart), bdd, curoper, inegoper); + } else { + switch(curoper) { + case '+': + if (inegvar ^ inegoper) ; else { + bdd = HIGH(manager); + Cudd_Ref(bdd); + } + break; + case '*': + if (inegvar ^ inegoper) { + bdd = LOW(manager); + Cudd_Ref(bdd); + } + break; + case '#': + if (inegvar ^ inegoper) ; else bdd = NOT(bdd); + break; + } + } + endAt = clock(); + secs = ((double) (endAt - startAt)) / ((double) CLOCKS_PER_SEC); + if (_debug) fprintf(stderr, "term: %s of line: %i took: %i\n", term, iline, endAt - startAt); + //if ((endAt - startAt) > 10000000) Cudd_AutodynDisable(manager); + if (bdd == NULL) { + fprintf(stderr, "Line Parser Error at line: %i. Error using operator %c on term: %s.\n", iline, curoper, term); + free(term); + return NULL; + } + } else { + // Term is an intermediate result + if (IsPosNumber(term + inegvar + 1)) ivar = atoi(term + inegvar + 1) - 1; else { + fprintf(stderr, "Line Parser Error at line: %i. Invalid intermediate result format term: %s.\n", iline, term); + free(term); + return NULL; + } + if (ivar < 0 || ivar > maxinter || inter[ivar] == NULL) { + fprintf(stderr, "Line Parser Error at line: %i. Usage of undeclared intermediate result term: %s.\n", iline, term); + free(term); + return NULL; + } + if (_debug) fprintf(stderr, "%s\n", term); + if (_debug) fprintf(stderr, "PNZ1:%.0f P1:%.0f S1:%i PNZ2:%.0f P2:%.0f S2:%i\n", + Cudd_CountPathsToNonZero(bdd), + Cudd_CountPath(bdd), + Cudd_DagSize(bdd), + Cudd_CountPathsToNonZero(inter[ivar]), + Cudd_CountPath(inter[ivar]), + Cudd_DagSize(inter[ivar]) ); + startAt = clock(); + if (inegvar) bdd = BDD_Operator(manager, NOT(inter[ivar]), bdd, curoper, inegoper); + else bdd = BDD_Operator(manager, inter[ivar], bdd, curoper, inegoper); + endAt = clock(); + secs = ((double) (endAt - startAt)) / ((double) CLOCKS_PER_SEC); + if (_debug) fprintf(stderr, "term: %s of line: %i took: %i\n", term, iline, endAt - startAt); + //if ((endAt - startAt) > 10000000) Cudd_AutodynDisable(manager); + if (bdd == NULL) { + fprintf(stderr, "Line Parser Error at line: %i. Error using operator %c on term: %s.\n", iline, curoper, term); + free(term); + return NULL; + } + } + free(term); + term = NULL; + curoper = function[symbol]; + if (curoper == '=') return bdd; + if (function[symbol - 1] == '~') { + inegoper = 1; + i--; + iend--; + } else { + inegoper = 0; + } + symbol = -1; + } + } + return NULL; +} + +int GetParam(char *inputline, int iParam) { + int icoma, istart, iend, ret; + char *numb; + istart = 1; + icoma = istart; + iend = strlen(inputline); + while((inputline[icoma] != ',') && (icoma < iend)) + icoma++; + if (iParam == 1) { + numb = (char *) malloc(sizeof(char) * icoma); + strncpy(numb, inputline + 1, icoma - 1); + numb[icoma - 1] = '\0'; + if (IsPosNumber(numb)) { + ret = atoi(numb); + free(numb); + return ret; + } + } else if(iParam == 2) { + numb = (char *) malloc(sizeof(char) * (iend - icoma + 1)); + strncpy(numb, inputline + icoma + 1, iend - icoma); + numb[iend - icoma] = '\0'; + if (IsPosNumber(numb)) { + ret = atoi(numb); + free(numb); + return ret; + } + } + return 0; +} + +void onlinetraverse(DdManager *manager, namedvars varmap, hisqueue *HisQueue, DdNode *bdd) { + char buf, *inputline; + int icur, maxlinesize, iline, index, iloop, ivalue, iQsize, i, inQ; + double dvalue; + DdNode **Q, **Q2, *h_node, *l_node, *curnode; + hisqueue *his; + hisnode *hnode; + iloop = 1; + icur = 0; // Pointer for inputline buffer location + iline = 1; // Current file line (first after header) + maxlinesize = 80; // inputline starting buffer size + inputline = (char *) malloc(sizeof(char) * maxlinesize); + curnode = bdd; + iQsize = 0; + Q = (DdNode **) malloc(sizeof(DdNode *) * iQsize); + Q2 = NULL; + his = InitHistory(varmap.varcnt); + do { + buf = fgetc(stdin); + if (buf == '\n') { + inputline[icur] = '\0'; + if ((icur > 0) && (inputline[0] == '@') && (inputline[2] == ',' || inputline[2] == '\0')) { + switch(inputline[1]) { + case 'c': + printf("bdd_temp_value('%s', %i).\n", GetNodeVarNameDisp(manager, varmap, curnode), iQsize); + break; + case 'n': + if (curnode != HIGH(manager) && curnode != LOW(manager) && (hnode = GetNode(his, varmap.varstart, curnode)) == NULL) { + AddNode(his, varmap.varstart, curnode, 0.0, 0, NULL); + l_node = LowNodeOf(manager, curnode); + h_node = HighNodeOf(manager, curnode); + inQ = 0; + for(i = 0; (i < iQsize / 2) && (inQ < 3); i++) + inQ = (Q[i] == l_node) || (Q[iQsize - i] == l_node) + 2 * (Q[i] == h_node) || (Q[iQsize - i] == h_node); + if (inQ & 1 == 0) inQ = inQ + (GetNode(his, varmap.varstart, l_node) != NULL); + if (inQ & 2 == 0) inQ = inQ + 2 * (GetNode(his, varmap.varstart, h_node) != NULL); + if (inQ & 1 == 1) inQ = inQ - (l_node == HIGH(manager) || l_node == LOW(manager)); + if (inQ & 2 == 2) inQ = inQ - 2 * (h_node == HIGH(manager) || h_node == LOW(manager)); + switch(inQ) { + case 0: + iQsize += 2; + Q = (DdNode **) realloc(Q, sizeof(DdNode *) * iQsize); + Q[iQsize - 2] = l_node; + Q[iQsize - 1] = h_node; + break; + case 1: + iQsize++; + Q = (DdNode **) realloc(Q, sizeof(DdNode *) * iQsize); + Q[iQsize - 1] = h_node; + break; + case 2: + iQsize++; + Q = (DdNode **) realloc(Q, sizeof(DdNode *) * iQsize); + Q[iQsize - 1] = l_node; + break; + case 3: + break; + default: + break; + } + } + if (inputline[2] == '\0' || strcmp(inputline + 3, "DFS") == 0) { + if (iQsize > 0) { + iQsize--; + curnode = Q[iQsize]; + Q = (DdNode **) realloc(Q, sizeof(DdNode *) * iQsize); + } + } else if (strcmp(inputline + 3, "BFS") == 0) { + if (iQsize > 0) { + iQsize--; + curnode = Q[0]; + Q2 = (DdNode **) malloc(sizeof(DdNode *) * iQsize); + for(i = 0; i < iQsize; i++) + Q2[i] = Q[i + 1]; + free(Q); + Q = Q2; + } + } else { + fprintf(stderr, "Error: Could not find method: %s, Correct syntax @n,[DFS, BFS].\n", inputline + 3); + free(Q); + free(inputline); + exit(-1); + } + break; + case 'h': + printf("bdd_temp_value('%s').\n", GetNodeVarNameDisp(manager, varmap, HighNodeOf(manager, curnode))); + break; + case 'l': + printf("bdd_temp_value('%s').\n", GetNodeVarNameDisp(manager, varmap, LowNodeOf(manager, curnode))); + break; + case 'v': + index = GetNamedVarIndex(varmap, inputline + 3); + if (index >= 0) { + fprintf(stdout, "bdd_temp_value([%f,%i,%s]).\n", varmap.dvalue[index], varmap.ivalue[index], (char *) varmap.dynvalue[index]); + } else { + fprintf(stderr, "Error: Could not find variable: %s, Correct syntax @v,[variable name].\n", inputline + 3); + free(Q); + free(inputline); + exit(-1); + } + break; + case 'e': + iloop = 0; + break; + default: + fprintf(stderr, "Error: Not recognizable instruction: %s.\n", inputline); + free(Q); + free(inputline); + exit(-1); + break; + } + icur = 0; + } else { + fprintf(stderr, "Error: Not recognizable instruction: %s.\n", inputline); + free(Q); + free(inputline); + exit(-1); + } + iline++; + } else if (buf != ' ' && buf != '\t') { + inputline[icur] = buf; + icur += 1; + if (icur == _maxbufsize) { + fprintf(stderr, "Error: Maximum buffer size(%i) exceeded.\n", _maxbufsize); + free(Q); + free(inputline); + exit(-1); + } + while (icur > maxlinesize - 1) { + maxlinesize *= 2; + inputline = (char *) realloc(inputline, sizeof(char) * maxlinesize); + } + } + } while(iloop); + free(Q); + free(inputline); +} diff --git a/packages/ProbLog/simplecudd/simplecudd.h b/packages/ProbLog/simplecudd/simplecudd.h new file mode 100644 index 000000000..49ed3a5aa --- /dev/null +++ b/packages/ProbLog/simplecudd/simplecudd.h @@ -0,0 +1,287 @@ +/******************************************************************************\ +* * +* SimpleCUDD library (www.cs.kuleuven.be/~theo/tools/simplecudd.html) * +* SimpleCUDD was developed at Katholieke Universiteit Leuven(www.kuleuven.be) * +* * +* Copyright T. Mantadelis and Katholieke Universiteit Leuven 2008 * +* * +* Author: Theofrastos Mantadelis * +* File: simplecudd.h * +* * +******************************************************************************** +* * +* The "Artistic License" * +* * +* Preamble * +* * +* The intent of this document is to state the conditions under which a * +* Package may be copied, such that the Copyright Holder maintains some * +* semblance of artistic control over the development of the package, * +* while giving the users of the package the right to use and distribute * +* the Package in a more-or-less customary fashion, plus the right to make * +* reasonable modifications. * +* * +* Definitions: * +* * +* "Package" refers to the collection of files distributed by the * +* Copyright Holder, and derivatives of that collection of files * +* created through textual modification. * +* * +* "Standard Version" refers to such a Package if it has not been * +* modified, or has been modified in accordance with the wishes * +* of the Copyright Holder as specified below. * +* * +* "Copyright Holder" is whoever is named in the copyright or * +* copyrights for the package. * +* * +* "You" is you, if you're thinking about copying or distributing * +* this Package. * +* * +* "Reasonable copying fee" is whatever you can justify on the * +* basis of media cost, duplication charges, time of people involved, * +* and so on. (You will not be required to justify it to the * +* Copyright Holder, but only to the computing community at large * +* as a market that must bear the fee.) * +* * +* "Freely Available" means that no fee is charged for the item * +* itself, though there may be fees involved in handling the item. * +* It also means that recipients of the item may redistribute it * +* under the same conditions they received it. * +* * +* 1. You may make and give away verbatim copies of the source form of the * +* Standard Version of this Package without restriction, provided that you * +* duplicate all of the original copyright notices and associated disclaimers. * +* * +* 2. You may apply bug fixes, portability fixes and other modifications * +* derived from the Public Domain or from the Copyright Holder. A Package * +* modified in such a way shall still be considered the Standard Version. * +* * +* 3. You may otherwise modify your copy of this Package in any way, provided * +* that you insert a prominent notice in each changed file stating how and * +* when you changed that file, and provided that you do at least ONE of the * +* following: * +* * +* a) place your modifications in the Public Domain or otherwise make them * +* Freely Available, such as by posting said modifications to Usenet or * +* an equivalent medium, or placing the modifications on a major archive * +* site such as uunet.uu.net, or by allowing the Copyright Holder to include * +* your modifications in the Standard Version of the Package. * +* * +* b) use the modified Package only within your corporation or organization. * +* * +* c) rename any non-standard executables so the names do not conflict * +* with standard executables, which must also be provided, and provide * +* a separate manual page for each non-standard executable that clearly * +* documents how it differs from the Standard Version. * +* * +* d) make other distribution arrangements with the Copyright Holder. * +* * +* 4. You may distribute the programs of this Package in object code or * +* executable form, provided that you do at least ONE of the following: * +* * +* a) distribute a Standard Version of the executables and library files, * +* together with instructions (in the manual page or equivalent) on where * +* to get the Standard Version. * +* * +* b) accompany the distribution with the machine-readable source of * +* the Package with your modifications. * +* * +* c) give non-standard executables non-standard names, and clearly * +* document the differences in manual pages (or equivalent), together * +* with instructions on where to get the Standard Version. * +* * +* d) make other distribution arrangements with the Copyright Holder. * +* * +* 5. You may charge a reasonable copying fee for any distribution of this * +* Package. You may charge any fee you choose for support of this * +* Package. You may not charge a fee for this Package itself. However, * +* you may distribute this Package in aggregate with other (possibly * +* commercial) programs as part of a larger (possibly commercial) software * +* distribution provided that you do not advertise this Package as a * +* product of your own. You may embed this Package's interpreter within * +* an executable of yours (by linking); this shall be construed as a mere * +* form of aggregation, provided that the complete Standard Version of the * +* interpreter is so embedded. * +* * +* 6. The scripts and library files supplied as input to or produced as * +* output from the programs of this Package do not automatically fall * +* under the copyright of this Package, but belong to whoever generated * +* them, and may be sold commercially, and may be aggregated with this * +* Package. If such scripts or library files are aggregated with this * +* Package via the so-called "undump" or "unexec" methods of producing a * +* binary executable image, then distribution of such an image shall * +* neither be construed as a distribution of this Package nor shall it * +* fall under the restrictions of Paragraphs 3 and 4, provided that you do * +* not represent such an executable image as a Standard Version of this * +* Package. * +* * +* 7. C subroutines (or comparably compiled subroutines in other * +* languages) supplied by you and linked into this Package in order to * +* emulate subroutines and variables of the language defined by this * +* Package shall not be considered part of this Package, but are the * +* equivalent of input as in Paragraph 6, provided these subroutines do * +* not change the language in any way that would cause it to fail the * +* regression tests for the language. * +* * +* 8. Aggregation of this Package with a commercial distribution is always * +* permitted provided that the use of this Package is embedded; that is, * +* when no overt attempt is made to make this Package's interfaces visible * +* to the end user of the commercial distribution. Such use shall not be * +* construed as a distribution of this Package. * +* * +* 9. The name of the Copyright Holder may not be used to endorse or promote * +* products derived from this software without specific prior written * +* permission. * +* * +* 10. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR * +* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * +* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * +* * +* The End * +* * +\******************************************************************************/ + + +#include +#include +#include +#include +#include +#include "util.h" +#include "cudd.h" +#include "cuddInt.h" +#include "general.h" + +#define IsHigh(manager, node) HIGH(manager) == node +#define IsLow(manager, node) LOW(manager) == node +#define HIGH(manager) Cudd_ReadOne(manager) +#define LOW(manager) Cudd_Not(Cudd_ReadOne(manager)) +#define NOT(node) Cudd_Not(node) +#define GetIndex(node) Cudd_NodeReadIndex(node) +#define GetVar(manager, index) Cudd_bddIthVar(manager, index) +#define NewVar(manager) Cudd_bddNewVar(manager) +#define KillBDD(manager) Cudd_Quit(manager) +#define GetVarCount(manager) Cudd_ReadSize(manager) +#define DEBUGON _debug = 1 +#define DEBUGOFF _debug = 0 +#define RAPIDLOADON _RapidLoad = 1 +#define RAPIDLOADOFF _RapidLoad = 0 +#define SETMAXBUFSIZE(size) _maxbufsize = size +#define BDDFILE_ERROR -1 +#define BDDFILE_OTHER 0 +#define BDDFILE_SCRIPT 1 +#define BDDFILE_NODEDUMP 2 + +extern int _RapidLoad; +extern int _debug; +extern int _maxbufsize; + +typedef struct _bddfileheader { + FILE *inputfile; + int version; + int varcnt; + int varstart; + int intercnt; + int filetype; +} bddfileheader; + +typedef struct _namedvars { + int varcnt; + int varstart; + char **vars; + int *loaded; + double *dvalue; + int *ivalue; + void **dynvalue; +} namedvars; + +typedef struct _hisnode { + DdNode *key; + double dvalue; + int ivalue; + void *dynvalue; +} hisnode; + +typedef struct _hisqueue { + int cnt; + hisnode *thenode; +} hisqueue; + +typedef struct _nodeline { + char *varname; + char *truevar; + char *falsevar; + int nodenum; + int truenode; + int falsenode; +} nodeline; + +/* Initialization */ + +DdManager* simpleBDDinit(int varcnt); + +/* BDD Generation */ + +DdNode* D_BDDAnd(DdManager *manager, DdNode *bdd1, DdNode *bdd2); +DdNode* D_BDDNand(DdManager *manager, DdNode *bdd1, DdNode *bdd2); +DdNode* D_BDDOr(DdManager *manager, DdNode *bdd1, DdNode *bdd2); +DdNode* D_BDDNor(DdManager *manager, DdNode *bdd1, DdNode *bdd2); +DdNode* D_BDDXor(DdManager *manager, DdNode *bdd1, DdNode *bdd2); +DdNode* D_BDDXnor(DdManager *manager, DdNode *bdd1, DdNode *bdd2); + +DdNode* FileGenerateBDD(DdManager *manager, namedvars varmap, bddfileheader fileheader); +DdNode* OnlineGenerateBDD(DdManager *manager, namedvars *varmap); +DdNode* LineParser(DdManager *manager, namedvars varmap, DdNode **inter, int maxinter, char *function, int iline); +DdNode* OnlineLineParser(DdManager *manager, namedvars *varmap, DdNode **inter, int maxinter, char *function, int iline); +DdNode* BDD_Operator(DdManager *manager, DdNode *bdd1, DdNode *bdd2, char Operator, int inegoper); +int getInterBDD(char *function); +char* getFileName(const char *function); +int GetParam(char *inputline, int iParam); +int LoadVariableData(namedvars varmap, char *filename); + +/* Named variables */ + +namedvars InitNamedVars(int varcnt, int varstart); +void EnlargeNamedVars(namedvars *varmap, int newvarcnt); +int AddNamedVarAt(namedvars varmap, const char *varname, int index); +int AddNamedVar(namedvars varmap, const char *varname); +void SetNamedVarValuesAt(namedvars varmap, int index, double dvalue, int ivalue, void *dynvalue); +int SetNamedVarValues(namedvars varmap, const char *varname, double dvalue, int ivalue, void *dynvalue); +int GetNamedVarIndex(const namedvars varmap, const char *varname); +int RepairVarcnt(namedvars *varmap); +char* GetNodeVarName(DdManager *manager, namedvars varmap, DdNode *node); +char* GetNodeVarNameDisp(DdManager *manager, namedvars varmap, DdNode *node); +int all_loaded(namedvars varmap, int disp); + +/* Traversal */ + +DdNode* HighNodeOf(DdManager *manager, DdNode *node); +DdNode* LowNodeOf(DdManager *manager, DdNode *node); + +/* Traversal - History */ + +hisqueue* InitHistory(int varcnt); +void ReInitHistory(hisqueue *HisQueue, int varcnt); +void AddNode(hisqueue *HisQueue, int varstart, DdNode *node, double dvalue, int ivalue, void *dynvalue); +hisnode* GetNode(hisqueue *HisQueue, int varstart, DdNode *node); +int GetNodeIndex(hisqueue *HisQueue, int varstart, DdNode *node); +void onlinetraverse(DdManager *manager, namedvars varmap, hisqueue *HisQueue, DdNode *bdd); + +/* Save-load */ + +bddfileheader ReadFileHeader(char *filename); +int CheckFileVersion(const char *version); + +DdNode * LoadNodeDump(DdManager *manager, namedvars varmap, FILE *inputfile); +DdNode * LoadNodeRec(DdManager *manager, namedvars varmap, hisqueue *Nodes, FILE *inputfile, nodeline current); +DdNode * GetIfExists(DdManager *manager, namedvars varmap, hisqueue *Nodes, char *varname, int nodenum); + +int SaveNodeDump(DdManager *manager, namedvars varmap, DdNode *bdd, char *filename); +void SaveExpand(DdManager *manager, namedvars varmap, hisqueue *Nodes, DdNode *Current, FILE *outputfile); +void ExpandNodes(hisqueue *Nodes, int index, int nodenum); + +/* Export */ + +int simpleBDDtoDot(DdManager *manager, DdNode *bdd, char *filename); +int simpleNamedBDDtoDot(DdManager *manager, namedvars varmap, DdNode *bdd, char *filename); + diff --git a/packages/cplint/Artistic b/packages/cplint/Artistic new file mode 100644 index 000000000..ddb9a463f --- /dev/null +++ b/packages/cplint/Artistic @@ -0,0 +1,201 @@ + The Artistic License 2.0 + + Copyright (c) 2000-2006, The Perl Foundation. + + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +Preamble + +This license establishes the terms under which a given free software +Package may be copied, modified, distributed, and/or redistributed. +The intent is that the Copyright Holder maintains some artistic +control over the development of that Package while still keeping the +Package available as open source and free software. + +You are always permitted to make arrangements wholly outside of this +license directly with the Copyright Holder of a given Package. If the +terms of this license do not permit the full use that you propose to +make of the Package, you should contact the Copyright Holder and seek +a different licensing arrangement. + +Definitions + + "Copyright Holder" means the individual(s) or organization(s) + named in the copyright notice for the entire Package. + + "Contributor" means any party that has contributed code or other + material to the Package, in accordance with the Copyright Holder's + procedures. + + "You" and "your" means any person who would like to copy, + distribute, or modify the Package. + + "Package" means the collection of files distributed by the + Copyright Holder, and derivatives of that collection and/or of + those files. A given Package may consist of either the Standard + Version, or a Modified Version. + + "Distribute" means providing a copy of the Package or making it + accessible to anyone else, or in the case of a company or + organization, to others outside of your company or organization. + + "Distributor Fee" means any fee that you charge for Distributing + this Package or providing support for this Package to another + party. It does not mean licensing fees. + + "Standard Version" refers to the Package if it has not been + modified, or has been modified only in ways explicitly requested + by the Copyright Holder. + + "Modified Version" means the Package, if it has been changed, and + such changes were not explicitly requested by the Copyright + Holder. + + "Original License" means this Artistic License as Distributed with + the Standard Version of the Package, in its current version or as + it may be modified by The Perl Foundation in the future. + + "Source" form means the source code, documentation source, and + configuration files for the Package. + + "Compiled" form means the compiled bytecode, object code, binary, + or any other form resulting from mechanical transformation or + translation of the Source form. + + +Permission for Use and Modification Without Distribution + +(1) You are permitted to use the Standard Version and create and use +Modified Versions for any purpose without restriction, provided that +you do not Distribute the Modified Version. + + +Permissions for Redistribution of the Standard Version + +(2) You may Distribute verbatim copies of the Source form of the +Standard Version of this Package in any medium without restriction, +either gratis or for a Distributor Fee, provided that you duplicate +all of the original copyright notices and associated disclaimers. At +your discretion, such verbatim copies may or may not include a +Compiled form of the Package. + +(3) You may apply any bug fixes, portability changes, and other +modifications made available from the Copyright Holder. The resulting +Package will still be considered the Standard Version, and as such +will be subject to the Original License. + + +Distribution of Modified Versions of the Package as Source + +(4) You may Distribute your Modified Version as Source (either gratis +or for a Distributor Fee, and with or without a Compiled form of the +Modified Version) provided that you clearly document how it differs +from the Standard Version, including, but not limited to, documenting +any non-standard features, executables, or modules, and provided that +you do at least ONE of the following: + + (a) make the Modified Version available to the Copyright Holder + of the Standard Version, under the Original License, so that the + Copyright Holder may include your modifications in the Standard + Version. + + (b) ensure that installation of your Modified Version does not + prevent the user installing or running the Standard Version. In + addition, the Modified Version must bear a name that is different + from the name of the Standard Version. + + (c) allow anyone who receives a copy of the Modified Version to + make the Source form of the Modified Version available to others + under + + (i) the Original License or + + (ii) a license that permits the licensee to freely copy, + modify and redistribute the Modified Version using the same + licensing terms that apply to the copy that the licensee + received, and requires that the Source form of the Modified + Version, and of any works derived from it, be made freely + available in that license fees are prohibited but Distributor + Fees are allowed. + + +Distribution of Compiled Forms of the Standard Version +or Modified Versions without the Source + +(5) You may Distribute Compiled forms of the Standard Version without +the Source, provided that you include complete instructions on how to +get the Source of the Standard Version. Such instructions must be +valid at the time of your distribution. If these instructions, at any +time while you are carrying out such distribution, become invalid, you +must provide new instructions on demand or cease further distribution. +If you provide valid instructions or cease distribution within thirty +days after you become aware that the instructions are invalid, then +you do not forfeit any of your rights under this license. + +(6) You may Distribute a Modified Version in Compiled form without +the Source, provided that you comply with Section 4 with respect to +the Source of the Modified Version. + + +Aggregating or Linking the Package + +(7) You may aggregate the Package (either the Standard Version or +Modified Version) with other packages and Distribute the resulting +aggregation provided that you do not charge a licensing fee for the +Package. Distributor Fees are permitted, and licensing fees for other +components in the aggregation are permitted. The terms of this license +apply to the use and Distribution of the Standard or Modified Versions +as included in the aggregation. + +(8) You are permitted to link Modified and Standard Versions with +other works, to embed the Package in a larger work of your own, or to +build stand-alone binary or bytecode versions of applications that +include the Package, and Distribute the result without restriction, +provided the result does not expose a direct interface to the Package. + + +Items That are Not Considered Part of a Modified Version + +(9) Works (including, but not limited to, modules and scripts) that +merely extend or make use of the Package, do not, by themselves, cause +the Package to be a Modified Version. In addition, such works are not +considered parts of the Package itself, and are not subject to the +terms of this license. + + +General Provisions + +(10) Any use, modification, and distribution of the Standard or +Modified Versions is governed by this Artistic License. By using, +modifying or distributing the Package, you accept this license. Do not +use, modify, or distribute the Package, if you do not accept this +license. + +(11) If your Modified Version has been derived from a Modified +Version made by someone other than you, you are nevertheless required +to ensure that your Modified Version complies with the requirements of +this license. + +(12) This license does not grant you the right to use any trademark, +service mark, tradename, or logo of the Copyright Holder. + +(13) This license includes the non-exclusive, worldwide, +free-of-charge patent license to make, have made, use, offer to sell, +sell, import and otherwise transfer the Package with respect to any +patent claims licensable by the Copyright Holder that are necessarily +infringed by the Package. If you institute patent litigation +(including a cross-claim or counterclaim) against any party alleging +that the Package constitutes direct or contributory patent +infringement, then this Artistic License to you shall terminate on the +date that such litigation is filed. + +(14) Disclaimer of Warranty: +THE PACKAGE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS "AS +IS' AND WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES. THE IMPLIED +WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR +NON-INFRINGEMENT ARE DISCLAIMED TO THE EXTENT PERMITTED BY YOUR LOCAL +LAW. UNLESS REQUIRED BY LAW, NO COPYRIGHT HOLDER OR CONTRIBUTOR WILL +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES ARISING IN ANY WAY OUT OF THE USE OF THE PACKAGE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/cplint/COPYRIGHT_SLG b/packages/cplint/COPYRIGHT_SLG new file mode 100644 index 000000000..44fe6bfec --- /dev/null +++ b/packages/cplint/COPYRIGHT_SLG @@ -0,0 +1,18 @@ + +Copyright (C) 1993 Southern Methodist University, + 1993 SUNY at Stony Brook + +Everyone is granted permission to use, copy, and distribute this +software free of charge provided that the notices in all files that +refer to file COPYRIGHT are kept intact and that file COPYRIGHT is +kept in all copies. Modification of this software is permitted +provided that all modified files carry prominent notices stating who +changed such files and the date of any change. + +This software is provided "as is" with absolutely NO warranties, +including the implied warranties of merchantability and fitness for a +particular purpose. In no event shall Southern Methodist University, +SUNY at Stony Brook, the authors, and/or any other party who may +modify and redistribute this software be liable to you for any damages +whatsoever arising out of or in connection with the use or performance +of this software. diff --git a/packages/cplint/Makefile.in b/packages/cplint/Makefile.in new file mode 100644 index 000000000..47f9ef139 --- /dev/null +++ b/packages/cplint/Makefile.in @@ -0,0 +1,168 @@ +# +# default base directory for YAP installation +# (EROOT for architecture-dependent files) +# +prefix = @prefix@ +ROOTDIR = $(prefix) +EROOTDIR = @exec_prefix@ +# +# where the binary should be +# +BINDIR = $(ROOTDIR)/bin +# +# where YAP should look for libraries +# +LIBDIR=$(ROOTDIR)/lib/Yap +# +# where YAP should look for architecture-independent Prolog libraries +# +SHAREDIR=$(ROOTDIR)/share/Yap +# +# +CC=@CC@ +CFLAGS= @CFLAGS@ $(YAP_EXTRAS) $(DEFS) -I$(srcdir) -I$(srcdir)/../include +# +# +# You shouldn't need to change what follows. +# +INSTALL=@INSTALL@ +INSTALL_DATA=@INSTALL_DATA@ +INSTALL_PROGRAM=@INSTALL_PROGRAM@ +SHELL=/bin/sh +RANLIB=@RANLIB@ +srcdir=@srcdir@ +SHLIB_CFLAGS=@SHLIB_CFLAGS@ +SHLIB_SUFFIX=@SHLIB_SUFFIX@ +CPLINT_CFLAGS=@CPLINT_CFLAGS@ +CPLINT_LDFLAGS=@CPLINT_LDFLAGS@ +CPLINT_LIBS=@CPLINT_LIBS@ +#4.1VPATH=@srcdir@:@srcdir@/OPTYap +CWD=$(PWD) +# +OBJS=cplint_yap.o cplint_Prob.o +SOBJS=cplint@SHLIB_SUFFIX@ + + + + +CPLINT_SRCDIR = $(srcdir) + +CPLINT_EXDIR = $(srcdir)/examples + +CPLINT_DOCDIR = $(srcdir)/doc + + +CPLINT_PROGRAMS= \ + $(CPLINT_SRCDIR)/lpadvel.pl \ + $(CPLINT_SRCDIR)/lpadclpbn.pl \ + $(CPLINT_SRCDIR)/lpadsld.pl \ + $(CPLINT_SRCDIR)/lpad.pl \ + $(CPLINT_SRCDIR)/cpl.pl + +CPLINT_SEMANTICS_PROGRAMS= \ + $(CPLINT_SRCDIR)/semlpadsld.pl \ + $(CPLINT_SRCDIR)/semlpad.pl \ + $(CPLINT_SRCDIR)/semcpl.pl \ + $(CPLINT_SRCDIR)/slg.pl + +CPLINT_TEST_PROGRAMS= \ + $(CPLINT_SRCDIR)/testlpadvel.pl \ + $(CPLINT_SRCDIR)/testlpadclpbn.pl \ + $(CPLINT_SRCDIR)/testlpadsld_gbtrue.pl \ + $(CPLINT_SRCDIR)/testlpadsld_gbfalse.pl \ + $(CPLINT_SRCDIR)/testlpad.pl \ + $(CPLINT_SRCDIR)/testcpl.pl \ + $(CPLINT_SRCDIR)/testsemlpadsld.pl \ + $(CPLINT_SRCDIR)/testsemlpad.pl \ + $(CPLINT_SRCDIR)/testsemcpl.pl + +CPLINT_EXAMPLES= \ + $(CPLINT_EXDIR)/dice.cpl \ + $(CPLINT_EXDIR)/dice.uni \ + $(CPLINT_EXDIR)/mendel.cpl \ + $(CPLINT_EXDIR)/mendels.cpl \ + $(CPLINT_EXDIR)/mendels.uni \ + $(CPLINT_EXDIR)/alarm.cpl \ + $(CPLINT_EXDIR)/coin.cpl \ + $(CPLINT_EXDIR)/coin.uni \ + $(CPLINT_EXDIR)/coin2.cpl \ + $(CPLINT_EXDIR)/coin2.uni \ + $(CPLINT_EXDIR)/student.cpl \ + $(CPLINT_EXDIR)/student.uni \ + $(CPLINT_EXDIR)/exapprox.cpl \ + $(CPLINT_EXDIR)/exapprox.uni \ + $(CPLINT_EXDIR)/exrange.cpl \ + $(CPLINT_EXDIR)/exrange.uni \ + $(CPLINT_EXDIR)/ex.cpl \ + $(CPLINT_EXDIR)/ex.uni \ + $(CPLINT_EXDIR)/school_simple.cpl \ + $(CPLINT_EXDIR)/school_simple.uni \ + $(CPLINT_EXDIR)/school.cpl \ + $(CPLINT_EXDIR)/paper_ref.cpl \ + $(CPLINT_EXDIR)/paper_ref_not.cpl \ + $(CPLINT_EXDIR)/paper_ref_simple.cpl \ + $(CPLINT_EXDIR)/threesideddice.cpl \ + $(CPLINT_EXDIR)/threesideddice.uni \ + $(CPLINT_EXDIR)/twosideddice.cpl \ + $(CPLINT_EXDIR)/female.cpl \ + $(CPLINT_EXDIR)/hiv.cpl \ + $(CPLINT_EXDIR)/hiv.uni \ + $(CPLINT_EXDIR)/invalid.cpl \ + $(CPLINT_EXDIR)/invalid.uni \ + $(CPLINT_EXDIR)/light.cpl \ + $(CPLINT_EXDIR)/light.uni \ + $(CPLINT_EXDIR)/throws.cpl \ + $(CPLINT_EXDIR)/throws.uni \ + $(CPLINT_EXDIR)/trigger.cpl \ + $(CPLINT_EXDIR)/trigger.uni \ + $(CPLINT_EXDIR)/win.cpl \ + $(CPLINT_EXDIR)/win.uni \ + $(CPLINT_EXDIR)/exist.cpl \ + $(CPLINT_EXDIR)/exist.uni \ + $(CPLINT_EXDIR)/exist1.cpl \ + $(CPLINT_EXDIR)/exist1.uni + +CPLINT_DOCS=\ + $(CPLINT_DOCDIR)/manual.bbl \ + $(CPLINT_DOCDIR)/manual.tex \ + $(CPLINT_DOCDIR)/manual.pdf \ + $(CPLINT_DOCDIR)/manual.html \ + $(CPLINT_DOCDIR)/manual.css \ + $(CPLINT_DOCDIR)/manual0x.png \ + $(CPLINT_DOCDIR)/Makefile + + +all: $(SOBJS) + +cplint_yap.o: $(srcdir)/cplint_yap.c $(srcdir)/cplint.h + $(CC) -c $(CFLAGS) $(SHLIB_CFLAGS) $(CPLINT_CFLAGS) $(srcdir)/cplint_yap.c -o cplint_yap.o + +cplint_Prob.o: $(srcdir)/cplint_Prob.c $(srcdir)/cplint.h + $(CC) -c $(CFLAGS) $(SHLIB_CFLAGS) $(CPLINT_CFLAGS) $(srcdir)/cplint_Prob.c -o cplint_Prob.o + + + +@DO_SECOND_LD@cplint@SHLIB_SUFFIX@: cplint_yap.o cplint_Prob.o +@DO_SECOND_LD@ @CPLINT_SHLIB_LD@ -o cplint@SHLIB_SUFFIX@ $(CPLINT_LDFLAGS) cplint_yap.o cplint_Prob.o $(CPLINT_LIBS) + +clean: + rm -f *.o *~ $(OBJS) $(SOBJS) *.BAK + +install: all + mkdir -p $(DESTDIR)$(SHAREDIR)/cplint + mkdir -p $(DESTDIR)$(SHAREDIR)/cplint/examples + mkdir -p $(DESTDIR)$(SHAREDIR)/cplint/doc + for h in $(CPLINT_PROGRAMS); do $(INSTALL_DATA) $$h $(DESTDIR)$(SHAREDIR); done + for h in $(CPLINT_EXAMPLES); do $(INSTALL_DATA) $$h $(DESTDIR)$(SHAREDIR)/cplint/examples; done + for h in $(CPLINT_DOCS); do $(INSTALL_DATA) $$h $(DESTDIR)$(SHAREDIR)/cplint/doc; done + for h in $(CPLINT_TEST_PROGRAMS); do $(INSTALL_DATA) $$h $(DESTDIR)$(SHAREDIR)/cplint; done + for h in $(CPLINT_SEMANTICS_PROGRAMS); do $(INSTALL_DATA) $$h $(DESTDIR)$(SHAREDIR); done + $(INSTALL_PROGRAM) $(SOBJS) $(DESTDIR)$(LIBDIR) + +installcheck: + for h in ${CPLINT_TEST_PROGRAMS}; do echo "t. halt." | yap -l $$h; done + +# use the following target to run individual tests, e.g. make testlpad +test%: + echo "t. halt." | yap -l $(CPLINT_SRCDIR)/$@.pl + diff --git a/packages/cplint/README b/packages/cplint/README new file mode 100644 index 000000000..e725d93aa --- /dev/null +++ b/packages/cplint/README @@ -0,0 +1,40 @@ +This directory contains the code of the LPAD anc CP-logic interpreter cplint + +COMPILATION: +This package requires GLU (a subpackage of VIS) and GLIB version 1.2. +You can download GLU from http://vlsi.colorado.edu/~vis/getting_VIS_2.1.html +You can download GLIB from http://www.gtk.org/. This is a standard Linux package +so it is easy to install using the package management software of your Linux +distribution + +INSTALLATION: +Install glu: + 1) downlad glu-2.1.tar.gz + 2) decompress it + 3) cd glu-2.1 + 3) mkdir arch + 4) cd arch + 5) ../configure + 6) make + 7) su + 8) make install +This will install glu into /usr/local, if you want to install to a different DIR +use ../configure --prefix DIR + +Installation of cplint: +When compiling Yap, use + configure --enable-cplint +Under Windows, you have to use cygwin (glu does not compile under MinGW), so + configure --enable-cplint --enable-cygwin +If you installed glu in DIR, use --enable-cplint=DIR + + +FEEDBACK: + +Send feedback to: + +Fabrizio Riguzzi +University of Ferrara +Dept. of Engineering +fabrizio.riguzzi@unife.it +http://www.ing.unife.it/Docenti/FabrizioRiguzzi/ diff --git a/packages/cplint/cpl.pl b/packages/cplint/cpl.pl new file mode 100644 index 000000000..ee82d4d51 --- /dev/null +++ b/packages/cplint/cpl.pl @@ -0,0 +1,157 @@ +/* + LPAD and CP-Logic reasoning suite + File cpl.pl + Computes the semantics of CP-logic programs + Copyright (c) 2007, Fabrizio Riguzzi +*/ + +:-use_module(lpad,[slg/3,setting/2,set/2]). + +:-use_module(semcpl,[build/0,print/0]). + +:-use_module(library(lists)). + +p(File):- + lpad:p(File). + +sc(Goals,Evidences,Prob,CPUTime1,0.0,WallTime1,0.0):- + statistics(cputime,[_,_]), + statistics(walltime,[_,_]), + lpad:convert_to_goal(Goals,Goal), + lpad:convert_to_goal(Evidences,Evidence), + solve_cond(Goal,Evidence,Prob), + statistics(cputime,[_,CT1]), + CPUTime1 is CT1/1000, + statistics(walltime,[_,WT1]), + WallTime1 is WT1/1000. + +sc(Goals,Evidences,Prob):- + lpad:convert_to_goal(Goals,Goal), + lpad:convert_to_goal(Evidences,Evidence), + solve_cond(Goal,Evidence,Prob). + + +solve_cond(Goal,Evidence,Prob):- + (setof((DerivE,D),slg(Evidence,DerivE,D),LCouplesE)-> + separate(LCouplesE,LCDupE,LDefClE), + lpad:rem_dup_lists(LCDupE,[],LCE), + lpad:build_formula(LCE,FormulaE,[],VarE), + lpad:var2numbers(VarE,0,NewVarE), + lpad:compute_prob(NewVarE,FormulaE,ProbE,0), + solve_cond_goals(Goal,LCE,ProbGE,LGE,LDefClGE), + (setof((R,S),N^(member(C,LGE),member((N,R,S),C)),LDisClGE)-> + true + ; + LDisClGE=[] + ), + append(LDefClGE,LDefClE,LDefDup), + remove_duplicates(LDefDup,LDef), + append(LDisClGE,LDef,LCl), + test_validity(LCl), + Prob is ProbGE/ProbE + ; + format("P(Evidence)=0~n",[]), + Prob=undefined + ). + +solve_cond_goals(Goals,LE,ProbGE,LGE,LDefClGE):- + (setof((DerivGE,D),find_deriv_GE(LE,Goals,DerivGE,D),LCouplesGE)-> + separate(LCouplesGE,LCDupGE,LDefClGE), + lpad:rem_dup_lists(LCDupGE,[],LGE), + lpad:build_formula(LGE,FormulaGE,[],VarGE), + lpad:var2numbers(VarGE,0,NewVarGE), + lpad:call_compute_prob(NewVarGE,FormulaGE,ProbGE) + ; + ProbGE=0 + ). + +find_deriv_GE(LD,GoalsList,Deriv,Def):- + member(D,LD), + lpad:slg(GoalsList,D,DerivDup,[],Def), + remove_duplicates(DerivDup,Deriv). + +s(GoalsList,Prob):- + lpad:convert_to_goal(GoalsList,Goal), + solve(Goal,Prob). + +s(GoalsList,Prob,CPUTime1,0.0,WallTime1,0.0):- + statistics(cputime,[_,_]), + statistics(walltime,[_,_]), + lpad:convert_to_goal(GoalsList,Goal), + solve(Goal,Prob), + statistics(cputime,[_,CT1]), + CPUTime1 is CT1/1000, + statistics(walltime,[_,WT1]), + WallTime1 is WT1/1000. + +solve(Goal,Prob):- + (setof((C,D),slg(Goal,C,D),LCouples)-> + separate(LCouples,LCDup,LDefCl), + (member(unsound,LCDup)-> + format("Unsound program ~n",[]), + Prob=unsound + ; + lpad:rem_dup_lists(LCDup,[],L), + (ground(L)-> + lpad:build_formula(L,Formula,[],Var), + lpad:var2numbers(Var,0,NewVar), + (setting(savedot,true)-> + format("Variables: ~p~n",[Var]), + lpad:compute_prob(NewVar,Formula,_Prob,1) + ; + lpad:compute_prob(NewVar,Formula,Prob,0) + ), + (setof((R,S),N^(member(C,LCDup),member((N,R,S),C)),LDisCl)-> + true + ; + LDisCl=[] + ), + append(LDisCl,LDefCl,LCl), + test_validity(LCl) + ; + format("It requires the choice of a head atom from a non ground head~n~p~n",[L]), + Prob=non_ground + ) + ) + ; + Prob=0 + ). + +test_validity(L):- + retractall(semcpl:root(_)), + retractall(semcpl:clauses(_)), + retractall(semcpl:herbrand_base(_)), + retractall(semcpl:node(_,_,_,_,_)), + retractall(semcpl:new_number(_)), + assert(semcpl:new_number(0)), + get_clauses_hb(L,LC,HBDup), + remove_duplicates(HBDup,HB0), + delete(HB0, '' ,HB), + assert(semcpl:herbrand_base(HB)), + assert(semcpl:clauses(LC)), + build. + +get_clauses_hb([],[],[]):-!. + +get_clauses_hb([(R,S)|T],[r(Head,Body)|TR],HB):- + lpad:rule(R,S,_,Head,Body),!, + get_atoms(Head,Atoms), + append(Atoms,HB0,HB), + get_clauses_hb(T,TR,HB0). + +get_clauses_hb([(R,S)|T],[r([Head:1],Body)|TR],HB):- + lpad:def_rule(R,S,Head,Body), + append([Head],HB0,HB), + get_clauses_hb(T,TR,HB0). + +get_atoms([],[]):-!. + +get_atoms([H:_P|T],[H|TA]):- + get_atoms(T,TA). + +separate([],[],[]):-!. + +separate([(C,D)|T],[C|TC],Cl):- + append(D,Cl0,Cl), + separate(T,TC,Cl0). + diff --git a/packages/cplint/cplint.h b/packages/cplint/cplint.h new file mode 100644 index 000000000..56e5491e8 --- /dev/null +++ b/packages/cplint/cplint.h @@ -0,0 +1,49 @@ +/* + LPAD and CP-Logic interpreter + +Copyright (c) 2007, Fabrizio Riguzzi + +This package uses the library cudd, see http://vlsi.colorado.edu/~fabio/CUDD/ +for the relative license. + +*/ + +#include "util.h" +#include "cuddInt.h" +#include "array.h" +#include "mtr.h" +#include "avl.h" +#include "YapInterface.h" +#include + +typedef struct + { + int var,value; + } factor; + +typedef struct + { + int nVal,nBit; + array_t * probabilities; + array_t * booleanVars; + } variable; + + +void createVars(array_t * vars, YAP_Term t,DdManager * mgr, array_t * bVar2mVar,int create_dot, char inames[1000][20]); +void createExpression(array_t * expression, YAP_Term t); +void init_my_predicates(void); +int compare(char *a, char *b); +gint my_equal(gconstpointer v,gconstpointer v2); +guint my_hash(gconstpointer key); +void dealloc(gpointer key,gpointer value,gpointer user_data); + + + +DdNode * retFunction(DdManager * mgr, array_t * expression,array_t * v); +DdNode * retTerm(DdManager * mgr,array_t *factors,array_t * v); +DdNode * retFactor(DdManager * mgr, factor f, array_t * v); + +double Prob(DdNode *node, array_t * vars,array_t * bVar2mVar, GHashTable * nodes); + +double ProbBool(DdNode *node, int bits, int nBit,int posBVar,variable v, +array_t * vars,array_t * bVar2mVar, GHashTable * nodes); diff --git a/packages/cplint/cplint_Prob.c b/packages/cplint/cplint_Prob.c new file mode 100644 index 000000000..9af2d2f32 --- /dev/null +++ b/packages/cplint/cplint_Prob.c @@ -0,0 +1,209 @@ +/* + LPAD and CP-Logic interpreter + +Copyright (c) 2007, Fabrizio Riguzzi + +This package uses the library cudd, see http://vlsi.colorado.edu/~fabio/CUDD/ +for the relative license. + + + This file contains the definition of Prob and ProbBool plus the functions + for building the BDD +*/ + + +#include "cplint.h" +#include + +int correctPosition(int index,variable v, DdNode * node,int posBVar); + + + +DdNode * retFunction(DdManager * mgr,array_t *expression, array_t *v) +/* given an expression term1+term2+...+termn, returns the BDD that implements that function */ +{ + array_t * term; + DdNode * tNode, * tmp, *tmp1; + int i; + + i=0; + tNode=Cudd_ReadLogicZero(mgr); + Cudd_Ref(tNode); + while(i>1; + i--; + Cudd_RecursiveDeref(mgr,node); + node=tmp; + } while (i>=0); + return node; + +} + + + +double Prob(DdNode *node, array_t * vars,array_t * bVar2mVar, GHashTable * nodes) +/* compute the probability of the expression rooted at node +nodes is used to store nodes for which the probability has alread been computed +so that it is not recomputed + */ +{ + int index,mVarIndex,nBit; + variable v; + double res; + double value; + double * value_p; + DdNode **key; + double *rp; + + index=node->index; + if (Cudd_IsConstant(node)) + { + value=node->type.value; + return value; + } + else +{ + + value_p=g_hash_table_lookup(nodes,&node); + if (value_p!=NULL) + { + return *value_p; + } + else + { + mVarIndex=array_fetch(int,bVar2mVar,index); + v=array_fetch(variable,vars,mVarIndex); + nBit=v.nBit; + res=ProbBool(node,0,nBit,0,v,vars,bVar2mVar,nodes); + key=(DdNode **)malloc(sizeof(DdNode *)); + *key=node; + rp=(double *)malloc(sizeof(double)); + *rp=res; + g_hash_table_insert(nodes, key, rp); + return res; + } +} +} + +double ProbBool(DdNode *node, int bits, int nBit,int posBVar,variable v, +array_t * vars,array_t * bVar2mVar, GHashTable * nodes) +/* explores a group of binary variables making up the multivalued variable v */ +{ + DdNode *T,*F; + double p,res; + array_t * probs; + + probs=v.probabilities; + if (nBit==0) + { + if (bits>=array_n(probs)) + return 0; + else + { + p=array_fetch(double,probs,bits); + res=p*Prob(node,vars,bVar2mVar,nodes); + return res; + } + } + else + { + if (correctPosition(node->index,v,node,posBVar)) + { + T = node->type.kids.T; + F = node->type.kids.E; + bits=bits<<1; + + res=ProbBool(T,bits+1,nBit-1,posBVar+1,v,vars,bVar2mVar,nodes)+ + ProbBool(F,bits,nBit-1,posBVar+1,v,vars,bVar2mVar,nodes); + return res; + } + else + { + + bits=bits<<1; + res=ProbBool(node,bits+1,nBit-1,posBVar+1,v,vars,bVar2mVar,nodes)+ + ProbBool(node,bits,nBit-1,posBVar+1,v,vars,bVar2mVar,nodes); + return res; + } + } +} + +int correctPosition(int index,variable v, DdNode * node,int posBVar) +/* returns 1 is the boolean variable with index posBVar is in the correct position +currently explored by ProbBool */ +{ + DdNode * bvar; + + bvar=array_fetch(DdNode *,v.booleanVars,posBVar); + return bvar->index==index; +} diff --git a/packages/cplint/cplint_yap.c b/packages/cplint/cplint_yap.c new file mode 100644 index 000000000..51ea7511d --- /dev/null +++ b/packages/cplint/cplint_yap.c @@ -0,0 +1,256 @@ +/* + LPAD and CP-Logic interpreter + +Copyright (c) 2007, Fabrizio Riguzzi + +This package uses the library cudd, see http://vlsi.colorado.edu/~fabio/CUDD/ +for the relative license. + + + This file contains the functions for interfacing Yap and C + The arguments of the predicate compute_prob are parsed and translated into C data + structures +*/ + +#include "cplint.h" +#include +#include +#include + + +unsigned long dividend; + +FILE *open_file (char *filename, const char *mode); +void reverse(char s[]); +static int compute_prob(void); + +void createVars(array_t * vars, YAP_Term t,DdManager * mgr, array_t * bVar2mVar,int create_dot, char inames[1000][20]) +/* adds the boolean variables to the BDD and returns +an array_t containing them (array_t is defined in the util library of glu) +returns also the names of the variables to be used to save the ADD in dot format + */ +{ + YAP_Term varTerm,probTerm; + int varIndex,nVal,i,b; + variable v; + char numberVar[10],numberBit[10]; + double p; + b=0; + + while(YAP_IsPairTerm(t)) + { + varTerm=YAP_HeadOfTerm(t); + varIndex=YAP_IntOfTerm(YAP_HeadOfTerm(varTerm)); + + varTerm=YAP_TailOfTerm(varTerm); + nVal=YAP_IntOfTerm(YAP_HeadOfTerm(varTerm)); + varTerm=YAP_TailOfTerm(varTerm); + probTerm=YAP_HeadOfTerm(varTerm); + v.nVal=nVal; + v.nBit=(int)ceil(log(nVal)/log(2)); + v.probabilities=array_alloc(double,0); + v.booleanVars=array_alloc(DdNode *,0); + for (i=0;ibval) + return 1; + else + return 0; +} +*/ +void init_my_predicates() +/* function required by YAP for intitializing the predicates defined by a C function*/ +{ + YAP_UserCPredicate("compute_prob",compute_prob,4); +} + FILE * +open_file(char *filename, const char *mode) +/* opens a file */ +{ + FILE *fp; + + if ((fp = fopen(filename, mode)) == NULL) { + perror(filename); + exit(1); + } + return fp; + +} +void reverse(char s[]) +/* reverses a string */ +{ + int i,c,j; + for (i=0,j=strlen(s)-1;i + +cplint Version beta2.0 Manual + + + + + + + + +
+ + + +

cplint Version beta2.0 Manual

+
Fabrizio Riguzzi +
fabrizio.riguzzi@unife.it
+
+
June 19, 2008
+
+

1 Introduction

+

cplint is a suite of programs for reasoning with LPADs [1112] and CP-logic +programs [1013]. +

It consists of three Prolog modules for answering queries using goal-oriented +procedures plus three Prolog modules for answering queries using the definition of the +semantics of LPADs and CP-logic. +

The modules for answering queries using using goal-oriented procedures are +lpadsld.pl, lpad.pl and cpl.pl: +

    +
  • lpadsld.pl: computes the probability of a query using the top-down + procedure described in in [7] and [8]. It is based on SLDNF resolution and + is an adaptation of the interpreter for ProbLog [4]. +

    It was proved correct [8] with respect to the semantics of LPADs for range + restricted acyclic programs [1] without function symbols. +

    It is also able to deal with extensions of LPADs and CP-logic: the clause + bodies can contain setof and bagof, the probabilities in the head may + be depend on variables in the body and it is possible to specify a uniform + distribution in the head with reference to a setof or bagof operator. + These extended features have been introduced in order to represent + CLP(BN) [9] programs and PRM models [6]: setof and bagof allow to + express dependency of an attribute from an aggregate function of another + attribute, as in CLP(BN) and PRM, while the possibility of specifying a + uniform distribution allows the use of the reference uncertainty feature of + PRM. + +

  • +
  • lpad.pl: computes the probability of a query using a top-down procedure + based on SLG resolution [3]. As a consequence, it works for any sound + LPADs, i.e., any LPAD such that each of its instances has a two valued + well founded model. +
  • +
  • cpl.pl: computes the probability of a query using a top-down procedure + based on SLG resolution and moreover checks that the CP-logic program + is valid, i.e., that it has at least an execution model.
+

The modules for answering queries using the definition of the semantics of LPADs +and CP-logic are semlpadsld.pl, semlpad.pl and semcpl.pl: +

    +
  • semlpadsld.pl: given an LPAD P, it generates all the instances of P. + The probability of a query Q is computed by identifying all the instances + where Q is derivable by SLDNF resolution. +
  • +
  • semlpad.pl: given an LPAD P, it generates all the instances of P. The + probability of a query Q is computed by identifying all the instances where + Q is derivable by SLG resolution. +
  • +
  • semlcpl.pl: given an LPAD P, it builds an execution model of P, i.e., + a probabilistic process that satisfy the principles of universal causation, + sufficient causation, independent causation, no deus ex machina events + and temporal precedence. It uses the definition of the semantics given in + [13].
+

+

2 Installation

+

cplint is distributed in source code in the CVS version of Yap. It +includes Prolog and C files. Download it by following the instruction in +http://www.ncc.up.pt/~vsc/Yap/downloads.html . +

cplint requires glu (a subpackage of vis) and glib-2.0. You can download glu +from http://vlsi.colorado.edu/~vis/getting_VIS_2.1.html You can download +glib-2.0 (version 2.0) from http://www.gtk.org/ . This is a standard GNU package +so it is easy to install it using the package management software of your Linux or +Cygwin distribution. +

Install glu: +

    +
  1. downlad glu-2.1.tar.gz + +
  2. +
  3. decompress it +
  4. +
  5. cd glu-2.1 +
  6. +
  7. mkdir arch +
  8. +
  9. cd arch +
  10. +
  11. ../configure +
  12. +
  13. make +
  14. +
  15. su +
  16. +
  17. make install
+

This will install glu into /usr/local, if you want to install to a different DIR use +../configure --prefix DIR +

Install Yap together with cplint: when compiling Yap following the instuction of +the INSTALL file in the root of the Yap folder, use + +
+configure --enable-cplint +
+
+

Under Windows, you have to use Cygwin (glu does not compile under MinGW), +so +
+ +
+configure --enable-cplint --enable-cygwin +
+
+

If you installed glu in DIR, use --enable-cplint=DIR +

After having performed make install you can do make installcheck that will +execute a suite of tests of the various programs. If no error is reported you have a +working installation of cplint. +

+

3 Syntax

+

Disjunction in the head is represented with a semicolon and atoms in the head are +separated from probabilities by a colon. For the rest, the usual syntax of Prolog is +used. For example, the CP-logic clause +

+h1 : p1 ∨...∨ hn : pn ← b1,...,bm,¬c1,...,¬cl
is +represented by + +
+h1:p1 ; ... ; hn:pn :- b1,...,bm,\+ c1,....,\+ cl +
+
+

No parentheses are necessary. The pi are numeric expressions. It is up to the user to +ensure that the numeric expressions are legal, i.e. that they sum up to less than +one. +

If the clause has an empty body, it can be represented like this + +
+h1:p1 ; ... ;hn:pn. +
+
+

If the clause has a single head with probability 1, the annotation can be omitted and +the clause takes the form of a normal prolog clause, i.e. + +
+h1:- b1,...,bm,\+ c1,...,\+ cl. +
+
+

stands for + +
+h1:1 :- b1,...,bm,\+ c1,...,\+ cl. +
+
+

+

The coin example of [12] is represented as (see file coin.cpl) + +
+heads(Coin):1/2 ; tails(Coin):1/2:- + 
     toss(Coin),\+biased(Coin). + 

heads(Coin):0.6 ; tails(Coin):0.4:- + 
     toss(Coin),biased(Coin). + 

fair(Coin):0.9 ; biased(Coin):0.1. + 

toss(coin). +
+
+

The first clause states that if we toss a coin that is not biased it has equal +probability of landing heads and tails. The second states that if the coin is biased it +has a slightly higher probability of landing heads. The third states that the coin is +fair with probability 0.9 and biased with probability 0.1 and the last clause states +that we toss a coin with certainty. +

+

4 Commands

+

All six modules accept the same commands for reading in files and answering queries. +The LPAD or CP-logic program must be stored in a text file with extension .cpl. +Suppose you have stored the example above in file coin.cpl. In order to answer +queries from this program, you have to run Yap, load one of the modules (such as for +example lpad.pl) by issuing the command + +
+use_module(library(lpad)). +
+
+

at the command prompt. Then you must parse the source file coin.cpl with the +command + +
+p(coin). +
+
+

if coin.cpl is in the current directory, or + +
+p(’path_to_coin/coin’). +
+
+

if coin.cpl is in a different directory. At this point you can pose query to the +program by using the predicate s/2 (for solve) that takes as its first argument a +conjunction of goals in the form of a list and returns the computed probability +as its second argument. For example, the probability of the conjunction +head(coin),biased(coin) can be asked with the query + +
+s([head(coin),biased(coin)],P). +
+
+

For computing the probability of a conjunction given another conjunction you can +use the predicate sc/3 (for solve conditional) that take takes as input the query +conjunction as its first argument, the evidence conjunction as its second argument +and returns the probability in its third argument. For example, the probability of the +query heads(coin) given the evidence biased(coin) can be asked with the +query + +
+sc([heads(coin)],[biased(coin)],P). +
+
+

After having parsed a program, in order to read in a new program you must restart +Yap when using semlpadsld.pl and semlpad.pl. With the other modules, you can +directly parse a new program. +

When using lpad.pl, the system can print the message “Uunsound program” in +the case in which an instance with a three valued well founded model is found. +Moreover, it can print the message “It requires the choice of a head atom from a non +ground head”: in this case, in order to answer the query, all the groundings of the +culprit clause must be generated, which may be impossible for programs with +function symbols. +

When using semcpl.pl, you can print the execution process by using the +command print. after p(file). Moreover, you can build an execution +process given a context by issuing the command parse(file). and then +build(context). where context is a list of atoms that are true in the context. +semcpl.pl can print “Invalid program” in the case in which no execution process +exists. +

When using cpl.pl you can print a partial execution model including all the +clauses involved in the query issued with print. cpl.pl can print the messages +“Uunsound program”, “It requires the choice of a head atom from a non ground +head” and “Invalid program”. +

The modules make use of a number of parameters in order to control their +behavior. They that can be set with the command + +
+set(parameter,value). +
+
+

from the Yap prompt after having loaded the module. The current value can be read +with + +
+setting(parameter,Value). +
+
+

from the Yap prompt. The available parameters are: +

    +
  • epsilon_parsing (valid for all six modules): if (1 - the sum of the + probabilities of all the head atoms) is smaller than epsilon_parsing then + cplint adds the null events to the head. Default value 0.00001 +
  • +
  • save_dot (valid for all goal-oriented modules): if true a graph representing the + BDD is saved in the file cpl.dot in the current directory in dot format. The + variables names are of the form Xn_m where n is the number of the multivalued + variable and m is the number of the binary variable. The correspondence + between variables and clauses can be evinced from the message printed on the + screen, such as + +
    + Variables: [(2,[X=2,X1=1]),(2,[X=1,X1=0]),(1,[])] +
    +
    +

    where the first element of each couple is the clause number of the input file + (starting from 1). In the example above variable X0 corresponds to clause 2 + with the substitutions X=2,X1=1, variable X1 corresponds to clause 2 with the + substitutions X=1,X1=0 and variable X2 corresponds to clause 1 with the empty + substitution. You can view the graph with graphviz ( www.graphviz.org ) + using the command + +
    + dotty cpl.dot & +
    +
    +

    +

  • +
  • ground_body (valid for lpadsld.pl and all semantic modules): determines how + non ground clauses are treated: if true, ground clauses are obtained from a non + ground clause by replacing each variable with a constant, if false, ground + clauses are obtained by replacing only variables in the head with a + constant. In the case where the body contains variables not in the + head, setting it to false means that the body represents an existential + event.
+

+

5 Semantic Modules

+

The three semantic modules need to produce a grounding of the program in order to +compute the semantics. They require an extra file with extension .uni (for universe) +in the same directory where the .cpl file is. +

There are two ways to specify how to ground a program. The first consists in +providing the list of constants to which each variable can be instantiated. For +example, in our case the current directory will contain a file coin.uni that is a +Prolog file containing facts of the form + +
+universe(var_list,const_list). +
+
+

where var_list is a list of variables names (each must be included in single quotes) +and const_list is a list of constants. The semantic modules generate the grounding +by instantiating in all possible ways the variables of var_list with the constants of +const_list. Note that the variables are identified by name, so a variable with +the same name in two different clauses will be instantiated with the same +constants. +

The other way to specify how to ground a program consists in using mode and +type information. For each predicate, the file .uni must contain a fact of the +form + +
+mode(predicate(t1,...,tn)). +
+
+

that specifies the number and types of each argument of the predicate. Then, the list +of constants that are in the domain of each type ti must be specified with a fact of +the form + +
+type(ti,list_of_constants). +
+
+

The file .uni can contain both universe and mode declaration, the ones to be used +depend on the value of the parameter grounding: with value variables, the +universe declarations are used, with value modes the mode declarations are +used. +

With semcpl.pl only mode declarations can be used. +

+

6 Extensions

+

In this section we will present the extensions to the syntax of LPADs and CP-logic +programs that cplint can handle. +

The first is the use of some standard Prolog predicates. The bodies can contain +the built-in predicates: + +
+is/2 + 
>/2 + 
</2 + 
>=/2 + 
=</2 + 
=:=/2 + 
=\=/2 + 
true/0 + 
false/0 + 
=/2 + 
==/2 + 
\=/2 + 
\==/2 + 
length/2 +
+
+

The bodies can also contain the following library predicates: + +
+member/2 + 
max_list/2 + 
min_list/2 + 
nth0/3 + 
nth/3 +
+
+

plus the predicate + +
+average/2 +
+
+

that, given a list of numbers, computes its arithmetic mean. +

When using lpadsld.pl, the bodies can contain the predicates setof/3 and +bagof/3 with the same meaning as in Prolog. Existential quantifiers are allowed in +both, so for example the query + +
+setof(Z, (term(X,Y))^foo(X,Y,Z), L). +
+
+

returns all the instantiations of Z such that there exists an instantiation of X and Y +for which foo(X,Y,Z) is true. +

An example of the use of setof and bagof is in the file female.cpl: + +
+male(C):M/P ; female(C):F/P:- + 
    person(C), + 
    setof(Male,known_male(Male),LM), + 
    length(LM,M), + 
    setof(Female,known_female(Female),LF), + 
    length(LF,F), + 
    P is F+M. + 

person(f). + 

known_female(a). + 

known_female(b). + 

known_female(c). + 

known_male(d). + 

known_male(e). +
+
+

The disjunctive rule expresses the probability of a person of unknown sex of being +male or female depending on the number of males and females that are known. This +is an example of the use of expressions in the probabilities in the head that depend +on variables in the body. The probabilities are well defined because they always sum +to 1 (unless P is 0). +

Another use of setof and bagof is to have an attribute depend on an +aggregate function of another attribute, similarly to what is done in PRM and +CLP(BN). +

So, in the classical school example (available in student.cpl) you can find the +following clauses: + +
+student_rank(S,h):0.6 ; student_rank(S,l):0.4:- + 
    bagof(G,R^(registr_stu(R,S),registr_gr(R,G)),L), + 
    average(L,Av),Av>1.5. + 

student_rank(S,h):0.4 ; student_rank(S,l):0.6:- + 
    bagof(G,R^(registr_stu(R,S),registr_gr(R,G)),L), + 
    average(L,Av),Av =< 1.5. +
+
+

where registr_stu(R,S) expresses that registration R refers to student S and +registr_gr(R,G) expresses that registration R reports grade G which is a natural +number. The two clauses express a dependency of the rank of the student from the +average of her grades. +

Another extension can be used with lpadsld.pl in order to be able to represent +reference uncertainty of PRMs. Reference uncertainty means that the link structure +of a relational model is not fixed but is uncertain: this is represented by having the +instance referenced in a relationship be chosen uniformly from a set. For example, +consider a domain modeling scientific papers: you have a single entity, paper, and a +relationship, cites, between paper and itself that connects the citing paper to the +cited paper. To represent the fact that the cited paper and the citing paper are +selected uniformly from certain sets, the following clauses can be used (see file +paper_ref_simple.cpl): + +
+uniform(cites_cited(C,P),P,L):- + 
    bagof(Pap,paper_topic(Pap,theory),L). + 

uniform(cites_citing(C,P),P,L):- + 
    bagof(Pap,paper_topic(Pap,ai),L). +
+
+

The first clauses states that the paper P cited in a citation C is selected +uniformly from the set of all papers with topic theory. The second clauses +expresses that the citing paper is selected uniformly from the papers with topic +ai. +

These clauses make use of the predicate + +
+uniform(Atom,Variable,List) +
+
+

in the head, where Atom must contain Variable. The meaning is the following: +the set of all the atoms obtained by instantiating Variable of Atom with a +term taken from List is generated and the head is obtained by having a +disjunct for each instantiation with probability 1∕N where N is the length of +List. +

A more elaborate example is present in file paper_ref.cpl: + +
+uniform(cites_citing(C,P),P,L):- + 
    setof(Pap,paper(Pap),L). + 

cites_cited_group(C,theory):0.9 ; cites_cited_group(C,ai):0.1:- + 
    cites_citing(C,P),paper_topic(P,theory). + 

cites_cited_group(C,theory):0.01;cites_cited_group(C,ai):0.99:- + 
    cites_citing(C,P),paper_topic(P,ai). + 

uniform(cites_cited(C,P),P,L):- + 
    cites_cited_group(C,T),bagof(Pap,paper_topic(Pap,T),L). +
+
+

where the cited paper depends on the topic of the citing paper. In particular, if the +topic is theory, the cited paper is selected uniformly from the papers about theory +with probability 0.9 and from the papers about ai with probability 0.1. if +the topic is ai, the cited paper is selected uniformly from the papers about +theory with probability 0.01 and from the papers about ai with probability +0.99. +

PRMs take into account as well existence uncertainty, where the existence of +instances is also probabilistic. For example, in the paper domain, the total number of +citations may be unknown and a citation between any two paper may have a +probability of existing. For example, a citation between two paper may be more +probable if they are about the same topic: + +
+cites(X,Y):0.005 :- + 
    paper_topic(X,theory),paper_topic(Y,theory). + 

cites(X,Y):0.001 :- + 
    paper_topic(X,theory),paper_topic(Y,ai). + 

cites(X,Y):0.003 :- + 
    paper_topic(X,ai),paper_topic(Y,theory). + 

cites(X,Y):0.008 :- + 
    paper_topic(X,ai),paper_topic(Y,ai). +
+
+

This is an example where the probabilities in the head do not sum up to one so the +null event is automatically added to the head. The first clause states that, if the topic +of a paper X is theory and of paper Y is theory, there is a probability of 0.005 that +there is a citation from X to Y. The other clauses consider the remaining cases for the +topics. +

+

7 Additional Files

+

In the directory where Yap keeps the library files (usually /usr/local/share/ Yap) +you can find the directory cplint that contains the files: +

    +
  • testlpadsld_gbtrue.pl, testlpadsld_gbfalse.pl, testlpad.pl, + testcpl.pl, testsemlpadsld.pl, testsemlpad.pl testsemcpl.pl: + Prolog programs for testing the modules. They are executed when issuing + the command make installcheck during the installation. To execute + them afterwords, load the file and issue the command t. +
  • +
  • Subdirectory examples: +
      +
    • alarm.cpl: representation of the Bayesian network in Figure 2 of + [12]. +
    • +
    • coin.cpl: coin example from [12]. +
    • +
    • coin2.cpl: coin example with two coins. + +
    • +
    • dice.cpl: dice example from [12]. +
    • +
    • twosideddice.cpl, threesideddice.cpl game with idealized dice + with two or three sides. Used in the experiments in [8]. +
    • +
    • ex.cpl: first example in [8]. +
    • +
    • exapprox.cpl: example showing the problems of approximate + inference (see [8]). +
    • +
    • exrange.cpl: example showing the problems with non range + restricted programs (see [8]). +
    • +
    • female.cpl: example showing the dependence of probabilities in the + head from variables in the body (from [12]). +
    • +
    • mendel.cpl, mendels.cpl: programs describing the Mendelian + rules of inheritance, taken from [2]. +
    • +
    • paper_ref.cpl, paper_ref_simple.cpl: paper citations examples, + showing reference uncertainty, inspired by [6]. +
    • +
    • paper_ref_not.cpl: paper citations example showing that negation + can be used also for predicates defined by clauses with uniform in + the head. +
    • +
    • school.cpl: example inspired by the example school_32.yap from + the source distribution of Yap in the CLPBN directory. +
    • +
    • school_simple.cpl: simplified version of school.cpl. +
    • +
    • student.cpl: student example from Figure 1.3 of [5]. +
    • +
    • win.cpl, light.cpl, trigger.cpl, throws.cpl, hiv.cpl, +
      invalid.cpl: programs taken from [13]. invalid.cpl is an example + of a program that is invalid but sound.
    +

    The files *.uni that are present for some of the examples are used by the + semantical modules. Some of the example files contain in an initial comment + some queries together with their result. +

  • +
  • Subdirectory doc: contains this manual in latex, html and pdf.
+ +

+

8 License

+

cplint, as Yap, follows the Artistic License 2.0 that you can find in Yap CVS root +dir. The copyright is by Fabrizio Riguzzi. +

The program uses the library CUDD for manipulating BDDs that is included in +glu. For the use of CUDD, the following license must be accepted: +

Copyright (c) 1995-2004, Regents of the University of Colorado +

All rights reserved. +

Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: +

    +
  • Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. +
  • +
  • Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. +
  • +
  • Neither the name of the University of Colorado nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission.
+

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS +
AND CONTRIBUTORS ”AS IS” AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE +GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAU-SED +
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +

lpad.pl, semlpad.pl and cpl.pl are based on the SLG system by Weidong +Chen and David Scott Warren , Copyright (C) 1993 Southern Methodist University, +1993 SUNY at Stony Brook, see the file COYPRIGHT_SLG for detailed information +on this copyright. + +

+

References

+

+

+

+ [1]   K. R. Apt and M. Bezem. Acyclic programs. New Generation + Comput., 9(3/4):335–364, 1991. +

+

+ [2]   H. Blockeel. Probabilistic logical models for mendel’s experiments: An + exercise. In Inductive Logic Programming (ILP 2004), Work in Progress + Track, 2004. +

+

+ [3]   Weidong Chen and David Scott Warren. Tabled evaluation with + delaying for general logic programs. J. ACM, 43(1):20–74, 1996. +

+

+ [4]   L. De Raedt, A. Kimmig, and H. Toivonen. Problog: A probabilistic + prolog and its application in link discovery. In Proceedings of the 20th + International Joint Conference on Artificial Intelligence, pages 2462–2467, + 2007. +

+

+ [5]   L. Getoor, N. Friedman, D. Koller, and A. Pfeffer. Learning + probabilistic relational models. In Saso Dzeroski and Nada Lavrac, editors, + Relational Data Mining. Springer-Verlag, Berlin, 2001. +

+

+ [6]   L. Getoor, N. Friedman, D. Koller, and B. Taskar. Learning + probabilistic models of relational structure. Journal of Machine Learning + Research, 3:679–707, December 2002. +

+

+ [7]   Fabrizio Riguzzi. A top down interpreter for lpad and cp-logic. In + 10th Congress of the Italian Association for Artificial Intelligence. Springer, + 2007. + http://www.ing.unife.it/docenti/FabrizioRiguzzi/Papers/Rig-AIIA07.pdf + . + +

+

+ [8]   Fabrizio Riguzzi. A top down interpreter for lpad and + cp-logic. In The 14th RCRA workshop Experimental Evaluation of + Algorithms for Solving Problems with Combinatorial Explosion, 2007. + http://pst.istc.cnr.it/RCRA07/articoli/P19-riguzzi-RCRA07.pdf . +

+

+ [9]   V. Santos Costa, D. Page, M. Qazi, and J. Cussens. CLP(BN): + Constraint logic programming for probabilistic knowledge. In Uncertainty + in Artificial Intelligence (UAI 2003), 2003. +

+

+ [10]   J. Vennekens, M. Denecker, and M. Bruynooghe. Representing causal + information about a probabilistic process. In 10th European Conference on + Logics in Artificial Intelligence, JELIA 2006, LNAI. Springer, September + 2006. +

+

+ [11]   J. Vennekens and S. Verbaeten. Logic programs with annotated + disjunctions. Technical Report CW386, K. U. Leuven, 2003. + http://www.cs.kuleuven.ac.be/~joost/techrep.ps . +

+

+ [12]   J. Vennekens, S. Verbaeten, and M. Bruynooghe. Logic programs with + annotated disjunctions. In The 20th International Conference on Logic + Programming (ICLP 2004), 2004. http://www.cs.kuleuven.ac.be/~joost/ + . +

+

+ [13]   Joost Vennekens, Marc Denecker, and Maurice Bruynooge. Extending + the role of causality in + probabilistic modeling. http://www.cs.kuleuven.ac.be/~joost/cplogic.pdf + , 2006. +

+
+ + + + + diff --git a/packages/cplint/doc/manual.pdf b/packages/cplint/doc/manual.pdf new file mode 100644 index 0000000000000000000000000000000000000000..87856811454c052e9c62eeb2121816703e536ae7 GIT binary patch literal 118367 zcmbqb1z1$u+6EEnM!Gu(W(J0#rMp|YySqiYI~9;dQa}Z15Rh&ZknR>~B>YFuIrn(t z{>OW-&*L-0p1r>Pt#8%)zU$kIURhj{9SGn;<)-4Kax}3)6%e4}P^03Ia#VMu;t;1| zay2(~vvza<0GX+Tgiy^L%)Z?O{q<%h83#8PM>F^Dw=nRWYtDCW% zo$Ne$bN!bg5bz%i zasR;(*KdZ@%wcxitWBvDVBxYe|H0rt1s?JTga3-WgqNGSgDWglKbZQb!1MfQ3jD9Y ziUk>ZnptaY$ObQR)BC z!MJ{H0V)9jR1SG_2TM0ADj+YEo9g>NRM`D?ZssnqaXl9NI>z=M|F6PGe zs9v+#+H$TRA=s^(T3gaX+DxC9%1a=M6V~tgyl|B`qOkB$`ksy#c1o#je(*Fbq)T_0 zHRwWop>1Ti2srt2Fy-m!{u-1QWr|mMaK=i`f4`@vVx_lq(yYA6g%tnYE6g3#fGlJG zz;jkR*%2Q4Jk(0=@`Q#!T}JDrrht|)_yg-Fr#)c|)0I37nAZuUh;`ITtph4MBm_Op z7BdWb)+H6u82Y^|<;xkdu_*&?qEgNJB@Dfu`lqjKL@@Vm;Y`ZjUYy#7ifWRYrqo%# zp4}2Re_#00Uf6ytXeZ+e>DjyD*;VtFGU=AoKJ^W!IvMpW$u!7UJ_yB#>>Ui>T2`SC zA*FIGJf5u3;jP}~As!NWWDgll(wF8W)=34+Ov+3bq4@QDM0}GXNbB0@r4n*zb{lp@ zuln;N4$ z@_7E-bGNoK-owFk8!w}s4T6@VRnnQpsV`B?FVo-T#)S{jPkg9n@>i=zQg1SPr%=D} z03Ax`3@6k^;$s|bBIX?Y`g}_r7akCiuLI|Mn{M0^*~!MVbwrkRGkQ!nyq`%%!S^Y% zxd{B(g;PFQ$_e-B!?;)J_P#Y}Q{WA0r1xdhTsrA~+1}Vw5+z&Ab-# z^=hUwlO#c>K;ICRvuGz{VR|@#a~V8tg~J=#XnvIoy+5pe1{`r~vEjgCn+L zC#VG0_=kETUX7YHx40~RK3Ytj%?vjJ+Zp7W55UiZ-q7x{VFKtPLzP+5o#!3XYnfuv zT6Z@Ut<^5?NhG5s2I*(qMQp@Ezcj&K+nYlq8qK`Jv|LezgK&f!@P#BmRwCm?$i12{ z{mfKWwDz z{>-ky)6U0jD1=8jNLFSsff`Re~y+o&#|t! z?ge79rB!i4#=9bDw+k6l9%VV@JUZw^WiEVrEhb} zt7H#7!#A>>cJS-5kscma2J8^8*dzWW}gC(#04Q1@iadpvj zxaa{3wWVjs3)Bd{z46HXZBi8JQ#wielG~3&hrCD?rLpclxyO7^l(=&p0Kgqbwz0l4 z^W@KNU2;RKk5kk*(RIEXU#YD`J?%U&q(rn0Us(XSi_@iCAHt})VWDB#MNu$d%{j{-H7Cv-28W>}Z4 zo5nqljuJi^tntk7N)8HiE{_j>p5&%*N9f!pK4y+NWWFHTKIa@Ad^vQG`Dm}hQZXGb zrSooj8&N-QtNtQT(0#M@z}tkBb}683Yn@Y-0bc1^_vPqt*Vh<=r441??8dJf8`7aA z;T8rT=Bl0E%H0bIIS$N+FA4|T=&%IkK3R!;)1cd#_VnE)Cu2f-Rd(6*9 z7X*oPqcOKSH2X8{0w!|(PR11;M`Zw=Ipb<;Jv2PmP0zMu>^!U*USE$x)i9BUL4blW9+RiYa1A4&%NLdWaxv&;znr zTf2{}sXD+e#J&G{a=9sRZ28^S^<@(cqK{h@^*q!cEUi90ujkR}LXN$wDWtwP#|`Cx zfOO;o%gy2_Zfcnn1e0o^FW)J6A3Xr0`V@ltRflD>{ebWiw(Y$3<*X|L^ip*Z|AZ8I;xxj2t@qGIoRzSqT!4YOrmx}uvHdCd7-TeLI8;XJb^$TW!e1lJ_ zRFH2F3HI>~=)pdIDFFGU0OXefkY5XYcZW(JhEu41t<`t?f2`H_XQOh6I=YydyL@*T zsLvtIA;TdC`vZnOVcx335IGeLIza(YAdriSix&t0bAy4f2!H_GoV>hL+?+rFCpYX) zHFp!Y@3E4%cCdxj3l_aUf_qbIH*BL`NswQFa6_Uml2a!=KS{YXE%R^m;a5MKyC&cQxUiW=+3g%Htxeh89i09Y$?u)|zwD482oC@P20^L75N-ez1RJriVFuvhfpSrS zVPCjGoZp7p&vi*vYfE+!8CVE;{@U8#N8EquBN)~xxp}z3zxxOVasjwNu=fA2d{h-v z{d*sO<$eE6OLM_SFAq0}3d{`~*E~?zu;vAD^YU=Re1;8c9xmRWj-t4zyfUAuqk{#9 zwT-EkEu4yK*>KnsSIZxry@rqK*6z(EnjV0&#!qkX#Td5C}GmxS%{#AP5LHA#nn!Kw#J~ z;^OA{>42&kJHS>+6=NUR9?ss5{9i{ zKEPBKAZ(fW1=_&A!=|KPt0M^$%DBH(RTXv*%o_JECCD5_9^All!#pV)h7goTRFTd4 z$+isH@{HtHd=oN950X;`ff6h<*6(h19fjd!Q?|QW&J5&{wc(=YZ}!sz8(SN$btG7s zL%Ag@t9V$SrzX^-mUAU>N)PQcUgMw4Pp9oF>k#{C4=kC3SJv;VC$VRX(gfd-m#d% z{KnAC{TQEi@Hur=8hPLAb;M>2b2W8p6uuMmkv07|q&0v_JK?VEJvzONj$~a51Anh~ z!D3UML(oY^TkqX1PpEe(pZbhottz=!5PM1fi2jHx!c5OnAe3RjuP~jK7>2qyu651l{!{2m)8(` zGF?$ICL(pxfwI+p*{tG~;Z?j#mwC+4n)IQlX*F71U{mV;{>Zk>}UM zof)JS;}L2#$pkQXpwY#zbyk>CGI0o+SLUJu2eY)pnTbxh7t6;k6LQ@EPdk~1X(_01(_93ypSXn#${*NI{+@Q zuui&=D(nqZx|C{cA$$Sb)2nNkGO61ri}SR_(<-4*$UnST*}s&xw}9wLl;w@-;X*l< zW8h6@IAHe0st-e_6aiG`7AL{)9hS6l;gpn@Rr$zro{7X^`=>R+bn*14E=8eri9_Y3 zAsh-+qgsjT1x0FV#+0SUT97ytre5T&lmbHKS{vs#y5f=YTto=k5+^QhT{s27V03a6 zTeTMa7bD|2gHGsu==7jNZwfF7k0r-%-Su@^k&KItt&>@hl5jVMqGIvARbB_q01Kcm zsowf@gxRL38MZNB)ykzQWe!5jJxuemTj59EJRRL_Uj1WfDyE=B=F!!~JFx=^hL|J` zk%NTJ2s#)h^cq4%oy+I>vS}!!nQix;#1uryiny50r`#lyZpx4ilgXhjT##wTNUNTH zn91`Q%tJJbuQ9TCpv{o!Mqu>?eu5EEW)@iT$v4N@on&w8IPZWbKA_QspOe1&WBvk< znsL}RrGzX=T&3E(JVva}ItihbAi8udIcqQB$8YE)_M0i&XQ!e=s|l5`mLB5oycYay z_=>{I0c*a;Atz$u*}m8F3Q4U8nu}f*>8^qzK>%T9)fv*`H#fK=Y7Ttr{1%1$4Lr2P zXW?a~kATC>qi?q9yguQ6tvNrM*eR@_m2jLQj`4?Q&8{ z6=9taYs(8U@=X#0!vj`U^*f*S#3)MKMM>|^F{Pp`sL=!0B4)yHSu6Y+Jy3R?>SaUv zS569%C67F`L7%nrC}osf@7q4cl~3zWB~7o=7ORf1kJ*nx;KmbWQFJOhjCi8vQi~MK z(`NWNij~C|m#a#77I9ISb9QCm>=}1CyFjKKM6W_u3(nWVa-2P@M!eqoCAyGmp$#AM zT}d4XVL`zXMxgSLa!JR1(BnH-m8|to0G@7JwoV0}!_fNetS}Vj_9cA5m@VD33GItR zQI6FjdW2T`0g=v|-2u4^<+!s$s@Z((RfE0o0ea7P9In0?t%*%(sexNm<(;>C{)T!m zg%P^ADnYMtdZB$+e+JFMeDex$#I~4*gRi(TSbsB`MP($9PF7ZJ>VHVjX3{O&DGNTj za5bYDB!3aey|6dKI;T=NrzyWOM~3-nmjWVvE5gJ!pQzxE$AVLda)eSEpEDopcd|D8 zkik=d;LHc)RBYb<;hm*7)-)n2W(?;T-YRq~)lB^7@Q$i`fK~&) zFSwQc(N?De5_DWSr*OhF)Rh|L^Pyqd9N@1_ZyFje?D;sKDxxdJUvFDStCgUbB_#41 z#O~eR-tM5p6R`M@J_$^a3S5cziYY+m=kpn+U3*;0jD@CNWzrTx;+DlRozQDW)f>dG zYKhGY<~U;~66kx>uIenYtbj8@i~1h_O7#;-y1=6_ZTQnGGrE2@i)XTQ?_w0#>4hZC zBy(S}Z?ND$^8I8((?fReB(_?+k=*sR>xgpt35ws26JzO=*i zH`K31XLcSjQP;idtI_XPY#qcxm#}-=dUYyXMal2}>XYB9)9%Ap{_hmjPqr?aJofbt zkc1i+su*2{kjqFDrtL}mKPAAnKHj^qLQ!&jSTp9<*^gfw_l>D8Oxc%yeh}O7l%(po za1{pwIhc)S%cg&*$FW%&(3dxMi|4k`W0dvQfADst4*A{ghktOaM(| zY@h1GuKultl8ePoM(HbU2lY|2RP&W1e;Z^XEa?h$$)=~@bOb2ONHhMSb>xO(Xa zv>&YO(>%h9Fw+S+kQaGlwvW@hCHNJM6T!mZF9I6$*R8xCAoQOEwC^D74+0wWyTtXs z2x!n>G%w!o!WtFtFOZP;7v<~^0PueR_&_cgjD`SV$_OVHjDGM^0bx9u2SUa5joEWU zej42WKeEVo|9?Zpzo?J@po4wm6u;eCNg7yZ|03j46X*f*6F8 z=LbU1@lB}X5D^gI`1TYIk?;HJ9BLdIsxsgHGg-O0Iq`9DczSvQ9866C?oI$FH;w=g zS5pohV+QHILQ%21Y1OWbB zHGZT<|6xmjVZ;jv+rI}vzyL4^#+r?a{oYr8vL4?W!qUwa;OJt> z@yB?>qVzkZfzhz<;}1rYevSbGf8755ccsD5Z~dL~uM7}IDgXJ|AmF#|$n{tD2~$4* zxik>g^1R7*gKR^5XeDzx&|DC-4 zfu#P6nEsK}f_SN*|01>jBCdx$mF zP=;C7baHAQHB7NrHH$S}jvCFf>L9JnQgZON;p%K7m5uQwB6@a9f22jt)1g?lS{sHs z5BOZ}+{~lg`0$M~Y>5LjK3k3@j=P7=B0Wv)ewwEUe&GZ{%eW$bIG#bzFcy}EkT_2X zIrqZ`Dpdj=C7B(O^n9!ecbsZ3k%>|*Qhv=;QnpyR>j2Se?WNc)URJ@VNVtLqTHPbF zn$BQOKW!@XXrJn^jZ4Vj^C2 zrxzcm8+EtFx+rr2$0HDQ(#(};`1~T_&c1L>ZrkHN`-i0T6|a2C2H0osVyJp0-$0I8 z%Fm!8yU)5ttHlPI;@#U6g8_t^*4(Ymlh3IePMNu1-Y-g_l{6gQ7%ts&#@JwBj-IzL zxw2wgXiNM*#@IPPx-r(I`cXTzYwRouO3F z#qp8;j)Y9^%|qI9`ljb^Hy^HD$os#3%fq7oy2|MjI{;Bg%n`@q(0;TteWY}S)&K`1 z!nfKrd6lM{gi5EDTKfu6HE&Uak$Ab1G2RzFV-}ohMKeeT5%s|vM-Vj77~U6 zZ;3({gGJUuJZL{ouqK;t_1h8a?F$Ew@ZWjPhObT%n#;F)tPyW8b*PN3BIGM4BI295 zPfSv(KTw^$sMG{sN9URxn$=SluaG^Awy%#9pSwXf>7Zh-Q)!NCkg(Y7wt+hn%}s(k z(fPzJCVWzTR!JNx90dcEqF!tV&yBrXYT4v;i z;m%cgtva8GT!pE0V9{y9Y0yv?KB$P{TzC@SZ(k#>)_os;P&Vtapjj#>ua9(k{^Tq! zI{~?B=H8~|xa?bZm9dgQG(=6NiU(VL@8=EQ5`f8yl_Q+ougU9B;y#?hmXc-Ee!=svg-APHyOdL7(v5(AIT_r$WAvl@5L4F?`Q z7(ynx$xWk5ULWRAnq^kywSk*R?w-_Zf3`~G_24X`#Q{Cjm^qS?%xdcb2Q-Dxy9jnc>H6WMz~MkH+>2nV^We%S=X< z*lULBY_KLdP>xrd&RnBORMJyltJDkb=RRYsK12 zTLHm~A5;l*IXmvG>qXPz9CR4XIRKc-0;juIYHZ@`4Wz(sdi@%6&J$jw1kE#JJK!+a z2HX_G8U4oUkYd#}7UAY|J{@aare3TftNYoacT}Dm<2~%Z^8!2P3@O)LU%@+$E6Qf> z%&&mYMtJWs9hcj4h$VbyLf6v(m@lnk5@zik!k(3u6Kc=D<74H|2Jpt!!YVTfD}I{# zRqbP(H5Me)8IPiDBWv3hhe>TGu-9utg~v`c(mO&QY>nQgu+<1G(VQrABrTPFi#n8X zwAYq6r9%_;RPKfufLq{D0mTw{Yq4lbd^$LBHNCy+DRU7Kt47Wrc!0hoGV~7jeVhcb zsngzS)|a6e->kQWh&488ifG}yGOQ}n+olpIx*V;ozMpvlu(*T%LSK0Qx>4~b`tp4l z{sVpC{l5MFpVOD$K{Jr^PdMzm8~*`{`_neS-xvRPLOx90{{dORP~hJdhwwrGKnQH( z_RnYt$oVH2`1i#juw7(M*sjQ5i~k7+{(W&S*k&Ks-|S%kVcTrK!=iudJO~8f<$_V6 zzdZeC9uDS$rE!UE@rRv@AAukbY_sNHsPG5m2!^F%z(V$I-{Yqs z;`ALjeq}3PqQ4+i5igiPpS`(}34L{?%NO&Y(q6k2c{at(s8S#e9 z!j;T6rIsoh=Kd3}7`NEk z3qdVg#)iw&gna5SUVgfcp?1QrWTKa|q}kCrv9@J%6xt7H3$&fHJvf+uf6?!0x>)P) zIcMj;=o#iZoNQM&rID(9GfXA`|_b3Y}#wN$BS4!XG=WN8?+JXrU-fOSY{p3od< zC%-3f)EFRRx;8XY#GL>^$RUaMAIy-Ne!xqX@HT=c`y4DE~$ z%Nek$19l8a&LwZ`rr4i2Vy(8~2jiCbhklaUzvQ~@vILDk+bjQAdDH~4)Y=JuDRe^P zJt2s4JbT&odC5@MLrBsN9%%AK{aKKmXbicCU)`xf7oRHpjCWr7yqSu2S!rf3<+JND zc5^&mshoh(um~j+>>BU%di{mX(|c!@i`3wO4JjU{nGdg$qaFR+UKwuK%7XIBX~;>( z2@YdlNEf10YgeIcF!pazC9t047_6dm_AAM|nT9>RP4n-;CSR+ZgXYW!E12@nKVe)^nGDiKKBgm~Wq&<_*)X9*wseIT-j~nmZ;XfdfMO$= zR>;;e$V zD%#W|mfQ1z)Lak)@P;=RHZ>b6uv1fDD$l6N0hMwT;=L?Kymm zX>IYhbEXlBPFZ95T z7m-r=J=X&tebo}v&X6z7NIB}U`(2pnxOYtGhiaS2y&N=5M@mu$Ym3VohTuXW!3@CE z#grDba%>{n^yx&7JuAjXALGjk76uvKPGngN86H*j+N*!@88n-{Top_?{i0P22fzB{ zT-RnkDu&r50*|EarAcF_FQKhbe$Q<(vKWB_-ZGhMQeC%|hjO{2jqr3;Ym$kquH8 z1-FYTqwPYren5Oo{5RL)t7lFY5t3KM64v>v-w@uYYp zi?WIzsciCy3}0YRn+YpHFTv367ej;m)J>!lufpc83Dx?owdh3;j$4HK_rSit;2_{{ z@5B6i9ru^T<_|~+`28gt*roqI6%q*iCe5h+VcY(fYrn0tKc&X~p1%kJ!^BTm9s(@8 z5+)`>VEKz6E-qLiBWyY6=79-x5YBHJ>d&Q%{hGn}?=u8}FnRd*1sH}#eu?AHBe@^p z=f5ougCYPRH%wvt3!3@uC8zJL_Pa9m2N3eNsT4m6FaAb?0zrOWf_kMR=eP#JZ5^rR z+(?2L*@~-9($=%RKrjn}lfI z^+Vaz+&5ogfS%%R zc;EEHL}T@b=d<&@oUixl<2*>EM4pyi>}c*%p}fsF_q`^WO(?#8bi7V`<9&e;*d)BA zG&Xfof77MV+K+XTZc%Eq%aCXIMIU3EO3nF8Jr_Qr3hqv5SU!^(h6KaM^&_?ShGOQ@ zIt{I}&cTzZqWaj3?w7{nBq`z#Cz_VNKxFm~7)!J(xP%S~CViS)ixB50 zY5n!-tVuZ|o z@e|sqe#uV$2*4Hp0GQylRY6!(m>?3MLu!S-5|_}^$~HmyBCk#Gjb-uMdCLYCHu%Jy z(3aJj<(ZQ`_GU7qw;$x5c=}$3F7;$8Wpx|Be#!(9!DmQ3#&{Tdn2!%dMx(kXY}(L+ zfvH?~Nv**b;cV48T(|7YQXAA~f)#RI3TJhGUCI(9v8lFaT^OkN!Gm{oIK zM6#>)VY0b1Q7xN?=_-SrUXt*p*<;Ojvcr z;fPIm;A95TWhu4gYahvC1#Q(tOmzzj?Z>skne4HdoXE`5IjgE>**t77`pBQ#4$SHY z8H-TK4d3hSoCFebh>jeFZo(T7j;}bOYq5+4VOHv}7C7`7z}4^FT>}~mPlBZiv~aXL z2=7@$43deD%Riv&oLJHn6uTR833ZNB%q=fzteEYzzaodEEWOn>6AhP`Bx2c;pM`3+ zg%}BMA%3yJmlv0cQHY%pNgp-!D>T@Xz#+&FsCVuC==A0?He+)62yGA%J46(;i=VWk z0N2$J?9Y{5(HMjKkoBlRyiKHO`Kleg$|Pnp2uYwhg>u2hx3w29<}O~on!T8&#U1;% z;1OM##COY?iuwZDqBsjXUwL}J*uN*zZ7>bMIk=OG`2=T;^k%_t2AS4Yz~bf2X%o}) zr%NR_$S=VxbAoFPbIFI#6B6TPZxI_%cEMt6 zzg*^4sLQ4G%-o1W(?T_qf5)T@pOhPeRPwNas38U|<^2)WnfXskx60!MC%Kelr|UV` zJqjc_qgi7yEu)7u9U!u+dt3u>Hwv;jk|GvKgG2XhXMMyOq$ADsr)e5`&rN0XnE(ym zMq7EaH$4a8{3r{`1*AAlA+i=u4O@GmWc(hxE;eNyMN*7{v?WIe9Bsgur4+#mqwOLusnR1 zA~uq7?VOk^AtWGvH}g`ooDszb7t1|JOt9B!;mgR{HrdRmZ;v?UHWrBWd|;JW!y&%J zR<5Eo^DxBQdgHDFZS9qV&4B&zfqoHA=}&K`d+a&MmICC+XPPMee1 ze88^5p@CckW4k!}Fn&{k+gXbv@0<5ElBW0TdMH?+?4J|E0>lB!%A=?wONGSQG?Y+= zk6yRKe0a|aCFnkdW+MUPDHn(3>3Wr?n>)xu!Q6KA`|f$&r%s9j;1U+FrH@>niA^s{ z!7kV3OD9?Mp=mk6ZfD?WE~cw~o{3V)$w;>Ka!0cypxHFov+|C;zuSF;z_7elN3yj& zOH0>hTu3n@_Y^;8NTmBw1~)ITrsG&4&Ahe^`--T^=g(-RjGD3SMh-@e#CcG$zk)$6 zAy5*_W0Ik@g~U`bVTGtR9e|;hfW10avQxxTe3@1EqIq7_ppVM+K;I|itgC-Xd1L_P z2AdA-obb>$2c0rL?!dvS1J^8kmXY@MWk2u(j}tjk){zAzbLJzv?*5nyi#3&bt@X2K zda#OX&WHaPxeEMaX#hABf{!)nx^Gfb&KJwX8EoHhTB`Iepul#kl zv8S-)_a~0ICg@ai<@7B&B`XaiFW2ltJOt74bdkx^RU357V$kj)$WwE-X7o1aTZ#@c z(`@!t)yssf(na9Cq9bu;p{MeU7!pMmtd7}g(6Hq2J-W)?xwA*$#lW%Z3lR_1(b>%o zVbW{ML?-f)i{u`dwH}aYBisnqU69h8u+Y(qtH=mh(&;xKa(d9W*Z}o$OA^wFD`L}n zGZx^&j=2oUsd;iuhbcN%4Z5ENj@y`o-p!j- zuc5VPfR?$(UH&OGvz5*+558(Qyfm)WF_C##Dkq|LP~Az@C)(2bbsOl-W+*@^{&*+U z?lbw))0P1`l+=wtLC(Nt`K5vcBOPyl4pzQtvkgw`jmhm7(Dfwd{+OiTNpD*JxrDa~ z)x3vWQ5r?c24nI?2qq89tp#!mlb3~Ackl4lO-x7NkUX^}X=o&q0zBYE+|}DI!MC;` zcXlgFP}7wT@nd+lEWO;t8wX2}51G?xL_DsC-e`(zm$~Trx88>E} zVBVKGAHPSv5`@&+sEHOZ+#Dm>%!>APLtQEtPqueRFKIw699ox8Ftfg{_B zJyW?MnGT#zgQ@B9f;zjU+83v;xm_wz;d1i@UFPKdr0pX>`lBr~_iRnkr?DXz?~9ZM z2r|D&#lL=nwG+pT$o^swXTDbtQ9Rx@%j#KAS>-irCkcxA#ACgnp4z9h*^`A*olB}J zqn^>nU+JHwD4U!-h^*PV!+2Gd2s}z?Jip(&E}&RH1OXL=E60k&Ou|ybU zp*4-?>xApWktVFKh_V|_y?;YZegw(Cuz^2mv_Kf(g^`FKU(x~s|96%4x7YQ*qwDYJ z{8!QLCpX)_yYL&0`5m4AxNrPBQvW$b4*F4h{Z~daY;*i)1wS2~_*DpQK(67K5*o1; zxY-S{SB?`U0rAY5R0Juz<3ZZiYdCTPnS-3+>P0^38JB^&mfq;WI_=XM?dz!9%jF5I zHXHAfl-^bCMZvvKDU&n<6|Hhbxc$YS=fzI(_rqJ~?c9qCwwGQQ3{c`R!l|jRf{SjoBDFQi%)i`H`y(60?M3=Gjbf=Z&9QPH}$)K)c|IS&C#Bv-DC zKEn{J*G^PUu6JKgPbmmaVRp!?XT(W}lf3EzIa1?e)|Fi1s4XUyP16+2Mic9DVk==n z6p=iZZ3o?xA_PXhVs3n-GBqZ#@--Dnq+_siiA3XSFyg7~d#!3_L!qxe<+VQSWHqrR zj=iknCsN`*35}f#D=9Y|ltp;Fb|iDcEB;9Ebxu~KRPd(u!lUF|hR~3*!uW@-=k{4> zv=iu@HKN}o5MLs*`auR2fP%g$l1V7iJwg`x*oAy z#2;&5i+aNl`PN!GKUX+#J9%d{K5OqW%h@{wYT+WL^tR5g`4Lgb$UaWRD&b8sKRSvSTe59x{Oojhe5TwG z%Rw7)Mmw=E^XP3Ow~TBQnY7pgce4z1J%7#NF$S!$d;YRlUZX1?7Kaf$6KW)LrCyWq z7W=gBvK};a;*er=2UR_kkSuYUtb1nR`xduolT$LzN3)yr_~Owx!|c?@y1FgxCq;E` z_~nbEZ#(B>G2G!j9yN72ZxCbiT9BmPa5j9Fwms8dZyf)uSKSlB(lRdNLavlqu<}4v z%7MMHUrzk9IHBU|p4;>-{Jr%@)2T1fu>H@WnQ!_u4jty91S4ep86A`I^G_KK-Q2T- z12cHif=%;1M{wV%MHZ6_gc3XAyhe9$@TgmyaY8rY&rhTEqc-a4msBE(vx}Eim>rn9$~l&rC*L!M&}AGMzWzmQ`4rQOlZmImvw?ovHNw`D_!svLXsx% zrsVT0Rzj+Claf`=`$^}W50nI7Nc&qk!l953+`8G3p*`R+s8EF<+ViDty7soFB+9K; zEJS1R2d_8s=M;0F9|C=B3+cIfA|dUIcSaj>1@E%-i?L<++`M-N^JC)A)#nS|b9QT- z`K+SBfH{5Nkn*WJK{DF&6{i-#{wX!e=()mW&Gx!5MgF7MdW<;P6v>{Pk_*<+#|hx@Xaw{yUpUi7`waf~!5L|P4zY*W1YHVl~e6|(LH)D7A$5gBoo_(c@x%h`sWFe znf}^~4`%wY8aQd6SSBD_`KO{_U%g)xnYN&L1twJH!A`5ApfDx}NZQkck03r9A*~;| z)k}UXe!{-lI_X3pCpzF3EeK+ z9PDWJT3V>is;jG4yq}5RJb*8|mBSYFJh(p3Ia*FgWF`Ni(@A=sDnSY}NEs8r zd#Bh1Ve$imR!J9z{X9&2C+J*;pyLDi??0>()-)`1!`6 zDEh^Y^lt6N$7YaYUlej|58g!!={zbqaS})fxgJwDJbY~!RH0fvTSMc;6@TM+$59mN zb#kg|3Yg{P0;Q@|<6XG2ASWYlLPcSD;<*}TSs_wo|956i*S=|3vCA_DgJMSst)iEH zulcBGju%!d(-veifcE3wheAF^R+6AVL=)Q2@8vig2He6ju16TGz=^i%i02d^Bk*|v z9B|!XaOi0x#5^*_5mp2wQy1duGQC!{<>yaR_f%Pi70tb#BqiNp4Ays!kDnUVa1y)3 ze9(dA*rq?g63jGfn$kUaW-^-jcC5zt81KrVNs>_zRN5rF;0wpdirUM%KFeZptR7J{ z>f|I5T2&2FwmA~ONBV-|_MzibtJO3RPg-j$jX1cF1|0*GNm+mxi52j{CsF z(Rbl9$My}z{?S^%=PZ4~SjwJH)NC{Ywe=dIdx5VSQw!+sc-hOUUJi+_!*%W@0otQd(;O{)J~O{r1-(34 z8+IP;-Q*D>3R5Z*s5-I5p9AL7wpky8*>{&WwnwfThfW)Hqmcw{hD6B0?$^6{n}$aR z1mnah>7i@1$M~b{dnBI`rHUhZNU=!f0u@h}O76KN8E=3RRRwH@qn^E^~@J0@ftgNLNgv)wZUb*q`-%l*w|!3Z3=CyRBA2vS=hRqik1um z$0m@ycV$16idG`8NMcIFff*Z21S2LQU4*+_}hs9-|||) zus3jdU}q43ps)i0VA3;~=UbXC_=opK|0%uI0(J}(-}mHJ7h@+Y4{M)q8Lod!a0SA4 z&3}*EH`M(-kUuS{{~_%Ewm9s}Cjckxq=vsr>c1Vt^(RUF??L;IZzTTsrs7Y6`5%eR zZ(yDimR|9bU_MoQ(Q&l_Ct$ISCLV-sE1^0W|8^e!!x@2<3jP)LGprVqJZ)K;_B1`Y z1-sj;VIFXbnbgcsi}sq6G-fz>(eK3YK*;afESc1FW!%@-_1wwS4!7ia9gnw(N%F?+ zM%As7+xg_vtfBYCGV0k7hViq88t;>s+?=~rDITwCBu+r3QE|#2#HDODRqAXh4a`oS zhaVgl?a+E`jp$dBMxA)=$Xt7sZJlE~zP3)1@YFt$iM^x+GFu!e7Rb+@&W~cQzPS7} zFYNG|A-;uU`^h+te+Q#&)6je3k%44p!;g*o6cSt}=3HklLtcJC@&i9ihwOya>^Lo{ zcyz-J!*y?#c!cLMZbPPO&)ruAFKfD04$fl%kp_(WzMqq=>a%lt#g9GgxgqX@?_>d3 zC)R4yrNU!#Ptz`X4){#)@aB_VFs=7;P3LOZYGK5_Tc8$(oNa%{34| znmafzn~P>RLygut>L?oBFxz~mRIGO|%hi03ty`&dKHECti=ja)z3)xdNg^kLDH|!FFS951t(xW&ecY29$?4+b=wz zjd;5zx#_&5UOk=rT6CCFR>x8+cs73B_ewZ?V=$qe?2x@Y!KJjey^o`X#0&<LdK6;A=kS?iOPTst_|t(3d*AmLRZ<Bf;fj#>7Qv%hHbp) zJHi&G;krxWw zvk!wB5o@{KOWoa0uD^VFi`Z20Y*2u!6q)z_rh#~>UsaW4$VkI1LC~X@LzCh$=!GT5z+ixfOoWS)E+|k zJQ8IEoz8l%{gK{ld_jCm6>CwJ3_mvUbgzee5{{jijCZ`*oNZNCy6qiC??rjtoo8qcDoDrAh`CjnVuFf8(m!P}YxRJhG@62rVT$l+R>_H*r(Q zc+G7)T#ovQ?k(X4cT&Cs-Yn!V=29yO-*v=pb?vL6NDnO5Ym(137`|m!BR6AnMGrbW9*9PLNbY#6)4j7Y?8En<*+6z z(4Z+0VU`+W`lva-Y@#5vP_^}l8Go$mN(>p#O{}JPV{pzKv-TQFJ67JyE)di#$4&EY zs+3zjQ$MLS>LGJSR=}2?P*&RE!Iry)8jC1vDn?@2P)1kvGf(`!m1l*4WU#?7zoMiU=vO-A|dPe&r z*RCHQ?`E5-$vn<^4sV^qzp{IHWvyH;s`yNhmeq4N%!UAgyMt~LdB1eh_C8~1tL+I! zmZfv1`2kCVZ^{wkxrEdq*&Ja@qfVh=NoQ+vb!{jj(qgX8iYQY7uQfR@d8u@~dguGc z&{bKSxr$HDysd}ruRc7E*G~(7c57WXRO^@jP%Eu+PX=CQ1mnq*fqsAhmRVk-Wk3J5 zm!toNqNC26ej2!^wd&-4?(V^@hWCM9@GU6%+I2DaLY}rb(>zJLizsurqKBawzvO2J zCcNWOn~lK!M7BW=PXKx}aJUS9Dw;}x53l&}WrW<6qia^+DyOXuADm#E^qJ@uu0*t%e#Pw;x(1c!j8y70as6k%hxV_^vS+{ z@kSF{GsJuWfVwcmi#-EQHGFwi^D>1ML6hQbL7A?9xAI+r9(^iSfpP^)BHpEf6`9>bLjQk38ddq-fxMM-!$W&gXW^q@T;kIivNrsq#>$)A`ayzCf zD6!zN$#PSVCo%ecc6?O(<|oPHfYmF*JmXDl8h+s&kirv!h&Miu^FN+j5XdcK$pmxL z7=hAMt93q24Wfw)_&@ble&0B^QP#a+)tKq+7qwYwML^yH33lfWZpGwx1?L4fa=$5$ z&d-T7`;vsf(o)z-y>F()Fch5|w-?^^uSI9XOr*>7H+V!lp_H&oz6CAZg zn@Mu%Tn7%aWpl-uJf7o%4P}}%%B#k*Yq|5pyf6M*?zX^Wt)6A0N#NGcfxj+?Hy>fH zPI+R_+a`RmI2OrmO7Rd{+sGX~J`{A9fA{i6R(WFZW5`_ioAdBU<(&?Fj(z1UIrKV* zkhpqfK^JyZSJ?<1ErPs}wjvp$5O(|Ul1v0MR9rIp-!>*MHAF}TR5{Hbl z`=hgQ{S;20O$C1S2>d*a6zC;pCL*Yx=eql0z@noQc-;!QxP2+9L*o zF|E<*Bj0mn6)epu$t5A$XCj(MU5$UtmB|5bVM91ln<$WGJ!`%Bx=%$eiSpJ(WwgOF zA~9Yyf%i(Yu={-<4*nA~ItjI>oo$VF^PjRd8(9>JWKa_ki#Z%--&Ggk78a$vBN5iU+>^LAG9GcFf4RvJx@?H-y=7XATM`-TfW9;VSjjNGpwuO!A@IF=I9<{ znPPF@R+PwY&{vcff|U1x*CjdP4or2Kbj&fZ1#KVPFU(CuJ`A@zBiAcOa-tSrU-I+2 zrHVwqRY#sG_8wzj;apxUUg(q{+4b|g63K~@*~%tmuKkU%`1)$Jaz0z*;(+g zJ(!`lFuWvdY%$XgJg!}LCJ>MDa{-v6)Qk9 z&BT`EgPyq~$YJt5m@y!<3GeHyPG0Yu2EY-v2Q(gcEp6rcY( z$tRWs{76^6pfs`72n8ubaqF$F>GLj6STokTKi>p?b5#DmS^ae+;ro8}&yfV6 z^6me86JYwI7XRLrpVs0G-}~^}UEud!{P(OEuyg;TKJDj3^KYKdKknR&^gq9IFJjGF zF0h_(Yp;sZtSAfZWi31r3nAr;dg^^xOW?0E<~nJT>xcNvbGg2tBOVRYeLqCZhW*mo zs5iZ2`ICETG*j*ZG5q=L`Gb_p91H2Faa7R4jN+GBhlj?q+$Hk-`T$w?C+Y4s@2p<6 z?E$>}!vFsw`$L5!VVxE?yTgtLuS5=)S9_PB7^Tytrt(*lKtY*NVV} zh8njoSU!70X@6RA`?jF6`P2N)OlDWBX@G#`mv~xS z8DxzWAA-y`V$bb5{dgru4TPQB6;W`9R2c~K>tE}|nR3vH_@1@z+|AU_zk9BcDdmJN zs&bdYc$<-Fg_!(|O@zaQOnaU$Ty6`$0^g8SNz>GCkXzVUx!5$Oqfegybw+5+bY-k` zL9q+LHPiO-C|y5;1c-y|u2K<3>kf+}wQ5!$c{m&Ah*Ubj&ow|hu( zR}M5g)?B7-y68>AYE{rDhg*r@94picb^g02*bj&iQf-k{@hHlN^R{eX!PG?vshJ(A zgo&_aNW5{$bniC2ma+mZyaoF=+>B*+$3z&Y<>GxAifvG`YT`Wa^u@1IsJ8L!1lH^~ z%Ri3Qv|CG5k#D}dT(9?jHZ|jPnupPydvfb`ZOW1y>56Q|>v)$0ULt*Nh5r*=L*{FXcliAthiJi%BI+7aqF=sjL6K;nsaf$Z;`vSQak1pW2& zPNFW=E*RofWm7GUAa{=Q1Aooj;j=ytXS}JkE5tbBb4v@eGZeNK-;q?3FNjX}fkF$T zq`XC&pI+ZwIwCz}FJ@yNT0T5;Bx}3_IXkw&;XDAp`vbSMApk(HL< zUH!3eaWo<;;UIXgRzGmIPJKP;9edbx@!s31LiQ&`@%UYvszbXymgb*!%(kR7vxf|% zOSTadj)ID8$WO-ISn~8XA-@#d23RrH@y2SdytkhfuZPxyUfB^x?`lN&n#mG(lo>}U zE-9vO6JkVv~gi!r>WG@o5-R~Lk3q8ErheO0M@n<&%W*EkWx+5$A&Y(zWP!|dt$+T z#t{xA$CUFv+oB%s-Lo>Bc*}MExFe*Z)p!%t#Ll#jdqOt8WT4~DM`^v@W{1M>5bC<9 z{N9dl`H4wcXqv}^+0?$!p;ffm!I4eOoqb-=))uqsF0Ag0K(wfziVlx$(jCb|v)eFt zCT)NL0!xcp21C_GW&s<5(tR0BO=Fio2rCbONsgmi&f>k4Iucv(VOoja}~5yQhg;~HS~$Czx(^Bw`M_Jyut2wkZ-x`_=9LAEBL)EazE z!ORee{Ji?*?$=9ae%@HJ0aYSc&zwt@e zsazA%$(PpMUoA;7H=$%e&vd1~2pR3;dmp`~IW7nu)tCH2BUY6Rvz%K;G$HOIb(e7v zPrvgS1^%)R?bOG|UJ8_U@X{mylD9?;M-+&dAG2CNM&I72B&0xQf9c;WGU%4aP`D*{ z9-D@x!78m0s|?&8dovV0i!?lsdC>Fa<%Mq%hw=C`Zw2i%pD zM~@K69#-vw@|`O3$+Ha0%5sHG44)a6XMriIBO>3u-Fp)5oY;*XWcNaKh9bWh4}~4< zV8OZ2;?}>!W$T(Hg3ajbC`i%z0AY#5;^*=g(oaKP%}hT-S1KwF^4CHw$-LMMKv0pB z6mdP?1@r1T5c7lK*RBVnI&4hiWo2}uScMA5dVXV$yK>06Ma#uMldN5`eD|c~cIfOc zPES92Km3c+)33Eczk570Fnv#={1;C){Dp-6Cv)j<8kp&qXB~dltmAth{&-g z379PD6Xj%?!QSrt`Vd4VzH<-(3< zW%tKx3p6ppmD!okOlBVGhSw0{Wti*Mp>Ws`5XeM3FdD63>YDPsNnxJU9y>USE>E6b z254J`hMm@tTdD+weH@a=t1dBpEYH`468hRyic}Yo$>Y@y;zNeV!HnC6vwU_$!gpeQKzQh6ykAtf;Whdo)~Rh{vK!N#odfN-k?#o=2B|203nU;8ADkiRpIg^;~yhxAW@sW78I& zE3T~tM?D*n9o}E|>*x|v*1GO>vqKex2uz}^5Z?7QLPAL6a6mS+6&U28Pu5YxAZ0X- z+dEvgw&sH^nhu1-Br+-LC05TI2#V>6`j@34wjK1i>kB%Vdjq;nId=zBs40)iPHbNs!p3}cl(q*D2G%2K#n;Ii&Njx0iYplxsX z(Z{uxEP+hN4E932uSoKAn{ZZK2KA9cf#=4A-_Of^BUINBFNDkAW#T0wNgbBbbCk29v?>c6kD@C6Qs$L zImSTb=-~13PeP&DSr|OH+ziLVN70vz5$SZp zc{kc{v2(Y6ao*s#;8j+Mia~i51A9NFPd-iE7VnP~k)k{tEDt`)`NXzG$~A&LD>I9e zvJa#5OJ;QRBm@6P4)8#Zo2|h5yNmu-g|EeVq`mcAoZ60(8C?=~$a}sjJatOkdOQq@Zc~k1-Ul|8tiHcL3Tc)* z3*G@0&4@Q*3aQ7=Q(w8SzK~A~M(3VPT9@3vW$_yK2R$nucd6y>hvl`cD^3OJm^;$Z zkSu0QPF*n)ykGeoc`RqmPBKC zGfh1`*?I|#(`3-pM6GAZxL@(-I@a3Wv&xg=GKjD9hfO%!E~)4lnp1IWfMRdC6X!D1 zVw!v~z!)J@7k)v3ccv5q?^D;4NhC-GPoZd$BuO z_F7pAJsN6QSBu_IUaV-Rg=+jAxJpM>87SXk5T8fYt_E8zNN|YaY{>E)b1Mf8Zc|AM zRCh-VDP}+k<$MUd!a{*#zu8M={+D40yd6toB+Oq7vBmbybJ(NAX-FwoS#MG1o#acC zBk^OAN<6^aMjO~AS#}2o-h{6|OnYYU)m-Piq&J8XF{1!~YBilK?Rf!#K^KU-dcwqZ zywg^;%A;6%&=97V)jp5VjI_Bwm=0dh7bdG^v(%+;pI%AguB0c*!ar%YgxId~q7YVub zGtZETovV9qv>~20wW&pGbPblN^rQM|d)ys3=ORa+EKK~lEZRM$BX*d};!3CodksT^ zwkA$PHSfMg=9$8yo75OdTaRlg6i3^VctL`pK@4LyWoB@H1u~hWo_X`lbVm^{h%q;k z`k&80|Af8z>od^zlffS%NWWH9|6kGwfApMY_=TtOvuOl|pD>R8J%R*8lm20|@N?0m z@9xvT9kG5p53#bd{_J_EOLf@_;DLD@1K}j>GVG`Idjk(BKe7^Pq#-$jq4+-$F#JD&5;TlriB=)^M0XmWhzB}LAjB0 zIUz--q;pD=*yo4@i#_aNtM|GN2(nj^$E)~oDIw#VoN=7(iRY)|lU8uK!Wg)fYLYZn zGBg&B7K8w|wD-I)U>mX4YQCLE#gy9$f3QUsY=rTHvi>$)X&rI7N%` zfI$r@B$^bMJrLbLzM{nCxcPj>oRmmRDPZB>yqN9nUQMxg69pkQG!{qg|NQi83ciK3 ztzP|AkTs zbsIOG+UP4)q|ZT9g}qxpiAAylCDPBdh;~6~hl$XF^yT*ak}17g?Im8i z!NwfP@lHGC=CJfJ08&MmAU$mzC07k+bp^aeg;-^tOx&rH#u6@A86JVT$0!?}o+~c2 zGp`N*Za)XQVde{QD%`OTra7fGO`hKT$sLB_^Fbp*`41?Zio0wndKK)KM3E?Vqj^N} zbYRIaiT!0kI$i8W{F@l^U+1!Icr@MJz@qELPT66^wg&wy#+6Bm6?q2GPMV-ZMBc7t z=e;>n(^FjWC$1!6J7wpS(AU-{mk0CP^^5)?hd| zF@eni$5L+?l7z1hxJDEJp^91fJ^}y}chfF41f@}&QP_k`fcucfs2@~o> z62g>*>=wSl#Uhw2_bHZ~kaIZLtFd7Pi1kVDQ}u@erVEClYu~*Zd}|!zLk?OXWPDvk z)XvBxtJ6;Ur2w`X)Wk%(SYdXxtaH!JDMTWx6!Ix5)YqBdWH1BwD|JQwp0Y!0H9aV6 zr^c?Zlg8T%PX5+nBgx(ZoNQd7dy!Q#{EExDbvDz-k0%cXg{tAg^s6Hm9gtgcaIV7~ zPsv|xBqI9la0eW)zhv0B)Yr(4i4v$f-*9&ly1m37vFNF2UG`EONy&C6TGLrp(4~Ze zhSF(aj_>t|xEs$$3O(y}w@J>-pF{E_T*f6(ek!~_OKXsER;A#UrULVBEA0x2(SSBm z?}b7PF#%ZgCntC^L$Ee+Z#k<17E!t5?V=}7CyC+s)e(D2Cr)(?EbKxl#LY{E6z|tnA9O=^JOg)Mp4ho#u`e#p^eguZ*wZuS9uR=nnsVZj#s+6Sa?utFmqF55z`)8=xp-piD6 zz?vhz_AA%3x`R|Sa~_g0RJ%<1*9&e>%WX%fuKEeH2lgyajI%zj zsq^^yupxjiBIm@tR0s>~&+wLmrj!E(H&Ddd?6`?TYEA?Un7s z{2qV&aNfLW= z2lM2GrY}p<`+WP^n%Nu&=Y-SR9439tY# zs5VS&Y)pg<-^fq^FXmfE>Dd5Y*|#cMw(q2~|COJ{_jU0%N0b==8v*bUV9Hql|1O{` zh8ZwK{#IPVz{(7m%KkjK?BDT%ep#`9vxkh|1`zNi0SGYwg9l)=08YoiqNE4VCk%k+ z7&FI@p3VPZb^hB<0+^rQr~6yvk@?#W@Y8wQ@6|xRUE{xO&I}NRfbZI0)KGulIeu&Z zpVGcR7ViK*|HBUL=MM1S(J;S#)IVydfv?q12Q<|qz8&C4N@qmt)hdaE_jWWYO$mal z$fGU1^>C>TG-`tSqYGaoOFz186Os%RfxrIhT<&6aH8jY^1zH1`HEA> zeKcFq2@u{2QWEaBcrdD#k%BkgD0`TQ?Rrx@PQ0UHhK={7Do(-&N(0}T3-KmfW3-B8 z(9)Xwz}Ki}{XFgQ3=+b`^ku)Xtc!LAyQ&#o>#H}J)#Boa8iye@1vS=M;2Iuq(lh8K zb_wmE$GT#$PMO%&W=K7+j07kt(jhcMFa!4cGLSVotx>AjQEZ5^VVLpBm_~_;eU6;{ zF%ZAfyXW-v?m~jRbl|%7>Q#T${zUn;O-Im%j712``j+AQ)v5F1#fvV)s9Z#dH*RXu85SjQAIBO|yfW8`eL(@6Fu!tbnETNgDH zd@D#a^|kSBic&dQDF=sxm`Twi-!rlafoj1RS~7Rd(kYR>fxaU+5xVN9oKHk>CJm+5 z;IF+}%#A20AS~yU@I*q}zcjxv_ zeGFexQIgRpRvk}ueLP;9%^1e*EN<#a*OM(kwM3lkRYv>`5+N(|4 zmuTEO>h8>ViIGe?GshzeV*c8Jov|VEMevt0?1mNXRKe25ue6^~DNPMl*s%&}klNbZ z5k+JQI!bz!3w_K=lS|5rjnffIY^FRgAD>Com5yTE(m`=yztL5QOVux0;ew*}N%Bv~ zXou#PDUYj%=}EIjL%a};E#8(<#Ih{^8TX z8_UD}cw7V>%UWdlmrG?-9&ouO!Ku8V==|E`@^#+emjll!EEwp~L?mSv%2|;w<3k;mvWYU*KrL@OO_}aOe$f9r6(Jf;k^EShK zzb`06_%lc#J?v10`DK&<%(FyF3~%NrdQQo0KAAyQ$PXn1uby2-_S1Z*%^$78Zf(cA zFlN4?YM`0Bqc+0FJO*VYS|blyUV%sILpR@meF&{L^S$jEQZe~*zGAWrQ~i1dceZ3l3+=|Ii86@Kn*(?NY5z?Q^oem=)i#n|>gT;E0uo1}$_*jV*Vmope*e>>TgyYy(Haiv%*kdGo2DS^^ z#C@r_e3e%_c45rEh00n=cE<4v$Je|q1#)>@&hY7-Qi>Ha!zS>Zy!&XOna{3E*Z6#L zC{WS7At-1JpttwhmZV0D_x3D}>H1UkBIE3vKP6DmP zpGGs ztlimCz`E9eA+oN^9Of8uctLYU@SK+xTO%b%D1Qt}{GDl|vnyp4!){7Q?RkMnZ|8`m z=hq{FU`Q%ZK4Z|d=$7Uy=fhwP&aDlM%{Wii6{>>~a!wREVUqwEBKs5p9Nab%)Q*!J zkUAw&XTcg}rA0kb6ukmW%1N2ZFtYSQ?XMMT2DVZpd?sZF&2^&K=fgy#Qq8`u#t%eT@_g> zy&O*~*yEt|Qn%xbidlYYKg1#COIZPGsk70Gx-B7|O)8{>R7C{1>M zw+;K!H=1jqRDLIfioVL;V&lZwl45=_bj^)`cx>;5^M*Tvn`zIp` z0J-^pmQlZwf`QZ4_hTHxudHAOAaVO$Ua|fvr+$Uw0qBfhU;i%Q{@Gmb```NQ#PnZE z0l*cPmW>GzbpWk{mW>{`T1I97zRM0c3bO+IV}KO=^YZH79$>#;=-=%mK;2+w_;!$F z0ethAfM6~o&|5|pfXv7WAY9m)SpHX1;K%3p{>zbMVyCC22NL|O4D0|o7ARk20!rc8 zn7+Nj$WF@$grNV2>hJq9`J1B&;1U5E2!Nbs0S1x&8)lgaSOfrXh6zAk18)JPmp|Q8 z0duQwoaJw{WmR#xKVw4y^$x7tzu8d$Vhq550SYuA1DTlsFb*?dfX&1Pj3^5*>kLfH zKM#!k57lXsHRYzF;W ztz=P_ExmdfeigAf=b86>-3ms7F^=OhVToZg#f9{1F8FtjCc%XZNd9>z)q7Eow|jEN z9OLRNSQ4u91zVONVI9q@DyeMySq2R*D%AT>N%9Ce`AtN(@?&r{OS+#MoL#$hN%B4> z5e<~e*^F8PaJ>ri2qlX&I3*d*ISd$n#SCTdrxO_9M#}XRI3`75tvd}1^lcKL<1b`p zEU6||ipkTRv2=QC_Vp5`8w3u))}ME5eGM2JLlC@q1kvAy!qO-yeXbe5Z;B*bU$UI& z@o^77;s_bt2UEl0LE*(+#?JGOq3wl;WOo&N%()p^lecp(`N9_1$27qP8$l0HI59jY zv$``Hp75BknsJTAUo`y>Z@OXJg=A6M{2 zhUFC;$OkM<3uO%RudYZ*iuUr4*j92D<;tZfs(4fy8JsF}j}{-YW}Om2-E=YtiPTJB z-qUbP&KLKcmFd1YNaJ8beA*7pUW3D2MP?KE32JhVN=6C!(S%g)SweWXYMM>LEI^7o-T`0(=!+V&hUEqEXN+zR@BRv+|{Nf)RK$>Np?$d2Pa@4XW%3oD`z%u z)W;x>;8`jCTk$Ntsn$%&;J#5s_~g$|J@Tq<9U- zyl!S95S74I==}P;8Z{csGvbZz&vu%UxT50p_`;ReAJ252p7C+@v`n*g&Rc|wB(8O3F}&RN#w3+r-?LF;ef(> zLf*>Am#eLH4qdtl>(m{D5Vx-&-$`+W(lL;R*153GHhYH!Ww*Co zcpLp{CQGJXqJL_i?5fXu>!-a4n!qUH^b7n)PA%6{f zyo1Q6RT>@m1X@Er#a~iS8wJsnIRaF-&4=_LbCry-Dw-gYTP0N{)}9OuQ73(o(I|QW z6(%r_qp?3|+rMwBkpffGW_giVimaF?@7P+Y9mG&$41v3Lpo=iYC-!(;Gy>~&wsnpP zXeaDuJJ0x3tR!U8R_3MfhGQ&G6fdcvW&URitV-#TP5KLBv$0*RGK9fsCwWxHlRPs! z9HM(vEvTEhgN|1I0Eto>`%$KRVnnVp+y}cn|0w0GK#bRfldCYXoLnu*xN|}T3cWM$ zuk`Y=a33OiNqB`}0;X;7iN#@v35Q5OJ4}#5Bc|TAd?72+X@5!v%4r}XreN>4XGC!q z(wJ2=pK%CLHIMmeYOPpY^v%3OPnFc7^u;EOe!bUZqVbfWSoz}++>3vc;2V;x* z_y&hm{H{R-wj=c@I3kA+{gXYDn*s^eP%9st5~)uf2;?%G%XJQ?4oOCQ`ljs=XViV{1v7hA8N8zD!2>$uhI!a-C{hA3HrtM!e6^9D_pn?-)Yi< zcw;UXXFci9zTC?J9U&9-Hv=J`hZ|1=32Pg5AF#FWi8oqicC$7fIWTTqI&K=#4t>Zo z{>pm+j}MF3_y~z0h}lec+nDxYUclMn?YyLG3mybw1Zu!GQR!~^##psE@`~D86?3lC zDQ@zfl_SEqt;6okvd|o)Hb+gdgL1W6tWveUVIStTVxne^1O1%)^3>ommxuM?#8ec9 zKl@dV-<*%Pw6@dgl?ok9gc?@+si6qYL1R|W6gRF{WH@3q(*C`=o3~lew%MaMRod5C z&S1Qz462*%a@(Ha#9{Xh@N3UA{MQKh7O_pn8g4|b`~|IP1!)V1aTk#~!@f(W4n5@y z`ntE>WWyF(?SOUj$BpKUxh6cErb;gV;9dvmZ7wHJ+HkK=XJPJc4rYwJYA0P~H?y62 z_hcUUS898@z8(ApNs`VD%x-5Dnvc}zCTI(v3>mOA!UN$CFXFOj0;C|_XqU_AJBtF& z1-+3-1D_7(G~9mZozk#8p37%;_4NuDrNp!$rpvt4p0F^xepaaWG327!cR(}qJ~ZN` zKP#mvR1ZQ*cGP3kw0il7xO?4H!fO#*_(gODUEDZ1X|^t^_!)p)1r_O3=xvd4v`}48 z-sf)Ku^3KZpHpgyFb=_%qpM~D3Xb%55Y9UNCpM>pBH- z1(~eI;i7s#IVXQUo+2VmAP-V_^rU|xl3Y_`Zu$M3QeJb%TO%!Va%UUWu?a99&>V+g zOW-Be;;H9b_M`_`%P5+)@1D$rTIas>b>HRv?y0*4|9&6Sg zQ`O(}(f7st)A9<)_y4f=|7Ckd0QSkk3@}Om$W#EN`R`wyf76^DkY|6vmty^+y8FxC zGXl(Bb`JVKe>xDO`iW0x05Y$@?EJCo0IutY)<0;&f8zNj#X|avm9mAZ>JH$+~F!fjB`ay-5@HK zZ7UWh7uHIkzGpk9v}qE{HPMN^ZI%l%d7~jHizjLGnUxLw;v+A0ynIqHdc=$up0@Kk z<@9-p+MS1c1KBvAU*eL61R54vt^t#YkJjWzOi6sv6H8~xa(uXHC#||!rIOyymeUi| zb}UrNCC$d-yA4_Vx2?TOGZ))L%3uefL=-Y_s&pQ+!}A&oq@EH>>@`J7)tg|-L+`&! z2lG6*QfzPytH~)hvAk|+sa%lL^%Nb@2p=E9a8|giff(5T1hsw!%St}AR%PQbGSrdR z41rKKHuca%+!MF<_$E{D^Tm+{x%8?(jEr^vQaf5`!GbHEn*nL}GVi^DKT2gT`4b$Q_A8SaQ#=&^lNfL=OZ#$#6Gua=0TZ9xF_Aks zhAQ_bvSpbxQh7uqJc?GtJXy=Hj0XZfUAz`;-bX7}K2i5G8@J#ZJb`sPt*r&lCz~mC!ndbjnCMixlGE$9^GElzj@1+1(PPf(TG3}k-VCTMiW3W}uR_G(^x2t$SO6r7&FRbelqN$E~75sMIk z?S4P_iSLC+5Tt&TTwP*}ZX~=%{yN`<*DZ^2C&&wsUV2+-vKbpMeKB!6p@GI*VQ^Yq z0cKPmI(+EQk5JFiFzB&N86V@5#gMqpN4{oM?b|$`2MZIZsVPQqyjJg~ghm%~z34Kn zw4ewyp?|L*g|Y2ov;AfO$rz4(^l3HeC;c802YW%x&g3=AgfqkVHdsSW5jcN}cyEPS zx7i!P&;Z_!R&U+sQe3d2HDyS>Ul9)B-qmtE-AnjF^hGYRr4O|Dtu2DAd(eZnReBnp z5gFH4>f>YtwtmR5+7x{;)e7r3N7?=r$**VLMHAlB}a7{d-Zhjll4oO>xo*>}(SH+edW8^Z0Pv&X~Q zJ4-<-2n+&D((p}uT9R?9;C%;s&21;bzKFV$W3i9jM6OM4yF4derrUAuQxaK2bYH$q zM!F?j@N{#7*J;+#Xw<;1Bk&_hfA6!@%42)`^yUngb4_+;)%uYRKM9P0331Avz_vU*=M0BWDyfYyVWv^-f=r z1wW|@&ePC`o#l(2VJs!}ZXU}}0Ta_S8lo!*2V?y%q$i}Mxq>rNa05bQGyxyPsIKpB z*@0q%_op!>sp`S_!_bc;`}(*j+qy4WQbs)5thcZqf_pe6>uGf%lf#7rdNrrF)zI4O zxlfbaTFJrWWT}VUM?C4bc{u3s1xdfAxQ2CDOwTr)&9eHt24Yx?Y-8Xow?o$^jD0b7 zj(ldV>0@Ja&H6c#?u+3A^lBio6+&d}2bd2y#TIsTJ#y_&X06lgN$*+KNuMclm@Z7a z@la`me@3)`e6tK!KwlFTAeRdkTniGrT_uIF`Lz4 zHP5|G%^#^XzdLL`v1yzcze?=p{<0E(5P>dTS(uzH4VmFCvC6}Hria|pqEER&$ORBfE*zp! z+-jTox>q5MIpL^GG+;Yfj-NKoHjO?>Z=D~kk#(J3KZq#~qRzZ~^2uZBQ?}BkygG*bWM$FZb=6D(0l_;D4@f1(& zjyOfzgj48)r7PG#yw#a%!%>9AYaIe169Wv1W}6fB`l8p~TH?=NzJ3+HB|Trca?--t z#qBjT6pEUT%$XQO2kMkQd+4Ntp)Lfuj>BNLwddJGpp(+cxyP5{MetaU$(o ztQeNSlC)crYYcrc+1r@*V&h)90^1{Hr+3e(&nV#gh<)Y@=x){VBh{J@4_FrGqA;-g zN7n_0@N_ae`GmE0b4gU82#~8R#p3#jtvo&iM-wWDGtw+p5N}4vj`owLC;FQ(!Y8V~ zbo1@^+FtEYWDjB>@4<@M1=kxq;Rvk(6ONHJFe~izcMDmk7fr=WTYW>T2DUx>DXyS( z-&<*x_`Mj+B-xp{NLoVn5;f(6UEKp*^!Yo3$F`z$i~L8h5!LKt*$jF(uT%wD~i0h3Az7$2|u#9HaD)9Jse` z)3yAA0&q%;s8M-6@mDoAdAStOlix_e#Mr+5m>W6zT(m7s0>L58n@YOCg=9=;xp95p z>G8?klQob(OE@5b_4`TiuanK+k6r&P;l7_Xx+-7NkO!E&p z(VrAb-&BXGr7^98rKyo2t*Jeoft9|YrM)Sgh_0TksjI0KkcD<|bv31v)3r9VwWIr% zl;#%~=Lhm!)&@p@aHjn}AbgKZS768icY(Qp_i4Dlq(sKay z1VBQWg^~5Yzo=hDu$hCop@XBLC9SSLt)3yB#~UjvJ9|2NLwyrlLu*=VyFaeGA7$O& zy^3#|9;iS5R%Xr$u#o{HCkCKm0|-O>*E92PFXE3~|8pSf=c5q6tttkf-kh2FTZKGe zJk7`m@CO+H^$rwF{BOIiZ*6X6Y^wiP%jl1){QKto(;^fJ{@nb>#rrQmo%!49 zWC0!){nMxacpLoJ%^84O2T(`<=jMM52L0vGGqD0OM4(FK&&_{o;u!%{Iy=)}M036e zKmX&zf9I1j0>0&cy7nKp214!q;v)DSu z0!y8sHJQo!oElon%2C?N5dl{n1h6gn?Du#cHmRN#ySofeV&~uHrPschI{r}WI?O&YkCvrvr&K?CKKbYNPnJK8t%r|fn^rdQ>pSC0BcUXYk7X29wON=GeeFu z`%rn;((tvVJItKMV&U zJ!8u!;Pe%?^ySufs*7XdW2o@V$`$sku6og>UjF_RVu(_7>*-u#=q zE_0)6*+cE#HZUDWdN9yKb1$P|&%%$7ukT9*@0}8#w3_Q#nVEgfZ->#Tv34p0nY*X3 zX?lI@cyW>EDZvG@MaLI;pAJUnHM@j(Wwqs2Y3+E+G<+R@Yz_+cz_R|#;w|QAdV6xn zxW>RkK>d=G&;v4?m-+!x(`LwHX03IQC)%Y(?8GxYDEfiB%v$(a-mf(b*SufjGfo1Q zP@g_Zb6L&H-w0amQF`vs@Sh_!krdo#)^ZmBZNY~;$LDFf?(&a6S-Et3?pTPDK9Z`$ z*E)~4oLB_3ww$EPJos7hYpTa+55lfj@Q_#akgE5hBAg^S^pu&9;hECSeIp zc@f`>Pv@O$MF*{tv)ZRFzH1<~B_VbxhtL9N_u0z%MH3|=2aW4Z_ zh~e{`EibNXYpX|kZ@_GWDY|4(qdkm5+=%4#J!y=tR@M4>rahi}g2>Vx;@lc~XP6m| zxni@#v2iJay4LJysunVS39YG{HZkSM?KyiT40CfiCIjU*)Eue4-ZUM&ePf!9SVt3{ z=X-_=?mMZVc8qzEu**a)5YW0eM0%ktX!Ld7X{(1Ra=1c+E6!ehqE->Z@ItA@fv|?Cg830LpIhF_jtI+S(m8&K zu?*}+5*(xG4YEjS-!8AT7a>#|Su~clNgg16B8>MJW92VfJ5NyE28_vPK*a zkJ5@2sw2-Q^V;m}z|G|;Bsj8+(CChXiFa}lKoDbchxSFor`HjA$a0X!o=svq2)|qd zdzrIo8K?vLCFY|bUv>dkjQVrk#?P%{Zp64Vqe%&dtmZu>}0@sR4KW&BgTs**k_ z(v;E9HDpIz*9Mp5w%}=tzG*zwU%DmnHObx=6zh-R@&su#5p{%U(~aHPo=H)bA|%di zYho{DI4e0iSiRwzMA5`v&F%a!fkVQpWcA5brz^ZH-v$Y@c`;B+ce4A9>^)$$*PMle zL7LNo=7^TJCDf7}^z8mKu85fyPR4WYPe?nkw8v|4ASq|H#B_chRqgFjZ;#Q0xN~dg z0|~@9LecAyNC)QhNWZX^$rnN=%%4)|-p_s1AwYjK-Xh7&E@QcjpC<3!`x1q!5;-L$ zP03(7(mxYIoAOP!WRKguv*Xb=6Kkb!BWz-FD`=M{q2!ep-5pWQq5h7qaS2Zx)10Gg zKqI6220kRp%L$m8w>i*rK?R=;W+FzVgBq#0?xAc$|7#y6wC{jQSvwjkxd!O8oaIa zq%ps7el*Dy_WX5k{@n-vyL6aWG;7%gso8h8Su0Oh?ohv!i4q9)MvP9s-#U%-2!I?R zsJTL{Gk7m@1$B0sp1n~Y)<{w~N%lm0?JC@M<6ZKLM!QD4@|HS(6`27~lCJ}luwGa+ zLbO{??_@YOFSD5K9nvcv3d3_P&_bs9M8oHz@a-XF=JKKW=?#N+SZ=~n(Y7%oV-A@& z9IyiHQBWBR!Qu6#vs`AF@f>;5_xAXQ#Uva$t*1z zb{F1Tksvp#&Y0uR{Q~j>wR?&v)1bL!U)u}1lhZ1sAZJAjDQD(&c)}vjV6Ycf`U3VI z@uQt5>PqH>TI;D$7u`2AQDX9;e%D&gJFp`)SKXWK6tM0jUjF!eN)tE1vYvMe+VV0A zuXre7Q8G*Oy4V68r@{@4{y*y38Qxaz-&gu#_w=^YB za96sfVA++X{7%;84WC{~BE*MOkejBm&8S0=*9)2ebiv4A_CiXdo)+WSY)&Rmor@#ccMxD?0d zBQop)M2zgTLhGk6q=EjWfH*qWo3AYKYU_kK=e_2{B2-5o(z{M9%Q=I2Ob#mM7y)QE z43WgFBMXVpS=QU!(PEOSFa29ne#X;OS|`+WRzd`m3*N?9M>8n0*xBxt7EbHN#}XNe z;oT`F8+q}%4=EGw&16+#Zd7qs-n zQdaUB@Hcg-iHH=o72URx&)~}{3Pid~En^ZTx=+n#*>X>62~D{iV6o45`XZ$YAT;Q72&CVMhmi}k`D_n)a?e8qFyE1Nt3vN{(%`*$mB6ZFL1$JmA@+9Qw zI1zT`*Pk^N13x?(q6D9#eS{hkT9Q0^ z;)8Ijr=P!k$kK{a&pM+X-G?)t?IyUc+>3AkfUB=IdRrOwx#CZ)HRfilVxViIAdug1w&syIxV=TA?zhGlI%)jO2pt@auBiq0EJ z@QMZ;Az))0OG475Pa<6p9eyE`ywzSVD!4tH5^sW}Hh1U;IbgVn!IueR%sE`!^ja3f*u;d=P8vyd6Pr|dGg z&qvde_(hV!d7CgDEysSyus@lk>AA9*{sgcMg%3xnwb>i3nl1)^fSdp?>oo7+$DSzb zR|2tO3-;ve(Kkzlv8o-XazQl;(0z9k2V{Jf*DU54!iLs%stclUWDgB=V`MW!9dxff zJB~TRhK259UjS0NNIdgF?S_q0I_|XMr+Mldd3PVL+fz%)KAZQ4%zl0Mg>rH(_fH-H=Lb8 z3D_7UH+tIy^LLzUsw<)-IZ47z2I`+ktPbw#}u^hD#dPu;%u`jqOZ3*vPOp8K)&toDBiTjzOoa->rF~W zX>hmm(xZ?0)=()HB)Ws(x2FGT7#_j}U*y)3MXN% zdNvk4GPk9X;d-7ibg{-j*(`3{uS(3hNu}%$3LhJeEQIw;EsWenuCiJqI520%WC(#_+43gi0XD@_^gSv|8B8!|2zl_qZk9LShXjt)>uAsT*3rULlY3BX z*IC(PoXcO2ck0Qd3h6S_a9ti5LCGS{q5gaifelUeTt7tDr%~$p$%nKo_GM~tamO@| zuL4@VH3%;_S;INyJGg~kYs#ce|3_h$0>#^xw2K?MoA}Q;>&LwVIe^3>)GTLL5%Z-NIkgea$7 zy11BMUd##(+6!S{9kT$e6yWB9z0fdR3f6o6q8XDQr)20pdnA?^?>$I=0xii_KURO87Xx7aZoWmv+zG zoIVxhZ)|FGM~xU%6js5^Wk51tU)dvzjRGon zeEtJeRXNcf!_*31;fya-*;?d;5MjQlb>G0@Wed2qhea%+Wh|X`3T$c)zL{RwabEP2 zBoFrNW3J6gm^4f9W31UwzEgOoFM39nR{7QuDq3t#o*9*x+QtxR3%LkI&3CwzsA3m< zqwVBMH_l=!9IcRZ0dkcJ4H5fhI&bpr$(cNK-Gd9p&AA=4m!uXkt7}-W09>vCtp}TD zbb?|D21xWD%^ds4tSpg+zLl_@8qiC{6URBq&7l&=YW3;X>8muXl3Y~5)=hKRZ=3zv zE@Gd)3f-9SaipC@1c{EVzUmkUerOwh`*w5XKY{ACD>8OGSy-->N78_ONI_NkSdH!v>~(K zWKxsb_Za6H@-iDvCaO^=m!}b(9UnrNmW&3fQrQGuRfNB*a@^y3RB(UnAyKQOxZJz) z3IUL++_Ixk9LHb4AjVJ#hsd7QFlx=g%*i*yoTVrFVq3>5_LHS33A+CHDrQt&T;^Gg z5kF0UC===sQg7{NY^JuMH()cDV7_%b=pD4F;vMk`hqs=ZaPyPTAY$Pb6J>8yb%?3m zQpV7NhSx!0cDk8!U6y0y(;-Ck7x-duP*?6P>99`BD6m3Szu}>f5M@J#;Oe!F1U(ab zN5<1|8pTzZxaIM<98>~Sr8?Nb9RJir)M4j6^-K}O)Vjg<7^Em4QAgMuv3eFk=wiUJ z8Hb-pJZ-z*+xdR%j@^Bd$LbXwr+8E$k~{hkb#;>YQOLxloUJn}c@)Qg^nI`W+trS{ z5c;)my7V&z^Bo&C!L|rXPKsdOQITuKS_gUil#O!ygE zQnG%B{{zG0(hu$OODo`@#GK%sQ#@!Zghp9%EyU|be|a||8{t#*SqR32P9ymsy)IYa z5ou4*=(M|uhE)Q583jP*MYddiTDhqAWDg?N@0QvmHPR@-&Jc`&PXgSm#rlf2%VIk% zGf3B=?#&znWSZBOhmb&uh(7(!JG+)f80_-#d$>31|Ngm zqYKOzR}wW-b%CNotO?SHI+IGmkuD$9CNVcHIDI4}JXsA=5+Z4?ozuv7>aqJ0T=;E4 zpaRR?!o(g6?>1KyptVXnIP#%CsfXL?hVTbUvGep48z8n)mJxU&s2QJqU~(}{K|D9! zWyS9nE5%alll@tqzHzO-MYRXLpq=V9L5|TmlrP+xdPIDl_e3u>0kF&C9PWj#L3kL@ zzAL8GpNx%h%A3GLcfLV5O4@-4c(MpJ&X{iL3`81e}mDb zv@XUpFc#%tb% zF%((Zcih6D>l+(UEVt9y1L7*a5vwu(1a0zs%qI<#U-cc#sWcQ>47WH9n3SX+$@t zcQR8ciC7?Y1bL}s<0!MDZ$NcGQ5IK zIqX8Q)aIZ&S5u#jQ#Yw;$2HhVhUp3`13kmEY$TZWvju=t2Dm@6G&!Mtsyw`2)nJyJd5z?S_xE131ouq2gT=$vX$K{=?>pku9V<= z4CeTj3g>{P#!xC=A#I^-xXtz40>yepU(u4DLIjUNhG#(wj;cwY#iM1aI}pVyi@Vd~ z1#~?1pt~4&j5Zyz)4)hRc^}3qrWoO}&!B~S+gK-x!T0CAZh>2Fqg2v&aI6tqBx z3aftlRff4+Au4)*Pc9w%$!2{t*&8K1gg@w4>vN}D|mMw!x<9lVyE*CDU+@b^vrQa1jDEe3&>w9Mugy`ZLsz98pB{g0P>)V`9o9d<8D;L-s^q7LnpJZcxsiF zEmO77ikBw!j>IHDLf^G=vuEN~p^E(KJ#f5?>;ZFIkyG1hsIe_IculON5HyRYE4Hu| z{kewu?(g1$AK9Eq917)Pns9?LXZXhtVlfqJR=F_Y zk9PB4K&Ga{S5(q(JVObU?nBvQEo%eyLAAsRg8Gmrl(+TezvYg|q4G(mz&Xxm7VLW? zw)-@c6XD39cQO+H$k*JP?15c~gfMQ~s;uEp?QT~tS=Xp*iy!w>w?C-^TZ|aN8R1k9 zHilvMmz(Debe*o>(Sa>2hof6nu@em--!7s=;?i#oqW|npx#1n^x&tM*>NEk$)L0VT zl3y+{XXyU($t}n>7#GgmV$-eJ5-yYyKE*45r@1Z_ClZlO|3}M$!Cj&O1EF-;3XMzt z#j=p1s$=Ma%zlzwM`X|=+pF2~y{zvuGGrcH{dqsR8pf*9)|CG#G9F7&Qsw8@>DKE7 z(>n*U=~cxq`0vZfXAEBbqFG55O+6UD4q1Aaus_UnmdsV-v7Ha7#10dS*mj>&KR$y1`ljJUs@kR> zrHfwyE3E4AI<5g?P2shjG`;&^Y=ZzH$-?Nu30_Hh3TL-J4uPqY8K5zWNMSP{eG0|r zV}lX9^=dke@QzgUn_0aam^(1dlj%m5<^Z!eD}GN3W7-fuB1hG5AU+(ey-|of*_M#B z?H*h-fAXuUV=QjNhn@K#91e^3X{w#&Qy~2Fl}WE|6XO0wrVzuCG;CmZd!Ws8(cg8? zcnh{~QNOfWc>B6Y4RTcS_Y5iLsn9%*NK9Hedik_lk_-QZl? zYBn7Xak(PKC5slfbGbiLDS2Ut9+u|5d>Al=nr6JTPB7LL>6tZw&rGxka>X0pZRS(r z8el>3Acbex%9Se@jAFDNNxX6z^ko~l*O&>E0c0ZjR|>3N(mxmGDSbOB04Hg>6*J< zFaK6Me;9>N6P}cYHv02&J*)2=V&HqWs<7@)5QlTnkhLGq%g-D77u!~Q`$;)i_2owX z#w?$M*L8lTiaMXqoI#7$8qdFu50cKPxwO>Un(W5Vm!^;&2~30){UArvh@0M0S591} zls<*rGL;iqTd&)~H3<;T_M;je?n}(voL!_B#J#z+=>h^4f z+}w)A*uyApOQ4xlShdZ+#aJO>vA1mtON6Vr=kj$JTb9s)O(hjqV;+Nm-I8_XF5)UO z&z>5taSagX9WjGZ<&Y@V&l58aO?tnQDl-dAAOFhbyjeB!vM&IDf&)KHEp!W~+uRnT zH4Q4^yfUdvo!nu1>9llCX~$7g_DoFv)3r} zt8E>1y$sdrisN+;yGBFrK!dt3v9J9u!;iZi!BiJ7ZUS{DOV&%h*Y@r)S7q6&i5Rog ze0}kehfeWB$-Cn@Fanr0RsLyYBQAs26nF%Nl+!)_81`#uu%T zFF3+2E?O^?WG}`Mqc;s{G|GdQ0VR%t*<@1|rav7tKctm#4@XM6!y@iD^|UUR67M-; zAZFIi^`a-s9-A*y`MIOJ=D&p$#y4TTQvz zLVq@V=KrAVkcN;QypY2BQNcyf{{t=090bn&vQDjM;eA;4Y0TtS_NE?AOgmkC8sL!k zN4x4Ly7Fg~*Kiw}tySG4zepv`7nijQ z=9L)WT63V_7gL)!AE_6m8F=3}Tzuh|rhsduAXKK)Xt$qQMB67w7(Qz9fl4d~0Y4+Y ziN4&?#9!A zfhk%q+s3K(OcZA7EId0)&3!}}%A*l~e7#eX|0+Jw7i*;@PBlv!Mm49)_ji3d#&W|$+hMmXd`%>5y+mMwO?on_-=5R1Njiv&OTf}G zB}@(hcv(AFgo9*4d;GjFH7?S)owRJQ98Bo+=!&apdY@5D9d|M68;oV=a&!dWmn9Nx zT&x}yC44&X8zi6ERy5EfsHB9Q4}+w;^Zp7WaCXI+ZGjlqqmoa$cA@*ibOiuIi>Tk#?@a;XxGeT{h+i)tb)r0 zpBX32ir?Nl;|<6s4#LR~HRMi$X`@Yu% zLI8I2dkiJb@tO!RepD)j1}VGJrh`4PGXk&gXtL$P&gR!^LrlI2UH&bwrFUX7*!^Lt zb*AU{p@8msv%dO}Ji=@QRGf$|ZcV7YCADd7>^dzIeA!jdEm{Q?^&&y_ZHsY+=&e2i zFL`8-MF;Rcm`;WrITVdaO}%)|#4bTkEh3$_HTG}hrOgo3f-VIc$zwZ0HM255k|yG>i)xsN8Vu1m7PoTi+i6ggod-@sfNlz9y>RK0#oEx!_8)t)P=Y zutc-Kcv$(xR;GZ*qb=!@I=-KNwg$v-h@}+?v~VIi=a~l_skY!J*2Eag?8MSyMo{ZT zNO)P+9NJuXXWeq{g=l|t?Yeh#I;EdXBZ=YM`^iCj)%VbX@nzVB?jiSxF{Y7`*xZfn zc*0~uWd~th#C4!vo%gdoRB)Q?;{wJwc=H32jQEhGu#A%V{M zb-Ua-2s0boli3I8$ei1Z7G+|-PbYdmq4I#bEq7So#a6wtt-`>1I5W#ArEOTO<@=&6 z*ykqP^7Zq8OOThJoplsC~4_)hqTfzIl@|L0F5D&jTAu--9^oL%XXO59TQ=TDrcLW1}^w9@yI+APv} z=jr1QEW*(-Q$(I~H_I&O^B~{^TRamdpQwn)`s9*Ypi2T6)WxIQW-M}7y`Hg`g+GHM zm&ipK~3R9{SL zd`|{9+n+AZUeX{*L>Jp2$(S+aokQRc$gQ__EGuF2`--CJ5odqkJf~xtrJ!p9DJLYm z)vZ!?;G!#$@R@;#&10cS_T)hiBZ+3fABn=>d+95~GrpltM#B(KCWs)9 z=w1cD{X9dp;{0?JnDgETRA>uYbWV~x zndwK-r*W!YUi_)7mrMq>5z$k8JowIV%2O87ok!Hee5Sf^m6~)4szrQ9BZs4O1|{t{ zwQ02cWx!H4Z7j*|wJ&9emu>2*1a#a`4fKI&nR(C?BOd`E5bI-*`-V)G1nvgL@E2Xm z^wIuk#EvEgL<91~tHl}Jz>7)h$|7<+y5$1|eBRGc{?usnVo9`Eh0;HV_o_R@!q6y8 z2gmfD#p7Z&Nv87`9HdC3@plu3;n$^K6W`m#26lJ|0bV z69T4R@m>saD^oBZw9lR{Wp*E=78;4gGBQU&e!R!n&4vlth<}uRP09+=JrWat&P#Se z@v@rMg*u~w55|$gaCCWG{-VOfcW^Z@ZN0p$fIKh07WMctZ^0djŭA8|x_&W_G_ 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�z%pnxHyWr%993+U^V}rl2a|aV$;GN?gG9u4 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 % pdflatex compilation +\documentclass[a4paper,12pt]{article} +\usepackage[pdftex]{graphicx} +\DeclareGraphicsExtensions{.pdf,.png,.jpg} +\RequirePackage[hyperindex]{hyperref} +\else % htlatex compilation +\documentclass{article} +\usepackage{graphicx} +\DeclareGraphicsExtensions{.png, .gif, .jpg} +\newcommand{\href}[2]{\Link[#1]{}{} #2 \EndLink} +\newcommand{\hypertarget}[2]{\Link[]{}{#1} #2 \EndLink} +\newcommand{\hyperlink}[2]{\Link[]{#1}{} #2 \EndLink} +\fi + + + +\begin{document} +\title{\texttt{cplint} Version beta2.0 Manual} + + +\author{Fabrizio Riguzzi\\ +fabrizio.riguzzi@unife.it} + +\maketitle + + +\section{Introduction} + + +\texttt{cplint} is a suite of programs for reasoning with LPADs \cite{VenVer03-TR,VenVer04-ICLP04-IC} and CP-logic programs \cite{VenDenBru-JELIA06,CP-logic-unp}. + +It consists of three Prolog modules for answering queries using goal-oriented procedures plus + three +Prolog modules for answering queries using the definition of the semantics of LPADs and CP-logic. + +The modules for answering queries using using goal-oriented procedures are \texttt{lpadsld.pl}, \texttt{lpad.pl} and +\texttt{cpl.pl}: +\begin{itemize} +\item \texttt{lpadsld.pl}: computes the probability of a query using the top-down procedure described in +in \cite{Rig-AIIA07-IC} and \cite{Rig-RCRA07-IC}. It is based on SLDNF resolution and is an adaptation of the interpreter for ProbLog \cite{DBLP:conf/ijcai/RaedtKT07}. + +It was proved correct \cite{Rig-RCRA07-IC} with respect to the semantics of LPADs for range restricted acyclic programs \cite{DBLP:journals/ngc/AptB91} without function symbols. + +It is also able to deal with extensions of LPADs and CP-logic: the clause bodies can contain \texttt{setof} and \texttt{bagof}, the probabilities in the head may be depend on variables in the body and it is possible to specify a uniform distribution in the head with reference to a \texttt{setof} or \texttt{bagof} operator. These extended features have been introduced in order to represent CLP(BN) \cite{SanPagQaz03-UAI-IC} programs and PRM models \cite{Getoor+al:JMLR02}: +\texttt{setof} and \texttt{bagof} allow to express dependency of an attribute from an aggregate function of another attribute, as in CLP(BN) and PRM, while the possibility of specifying a uniform distribution allows the use of the reference uncertainty feature of PRM. +\item \texttt{lpad.pl}: computes the probability of a query using a top-down procedure based on SLG resolution \cite{DBLP:journals/jacm/ChenW96}. As a consequence, it works for any sound LPADs, i.e., any LPAD such that each of its instances has a two valued well founded model. +\item \texttt{cpl.pl}: computes the probability of a query using a top-down procedure based on SLG resolution and moreover checks that the CP-logic program is valid, i.e., that it has at least an execution model. +\end{itemize} + +The modules for answering queries using the definition of the semantics of LPADs and CP-logic are \texttt{semlpadsld.pl}, \texttt{semlpad.pl} and +\texttt{semcpl.pl}: +\begin{itemize} +\item \texttt{semlpadsld.pl}: given an LPAD $P$, it generates all the instances of $P$. The probability of a query $Q$ is computed by identifying all the instances where $Q$ is derivable by SLDNF resolution. +\item \texttt{semlpad.pl}: given an LPAD $P$, it generates all the instances of $P$. The probability of a query $Q$ is computed by identifying all the instances where $Q$ is derivable by SLG resolution. +\item \texttt{semlcpl.pl}: given an LPAD $P$, it builds an execution model of $P$, i.e., a probabilistic process that satisfy the principles of universal causation, sufficient causation, independent causation, no deus ex machina events and temporal precedence. It uses the definition of the semantics given in \cite{CP-logic-unp}. +\end{itemize} +%For program with function symbols, the semantics of LPADs and CP-logic are not defined. However, the interpreter accepts programs with function symbols and, if it does not go into a loop, it returns an answer. What is the meaning of this answer is subject of current study. + +\section{Installation} +\texttt{cplint} is distributed in source code in the CVS version of Yap. It includes Prolog and C files. Download it by following the instruction in \href{http://www.ncc.up.pt/~vsc/Yap/downloads.html}{http://www.ncc.up.pt/$\sim$vsc/Yap/downloads.html}. + +\texttt{cplint} requires glu (a subpackage of vis) and glib-2.0. +You can download glu from \href{http://vlsi.colorado.edu/~vis/getting_VIS_2.1.html}{http://vlsi.colorado.edu/$\sim$vis/getting\_VIS\_2.1.html} +You can download glib-2.0 (version $\geq 2.0$) from \href{http://www.gtk.org/}{http://www.gtk.org/}. This is a standard GNU package +so it is easy to install it using the package management software of your Linux or Cygwin +distribution. + +Install glu: +\begin{enumerate} +\item downlad \texttt{glu-2.1.tar.gz} +\item decompress it +\item \texttt{cd glu-2.1} +\item \texttt{mkdir arch} +\item \texttt{cd arch} +\item \texttt{../configure} +\item \texttt{make} + \item \texttt{su} + \item \texttt{make install} +\end{enumerate} +This will install glu into \texttt{/usr/local}, if you want to install to a different \texttt{DIR} +use \texttt{../configure --prefix DIR} + +Install Yap together with \texttt{cplint}: +when compiling Yap following the instuction of the \texttt{INSTALL} file in the root of the Yap folder, use +\begin{verbatim} +configure --enable-cplint +\end{verbatim} +Under Windows, you have to use Cygwin (glu does not compile under MinGW), so\\ +\begin{verbatim} +configure --enable-cplint --enable-cygwin +\end{verbatim} +If you installed glu in \texttt{DIR}, use \texttt{--enable-cplint=DIR} + +After having performed \texttt{make install} you can do \texttt{make installcheck} that will execute a suite of tests of the various programs. If no error is reported you have a working installation of \texttt{cplint}. + + +\section{Syntax} + +Disjunction in the head is represented with a semicolon and atoms in the head are separated from probabilities by a colon. For the rest, the usual syntax of Prolog is used. +For example, the CP-logic clause +$$h_1:p_1\vee \ldots \vee h_n:p_n\leftarrow b_1,\dots,b_m ,\neg c_1,\ldots,\neg c_l$$ +is represented by +\begin{verbatim} +h1:p1 ; ... ; hn:pn :- b1,...,bm,\+ c1,....,\+ cl +\end{verbatim} + No parentheses are necessary. The \texttt{pi} are numeric expressions. It is up to the user to ensure that the numeric expressions are legal, i.e. that they sum up to less than one. + +If the clause has an empty body, it can be represented like this +\begin{verbatim} +h1:p1 ; ... ;hn:pn. +\end{verbatim} +If the clause has a single head with probability 1, the annotation can be omitted and the clause takes the form of a normal prolog clause, i.e. +\begin{verbatim} +h1:- b1,...,bm,\+ c1,...,\+ cl. +\end{verbatim} +stands for +\begin{verbatim} +h1:1 :- b1,...,bm,\+ c1,...,\+ cl. +\end{verbatim} + +The coin example of \cite{VenVer04-ICLP04-IC} is represented as (see file \texttt{coin.cpl}) +\begin{verbatim} +heads(Coin):1/2 ; tails(Coin):1/2:- + toss(Coin),\+biased(Coin). + +heads(Coin):0.6 ; tails(Coin):0.4:- + toss(Coin),biased(Coin). + +fair(Coin):0.9 ; biased(Coin):0.1. + +toss(coin). +\end{verbatim} +The first clause states that if we toss a coin that is not biased it has equal probability of landing heads and tails. The second states that if the coin is biased it has a slightly higher probability of landing heads. The third states that the coin is fair with probability 0.9 and biased with probability 0.1 and the last clause states that we toss a coin with certainty. + + + +\section{Commands} +All six modules accept the same commands for reading in files and answering queries. +The LPAD or CP-logic program must be stored in a text file with extension \texttt{.cpl}. Suppose you have stored the example above in file \texttt{coin.cpl}. +In order to answer queries from this program, you have to run Yap, +load one of the modules (such as for example \texttt{lpad.pl}) by issuing the command +\begin{verbatim} +use_module(library(lpad)). +\end{verbatim} +at the command prompt. +Then you must parse the source file \texttt{coin.cpl} with the command +\begin{verbatim} +p(coin). +\end{verbatim} +if \texttt{coin.cpl} is in the current directory, or +\begin{verbatim} +p('path_to_coin/coin'). +\end{verbatim} +if \texttt{coin.cpl} is in a different directory. +At this point you can pose query to the program by using the predicate \texttt{s/2} (for solve) that takes as its first argument a conjunction of goals in the form of a list and returns the computed probability as its second argument. For example, the probability of the conjunction \texttt{head(coin),biased(coin)} can be asked with the query +\begin{verbatim} +s([head(coin),biased(coin)],P). +\end{verbatim} +For computing the probability of a conjunction given another conjunction you can use the predicate \texttt{sc/3} (for solve conditional) that take takes as input the query conjunction as its first argument, the evidence conjunction as its second argument and returns the probability in its third argument. +For example, the probability of the query \texttt{heads(coin)} given the evidence \texttt{biased(coin)} can be asked with the query +\begin{verbatim} +sc([heads(coin)],[biased(coin)],P). +\end{verbatim} +After having parsed a program, in order to read in a new program you must restart Yap when using +\texttt{semlpadsld.pl} and \texttt{semlpad.pl}. With the other modules, you can directly parse a new program. + +When using \texttt{lpad.pl}, the system can print the message ``Uunsound program'' in the case in which an instance with a three valued well founded model is found. Moreover, it can print the message ``It requires the choice of a head atom from a non ground head'': in this case, in order to answer the query, all the groundings of the culprit clause must be generated, which may be impossible for programs with function symbols. + +When using \texttt{semcpl.pl}, you can print the execution process by using the command \texttt{print.} +after \texttt{p(file).} Moreover, you can build an execution process given a context by issuing the command \texttt{parse(file)}. and then +\texttt{build(context).} where \texttt{context} is a list of atoms that are true in the context. +\texttt{semcpl.pl} can print ``Invalid program'' in the case in which no execution process exists. + +When using \texttt{cpl.pl} you can print a partial execution model including all the clauses involved in the query issued with \texttt{print.} \texttt{cpl.pl} can print the messages ``Uunsound program'', ``It requires the choice of a head atom from a non ground head'' and ``Invalid program''. + + +The modules make use of a number of parameters in order to control their behavior. They that can be set with the command +\begin{verbatim} +set(parameter,value). +\end{verbatim} +from the Yap prompt after having loaded the module. +The current value can be read with +\begin{verbatim} +setting(parameter,Value). +\end{verbatim} +from the Yap prompt. +The available parameters are: +\begin{itemize} +\item + \verb|epsilon_parsing| (valid for all six modules): if (1 - the sum of the probabilities of all the head atoms) is smaller than + \verb|epsilon_parsing| + then \texttt{cplint} adds the null events to the head. Default value 0.00001 +\item \verb|save_dot| (valid for all goal-oriented modules): if \texttt{true} a graph representing the BDD is saved in the file \texttt{cpl.dot} in the current directory in dot format. + The variables names are of the form \verb|Xn_m| where \texttt{n} is the number of the multivalued + variable and \texttt{m} is the number of the binary variable. The correspondence between variables and + clauses can be evinced from the message printed on the screen, such as +\begin{verbatim} +Variables: [(2,[X=2,X1=1]),(2,[X=1,X1=0]),(1,[])] +\end{verbatim} + where the first element of each couple is the clause number of the input file (starting from 1). + In the example above variable \texttt{X0} corresponds to clause \texttt{2} with the substitutions \texttt{X=2,X1=1}, + variable \texttt{X1} corresponds to clause \texttt{2} with the substitutions \texttt{X=1,X1=0} and + variable \texttt{X2} corresponds to clause \texttt{1} with the empty substitution. + You can view the graph with \texttt{graphviz} (\href{www.graphviz.org}{www.graphviz.org}) using the + command +\begin{verbatim} +dotty cpl.dot & +\end{verbatim} +\item \verb|ground_body| (valid for \texttt{lpadsld.pl} and all semantic modules): determines how non ground clauses are treated: if \texttt{true}, ground clauses are obtained from a non ground clause by replacing each variable with a constant, if \texttt{false}, ground clauses are obtained by replacing only variables in the head with a constant. In the case where the body contains variables not in the head, setting it to false means that the body represents an existential event. +\end{itemize} + +\section{Semantic Modules} +The three semantic modules need to produce a grounding of the program in order to compute the semantics. +They require an extra file with extension \texttt{.uni} (for universe) in the same directory where the \texttt{.cpl} file is. + +There are two ways to specify how to ground a program. The first consists in providing the list of constants to which each variable can be instantiated. For example, in our case the current directory will contain a file \texttt{coin.uni} that is a Prolog file containing facts of the form +\begin{verbatim} +universe(var_list,const_list). +\end{verbatim} +where \verb|var_list| is a list of variables names (each must be included in single quotes) and \verb|const_list| is a list of constants. The semantic modules generate the grounding by instantiating in all possible ways the variables of \verb|var_list| with the constants of \verb|const_list|. Note that the variables are identified by name, so a variable with the same name in two different clauses will be instantiated with the same constants. + +The other way to specify how to ground a program consists in using mode and type information. For each predicate, the file \texttt{.uni} must contain a fact of the form +\begin{verbatim} +mode(predicate(t1,...,tn)). +\end{verbatim} +that specifies the number and types of each argument of the predicate. Then, the list of constants that +are in the domain of each type \texttt{ti} must be specified with a fact of the form +\begin{verbatim} +type(ti,list_of_constants). +\end{verbatim} +The file \texttt{.uni} can contain both universe and mode declaration, the ones to be used depend on the value of the parameter \texttt{grounding}: with value \texttt{variables}, the universe declarations are used, with value \texttt{modes} the mode declarations are used. + +With \texttt{semcpl.pl} only mode declarations can be used. + + + +\section{Extensions} +In this section we will present the extensions to the syntax of LPADs and CP-logic programs that \texttt{cplint} can handle. + +The first is the use of some standard Prolog predicates. +The bodies can contain the built-in predicates: +\begin{verbatim} +is/2 +>/2 +=/2 +=1.5. + +student_rank(S,h):0.4 ; student_rank(S,l):0.6:- + bagof(G,R^(registr_stu(R,S),registr_gr(R,G)),L), + average(L,Av),Av =< 1.5. +\end{verbatim} +where \verb|registr_stu(R,S)| expresses that registration \texttt{R} refers to student \texttt{S} and \verb|registr_gr(R,G)| expresses that registration \texttt{R} reports grade \texttt{G} which is a natural number. The two clauses express a dependency of the rank of the student from the average of her grades. + +Another extension can be used with \texttt{lpadsld.pl} in order to be able to represent reference uncertainty of PRMs. Reference uncertainty means that the link structure of a relational model is not fixed but is uncertain: this is represented by having the instance referenced in a relationship be chosen uniformly from a set. For example, consider a domain modeling scientific papers: you have a single entity, paper, and a relationship, cites, between paper and itself that connects the citing paper to the cited paper. To represent the fact that the cited paper and the citing paper are selected uniformly from certain sets, the following clauses can be used (see file \verb|paper_ref_simple.cpl|): +\begin{verbatim} +uniform(cites_cited(C,P),P,L):- + bagof(Pap,paper_topic(Pap,theory),L). + +uniform(cites_citing(C,P),P,L):- + bagof(Pap,paper_topic(Pap,ai),L). +\end{verbatim} +The first clauses states that the paper \texttt{P} cited in a citation \texttt{C} is selected uniformly from the set of all papers with topic theory. +The second clauses expresses that the citing paper is selected uniformly from the papers with +topic ai. + +These clauses make use of the predicate +\begin{verbatim} +uniform(Atom,Variable,List) +\end{verbatim} +in the head, where \texttt{Atom} must contain \texttt{Variable}. The meaning is the following: the set of all the atoms obtained by instantiating \texttt{Variable} of \texttt{Atom} with a term taken from \texttt{List} is generated and the head is obtained by having a disjunct for each instantiation with probability $1/N$ where $N$ is the length of \texttt{List}. + + +A more elaborate example is present in file \verb|paper_ref.cpl|: +\begin{verbatim} +uniform(cites_citing(C,P),P,L):- + setof(Pap,paper(Pap),L). + +cites_cited_group(C,theory):0.9 ; cites_cited_group(C,ai):0.1:- + cites_citing(C,P),paper_topic(P,theory). + +cites_cited_group(C,theory):0.01;cites_cited_group(C,ai):0.99:- + cites_citing(C,P),paper_topic(P,ai). + +uniform(cites_cited(C,P),P,L):- + cites_cited_group(C,T),bagof(Pap,paper_topic(Pap,T),L). +\end{verbatim} +where the cited paper depends on the topic of the citing paper. In particular, if the topic is theory, the cited paper is selected uniformly from the papers about theory with probability 0.9 and from the papers about ai with probability 0.1. if the topic is ai, the cited paper is selected uniformly from the papers about theory with probability 0.01 and from the papers about ai with probability 0.99. + +PRMs take into account as well existence uncertainty, where the existence of instances is also probabilistic. For example, in the paper domain, the total number of citations may be unknown and a citation between any two paper may have a probability of existing. For example, a citation between two paper may be more probable if they are about the same topic: +\begin{verbatim} +cites(X,Y):0.005 :- + paper_topic(X,theory),paper_topic(Y,theory). + +cites(X,Y):0.001 :- + paper_topic(X,theory),paper_topic(Y,ai). + +cites(X,Y):0.003 :- + paper_topic(X,ai),paper_topic(Y,theory). + +cites(X,Y):0.008 :- + paper_topic(X,ai),paper_topic(Y,ai). +\end{verbatim} +This is an example where the probabilities in the head do not sum up to one so the null event is automatically added to the head. +The first clause states that, if the topic of a paper \texttt{X} is theory and of paper \texttt{Y} is theory, there is a probability of 0.005 that there is a citation from \texttt{X} to \texttt{Y}. The other clauses consider the remaining cases for the topics. + + +\section{Additional Files} +In the directory where Yap keeps the library files (usually \texttt{/usr/local/share/ Yap}) you can find the directory \texttt{cplint} that contains the files: +\begin{itemize} +\item \verb|testlpadsld_gbtrue.pl, testlpadsld_gbfalse.pl, testlpad.pl,| +\verb|testcpl.pl, testsemlpadsld.pl, testsemlpad.pl testsemcpl.pl|: Prolog programs for testing the modules. They are executed when issuing the command \texttt{make installcheck} during the installation. To execute them afterwords, load the file and issue the command \texttt{t.} +\item Subdirectory \texttt{examples}: +\begin{itemize} +\item \texttt{alarm.cpl}: representation of the Bayesian network in Figure 2 of + \cite{VenVer04-ICLP04-IC}. +\item \texttt{coin.cpl}: coin example from \cite{VenVer04-ICLP04-IC}. +\item \texttt{coin2.cpl}: coin example with two coins. +\item \texttt{dice.cpl}: dice example from \cite{VenVer04-ICLP04-IC}. +\item \verb|twosideddice.cpl, threesideddice.cpl| game with idealized dice with two or three sides. Used in the experiments in \cite{Rig-RCRA07-IC}. +\item \texttt{ex.cpl}: first example in \cite{Rig-RCRA07-IC}. +\item \texttt{exapprox.cpl}: example showing the problems of approximate inference (see \cite{Rig-RCRA07-IC}). +\item \texttt{exrange.cpl}: example showing the problems with non range restricted programs (see \cite{Rig-RCRA07-IC}). +\item \texttt{female.cpl}: example showing the dependence of probabilities in the head from variables in the body (from \cite{VenVer04-ICLP04-IC}). +\item \texttt{mendel.cpl, mendels.cpl}: programs describing the Mendelian rules of inheritance, taken from \cite{Blo04-ILP04WIP-IC}. +\item \verb|paper_ref.cpl, paper_ref_simple.cpl|: paper citations examples, showing reference uncertainty, inspired by \cite{Getoor+al:JMLR02}. +\item \verb|paper_ref_not.cpl|: paper citations example showing that negation can be used also for predicates defined by clauses with \texttt{uniform} in the head. +\item \texttt{school.cpl}: example inspired by the example \verb|school_32.yap| from the +source distribution of Yap in the \texttt{CLPBN} directory. +\item \verb|school_simple.cpl|: simplified version of \texttt{school.cpl}. +\item \verb|student.cpl|: student example from Figure 1.3 of \cite{GetFri01-BC}. +\item \texttt{win.cpl, light.cpl, trigger.cpl, throws.cpl, hiv.cpl,}\\ \texttt{ invalid.cpl}: programs taken from \cite{CP-logic-unp}. \texttt{invalid.cpl} is an example of a program that is invalid but sound. +\end{itemize} +The files \texttt{*.uni} that are present for some of the examples are used by the semantical modules. Some of the example files contain in an initial comment some queries together with their result. +\item Subdirectory \texttt{doc}: contains this manual in latex, html and pdf. +\end{itemize} +\section{License} +\label{license} + + + +\texttt{cplint}, as Yap, follows the Artistic License 2.0 that you can find in Yap CVS root dir. The copyright is by Fabrizio Riguzzi. + + +\vspace{3mm} + +The program uses the library \href{http://vlsi.colorado.edu/~fabio/}{CUDD} for manipulating BDDs that is included in glu. +For the use of CUDD, the following license must be accepted: + +\vspace{3mm} + +Copyright (c) 1995-2004, Regents of the University of Colorado + +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +\begin{itemize} +\item +Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +\item +Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. +\item +Neither the name of the University of Colorado nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. +\end{itemize} +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS \\ AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAU-SED +\\ AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +\texttt{lpad.pl}, \texttt{semlpad.pl} and \texttt{cpl.pl} are based on the SLG system +by \href{http://engr.smu.edu/~wchen/}{Weidong Chen} and \href{http://www.cs.sunysb.edu/~warren/}{David Scott Warren}, +Copyright (C) 1993 Southern Methodist University, 1993 SUNY at Stony Brook, see the file COYPRIGHT\_SLG for detailed information on this copyright. + +\bibliographystyle{plain} +\bibliography{bib} + +\end{document} diff --git a/packages/cplint/doc/manual0x.png b/packages/cplint/doc/manual0x.png new file mode 100644 index 0000000000000000000000000000000000000000..f64b50211d605899ca9a99ccab2450d9e02e4857 GIT binary patch literal 1593 zcmZXUdpOg37{GtTn9JO%byTeB5y@ab{^8`f39V8NoS4-gcldA%d zHw*ANW68Ba5B!iTHs_F@=Nnn)xSJQzSG{k)H|>-=x}8$<%W0+zxaqsV6_c#dgy#fQ zp*}48<&Y0g#N2I=U+w`tL99G-|B#uI_T)1H>QYG3IjZVP z+bs#$E2{M4+ClqL=|C-2*D5V2|FkN*^HELaeGC5QR#vH*EO96`Al91m<|wY~Qoq7m z%Mz#y3&k)~CN8uyN)dmN@-7qo}7<=S0P8WlO-ofSoTv5`!e z1|*e^*#FH&KiB2D&i;E|0@h%9L%N&Yy>XK>aD{!mu{PB69|qH-Y2=zDWkmsD`>ls? z*g9Lp+jjEJveo>Nkl{YAVdO)R#oE(N#ImlRZJiU_6nPn6aF2ucz3}gV^@#PFXbTc4 zyS}^Wc8vhm#1pF*PvIuzreOGk35Cm8u15*jyCp*Ys^rT#pJbKZUQ*hvCc^g^R=sag zE2@miE!Sw0`0B27txvL_Z+uQJ z@tY3O1??7==1H3$pSRrUk#}l>*9|`#KU8^mH~mz(b;-n;n}+RfoA9o76#}aBd_AHt z&{1UXmoc0g9hsJdg>t4>jMhmGu5KT!?lte8n+_O^S$LOT9K5mA>eJ4^zo3RQ84s|3 zvaJ+tyR?h&-ApbeHs!jo4{g0is}E9Qo0+fKOv@ar78PU(7~`$1n&u2AbA8#eq`6=q zzpf^`gg1*z>+%?4iNDC~v?k&Oi$-HvPZ?FBH7d#jhC=^{*+Rd%Z$f_1Qr>|S2>Mpx1ZF3pk@9oqH8+uO;M3RmR&SzT%!`1M%~?o8zth;aV4-+=owFGS_kpdE%vs z5C2T2q@qRdc1(pWwfGe;QbsoR#>sAvSEoTOW@fjPWQzh~{y@Zc=M`@V;=C_JTSHao z_eqUTU$Poz`XFj$t88~|qs5(kAjL0uk}h@BsN^qZ(4{4U`R}a~fp`>kOsEsyhb?{D z18vW&C(alh#0J-<2;VN{GG;A5ME1h8>yk4rcB~qCQLR*qn`&=t+bumMg(?Kkrhj?V zfg9?`Yjeh)lX@7Klx}qqL3E36vM5(aIB2TqJdkfl^-2#j zU5VnS6<$j+P2Ti4TO@ln@S$3<(!%6ub3gUo@E1nXoBp)AtL5wy?9jXBFJ<9HK`kyO z17Gh3PoAB-W_UUJypLH#vDV;}L>6-Kz;)x4ZR%HA)*x%~>DL^*e1N7oyzf>Mokq!2 zhOqnfryTt3R%fkFzE|yvqS*n|Rvr{c1!v&zG-rPrjuIC~BGUkbdt7J)2@ydelM+H{ zq;LfB7{bBD#|z;aNlBz7h9yK%X$X^W5+f>%^gERtmk^p{s&*(G2nGWo<$tZLz;^U5CI(}M*?~5*v_#*if{%do=3lfIi9w159KtC?k_&}QGsmDX zwg}u_JO+)xpwMVXwfCADdLY047k_|C0jrIrB$%TC+}^$JJ3-jj9fS5u-YEq!?f+pI V0F(17WgX}P+?~ChDjY*j{0qXk_qzZ9 literal 0 HcmV?d00001 diff --git a/packages/cplint/examples/alarm.cpl b/packages/cplint/examples/alarm.cpl new file mode 100644 index 000000000..62bcdba95 --- /dev/null +++ b/packages/cplint/examples/alarm.cpl @@ -0,0 +1,7 @@ + +burg(t):0.1; burg(f):0.9. +earthq(t):0.2; earthq(f):0.8. +alarm(t):-burg(t),earthq(t). +alarm(t):0.8 ; alarm(f):0.2:-burg(t),earthq(f). +alarm(t):0.8 ; alarm(f):0.2:-burg(f),earthq(t). +alarm(t):0.1 ; alarm(f):0.9:-burg(f),earthq(f). diff --git a/packages/cplint/examples/coin.cpl b/packages/cplint/examples/coin.cpl new file mode 100644 index 000000000..90ab0b900 --- /dev/null +++ b/packages/cplint/examples/coin.cpl @@ -0,0 +1,17 @@ +/* +s([heads(C)],P). +C = coin +P = 0.51 ?; +no +s([tails(C)],P). +C = coin +P = 0.49 ?; +no + + +*/ + +heads(Coin): 1/2; tails(Coin) : 1/2:-toss(Coin),\+biased(Coin). +heads(Coin): 0.6 ; tails(Coin) : 0.4:-toss(Coin),biased(Coin). +fair(Coin):0.9 ; biased(Coin):0.1. +toss(coin). diff --git a/packages/cplint/examples/coin.uni b/packages/cplint/examples/coin.uni new file mode 100644 index 000000000..e69de29bb diff --git a/packages/cplint/examples/coin2.cpl b/packages/cplint/examples/coin2.cpl new file mode 100644 index 000000000..1f8d3218d --- /dev/null +++ b/packages/cplint/examples/coin2.cpl @@ -0,0 +1,23 @@ +/* + ?- s([heads(C)],P). +C = coin1 +P = 0.51 ? ; +C = coin2 +P = 0.51 ? ; +no + ?- s([tails(C)],P). +C = coin1 +P = 0.49 ? ; +C = coin2 +P = 0.49 ? ; +no + +s([tails(coin1)],P). +P = 0.49 ? +*/ + +heads(Coin): 0.5; tails(Coin) : 0.5:-toss(Coin),fair(Coin). +heads(Coin): 0.6 ; tails(Coin) : 0.4:-toss(Coin),biased(Coin). +fair(Coin):0.9 ; biased(Coin):0.1. +toss(coin1). +toss(coin2). diff --git a/packages/cplint/examples/coin2.uni b/packages/cplint/examples/coin2.uni new file mode 100644 index 000000000..2a13c4019 --- /dev/null +++ b/packages/cplint/examples/coin2.uni @@ -0,0 +1,9 @@ +universe(['Coin'],[coin1,coin2]). + +mode(heads(coin)). +mode(tails(coin)). +mode(toss(coin)). +mode(fair(coin)). +mode(biased(coin)). + +type(coin,[coin1,coin2]). diff --git a/packages/cplint/examples/dice.cpl b/packages/cplint/examples/dice.cpl new file mode 100644 index 000000000..dab072b3f --- /dev/null +++ b/packages/cplint/examples/dice.cpl @@ -0,0 +1,29 @@ +/* +s([on(0,1)],P). +P = 0.166666666666667 ?; +s([\+ on(0,6)],P). +P = 0.833333333333333 ?; + + +s([on(1,1)],P). +P = 0.138888888888889 ? +s([on(1,6)],P). +P = 0.138888888888889 ? +s([on(2,1)],P). +out of memory +s([on(0,1),on(1,1)],P). +P = 0.0277777777777778 ? +s([on(0,1),on(1,1),on(2,1)],P). +P = 0.00462962962962963 ? + + + + +*/ +on(0,1):1/6;on(0,2):1/6;on(0,3):1/6; +on(0,4):1/6;on(0,5):1/6;on(0,6):1/6. + +on(X,1):1/6;on(X,2):1/6;on(X,3):1/6; +on(X,4):1/6;on(X,5):1/6;on(X,6):1/6:- + X1 is X-1,X1>=0,on(X1,_), + \+ on(X1,6). diff --git a/packages/cplint/examples/dice.uni b/packages/cplint/examples/dice.uni new file mode 100644 index 000000000..5792571af --- /dev/null +++ b/packages/cplint/examples/dice.uni @@ -0,0 +1,2 @@ +universe(['X'],[1,2]). +universe(['X1'],[0,1]). diff --git a/packages/cplint/examples/ex.cpl b/packages/cplint/examples/ex.cpl new file mode 100644 index 000000000..90f09c34b --- /dev/null +++ b/packages/cplint/examples/ex.cpl @@ -0,0 +1,13 @@ +/* +s([a],P). +Variables: [(1,[]),(2,[]),(3,[])] +P = 0.226 ? +*/ + +a:0.1. + + + +b:0.3;c:0.6. + +a:0.2:- \+ b. diff --git a/packages/cplint/examples/ex.uni b/packages/cplint/examples/ex.uni new file mode 100644 index 000000000..645a314b5 --- /dev/null +++ b/packages/cplint/examples/ex.uni @@ -0,0 +1,6 @@ + +mode(a). + +mode(b). + +mode(c). diff --git a/packages/cplint/examples/exapprox.cpl b/packages/cplint/examples/exapprox.cpl new file mode 100644 index 000000000..bdfef43c6 --- /dev/null +++ b/packages/cplint/examples/exapprox.cpl @@ -0,0 +1,17 @@ +/* + +set(ground_body,true). +s([a],P). +Variables: [(1,[]),(2,[]),(3,[])] +P = 0.1719 ? ; + +set(ground_body,false). + ?- s([a],P). +P = 0.099 ? +*/ + +a:0.1:-p(X). + +p(1):0.9. + +p(2):0.9. diff --git a/packages/cplint/examples/exapprox.uni b/packages/cplint/examples/exapprox.uni new file mode 100644 index 000000000..db839c67e --- /dev/null +++ b/packages/cplint/examples/exapprox.uni @@ -0,0 +1,9 @@ + +universe(['X'],[1,2]). + + +mode(a). + +mode(p(int)). + +type(int,[1,2]). diff --git a/packages/cplint/examples/exist.cpl b/packages/cplint/examples/exist.cpl new file mode 100644 index 000000000..220564898 --- /dev/null +++ b/packages/cplint/examples/exist.cpl @@ -0,0 +1,32 @@ +/* +semlpad.pl +ground_body(false) + ?- s([a],P). +P = 0.18 ? + +ground_body(true) + ?- s([a],P). +P = 0.19 ? +yes + + +yes +lpad.pl +ground_body(false) + ?- s([a],P). +P = 0.02 ? +yes +ground_body(true) + ?- s([a],P). +P = 0.19 ? +yes + +*/ + +a:0.5 :- p(X). + +p(X):0.2 :- c(X). + +c(1). + +c(2). diff --git a/packages/cplint/examples/exist.uni b/packages/cplint/examples/exist.uni new file mode 100644 index 000000000..95875b009 --- /dev/null +++ b/packages/cplint/examples/exist.uni @@ -0,0 +1,8 @@ + +mode(a). + +mode(p(int)). + +mode(c(int)). + +type(int,[1,2]). diff --git a/packages/cplint/examples/exist1.cpl b/packages/cplint/examples/exist1.cpl new file mode 100644 index 000000000..22b194661 --- /dev/null +++ b/packages/cplint/examples/exist1.cpl @@ -0,0 +1,31 @@ +/* +semlpad.pl +ground_body(false) + ?- s([a],P). +P = 0.276 ? + +ground_body(true) + ?- s([a],P). +P = 0.3115 ? + + +yes +lpad.pl +ground_body(false) + ?- s([a],P). +P = 0.276 ? + +ground_body(true) + ?- s([a],P). +P = 0.3115 ? +*/ + +a:0.5 :- p(X). + +p(3):0.3. + +p(X):0.2 :- c(X). + +c(1). + +c(2). diff --git a/packages/cplint/examples/exist1.uni b/packages/cplint/examples/exist1.uni new file mode 100644 index 000000000..10413df56 --- /dev/null +++ b/packages/cplint/examples/exist1.uni @@ -0,0 +1,10 @@ + +mode(a). + +mode(p(int)). + +mode(c(int)). + +type(int,[1,2,3]). + + diff --git a/packages/cplint/examples/exrange.cpl b/packages/cplint/examples/exrange.cpl new file mode 100644 index 000000000..9d46e8918 --- /dev/null +++ b/packages/cplint/examples/exrange.cpl @@ -0,0 +1,21 @@ +/* +s([a(X)],P). +Variables: [(1,[]),(5,[]),(2,[]),(6,[])] +P = 0.2775 +X = 1 ? ; +Variables: [(3,[]),(5,[]),(4,[]),(6,[])] +P = 0.36 +X = 2 ? ; +*/ + +a(1):0.3:-p(1). + +a(1):0.3:-p(2). + +a(2):0.4:-p(1). + +a(2):0.4:-p(2). + +p(1):0.5. + +p(2):0.5. diff --git a/packages/cplint/examples/exrange.uni b/packages/cplint/examples/exrange.uni new file mode 100644 index 000000000..c8eb84676 --- /dev/null +++ b/packages/cplint/examples/exrange.uni @@ -0,0 +1,6 @@ + +mode(a(int)). + +mode(p(int)). + +type(int,[1,2]). diff --git a/packages/cplint/examples/female.cpl b/packages/cplint/examples/female.cpl new file mode 100644 index 000000000..9dd24e7ee --- /dev/null +++ b/packages/cplint/examples/female.cpl @@ -0,0 +1,26 @@ +/* +s([female(f)],P). +P = 0.6 ? +s([male(f)],P). +P = 0.4 ? + +*/ + + +male(C):M/P;female(C):F/P:- + person(C), + setof(Male,known_male(Male),LM), + length(LM,M), + setof(Female,known_female(Female),LF), + length(LF,F), + P is F+M. + + +person(f). + +known_female(a). +known_female(b). +known_female(c). + +known_male(d). +known_male(e). diff --git a/packages/cplint/examples/hiv.cpl b/packages/cplint/examples/hiv.cpl new file mode 100644 index 000000000..b638b1790 --- /dev/null +++ b/packages/cplint/examples/hiv.cpl @@ -0,0 +1,27 @@ +/* + ?- s([hiv(a)],P). +P = 0.154 ? +yes + ?- s([hiv(b)],P). +P = 0.154 ? +yes + ?- s([hiv(b),hiv(a)],P). +P = 0.118 ? +yes + ?- s([\+ hiv(b),\+ hiv(a)],P). +P = 0.81 ? +yes + ?- s([ hiv(b),\+ hiv(a)],P). +P = 0.036 ? +yes + ?- s([\+ hiv(b),hiv(a)],P). +P = 0.036 ? +yes +*/ + +(hiv(a) : 0.1). +(hiv(b) : 0.1). +(hiv(a) : 0.6) :- hiv(b). +(hiv(b) : 0.6) :- hiv(a). +hiv(a) :- hiv(a). +hiv(b) :- hiv(b). diff --git a/packages/cplint/examples/hiv.uni b/packages/cplint/examples/hiv.uni new file mode 100644 index 000000000..f89790e60 --- /dev/null +++ b/packages/cplint/examples/hiv.uni @@ -0,0 +1,4 @@ + +mode(hiv(person)). + +type(person,[a,b]). diff --git a/packages/cplint/examples/invalid.cpl b/packages/cplint/examples/invalid.cpl new file mode 100644 index 000000000..e0ab4f196 --- /dev/null +++ b/packages/cplint/examples/invalid.cpl @@ -0,0 +1,15 @@ +/* + ?- s([p],P). +P = 0.5 ? +yes + ?- s([q],P). +P = 0.5 ? +yes + ?- s([p,q],P). +P = 0 ? +yes +*/ + +p : 0.5;q : 0.5:- r. +r :- \+ p. +r :- \+ q. diff --git a/packages/cplint/examples/invalid.uni b/packages/cplint/examples/invalid.uni new file mode 100644 index 000000000..b7aeb74f6 --- /dev/null +++ b/packages/cplint/examples/invalid.uni @@ -0,0 +1,7 @@ + + +mode(p). + +mode(r). + +mode(q). diff --git a/packages/cplint/examples/light.cpl b/packages/cplint/examples/light.cpl new file mode 100644 index 000000000..516cfa920 --- /dev/null +++ b/packages/cplint/examples/light.cpl @@ -0,0 +1,26 @@ +/* + ?- p(light). +yes + ?- s([push,replace],P). +P = 0.5 ? +yes + ?- s([push,light],P). +P = 0.5 ? +yes + ?- s([push,light,replace],P). +P = 0 ? +yes + ?- s([light,replace],P). +P = 0 ? +yes + ?- s([light],P). +P = 0.5 ? +yes + ?- s([replace],P). +P = 0.5 ? +yes +*/ + +push. +light : 0.5 :- push. +replace :- \+ light. diff --git a/packages/cplint/examples/light.uni b/packages/cplint/examples/light.uni new file mode 100644 index 000000000..8c642f72c --- /dev/null +++ b/packages/cplint/examples/light.uni @@ -0,0 +1,4 @@ + +mode(push). +mode(light). +mode(replace). diff --git a/packages/cplint/examples/mendel.cpl b/packages/cplint/examples/mendel.cpl new file mode 100644 index 000000000..4df68828d --- /dev/null +++ b/packages/cplint/examples/mendel.cpl @@ -0,0 +1,38 @@ +/* +this file can not be used with s.pl: it generates too many programs +s([cg(s,1,p)],P). +P = 0.75 ? +s([cg(s,1,w)],P). +P = 0.25 ? +s([cg(s,2,p)],P). +P = 0.25 ? +s([cg(s,2,w)],P). +P = 0.75 ? +s([cg(f,2,w)],P). +P = 0.5 +s([cg(s,2,w)],P). +P = 0.75 + +*/ + +mother(m,s). +mother(mm,m). +mother(mf,f). +father(f,s). +father(fm,m). +father(ff,f). + + +cg(mm,1,p). +cg(mm,2,w). +cg(fm,1,p). +cg(fm,2,p). +cg(mf,1,w). +cg(mf,2,w). +cg(ff,1,w). +cg(ff,2,p). + + +cg(X,1,A):0.5 ; cg(X,1,B):0.5 :- mother(Y,X),cg(Y,1,A) , cg(Y,2,B). + +cg(X,2,A):0.5 ; cg(X,2,B):0.5 :- father(Y,X),cg(Y,1,A) , cg(Y,2,B). diff --git a/packages/cplint/examples/mendel.uni b/packages/cplint/examples/mendel.uni new file mode 100644 index 000000000..9a07bc1b6 --- /dev/null +++ b/packages/cplint/examples/mendel.uni @@ -0,0 +1,13 @@ +mode(mother(person,person)). +mode(father(person,person)). +mode(cg(person,chr,allele)). + +type(person,[s,m,f,mm,fm,mf,ff]). + +type(chr,[1,2]). + +type(allele,[p,w]). + +universe(['X'],[s,m,f]). + +universe(['A','B'],[p,w]). diff --git a/packages/cplint/examples/mendels.cpl b/packages/cplint/examples/mendels.cpl new file mode 100644 index 000000000..d079fb97e --- /dev/null +++ b/packages/cplint/examples/mendels.cpl @@ -0,0 +1,30 @@ +/* +this file can not be used with s.pl: it generates too many programs +s([cg(s,1,p)],P). +P = 0.75 ? +s([cg(s,1,w)],P). +P = 0.25 ? +s([cg(s,2,p)],P). +P = 0.25 ? +s([cg(s,2,w)],P). +P = 0.75 ? +s([cg(f,2,w)],P). +P = 0.5 +s([cg(s,2,w)],P). +P = 0.75 + +*/ + +mother(m,s). +father(f,s). + + +cg(m,1,p). +cg(m,2,w). +cg(f,1,p). +cg(f,2,p). + + +cg(X,1,A):0.5 ; cg(X,1,B):0.5 :- mother(Y,X),cg(Y,1,A) , cg(Y,2,B). + +cg(X,2,A):0.5 ; cg(X,2,B):0.5 :- father(Y,X),cg(Y,1,A) , cg(Y,2,B). diff --git a/packages/cplint/examples/mendels.uni b/packages/cplint/examples/mendels.uni new file mode 100644 index 000000000..a102b83fb --- /dev/null +++ b/packages/cplint/examples/mendels.uni @@ -0,0 +1,13 @@ +mode(mother(person,person)). +mode(father(person,person)). +mode(cg(person,chr,allele)). + +type(person,[s,m,f]). + +type(chr,[1,2]). + +type(allele,[p,w]). + +universe(['X'],[s]). + +universe(['A','B'],[p,w]). diff --git a/packages/cplint/examples/paper_ref.cpl b/packages/cplint/examples/paper_ref.cpl new file mode 100644 index 000000000..08da27c02 --- /dev/null +++ b/packages/cplint/examples/paper_ref.cpl @@ -0,0 +1,51 @@ +/* + + ?- s([cites_cited(c1,Pap)],P). +P = 0.181333333333333, +Pap = p1 ? ; +P = 0.181333333333333, +Pap = p2 ? ; +P = 0.228, +Pap = p3 ? ; +P = 0.181333333333333, +Pap = p4 ? ; +P = 0.228, +Pap = p5 ? ; +no + +*/ +paper(p1). + +paper(p2). + +paper(p3). + +paper(p4). + +paper(p5). + +paper_topic(p1,theory). + +paper_topic(p2,theory). + +paper_topic(p4,theory). + +paper_topic(p3,ai). + +paper_topic(p5,ai). + +cites(c1). + + +uniform(cites_citing(C,P),P,L):- + setof(Pap,paper(Pap),L). + +cites_cited_group(C,theory):0.9;cites_cited_group(C,ai):0.1:- + cites_citing(C,P),paper_topic(P,theory). + +cites_cited_group(C,theory):0.01;cites_cited_group(C,ai):0.99:- + cites_citing(C,P),paper_topic(P,ai). + +uniform(cites_cited(C,P),P,L):- + cites_cited_group(C,T),bagof(Pap,paper_topic(Pap,T),L). + diff --git a/packages/cplint/examples/paper_ref_not.cpl b/packages/cplint/examples/paper_ref_not.cpl new file mode 100644 index 000000000..2e207c6f5 --- /dev/null +++ b/packages/cplint/examples/paper_ref_not.cpl @@ -0,0 +1,41 @@ +/* +s([\+ cites_cited(c1,p1)],P). +P = 0.7 ? + +s([cites_citing(c1,p1)],P). +P = 0.14 ? + +*/ +paper(p1). + +paper(p2). + +paper(p3). + +paper(p4). + +paper(p5). + +paper_topic(p1,theory). + +paper_topic(p2,theory). + +paper_topic(p4,theory). + +paper_topic(p3,ai). + +paper_topic(p5,ai). + +cites(c1). + + +cites_cited_group(C,theory):0.9;cites_cited_group(C,ai):0.1. + +uniform(cites_cited(C,P),P,L):- + cites_cited_group(C,T),bagof(Pap,paper_topic(Pap,T),L). + + +uniform(cites_citing(C,P),P,L):- + setof(Paper,paper(Paper),L), + cites_cited(C,Pap), + \+ cites_cited(C,p1). diff --git a/packages/cplint/examples/paper_ref_simple.cpl b/packages/cplint/examples/paper_ref_simple.cpl new file mode 100644 index 000000000..be608e15a --- /dev/null +++ b/packages/cplint/examples/paper_ref_simple.cpl @@ -0,0 +1,45 @@ +/* + ?- s([cites_cited(c1,Pap)],P). +P = 0.333333333333333, +Pap = p1 ? ; +P = 0.333333333333333, +Pap = p2 ? ; +P = 0.333333333333333, +Pap = p4 ? ; +no + ?- Action (h for help): c + | s([cites_citing(c1,Pap)],P). +P = 0.5, +Pap = p3 ? ; +P = 0.5, +Pap = p5 ? ; +no + +*/ +paper(p1). + +paper(p2). + +paper(p3). + +paper(p4). + +paper(p5). + +paper_topic(p1,theory). + +paper_topic(p2,theory). + +paper_topic(p4,theory). + +paper_topic(p3,ai). + +paper_topic(p5,ai). + +cites(c1). + +uniform(cites_cited(C,P),P,L):- + bagof(Pap,paper_topic(Pap,theory),L). + +uniform(cites_citing(C,P),P,L):- + bagof(Pap,paper_topic(Pap,ai),L). diff --git a/packages/cplint/examples/school.cpl b/packages/cplint/examples/school.cpl new file mode 100644 index 000000000..f5fdc5bf1 --- /dev/null +++ b/packages/cplint/examples/school.cpl @@ -0,0 +1,796 @@ +/* +Yap run on school_32.yap + ?- s([professor_ability(p0,X)],P). +P = 0.5, +X = h ? ; +P = 0.1, +X = l ? ; +P = 0.4, +X = m ? ; +no + ?- s([professor_popularity(p0,X)],P). +P = 0.531, +X = h ? ; +P = 0.175, +X = l ? ; +P = 0.294, +X = m ? ; +no +ok + +sc([professor_ability(p0,X)],[professor_popularity(p0,h)],P). +P = 0.847457627118644, +X = h ? ; +P = 0.00188323917137476, +X = l ? ; +P = 0.150659133709981, +X = m ? +ok + +sc([professor_popularity(p0,X)],[professor_ability(p0,h)],P). +P = 0.9, +X = h ? ; +P = 0.01, +X = l ? ; +P = 0.09, +X = m ? ; +no +ok + ?- s([registration_grade(r0,X)],P). +P = 0.06675, +X = 1 ? ; +P = 0.16575, +X = 2 ? ; +Action (";" for more choices, for exit) ? ; +P = 0.356, +X = 3 ? ; +P = 0.4115, +X = 4 ? +no +ok + +sc([registration_grade(r0,X)],[registration_course(r0,C), course_difficulty(C,h)],P). +C = c16, +P = 0.15, +X = 1 ? ; +C = c16, +P = 0.285, +X = 2 ? ; +C = c16, +P = 0.424, +X = 3 ? ; +C = c16, +P = 0.141, +X = 4 ? ; +no +ok (a=4, ...,d=1) + +sc([registration_grade(r0,X)], [registration_course(r0,C), course_difficulty(C,h), registration_student(r0,S), student_intelligence(S,h)],P). +C = c16, +P = 0.05, +S = s0, +X = 1 ? ; +C = c16, +P = 0.15, +S = s0, +X = 2 ? ; +C = c16, +P = 0.6, +S = s0, +X = 3 ? ; +C = c16, +P = 0.2, +S = s0, +X = 4 ? ; +no +ok + +sc([registration_grade(r0,X)],[registration_course(r0,C), course_difficulty(C,l), registration_student(r0,S), student_intelligence(S,h)],P). +C = c16, +P = 0.01, +S = s0, +X = 1 ? ; +C = c16, +P = 0.02, +S = s0, +X = 2 ? ; +C = c16, +P = 0.12, +S = s0, +X = 3 ? ; +C = c16, +P = 0.85, +S = s0, +X = 4 ? ; +no +ok + +s([registration_satisfaction(r0,X)],P). +P = 0.15197525, +X = 1 ? ; +P = 0.15331025, +X = 2 ? ; +P = 0.6947145, +X = 3 ? ; +no +ok +sc([registration_satisfaction(r0,X)],[ registration_student(r0,S), student_intelligence(S,h)],P). +P = 0.0959225, +S = s0, +X = 1 ? ; +P = 0.124515, +S = s0, +X = 2 ? ; +P = 0.7795625, +S = s0, +X = 3 ? ; +no +ok (h=3, l=1) + +sc([registration_satisfaction(r0,X)],[registration_grade(r0,4)],P). +P = 0.04, +X = 1 ? ; +P = 0.06, +X = 2 ? ; +P = 0.9, +X = 3 ? ; +in Yap: + ?- registration_satisfaction(r0,X), registration_grade(r0,a). +% YAP: no handler for error error(domain_error(bayesian_domain),bind_clpbns(var(grade(r0),[a,b,c,d],[0.2,0.7,0.85,0.1,0.2,0.5,0.01,0.05,0.1,0.6,0.25,0.12,0.3,0.6,0.35,0.04,0.15,0.4,0.15,0.04,0.02,0.4,0.15,0.12,0.5,0.6,0.4,0.05,0.01,0.01,0.2,0.05,0.03,0.45,0.2,0.1],[_D11,_D12]),var(grade(r0),[a,b,c,d],[0.2,0.7,0.85,0.1,0.2,0.5,0.01,0.05,0.1,0.6,0.25,0.12,0.3,0.6,0.35,0.04,0.15,0.4,0.15,0.04,0.02,0.4,0.15,0.12,0.5,0.6,0.4,0.05,0.01,0.01,0.2,0.05,0.03,0.45,0.2,0.1],[_D13,_D12]))) + +sc([registration_satisfaction(r0,X)],[registration_grade(r0,1)],P). +P = 0.528, +X = 1 ? ; +P = 0.167, +X = 2 ? ; +P = 0.305, +X = 3 ? ; +no + ?- sc([ registration_grade(r0,X)],[registration_satisfaction(r0,3)],P). +P = 0.0293052037923492, +X = 1 ? ; +P = 0.114760451955444, +X = 2 ? ; +P = 0.322837654892765, +X = 3 ? ; +P = 0.533096689359442, +X = 4 ? ; +no + ?- registration_satisfaction(r0,X), registration_grade(r0,d). +% YAP: no handler for error error(domain_error(bayesian_domain),bind_clpbns(var(grade(r0),[a,b,c,d],[0.2,0.7,0.85,0.1,0.2,0.5,0.01,0.05,0.1,0.6,0.25,0.12,0.3,0.6,0.35,0.04,0.15,0.4,0.15,0.04,0.02,0.4,0.15,0.12,0.5,0.6,0.4,0.05,0.01,0.01,0.2,0.05,0.03,0.45,0.2,0.1],[_D11,_D12]),var(grade(r0),[a,b,c,d],[0.2,0.7,0.85,0.1,0.2,0.5,0.01,0.05,0.1,0.6,0.25,0.12,0.3,0.6,0.35,0.04,0.15,0.4,0.15,0.04,0.02,0.4,0.15,0.12,0.5,0.6,0.4,0.05,0.01,0.01,0.2,0.05,0.03,0.45,0.2,0.1],[_D13,_D12]))) + +sc([ registration_grade(r0,X)],[registration_satisfaction(r0,3)],P). + ?- registration_satisfaction(r0,h), registration_grade(r0,X). +% YAP: no handler for error error(domain_error(bayesian_domain),bind_clpbns(var(grade(r0),[a,b,c,d],[0.2,0.7,0.85,0.1,0.2,0.5,0.01,0.05,0.1,0.6,0.25,0.12,0.3,0.6,0.35,0.04,0.15,0.4,0.15,0.04,0.02,0.4,0.15,0.12,0.5,0.6,0.4,0.05,0.01,0.01,0.2,0.05,0.03,0.45,0.2,0.1],[_D11,_D12]),var(grade(r0),[a,b,c,d],[0.2,0.7,0.85,0.1,0.2,0.5,0.01,0.05,0.1,0.6,0.25,0.12,0.3,0.6,0.35,0.04,0.15,0.4,0.15,0.04,0.02,0.4,0.15,0.12,0.5,0.6,0.4,0.05,0.01,0.01,0.2,0.05,0.03,0.45,0.2,0.1],[_D13,_D12]))) + +s([course_rating(c0,X)],P). +P = 0.5392099, +X = h ? ; +P = 0.2, +X = l ? ; +P = 0.2607901, +X = m ? ; +no +yap does not end, starts thrashing +sc([course_difficulty(c0,X)],[course_rating(c0,h)],P). +P = 0.235185778302661, +X = h ? ; +P = 0.259096503977393, +X = l ? ; +P = 0.505717717719945, +X = m ? ; +no +yap does not end, starts thrashing +s([course_difficulty(c0,X)],P). +P = 0.25, +X = h ? ; +P = 0.25, +X = l ? ; +P = 0.5, +X = m ? ; +no +ok +student_ranking(s0,X). +| ?- s([student_ranking(s0,X)],P). +P = 0.33105221125, +X = h ? ; +P = 0.204865630625, +X = l ? ; +P = 0.46408215812500003, +X = m ? +not checked with s +yap: +true ? +yes + + +sc([student_ranking(s0,X)],[student_intelligence(s0,h)],P). +P = 0.42922046875000003, +X = h ? ; +P = 0.20003319999999997, +X = l ? ; +P = 0.3707463312499999, +X = m ? ; +no +not checked with s +yap: +true +*/ + + + + +professor_ability(Key,h):0.50;professor_ability(Key,m): 0.40;professor_ability(Key,l): 0.10. + +professor_popularity(Key, h):0.9; professor_popularity(Key, m):0.09; professor_popularity(Key, l):0.01 :- + professor_ability(Key, h). + +professor_popularity(Key, h):0.2; professor_popularity(Key, m):0.6; professor_popularity(Key, l):0.2:- + professor_ability(Key, m). + +professor_popularity(Key, h):0.01; professor_popularity(Key, m):0.09; professor_popularity(Key, l):0.9 :- + professor_ability(Key,l). + + + +registration_course(Key, CKey) :- + registration(Key, CKey, _). + +registration_student(Key, SKey) :- + registration(Key, _, SKey). + +registration_grade(Key, 4): 0.2;registration_grade(Key, 3): 0.6;registration_grade(Key, 2): 0.15 ; + registration_grade(Key, 1): 0.05 :- + registration(Key, CKey, SKey) , + student_intelligence(SKey, h) , + course_difficulty(CKey, h). + +registration_grade(Key, 4): 0.7;registration_grade(Key, 3): 0.25;registration_grade(Key, 2): 0.04 ; + registration_grade(Key, 1): 0.01 :- + registration(Key, CKey, SKey) , + student_intelligence(SKey, h) , + course_difficulty(CKey, m). + + +registration_grade(Key, 4): 0.85;registration_grade(Key, 3): 0.12;registration_grade(Key, 2): 0.02 ; + registration_grade(Key, 1): 0.01 :- + registration(Key, CKey, SKey) , + student_intelligence(SKey, h) , + course_difficulty(CKey, l). + + +registration_grade(Key, 4): 0.1;registration_grade(Key, 3): 0.3;registration_grade(Key, 2): 0.4 ; + registration_grade(Key, 1): 0.2 :- + registration(Key, CKey, SKey) , + student_intelligence(SKey, m) , + course_difficulty(CKey, h). + + +registration_grade(Key, 4): 0.2;registration_grade(Key, 3): 0.6;registration_grade(Key, 2): 0.15 ; + registration_grade(Key, 1): 0.05 :- + registration(Key, CKey, SKey) , + student_intelligence(SKey, m) , + course_difficulty(CKey, m). + +registration_grade(Key, 4): 0.5;registration_grade(Key, 3): 0.35;registration_grade(Key, 2): 0.12; + registration_grade(Key, 1): 0.03 :- + registration(Key, CKey, SKey) , + student_intelligence(SKey, m) , + course_difficulty(CKey, l). + +registration_grade(Key, 4): 0.01;registration_grade(Key, 3): 0.04;registration_grade(Key, 2): 0.5 ; + registration_grade(Key, 1): 0.45 :- + registration(Key, CKey, SKey) , + student_intelligence(SKey, l) , + course_difficulty(CKey, h). + +registration_grade(Key, 4): 0.05;registration_grade(Key, 3): 0.15;registration_grade(Key, 2): 0.6 ; + registration_grade(Key, 1): 0.2 :- + registration(Key, CKey, SKey) , + student_intelligence(SKey, l) , + course_difficulty(CKey, m). + +registration_grade(Key, 4): 0.1;registration_grade(Key, 3): 0.4;registration_grade(Key, 2): 0.4 ; + registration_grade(Key, 1): 0.1 :- + registration(Key, CKey, SKey) , + student_intelligence(SKey, l) , + course_difficulty(CKey, l). + + +registration_satisfaction(Key, 3): 0.98 ; registration_satisfaction(Key, 2): 0.01 ; + registration_satisfaction(Key, 1): 0.01 :- + registration(Key, CKey,_), + course(CKey, PKey), + professor_ability(PKey, h), + registration_grade(Key, 4). + +registration_satisfaction(Key, 3): 0.9 ; registration_satisfaction(Key, 2): 0.09 ; + registration_satisfaction(Key, 1): 0.01 :- + registration(Key, CKey,_), + course(CKey, PKey), + professor_ability(PKey, h), + registration_grade(Key, 3). + +registration_satisfaction(Key, 3): 0.8 ; registration_satisfaction(Key, 2): 0.15 ; + registration_satisfaction(Key, 1): 0.05 :- + registration(Key, CKey,_), + course(CKey, PKey), + professor_ability(PKey, h), + registration_grade(Key, 2). + + + +registration_satisfaction(Key, 3): 0.6 ; registration_satisfaction(Key, 2): 0.3 ; + registration_satisfaction(Key, 1): 0.1 :- + registration(Key, CKey,_), + course(CKey, PKey), + professor_ability(PKey, h), + registration_grade(Key, 1). + +registration_satisfaction(Key, 3): 0.9 ; registration_satisfaction(Key, 2): 0.05 ; + registration_satisfaction(Key, 1): 0.05 :- + registration(Key, CKey,_), + course(CKey, PKey), + professor_ability(PKey, m), + registration_grade(Key, 4). + +registration_satisfaction(Key, 3): 0.4 ; registration_satisfaction(Key, 2): 0.4 ; + registration_satisfaction(Key, 1): 0.2 :- + registration(Key, CKey,_), + course(CKey, PKey), + professor_ability(PKey, m), + registration_grade(Key, 3). + +registration_satisfaction(Key, 3): 0.2 ; registration_satisfaction(Key, 2): 0.3 ; + registration_satisfaction(Key, 1): 0.5 :- + registration(Key, CKey,_), + course(CKey, PKey), + professor_ability(PKey, m), + registration_grade(Key, 2). + +registration_satisfaction(Key, 3): 0.01 ; registration_satisfaction(Key, 2): 0.04 ; + registration_satisfaction(Key, 1): 0.95 :- + registration(Key, CKey,_), + course(CKey, PKey), + professor_ability(PKey, m), + registration_grade(Key, 1). + +registration_satisfaction(Key, 3): 0.5 ; registration_satisfaction(Key, 2): 0.35 ; + registration_satisfaction(Key, 1): 0.15 :- + registration(Key, CKey,_), + course(CKey, PKey), + professor_ability(PKey, l), + registration_grade(Key, 4). + +registration_satisfaction(Key, 3): 0.2 ; registration_satisfaction(Key, 2): 0.3 ; + registration_satisfaction(Key, 1): 0.5 :- + registration(Key, CKey,_), + course(CKey, PKey), + professor_ability(PKey, l), + registration_grade(Key, 3). + +registration_satisfaction(Key, 3): 0.01 ; registration_satisfaction(Key, 2): 0.09 ; + registration_satisfaction(Key, 1): 0.9 :- + registration(Key, CKey,_), + course(CKey, PKey), + professor_ability(PKey, l), + registration_grade(Key, 2). + +registration_satisfaction(Key, 3): 0.01 ; registration_satisfaction(Key, 2): 0.01 ; + registration_satisfaction(Key, 1): 0.98 :- + registration(Key, CKey,_), + course(CKey, PKey), + professor_ability(PKey, l), + registration_grade(Key, 1). + +course_rating(CKey, h):0.2; course_rating(CKey, m):0.2;course_rating(CKey, l):0.6:- + bagof(Sat, RKey^(registration_course(RKey,CKey), registration_satisfaction(RKey,Sat)), Sats), + average(Sats, Av),Av<1. + +course_rating(CKey, h):0.2; course_rating(CKey, m):0.6;course_rating(CKey, l):0.2:- + bagof(Sat, RKey^(registration_course(RKey,CKey), registration_satisfaction(RKey,Sat)), Sats), + average(Sats, Av),Av<2,Av>=1. + +course_rating(CKey, h):0.6; course_rating(CKey,m):0.2;course_rating(CKey, l):0.2:- + bagof(Sat, RKey^(registration_course(RKey,CKey), registration_satisfaction(RKey,Sat)), Sats), + average(Sats, Av),Av>=2. + +course_difficulty(Key, h) :0.25 ; course_difficulty(Key, m): 0.5 ; course_difficulty(Key, l) : 0.25. + +student_intelligence(Key, h): 0.5; student_intelligence(Key,m):0.4; student_intelligence(Key,l):0.1. + +student_ranking(Key, h):0.2; student_ranking(Key, m):0.2;student_ranking(Key, l):0.6:- + bagof(Grade, CKey^(registration_student(CKey,Key), + registration_grade(CKey, Grade)), Grades), + average(Grades, Av),Av<1.5. + +student_ranking(Key, h):0.2; student_ranking(Key, m):0.6;student_ranking(Key, l):0.2:- + bagof(Grade, CKey^(registration_student(CKey,Key), + registration_grade(CKey, Grade)), Grades), + average(Grades, Av),Av>=1.5,Av<3.5. + +student_ranking(Key, h):0.6; student_ranking(Key, m):0.2;student_ranking(Key, l):0.2:- + bagof(Grade, CKey^(registration_student(CKey,Key), + registration_grade(CKey, Grade)), Grades), + average(Grades, Av),Av>=3.5. + + +professor(p0). +professor(p1). +professor(p2). +professor(p3). +professor(p4). +professor(p5). +professor(p6). +professor(p7). +professor(p8). +professor(p9). +professor(p10). +professor(p11). +professor(p12). +professor(p13). +professor(p14). +professor(p15). +professor(p16). +professor(p17). +professor(p18). +professor(p19). +professor(p20). +professor(p21). +professor(p22). +professor(p23). +professor(p24). +professor(p25). +professor(p26). +professor(p27). +professor(p28). +professor(p29). +professor(p30). +professor(p31). + + +course(c0,p24). +course(c1,p7). +course(c2,p16). +course(c3,p27). +course(c4,p25). +course(c5,p6). +course(c6,p28). +course(c7,p1). +course(c8,p29). +course(c9,p23). +course(c10,p17). +course(c11,p16). +course(c12,p11). +course(c13,p28). +course(c14,p13). +course(c15,p7). +course(c16,p21). +course(c17,p15). +course(c18,p8). +course(c19,p30). +course(c20,p1). +course(c21,p23). +course(c22,p11). +course(c23,p9). +course(c24,p0). +course(c25,p30). +course(c26,p15). +course(c27,p4). +course(c28,p26). +course(c29,p29). +course(c30,p31). +course(c31,p19). +course(c32,p5). +course(c33,p14). +course(c34,p14). +course(c35,p25). +course(c36,p21). +course(c37,p10). +course(c38,p2). +course(c39,p20). +course(c40,p3). +course(c41,p18). +course(c42,p9). +course(c43,p20). +course(c44,p17). +course(c45,p19). +course(c46,p6). +course(c47,p4). +course(c48,p12). +course(c49,p10). +course(c50,p2). +course(c51,p22). +course(c52,p31). +course(c53,p24). +course(c54,p0). +course(c55,p5). +course(c56,p22). +course(c57,p13). +course(c58,p18). +course(c59,p12). +course(c60,p27). +course(c61,p3). +course(c62,p8). +course(c63,p26). + + +student(s0). +student(s1). +student(s2). +student(s3). +student(s4). +student(s5). +student(s6). +student(s7). +student(s8). +student(s9). +student(s10). +student(s11). +student(s12). +student(s13). +student(s14). +student(s15). +student(s16). +student(s17). +student(s18). +student(s19). +student(s20). +student(s21). +student(s22). +student(s23). +student(s24). +student(s25). +student(s26). +student(s27). +student(s28). +student(s29). +student(s30). +student(s31). +student(s32). +student(s33). +student(s34). +student(s35). +student(s36). +student(s37). +student(s38). +student(s39). +student(s40). +student(s41). +student(s42). +student(s43). +student(s44). +student(s45). +student(s46). +student(s47). +student(s48). +student(s49). +student(s50). +student(s51). +student(s52). +student(s53). +student(s54). +student(s55). +student(s56). +student(s57). +student(s58). +student(s59). +student(s60). +student(s61). +student(s62). +student(s63). +student(s64). +student(s65). +student(s66). +student(s67). +student(s68). +student(s69). +student(s70). +student(s71). +student(s72). +student(s73). +student(s74). +student(s75). +student(s76). +student(s77). +student(s78). +student(s79). +student(s80). +student(s81). +student(s82). +student(s83). +student(s84). +student(s85). +student(s86). +student(s87). +student(s88). +student(s89). +student(s90). +student(s91). +student(s92). +student(s93). +student(s94). +student(s95). +student(s96). +student(s97). +student(s98). +student(s99). +student(s100). +student(s101). +student(s102). +student(s103). +student(s104). +student(s105). +student(s106). +student(s107). +student(s108). +student(s109). +student(s110). +student(s111). +student(s112). +student(s113). +student(s114). +student(s115). +student(s116). +student(s117). +student(s118). +student(s119). +student(s120). +student(s121). +student(s122). +student(s123). +student(s124). +student(s125). +student(s126). +student(s127). +student(s128). +student(s129). +student(s130). +student(s131). +student(s132). +student(s133). +student(s134). +student(s135). +student(s136). +student(s137). +student(s138). +student(s139). +student(s140). +student(s141). +student(s142). +student(s143). +student(s144). +student(s145). +student(s146). +student(s147). +student(s148). +student(s149). +student(s150). +student(s151). +student(s152). +student(s153). +student(s154). +student(s155). +student(s156). +student(s157). +student(s158). +student(s159). +student(s160). +student(s161). +student(s162). +student(s163). +student(s164). +student(s165). +student(s166). +student(s167). +student(s168). +student(s169). +student(s170). +student(s171). +student(s172). +student(s173). +student(s174). +student(s175). +student(s176). +student(s177). +student(s178). +student(s179). +student(s180). +student(s181). +student(s182). +student(s183). +student(s184). +student(s185). +student(s186). +student(s187). +student(s188). +student(s189). +student(s190). +student(s191). +student(s192). +student(s193). +student(s194). +student(s195). +student(s196). +student(s197). +student(s198). +student(s199). +student(s200). +student(s201). +student(s202). +student(s203). +student(s204). +student(s205). +student(s206). +student(s207). +student(s208). +student(s209). +student(s210). +student(s211). +student(s212). +student(s213). +student(s214). +student(s215). +student(s216). +student(s217). +student(s218). +student(s219). +student(s220). +student(s221). +student(s222). +student(s223). +student(s224). +student(s225). +student(s226). +student(s227). +student(s228). +student(s229). +student(s230). +student(s231). +student(s232). +student(s233). +student(s234). +student(s235). +student(s236). +student(s237). +student(s238). +student(s239). +student(s240). +student(s241). +student(s242). +student(s243). +student(s244). +student(s245). +student(s246). +student(s247). +student(s248). +student(s249). +student(s250). +student(s251). +student(s252). +student(s253). +student(s254). +student(s255). + + +registration(r0,c16,s0). +registration(r1,c10,s0). +registration(r2,c57,s0). +registration(r3,c22,s1). +registration(r4,c55,s1). +registration(r5,c27,s1). +registration(r6,c14,s2). +registration(r7,c52,s2). +registration(r8,c10,s2). +registration(r9,c47,s3). +registration(r10,c16,s3). +registration(r11,c62,s3). +registration(r12,c12,s4). +registration(r13,c11,s4). +registration(r14,c17,s4). +registration(r15,c52,s5). +registration(r16,c1,s5). +registration(r17,c35,s5). +registration(r18,c0,s6). +registration(r19,c7,s6). +registration(r20,c40,s6). diff --git a/packages/cplint/examples/school_simple.cpl b/packages/cplint/examples/school_simple.cpl new file mode 100644 index 000000000..3fb1dd79b --- /dev/null +++ b/packages/cplint/examples/school_simple.cpl @@ -0,0 +1,52 @@ +/* + ?- s([registration_grade(r0,X)],P). + + + + +student_ranking(s0,X). +s([student_ranking(s0,h)],P). +P = 0,6646250000000005 ? +s([student_ranking(s0,l)],P). +P = 0,33537499999999987 +ok, checked with s.pl +*/ + + + +registration_course(Key, CKey) :- + registration(Key, CKey, _). + +registration_student(Key, SKey) :- + registration(Key, _, SKey). + +registration_grade(Key, 4): 0.2; + registration_grade(Key, 1): 0.8 :- + registration(Key, CKey, SKey) , + course_difficulty(CKey, h). + + +registration_grade(Key, 4): 0.85; + registration_grade(Key, 1): 0.15 :- + registration(Key, CKey, SKey) , + course_difficulty(CKey, l). + + +course_difficulty(Cou, h) :0.5 ; course_difficulty(Cou, l) : 0.5. + + +student_ranking(Stu, h):0.2; student_ranking(Stu, l):0.8:- + bagof(Grade, CKey^(registration_student(CKey,Stu), + registration_grade(CKey, Grade)), Grades), + average(Grades, Av),Av<2. + +student_ranking(Stu, h):0.8; student_ranking(Stu, l):0.2:- + bagof(Grade, CKey^(registration_student(CKey,Stu), + registration_grade(CKey, Grade)), Grades), + average(Grades, Av),Av>=2. + + + + +registration(r0,c16,s0). +registration(r1,c10,s0). diff --git a/packages/cplint/examples/school_simple.uni b/packages/cplint/examples/school_simple.uni new file mode 100644 index 000000000..7b5b9ea82 --- /dev/null +++ b/packages/cplint/examples/school_simple.uni @@ -0,0 +1,18 @@ +universe(['Stu'],[s0]). +universe(['Key'],[r0,r1]). +universe(['Cou'],[c16,c10]). + +type(stu,[s0]). +type(reg,[r0,r1]). +type(cou,[c16,c10]). +type(gr,[1,4]). +type(dif,[h,l]). +type(ran,[h,l]). + +mode(registration(reg,cou,stu)). +mode(registration_grade(reg,gr)). +mode(registration_course(reg,cou)). +mode(registration_student(reg,stu)). +mode(course_difficulty(cou,dif)). +mode(student_ranking(stu,ran)). + diff --git a/packages/cplint/examples/student.cpl b/packages/cplint/examples/student.cpl new file mode 100644 index 000000000..4f3931feb --- /dev/null +++ b/packages/cplint/examples/student.cpl @@ -0,0 +1,95 @@ +/* +s([student_rank(jane_doe,h)],P). +P = 0.465 + +s([student_rank(jane_doe,l)],P). +P = 0.535 + +s([course_rat(C,h)],P). +C = phil101, +P = 0.330656 + +s([course_rat(C,l)],P). +C = phil101, +P = 0.669344 + +*/ +professor(gump). +%1 +professor_teach_ab(P,h):0.2;professor_teach_ab(P,l):0.8:- + professor(P). +%2 +professor_pop(P,h):0.7;professor_pop(P,l):0.3:- + professor_teach_ab(P,h). +%3 +professor_pop(P,h):0.2;professor_pop(P,l):0.8:- + professor_teach_ab(P,l). + +student(jane_doe). +%4 +student_int(S,h):0.6;student_int(S,l):0.4:- + student(S). +%5 +student_rank(S,h):0.6;student_rank(S,l):0.4:- + bagof(G,R^(registr_stu(R,S),registr_gr(R,G)),L), + average(L,Av),Av>1.5. +%6 +student_rank(S,h):0.4;student_rank(S,l):0.6:- + bagof(G,R^(registr_stu(R,S),registr_gr(R,G)),L), + average(L,Av),Av =< 1.5. + +registr(5639). + +registr_cou(5639,phil101). + +registr_stu(5639,jane_doe). + +registr(5640). + +registr_cou(5640,phil101). + +registr_stu(5640,jane_doe). + +%7 +registr_gr(Reg,1):0.5;registr_gr(Reg,2):0.5:- + registr_stu(Reg,S),student_int(S,h),registr_cou(Reg,C),course_dif(C,h). +%8 +registr_gr(Reg,1):0.2;registr_gr(Reg,2):0.8:- + registr_stu(Reg,S),student_int(S,h),registr_cou(Reg,C),course_dif(C,l). +%9 +registr_gr(Reg,1):0.8;registr_gr(Reg,2):0.2:- + registr_stu(Reg,S),student_int(S,l),registr_cou(Reg,C),course_dif(C,h). +%10 +registr_gr(Reg,1):0.5;registr_gr(Reg,2):0.5:- + registr_stu(Reg,S),student_int(S,l),registr_cou(Reg,C),course_dif(C,l). +%11 +registr_sat(Reg,1):0.2;registr_sat(Reg,2):0.8:- + registr_gr(Reg,2),registr_cou(Reg,C),course_prof(C,P), + professor_teach_ab(P,h). +%12 +registr_sat(Reg,1):0.4;registr_sat(Reg,2):0.6:- + registr_gr(Reg,2),registr_cou(Reg,C),course_prof(C,P), + professor_teach_ab(P,l). +%13 +registr_sat(Reg,1):0.6;registr_sat(Reg,2):0.4:- + registr_gr(Reg,1),registr_cou(Reg,C),course_prof(C,P), + professor_teach_ab(P,h). +%14 +registr_sat(Reg,1):0.8;registr_sat(Reg,2):0.2:- + registr_gr(Reg,1),registr_cou(Reg,C),course_prof(C,P), + professor_teach_ab(P,l). + +course(phil101). + +course_prof(phil101,gump). +%15 +course_dif(C,h):0.5;course_dif(C,l):0.5:- + course(C). +%16 +course_rat(C,h):0.8;course_rat(C,l):0.2:- + bagof(Stu,R^(registr_cou(R,C),registr_sat(R,Stu)),L), + average(L,Av),Av>1.5. +%17 +course_rat(C,h):0.2;course_rat(C,l):0.8:- + bagof(Stu,R^(registr_cou(R,C),registr_sat(R,Stu)),L), + average(L,Av),Av=< 1.5. diff --git a/packages/cplint/examples/student.uni b/packages/cplint/examples/student.uni new file mode 100644 index 000000000..48ff2de0a --- /dev/null +++ b/packages/cplint/examples/student.uni @@ -0,0 +1,29 @@ +universe(['S'],[jane_doe]). +universe(['P'],[gump]). +universe(['Reg'],[5639,5640]). +universe(['C'],[phil101]). + +type(prof,[gump]). +type(stu,[jane_doe]). +type(abi,[l,h]). +type(int,[h,l]). +type(reg,[5639,5640]). +type(cou,[phil101]). +type(gr,[1,2]). +type(sat,[1,2]). +type(dif,[h,l]). +type(rat,[h,l]). + +mode(professor(prof)). +mode(professor_teach_ab(prof,abi) +mode(student(stu)). +mode(student_int(stu,int)). +mode(registr(reg)). +mode(registr_cou(reg,cou)). +mode(registr_stu(reg,stu)). +mode(registr_gr(reg,gr)). +mode(registr_sat(reg,sat)). +mode(course(cou)). +mode(course_prof(cou,prof)). +mode(course_dif(cou,dif)). +mode(course_rat(cou,rat)). diff --git a/packages/cplint/examples/threesideddice.cpl b/packages/cplint/examples/threesideddice.cpl new file mode 100644 index 000000000..adf114740 --- /dev/null +++ b/packages/cplint/examples/threesideddice.cpl @@ -0,0 +1,39 @@ +/* +s([on(0,1)],P). +P = 0.333333333333333 ? + +s([on(1,1)],P). +P = 0.222222222222222 +s([on(2,1)],P). +P = 0.148148147703704 +s([on(3,1)],P). +% OUT OF DATABASE SPACE ERROR- Database crashed against Stacks +s([on(4,1)],P). +% OUT OF DATABASE SPACE ERROR- Database crashed against Stacks +s([on(5,1)],P). +% OUT OF DATABASE SPACE ERROR- Database crashed against Stacks + +s([on(0,1),on(1,1)],P). +P = 0.111111111111111 +s([on(0,1),on(1,1),on(2,1)],P). +P = 0.037037037037037 +sc([on(1,1)],[on(0,1)],P). +P = 0.333333333333333 + +sc([on(2,1)],[on(0,1)],P). +P = 0.222222222222222 + +sc([on(3,1)],[on(0,1)],P). +P = 0.148148148148148 + +sc([on(2,1)],[on(1,1)],P). +P = 0.333333333333333 ? + + +*/ +on(0,1):1/3;on(0,2):1/3;on(0,3):1/3. + +on(X,1):1/3;on(X,2):1/3;on(X,3):1/3:- + X1 is X-1,X1>=0, + on(X1,Y), + \+ on(X1,3). diff --git a/packages/cplint/examples/threesideddice.uni b/packages/cplint/examples/threesideddice.uni new file mode 100644 index 000000000..4aa40cc92 --- /dev/null +++ b/packages/cplint/examples/threesideddice.uni @@ -0,0 +1,9 @@ +mode(on(time,face)). + +type(time,[0,1,2]). + +type(face,[1,2,3]). + +universe(['X'],[0,1,2]). +universe(['X1'],[0,1,2]). +universe(['Y'],[1,2,3]). diff --git a/packages/cplint/examples/throws.cpl b/packages/cplint/examples/throws.cpl new file mode 100644 index 000000000..a27096ea5 --- /dev/null +++ b/packages/cplint/examples/throws.cpl @@ -0,0 +1,21 @@ +/* +no + ?- s([throws(mary),throws(john),break],P). +P = 0.46 ? +yes + ?- s([throws(mary),throws(john),\+break],P). +P = 0.04 ? +yes + ?- s([\+ throws(mary),throws(john),break],P). +P = 0.3 ? +yes + ?- s([\+ throws(mary),throws(john),\+ break],P). +P = 0.2 ? +yes + ?- + */ + +break : 0.8 :- throws(mary). +break : 0.6 :- throws(john). +throws(mary) : 0.5. +throws(john). diff --git a/packages/cplint/examples/throws.uni b/packages/cplint/examples/throws.uni new file mode 100644 index 000000000..4f2237fc9 --- /dev/null +++ b/packages/cplint/examples/throws.uni @@ -0,0 +1,6 @@ + +type(person,[mary,john]). + +mode(break). + +mode(throws(person)). diff --git a/packages/cplint/examples/trigger.cpl b/packages/cplint/examples/trigger.cpl new file mode 100644 index 000000000..d7dd60bc7 --- /dev/null +++ b/packages/cplint/examples/trigger.cpl @@ -0,0 +1,13 @@ +/* + + ?- s([death],P). +P = 0.305555555555556 ? +yes + ?- +*/ + +death : 1/6 :- pull_trigger(left_gun). +death : 1/6 :- pull_trigger(right_gun). + +pull_trigger(left_gun). +pull_trigger(right_gun). diff --git a/packages/cplint/examples/trigger.uni b/packages/cplint/examples/trigger.uni new file mode 100644 index 000000000..ab4bf8f01 --- /dev/null +++ b/packages/cplint/examples/trigger.uni @@ -0,0 +1,4 @@ +mode(death). +mode(pull_trigger(gun)). + +type(gun,[left_gun,right_gun]). diff --git a/packages/cplint/examples/twosideddice.cpl b/packages/cplint/examples/twosideddice.cpl new file mode 100644 index 000000000..397645e94 --- /dev/null +++ b/packages/cplint/examples/twosideddice.cpl @@ -0,0 +1,21 @@ +/* + +s([on(3,1)],P). +P = 0.0625 +sc([on(3,1)],[on(2,1)],P). +P = 0.5 ? + +sc([on(4,1)],[on(2,1)],P). +P = 0.25 + +sc([on(10,1)],[on(2,1)],P). +P = 0.00390625 + + +*/ +on(0,1):0.5;on(0,2):0.5. + +on(X,1):0.5;on(X,2):0.5:- + X1 is X-1,X1>=0, + on(X1,Y), + \+ on(X1,2). diff --git a/packages/cplint/examples/win.cpl b/packages/cplint/examples/win.cpl new file mode 100644 index 000000000..988f0fd16 --- /dev/null +++ b/packages/cplint/examples/win.cpl @@ -0,0 +1,14 @@ +/* + ?- s([win(white)],P). +P = 0.5 ? +yes + ?- s([win(black)],P). +P = 0.5 ? +yes + ?- s([win(black),win(white)],P). +P = 0 ? +*/ + +win(white) :- \+ win(black). +win(black):- \+ win(white). +win(white) : 0.5 ; win(black) : 0.5. diff --git a/packages/cplint/examples/win.uni b/packages/cplint/examples/win.uni new file mode 100644 index 000000000..3561396a2 --- /dev/null +++ b/packages/cplint/examples/win.uni @@ -0,0 +1,6 @@ + +mode(win(player)). + + +type(player,[white,black]). + diff --git a/packages/cplint/lpad.pl b/packages/cplint/lpad.pl new file mode 100644 index 000000000..826996405 --- /dev/null +++ b/packages/cplint/lpad.pl @@ -0,0 +1,2257 @@ +/* + LPAD and CP-Logic reasoning suite + File lpad.pl + Goal-oriented interpreter for LPADs based on SLG + Copyright (c) 2007, Fabrizio Riguzzi + Based on the SLG System, see below +*/ + +/***************************************************************************/ +/* */ +/* The SLG System */ +/* Authors: Weidong Chen and David Scott Warren */ +/* Copyright (C) 1993 Southern Methodist University */ +/* 1993 SUNY at Stony Brook */ +/* See file COPYRIGHT_SLG for copying policies and disclaimer. */ +/* */ +/***************************************************************************/ + +/*========================================================================== + File : slg.pl + Last Modification : November 1, 1993 by Weidong Chen +=========================================================================== + File : lpad.pl + Last Modification : November 14, 2007 by Fabrizio Riguzzi +===========================================================================*/ + +/* ----------- beginning of system dependent features --------------------- + To run the SLG system under a version of Prolog other than Quintus, + comment out the following Quintus-specific code, and include the code + for the Prolog you are running. +*/ +:- module(lpad, [s/2,s/6, + sc/3,sc/7, + p/1, + slg/3,setting/2,set/2 + ]). + + :- dynamic wfs_trace/0. + :-use_module(library(ugraphs)). + :-use_module(library(lists)). + :- use_module(library(charsio)). + + +:- op(1200,xfx,<--). +:- op(900,xfx,<-). + + + + +/* SLG tracing: + xtrace: turns SLG trace on, which prints out tables at various + points + xnotrace: turns off SLG trace +*/ +xtrace :- + ( wfs_trace -> + true + ; assert(wfs_trace) + ). +xnotrace :- + ( wfs_trace -> + retractall(wfs_trace) + ; true + ). + +/* isprolog(Call): Call is a Prolog subgoal */ +isprolog(Call) :- + builtin(Call). + +/* slg(Call): + It returns all true answers of Call under the well-founded semantics + one by one. +*/ +slg(Call,C,D):- + slg(Call,[],C,[],D). + +slg(Call,C0,C,D0,D):- + ( isprolog(Call) -> + call(Call), + C=C0, + D=D0 + ; oldt(Call,Tab,C0,C1,D0,D1), + delete(D1,(goal(_),_),D), + ground(Call,Ggoal), + find(Tab,Ggoal,Ent), + ent_to_anss(Ent,Anss), + member_anss(d(Call,Delay),Anss), + (Delay=[]-> + C=C1 + ; + write('Unsound program'), + nl, + C=unsound + ) + ). + +get_new_atom(Atom):- + retract(new_number(N)), + N1 is N+1, + assert(new_number(N1)), + number_atom(N,NA), + atom_concat('$call',NA,Atom). + +s(GoalsList,Prob):- + convert_to_goal(GoalsList,Goal), + solve(Goal,Prob). + +s(GoalsList,Prob,CPUTime1,0.0,WallTime1,0.0):- + statistics(cputime,[_,_]), + statistics(walltime,[_,_]), + convert_to_goal(GoalsList,Goal), + solve(Goal,Prob), + statistics(cputime,[_,CT1]), + CPUTime1 is CT1/1000, + statistics(walltime,[_,WT1]), + WallTime1 is WT1/1000. + +convert_to_goal([Goal],Goal):-Goal \= (\+ _) ,!. + +convert_to_goal(GoalsList,Head):- + get_new_atom(Atom), + extract_vars(GoalsList,[],V), + Head=..[Atom|V], + assertz(def_rule(goal(Atom),_,Head,GoalsList)). + + +solve(Goal,Prob):- + (setof(C,D^slg(Goal,C,D),LDup)-> + (member(unsound,LDup)-> + format("Unsound program ~n",[]), + Prob=unsound + ; + rem_dup_lists(LDup,[],L), + (ground(L)-> + build_formula(L,Formula,[],Var), + var2numbers(Var,0,NewVar), + (setting(save_dot,true)-> + format("Variables: ~p~n",[Var]), + compute_prob(NewVar,Formula,_Prob,1) + ; + compute_prob(NewVar,Formula,Prob,0) + ) + ; + format("It requires the choice of a head atom from a non ground head~n~p~n",[L]), + Prob=non_ground + ) + ) + ; + Prob=0 + ). + +compute_prob(Var,For,Prob,_):- + compute_prob_term(Var,For,0,Prob). + +compute_prob_term(_Var,[],Prob,Prob). + +compute_prob_term(Var,[H|T],Prob0,Prob):- + compute_prob_factor(Var,H,1,PF), + Prob1 is Prob0 + PF, + compute_prob_term(Var,T,Prob1,Prob). + +compute_prob_factor(_Var,[],PF,PF). + +compute_prob_factor(Var,[[N,Value]|T],PF0,PF):- + nth0(N,Var,[_N,_NH,ListProb]), + nth0(Value,ListProb,P), + PF1 is PF0*P, + compute_prob_factor(Var,T,PF1,PF). + +sc(Goals,Evidences,Prob):- + convert_to_goal(Goals,Goal), + convert_to_goal(Evidences,Evidence), + solve_cond(Goal,Evidence,Prob). + +sc(Goals,Evidences,Prob,CPUTime1,0.0,WallTime1,0.0):- + statistics(cputime,[_,_]), + statistics(walltime,[_,_]), + convert_to_goal(Goals,Goal), + convert_to_goal(Evidences,Evidence), + solve_cond(Goal,Evidence,Prob), + statistics(cputime,[_,CT1]), + CPUTime1 is CT1/1000, + statistics(walltime,[_,WT1]), + WallTime1 is WT1/1000. + +solve_cond(Goal,Evidence,Prob):- + (setof(DerivE,D^slg(Evidence,DerivE,D),LDupE)-> + rem_dup_lists(LDupE,[],LE), + build_formula(LE,FormulaE,[],VarE), + var2numbers(VarE,0,NewVarE), + compute_prob(NewVarE,FormulaE,ProbE,0), + solve_cond_goals(Goal,LE,ProbGE), + Prob is ProbGE/ProbE + ; + format("P(Evidence)=0~n",[]), + Prob=undefined + ). + +solve_cond_goals(Goals,LE,ProbGE):- + (setof(DerivGE,find_deriv_GE(LE,Goals,DerivGE),LDupGE)-> + rem_dup_lists(LDupGE,[],LGE), + build_formula(LGE,FormulaGE,[],VarGE), + var2numbers(VarGE,0,NewVarGE), + call_compute_prob(NewVarGE,FormulaGE,ProbGE) + ; + ProbGE=0 + ). + +solve_cond_goals(Goals,LE,0):- + \+ find_deriv_GE(LE,Goals,_DerivGE). + +find_deriv_GE(LD,GoalsList,Deriv):- + member(D,LD), + slg(GoalsList,D,DerivDup,[],_Def), + remove_duplicates(DerivDup,Deriv). + +call_compute_prob(NewVarGE,FormulaGE,ProbGE):- + (setting(save_dot,true)-> + format("Variables: ~p~n",[NewVarGE]), + compute_prob(NewVarGE,FormulaGE,ProbGE,1) + ; + compute_prob(NewVarGE,FormulaGE,ProbGE,0) + ). + + +/* emptytable(EmptTab): creates an initial empty stable. +*/ +emptytable(0:[]). + +/* slgall(Call,Anss): + slgall(Call,Anss,N0-Tab0,N-Tab): + If Call is a prolog call, findall is used, and Tab = Tab0; + If Call is an atom of a tabled predicate, SLG evaluation + is carried out. +*/ +slgall(Call,Anss) :- + slgall(Call,Anss,0:[],_). +slgall(Call,Anss,N0:Tab0,N:Tab) :- + ( isprolog(Call) -> + findall(Call,Call,Anss), + N = N0, Tab = Tab0 + ; ground(Call,Ggoal), + ( find(Tab0,Ggoal,Ent) -> + ent_to_anss(Ent,Answers), + Tab = Tab0 + ; new_init_call(Call,Ggoal,Ent,[],S1,1,Dfn1), + add_tab_ent(Ggoal,Ent,Tab0,Tab1), + oldt(Call,Ggoal,Tab1,Tab,S1,_S,Dfn1,_Dfn,maxint-maxint,_Dep,N0:[],N:_TP), + find(Tab,Ggoal,NewEnt), + ent_to_anss(NewEnt,Answers) + ), + ansstree_to_list(Answers,Anss,[]) + ). + + +/* oldt(QueryAtom,Table,C0,C,D0,D): top level call for SLG resolution. + It returns a table consisting of answers for each relevant + subgoal. For stable predicates, it basically extract the + relevant set of ground clauses by solving Prolog predicates + and other well-founded predicates. +*/ +oldt(Call,Tab,C0,C,D0,D) :- + new_init_call(Call,Ggoal,Ent,[],S1,1,Dfn1), + add_tab_ent(Ggoal,Ent,[],Tab1), + oldt(Call,Ggoal,Tab1,Tab,S1,_S,Dfn1,_Dfn,maxint-maxint,_Dep,0:[],_TP,C0,C1,D0,D,PC), + add_PC_to_C(PC,C1,C), + ( wfs_trace -> + nl, write('Final '), display_table(Tab), nl + ; true + ). + +/* oldt(Call,Ggoal,Tab0,Tab,Stack0,Stack,DFN0,DFN,Dep0,Dep,TP0,TP,C0,C,D0,D,PC) + explores the initial set of edges, i.e., all the + program clauses for Call. Ggoal is of the form + Gcall-Gdfn, where Gcall is numbervar of Call and Gdfn + is the depth-first number of Gcall. Tab0/Tab,Stack0/Stack, + DFN0/DFN, and Dep0/Dep are accumulators for the table, + the stack of subgoals, the DFN counter, and the dependencies. + TP0/TP is the accumulator for newly created clauses during + the processing of general clauss with universal disjunctions + in the body. These clauses are created in order to guarantee + polynomial data complexity in processing clauses with + universal disjuntions in the body of a clause. The newly + created propositions are represented by numbers. + C0/C are accumulators for disjunctive clauses used in the derivation of Call: + they are list of triples (N,R,S) where N is the number of the head atom used + (starting from 0), R is the number of the rule used (starting from 1) and + S is the substitution of the variables in the head atom used. S is a list + of elements of the form Varname=Term. + D0/D are accumulators for definite clauses: they are list of couples (R,S), + where R is a rule number and S is a substitution. + PC is a list of disjunctive rules selected but not used in the derivation, + they are added to the C set afterwards if they are consistent with C + (PC stands for Possible C, i.e., possible additions to the C set). +*/ +oldt(Call,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C,D0,D,PC) :- + ( number(Call) -> + TP0 = (_ : Tcl), + find(Tcl,Call,Clause), + edge_oldt(Clause,Ggoal,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1, + C0,C,D0,D) + ; find_rules(Call,Frames,C0,PC), + map_oldt(Frames,Ggoal,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1, + C0,C,D0,D) + ), + comp_tab_ent(Ggoal,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP). + +/* find_rules(Call,Frames,C,PossC) + finds rules for Call. Frames is the list of clauses that resolve with Call. It + is a list of terms of the form + rule(d(Call,[]),Body,R,N,S) + C is the current set of disjunctive clauses together with the head selected + PossC is the list of possible disjunctive clauses together with the head + selected: they are the clauses with an head that does not unify with Call. It + is a list of terms of the form + rule(d(Call,[]),Body,R,N,S) +*/ +find_rules(Call,Frames,C,PossC):- + findall(rule(d(Call,[]),Body,def(N),_,Subs,_),def_rule(N,Subs,Call,Body),Fr1), + find_disj_rules(Call,Fr2,C,PossC), + append(Fr1,Fr2,Frames). + +/* find_disj_rules(Call,Fr,C,PossC):- + finds disjunctive rules for Call. +*/ +find_disj_rules(Call,Fr,C,[]):- + findall(rule(d(Call,[]),Body,R,N,S,LH), + find_rule(Call,(R,S,N),Body,LH),Fr). + +find_disj_rulesold(Call,Fr,C,PossC):- + findall(rule(d(Call,[]),Body,R,S,N,LH), + find_rule(Call,(R,S,N),Body,LH),LD), + (setof((R,LH),(Call,Body,S,N)^member(rule(d(Call,[]),Body,R,S,N,LH),LD),LR)-> + choose_rules(LR,LD,[],Fr,C,[],PossC) + ; + Fr=[], + PossC=[] + ). + + + +/* choose_rules(LR,LD,Fr0,Fr,C,PossC0,PossC) + LR is a list of couples (R,LH) where R is a disjunctive rule number and LH is + a list of head atoms numbers, from 0 to length(head)-1 + LD is the list of disjunctive clauses resolving with Call. Its elements are + of the form + rule(d(Call,[]),Body,R,N,S) + Fr0/Fr are accumulators for the matching disjunctive clauses + PossC0/PossC are accumulators for the additional disjunctive clauses + +*/ +choose_rules([],Fr,Fr,_C,PC,PC). + +choose_rules([rule(d(Call,[]),Body,R,S,N1,LH)|LD],Fr0,Fr,C,PC0,PC):- + member(N,LH), + (N=N1-> + % the selected head resolves with Call + consistent(N,R,S,C), + Fr=[rule(d(Call,[]),Body,R,N,S)|Fr1], + PC=PC1 + ; + % the selected head does not resolve with Call + consistent(N,R,S,C), + Fr=[rule(d('$null',[]),Body,R,N,S)|Fr1], + PC=PC1 + ), + choose_rules(LD,Fr0,Fr1,C,PC0,PC1). + +choose_rulesold([],_LD,Fr,Fr,_C,PC,PC). + +choose_rulesold([(R,LH)|LR],LD,Fr0,Fr,C,PC0,PC):- + member(N,LH), + (member(rule(d(Call,[]),Body,R,S,N,LH),LD)-> + % the selected head resolves with Call + consistent(N,R,S,C), + Fr=[rule(d(Call,[]),Body,R,N,S)|Fr1], + PC=PC1 + ; + % the selected head does not resolve with Call + findall(S,member(rule(d(Call,[]),Body,R,S,_N,LH),LD),LS), + % this is done to handle the case in which there are + % multiple instances of rule R with different substitutions + (merge_subs(LS,S)-> + % all the substitutions are consistent, their merge is used + consistent(N,R,S,C), + Fr=Fr1, + PC=[rule(d(_Call,[]),Body,R,N,S)|PC1] + ; + % the substitutions are inconsistent, the empty substitution is used + rule(R,S,_LH,_Head,_Body), + consistent(N,R,S,C), + Fr=Fr1, + PC=[rule(d(_Call,[]),Body,R,N,S)|PC1] + ) + ), + choose_rules(LR,LD,Fr0,Fr1,C,PC0,PC1). + +merge_subs([],_S). + +merge_subs([S|ST],S):- + merge_subs(ST,S). + +merge_subs([],_Call,_S). + +merge_subs([(S,Call)|ST],Call,S):- + merge_subs(ST,Call,S). + +/* consistent(N,R,S,C) + head N of rule R with substitution S is consistent with C +*/ + +consistent(_N,_R,_S,[]):-!. + +consistent(N,R,S,[(_N,R1,_S)|T]):- +% different rule + R\=R1,!, + consistent(N,R,S,T). + +consistent(N,R,S,[(N,R,_S)|T]):- +% same rule, same head + consistent(N,R,S,T). + +consistent(N,R,S,[(N1,R,S1)|T]):- +% same rule, different head + N\=N1, +% different substitutions + dif(S,S1), + consistent(N,R,S,T). + + + +map_oldt([],_Ggoal,Tab,Tab,S,S,Dfn,Dfn,Dep,Dep,TP,TP,C,C,D,D). +map_oldt([Clause|Frames],Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP, + C0,C,D0,D) :- + edge_oldt(Clause,Ggoal,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1, + C0,C1,D0,D1), + map_oldt(Frames,Ggoal,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP,C1,C,D1,D). + +/* edge_oldt(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + Clause may be one of the following forms: + rule(d(H,Dlist),Blist) + rule(d(H,all(Dlist)),all(Blist)) + where the second form is for general clauses with a universal + disjunction of literals in the body. Dlist is a list of delayed + literals, and Blist is the list of literals to be solved. + Clause represents a directed edge from Ggoal to the left most + subgoal in Blist. +*/ +edge_oldt(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C,D0,D) :- + Clause = rule(Ans,B,Rule,Number,Sub,LH), + ( B == [] -> + ans_edge(rule(Ans,B,Rule,Number,Sub,LH),Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C,D0,D) + ; B = [Lit|_] -> + ( Lit = (\+N) -> + neg_edge(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C,D0,D) + ; pos_edge(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C,D0,D) + ) + ; B = all(Bl) -> + ( Bl == [] -> + ans_edge(Ans,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + ; Bl = [Lit|_], + ( Lit = (\+N) -> + aneg_edge(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + ; apos_edge(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + ) + ) + ). +/* add_ans_to_C(rule(Head,Body,R,N,S),C0,C,D0,D):- + adds rule rule(Head,Body,R,N,S) to the C set if it is disjunctive + or to the D set if it is definite. The rule is added only if it is consistent + with the current C set +*/ +add_ans_to_C(rule(_,_,def(N),_,S,_),C,C,D,[(N,S)|D],true):-!. + +add_ans_to_C(rule(_Ans,_B,R,N,S,LH),C0,C,D,D,HeadSelected):- + member(N1,LH), + (N1=N-> + HeadSelected=true + ; + HeadSelected=false + ), + \+ already_present_with_a_different_head(N1,R,S,C0), + (already_present_with_the_same_head(N1,R,S,C0)-> + C=C0 + ; + C=[(N1,R,S)|C0] + ). +/* already_present_with_the_same_head(N,R,S,C) + succeeds if rule R is present in C with head N and substitution S +*/ +already_present_with_the_same_head(N,R,S,[(N,R,S)|_T]):-!. + +already_present_with_the_same_head(N,R,S,[(_N,_R,_S)|T]):-!, + already_present_with_the_same_head(N,R,S,T). + +/* already_present_with_a_different_head(N,R,S,C) + succeeds if rule R is present in C with susbtitution S and a head different + from N +*/ + +already_present_with_a_different_head(N,R,S,[(N1,R,S1)|_T]):- + different_head(N,N1,S,S1),!. + +already_present_with_a_different_head(N,R,S,[(_N1,_R1,_S1)|T]):- + already_present_with_a_different_head(N,R,S,T). + +different_head(N,N1,S,S1):- + N\=N1,S=S1, !. + +/* add_PC_to_C(PossC,C0,C) + adds the rules in PossC to C if they are consistent with it, otherwise it + fails +*/ +add_PC_to_C([],C,C). + +add_PC_to_C([rule(H,B,R,N,S)|T],C0,C):- + add_ans_to_C(rule(H,B,R,N,S),C0,C1,[],[]), + add_PC_to_C(T,C1,C). + +ans_edge(rule(Ans,B,Rule,Number,Sub,LH),Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C,D0,D) :- + add_ans_to_C(rule(Ans,B,Rule,Number,Sub,LH),C0,C1,D0,D1,HeadSelected), + (HeadSelected=false-> + Tab = Tab0, S = S0, Dfn = Dfn0, Dep = Dep0, TP = TP0, C=C1, D=D1 + ; + (add_ans(Tab0,Ggoal,Ans,Nodes,Mode,Tab1) -> + (Mode = new_head -> + returned_ans(Ans,Ggoal,RAns), + map_nodes(Nodes,RAns,Tab1,Tab, + S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C1,C,D1,D) + ; + Mode = no_new_head -> + Tab = Tab1, S = S0, Dfn = Dfn0, Dep = Dep0, + TP = TP0, C=C1, D=D1 + ) + ; + Tab = Tab0, S = S0, Dfn = Dfn0, Dep = Dep0, TP = TP0, C=C1, D=D1 + ) + ). + +neg_edge(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C,D0,D) :- + Clause = rule(_,[\+N|_],_R,_N,_Sub,_LH), + ( ground(N) -> true + ; write('Flounder: '), write(\+N), nl, fail + ), + Node = (Ggoal:Clause), + Ngoal = N, % N is already ground + ( isprolog(N) -> % if N is a Prolog predicate + ( call(N) -> % then just call + Tab = Tab0, S = S0, Dfn = Dfn0, Dep = Dep0, C=C0, D=D0, TP = TP0 + ; apply_subst(Node,d(\+ N,[]),Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C1,D0,D) + ) + ; ( find(Tab0,Ngoal,Nent) -> + Tab2 = Tab0, S2 = S0, Dfn2 = Dfn0, Dep2 = Dep0, TP2 = TP0, C2=C0, D2=D0 + ; new_init_call(N,Ngoal,Ent,S0,S1,Dfn0,Dfn1), + add_tab_ent(Ngoal,Ent,Tab0,Tab1), + oldt(N,Ngoal,Tab1,Tab2,S1,S2,Dfn1,Dfn2,maxint-maxint,Ndep,TP0,TP2,C0,C1,D0,D2,PC), + add_PC_to_C(PC,C1,C2), + compute_mins(Dep0,Ndep,pos,Dep2), + find(Tab2,Ngoal,Nent) + ), + ent_to_comp(Nent,Ncomp), + ent_to_anss(Nent,Nanss), + ( succeeded(Nanss) -> + Tab = Tab2, S = S2, Dfn = Dfn2, Dep = Dep2, TP = TP2, C =C2, D=D2 + ; failed(Nanss), Ncomp == true -> + apply_subst(Node,d(\+N,[]),Tab2,Tab,S2,S,Dfn2,Dfn,Dep2,Dep,TP2,TP,C2,C,D2,D) + ; apply_subst(Node,d(\+N,[\+N]),Tab2,Tab,S2,S,Dfn2,Dfn,Dep2,Dep,TP2,TP,C2,C,D2,D) + ) + ). + +pos_edge(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C,D0,D) :- + Clause = rule(_H,[N|_B],_R,_N,_Sub,_LH), + Node = (Ggoal:Clause), + ground(N,Ngoal), + ( isprolog(N) -> + findall(d(N,[]),call(N),Nanss), + map_anss_list(Nanss,Node,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C,D0,D) + ; ( find(Tab0,Ngoal,Nent) -> + ent_to_comp(Nent,Ncomp), + ent_to_anss(Nent,Nanss), + ( Ncomp \== true -> + update_lookup_mins(Ggoal,Node,Ngoal,pos,Tab0,Tab1,Dep0,Dep1), + map_anss(Nanss,Node,Ngoal,Tab1,Tab,S0,S,Dfn0,Dfn,Dep1,Dep,TP0,TP,C0,C,D0,D) + ; % N is completed. + map_anss(Nanss,Node,Ngoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C,D0,D) + ) + ; % otherwise N is new + new_pos_call(Ngoal,Node,Ent,S0,S1,Dfn0,Dfn1), + add_tab_ent(Ngoal,Ent,Tab0,Tab1), + oldt(N,Ngoal,Tab1,Tab2,S1,S,Dfn1,Dfn,maxint-maxint,Ndep,TP0,TP,C0,C1,D0,D,PC), + add_PC_to_C(PC,C1,C), + update_solution_mins(Ggoal,Ngoal,pos,Tab2,Tab,Ndep,Dep0,Dep) + ) + ). + +aneg_edge(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + Clause = rule(_H,all([\+N|_B])), + Node = (Ggoal:Clause), + ground(N,Ngoal), + ( isprolog(N) -> + findall(d(N,[]),call(N),Nanss), + return_to_disj_list(Nanss,Node,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + ; ( find(Tab0,Ngoal,Nent) -> + ent_to_comp(Nent,Ncomp), + ent_to_anss(Nent,Nanss), + ( Ncomp \== true -> + update_lookup_mins(Ggoal,Node,Ngoal,aneg,Tab0,Tab,Dep0,Dep), + S = S0, Dfn = Dfn0, TP = TP0 + ; % N is completed. + return_to_disj(Nanss,Node,Ngoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + ) + ; % otherwise N is new + new_aneg_call(Ngoal,Node,Ent,S0,S1,Dfn0,Dfn1), + add_tab_ent(Ngoal,Ent,Tab0,Tab1), + oldt(N,Ngoal,Tab1,Tab2,S1,S,Dfn1,Dfn,maxint-maxint,Ndep,TP0,TP), + update_solution_mins(Ggoal,Ngoal,pos,Tab2,Tab,Ndep,Dep0,Dep) + ) + ). + +apos_edge(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + Clause = rule(d(H,D),all([N|B])), + ( ground(N) -> true + ; write('Flounder in a universal disjunction: '), + write(N), + nl, + fail + ), + pos_edge(rule(d(H,[]),[N]),Ggoal,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1), + edge_oldt(rule(d(H,D),all(B)),Ggoal,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP). + +apply_subst(Ggoal:Cl,d(An,Vr),Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C,D0,D) :- + copy_term(Cl,rule(d(Ac,Vc),Body,R,N,Sub,LH)), + ( Body = [Call|NBody] -> + Call = An, + append(Vr,Vc,Vn) + ; Body = all([Call|Calls]), + % Call = An, % An is the numbervar-ed version of Call. + ( Vc == [] -> + Vn = all(Vr) + ; Vc = all(Vc0), + append(Vr,Vc0,Vn0), + Vn = all(Vn0) + ), + NBody = all(Calls) + ), + edge_oldt(rule(d(Ac,Vn),NBody,R,N,Sub,LH),Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C,D0,D). + +/* map_nodes(Nodes,Ans,....): + return Ans to each of the waiting nodes in Nodes, where a node + is of the form Ggoal:Clause. +*/ +map_nodes([],_Ans,Tab,Tab,S,S,Dfn,Dfn,Dep,Dep,TP,TP,C,C,D,D). +map_nodes([Node|Nodes],Ans,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C,D0,D) :- + apply_subst(Node,Ans,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1,C0,C1,D0,D1), + map_nodes(Nodes,Ans,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP,C1,C,D1,D). + +map_anss([],_Node,_Ngoal,Tab,Tab,S,S,Dfn,Dfn,Dep,Dep,TP,TP,C,C,D,D). +map_anss(l(_GH,Lanss),Node,Ngoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C,D0,D) :- + ( Lanss == [] -> + Tab = Tab0, S = S0, Dfn = Dfn0, Dep = Dep0, TP = TP0, C=C0, D=D0 + ; Lanss = [Ans|_], + returned_ans(Ans,Ngoal,RAns), + apply_subst(Node,RAns,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C,D0,D) + ). +map_anss(n2(T1,_,T2),Node,Ngoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C,D0,D) :- + map_anss(T1,Node,Ngoal,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1,C0,C1,D0,D1), + map_anss(T2,Node,Ngoal,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP,C1,C,D1,D). +map_anss(n3(T1,_,T2,_,T3),Node,Ngoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C,D0,D) :- + map_anss(T1,Node,Ngoal,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1,C0,C1,D0,D1), + map_anss(T2,Node,Ngoal,Tab1,Tab2,S1,S2,Dfn1,Dfn2,Dep1,Dep2,TP1,TP2,C1,C2,D1,D2), + map_anss(T3,Node,Ngoal,Tab2,Tab,S2,S,Dfn2,Dfn,Dep2,Dep,TP2,TP,C2,C,D2,D). + +map_anss_list([],_Node,Tab,Tab,S,S,Dfn,Dfn,Dep,Dep,TP,TP,C,C,D,D). +map_anss_list([Ans|Lanss],Node,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP,C0,C,D0,D) :- + apply_subst(Node,Ans,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1,C0,C1,D0,D1), + map_anss_list(Lanss,Node,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP,C1,C,D1,D). + +/* return_to_disj(Nanss,Node,Ngoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + Nanss: an answer table for Ngoal + Node: is of the form (Ggoal:Clause), where Clause is of the form + rule(d(H,D),all([\+N|B])) + It carries out resolution of each answer with Clause, and constructs + a new clause rule(Head,NBody), where the body is basically a + conjunction of all the resolvents. If a resolvent is a disjunction + or a non-ground literal, a new proposition is created (which is + actually represented by a number), which has a clause whose body + is the resolvent. +*/ +return_to_disj(Nanss,Node,Ngoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + Node = (Ggoal : Clause), + Clause = rule(Head,all(Body)), + TP0 = (N0 : Tcl0), + negative_return_all(Nanss,Body,Ngoal,NBody,[],N0,N,Tcl0,Tcl), + TP1 = (N : Tcl), + edge_oldt(rule(Head,NBody),Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP1,TP). + +negative_return_all([],_Body,_Ngoal,NBody,NBody,N,N,Tcl,Tcl). +negative_return_all(l(_GH,Lanss),Body,Ngoal,NBody0,NBody,N0,N,Tcl0,Tcl) :- + ( Lanss == [] -> + NBody0 = NBody, N = N0, Tcl = Tcl0 + ; Lanss = [Ans|_], + negative_return_one(Ans,Body,Ngoal,NBody0,NBody,N0,N,Tcl0,Tcl) + ). +negative_return_all(n2(T1,_,T2),Body,Ngoal,NBody0,NBody,N0,N,Tcl0,Tcl) :- + negative_return_all(T1,Body,Ngoal,NBody0,NBody1,N0,N1,Tcl0,Tcl1), + negative_return_all(T2,Body,Ngoal,NBody1,NBody,N1,N,Tcl1,Tcl). +negative_return_all(n3(T1,_,T2,_,T3),Body,Ngoal,NBody0,NBody,N0,N,Tcl0,Tcl) :- + negative_return_all(T1,Body,Ngoal,NBody0,NBody1,N0,N1,Tcl0,Tcl1), + negative_return_all(T2,Body,Ngoal,NBody1,NBody2,N1,N2,Tcl1,Tcl2), + negative_return_all(T3,Body,Ngoal,NBody2,NBody,N2,N,Tcl2,Tcl). + +negative_return_one(d(H,Tv),Body,Ngoal,NBody0,NBody,N0,N,Tcl0,Tcl) :- + copy_term(Body,[\+Call|Bs]), + H = Call, + ( Tv == [] -> % no delay + ( (Bs = [Lit], ground(Lit)) -> % resovlent is a ground literal + NBody0 = [Lit|NBody], + N = N0, Tcl = Tcl0 + ; Lit = N0, % otherwise, replace it with a number + N is N0+1, + NBody0 = [Lit|NBody], + Clause = rule(d(Lit,[]),all(Bs)), + add_tab_ent(Lit,Clause,Tcl0,Tcl) + ) + ; ( ground(H) -> % if there is delay, always replace with number + NewTv = [\+H] + ; ground(H,GH), + NewTv = [Ngoal - (\+GH)] + ), + Lit = N0, + N is N0+1, + NBody0 = [Lit|NBody], + Clause = rule(d(Lit,all(NewTv)),all(Bs)), + add_tab_ent(Lit,Clause,Tcl0,Tcl) + ). + +return_to_disj_list(Lanss,Node,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + Node = (Ggoal : Clause), + Clause = rule(Head,all(Body)), + TP0 = (N0 : Tcl0), + negative_return_list(Lanss,Body,NBody,[],N0,N,Tcl0,Tcl), + TP1 = (N : Tcl), + edge_oldt(rule(Head,NBody),Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP1,TP). + +negative_return_list([],_Body,NBody,NBody,N,N,Tcl,Tcl). +negative_return_list([d(H,[])|Lanss],Body,NBody0,NBody,N0,N,Tcl0,Tcl) :- + copy_term(Body,[\+Call|Bs]), + H = Call, + ( Bs = [Lit], ground(Lit) -> + NBody0 = [Lit|NBody1], + N1 = N0, Tcl1 = Tcl0 + ; Lit = N0, + N1 is N0+1, + NBody0 = [Lit|NBody1], + Clause = rule(d(Lit,[]),all(Bs)), + add_tab_ent(Lit,Clause,Tcl0,Tcl1) + ), + negative_return_list(Lanss,Body,NBody1,NBody,N1,N,Tcl1,Tcl). + +/* comp_tab_ent(Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + check if Ggoal and subgoals on top of it on the stack are + completely evaluated. +*/ +comp_tab_ent(Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + ( Dep0 == maxint-maxint -> + process_pos_scc(Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep,TP0,TP) + ; update_mins(Ggoal,Dep0,pos,Tab0,Tab1,Gdfn,Gdep), + Gdep = Gpmin-Gnmin, + ( Gdfn @=< Gpmin, Gnmin == maxint -> + process_pos_scc(Ggoal,Tab1,Tab,S0,S,Dfn0,Dfn,Dep,TP0,TP) + ; Gdfn @=< Gpmin, Gdfn @=< Gnmin -> + process_neg_scc(Ggoal,Tab1,Tab,S0,S,Dfn0,Dfn,Dep,TP0,TP) + ; Tab = Tab1, S0 = S, Dfn = Dfn0, Dep = Gdep, TP = TP0 + ) + ). + +process_pos_scc(Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep,TP0,TP) :- + ( wfs_trace -> + write('Stack: '), nl, display_stack(S0,Tab0), + write('Completed call found: '), write(Ggoal), nl, + display_table(Tab0), + write('Completing calls ......'), nl, nl + ; true + ), + pop_subgoals(Ggoal,S0,S1,[],Scc), + complete_comp(Scc,Tab0,Tab1,Alist,[]), + return_aneg_nodes(Alist,Tab1,Tab,S1,S,Dfn0,Dfn,maxint-maxint,Dep,TP0,TP). + +/* pop_subgoals(Ggoal,S0,S,Scc0,Scc) + pop off the stack subgoals up to and including Ggoal +*/ +pop_subgoals(Ggoal,S0,S,Scc0,Scc) :- + S0 = [Sent|S1], + ( Ggoal == Sent -> + S = S1, + Scc = [Sent|Scc0] + ; pop_subgoals(Ggoal,S1,S,[Sent|Scc0],Scc) + ). + +/* complete_comp(Scc,Tab0,Tab,Alist0,Alist): + process the list Scc of subgoals that are + completely evaluated. +*/ +complete_comp([],Tab,Tab,Alist,Alist). +complete_comp([Ggoal|Scc],Tab0,Tab,Alist0,Alist) :- + complete_one(Ggoal,Tab0,Tab1,Alist0,Alist1), + complete_comp(Scc,Tab1,Tab,Alist1,Alist). + +/* complete_one(Ggoal,Tab0,Tab,Alist0,Alist) + process one subgoal that has been completely + evaluated: + 1. set its Nodes and Negs to [] and Comp to true; + 2. simplify its answers and set up links + for further simplification later; + 3. use the truth value of Ggoal to simplify + answers of other complete subgoals (possibly + including itself). + 4. set Alist0/Alist: a list of negation nodes with + universal disjunctions with associated answers + for the selected negative literal. +*/ +complete_one(Ggoal,Tab0,Tab,Alist0,Alist) :- + updatevs(Tab0,Ggoal,Ent0,Ent,Tab1), + Ent0 = e(_Nodes,ANegs,Anss0,Delay,_Comp,Gdfn,Slist0), + Ent = e([],[],Anss,Delay,true,Gdfn,Slist), + ( Delay == true -> + reduce_ans(Anss0,Anss,Tab0), + setup_simp_links(Anss,Ggoal,Slist0,Slist1,Tab1,Tab2) + ; % Delay == false + Anss = Anss0, + Tab2 = Tab1, + Slist1 = Slist0 + ), + extract_known(Ggoal,Anss,Slist1,Slist,Klist), + simplify(Klist,Tab2,Tab,[]), + ( ANegs == [] -> + Alist0 = Alist + ; Alist0 = [(Anss,Ggoal)-ANegs|Alist] + ). + +setup_simp_links([],_,Slist,Slist,Tab,Tab). +setup_simp_links(l(GH,Lanss),Ggoal,Slist0,Slist,Tab0,Tab) :- + setup_simp_links_list(Lanss,Ggoal-GH,Ggoal,Slist0,Slist,Tab0,Tab). +setup_simp_links(n2(T1,_,T2),Ggoal,Slist0,Slist,Tab0,Tab) :- + setup_simp_links(T1,Ggoal,Slist0,Slist1,Tab0,Tab1), + setup_simp_links(T2,Ggoal,Slist1,Slist,Tab1,Tab). +setup_simp_links(n3(T1,_,T2,_,T3),Ggoal,Slist0,Slist,Tab0,Tab) :- + setup_simp_links(T1,Ggoal,Slist0,Slist1,Tab0,Tab1), + setup_simp_links(T2,Ggoal,Slist1,Slist2,Tab1,Tab2), + setup_simp_links(T3,Ggoal,Slist2,Slist,Tab2,Tab). + +/* setup_simp_link_list(Lanss,Ggoal-GH,Ggoal,Slist0,Slist,Tab0,Tab) + Ggoal-GH is to tell what portion of answers of Ggoal can be + simplified. +*/ +setup_simp_links_list([],_,_,Slist,Slist,Tab,Tab). +setup_simp_links_list([d(_,D)|Anss],GHead,Ggoal,Slist0,Slist,Tab0,Tab) :- + ( D = all(Ds) -> + true + ; Ds = D + ), + links_from_one_delay(Ds,GHead,Ggoal,Slist0,Slist1,Tab0,Tab1), + setup_simp_links_list(Anss,GHead,Ggoal,Slist1,Slist,Tab1,Tab). + +/* A link ((Ggoal-GH):Lit) in an entry for Ngoal means that + the literal Lit in an answer with head GH in Ggoal can + be potentially simplified if we know answers for Ngoal. +*/ +links_from_one_delay([],_,_,Slist,Slist,Tab,Tab). +links_from_one_delay([D|Ds],GHead,Ggoal,Slist0,Slist,Tab0,Tab) :- + ( D = (\+ Ngoal) -> + ( Ggoal == Ngoal -> + Tab1 = Tab0, + Slist1 = [GHead:D|Slist0] + ; add_link_to_ent(Tab0,Ngoal,GHead:D,Tab1), + Slist1 = Slist0 + ) + ; D = (Ngoal-_) -> + ( Ggoal == Ngoal -> + Slist1 = [GHead:D|Slist0], + Tab1 = Tab0 + ; Slist1 = Slist0, + add_link_to_ent(Tab0,Ngoal,GHead:D,Tab1) + ) + ), + links_from_one_delay(Ds,GHead,Ggoal,Slist1,Slist,Tab1,Tab). + +/* extract_known(Ggoal,Anss,Links,Slist,Klist): + Given Ggoal and its answers Anss, and its + simplification Links, it partitioned Links + into Slist and Klist of links, where Klist + is a list of links that are known to be either + true or false. + + Klist is either of the form Val-Links, or a + list of the form Val-Link. In case of non-ground + calls, the corresponding portion of Anss has to + be searched. +*/ +extract_known(Ggoal,Anss,Links,Slist,Klist) :- + ( failed(Anss) -> + Klist = fail-Links, + Slist = [] + ; Anss = l(GH,Lanss) -> + ( Ggoal == GH -> % Ground or most general call + ( memberchk(d(_,[]),Lanss) -> + Klist = succ-Links, + Slist = [] + ; Klist = [], + Slist = Links + ) + ; % non-ground call + extract_known_anss(Links,Anss,[],Slist,[],Klist) + ) + ; % non-ground call + extract_known_anss(Links,Anss,[],Slist,[],Klist) + ). + +extract_known_anss([],_,Slist,Slist,Klist,Klist). +extract_known_anss([Link|Links],Anss,Slist0,Slist,Klist0,Klist) :- + Link = (_:Lit), + extract_lit_val(Lit,Anss,true,Val), + ( Val == undefined -> + Slist1 = [Link|Slist0], + Klist1 = Klist0 + ; Slist1 = Slist0, + Klist1 = [Val-Link|Klist0] + ), + extract_known_anss(Links,Anss,Slist1,Slist,Klist1,Klist). + +/* extract_lit_val(Lit,Anss,Comp,Val): + extract the truth value of Lit according to Anss and Comp. + In case of a non-ground calls, the corresponding portion + of Anss has to be searched. +*/ +extract_lit_val(Lit,Anss,Comp,Val) :- + ( Lit = (\+ _) -> + ( succeeded(Anss) -> + Val = fail + ; failed(Anss), Comp == true -> + Val = succ + ; Val = undefined + ) + ; Lit = (_ - (\+GH)) -> + ( find(Anss,GH,Lanss) -> + ( (\+ \+ memberchk(d(GH,[]),Lanss)) -> + Val = fail + ; Lanss == [], Comp == true -> + Val = succ + ; Val = undefined + ) + ; ( Comp == true -> + Val = succ + ; Val = undefined + ) + ) + ; Lit = (_-GH) -> + ( find(Anss,GH,Lanss) -> + ( (\+ \+ memberchk(d(GH,[]),Lanss)) -> + Val = succ + ; Lanss == [], Comp == true -> + Val = fail + ; Val = undefined + ) + ; ( Comp == true -> + Val = fail + ; Val = undefined + ) + ) + ). + +/* simplify(KnownLinks,Tab0,Tab,Abd): + Given a list of KnownLinks, Tab0 and Abd, + it tries to simplify answers according to + KnownLinks. When a subgoal is found to be + true or false according to answers, + consistency with assumed truth values in Abd + is checked. +*/ +simplify([],Tab,Tab,_Abd). +simplify([Val-Link|Klist],Tab0,Tab,Abd) :- + simplify_one(Val,Link,Tab0,Tab1,Abd), + simplify(Klist,Tab1,Tab,Abd). +simplify(Val-Links,Tab0,Tab,Abd) :- + simplify_list(Links,Val,Tab0,Tab,Abd). + +simplify_list([],_,Tab,Tab,_Abd). +simplify_list([Link|Links],Val,Tab0,Tab,Abd) :- + Link = (_ : Lit), + ( ( Lit = (\+_); Lit = (_ - (\+_)) ) -> + ( Val = fail -> LVal = succ; LVal = fail ) + ; LVal = Val + ), + simplify_one(LVal,Link,Tab0,Tab1,Abd), + simplify_list(Links,Val,Tab1,Tab,Abd). + +simplify_one(Val,Link,Tab0,Tab,Abd) :- + Link = ((Ngoal - GH) : Lit), + updatevs(Tab0,Ngoal,Ent0,Ent,Tab1), + Ent0 = e(Nodes,ANegs,Anss0,Delay,Comp,Dfn,Slist0), + Ent = e(Nodes,ANegs,Anss,Delay,Comp,Dfn,Slist), + ( updatevs(Anss0,GH,Lanss0,Lanss,Anss) -> + simplify_anss(Lanss0,Val,Lit,[],Lanss,C), + ( C == true -> + ( find(Abd,GH,Aval) -> + ( Aval == true, Lanss == [] -> % deduced result inconsistent with assumption + fail + ; Aval == false, memberchk( d(_ , []), Lanss) -> + fail + ; true + ) + ; true + ), + extract_known(Ngoal,Anss,Slist0,Slist,Klist), + simplify(Klist,Tab1,Tab,Abd) + ; Tab = Tab0 + ) + ; Tab = Tab0 + ). + +/* simplify_anss(List,Val,Lit,Lanss0,Lanss,C): + Given a List of answers, Val of Lit, it + simplifies the List and construct a new list + Lanss0/Lanss of answers. C is unified with true + if some simplification is carried out. + + As soon as a true answer is detected, all + other answers with the same head are deleted. +*/ +simplify_anss([],_,_,Anss,Anss,_). +simplify_anss([Ans|Rest],Val,Lit,Anss0,Anss,C) :- + ( simplified_ans(Ans,Val,Lit,NewAns,C) -> + ( NewAns = d(_,[]) -> + Anss = [NewAns] + ; Anss1 = [NewAns|Anss0], + simplify_anss(Rest,Val,Lit,Anss1,Anss,C) + ) + ; C = true, + simplify_anss(Rest,Val,Lit,Anss0,Anss,C) + ). + +simplified_ans(Ans,Val,Lit,NewAns,C) :- + Ans = d(H,Ds), + ( Ds == [] -> + NewAns = Ans + ; Ds = all(Dlist) -> + ( Val == fail -> + delete_lit(Dlist,Lit,NewDlist,[],C), + ( NewDlist == [] -> + fail + ; NewAns = d(H,all(NewDlist)) + ) + ; % Val == succ -> + ( memberchk(Lit,Dlist) -> + NewAns = d(H,[]), + C = true + ; NewAns = Ans + ) + ) + ; % Ds is a conjunction + ( Val == fail -> + ( memberchk(Lit,Ds) -> + fail + ; NewAns = Ans + ) + ; % Val == succ -> + delete_lit(Ds,Lit,NewDs,[],C), + NewAns = d(H,NewDs) + ) + ). + +/* delete_lit(Delays,Lit,Ds0,Ds,C): + deletes Lit from Delays. Delays is + a list of delayed literals and it + is guaranteed to have no duplicates. +*/ +delete_lit([],_,Ds,Ds,_). +delete_lit([D|Rest],Lit,Ds0,Ds,C) :- + ( D == Lit -> + Ds0 = Rest, + C = true + ; Ds0 = [D|Ds1], + delete_lit(Rest,Lit,Ds1,Ds,C) + ). + +% return answers to negative nodes within universal disjunctions +return_aneg_nodes([],Tab,Tab,S,S,Dfn,Dfn,Dep,Dep,TP,TP). +return_aneg_nodes([(Anss,Ngoal)-ANegs|Alist],Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + map_anegs(ANegs,Anss,Ngoal,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1), + return_aneg_nodes(Alist,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP). + +map_anegs([],_Anss,_Ngoal,Tab,Tab,S,S,Dfn,Dfn,Dep,Dep,TP,TP). +map_anegs([Node|ANegs],Anss,Ngoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + return_to_disj(Anss,Node,Ngoal,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1), + map_anegs(ANegs,Anss,Ngoal,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP). + +/* process a component of subgoals that may be involved in + negative loops. +*/ +process_neg_scc(Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep,TP0,TP) :- + ( wfs_trace -> + write('Stack: '), nl, display_stack(S0,Tab0), + write('Possible negative loop: '), write(Ggoal), nl, + display_table(Tab0) + ; true + ), + extract_subgoals(Ggoal,S0,Scc,[]), + reset_nmin(Scc,Tab0,Tab1,Ds,[]), + ( wfs_trace -> + write('Delaying: '), display_dlist(Ds) + ; true + ), + delay_and_cont(Ds,Tab1,Tab2,S0,S1,Dfn0,Dfn1,maxint-maxint,Dep1,TP0,TP1), + recomp_scc(Scc,Tab2,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP). + +/* extract_subgoals(Ggoal,S0,Scc0,Scc) + extract subgoals that may be involved in negative loops, + but leave the stack of subgoals intact. +*/ +extract_subgoals(Ggoal,[Sent|S],[Sent|Scc0],Scc) :- + ( Ggoal == Sent -> + Scc0 = Scc + ; extract_subgoals(Ggoal,S,Scc0,Scc) + ). + +/* reset_nmin(Scc,Tab0,Tab,Dnodes0,Dnodes) + reset NegLink and collect all waiting nodes that need to be + delayed. Dnodes0/Dnodes is a difference list. +*/ +reset_nmin([],Tab,Tab,Ds,Ds). +reset_nmin([Ggoal|Scc],Tab0,Tab,Ds0,Ds) :- + get_and_reset_negs(Tab0,Ggoal,ANegs,Tab1), + ( ANegs == [] -> + Ds0 = Ds1 + ; Ds0 = [Ggoal-ANegs|Ds1] + ), + reset_nmin(Scc,Tab1,Tab,Ds1,Ds). + +delay_and_cont([],Tab,Tab,S,S,Dfn,Dfn,Dep,Dep,TP,TP). +delay_and_cont([Ggoal-Negs|Dnodes],Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + map_nodes(Negs,d(\+Ggoal,[\+Ggoal]),Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1), + delay_and_cont(Dnodes,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP). + +recomp_scc([],Tab,Tab,S,S,Dfn,Dfn,Dep,Dep,TP,TP). +recomp_scc([Ggoal|Scc],Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + comp_tab_ent(Ggoal,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1), + recomp_scc(Scc,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP). + +/* routines for incremental update of dependency information +*/ + +/* update_mins(Ggoal,Dep,Sign,Tab0,Tab,Gdfn,Gdep) + update the PosLink and NegLink of Ggoal according to + Dep and Sign +*/ +update_mins(Ggoal,Dep,Sign,Tab0,Tab,Gdfn,Gdep) :- + Ent0 = e(Nodes,ANegs,Anss,Delay,Comp,Gdfn:Gdep0,Slist), + Ent = e(Nodes,ANegs,Anss,Delay,Comp,Gdfn:Gdep,Slist), + updatevs(Tab0,Ggoal,Ent0,Ent,Tab), + compute_mins(Gdep0,Dep,Sign,Gdep). + +/* update_lookup_mins(Ggoal,Node,Ngoal,Sign,Tab0,Tab,Dep0,Dep) + There is a lookup edge (Node) from Ggoal to Ngoal + with Sign. It adds Node to the corresponding waiting list + in Ngoal and then update the dependencies of Ggoal. +*/ +update_lookup_mins(Ggoal,Node,Ngoal,Sign,Tab0,Tab,Dep0,Dep) :- + updatevs(Tab0,Ngoal,Ent0,Ent,Tab1), + ( Sign == pos -> + pos_to_newent(Ent0,Ent,Node) + ; Sign == aneg -> + aneg_to_newent(Ent0,Ent,Node) + ), + Ent0 = e(_,_,_,_,_,_Ndfn:Ndep,_), + compute_mins(Dep0,Ndep,Sign,Dep), + update_mins(Ggoal,Ndep,Sign,Tab1,Tab,_,_). + +/* update_solution_mins(Ggoal,Ngoal,Sign,Tab0,Tab,Ndep,Dep0,Dep) + There is an edge with Sign from Ggoal to Ngoal, where Ngoal is + a new subgoal. Ndep is the final dependency information of + Ngoal. Dep0/Dep is for the most recent enclosing new call. + This predicate is called after Ngoal is solved. +*/ +update_solution_mins(Ggoal,Ngoal,Sign,Tab0,Tab,Ndep,Dep0,Dep) :- + find(Tab0,Ngoal,Nent), + ent_to_comp(Nent,Ncomp), + ( Ncomp == true -> + ( Ndep == maxint-maxint -> + Tab = Tab0, Dep = Dep0 + ; update_mins(Ggoal,Ndep,pos,Tab0,Tab,_,_), + compute_mins(Dep0,Ndep,pos,Dep) + ) + ; update_mins(Ggoal,Ndep,Sign,Tab0,Tab,_,_), + compute_mins(Dep0,Ndep,Sign,Dep) + ). + +compute_mins(Gpmin-Gnmin,Npmin-Nnmin,Sign,Newpmin-Newnmin) :- + ( Sign == pos -> + min(Gpmin,Npmin,Newpmin), + min(Gnmin,Nnmin,Newnmin) + ; % (Sign == neg; Sign == aneg) -> + Newpmin=Gpmin, + min(Gnmin,Npmin,Imin), + min(Imin,Nnmin,Newnmin) + ). + +min(X,Y,M) :- ( X @< Y -> M=X; M=Y ). + +%%%%%%%%%%%%%%% Local table manipulation predicates %%%%%%%%%% + +/* Table Entry Structure: + For each Call, its table entry is identified with its number-vared + version -- Ggoal. Its value is a term of the form + + e(Nodes,ANegs,Anss,Delay,Comp,Dfn:Dep,Slist) + + where + Nodes: positive suspension list + ANegs: negative suspension list (for universal disjunction clauss) + Anss: another table. + Delay: whether Anss contains any answer with delay + Comp: whether Call is completely evaluated or not + Dfn: depth-first number of Gcall + Dep: (PosLink-NegLink) --- dependency information + Slist: a list of nodes whose answers may be simplified + if the truth value of Ggoal is known. Each element of Slist + is of the form (Ngoal-GH):Literal. + Stack Entry Structure: + Ggoal +*/ + +/* routines for accessing individual fields of an entry +*/ +ent_to_nodes(e(Nodes,_,_,_,_,_,_),Nodes). +ent_to_anegs(e(_,ANegs,_,_,_,_,_),ANegs). +ent_to_anss(e(_,_,Anss,_,_,_,_),Anss). +ent_to_delay(e(_,_,_,Delay,_,_,_),Delay). +ent_to_comp(e(_,_,_,_,Comp,_,_),Comp). +ent_to_dfn(e(_,_,_,_,_,Dfn,_),Dfn). +ent_to_slist(e(_,_,_,_,_,_,Slist),Slist). + +get_and_reset_negs(Tab0,Ggoal,ANegs,Tab) :- + Ent0 = e(Nodes,ANegs,Anss,Delay,Comp,Gdfn: (Gpmin - _),Slist), + Ent = e(Nodes,[],Anss,Delay,Comp,Gdfn:Gpmin-maxint,Slist), + updatevs(Tab0,Ggoal,Ent0,Ent,Tab). + +/* adding a new table entry +*/ +add_tab_ent(Ggoal,Ent,Tab0,Tab) :- + addkey(Tab0,Ggoal,Ent,Tab). + +/* The following three routines are for creating + new calls +*/ +/* a new call with empty suspensions +*/ +new_init_call(Call,Ggoal,Ent,S0,S,Dfn0,Dfn) :- + ground(Call,Ggoal), + S = [Ggoal|S0], + Dfn is Dfn0+1, + Ent = e([],[],[],false,false,Dfn0:Dfn0-maxint,[]). + +/* a new call with an initial negative suspension from + inside a universal disjunction +*/ +new_aneg_call(Ngoal,Neg,Ent,S0,S,Dfn0,Dfn) :- + S = [Ngoal|S0], + Dfn is Dfn0+1, + Ent = e([],[Neg],[],false,false,Dfn0:Dfn0-maxint,[]). + +/* a new call with an initial positive suspension +*/ +new_pos_call(Ngoal,Node,Ent,S0,S,Dfn0,Dfn) :- + S = [Ngoal|S0], + Dfn is Dfn0+1, + Ent = e([Node],[],[],false,false,Dfn0:Dfn0-maxint,[]). + +/* routines for adding more information to a + table entry. +*/ +aneg_to_newent(Ent0,Ent,ANeg) :- + Ent0 = e(Nodes,ANegs,Anss,Delay,Comp,Dfn,Slist), + Ent = e(Nodes,[ANeg|ANegs],Anss,Delay,Comp,Dfn,Slist). + +pos_to_newent(Ent0,Ent,Node) :- + Ent0 = e(Nodes,ANegs,Anss,Delay,Comp,Dfn,Slist), + Ent = e([Node|Nodes],ANegs,Anss,Delay,Comp,Dfn,Slist). + +add_link_to_ent(Tab0,Ggoal,Link,Tab) :- + updatevs(Tab0,Ggoal,Ent0,Ent,Tab), + link_to_newent(Ent0,Ent,Link). + +link_to_newent(Ent0,Ent,Link) :- + Ent0 = e(Nodes,ANegs,Anss,Delay,Comp,Dfn,Slist), + Ent = e(Nodes,ANegs,Anss,Delay,Comp,Dfn,[Link|Slist]). + +/* routines for manipulating answers */ +ansstree_to_list([],L,L). +ansstree_to_list(l(_GH,Lanss),L0,L) :- + attach(Lanss,L0,L). +ansstree_to_list(n2(T1,_M,T2),L0,L) :- + ansstree_to_list(T1,L0,L1), + ansstree_to_list(T2,L1,L). +ansstree_to_list(n3(T1,_M2,T2,_M3,T3),L0,L) :- + ansstree_to_list(T1,L0,L1), + ansstree_to_list(T2,L1,L2), + ansstree_to_list(T3,L2,L). + +attach([],L,L). +attach([d(H,B)|R],[X|L0],L) :- + ( B == [] -> + X = H + ; X = (H <- B) + ), + attach(R,L0,L). + +member_anss(Ans,Anss) :- + member_anss_1(Anss,Ans). + +member_anss_1(l(_,Lanss),Ans) :- + member(Ans,Lanss). +member_anss_1(n2(T1,_,T2),Ans) :- + ( member_anss_1(T1,Ans) + ; member_anss_1(T2,Ans) + ). +member_anss_1(n3(T1,_,T2,_,T3),Ans) :- + ( member_anss_1(T1,Ans) + ; member_anss_1(T2,Ans) + ; member_anss_1(T3,Ans) + ). + +/* failed(Anss): Anss is empty */ +failed([]). +failed(l(_,[])). + +/* succeeded(Anss): Anss contains a single definite answer */ +succeeded(l(_,Lanss)) :- + memberchk(d(_,[]),Lanss). + +/* add_ans(Tab0,Goal,Ans,Nodes,Mode,Tab): + If Ans is not subsumed by any existing answer then + Ans is added to Anss(Goal); + If some existing answer also has head H then + Mode = no_new_head + else + Mode = new_head + else + fail. +*/ +add_ans(Tab0,Ggoal,Ans,Nodes,Mode,Tab) :- + updatevs(Tab0,Ggoal,Ent0,Ent,Tab), + Ans = d(H,Ds), + ( Ds == [] -> + new_ans_ent(Ent0,Ent,Ans,Nodes,Mode) + ; setof(X,member(X,Ds),NewDs), + new_ans_ent(Ent0,Ent,d(H,NewDs),Nodes,Mode) + ). + +new_ans_ent(Ent0,Ent,Ans,Nodes,Mode) :- + Ent0 = e(Nodes,ANegs,Anss0,Delay0,Comp,Dfn,Slist), + Ent = e(Nodes,ANegs,Anss,Delay,Comp,Dfn,Slist), + Ans = d(H,D), + ground(H,GH), + ( updatevs(Anss0,GH,Lanss0,Lanss,Anss) -> + ( D == [] -> + \+(memberchk(d(_,[]),Lanss0)), + Lanss = [Ans] + ; not_subsumed_ans(Ans,Lanss0), + Lanss = [Ans|Lanss0] + ), + Mode = no_new_head + ; addkey(Anss0,GH,[Ans],Anss), + Mode = new_head + ), + ( D == [] -> + Delay = Delay0 + ; Delay = true + ). + +/* returned_ans(Ans,Ggoal,RAns): + determines whether SLG resolution or SLG factoring should + be applied. +*/ +returned_ans(d(H,Tv),Ggoal,d(H,NewTv)) :- + ( Tv = [] -> + NewTv = [] + ; ground(H,GH), + NewTv = [Ggoal-GH] + ). + +% reduce a list of answers, by reducing delay list, and by subsumption +reduce_ans(Anss0,Anss,Tab) :- + reduce_completed_ans(Anss0,Anss,Tab). + +% simplify all the delay lists in a list of answers. +reduce_completed_ans([],[],_Tab). +reduce_completed_ans(l(GH,Lanss0),l(GH,Lanss),Tab) :- + reduce_completed_anslist(Lanss0,[],Lanss,Tab). +reduce_completed_ans(n2(T1,M,T2),n2(NT1,M,NT2),Tab) :- + reduce_completed_ans(T1,NT1,Tab), + reduce_completed_ans(T2,NT2,Tab). +reduce_completed_ans(n3(T1,M2,T2,M3,T3),n3(NT1,M2,NT2,M3,NT3),Tab) :- + reduce_completed_ans(T1,NT1,Tab), + reduce_completed_ans(T2,NT2,Tab), + reduce_completed_ans(T3,NT3,Tab). + +reduce_completed_anslist([],Lanss,Lanss,_Tab). +reduce_completed_anslist([d(G,D0)|List],Lanss0,Lanss,Tab) :- + ( D0 = all(Dlist1) -> + ( filter_delays(Dlist1,[],Dlist,disj,V,Tab) -> + ( V == true -> % true answer + Lanss = [d(G,[])] + ; Dlist == [] -> % false answer, ignore + reduce_completed_anslist(List,Lanss0,Lanss,Tab) + ; reduce_completed_anslist(List,[d(G,all(Dlist))|Lanss0],Lanss,Tab) + ) + ; reduce_completed_anslist(List,Lanss0,Lanss,Tab) + ) + ; ( filter_delays(D0,[],D,conj,_V,Tab) -> + ( D == [] -> + Lanss = [d(G,[])] + ; reduce_completed_anslist(List,[d(G,D)|Lanss0],Lanss,Tab) + ) + ; reduce_completed_anslist(List,Lanss0,Lanss,Tab) + ) + ). + +% simplify a delay list by the completed table: delete true negations, +% fail if a false one. +filter_delays([],Fds,Fds,_DC,_V,_Tab). +filter_delays([Lit|Ds],Fds0,Fds,DC,V,Tab) :- + lit_to_call(Lit,Gcall), + find(Tab,Gcall,Gent), + ent_to_comp(Gent,Gcomp), + ent_to_anss(Gent,Ganss), + extract_lit_val(Lit,Ganss,Gcomp,Val), + ( Val == succ -> + ( DC == conj -> + filter_delays(Ds,Fds0,Fds,DC,V,Tab) + ; DC == disj -> + V = true + ) + ; Val == fail -> + ( DC == conj -> + fail + ; DC == disj -> + filter_delays(Ds,Fds0,Fds,DC,V,Tab) + ) + ; % Val == undefined + filter_delays(Ds,[Lit|Fds0],Fds,DC,V,Tab) + ). + +lit_to_call(\+G,G). +lit_to_call(Gcall-_,Gcall). + +not_subsumed_ans(Ans,Lanss0) :- + \+ + ( numbervars(Ans,0,_), + subsumed_ans1(Ans,Lanss0) + ). + +% succeed if answer is subsumed by any in list1 or 2. +subsumed_ans(Tv,List1,List2) :- + \+ + (numbervars(Tv,0,_), + \+ subsumed_ans1(Tv,List1), + \+ subsumed_ans1(Tv,List2) + ). + +% check if a delay is subsumed one of the element in the list +subsumed_ans1(d(T,V),List) :- + member(d(T,V1),List), + ( V1 == [] + ; V = all(LV), V1 = all(LV1) -> + subset(LV,LV1) + ; subset(V1,V) + ). + +/****************** auxiliary routines *******************/ +% variantchk/2 finds a variant in a list of atoms. +variantchk(G,[G1|_]) :- variant(G,G1), !. +variantchk(G,[_|L]) :- variantchk(G,L). + +variant(A, B) :- + A == B + -> true + ; subsumes_chk(A, B), + subsumes_chk(B, A), + A = B. +/* +subsumes_chk(General, Specific) :- + \+ ( numbervars(Specific, 0, _), + \+ General = Specific + ). +*/ +ground(O,C) :- ground(O) -> C = O ; copy_term(O,C), numbervars(C,0,_). + +subset([],_). +subset([E|L1],L2) :- memberchk(E,L2), subset(L1,L2). + +reverse([],R,R). +reverse([Goal|Scc],R0,R) :- reverse(Scc,[Goal|R0],R). + +/***************** routines for debugging *******************/ + +% Debugging help: pretty-prints strongly connected components and local table. +display_stack(Stack,Tab) :- + reverse(Stack,[],Rstack), + display_st(Rstack,Tab). +display_st([],_Tab). +display_st([Ggoal|Scc],Tab) :- + find(Tab,Ggoal,Ent), + ent_to_dfn(Ent,Dfn:Pmin-Nmin), + tab(2), + write(Ggoal-Dfn), + write(': '), + write('Pmin='), + write(Pmin), + write('; '), + write('Nmin='), + write(Nmin), + write('; '), + nl, + display_st(Scc,Tab). + +display_dlist([]) :- nl,nl. +display_dlist([Ngoal-_|Dlist]) :- + write(\+ Ngoal), + write('; '), + display_dlist(Dlist). + +display_table(Tab) :- + write('Table: '), + nl, + write_tab(Tab). + +display_final(Tab) :- + write(' Final Set of Answers: '), + nl, + display_final1(Tab). +display_final1([]). +display_final1(l(_,e(_,_,Anss,_,_,_,_))) :- + write_anss(Anss). +display_final1(n2(X,_,Y)) :- + display_final1(X), + display_final1(Y). +display_final1(n3(X,_,Y,_,Z)) :- + display_final1(X), + display_final1(Y), + display_final1(Z). + +write_tab([]). +write_tab(l(G,e(Nodes,ANegs,Anss,_,Comp,Dfn:_,_))) :- + write(' Entry: '), + write(G-Dfn), + write(': '), + ( Comp == true -> + write('Complete!') + ; write('Incomplete!') + ), + nl, + ( Anss == [] -> + true + ; write(' Anss: '), + nl, + write_anss(Anss) + ), + ( ( Comp == true; Nodes == []) -> + true + ; write(' Nodes: '), + write(Nodes), + nl + ), + ( ( Comp == true; ANegs == []) -> + true + ; write(' ANegs: '), + write(ANegs), + nl + ). +write_tab(n2(X,_,Y)) :- + write_tab(X), + write_tab(Y). +write_tab(n3(X,_,Y,_,Z)) :- + write_tab(X), + write_tab(Y), + write_tab(Z). + +write_anss([]). +write_anss(l(_,Lanss)) :- + write_anss_list(Lanss). +write_anss(n2(T1,_,T2)) :- + write_anss(T1), + write_anss(T2). +write_anss(n3(T1,_,T2,_,T3)) :- + write_anss(T1), + write_anss(T2), + write_anss(T3). + +write_anss_list([]). +write_anss_list([Ans|Anss]) :- + write_ans(Ans), + write_anss_list(Anss). + +write_ans(d(H,Ds)) :- + write(' '), + write(H), + ( Ds == [] -> + true + ; write(' :- '), + ( Ds = all([D|Ds1]) -> + ( D = (_-GH) -> + write(GH) + ; write(D) + ), + write_delay(Ds1,'; ') + ; Ds = [D|Ds1], + ( D = (_-GH) -> + write(GH) + ; write(D) + ), + write_delay(Ds1,', ') + ) + ), + write('.'), + nl. +write_delay([],_). +write_delay([D|Ds1],Sep) :- + write(Sep), + ( D = (_Gcall-GH) -> + write(GH) + ; write(D) + ), + write_delay(Ds1,Sep). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +/* +This is a set of routines that supports indexed tables. Tables +are sets of key-value_list pairs. With each key is associated a list +of values. It uses 2-3 trees for the index (modified by D.S. Warren +from Ivan Bratko: ``Prolog Programming for Artificial +Intelligence'', Addison Wesley, 1986). Operations are: + +Keys must be ground! (so numbervar them) + +addkey(Tree,Key,V,Tree1) adds a new Key with value V, returning + new Tree1. Fails if the key is already there. + +find(Tree,Key,V) finds the entry with Key and returns associated + values in V. + +updatevs(Tree,Key,OldV,NewV,Tree1) replaces value of entry with key + Key and value OldV with NewV. +*/ + + +addkey([],X,V,l(X,V)):-!. +addkey(Tree,X,V,Tree1) :- + ins2(Tree,X,V,Trees), + cmb0(Trees,Tree1). + + +find(l(X,V),Xs,V) :- X == Xs. +find(n2(T1,M,T2),X,V) :- + M @=< X + -> find(T2,X,V) + ; find(T1,X,V). +find(n3(T1,M2,T2,M3,T3),X,V) :- + M2 @=< X + -> (M3 @=< X + -> find(T3,X,V) + ; find(T2,X,V) + ) + ; find(T1,X,V). + + +% updatevs(Tab0,X,Ov,Nv,Tab) updates Tab0 to Tab, by replacing +% Ov of entry with key X by Nv. +/* +updatevs(Tab0,X,Ov,Nv,Tab) :- + updatevs(Tab0,X,Ov,Nv), + Tab = Tab0. + +updatevs(Tab,X,Ov,Nv) :- + ( Tab = l(Xs,Ov), Xs == X -> + setarg(2,Tab,Nv) + ; Tab = n2(T1,M,T2) -> + ( M @=< X -> + updatevs(T2,X,Ov,Nv) + ; updatevs(T1,X,Ov,Nv) + ) + ; Tab = n3(T1,M2,T2,M3,T3) -> + ( M2 @=< X -> + ( M3 @=< X -> + updatevs(T3,X,Ov,Nv) + ; updatevs(T2,X,Ov,Nv) + ) + ; updatevs(T1,X,Ov,Nv) + ) + ). +*/ + +updatevs(l(X,Ov),Xs,Ov,Nv,l(X,Nv)) :- X == Xs. +updatevs(n2(T1,M,T2),X,Ov,Nv,n2(NT1,M,NT2)) :- + M @=< X + -> NT1=T1, updatevs(T2,X,Ov,Nv,NT2) + ; NT2=T2, updatevs(T1,X,Ov,Nv,NT1). +updatevs(n3(T1,M2,T2,M3,T3),X,Ov,Nv,n3(NT1,M2,NT2,M3,NT3)) :- + M2 @=< X + -> (M3 @=< X + -> NT2=T2, NT1=T1, updatevs(T3,X,Ov,Nv,NT3) + ; NT1=T1, NT3=T3, updatevs(T2,X,Ov,Nv,NT2) + ) + ; NT2=T2, NT3=T3, updatevs(T1,X,Ov,Nv,NT1). + +ins2(n2(T1,M,T2),X,V,Tree) :- + M @=< X + -> ins2(T2,X,V,Tree1), + cmb2(Tree1,T1,M,Tree) + ; ins2(T1,X,V,Tree1), + cmb1(Tree1,M,T2,Tree). +ins2(n3(T1,M2,T2,M3,T3),X,V,Tree) :- + M2 @=< X + -> (M3 @=< X + -> ins2(T3,X,V,Tree1), + cmb4(Tree1,T1,M2,T2,M3,Tree) + ; ins2(T2,X,V,Tree1), + cmb5(Tree1,T1,M2,M3,T3,Tree) + ) + ; ins2(T1,X,V,Tree1), + cmb3(Tree1,M2,T2,M3,T3,Tree). +ins2(l(A,V),X,Vn,Tree) :- + A @=< X + -> (X @=< A + -> fail + ; Tree = t(l(A,V),X,l(X,Vn)) + ) + ; Tree = t(l(X,Vn),A,l(A,V)). + +cmb0(t(Tree),Tree). +cmb0(t(T1,M,T2),n2(T1,M,T2)). + +cmb1(t(NT1),M,T2,t(n2(NT1,M,T2))). +cmb1(t(NT1a,Mb,NT1b),M,T2,t(n3(NT1a,Mb,NT1b,M,T2))). + +cmb2(t(NT2),T1,M,t(n2(T1,M,NT2))). +cmb2(t(NT2a,Mb,NT2b),T1,M,t(n3(T1,M,NT2a,Mb,NT2b))). + +cmb3(t(NT1),M2,T2,M3,T3,t(n3(NT1,M2,T2,M3,T3))). +cmb3(t(NT1a,Mb,NT1b),M2,T2,M3,T3,t(n2(NT1a,Mb,NT1b),M2,n2(T2,M3,T3))). + +cmb4(t(NT3),T1,M2,T2,M3,t(n3(T1,M2,T2,M3,NT3))). +cmb4(t(NT3a,Mb,NT3b),T1,M2,T2,M3,t(n2(T1,M2,T2),M3,n2(NT3a,Mb,NT3b))). + +cmb5(t(NT2),T1,M2,M3,T3,t(n3(T1,M2,NT2,M3,T3))). +cmb5(t(NT2a,Mb,NT2b),T1,M2,M3,T3,t(n2(T1,M2,NT2a),Mb,n2(NT2b,M3,T3))). + + + + +:-dynamic rule/5,def_rule/4,setting/2. + +/* start of list of parameters that can be set by the user with +set(Parameter,Value) */ +setting(epsilon_parsing,0.00001). +setting(save_dot,false). +setting(ground_body,false). + +/* find_rule(G,(R,S,N),Body,C) takes a goal G and the current C set and +returns the index R of a disjunctive rule resolving with G together with +the index N of the resolving head, the substitution S and the Body of the +rule */ +find_rule(H,(R,S,N),Body,LH):- + rule(R,S,_,Head,Body), + member_head(H,Head,0,N), + length(Head,NH), + listN(0,NH,LH). + +find_rule(H,(R,S,Number),Body,C):- + rule(R,S,_,uniform(H:1/_Num,_P,Number),Body), + not_already_present_with_a_different_head(Number,R,S,C). + + +not_already_present_with_a_different_head(_N,_R,_S,[]). + +not_already_present_with_a_different_head(N,R,S,[(N1,R,S1)|T]):- + not_different(N,N1,S,S1),!, + not_already_present_with_a_different_head(N,R,S,T). + +not_already_present_with_a_different_head(N,R,S,[(_N1,R1,_S1)|T]):- + R\==R1, + not_already_present_with_a_different_head(N,R,S,T). + + +not_different(N,N,S,S). + +not_different(_N,_N1,S,S1):- + S\=S1,!. + +not_different(N,N1,S,S1):- + N\=N1,!, + dif(S,S1). + +not_different(N,N,S,S). + + +member_head(H,[(H:_P)|_T],N,N). + +member_head(H,[(_H:_P)|T],NIn,NOut):- + N1 is NIn+1, + member_head(H,T,N1,NOut). + +/* rem_dup_lists removes the C sets that are a superset of +another C sets further on in the list of C sets */ +rem_dup_lists([],L,L). + +rem_dup_lists([H|T],L0,L):- + (member_subset(H,T);member_subset(H,L0)),!, + rem_dup_lists(T,L0,L). + +rem_dup_lists([H|T],L0,L):- + rem_dup_lists(T,[H|L0],L). + +member_subset(E,[H|_T]):- + subset_my(H,E),!. + +member_subset(E,[_H|T]):- + member_subset(E,T). + + +rem_dup_lists_tab([],L,L). + +rem_dup_lists_tab([(H,_Tab)|T],L0,L):- + (member_subset_tab(H,T);member_subset_tab(H,L0)),!, + rem_dup_lists_tab(T,L0,L). + +rem_dup_lists_tab([(H,Tab)|T],L0,L):- + rem_dup_lists_tab(T,[(H,Tab)|L0],L). + + +member_subset_tab(E,[(H,_Tab)|_T]):- + subset_my(H,E),!. + +member_subset_tab(E,[_H|T]):- + member_subset_tab(E,T). + +/* predicates for building the formula to be converted into a BDD */ + +/* build_formula(LC,Formula,VarIn,VarOut) takes as input a set of C sets +LC and a list of Variables VarIn and returns the formula and a new list +of variables VarOut +Formula is of the form [Term1,...,Termn] +Termi is of the form [Factor1,...,Factorm] +Factorj is of the form (Var,Value) where Var is the index of +the multivalued variable Var and Value is the index of the value +*/ +build_formula([],[],Var,Var). + +build_formula([D|TD],[F|TF],VarIn,VarOut):- + build_term(D,F,VarIn,Var1), + build_formula(TD,TF,Var1,VarOut). + +build_term([],[],Var,Var). + +build_term([(N,R,S)|TC],[[NVar,N]|TF],VarIn,VarOut):- + (nth0_eq(0,NVar,VarIn,(R,S))-> + Var1=VarIn + ; + append(VarIn,[(R,S)],Var1), + length(VarIn,NVar) + ), + build_term(TC,TF,Var1,VarOut). + +/* nth0_eq(PosIn,PosOut,List,El) takes as input a List, +an element El and an initial position PosIn and returns in PosOut +the position in the List that contains an element exactly equal to El +*/ +nth0_eq(N,N,[H|_T],El):- + H==El,!. + +nth0_eq(NIn,NOut,[_H|T],El):- + N1 is NIn+1, + nth0_eq(N1,NOut,T,El). + +/* var2numbers converts a list of couples (Rule,Substitution) into a list +of triples (N,NumberOfHeadsAtoms,ListOfProbabilities), where N is an integer +starting from 0 */ +var2numbers([],_N,[]). + +var2numbers([(R,S)|T],N,[[N,ValNumber,Probs]|TNV]):- + find_probs(R,S,Probs), + length(Probs,ValNumber), + N1 is N+1, + var2numbers(T,N1,TNV). + +find_probs(R,S,Probs):- + rule(R,S,_N,Head,_Body), + get_probs(Head,Probs). + +get_probs(uniform(_A:1/Num,_P,_Number),ListP):- + Prob is 1/Num, + list_el(Num,Prob,ListP). + +get_probs([],[]). + +get_probs([_H:P|T],[P1|T1]):- + P1 is P, + get_probs(T,T1). + +list_el(0,_P,[]):-!. + +list_el(N,P,[P|T]):- + N1 is N-1, + list_el(N1,P,T). + +/* end of predicates for building the formula to be converted into a BDD */list_el(0,_P,[]):-!. + +/* p(File) parses the file File.cpl. It can be called more than once without +exiting yap */ +p(File):- + parse(File). + +parse(File):- + atom_concat(File,'.cpl',FilePl), + open(FilePl,read,S), + read_clauses(S,C), + close(S), + retractall(rule(_,_,_,_,_)), + retractall(def_rule(_,_,_,_)), + retractall(new_number(_)), + assert(new_number(0)), + process_clauses(C,1),!. + +process_clauses([(end_of_file,[])],_N). + +process_clauses([((H:-B),V)|T],N):- + H=uniform(A,P,L),!, + list2and(BL,B), + process_body(BL,V,V1), + remove_vars([P],V1,V2), + append(BL,[length(L,Tot),nth0(Number,L,P)],BL1), + append(V2,['Tot'=Tot],V3), + assertz(rule(N,V3,_NH,uniform(A:1/Tot,L,Number),BL1)), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([((H:-B),V)|T],N):- + H=(_;_),!, + list2or(HL1,H), + process_head(HL1,HL), + list2and(BL,B), + process_body(BL,V,V1), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V1,NH,HL,BL)), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([((H:-B),V)|T],N):- + H=(_:_),!, + list2or(HL1,H), + process_head(HL1,HL), + list2and(BL,B), + process_body(BL,V,V1), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V1,NH,HL,BL)), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([((H:-B),V)|T],N):-!, + list2and(BL,B), + assert(def_rule(N,V,H,BL)), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([(H,V)|T],N):- + H=(_;_),!, + list2or(HL1,H), + process_head(HL1,HL), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V,NH,HL,[])), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([(H,V)|T],N):- + H=(_:_),!, + list2or(HL1,H), + process_head(HL1,HL), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V,NH,HL,[])), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([(H,V)|T],N):- + assert(def_rule(N,V,H,[])), + N1 is N+1, + process_clauses(T,N1). + +/* if the annotation in the head are not ground, the null atom is not added +and the eventual formulas are not evaluated */ + +process_head(HL,NHL):- + (ground_prob(HL)-> + process_head_ground(HL,0,NHL) + ; + NHL=HL + ). + +ground_prob([]). + +ground_prob([_H:PH|T]):- + ground(PH), + ground_prob(T). + +process_head_ground([H:PH],P,[H:PH1|Null]):- + PH1 is PH, + PNull is 1-P-PH1, + setting(epsilon_parsing,Eps), + EpsNeg is - Eps, + PNull > EpsNeg, + (PNull>Eps-> + Null=['':PNull] + ; + Null=[] + ). + +process_head_ground([H:PH|T],P,[H:PH1|NT]):- + PH1 is PH, + P1 is P+PH1, + process_head_ground(T,P1,NT). + +/* setof must have a goal of the form B^G where B is a term containing the existential variables */ +process_body([],V,V). + +process_body([setof(A,B^_G,_L)|T],VIn,VOut):-!, + get_var(A,VA), + get_var(B,VB), + remove_vars(VA,VIn,V1), + remove_vars(VB,V1,V2), + process_body(T,V2,VOut). + +process_body([setof(A,_G,_L)|T],VIn,VOut):-!, + get_var(A,VA), + remove_vars(VA,VIn,V1), + process_body(T,V1,VOut). + +process_body([bagof(A,B^_G,_L)|T],VIn,VOut):-!, + get_var(A,VA), + get_var(B,VB), + remove_vars(VA,VIn,V1), + remove_vars(VB,V1,V2), + process_body(T,V2,VOut). + +process_body([bagof(A,_G,_L)|T],VIn,VOut):-!, + get_var(A,VA), + remove_vars(VA,VIn,V1), + process_body(T,V1,VOut). + +process_body([_H|T],VIn,VOut):-!, + process_body(T,VIn,VOut). + +get_var_list([],[]). + +get_var_list([H|T],[H|T1]):- + var(H),!, + get_var_list(T,T1). + +get_var_list([H|T],VarOut):-!, + get_var(H,Var), + append(Var,T1,VarOut), + get_var_list(T,T1). + +get_var(A,[A]):- + var(A),!. + +get_var(A,V):- + A=..[_F|Args], + get_var_list(Args,V). + +remove_vars([],V,V). + +remove_vars([H|T],VIn,VOut):- + delete_var(H,VIn,V1), + remove_vars(T,V1,VOut). + +delete_var(_H,[],[]). + +delete_var(V,[VN=Var|T],[VN=Var|T1]):- + V\==Var,!, + delete_var(V,T,T1). + +delete_var(_V,[_H|T],T). + +read_clauses(S,Clauses):- + (setting(ground_body,true)-> + read_clauses_ground_body(S,Clauses) + ; + read_clauses_exist_body(S,Clauses) + ). + +read_clauses_ground_body(S,[(Cl,V)|Out]):- + read_term(S,Cl,[variable_names(V)]), + (Cl=end_of_file-> + Out=[] + ; + read_clauses_ground_body(S,Out) + ). + + +read_clauses_exist_body(S,[(Cl,V)|Out]):- + read_term(S,Cl,[variable_names(VN)]), + extract_vars_cl(Cl,VN,V), + (Cl=end_of_file-> + Out=[] + ; + read_clauses_exist_body(S,Out) + ). + +extract_vars_cl(end_of_file,[]). + +extract_vars_cl(Cl,VN,Couples):- + (Cl=(H:-_B)-> + true + ; + H=Cl + ), + extract_vars(H,[],V), + pair(VN,V,Couples). + +pair(_VN,[],[]). + +pair([VN= _V|TVN],[V|TV],[VN=V|T]):- + pair(TVN,TV,T). + +extract_vars(Var,V0,V):- + var(Var),!, + (member_eq(Var,V0)-> + V=V0 + ; + append(V0,[Var],V) + ). + +extract_vars(Term,V0,V):- + Term=..[_F|Args], + extract_vars_list(Args,V0,V). + +extract_vars_list([],V,V). + +extract_vars_list([Term|T],V0,V):- + extract_vars(Term,V0,V1), + extract_vars_list(T,V1,V). + + +listN(N,N,[]):-!. + +listN(NIn,N,[NIn|T]):- + N1 is NIn+1, + listN(N1,N,T). +/* end of predicates for parsing an input file containing a program */ + +/* start of utility predicates */ +list2or([X],X):- + X\=;(_,_),!. + +list2or([H|T],(H ; Ta)):-!, + list2or(T,Ta). + +list2and([X],X):- + X\=(_,_),!. + +list2and([H|T],(H,Ta)):-!, + list2and(T,Ta). + +member_eq(A,[H|_T]):- + A==H. + +member_eq(A,[_H|T]):- + member_eq(A,T). + +subset_my([],_). + +subset_my([H|T],L):- + member_eq(H,L), + subset_my(T,L). + +remove_duplicates_eq([],[]). + +remove_duplicates_eq([H|T],T1):- + member_eq(H,T),!, + remove_duplicates_eq(T,T1). + +remove_duplicates_eq([H|T],[H|T1]):- + remove_duplicates_eq(T,T1). + +builtin(_A is _B). +builtin(_A > _B). +builtin(_A < _B). +builtin(_A >= _B). +builtin(_A =< _B). +builtin(_A =:= _B). +builtin(_A =\= _B). +builtin(true). +builtin(false). +builtin(_A = _B). +builtin(_A==_B). +builtin(_A\=_B). +builtin(_A\==_B). +builtin(length(_L,_N)). +builtin(member(_El,_L)). +builtin(average(_L,_Av)). +builtin(max_list(_L,_Max)). +builtin(min_list(_L,_Max)). +builtin(nth0(_,_,_)). +builtin(nth(_,_,_)). +average(L,Av):- + sum_list(L,Sum), + length(L,N), + Av is Sum/N. + +clique([],[]):-!. + +clique(Graph,Clique):- + vertices(Graph,Candidates), + extend_cycle(Graph,Candidates,[],[],Clique). + +extend_cycle(G,[H|T],Not,CS,CSOut):- + neighbours(H, G, Neigh), + intersection(Neigh,T,NewCand), + intersection(Neigh,Not,NewNot), + extend(G,NewCand,NewNot,[H|CS],CSOut). + +extend_cycle(G,[H|T],Not,CS,CSOut):- + extend_cycle(G,T,[H|Not],CS,CSOut). + +extend(_G,[],[],CompSub,CompSub):-!. + +extend(G,Cand,Not,CS,CSOut):- + extend_cycle(G,Cand,Not,CS,CSOut). + +intersection([],_Y,[]). + +intersection([H|T],Y,[H|Z]):- + member(H,Y),!, + intersection(T,Y,Z). + +intersection([_H|T],Y,Z):- + intersection(T,Y,Z). + +/* set(Par,Value) can be used to set the value of a parameter */ +set(Parameter,Value):- + retract(setting(Parameter,_)), + assert(setting(Parameter,Value)). + +/* end of utility predicates */ + diff --git a/packages/cplint/lpadclpbn.pl b/packages/cplint/lpadclpbn.pl new file mode 100644 index 000000000..180318415 --- /dev/null +++ b/packages/cplint/lpadclpbn.pl @@ -0,0 +1,1183 @@ +/* + LPAD and CP-Logic reasoning suite + File lpadclpbn.pl + Goal oriented interpreter for LPADs based on SLDNF + Copyright (c) 2008, Fabrizio Riguzzi + Inference is performed translating the portion of the LPAD related to the goal + into CLP(BN) +*/ + +:- module(lpadclpbn, [p/1, + s/2,sc/3,s/6,sc/7,set/2,setting/2]). + + +:-dynamic rule/4,def_rule/2,setting/2. + +:-use_module(library(lists)). +:-use_module(library(ugraphs)). +:-use_module(library(avl)). +:-use_module(library(clpbn)). + +:-set_clpbn_flag(suppress_attribute_display,true). + +:-set_clpbn_flag(bnt_model,propositional). + + +/* start of list of parameters that can be set by the user with +set(Parameter,Value) */ +setting(epsilon_parsing,0.00001). +setting(save_dot,false). +setting(ground_body,true). +/* available values: true, false +if true, both the head and the body of each clause will be grounded, otherwise +only the head is grounded. In the case in which the body contains variables +not appearing in the head, the body represents an existential event */ + +setting(cpt_zero,0.0001). + +/* end of list of parameters */ + +/* s(GoalsList,Prob) compute the probability of a list of goals +GoalsLis can have variables, s returns in backtracking all the solutions with +their corresponding probability */ +s(GL,P):- + setof(Deriv,find_deriv(GL,Deriv),LDup),!, + append_all(LDup,[],L), + remove_head(L,L1), + remove_duplicates(L1,L2), + build_ground_lpad(L2,0,CL), + convert_to_clpbn(CL,GL,LV,P). + +s(_GL,0.0). +/* sc(GoalsList,EvidenceList,Prob) compute the probability of a list of goals +GoalsList given EvidenceList. Both lists can have variables, sc returns in +backtracking all the solutions with their corresponding probability +Time1 is the time for performing resolution +Time2 is the time for performing bayesian inference */ +sc(GL,GLC,P):- + (setof(Deriv,find_deriv(GLC,Deriv),LDupC)-> + (setof(Deriv,find_deriv(GL,Deriv),LDup)-> + append_all(LDup,[],L), + remove_head(L,L1), + append_all(LDupC,[],LC), + remove_head(LC,LC1), + append(L1,LC1,LD), + remove_duplicates(LD,LD1), + build_ground_lpad(LD1,0,CL), + convert_to_clpbn(CL,GL,LV,P,GLC) + ; + P=0.0 + ) + ; + P=undef + ). + + + +/* s(GoalsList,Prob,Time1,Time2) compute the probability of a list of goals +GoalsLis can have variables, s returns in backtracking all the solutions with +their corresponding probability +Time1 is the time for performing resolution +Time2 is the time for performing bayesian inference */ +s(GL,P,Time1,Time2):- + statistics(cputime,[_,_]), + statistics(walltime,[_,_]), + (setof(Deriv,find_deriv(GL,Deriv),LDup)-> + append_all(LDup,[],L), + remove_head(L,L1), + remove_duplicates(L1,L2), + build_ground_lpad(L2,0,CL), + convert_to_clpbn(CL,GL,LV,P), + statistics(cputime,[_,CT2]), + Time1 is CT2/1000, + statistics(walltime,[_,WT2]), + Time2 is WT2/1000 + ; + P=0.0, + statistics(cputime,[_,CT1]), + Time1 is CT1/1000, + statistics(walltime,[_,WT1]), + Time2 is WT1/1000 + ). + +s(GoalsList,Prob,CPUTime1,CPUTime2,WallTime1,WallTime2):- + solve(GoalsList,Prob,CPUTime1,CPUTime2,WallTime1,WallTime2). + + +solve(GL,P,CPUTime1,CPUTime2,WallTime1,WallTime2):- + statistics(cputime,[_,_]), + statistics(walltime,[_,_]), + (setof(Deriv,find_deriv(GL,Deriv),LDup)-> + append_all(LDup,[],L), + remove_head(L,L1), + remove_duplicates(L1,L2), + statistics(cputime,[_,CT1]), + CPUTime1 is CT1/1000, + statistics(walltime,[_,WT1]), + WallTime1 is WT1/1000, + print_mem, + build_ground_lpad(L2,0,CL), + convert_to_clpbn(CL,GL,LV,P), + statistics(cputime,[_,CT2]), + CPUTime2 is CT2/1000, + statistics(walltime,[_,WT2]), + WallTime2 is WT2/1000 + ; + print_mem, + P=0.0, + statistics(cputime,[_,CT1]), + CPUTime1 is CT1/1000, + statistics(walltime,[_,WT1]), + WallTime1 is WT1/1000, + CPUTime2 =0.0, + statistics(walltime,[_,WT2]), + WallTime2 =0.0 + ),!, + format(user_error,"Memory after inference~n",[]), + print_mem. + +/* sc(GoalsList,EvidenceList,Prob) compute the probability of a list of goals +GoalsList given EvidenceList. Both lists can have variables, sc returns in +backtracking all the solutions with their corresponding probability */ + +sc(GL,GLC,P,CPUTime1,CPUTime2,WallTime1,WallTime2):- + statistics(cputime,[_,_]), + statistics(walltime,[_,_]), + (setof(Deriv,find_deriv(GLC,Deriv),LDupC)-> + (setof(Deriv,find_deriv(GL,Deriv),LDup)-> + append_all(LDup,[],L), + remove_head(L,L1), + append_all(LDupC,[],LC), + remove_head(LC,LC1), + append(L1,LC1,LD), + remove_duplicates(LD,LD1), + statistics(cputime,[_,CT1]), + CPUTime1 is CT1/1000, + statistics(walltime,[_,WT1]), + WallTime1 is WT1/1000, + print_mem, + build_ground_lpad(LD1,0,CL), + convert_to_clpbn(CL,GL,LV,P,GLC), + statistics(cputime,[_,CT2]), + CPUTime2 is CT2/1000, + statistics(walltime,[_,WT2]), + WallTime2 is WT2/1000 + ; + P=0.0, + print_mem, + format(user_error,"Porb 0~n",[]), + statistics(cputime,[_,CT1]), + CPUTime1 is CT1/1000, + statistics(walltime,[_,WT1]), + WallTime1 is WT1/1000, + CPUTime2 =0.0, + WallTime2 =0.0 + ) + ; + P=undef, + print_mem, + statistics(cputime,[_,CT1]), + CPUTime1 is CT1/1000, + statistics(walltime,[_,WT1]), + WallTime1 is WT1/1000, + CPUTime2 =0.0, + WallTime2 =0.0, + print_mem, + format(user_error,"Undef~n",[]) + ), + format(user_error,"Memory after inference~n",[]), + print_mem. + +remove_head([],[]). + +remove_head([(_N,R,S)|T],[(R,S)|T1]):- + remove_head(T,T1). + +append_all([],L,L):-!. + +append_all([LIntH|IntT],IntIn,IntOut):- + append(IntIn,LIntH,Int1), + append_all(IntT,Int1,IntOut). + +process_goals([],[],[]). + +process_goals([H|T],[HG|TG],[HV|TV]):- + H=..[F,HV|Rest], + HG=..[F|Rest], + process_goals(T,TG,TV). + +build_ground_lpad([],_N,[]). + +build_ground_lpad([(R,S)|T],N,[(N1,Head1,Body1)|T1]):- + rule(R,S,_,Head,Body), + N1 is N+1, + merge_identical(Head,Head1), + remove_built_ins(Body,Body1), + build_ground_lpad(T,N1,T1). + +remove_built_ins([],[]):-!. + +remove_built_ins([\+H|T],T1):- + builtin(H),!, + remove_built_ins(T,T1). + +remove_built_ins([H|T],T1):- + builtin(H),!, + remove_built_ins(T,T1). + +remove_built_ins([H|T],[H|T1]):- + remove_built_ins(T,T1). + +merge_identical([],[]):-!. + +merge_identical([A:P|T],[A:P1|Head]):- + find_identical(A,P,T,P1,T1), + merge_identical(T1,Head). + +find_identical(_A,P,[],P,[]):-!. + +find_identical(A,P0,[A:P|T],P1,T1):-!, + P2 is P0+P, + find_identical(A,P2,T,P1,T1). + +find_identical(A,P0,[H:P|T],P1,[H:P|T1]):- + find_identical(A,P0,T,P1,T1). + +convert_to_clpbn(CL,GL,LV,P,GLC):- + find_ground_atoms(CL,[],GAD), + remove_duplicates(GAD,GANull), + delete(GANull,'',GA), + atom_vars(GA,[],AV,AVL), + choice_vars(CL,[],CV,CVL), + add_rule_tables(CL,CVL,AV), + add_atoms_tables(AVL,GA,CL,CV,AV), + add_ev(GLC,AV), + get_prob(GL,AV,AVL,CVL,P). + +add_ev([],_AV). + +add_ev([\+ H|T],AV):-!, + avl_lookup(H,V,AV), + clpbn:put_atts(V,evidence(0)), + add_ev(T,AV). + +add_ev([H|T],AV):- + avl_lookup(H,V,AV), + clpbn:put_atts(V,evidence(1)), + add_ev(T,AV). + +convert_to_clpbn(CL,GL,LV,P):- + find_ground_atoms(CL,[],GAD), + remove_duplicates(GAD,GANull), + delete(GANull,'',GA), + atom_vars(GA,[],AV,AVL), + choice_vars(CL,[],CV,CVL), + add_rule_tables(CL,CVL,AV), + add_atoms_tables(AVL,GA,CL,CV,AV), + get_prob(GL,AV,AVL,CVL,P). + +get_prob(GL,AV,AVL,CVL,P):- + build_table_conj(GL,Table), + find_atoms_body(GL,Atoms), + lookup_gvars(GL,AV,Parents,[],_Signs), + {G=goal with p([f,t],Table, Parents)}, + append(AVL,CVL,Vars), + append(Vars,[G],Vars1), + clpbn:call_solver([G], Vars1), + clpbn_display:get_atts(G, [posterior(Vs,Vals,[_P0,P],AllDiffs)]). + +lookup_gvars([],_AV,[],S,S). + +lookup_gvars([\+ H|T],AV,[HV|T1],Sign0,Sign2):- !, + avl_lookup(H,HV,AV), + clpbn:get_atts(HV, [key(K)]), + avl_insert(K,f,Sign0,Sign1), + lookup_gvars(T,AV,T1,Sign1,Sign2). + +lookup_gvars([H|T],AV,[HV|T1],Sign0,Sign2):- + avl_lookup(H,HV,AV), + clpbn:get_atts(HV, [key(K)]), + avl_insert(K,t,Sign0,Sign1), + lookup_gvars(T,AV,T1,Sign1,Sign2). + +add_atoms_tables([],[],_CL,_CV,_AV). + +add_atoms_tables([H|T],[HA|TA],CL,CV,AV):- + find_rules_with_atom(HA,CL,R), + parents(R,CV,Par), + build_table_atoms(HA,R,Table), + {H = HA with p([f,t],Table,Par)}, + add_atoms_tables(T,TA,CL,CV,AV). + +build_table_conj(R,Table):- + build_col_conj(R,t,f,[],Row1), + build_col_conj(R,t,t,Row1,Table). + +build_col_conj([],Tr,Final,Row0,Row1):- + (Tr=Final-> + append(Row0,[1.0],Row1) + ; + setting(cpt_zero,Zero), + append(Row0,[Zero],Row1) + ). + +build_col_conj([\+H|RP],Tr,Final,Row0,Row2):-!, + build_col_conj(RP,Tr,Final,Row0,Row1), + build_col_conj(RP,f,Final,Row1,Row2). + +build_col_conj([H|RP],Tr,Final,Row0,Row2):- + build_col_conj(RP,f,Final,Row0,Row1), + build_col_conj(RP,Tr,Final,Row1,Row2). + +build_table_atoms(H,R,Table):- + build_col(H,R,f,f,[],Row1), + build_col(H,R,t,f,Row1,Table). + +build_col(A,[],Tr,Found,Row0,Row1):- + (Tr=Found-> + append(Row0,[1.0],Row1) + ; + setting(cpt_zero,Zero), + append(Row0,[Zero],Row1) + ). + +build_col(A,[(N,H)|RP],Tr,Found,Row0,Row1):- + build_col_cycle(A,H,RP,Tr,Found,Row0,Row1). + +build_col_cycle(_A,[],_RP,_Tr,_Found,Row,Row). + +build_col_cycle(A,[A:P|T],RP,Tr,Found,Row0,Row2):-!, + build_col(A,RP,Tr,t,Row0,Row1), + build_col_cycle(A,T,RP,Tr,Found,Row1,Row2). + +build_col_cycle(A,[_|T],RP,Tr,Found,Row0,Row2):- + build_col(A,RP,Tr,Found,Row0,Row1), + build_col_cycle(A,T,RP,Tr,Found,Row1,Row2). + +parents([],_CV,[]). + +parents([(N,_H)|T],CV,[V|T1]):- + avl_lookup(N,V,CV), + parents(T,CV,T1). + +find_rules_with_atom(_A,[],[]). + +find_rules_with_atom(A,[(N,Head,Body)|T],[(N,Head)|R]):- + member(A:P,Head),!, + find_rules_with_atom(A,T,R). + +find_rules_with_atom(A,[_H|T],R):- + find_rules_with_atom(A,T,R). + +add_rule_tables([],[],_AV). + +add_rule_tables([(N,Head,Body)|T],[CV|TCV],AV):- + find_atoms_head(Head,Atoms,Probs), + get_parents(Body,AV,Par), + build_table(Probs,Body,Table), + {CV=ch(N) with p(Atoms,Table,Par)}, + add_rule_tables(T,TCV,AV). + +build_table([P],L,Row):-!, + build_col(L,t,P,1.0,Row). + +build_table([HP|TP],L,Tab):- + setting(cpt_zero,Zero), + build_col(L,t,HP,Zero,Row), + append(Row,Row1,Tab), + build_table(TP,L,Row1). + +build_col([],t,HP,_PNull,[HP]):-!. + +build_col([],f,_HP,PNull,[PNull]):-!. + + +build_col([\+ H|T],Truth,P,PNull,Row):-!, + build_col(T,Truth,P,PNull,Row1), + append(Row1,Row2,Row), + build_col(T,f,P,PNull,Row2). + +build_col([_H|T],Truth,P,PNull,Row):- + build_col(T,f,P,PNull,Row1), + append(Row1,Row2,Row), + build_col(T,Truth,P,PNull,Row2). + +get_parents([],_AV,[]). + +get_parents([\+ H|T],AV,[V|T1]):-!, + avl_lookup(H,V,AV), + get_parents(T,AV,T1). + +get_parents([H|T],AV,[V|T1]):-!, + avl_lookup(H,V,AV), + get_parents(T,AV,T1). + +choice_vars([],Tr,Tr,[]). + +choice_vars([(N,_H,_B)|T],Tr0,Tr1,[NV|T1]):- + avl_insert(N,NV,Tr0,Tr2), + choice_vars(T,Tr2,Tr1,T1). + +atom_vars([],Tr,Tr,[]). + +atom_vars([H|T],Tr0,Tr1,[VH|VT]):- + avl_insert(H,VH,Tr0,Tr2), + atom_vars(T,Tr2,Tr1,VT). + +find_ground_atoms([],GA,GA). + +find_ground_atoms([(_N,Head,Body)|T],GA0,GA1):- + find_atoms_head(Head,AtH,_P), + append(GA0,AtH,GA2), + find_atoms_body(Body,AtB), + append(GA2,AtB,GA3), + find_ground_atoms(T,GA3,GA1). + +find_atoms_body([],[]). + +find_atoms_body([\+H|T],[H|T1]):-!, + find_atoms_body(T,T1). + +find_atoms_body([H|T],[H|T1]):- + find_atoms_body(T,T1). + + +find_atoms_head([],[],[]). + +find_atoms_head([H:P|T],[H|TA],[P|TP]):- + find_atoms_head(T,TA,TP). + +print_mem:- + statistics(global_stack,[GS,GSF]), + statistics(local_stack,[LS,LSF]), + statistics(heap,[HP,HPF]), + statistics(trail,[TU,TF]), + format(user_error,"~nGloabal stack used ~d execution stack free: ~d~n",[GS,GSF]), + format(user_error,"Local stack used ~d execution stack free: ~d~n",[LS,LSF]), + format(user_error,"Heap used ~d heap free: ~d~n",[HP,HPF]), + format(user_error,"Trail used ~d Trail free: ~d~n",[TU,TF]). + +find_deriv(GoalsList,Deriv):- + solve(GoalsList,[],DerivDup), + remove_duplicates(DerivDup,Deriv). +/* duplicate can appear in the C set because two different unistantiated clauses may become the +same clause when instantiated */ + + + +/* solve(GoalsList,CIn,COut) takes a list of goals and an input C set +and returns an output C set +The C set is a list of triple (N,R,S) where +- N is the index of the head atom used, starting from 0 +- R is the index of the non ground rule used, starting from 1 +- S is the substitution of rule R, in the form of a list whose elements + are of the form 'VarName'=value +*/ +solve([],C,C):-!. + +solve([bagof(V,EV^G,L)|T],CIn,COut):-!, + list2and(GL,G), + bagof((V,C),EV^solve(GL,CIn,C),LD), + length(LD,N), + build_initial_graph(N,GrIn), + build_graph(LD,0,GrIn,Gr), + clique(Gr,Clique), + build_Cset(LD,Clique,L,[],C1), + remove_duplicates_eq(C1,C2), + solve(T,C2,COut). + +solve([bagof(V,G,L)|T],CIn,COut):-!, + list2and(GL,G), + bagof((V,C),solve(GL,CIn,C),LD), + length(LD,N), + build_initial_graph(N,GrIn), + build_graph(LD,0,GrIn,Gr), + clique(Gr,Clique), + build_Cset(LD,Clique,L,[],C1), + remove_duplicates_eq(C1,C2), + solve(T,C2,COut). + + +solve([setof(V,EV^G,L)|T],CIn,COut):-!, + list2and(GL,G), + setof((V,C),EV^solve(GL,CIn,C),LD), + length(LD,N), + build_initial_graph(N,GrIn), + build_graph(LD,0,GrIn,Gr), + clique(Gr,Clique), + build_Cset(LD,Clique,L1,[],C1), + remove_duplicates(L1,L), + solve(T,C1,COut). + +solve([setof(V,G,L)|T],CIn,COut):-!, + list2and(GL,G), + setof((V,C),solve(GL,CIn,C),LD), + length(LD,N), + build_initial_graph(N,GrIn), + build_graph(LD,0,GrIn,Gr), + clique(Gr,Clique), + build_Cset(LD,Clique,L1,[],C1), + remove_duplicates(L1,L), + solve(T,C1,COut). + +solve([\+ H |T],CIn,COut):-!, + list2and(HL,H), + (setof(D,find_deriv(HL,D),LDup)-> + rem_dup_lists(LDup,[],L), + choose_clauses(CIn,L,C1), + solve(T,C1,COut) + ; + solve(T,CIn,COut) + ). + +solve([H|T],CIn,COut):- + builtin(H),!, + call(H), + solve(T,CIn,COut). + +solve([H|T],CIn,COut):- + def_rule(H,B), + append(B,T,NG), + solve(NG,CIn,COut). + +solve([H|T],CIn,COut):- + find_rule(H,(R,S,N),B,CIn), + solve_pres(R,S,N,B,T,CIn,COut). + +solve_pres(R,S,N,B,T,CIn,COut):- + member_eq((N,R,S),CIn),!, + append(B,T,NG), + solve(NG,CIn,COut). + +solve_pres(R,S,N,B,T,CIn,COut):- + append(CIn,[(N,R,S)],C1), + append(B,T,NG), + solve(NG,C1,COut). + +build_initial_graph(N,G):- + listN(0,N,Vert), + add_vertices([],Vert,G). + + +build_graph([],_N,G,G). + +build_graph([(_V,C)|T],N,GIn,GOut):- + N1 is N+1, + compatible(C,T,N,N1,GIn,G1), + build_graph(T,N1,G1,GOut). + +compatible(_C,[],_N,_N1,G,G). + +compatible(C,[(_V,H)|T],N,N1,GIn,GOut):- + (compatible(C,H)-> + add_edges(GIn,[N-N1,N1-N],G1) + ; + G1=GIn + ), + N2 is N1 +1, + compatible(C,T,N,N2,G1,GOut). + +compatible([],_C). + +compatible([(N,R,S)|T],C):- + not_present_with_a_different_head(N,R,S,C), + compatible(T,C). + +not_present_with_a_different_head(_N,_R,_S,[]). + +not_present_with_a_different_head(N,R,S,[(N,R,S)|T]):-!, + not_present_with_a_different_head(N,R,S,T). + +not_present_with_a_different_head(N,R,S,[(_N1,R,S1)|T]):- + S\=S1,!, + not_present_with_a_different_head(N,R,S,T). + +not_present_with_a_different_head(N,R,S,[(_N1,R1,_S1)|T]):- + R\=R1, + not_present_with_a_different_head(N,R,S,T). + + + +build_Cset(_LD,[],[],C,C). + +build_Cset(LD,[H|T],[V|L],CIn,COut):- + nth0(H,LD,(V,C)), + append(C,CIn,C1), + build_Cset(LD,T,L,C1,COut). + + +/* find_rule(G,(R,S,N),Body,C) takes a goal G and the current C set and +returns the index R of a disjunctive rule resolving with G together with +the index N of the resolving head, the substitution S and the Body of the +rule */ +find_rule(H,(R,S,N),Body,C):- + rule(R,S,_,Head,Body), + member_head(H,Head,0,N), + not_already_present_with_a_different_head(N,R,S,C). + +find_rule(H,(R,S,Number),Body,C):- + rule(R,S,_,uniform(H:1/_Num,_P,Number),Body), + not_already_present_with_a_different_head(Number,R,S,C). + +not_already_present_with_a_different_head(_N,_R,_S,[]). + +not_already_present_with_a_different_head(N,R,S,[(N1,R,S1)|T]):- + not_different(N,N1,S,S1),!, + not_already_present_with_a_different_head(N,R,S,T). + +not_already_present_with_a_different_head(N,R,S,[(_N1,R1,_S1)|T]):- + R\==R1, + not_already_present_with_a_different_head(N,R,S,T). + +not_different(_N,_N1,S,S1):- + S\=S1,!. + +not_different(N,N1,S,S1):- + N\=N1,!, + dif(S,S1). + +not_different(N,N,S,S). + + +member_head(H,[(H:_P)|_T],N,N). + +member_head(H,[(_H:_P)|T],NIn,NOut):- + N1 is NIn+1, + member_head(H,T,N1,NOut). + +/* choose_clauses(CIn,LC,COut) takes as input the current C set and +the set of C sets for a negative goal and returns a new C set that +excludes all the derivations for the negative goals */ +choose_clauses(C,[],C). + +choose_clauses(CIn,[D|T],COut):- + member((N,R,S),D), + already_present_with_a_different_head(N,R,S,CIn),!, + choose_a_head(N,R,S,CIn,C1), + choose_clauses(C1,T,COut). + + +choose_clauses(CIn,[D|T],COut):- + member((N,R,S),D), + new_head(N,R,S,N1), + \+ already_present(N1,R,S,CIn), + impose_dif_cons(R,S,CIn), + choose_clauses([(N1,R,S)|CIn],T,COut). + +impose_dif_cons(_R,_S,[]):-!. + +impose_dif_cons(R,S,[(_NH,R,SH)|T]):-!, + dif(S,SH), + impose_dif_cons(R,S,T). + +impose_dif_cons(R,S,[_H|T]):- + impose_dif_cons(R,S,T). + +/* instantiation_present_with_the_same_head(N,R,S,C) +takes rule R with substitution S and selected head N and a C set +and asserts dif constraints for all the clauses in C of which RS +is an instantitation and have the same head selected */ +instantiation_present_with_the_same_head(_N,_R,_S,[]). + +instantiation_present_with_the_same_head(N,R,S,[(NH,R,SH)|T]):- + \+ \+ S=SH,!, + dif_head_or_subs(N,R,S,NH,SH,T). + +instantiation_present_with_the_same_head(N,R,S,[_H|T]):- + instantiation_present_with_the_same_head(N,R,S,T). + +dif_head_or_subs(N,R,S,NH,_SH,T):- + dif(N,NH), + instantiation_present_with_the_same_head(N,R,S,T). + +dif_head_or_subs(N,R,S,N,SH,T):- + dif(S,SH), + instantiation_present_with_the_same_head(N,R,S,T). + +/* case 1 of Select: a more general rule is present in C with +a different head, instantiate it */ +choose_a_head(N,R,S,[(NH,R,SH)|T],[(NH,R,SH)|T]):- + S=SH, + dif(N,NH). + +/* case 2 of Select: a more general rule is present in C with +a different head, ensure that they do not generate the same +ground clause */ +choose_a_head(N,R,S,[(NH,R,SH)|T],[(NH,R,S),(NH,R,SH)|T]):- + \+ \+ S=SH, S\==SH, + dif(N,NH), + dif(S,SH). + +choose_a_head(N,R,S,[H|T],[H|T1]):- + choose_a_head(N,R,S,T,T1). + +/* select a head different from N for rule R with +substitution S, return it in N1 */ +new_head(N,R,S,N1):- + rule(R,S,Numbers,Head,_Body), + Head\=uniform(_,_,_),!, + nth0(N, Numbers, _Elem, Rest), + member(N1,Rest). + +new_head(N,R,S,N1):- + rule(R,S,Numbers,uniform(_A:1/Tot,_L,_Number),_Body), + listN(0,Tot,Numbers), + nth0(N, Numbers, _Elem, Rest), + member(N1,Rest). + +already_present_with_a_different_head(N,R,S,[(NH,R,SH)|_T]):- + \+ \+ S=SH,NH \= N. + +already_present_with_a_different_head(N,R,S,[_H|T]):- + already_present_with_a_different_head(N,R,S,T). + + +/* checks that a rule R with head N and selection S is already +present in C (or a generalization of it is in C) */ +already_present(N,R,S,[(N,R,SH)|_T]):- + S=SH. + +already_present(N,R,S,[_H|T]):- + already_present(N,R,S,T). + +/* rem_dup_lists removes the C sets that are a superset of +another C sets further on in the list of C sets */ +/* rem_dup_lists removes the C sets that are a superset of +another C sets further on in the list of C sets */ +rem_dup_lists([],L,L). + +rem_dup_lists([H|T],L0,L):- + (member_subset(H,T);member_subset(H,L0)),!, + rem_dup_lists(T,L0,L). + +rem_dup_lists([H|T],L0,L):- + rem_dup_lists(T,[H|L0],L). + +member_subset(E,[H|_T]):- + subset_my(H,E),!. + +member_subset(E,[_H|T]):- + member_subset(E,T). + + + +/* predicates for building the formula to be converted into a BDD */ + +/* build_formula(LC,Formula,VarIn,VarOut) takes as input a set of C sets +LC and a list of Variables VarIn and returns the formula and a new list +of variables VarOut +Formula is of the form [Term1,...,Termn] +Termi is of the form [Factor1,...,Factorm] +Factorj is of the form (Var,Value) where Var is the index of +the multivalued variable Var and Value is the index of the value +*/ +build_formula([],[],Var,Var). + +build_formula([D|TD],[F|TF],VarIn,VarOut):- + build_term(D,F,VarIn,Var1), + build_formula(TD,TF,Var1,VarOut). + +build_term([],[],Var,Var). + +build_term([(N,R,S)|TC],[[NVar,N]|TF],VarIn,VarOut):- + (nth0_eq(0,NVar,VarIn,(R,S))-> + Var1=VarIn + ; + append(VarIn,[(R,S)],Var1), + length(VarIn,NVar) + ), + build_term(TC,TF,Var1,VarOut). + +/* nth0_eq(PosIn,PosOut,List,El) takes as input a List, +an element El and an initial position PosIn and returns in PosOut +the position in the List that contains an element exactly equal to El +*/ +nth0_eq(N,N,[H|_T],El):- + H==El,!. + +nth0_eq(NIn,NOut,[_H|T],El):- + N1 is NIn+1, + nth0_eq(N1,NOut,T,El). + +/* var2numbers converts a list of couples (Rule,Substitution) into a list +of triples (N,NumberOfHeadsAtoms,ListOfProbabilities), where N is an integer +starting from 0 */ +var2numbers([],_N,[]). + +var2numbers([(R,S)|T],N,[[N,ValNumber,Probs]|TNV]):- + find_probs(R,S,Probs), + length(Probs,ValNumber), + N1 is N+1, + var2numbers(T,N1,TNV). + +find_probs(R,S,Probs):- + rule(R,S,_N,Head,_Body), + get_probs(Head,Probs). + +get_probs(uniform(_A:1/Num,_P,_Number),ListP):- + Prob is 1/Num, + list_el(Num,Prob,ListP). + +get_probs([],[]). + +get_probs([_H:P|T],[P1|T1]):- + P1 is P, + get_probs(T,T1). + +list_el(0,_P,[]):-!. + +list_el(N,P,[P|T]):- + N1 is N-1, + list_el(N1,P,T). + +/* end of predicates for building the formula to be converted into a BDD */list_el(0,_P,[]):-!. + + +/* start of predicates for parsing an input file containing a program */ + +/* p(File) parses the file File.cpl. It can be called more than once without +exiting yap */ +p(File):- + parse(File). + +parse(File):- + atom_concat(File,'.cpl',FilePl), + open(FilePl,read,S), + read_clauses(S,C), + close(S), + retractall(rule(_,_,_,_,_)), + retractall(def_rule(_,_)), + process_clauses(C,1). + +process_clauses([(end_of_file,[])],_N). + +process_clauses([((H:-B),V)|T],N):- + H=uniform(A,P,L),!, + list2and(BL,B), + process_body(BL,V,V1), + remove_vars([P],V1,V2), + append(BL,[length(L,Tot),nth0(Number,L,P)],BL1), + append(V2,['Tot'=Tot],V3), + assertz(rule(N,V3,_NH,uniform(A:1/Tot,L,Number),BL1)), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([((H:-B),V)|T],N):- + H=(_;_),!, + list2or(HL1,H), + process_head(HL1,HL), + list2and(BL,B), + process_body(BL,V,V1), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V1,NH,HL,BL)), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([((H:-B),V)|T],N):- + H=(_:_),!, + list2or(HL1,H), + process_head(HL1,HL), + list2and(BL,B), + process_body(BL,V,V1), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V1,NH,HL,BL)), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([((H:-B),V)|T],N):-!, + process_head([H:1.0],HL), + list2and(BL,B), + process_body(BL,V,V1), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V1,NH,HL,BL)), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([(H,V)|T],N):- + H=(_;_),!, + list2or(HL1,H), + process_head(HL1,HL), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V,NH,HL,[])), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([(H,V)|T],N):- + H=(_:_),!, + list2or(HL1,H), + process_head(HL1,HL), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V,NH,HL,[])), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([(H,V)|T],N):- + process_head([H:1.0],HL), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V,NH,HL,[])), + N1 is N+1, + process_clauses(T,N1). + +/* if the annotation in the head are not ground, the null atom is not added +and the eventual formulas are not evaluated */ + +process_head(HL,NHL):- + (ground_prob(HL)-> + process_head_ground(HL,0.0,NHL) + ; + NHL=HL + ). + +ground_prob([]). + +ground_prob([_H:PH|T]):- + ground(PH), + ground_prob(T). + +process_head_ground([H:PH],P,[H:PH1,'':PNull1]):-!, + PH1 is PH, + PNull is 1.0-P-PH1, + (PNull>=0.0-> + PNull1 =PNull + ; + PNull1=0.0 + ). + +process_head_ground([H:PH|T],P,[H:PH1|NT]):- + PH1 is PH, + P1 is P+PH1, + process_head_ground(T,P1,NT). + +/* setof must have a goal of the form B^G where B is a term containing the existential variables */ +process_body([],V,V). + +process_body([setof(A,B^_G,_L)|T],VIn,VOut):-!, + get_var(A,VA), + get_var(B,VB), + remove_vars(VA,VIn,V1), + remove_vars(VB,V1,V2), + process_body(T,V2,VOut). + +process_body([setof(A,_G,_L)|T],VIn,VOut):-!, + get_var(A,VA), + remove_vars(VA,VIn,V1), + process_body(T,V1,VOut). + +process_body([bagof(A,B^_G,_L)|T],VIn,VOut):-!, + get_var(A,VA), + get_var(B,VB), + remove_vars(VA,VIn,V1), + remove_vars(VB,V1,V2), + process_body(T,V2,VOut). + +process_body([bagof(A,_G,_L)|T],VIn,VOut):-!, + get_var(A,VA), + remove_vars(VA,VIn,V1), + process_body(T,V1,VOut). + +process_body([_H|T],VIn,VOut):-!, + process_body(T,VIn,VOut). + +get_var_list([],[]). + +get_var_list([H|T],[H|T1]):- + var(H),!, + get_var_list(T,T1). + +get_var_list([H|T],VarOut):-!, + get_var(H,Var), + append(Var,T1,VarOut), + get_var_list(T,T1). + +get_var(A,[A]):- + var(A),!. + +get_var(A,V):- + A=..[_F|Args], + get_var_list(Args,V). + +remove_vars([],V,V). + +remove_vars([H|T],VIn,VOut):- + delete_var(H,VIn,V1), + remove_vars(T,V1,VOut). + +delete_var(_H,[],[]). + +delete_var(V,[VN=Var|T],[VN=Var|T1]):- + V\==Var,!, + delete_var(V,T,T1). + +delete_var(_V,[_H|T],T). + +/* predicates for reading in the program clauses */ +read_clauses(S,Clauses):- + (setting(ground_body,true)-> + read_clauses_ground_body(S,Clauses) + ; + read_clauses_exist_body(S,Clauses) + ). + + +read_clauses_ground_body(S,[(Cl,V)|Out]):- + read_term(S,Cl,[variable_names(V)]), + (Cl=end_of_file-> + Out=[] + ; + read_clauses_ground_body(S,Out) + ). + + +read_clauses_exist_body(S,[(Cl,V)|Out]):- + read_term(S,Cl,[variable_names(VN)]), + extract_vars_cl(Cl,VN,V), + (Cl=end_of_file-> + Out=[] + ; + read_clauses_exist_body(S,Out) + ). + + +extract_vars_cl(end_of_file,[]). + +extract_vars_cl(Cl,VN,Couples):- + (Cl=(H:-_B)-> + true + ; + H=Cl + ), + extract_vars(H,[],V), + pair(VN,V,Couples). + + +pair(_VN,[],[]). + +pair([VN= _V|TVN],[V|TV],[VN=V|T]):- + pair(TVN,TV,T). + + +extract_vars(Var,V0,V):- + var(Var),!, + (member_eq(Var,V0)-> + V=V0 + ; + append(V0,[Var],V) + ). + +extract_vars(Term,V0,V):- + Term=..[_F|Args], + extract_vars_list(Args,V0,V). + + +extract_vars_list([],V,V). + +extract_vars_list([Term|T],V0,V):- + extract_vars(Term,V0,V1), + extract_vars_list(T,V1,V). + + +listN(N,N,[]):-!. + +listN(NIn,N,[NIn|T]):- + N1 is NIn+1, + listN(N1,N,T). +/* end of predicates for parsing an input file containing a program */ + +/* start of utility predicates */ +list2or([X],X):- + X\=;(_,_),!. + +list2or([H|T],(H ; Ta)):-!, + list2or(T,Ta). + +list2and([X],X):- + X\=(_,_),!. + +list2and([H|T],(H,Ta)):-!, + list2and(T,Ta). + +member_eq(A,[H|_T]):- + A==H,!. + +member_eq(A,[_H|T]):- + member_eq(A,T). + +subset_my([],_). + +subset_my([H|T],L):- + member_eq(H,L), + subset_my(T,L). + +remove_duplicates_eq([],[]). + +remove_duplicates_eq([H|T],T1):- + member_eq(H,T),!, + remove_duplicates_eq(T,T1). + +remove_duplicates_eq([H|T],[H|T1]):- + remove_duplicates_eq(T,T1). + +builtin(_A is _B). +builtin(_A > _B). +builtin(_A < _B). +builtin(_A >= _B). +builtin(_A =< _B). +builtin(_A =:= _B). +builtin(_A =\= _B). +builtin(true). +builtin(false). +builtin(_A = _B). +builtin(_A==_B). +builtin(_A\=_B). +builtin(_A\==_B). +builtin(length(_L,_N)). +builtin(member(_El,_L)). +builtin(average(_L,_Av)). +builtin(max_list(_L,_Max)). +builtin(min_list(_L,_Max)). +builtin(nth0(_,_,_)). +builtin(nth(_,_,_)). +average(L,Av):- + sum_list(L,Sum), + length(L,N), + Av is Sum/N. + +clique(Graph,Clique):- + vertices(Graph,Candidates), + extend_cycle(Graph,Candidates,[],[],Clique). + +extend_cycle(G,[H|T],Not,CS,CSOut):- + neighbours(H, G, Neigh), + intersection(Neigh,T,NewCand), + intersection(Neigh,Not,NewNot), + extend(G,NewCand,NewNot,[H|CS],CSOut). + +extend_cycle(G,[H|T],Not,CS,CSOut):- + extend_cycle(G,T,[H|Not],CS,CSOut). + +extend(_G,[],[],CompSub,CompSub):-!. + +extend(G,Cand,Not,CS,CSOut):- + extend_cycle(G,Cand,Not,CS,CSOut). + +intersection([],_Y,[]). + +intersection([H|T],Y,[H|Z]):- + member(H,Y),!, + intersection(T,Y,Z). + +intersection([_H|T],Y,Z):- + intersection(T,Y,Z). + +/* set(Par,Value) can be used to set the value of a parameter */ +set(Parameter,Value):- + retract(setting(Parameter,_)), + assert(setting(Parameter,Value)). + +/* end of utility predicates */ diff --git a/packages/cplint/lpadsld.pl b/packages/cplint/lpadsld.pl new file mode 100644 index 000000000..a9578f9ad --- /dev/null +++ b/packages/cplint/lpadsld.pl @@ -0,0 +1,1480 @@ +/* + LPAD and CP-Logic reasoning suite + File lpadsld.pl + Goal oriented interpreter for LPADs based on SLDNF + Copyright (c) 2007, Fabrizio Riguzzi +*/ + +:-dynamic rule/4,def_rule/2,setting/2. + +:-use_module(library(lists)). +:-use_module(library(ugraphs)). + +:-load_foreign_files(['cplint'],[],init_my_predicates). + +/* start of list of parameters that can be set by the user with +set(Parameter,Value) */ +setting(epsilon_parsing,0.00001). +setting(save_dot,false). +setting(ground_body,false). +/* available values: true, false +if true, both the head and the body of each clause will be grounded, otherwise +only the head is grounded. In the case in which the body contains variables +not appearing in the head, the body represents an existential event */ +setting(min_error,0.01). +setting(depth_bound,4). +setting(prob_threshold,0.00001). +/* end of list of parameters */ + +/* s(GoalsLIst,Prob) compute the probability of a list of goals +GoalsLis can have variables, s returns in backtracking all the solutions with their +corresponding probability */ +s(GoalsList,Prob):- + solve(GoalsList,Prob). + + +solve(GoalsList,Prob):- + setof(Deriv,find_deriv(GoalsList,Deriv),LDup), + rem_dup_lists(LDup,[],L), + build_formula(L,Formula,[],Var), + var2numbers(Var,0,NewVar), + (setting(save_dot,true)-> + format("Variables: ~p~n",[Var]), + compute_prob(NewVar,Formula,Prob,1) + ; + compute_prob(NewVar,Formula,Prob,0) + ). + +solve(GoalsList,0.0):- + \+ find_deriv(GoalsList,_Deriv). + +/* s(GoalsList,Prob,CPUTime1,CPUTime2,WallTime1,WallTime2) compute the probability of a list of goals +GoalsLis can have variables, s returns in backtracking all the solutions with +their corresponding probability +CPUTime1 is the cpu time for performing resolution +CPUTime2 is the cpu time for elaborating the BDD +WallTime1 is the wall time for performing resolution +WallTime2 is the wall time for elaborating the BDD */ + + +s(GoalsList,Prob,CPUTime1,CPUTime2,WallTime1,WallTime2):- + solve(GoalsList,Prob,CPUTime1,CPUTime2,WallTime1,WallTime2). + + +solve(GoalsList,Prob,CPUTime1,CPUTime2,WallTime1,WallTime2):- + statistics(cputime,[_,_]), + statistics(walltime,[_,_]), + (setof(Deriv,find_deriv(GoalsList,Deriv),LDup)-> + rem_dup_lists(LDup,[],L), + statistics(cputime,[_,CT1]), + CPUTime1 is CT1/1000, + statistics(walltime,[_,WT1]), + WallTime1 is WT1/1000, + print_mem, + build_formula(L,Formula,[],Var,0,Conj), + length(L,ND), + length(Var,NV), + format(user_error,"Disjunctions :~d~nConjunctions: ~d~nVariables ~d~n",[ND,Conj,NV]), + var2numbers(Var,0,NewVar), + (setting(save_dot,true)-> + format("Variables: ~p~n",[Var]), + compute_prob(NewVar,Formula,Prob,1) + ; + compute_prob(NewVar,Formula,Prob,0) + ), + statistics(cputime,[_,CT2]), + CPUTime2 is CT2/1000, + statistics(walltime,[_,WT2]), + WallTime2 is WT2/1000 + ; + print_mem, + Prob=0.0, + statistics(cputime,[_,CT1]), + CPUTime1 is CT1/1000, + statistics(walltime,[_,WT1]), + WallTime1 is WT1/1000, + CPUTime2 =0.0, + statistics(walltime,[_,WT2]), + WallTime2 =0.0 + ),!, + format(user_error,"~nMemory after inference~n",[]), + print_mem. + +si(GoalsList,ProbL,ProbU,CPUTime):- + statistics(cputime,[_,_]), + setting(depth_bound,D), + solve_i([(GoalsList,[])],[],D,ProbL,ProbU), + statistics(cputime,[_,CT]), + CPUTime is CT/1000. + + + +solve_i(L0,Succ,D,ProbL0,ProbU0):- + (findall((G1,Deriv),(member((G0,C0),L0),solvei(G0,D,C0,Deriv,G1)),L)-> + % print_mem, + separate_ulbi(L,[],LL0,[],LU,[],Incomplete), + append(Succ,LL0,LL), + compute_prob_deriv(LL,ProbL), + append(Succ,LU,LU1), + compute_prob_deriv(LU1,ProbU), + Err is ProbU-ProbL, + setting(min_error,ME), + (Err + ProbU0=ProbU, + ProbL0=ProbL + ; + setting(depth_bound,DB), + D1 is D+DB, + solve_i(Incomplete,LL,D1,ProbL0,ProbU0) + ) + ; + % print_mem, + ProbL0=0.0, + ProbU0=0.0 + ). + +sir(GoalsList,ProbL,ProbU,CPUTime):- + statistics(cputime,[_,_]), + setting(depth_bound,D), + solveir(GoalsList,D,ProbL,ProbU), + statistics(cputime,[_,CT]), + CPUTime is CT/1000. + + + +solveir(GoalsList,D,ProbL0,ProbU0):- + (setof(Deriv,find_derivr(GoalsList,D,Deriv),LDup)-> + rem_dup_lists(LDup,[],L), + % print_mem, + separate_ulb(L,[],LL,[],LU), + compute_prob_deriv(LL,ProbL), + compute_prob_deriv(LU,ProbU), + Err is ProbU-ProbL, + setting(min_error,ME), + (Err + ProbU0=ProbU, + ProbL0=ProbL + ; + setting(depth_bound,DB), + D1 is D+DB, + solveir(GoalsList,D1,ProbL0,ProbU0) + ) + ; + % print_mem, + ProbL0=0.0, + ProbU0=0.0 + ). + + +sic(GoalsList,ProbL,ProbU,CPUTime):- + statistics(cputime,[_,_]), + setting(depth_bound,D), + solveic(GoalsList,D,ProbL,ProbU), + statistics(cputime,[_,CT]), + CPUTime is CT/1000. + + + +solveic(GoalsList,D,ProbL0,ProbU0):- + (setof((Deriv,P,Pruned),solvec(GoalsList,D,[],Deriv,1.0,P,Pruned),L)-> + % print_mem, + separate_ulbc(L,[],LL,0,Err), + compute_prob_deriv(LL,ProbL0), + ProbU0 is ProbL0+Err + /*(ProbU>1.0-> + ProbU0=1.0 + ; + ProbU0=ProbU + )*/ + ; + % print_mem, + ProbL0=0.0, + ProbU0=0.0 + ). + +compute_prob_deriv(LL,ProbL):- + build_formula(LL,FormulaL,[],VarL,0,ConjL), + length(LL,NDL), + length(VarL,NVL), + %format(user_error,"Disjunctions :~d~nConjunctions: ~d~nVariables ~d~n",[NDL,ConjL,NVL]), + var2numbers(VarL,0,NewVarL), + (setting(save_dot,true)-> + % format("Variables: ~p~n",[VarL]), + compute_prob(NewVarL,FormulaL,ProbL,1) + ; + compute_prob(NewVarL,FormulaL,ProbL,0) + ). + +print_mem:- + statistics(global_stack,[GS,GSF]), + statistics(local_stack,[LS,LSF]), + statistics(heap,[HP,HPF]), + statistics(trail,[TU,TF]), + format(user_error,"~nGloabal stack used ~d execution stack free: ~d~n",[GS,GSF]), + format(user_error,"Local stack used ~d execution stack free: ~d~n",[LS,LSF]), + format(user_error,"Heap used ~d heap free: ~d~n",[HP,HPF]), + format(user_error,"Trail used ~d Trail free: ~d~n",[TU,TF]). + +find_deriv(GoalsList,Deriv):- + solve(GoalsList,[],DerivDup), + remove_duplicates(DerivDup,Deriv). + +find_derivr(GoalsList,DB,Deriv):- + solver(GoalsList,DB,[],DerivDup), + remove_duplicates(DerivDup,Deriv). + + +/* duplicate can appear in the C set because two different unistantiated clauses may become the +same clause when instantiated */ + +/* sc(Goals,Evidence,Prob) compute the conditional probability of the list of goals +Goals given the list of goals Evidence +Goals and Evidence can have variables, sc returns in backtracking all the solutions with their +corresponding probability +*/ +sc(Goals,Evidence,Prob):- + solve_cond(Goals,Evidence,Prob). + +solve_cond(Goals,Evidence,Prob):- + (setof(DerivE,find_deriv(Evidence,DerivE),LDupE)-> + rem_dup_lists(LDupE,[],LE), + (setof(DerivGE,find_deriv_GE(LE,Goals,DerivGE),LDupGE)-> + print_mem, + rem_dup_lists(LDupGE,[],LGE), + build_formula(LE,FormulaE,[],VarE), + var2numbers(VarE,0,NewVarE), + build_formula(LGE,FormulaGE,[],VarGE), + var2numbers(VarGE,0,NewVarGE), + compute_prob(NewVarE,FormulaE,ProbE,0), + call_compute_prob(NewVarGE,FormulaGE,ProbGE), + Prob is ProbGE/ProbE + ; + print_mem, + Prob=0.0 + ) + ; + print_mem, + Prob=undefined + ), + format(user_error,"~nMemory after inference~n",[]), + print_mem. + +sci(Goals,Evidence,ProbL,ProbU,CPUTime):- + statistics(cputime,[_,_]), + setting(depth_bound,D), + append(Goals,Evidence,GE), + solve_condi([(GE,[])],[(Evidence,[])],[],[],D,ProbL,ProbU), + statistics(cputime,[_,CT]), + CPUTime is CT/1000. + +solve_condi(LGoals,LEvidence,SuccGE,SuccE,D,ProbL0,ProbU0):- + findall((GE1,DerivE), + (member((GE,CE),LEvidence),solvei(GE,D,CE,DerivE,GE1)), + LE), + findall((GE1,DerivE), + (member((GE,CE),LGoals),solvei(GE,D,CE,DerivE,GE1)), + LGE), + separate_ulbi(LE,[],LLE0,[],LUE0,[],IncE), + append(SuccE,LUE0,LUE), + compute_prob_deriv(LUE,ProbUE), + (ProbUE\==0.0-> + separate_ulbi(LGE,[],LLGE0,[],LUGE0,[],IncGE), + append(SuccGE,LLGE0,LLGE), + compute_prob_deriv(LLGE,ProbLGE), + ProbL is ProbLGE/ProbUE, + append(SuccE,LLE0,LLE), + compute_prob_deriv(LLE,ProbLE), + (ProbLE\==0.0-> + append(SuccGE,LUGE0,LUGE), + compute_prob_deriv(LUGE,ProbUGE), + ProbU1 is ProbUGE/ProbLE + ; + ProbU1=1.0 + ), + (ProbU1>1.0-> + ProbU=1.0 + ; + ProbU=ProbU1 + ), + Err is ProbU-ProbL, + setting(min_error,ME), + (Err + ProbU0=ProbU, + ProbL0=ProbL + ; + setting(depth_bound,DB), + D1 is D+DB, + solve_condi(IncGE,IncE,LLGE,LLE,D1,ProbL0,ProbU0) + ) + ; + ProbL0=undefined, + ProbU0=undefined + ). + + +scir(Goals,Evidence,ProbL,ProbU,CPUTime):- + statistics(cputime,[_,_]), + setting(depth_bound,D), + solve_condir(Goals,Evidence,D,ProbL,ProbU), + statistics(cputime,[_,CT]), + CPUTime is CT/1000. + +solve_condir(Goals,Evidence,D,ProbL0,ProbU0):- + (call_residue(setof(DerivE,find_derivr(Evidence,D,DerivE),LDupE),_R0)-> + rem_dup_lists(LDupE,[],LE), + append(Evidence,Goals,EG), + (call_residue(setof(DerivGE,find_derivr(EG,D,DerivGE),LDupGE),_R1)-> + rem_dup_lists(LDupGE,[],LGE), + separate_ulb(LGE,[],LLGE,[],LUGE), + compute_prob_deriv(LLGE,ProbLGE), + compute_prob_deriv(LUGE,ProbUGE), + separate_ulb(LE,[],LLE,[],LUE), + compute_prob_deriv(LLE,ProbLE), + compute_prob_deriv(LUE,ProbUE), + ProbL is ProbLGE/ProbUE, + (ProbLE=0.0-> + ProbU1=1.0 + ; + ProbU1 is ProbUGE/ProbLE + ), + (ProbU1>1.0-> + ProbU=1.0 + ; + ProbU=ProbU1 + ), + Err is ProbU-ProbL, + setting(min_error,ME), + (Err + ProbU0=ProbU, + ProbL0=ProbL + ; + setting(depth_bound,DB), + D1 is D+DB, + solve_condir(Goals,Evidence,D1,ProbL0,ProbU0) + ) + ; + ProbL0=0.0, + ProbU0=0.0 + ) + ; + ProbL0=undefined, + ProbU0=undefined + ). + +scic(Goals,Evidence,ProbL,ProbU,CPUTime):- + statistics(cputime,[_,_]), + setting(depth_bound,D), + solve_condic(Goals,Evidence,D,ProbL,ProbU), + statistics(cputime,[_,CT]), + CPUTime is CT/1000. + +solve_condic(Goals,Evidence,D,ProbL0,ProbU0):- + (call_residue(setof((DerivE,P,Pruned),solvec(Evidence,D,[],DerivE,1.0,P,Pruned),LE),_R0)-> + append(Evidence,Goals,EG), + (call_residue(setof((DerivGE,P,Pruned),solvec(EG,D,[],DerivGE,1.0,P,Pruned),LGE),_R1)-> + separate_ulbc(LGE,[],LLGE,0.0,ErrGE), + compute_prob_deriv(LLGE,ProbLGE), + separate_ulbc(LE,[],LLE,0.0,ErrE), + compute_prob_deriv(LLE,ProbLE), + ProbUGE0 is ProbLGE+ErrGE, + (ProbUGE0>1.0-> + ProbUGE=1.0 + ; + ProbUGE=ProbUGE0 + ), + ProbUE0 is ProbLE+ErrE, + (ProbUE0>1.0-> + ProbUE=1.0 + ; + ProbUE=ProbUE0 + ), + ProbL0 is ProbLGE/ProbUE, + (ProbLE=0.0-> + ProbU1=1.0 + ; + ProbU1 is ProbUGE/ProbLE + ), + (ProbU1>1.0-> + ProbU0=1.0 + ; + ProbU0=ProbU1 + ) + ; + ProbL0=0.0, + ProbU0=0.0 + ) + ; + ProbL0=undefined, + ProbU0=undefined + ). + +/* sc(Goals,Evidence,Prob,Time1,Time2) compute the conditional probability of the list of goals +Goals given the list of goals Evidence +Goals and Evidence can have variables, sc returns in backtracking all the solutions with their +corresponding probability +Time1 is the time for performing resolution +Time2 is the time for elaborating the two BDDs +*/ +sc(Goals,Evidence,Prob,CPUTime1,CPUTime2,WallTime1,WallTime2):- + solve_cond(Goals,Evidence,Prob,CPUTime1,CPUTime2,WallTime1,WallTime2). + +solve_cond(Goals,Evidence,Prob,CPUTime1,CPUTime2,WallTime1,WallTime2):- + statistics(cputime,[_,_]), + statistics(walltime,[_,_]), + (setof(DerivE,find_deriv(Evidence,DerivE),LDupE)-> + rem_dup_lists(LDupE,[],LE), + (setof(DerivGE,find_deriv_GE(LE,Goals,DerivGE),LDupGE)-> + rem_dup_lists(LDupGE,[],LGE), + statistics(cputime,[_,CT1]), + CPUTime1 is CT1/1000, + statistics(walltime,[_,WT1]), + WallTime1 is WT1/1000, + build_formula(LE,FormulaE,[],VarE), + var2numbers(VarE,0,NewVarE), + build_formula(LGE,FormulaGE,[],VarGE), + var2numbers(VarGE,0,NewVarGE), + compute_prob(NewVarE,FormulaE,ProbE,0), + call_compute_prob(NewVarGE,FormulaGE,ProbGE), + Prob is ProbGE/ProbE, + statistics(cputime,[_,CT2]), + CPUTime2 is CT2/1000, + statistics(walltime,[_,WT2]), + WallTime2 is WT2/1000 + ; + Prob=0.0, + statistics(cputime,[_,CT1]), + CPUTime1 is CT1/1000, + statistics(walltime,[_,WT1]), + WallTime1 is WT1/1000, + CPUTime2=0.0, + WallTime2=0.0 + ) + ; + Prob=undefined, + statistics(cputime,[_,CT1]), + CPUTime1 is CT1/1000, + statistics(walltime,[_,WT1]), + WallTime1 is WT1/1000, + CPUTime2=0.0, + WallTime2=0.0 + ). + +solve_cond_goals(Goals,LE,0,Time1,0):- + statistics(runtime,[_,_]), + \+ find_deriv_GE(LE,Goals,_DerivGE), + statistics(runtime,[_,T1]), + Time1 is T1/1000. + +call_compute_prob(NewVarGE,FormulaGE,ProbGE):- + (setting(save_dot,true)-> + format("Variables: ~p~n",[NewVarGE]), + compute_prob(NewVarGE,FormulaGE,ProbGE,1) + ; + compute_prob(NewVarGE,FormulaGE,ProbGE,0) + ). + +find_deriv_GE(LD,GoalsList,Deriv):- + member(D,LD), + solve(GoalsList,D,DerivDup), + remove_duplicates(DerivDup,Deriv). + +find_deriv_GE(LD,GoalsList,DB,Deriv):- + member(D,LD), + solve(GoalsList,DB,D,DerivDup), + remove_duplicates(DerivDup,Deriv). + +/* solve(GoalsList,CIn,COut) takes a list of goals and an input C set +and returns an output C set +The C set is a list of triple (N,R,S) where +- N is the index of the head atom used, starting from 0 +- R is the index of the non ground rule used, starting from 1 +- S is the substitution of rule R, in the form of a list whose elements + are of the form 'VarName'=value +*/ +solve([],C,C):-!. + +solve([bagof(V,EV^G,L)|T],CIn,COut):-!, + list2and(GL,G), + bagof((V,C),EV^solve(GL,CIn,C),LD), + length(LD,N), + build_initial_graph(N,GrIn), + build_graph(LD,0,GrIn,Gr), + clique(Gr,Clique), + build_Cset(LD,Clique,L,[],C1), + remove_duplicates_eq(C1,C2), + solve(T,C2,COut). + +solve([bagof(V,G,L)|T],CIn,COut):-!, + list2and(GL,G), + bagof((V,C),solve(GL,CIn,C),LD), + length(LD,N), + build_initial_graph(N,GrIn), + build_graph(LD,0,GrIn,Gr), + clique(Gr,Clique), + build_Cset(LD,Clique,L,[],C1), + remove_duplicates_eq(C1,C2), + solve(T,C2,COut). + + +solve([setof(V,EV^G,L)|T],CIn,COut):-!, + list2and(GL,G), + setof((V,C),EV^solve(GL,CIn,C),LD), + length(LD,N), + build_initial_graph(N,GrIn), + build_graph(LD,0,GrIn,Gr), + clique(Gr,Clique), + build_Cset(LD,Clique,L1,[],C1), + remove_duplicates(L1,L), + solve(T,C1,COut). + +solve([setof(V,G,L)|T],CIn,COut):-!, + list2and(GL,G), + setof((V,C),solve(GL,CIn,C),LD), + length(LD,N), + build_initial_graph(N,GrIn), + build_graph(LD,0,GrIn,Gr), + clique(Gr,Clique), + build_Cset(LD,Clique,L1,[],C1), + remove_duplicates(L1,L), + solve(T,C1,COut). + +solve([\+ H |T],CIn,COut):-!, + list2and(HL,H), + (setof(D,find_deriv(HL,D),LDup)-> + rem_dup_lists(LDup,[],L), + choose_clauses(CIn,L,C1), + solve(T,C1,COut) + ; + solve(T,CIn,COut) + ). + +solve([H|T],CIn,COut):- + builtin(H),!, + call(H), + solve(T,CIn,COut). + +solve([H|T],CIn,COut):- + def_rule(H,B), + append(B,T,NG), + solve(NG,CIn,COut). + +solve([H|T],CIn,COut):- + find_rule(H,(R,S,N),B,CIn), + solve_pres(R,S,N,B,T,CIn,COut). + + +solvei([],_DB,C,C,[]):-!. + +solvei(G,0,C,C,G):-!. + +solvei([\+ H |T],DB,CIn,COut,G):-!, + list2and(HL,H), + (findall((GH,D),solvei(HL,DB,CIn,D,GH),L)-> + separate_ulbi(L,[],LB,[],UB,[],I), + (I\=[]-> + C1=CIn, + G=[\+ H|G1] + ; + choose_clauses(CIn,LB,C1), + G=G1 + ), + solvei(T,DB,C1,COut,G1) + ; + solvei(T,DB,CIn,COut,G1) + ). +solvei([H|T],DB,CIn,COut,G):- + builtin(H),!, + call(H), + solvei(T,DB,CIn,COut,G). + +solvei([H|T],DB,CIn,COut,G):- + def_rule(H,B), + append(B,T,NG), + DB1 is DB-1, + solvei(NG,DB1,CIn,COut,G). + +solvei([H|T],DB,CIn,COut,G):- + find_rule(H,(R,S,N),B,CIn), + DB1 is DB-1, + solve_presi(R,S,N,B,T,DB1,CIn,COut,G). + +solver([],_DB,C,C):-!. + +solver(_G,0,C,[(_,pruned,_)|C]):-!. + +solver([\+ H |T],DB,CIn,COut):-!, + list2and(HL,H), + (setof(D,find_derivr(HL,DB,D),LDup)-> + rem_dup_lists(LDup,[],L), + separate_ulb(L,[],LB,[],UB), + (\+ LB=UB-> + + choose_clauses(CIn,LB,C0), + C1=[(_,pruned,_)|C0] + ; + choose_clauses(CIn,L,C1) + ), + solver(T,DB,C1,COut) + ; + solver(T,DB,CIn,COut) + ). +solver([H|T],DB,CIn,COut):- + builtin(H),!, + call(H), + solver(T,DB,CIn,COut). + +solver([H|T],DB,CIn,COut):- + def_rule(H,B), + append(B,T,NG), + DB1 is DB-1, + solver(NG,DB1,CIn,COut). + +solver([H|T],DB,CIn,COut):- + find_rule(H,(R,S,N),B,CIn), + DB1 is DB-1, + solve_presr(R,S,N,B,T,DB1,CIn,COut). + + +solvec([],_DB,C,C,P,P,false):-!. + +solvec(_G,0,C,C,P,P,true):-!. + +solvec(_G,_DB,C,C,P,P,true):- + setting(prob_threshold,T), + P= + separate_ulbc(L,[],LB,0.0,PP), + (PP=\=0.0-> + + choose_clausesc(CIn,LB,C1,P0,P2), + Pruned=true, + solvec(T,DB,C1,COut,P2,P1,_) + + ; + choose_clausesc(CIn,LB,C1,P0,P2), + solvec(T,DB,C1,COut,P2,P1,Pruned) + ) + ; + solve(T,DB,CIn,COut,P0,P1,Pruned) + ). + +solvec([H|T],DB,CIn,COut,P0,P1,Pruned):- + builtin(H),!, + call(H), + solvec(T,DB,CIn,COut,P0,P1,Pruned). + +solvec([H|T],DB,CIn,COut,P0,P1,Pruned):- + def_rule(H,B), + append(B,T,NG), + DB1 is DB-1, + solvec(NG,DB1,CIn,COut,P0,P1,Pruned). + +solvec([H|T],DB,CIn,COut,P0,P1,Pruned):- + find_rulec(H,(R,S,N),B,CIn,P), + DB1 is DB-1, + solve_presc(R,S,N,B,T,DB1,CIn,COut,P,P0,P1,Pruned). + + + +solve_pres(R,S,N,B,T,CIn,COut):- + member_eq((N,R,S),CIn),!, + append(B,T,NG), + solve(NG,CIn,COut). + +solve_pres(R,S,N,B,T,CIn,COut):- + append(CIn,[(N,R,S)],C1), + append(B,T,NG), + solve(NG,C1,COut). + +solve_presi(R,S,N,B,T,DB,CIn,COut,G):- + member_eq((N,R,S),CIn),!, + append(B,T,NG), + solvei(NG,DB,CIn,COut,G). + +solve_presi(R,S,N,B,T,DB,CIn,COut,G):- + append(CIn,[(N,R,S)],C1), + append(B,T,NG), + solvei(NG,DB,C1,COut,G). + + +solve_presr(R,S,N,B,T,DB,CIn,COut):- + member_eq((N,R,S),CIn),!, + append(B,T,NG), + solver(NG,DB,CIn,COut). + +solve_presr(R,S,N,B,T,DB,CIn,COut):- + append(CIn,[(N,R,S)],C1), + append(B,T,NG), + solver(NG,DB,C1,COut). + + +solve_presc(R,S,N,B,T,DB,CIn,COut,_,P0,P1,Pruned):- + member_eq((N,R,S),CIn),!, + append(B,T,NG), + solvec(NG,DB,CIn,COut,P0,P1,Pruned). + +solve_presc(R,S,N,B,T,DB,CIn,COut,P,P0,P1,Pruned):- + append(CIn,[(N,R,S)],C1), + append(B,T,NG), + P2 is P0*P, + solvec(NG,DB,C1,COut,P2,P1,Pruned). + + +build_initial_graph(N,G):- + listN(0,N,Vert), + add_vertices([],Vert,G). + + +build_graph([],_N,G,G). + +build_graph([(_V,C)|T],N,GIn,GOut):- + N1 is N+1, + compatible(C,T,N,N1,GIn,G1), + build_graph(T,N1,G1,GOut). + +compatible(_C,[],_N,_N1,G,G). + +compatible(C,[(_V,H)|T],N,N1,GIn,GOut):- + (compatible(C,H)-> + add_edges(GIn,[N-N1,N1-N],G1) + ; + G1=GIn + ), + N2 is N1 +1, + compatible(C,T,N,N2,G1,GOut). + +compatible([],_C). + +compatible([(N,R,S)|T],C):- + not_present_with_a_different_head(N,R,S,C), + compatible(T,C). + +not_present_with_a_different_head(_N,_R,_S,[]). + +not_present_with_a_different_head(N,R,S,[(N,R,S)|T]):-!, + not_present_with_a_different_head(N,R,S,T). + +not_present_with_a_different_head(N,R,S,[(_N1,R,S1)|T]):- + S\=S1,!, + not_present_with_a_different_head(N,R,S,T). + +not_present_with_a_different_head(N,R,S,[(_N1,R1,_S1)|T]):- + R\=R1, + not_present_with_a_different_head(N,R,S,T). + + + +build_Cset(_LD,[],[],C,C). + +build_Cset(LD,[H|T],[V|L],CIn,COut):- + nth0(H,LD,(V,C)), + append(C,CIn,C1), + build_Cset(LD,T,L,C1,COut). + + +/* find_rule(G,(R,S,N),Body,C) takes a goal G and the current C set and +returns the index R of a disjunctive rule resolving with G together with +the index N of the resolving head, the substitution S and the Body of the +rule */ +find_rule(H,(R,S,N),Body,C):- + rule(R,S,_,Head,Body), + member_head(H,Head,0,N), + not_already_present_with_a_different_head(N,R,S,C). + +find_rule(H,(R,S,Number),Body,C):- + rule(R,S,_,uniform(H:1/_Num,_P,Number),Body), + not_already_present_with_a_different_head(Number,R,S,C). + +find_rulec(H,(R,S,N),Body,C,P):- + rule(R,S,_,Head,Body), + member_headc(H,Head,0,N,P), + not_already_present_with_a_different_head(N,R,S,C). + + +not_already_present_with_a_different_head(_N,_R,_S,[]). + + +not_already_present_with_a_different_head(N,R,S,[(N1,R,S1)|T]):- + not_different(N,N1,S,S1),!, + not_already_present_with_a_different_head(N,R,S,T). + +not_already_present_with_a_different_head(N,R,S,[(_N1,R1,_S1)|T]):- + R\==R1, + not_already_present_with_a_different_head(N,R,S,T). + + +not_different(_N,_N1,S,S1):- + S\=S1,!. + +not_different(N,N1,S,S1):- + N\=N1,!, + dif(S,S1). + +not_different(N,N,S,S). + + +member_head(H,[(H:_P)|_T],N,N). + +member_head(H,[(_H:_P)|T],NIn,NOut):- + N1 is NIn+1, + member_head(H,T,N1,NOut). + +member_headc(H,[(H:P)|_T],N,N,P). + +member_headc(H,[(_H:_P)|T],NIn,NOut,P):- + N1 is NIn+1, + member_headc(H,T,N1,NOut,P). + + +/* choose_clauses(CIn,LC,COut) takes as input the current C set and +the set of C sets for a negative goal and returns a new C set that +excludes all the derivations for the negative goals */ +choose_clauses(C,[],C). + +choose_clauses(CIn,[D|T],COut):- + member((N,R,S),D), + already_present_with_a_different_head(N,R,S,CIn),!, + choose_a_head(N,R,S,CIn,C1), + choose_clauses(C1,T,COut). + + +choose_clauses(CIn,[D|T],COut):- + member((N,R,S),D), + new_head(N,R,S,N1), + \+ already_present(N1,R,S,CIn), + impose_dif_cons(R,S,CIn), + choose_clauses([(N1,R,S)|CIn],T,COut). + +choose_clausesc(C,[],C,P,P). + +choose_clausesc(CIn,[D|T],COut,P0,P1):- + member((N,R,S),D), + already_present_with_a_different_head(N,R,S,CIn),!, + choose_a_headc(N,R,S,CIn,C1,P0,P2), + choose_clausesc(C1,T,COut,P2,P1). + + +choose_clausesc(CIn,[D|T],COut,P0,P1):- + member((N,R,S),D), + new_head(N,R,S,N1), + \+ already_present(N1,R,S,CIn), + impose_dif_cons(R,S,CIn), + rule(R,S,_Numbers,Head,_Body), + nth0(N1, Head, (_H:P), _Rest), + P2 is P0*P, + choose_clausesc([(N1,R,S)|CIn],T,COut,P2,P1). + + +choose_clauses_DB(C,[],C). + +choose_clauses_DB(CIn,[D|T],COut):- + member((N,R,S),D), + ground((N,R,S)), + already_present_with_a_different_head(N,R,S,CIn),!, + choose_a_head(N,R,S,CIn,C1), + choose_clauses_DB(C1,T,COut). + +choose_clauses_DB(CIn,[D|T],COut):- + member((N,R,S),D), + ground((N,R,S)),!, + new_head(N,R,S,N1), + \+ already_present(N1,R,S,CIn), + impose_dif_cons(R,S,CIn), + choose_clauses_DB([(N1,R,S)|CIn],T,COut). + + +impose_dif_cons(_R,_S,[]):-!. + +impose_dif_cons(R,S,[(_NH,R,SH)|T]):-!, + dif(S,SH), + impose_dif_cons(R,S,T). + +impose_dif_cons(R,S,[_H|T]):- + impose_dif_cons(R,S,T). + +/* instantiation_present_with_the_same_head(N,R,S,C) +takes rule R with substitution S and selected head N and a C set +and asserts dif constraints for all the clauses in C of which RS +is an instantitation and have the same head selected */ +instantiation_present_with_the_same_head(_N,_R,_S,[]). + +instantiation_present_with_the_same_head(N,R,S,[(NH,R,SH)|T]):- + \+ \+ S=SH,!, + dif_head_or_subs(N,R,S,NH,SH,T). + +instantiation_present_with_the_same_head(N,R,S,[_H|T]):- + instantiation_present_with_the_same_head(N,R,S,T). + +dif_head_or_subs(N,R,S,NH,_SH,T):- + dif(N,NH), + instantiation_present_with_the_same_head(N,R,S,T). + +dif_head_or_subs(N,R,S,N,SH,T):- + dif(S,SH), + instantiation_present_with_the_same_head(N,R,S,T). + +/* case 1 of Select: a more general rule is present in C with +a different head, instantiate it */ +choose_a_headc(N,R,S,[(NH,R,SH)|T],[(NH,R,SH)|T],P,P):- + S=SH, + dif(N,NH). + +/* case 2 of Select: a more general rule is present in C with +a different head, ensure that they do not generate the same +ground clause */ +choose_a_headc(N,R,S,[(NH,R,SH)|T],[(NH,R,S),(NH,R,SH)|T],P0,P1):- + \+ \+ S=SH, S\==SH, + dif(N,NH), + dif(S,SH), + rule(R,S,_Numbers,Head,_Body), + nth0(NH, Head, (_H:P), _Rest), + P1 is P0*P. + +choose_a_headc(N,R,S,[H|T],[H|T1],P0,P1):- + choose_a_headc(N,R,S,T,T1,P0,P1). + +/* case 1 of Select: a more general rule is present in C with +a different head, instantiate it */ +choose_a_head(N,R,S,[(NH,R,SH)|T],[(NH,R,SH)|T]):- + S=SH, + dif(N,NH). + +/* case 2 of Select: a more general rule is present in C with +a different head, ensure that they do not generate the same +ground clause */ +choose_a_head(N,R,S,[(NH,R,SH)|T],[(NH,R,S),(NH,R,SH)|T]):- + \+ \+ S=SH, S\==SH, + dif(N,NH), + dif(S,SH). + +choose_a_head(N,R,S,[H|T],[H|T1]):- + choose_a_head(N,R,S,T,T1). + + +/* select a head different from N for rule R with +substitution S, return it in N1 */ +new_head(N,R,S,N1):- + rule(R,S,Numbers,Head,_Body), + Head\=uniform(_,_,_),!, + nth0(N, Numbers, _Elem, Rest), + member(N1,Rest). + +new_head(N,R,S,N1):- + rule(R,S,Numbers,uniform(_A:1/Tot,_L,_Number),_Body), + listN(0,Tot,Numbers), + nth0(N, Numbers, _Elem, Rest), + member(N1,Rest). + +already_present_with_a_different_head(N,R,S,[(NH,R,SH)|_T]):- + \+ \+ S=SH,NH \= N. + +already_present_with_a_different_head(N,R,S,[_H|T]):- + already_present_with_a_different_head(N,R,S,T). + + +/* checks that a rule R with head N and selection S is already +present in C (or a generalization of it is in C) */ +already_present(N,R,S,[(N,R,SH)|_T]):- + S=SH. + +already_present(N,R,S,[_H|T]):- + already_present(N,R,S,T). + +/* rem_dup_lists removes the C sets that are a superset of +another C sets further on in the list of C sets */ +/* rem_dup_lists removes the C sets that are a superset of +another C sets further on in the list of C sets */ +rem_dup_lists([],L,L). + +rem_dup_lists([H|T],L0,L):- + (member_subset(H,T);member_subset(H,L0)),!, + rem_dup_lists(T,L0,L). + +rem_dup_lists([H|T],L0,L):- + rem_dup_lists(T,[H|L0],L). + +member_subset(E,[H|_T]):- + subset_my(H,E),!. + +member_subset(E,[_H|T]):- + member_subset(E,T). + +separate_ulbi([],L,L,U,U,I,I):-!. +/* +separate_ulb([H|T],L0,L1,U0,[H|U1]):- + member(pruned,H),!, + separate_ulb(T,L0,L1,U0,U1). +*/ +separate_ulbi([([],H)|T],L0,[H|L1],U0,[H|U1],I0,I1):- + !, + separate_ulbi(T,L0,L1,U0,U1,I0,I1). + +separate_ulbi([(G,H)|T],L0,L1,U0,[H1|U1],I0,[(G,H)|I1]):- + get_ground(H,H1), + separate_ulbi(T,L0,L1,U0,U1,I0,I1). + + +separate_ulb([],L,L,U,U):-!. +/* +separate_ulb([H|T],L0,L1,U0,[H|U1]):- + member(pruned,H),!, + separate_ulb(T,L0,L1,U0,U1). +*/ +separate_ulb([H|T],L0,[H|L1],U0,[H|U1]):- + ground(H),!, + separate_ulb(T,L0,L1,U0,U1). + +separate_ulb([H|T],L0,L1,U0,[H1|U1]):- + get_ground(H,H1), + separate_ulb(T,L0,L1,U0,U1). + + +separate_ulbc([],L,L,P,P):-!. + +separate_ulbc([(H,P,true)|T],L0,L1,P0,P1):-!, + P2 is P0+P, + separate_ulbc(T,L0,L1,P2,P1). + +separate_ulbc([(H,_P,false)|T],L0,[H|L1],P0,P1):- + separate_ulbc(T,L0,L1,P0,P1). + + +get_ground([],[]):-!. + +get_ground([H|T],[H|T1]):- + ground(H),!, + get_ground(T,T1). + +get_ground([H|T],T1):- + get_ground(T,T1). + + +/* predicates for building the formula to be converted into a BDD */ + +/* build_formula(LC,Formula,VarIn,VarOut) takes as input a set of C sets +LC and a list of Variables VarIn and returns the formula and a new list +of variables VarOut +Formula is of the form [Term1,...,Termn] +Termi is of the form [Factor1,...,Factorm] +Factorj is of the form (Var,Value) where Var is the index of +the multivalued variable Var and Value is the index of the value +*/ +build_formula([],[],Var,Var,C,C). + +build_formula([D|TD],[F|TF],VarIn,VarOut,C0,C1):- + length(D,NC), + C2 is C0+NC, + build_term(D,F,VarIn,Var1), + build_formula(TD,TF,Var1,VarOut,C2,C1). + +build_formula([],[],Var,Var). + +build_formula([D|TD],[F|TF],VarIn,VarOut):- + build_term(D,F,VarIn,Var1), + build_formula(TD,TF,Var1,VarOut). + + +build_term([],[],Var,Var). + +build_term([(_,pruned,_)|TC],TF,VarIn,VarOut):-!, + build_term(TC,TF,VarIn,VarOut). + +build_term([(N,R,S)|TC],[[NVar,N]|TF],VarIn,VarOut):- + (nth0_eq(0,NVar,VarIn,(R,S))-> + Var1=VarIn + ; + append(VarIn,[(R,S)],Var1), + length(VarIn,NVar) + ), + build_term(TC,TF,Var1,VarOut). + +/* nth0_eq(PosIn,PosOut,List,El) takes as input a List, +an element El and an initial position PosIn and returns in PosOut +the position in the List that contains an element exactly equal to El +*/ +nth0_eq(N,N,[H|_T],El):- + H==El,!. + +nth0_eq(NIn,NOut,[_H|T],El):- + N1 is NIn+1, + nth0_eq(N1,NOut,T,El). + +/* var2numbers converts a list of couples (Rule,Substitution) into a list +of triples (N,NumberOfHeadsAtoms,ListOfProbabilities), where N is an integer +starting from 0 */ +var2numbers([],_N,[]). + +var2numbers([(R,S)|T],N,[[N,ValNumber,Probs]|TNV]):- + find_probs(R,S,Probs), + length(Probs,ValNumber), + N1 is N+1, + var2numbers(T,N1,TNV). + +find_probs(R,S,Probs):- + rule(R,S,_N,Head,_Body), + get_probs(Head,Probs). + +get_probs(uniform(_A:1/Num,_P,_Number),ListP):- + Prob is 1/Num, + list_el(Num,Prob,ListP). + +get_probs([],[]). + +get_probs([_H:P|T],[P1|T1]):- + P1 is P, + get_probs(T,T1). + +list_el(0,_P,[]):-!. + +list_el(N,P,[P|T]):- + N1 is N-1, + list_el(N1,P,T). + +/* end of predicates for building the formula to be converted into a BDD */list_el(0,_P,[]):-!. + + +/* start of predicates for parsing an input file containing a program */ + +/* p(File) parses the file File.cpl. It can be called more than once without +exiting yap */ +p(File):- + parse(File). + +parse(File):- + atom_concat(File,'.cpl',FilePl), + open(FilePl,read,S), + read_clauses(S,C), + close(S), + retractall(rule(_,_,_,_,_)), + retractall(def_rule(_,_)), + process_clauses(C,1). + +process_clauses([(end_of_file,[])],_N). + +process_clauses([((H:-B),V)|T],N):- + H=uniform(A,P,L),!, + list2and(BL,B), + process_body(BL,V,V1), + remove_vars([P],V1,V2), + append(BL,[length(L,Tot),nth0(Number,L,P)],BL1), + append(V2,['Tot'=Tot],V3), + assertz(rule(N,V3,_NH,uniform(A:1/Tot,L,Number),BL1)), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([((H:-B),V)|T],N):- + H=(_;_),!, + list2or(HL1,H), + process_head(HL1,HL), + list2and(BL,B), + process_body(BL,V,V1), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V1,NH,HL,BL)), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([((H:-B),V)|T],N):- + H=(_:_),!, + list2or(HL1,H), + process_head(HL1,HL), + list2and(BL,B), + process_body(BL,V,V1), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V1,NH,HL,BL)), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([((H:-B),_V)|T],N):-!, + list2and(BL,B), + assert(def_rule(H,BL)), + process_clauses(T,N). + +process_clauses([(H,V)|T],N):- + H=(_;_),!, + list2or(HL1,H), + process_head(HL1,HL), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V,NH,HL,[])), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([(H,V)|T],N):- + H=(_:_),!, + list2or(HL1,H), + process_head(HL1,HL), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V,NH,HL,[])), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([(H,_V)|T],N):- + assert(def_rule(H,[])), + process_clauses(T,N). + +/* if the annotation in the head are not ground, the null atom is not added +and the eventual formulas are not evaluated */ + +process_head(HL,NHL):- + (ground_prob(HL)-> + process_head_ground(HL,0,NHL) + ; + NHL=HL + ). + +ground_prob([]). + +ground_prob([_H:PH|T]):- + ground(PH), + ground_prob(T). + +process_head_ground([H:PH],P,[H:PH1|Null]):- + PH1 is PH, + PNull is 1-P-PH1, + setting(epsilon_parsing,Eps), + EpsNeg is - Eps, + PNull > EpsNeg, + (PNull>Eps-> + Null=['':PNull] + ; + Null=[] + ). + +process_head_ground([H:PH|T],P,[H:PH1|NT]):- + PH1 is PH, + P1 is P+PH1, + process_head_ground(T,P1,NT). + +/* setof must have a goal of the form B^G where B is a term containing the existential variables */ +process_body([],V,V). + +process_body([setof(A,B^_G,_L)|T],VIn,VOut):-!, + get_var(A,VA), + get_var(B,VB), + remove_vars(VA,VIn,V1), + remove_vars(VB,V1,V2), + process_body(T,V2,VOut). + +process_body([setof(A,_G,_L)|T],VIn,VOut):-!, + get_var(A,VA), + remove_vars(VA,VIn,V1), + process_body(T,V1,VOut). + +process_body([bagof(A,B^_G,_L)|T],VIn,VOut):-!, + get_var(A,VA), + get_var(B,VB), + remove_vars(VA,VIn,V1), + remove_vars(VB,V1,V2), + process_body(T,V2,VOut). + +process_body([bagof(A,_G,_L)|T],VIn,VOut):-!, + get_var(A,VA), + remove_vars(VA,VIn,V1), + process_body(T,V1,VOut). + +process_body([_H|T],VIn,VOut):-!, + process_body(T,VIn,VOut). + +get_var_list([],[]). + +get_var_list([H|T],[H|T1]):- + var(H),!, + get_var_list(T,T1). + +get_var_list([H|T],VarOut):-!, + get_var(H,Var), + append(Var,T1,VarOut), + get_var_list(T,T1). + +get_var(A,[A]):- + var(A),!. + +get_var(A,V):- + A=..[_F|Args], + get_var_list(Args,V). + +remove_vars([],V,V). + +remove_vars([H|T],VIn,VOut):- + delete_var(H,VIn,V1), + remove_vars(T,V1,VOut). + +delete_var(_H,[],[]). + +delete_var(V,[VN=Var|T],[VN=Var|T1]):- + V\==Var,!, + delete_var(V,T,T1). + +delete_var(_V,[_H|T],T). + +/* predicates for reading in the program clauses */ +read_clauses(S,Clauses):- + (setting(ground_body,true)-> + read_clauses_ground_body(S,Clauses) + ; + read_clauses_exist_body(S,Clauses) + ). + + +read_clauses_ground_body(S,[(Cl,V)|Out]):- + read_term(S,Cl,[variable_names(V)]), + (Cl=end_of_file-> + Out=[] + ; + read_clauses_ground_body(S,Out) + ). + + +read_clauses_exist_body(S,[(Cl,V)|Out]):- + read_term(S,Cl,[variable_names(VN)]), + extract_vars_cl(Cl,VN,V), + (Cl=end_of_file-> + Out=[] + ; + read_clauses_exist_body(S,Out) + ). + + +extract_vars_cl(end_of_file,[]). + +extract_vars_cl(Cl,VN,Couples):- + (Cl=(H:-_B)-> + true + ; + H=Cl + ), + extract_vars(H,[],V), + pair(VN,V,Couples). + + +pair(_VN,[],[]). + +pair([VN= _V|TVN],[V|TV],[VN=V|T]):- + pair(TVN,TV,T). + + +extract_vars(Var,V0,V):- + var(Var),!, + (member_eq(Var,V0)-> + V=V0 + ; + append(V0,[Var],V) + ). + +extract_vars(Term,V0,V):- + Term=..[_F|Args], + extract_vars_list(Args,V0,V). + + +extract_vars_list([],V,V). + +extract_vars_list([Term|T],V0,V):- + extract_vars(Term,V0,V1), + extract_vars_list(T,V1,V). + + +listN(N,N,[]):-!. + +listN(NIn,N,[NIn|T]):- + N1 is NIn+1, + listN(N1,N,T). +/* end of predicates for parsing an input file containing a program */ + +/* start of utility predicates */ +list2or([X],X):- + X\=;(_,_),!. + +list2or([H|T],(H ; Ta)):-!, + list2or(T,Ta). + +list2and([X],X):- + X\=(_,_),!. + +list2and([H|T],(H,Ta)):-!, + list2and(T,Ta). + +member_eq(A,[H|_T]):- + A==H,!. + +member_eq(A,[_H|T]):- + member_eq(A,T). + +subset_my([],_). + +subset_my([H|T],L):- + member_eq(H,L), + subset_my(T,L). + +remove_duplicates_eq([],[]). + +remove_duplicates_eq([H|T],T1):- + member_eq(H,T),!, + remove_duplicates_eq(T,T1). + +remove_duplicates_eq([H|T],[H|T1]):- + remove_duplicates_eq(T,T1). + +builtin(_A is _B). +builtin(_A > _B). +builtin(_A < _B). +builtin(_A >= _B). +builtin(_A =< _B). +builtin(_A =:= _B). +builtin(_A =\= _B). +builtin(true). +builtin(false). +builtin(_A = _B). +builtin(_A==_B). +builtin(_A\=_B). +builtin(_A\==_B). +builtin(length(_L,_N)). +builtin(member(_El,_L)). +builtin(average(_L,_Av)). +builtin(max_list(_L,_Max)). +builtin(min_list(_L,_Max)). +builtin(nth0(_,_,_)). +builtin(nth(_,_,_)). +average(L,Av):- + sum_list(L,Sum), + length(L,N), + Av is Sum/N. + +clique(Graph,Clique):- + vertices(Graph,Candidates), + extend_cycle(Graph,Candidates,[],[],Clique). + +extend_cycle(G,[H|T],Not,CS,CSOut):- + neighbours(H, G, Neigh), + intersection(Neigh,T,NewCand), + intersection(Neigh,Not,NewNot), + extend(G,NewCand,NewNot,[H|CS],CSOut). + +extend_cycle(G,[H|T],Not,CS,CSOut):- + extend_cycle(G,T,[H|Not],CS,CSOut). + +extend(_G,[],[],CompSub,CompSub):-!. + +extend(G,Cand,Not,CS,CSOut):- + extend_cycle(G,Cand,Not,CS,CSOut). + +intersection([],_Y,[]). + +intersection([H|T],Y,[H|Z]):- + member(H,Y),!, + intersection(T,Y,Z). + +intersection([_H|T],Y,Z):- + intersection(T,Y,Z). + +/* set(Par,Value) can be used to set the value of a parameter */ +set(Parameter,Value):- + retract(setting(Parameter,_)), + assert(setting(Parameter,Value)). + +/* end of utility predicates */ diff --git a/packages/cplint/lpadvel.pl b/packages/cplint/lpadvel.pl new file mode 100644 index 000000000..acde32d54 --- /dev/null +++ b/packages/cplint/lpadvel.pl @@ -0,0 +1,1538 @@ +/* + LPAD and CP-Logic reasoning suite + File lpadclpbn.pl + Goal oriented interpreter for LPADs based on SLDNF + Copyright (c) 2008, Fabrizio Riguzzi + Inference is performed translating the portion of the LPAD related to the goal + into CLP(BN) +*/ + +:- set_prolog_flag(unknown,error). +:- set_prolog_flag(profiling,on). +:- set_prolog_flag(debug,on). +:- set_prolog_flag(discontiguous_warnings,on). +:- set_prolog_flag(single_var_warnings,on). +:-source. +%:- module(lpadclpbn, [p/1, +% s/2,sc/3,s/6,sc/7,set/2,setting/2]). + + +:-dynamic rule/5,def_rule/2,setting/2. + +:-use_module(library(lists)). +:-use_module(library(undgraphs)). +:-use_module(library(dgraphs)). +:-use_module(library(avl)). + +:-use_module(library(matrix)). + + +/* start of list of parameters that can be set by the user with +set(Parameter,Value) */ +setting(epsilon_parsing,0.00001). +setting(save_dot,false). +setting(ground_body,true). +/* available values: true, false +if true, both the head and the body of each clause will be grounded, otherwise +only the head is grounded. In the case in which the body contains variables +not appearing in the head, the body represents an existential event */ + +setting(cpt_zero,0.0001). + +%setting(order,top_sort). +setting(order,min_def). +%setting(order,max_card). + +/* end of list of parameters */ + +/* s(GoalsList,Prob) compute the probability of a list of goals +GoalsLis can have variables, s returns in backtracking all the solutions with +their corresponding probability */ +s(GL,P):- + get_ground_portion(GL,CL),!, + convert_to_bn(CL,GL,[],P). + +s(_GL,0.0). +/* sc(GoalsList,EvidenceList,Prob) compute the probability of a list of goals +GoalsList given EvidenceList. Both lists can have variables, sc returns in +backtracking all the solutions with their corresponding probability +Time1 is the time for performing resolution +Time2 is the time for performing bayesian inference */ + +sc(GL,GL,1.0). + +sc(GL,GLC,P):- + get_ground_portion(GL,GLC,CL,Undef),!, + (Undef=yes-> + P=undef + ; + convert_to_bn(CL,GL,GLC,P) + ). + +sc(_GL,_GLC,0.0). + +get_ground_portion(GL,CL):- + setof(Deriv,find_deriv(GL,Deriv),LDup), + append_all(LDup,[],L), + remove_head(L,LD), + remove_duplicates(LD,LD1), + build_ground_lpad(LD1,0,CL). + +get_ground_portion(GL,GLC,CL,Undef):- + setof(Deriv,find_deriv(GL,Deriv),LDup), + (setof(Deriv,find_deriv(GLC,Deriv),LDupC)-> + append_all(LDup,[],L), + remove_head(L,L1), + append_all(LDupC,[],LC), + remove_head(LC,LC1), + append(L1,LC1,LD), + remove_duplicates(LD,LD1), + build_ground_lpad(LD1,0,CL), + Undef=no + ; + Undef=yes + ). + + +/* s(GoalsList,Prob,Time1,Time2) compute the probability of a list of goals +GoalsLis can have variables, s returns in backtracking all the solutions with +their corresponding probability +Time1 is the time for performing resolution +Time2 is the time for performing bayesian inference */ +s(GL,P,CPUTime1,CPUTime2,WallTime1,WallTime2):- + statistics(cputime,[_,_]), + statistics(walltime,[_,_]), + (get_ground_portion(GL,CL)-> + statistics(cputime,[_,CT1]), + CPUTime1 is CT1/1000, + statistics(walltime,[_,WT1]), + WallTime1 is WT1/1000, + print_mem, + convert_to_bn(CL,GL,[],P), + statistics(cputime,[_,CT2]), + CPUTime2 is CT2/1000, + statistics(walltime,[_,WT2]), + WallTime2 is WT2/1000 + + ; + statistics(cputime,[_,CT1]), + CPUTime1 is CT1/1000, + statistics(walltime,[_,WT1]), + WallTime1 is WT1/1000, + print_mem, + CPUTime2=0.0, + WallTime2=0.0, + P=0.0 + ), + format(user_error,"~nMemory after inference~n",[]), + print_mem. + +print_mem:- + statistics(global_stack,[GS,GSF]), + statistics(local_stack,[LS,LSF]), + statistics(heap,[HP,HPF]), + statistics(trail,[TU,TF]), + format(user_error,"~nGloabal stack used ~d execution stack free: ~d~n",[GS,GSF]), + format(user_error,"Local stack used ~d execution stack free: ~d~n",[LS,LSF]), + format(user_error,"Heap used ~d heap free: ~d~n",[HP,HPF]), + format(user_error,"Trail used ~d Trail free: ~d~n",[TU,TF]). + + +/* sc(GoalsList,EvidenceList,Prob) compute the probability of a list of goals +GoalsList given EvidenceList. Both lists can have variables, sc returns in +backtracking all the solutions with their corresponding probability */ + +sc(GL,GL,1.0,0.0,0.0,0.0,0.0). + +sc(GL,GLC,P,CPUTime1,CPUTime2,WallTime1,WallTime2):- + statistics(cputime,[_,_]), + statistics(walltime,[_,_]), + (get_ground_portion(GL,GLC,CL,Undef)-> + statistics(cputime,[_,CT1]), + CPUTime1 is CT1/1000, + statistics(walltime,[_,WT1]), + WallTime1 is WT1/1000, + print_mem, + (Undef=yes-> + P=undef, + CPUTime2=0.0, + WallTime2=0.0 + ; + convert_to_bn(CL,GL,GLC,P), + statistics(cputime,[_,CT2]), + CPUTime2 is CT2/1000, + statistics(walltime,[_,WT2]), + WallTime2 is WT2/1000 + ) + ; + print_mem, + statistics(cputime,[_,CT1]), + CPUTime1 is CT1/1000, + statistics(walltime,[_,WT1]), + WallTime1 is WT1/1000, + CPUTime2=0.0, + WallTime2=0.0, + P=0.0 + ), + format(user_error,"~nMemory after inference~n",[]), + print_mem. + +remove_head([],[]). + +remove_head([(_N,R,S)|T],[(R,S)|T1]):- + remove_head(T,T1). + +append_all([],L,L):-!. + +append_all([LIntH|IntT],IntIn,IntOut):- + append(IntIn,LIntH,Int1), + append_all(IntT,Int1,IntOut). + +process_goals([],[],[]). + +process_goals([H|T],[HG|TG],[HV|TV]):- + H=..[F,HV|Rest], + HG=..[F|Rest], + process_goals(T,TG,TV). + +build_ground_lpad([],_N,[]). + +build_ground_lpad([(R,S)|T],N,[(N1,Head1,Body1)|T1]):- + rule(R,S,_,Head,Body), + N1 is N+1, + merge_identical(Head,Head1), + remove_built_ins(Body,Body1), + build_ground_lpad(T,N1,T1). + +remove_built_ins([],[]):-!. + +remove_built_ins([\+H|T],T1):- + builtin(H),!, + remove_built_ins(T,T1). + +remove_built_ins([H|T],T1):- + builtin(H),!, + remove_built_ins(T,T1). + +remove_built_ins([H|T],[H|T1]):- + remove_built_ins(T,T1). + +merge_identical([],[]):-!. + +merge_identical([A:P|T],[A:P1|Head]):- + find_identical(A,P,T,P1,T1), + merge_identical(T1,Head). + +find_identical(_A,P,[],P,[]):-!. + +find_identical(A,P0,[A:P|T],P1,T1):-!, + P2 is P0+P, + find_identical(A,P2,T,P1,T1). + +find_identical(A,P0,[H:P|T],P1,[H:P|T1]):- + find_identical(A,P0,T,P1,T1). + +convert_to_bn(CL,GL,GLC,P):- + find_ground_atoms(CL,[],GADup), + remove_duplicates(GADup,GANull), + delete(GANull,'',GA), + undgraph_new(Graph0), + rule_factors(CL,[],HetF,HomFR,Graph0,Graph1), + identity_facotrs(GA,_GAD,IF,Graph1,Graph2), + setting(order,Order)-> + (Order=top_sort-> + dgraph_top_sort(Graph2,SortedAtoms) + ; + dgraph_to_undgraph(Graph2,Graph3), + undgraph_vertices(Graph3,SortedAtoms0), + (Order=max_card-> + max_card_order(SortedAtoms0,[],SortedAtoms,Graph3) + ; + SortedAtoms=SortedAtoms0 + ) + ), + find_atoms_body(GL,QAtoms), + append(HomFR,IF,HomF), + vel(HomF,HetF,QAtoms,GLC,Graph3,SortedAtoms,OutptutTable), + get_prob_goal(GL,QAtoms,SortedAtoms,OutptutTable,P). + + +max_card_order([],SortedAtoms,SortedAtoms,_Graph):-!. + +max_card_order(Atoms,SortedAtoms0,SortedAtoms1,Graph):- + find_max_card(Atoms,SortedAtoms0,Graph,null,-1,At), + delete(Atoms,At,Atoms1), + max_card_order(Atoms1,[At|SortedAtoms0],SortedAtoms1,Graph). + +find_max_card([],_SortedAtoms,_Graph,At,_MaxCard,At):-!. + +find_max_card([HVar|T],SortedAtoms,Graph,MaxAt0,MaxCard0,MaxAt1):- + ( + (HVar \= d(_At);HVar=ch(_N)) + ; + HVar = d(Var), + member(Var,SortedAtoms) + ),!, + find_card(SortedAtoms,Graph,HVar,0,Card), + (Card>MaxCard0-> + MaxCard2=Card, + MaxAt2=HVar + ; + MaxCard2=MaxCard0, + MaxAt2=MaxAt0 + ), + find_max_card(T,SortedAtoms,Graph,MaxAt2,MaxCard2,MaxAt1). + +find_max_card([_HVar|T],SortedAtoms,Graph,MaxAt0,MaxCard0,MaxAt1):- + find_max_card(T,SortedAtoms,Graph,MaxAt0,MaxCard0,MaxAt1). + +find_card([],_Graph,_At,Card,Card):-!. + +find_card([H|T],Graph,At,Card0,Card1):- + (undgraph_edge(H,At,Graph)-> + Card2 is Card0+1 + ; + Card2 = Card0 + ), + find_card(T,Graph,At,Card2,Card1). + + +compute_min_def([],_Eliminated,Graph0,Graph1,MinVar,MinVar,_MinDef0):- + undgraph_del_vertices(Graph0,[MinVar],Graph1). + +compute_min_def([HVar|TVars],Eliminated,Graph0,Graph1,MinVar0,MinVar1,MinDef0):- + ( + (HVar=d(_At);HVar=ch(_N)) + ; + member(d(HVar),Eliminated) + ),!, + compute_def(HVar,Graph0,Def), + (Def + MinDef2=Def, + MinVar2=HVar + ; + MinDef2=MinDef0, + MinVar2=MinVar0 + ), + compute_min_def(TVars,Eliminated,Graph0,Graph1,MinVar2,MinVar1,MinDef2). + +compute_min_def([_HVar|TVars],Eliminated,Graph0,Graph1,MinVar0,MinVar1,MinDef0):- + compute_min_def(TVars,Eliminated,Graph0,Graph1,MinVar0,MinVar1,MinDef0). + + +compute_def(Node,UndGraph,Def):- + undgraph_neighbors(Node,UndGraph,AdjNodes), + undgraph_new(SecGraph0), + section_graph([Node|AdjNodes],UndGraph,SecGraph0,SecGraph1), + undgraph_complement(SecGraph1,SecGraphC), + undgraph_edges(SecGraphC, Edges), + length(Edges,Def). + + +section_graph([],_Graph,SG,SG):-!. + +section_graph([H|T],Graph,SecGraph0,SecGraph1):-!, + undgraph_neighbors(H,Graph,Neig), + new_edges(Neig,H,Edges), + undgraph_add_edges(SecGraph0,Edges,SecGraph2), + section_graph(T,Graph,SecGraph2,SecGraph1). + +new_edges([],_V,[]):-!. + +new_edges([H|T],V,[V-H|TE]):- + new_edges(T,V,TE). + +get_prob_goal(GL,QAtoms,SortedAtoms,f(M,_D,_S),P):- + positions(QAtoms,SortedAtoms,VarsPos), + keysort(VarsPos,Vars1Pos), + split_map(Vars1Pos,Vars1), + get_index(Vars1,GL,Index), + matrix_get(M,Index,P). + +get_index([],_GL,[]):-!. + +get_index([H|Vars1],GL,[1|Index]):- + member(H,GL),!, + get_index(Vars1,GL,Index). + +get_index([H|Vars1],GL,[0|Index]):- + member(\+H,GL), + get_index(Vars1,GL,Index). + + +vel(IF,RF,QAtoms,GLC,Graph,SortedAtoms,OutptutTable):- + fix_evidence(RF,RF1,GLC), + fix_evidence(IF,IF1,GLC), + sort_tables(RF1,RF2,SortedAtoms), + sort_tables(IF1,IF2,SortedAtoms), + find_atoms_body(GLC,AtomsC), + delete_all(QAtoms,SortedAtoms,SortedAtoms1), + delete_all(AtomsC,SortedAtoms1,SortedAtoms2), + vel_cycle(SortedAtoms2,IF2,RF2,Graph,SortedAtoms,[],_Eliminated,OutptutTable). + + +fix_evidence([],[],_Ev):-!. + +fix_evidence([f(Tab,Dep,Sz)|T],[f(Tab1,Dep1,Sz1)|T1],Ev):- + simplify_evidence(Ev,Tab,Dep,Sz,Tab1,Dep1,Sz1), + fix_evidence(T,T1,Ev). + + +simplify_evidence([], Table, Deps, Sizes, Table, Deps, Sizes). +simplify_evidence([V|VDeps], Table0, Deps0, Sizes0, Table, Deps, Sizes) :-!, + project_from_CPT(V,tab(Table0,Deps0,Sizes0),tab(Table1,Deps1,Sizes1)), + simplify_evidence(VDeps, Table1, Deps1, Sizes1, Table, Deps, Sizes). + + + + +project_from_CPT(\+H,tab(Table,Deps,_),tab(NewTable,NDeps,NSzs)) :- + nth0(N,Deps, H),!, + matrix_select(Table, N, 0, NewTable), + matrix_dims(NewTable, NSzs), + delete(Deps,H,NDeps). +project_from_CPT(H,tab(Table,Deps,_),tab(NewTable,NDeps,NSzs)) :- + nth0(N,Deps, H),!, + matrix_select(Table, N, 1, NewTable), + matrix_dims(NewTable, NSzs), + delete(Deps,H,NDeps). +project_from_CPT(_H,tab(Table,Deps,S),tab(Table,Deps,S)). + + + +sort_tables([],[],_SortedAtoms):-!. + +sort_tables([f(Mat,Vars,_Sz)|T],[f(Mat1,Vars1,Sz1)|T1],SortedAtoms):- + reorder_CPT(Vars,SortedAtoms,Vars1,Map), + matrix_shuffle(Mat,Map,Mat1), + matrix_dims(Mat1,Sz1), + sort_tables(T,T1,SortedAtoms). + + +delete_all([],L,L):-!. + +delete_all([H|T],L0,L1):- + delete(L0,H,L2), + delete_all(T,L2,L1). + +mapping(Vs0,Vs,Map) :- + add_indices(Vs0,0,I1s), + add_indices( Vs,I2s), + keysort(I1s,Ks), + keysort(I2s,Ks), + split_map(I2s, Map). + +add_indices([],[]). +add_indices([V|Vs0],[V-_|I1s]) :- + add_indices(Vs0,I1s). + +split_map([], []). +split_map([_-M|Is], [M|Map]) :- + split_map(Is, Map). + +split_pos([], []). +split_pos([V-_|Is], [V|Map]) :- + split_pos(Is, Map). + +positions([],_SA,[]):-!. + +positions([HV|Vars],SortedAtoms,[Pos-HV|VarsPos]):- + nth(Pos,SortedAtoms,HV),!, + positions(Vars,SortedAtoms,VarsPos). + + +reorder_CPT(Vars,SortedAtoms,Vars1,Map):- + positions(Vars,SortedAtoms,VarsPos), + keysort(VarsPos,Vars1Pos), + split_map(Vars1Pos,Vars1), + mapping(Vars,Vars1,Map). + +add_indices([],_,[]). +add_indices([V|Vs0],I0,[V-I0|Is]) :- + I is I0+1, + add_indices(Vs0,I,Is). + +vel_cycle([],HomFact,HetFact,_Graph,SortedAtoms,Eliminated,Eliminated,f(Mat1,Dep,Sz)):-!, + combine_factors(HomFact,HetFact,SortedAtoms,f(Mat,Dep,Sz)), + normalise_CPT(Mat,Mat1). + +vel_cycle(Vars0,HomFact,HetFact,Graph0,SortedAtoms,Eliminated0,Eliminated1,OutputTable):- + (setting(order,min_def)-> + compute_min_def(Vars0,Eliminated0,Graph0,Graph1,null,MinVar,+inf), + delete(Vars0,MinVar,Vars1) + ; + Vars0=[MinVar|Vars1] + ), + sum_out1(MinVar,HomFact,HetFact,HomFact1,HetFact1,SortedAtoms), + append(Eliminated0,[MinVar],Eliminated2), + vel_cycle(Vars1,HomFact1,HetFact1,Graph1,SortedAtoms,Eliminated2,Eliminated1,OutputTable). + +normalise_CPT(MAT,NMAT) :- + matrix_sum(MAT, Sum), + matrix_op_to_all(MAT,/,Sum,NMAT). + +combine_factors(HomFacts,HetFacts,SortedAtoms,Fact):- + combine_tables(HetFacts,HetFact,SortedAtoms), + multiply_tables([HetFact|HomFacts],Fact,SortedAtoms). + + +sum_out1(Var,Hom,Het,Hom2,Het2,SortedAtoms):- + get_factors_with_var(Hom,Var,HomFacts,Hom1), + multiply_tables(HomFacts,HomFact,SortedAtoms), + get_factors_with_var(Het,Var,HetFacts,Het1), + combine_tables(HetFacts,HetFact,SortedAtoms), + update_factors(Var,HomFact,HetFact,Hom1,Hom2,Het1,Het2,SortedAtoms). + +update_factors(_Var,[],[],Hom,Hom,Het,Het,_SortedAtoms):-!. + +update_factors(Var,HomFact,[],Hom,[Fact|Hom],Het,Het,_SortedAtoms):-!, + sum_var(Var,HomFact,Fact). + +update_factors(Var,[],HetFact,Hom,Hom,Het,[Fact|Het],_SortedAtoms):- + sum_var(Var,HetFact,Fact). + +update_factors(Var,HomFact,HetFact,Hom,Hom,Het,[Fact1|Het],SortedAtoms):- + multiply_CPTs(HomFact,HetFact,Fact,SortedAtoms), + sum_var(Var,Fact,Fact1). + +sum_var(Var,f(Table,Deps,_),f(NewTable,NDeps,NSzs)):- + nth0(N,Deps, Var),!, + delete(Deps,Var,NDeps), + matrix_sum_out(Table, N, NewTable), + matrix_dims(NewTable, NSzs). + +combine_tables([],[],_SortedAtoms):-!. + +combine_tables([Fact],Fact,_SortedAtoms):-!. + +combine_tables([Fact1,Fact2|T],Fact,SortedAtoms):- + combine_CPTs(Fact1,Fact2,Fact0,SortedAtoms), + combine_tables([Fact0|T],Fact,SortedAtoms). + +get_factors_with_var([],_V,[],[]):-!. + +get_factors_with_var([f(Table,Vars,Sz)|T],Var,[f(Table,Vars,Sz)|TFV],TRest):- + member(Var,Vars),!, + get_factors_with_var(T,Var,TFV,TRest). + +get_factors_with_var([f(Table,Vars,Sz)|T],Var,TFV,[f(Table,Vars,Sz)|TRest]):- + get_factors_with_var(T,Var,TFV,TRest). + +multiply_tables([], [],_SorteAtoms) :- !. + +multiply_tables([Table], Table,_SorteAtoms) :- !. +multiply_tables([TAB1, TAB2| Tables], Out,SorteAtoms) :- + multiply_CPTs(TAB1, TAB2, TAB,SorteAtoms), + multiply_tables([TAB| Tables], Out,SorteAtoms). + +combine_CPTs(f(Tab1, Deps1, Sz1), f(Tab2, Deps2, Sz2), F, SortedAtoms) :- + get_common_conv(Deps1,Deps2,CommConv), + rename_convergent(1,CommConv,Deps1,Deps11,[],NewAt0), + rename_convergent(2,CommConv,Deps2,Deps21,NewAt0,NewAt1), + update_sorted(SortedAtoms,NewAt1,SortedAtoms1), + expand_tabs(Deps11, Sz1, Deps21, Sz2, Map1, Map2, NDeps0,SortedAtoms1), + matrix_expand(Tab1, Map1, NTab1), + matrix_expand(Tab2, Map2, NTab2), + matrix_op(NTab1,NTab2,*,OT0), + matrix_dims(OT0,NSz0), + sum_fact(CommConv,OT0,NDeps0,NSz0,OT,NDeps,NSz), + sort_tables([f(OT, NDeps, NSz)],[F],SortedAtoms). + +get_common_conv(Deps1,Deps2,CommConv):- + get_conv(Deps1,C1), + get_conv(Deps2,C2), + intersection(C1,C2,CommConv). + +get_conv([],[]):-!. + +get_conv([d(H)|T],[H|T1]):-!, + get_conv(T,T1). + +get_conv([_H|T],T1):-!, + get_conv(T,T1). + + +sum_fact([],T,D,S,T,D,S):-!. + +% remove_renamed_conv(D0,D1). + +sum_fact([H|T],T0,D0,S0,T1,D1,S1):- + simplify_evidence([\+d(H,1),\+d(H,2)],T0,D0,S0,Tff,D,S), + simplify_evidence([\+d(H,1),d(H,2)],T0,D0,S0,Tft,D,S), + simplify_evidence([d(H,1),\+d(H,2)],T0,D0,S0,Ttf,D,S), + simplify_evidence([d(H,1),d(H,2)],T0,D0,S0,Ttt,D,S), + matrix_op(Tft,Ttf,+,T2), + matrix_op(T2,Ttt,+,T3), + matrix_to_list(T3,Lt), + matrix_to_list(Tff,Lf), + append(Lf,Lt,L), + matrix_new(floats, [2|S], L,T4), + sum_fact(T,T4,[d(H)|D],[2|S],T1,D1,S1). + +remove_renamed_conv([],[]):-!. + +remove_renamed_conv([d(H,_N)|D0],[d(H)|D1]):-!, + remove_renamed_conv(D0,D1). + +remove_renamed_conv([H|D0],[H|D1]):- + remove_renamed_conv(D0,D1). + + + +update_sorted([],_NewAt,[]):-!. + +update_sorted([d(H)|T],NewAt,[d(H,1)|T1]):- + member(d(H,1),NewAt),!, + update_sorted1(H,T,NewAt,T1). + +update_sorted([d(H)|T],NewAt,[d(H,2)|T1]):- + member(d(H,2),NewAt),!, + update_sorted(T,NewAt,T1). + +update_sorted([H|T],NewAt,[H|T1]):- + update_sorted(T,NewAt,T1). + +update_sorted1(H,T,NewAt,[d(H,2)|T1]):- + member(d(H,2),NewAt),!, + update_sorted(T,NewAt,T1). + +update_sorted1(_H,T,NewAt,T1):- + update_sorted(T,NewAt,T1). + +rename_convergent(_N,_CommConv,[],[],NA,NA):-!. + +rename_convergent(N,CommConv,[d(H)|T],[d(H,N)|T1],NA0,[d(H,N)|NA1]):- + member(H,CommConv),!, + rename_convergent(N,CommConv,T,T1,NA0,NA1). + +rename_convergent(N,CommConv,[H|T],[H|T1],NA0,NA1):- + rename_convergent(N,CommConv,T,T1,NA0,NA1). + + +multiply_CPTs(f(Tab1, Deps1, Sz1), f(Tab2, Deps2, Sz2), f(OT, NDeps, NSz), SortedAtoms) :- + expand_tabs(Deps1, Sz1, Deps2, Sz2, Map1, Map2, NDeps,SortedAtoms), + matrix_expand(Tab1, Map1, NTab1), + matrix_expand(Tab2, Map2, NTab2), + matrix_op(NTab1,NTab2,*,OT), + matrix_dims(OT,NSz). + +expand_tabs([], [], [], [], [], [], [],_SortedAtoms):-!. +expand_tabs([V1|Deps1], [S1|Sz1], [], [], [0|Map1], [S1|Map2], [V1|NDeps],SortedAtoms) :-!, + expand_tabs(Deps1, Sz1, [], [], Map1, Map2, NDeps,SortedAtoms). +expand_tabs([], [], [V2|Deps2], [S2|Sz2], [S2|Map1], [0|Map2], [V2|NDeps],SortedAtoms) :-!, + expand_tabs([], [], Deps2, Sz2, Map1, Map2, NDeps,SortedAtoms). +expand_tabs([V1|Deps1], [S1|Sz1], [V2|Deps2], [S2|Sz2], Map1, Map2, NDeps,SortedAtoms) :- + compare_var(C,V1,V2,SortedAtoms), + (C == = -> + NDeps = [V1|MDeps], + Map1 = [0|M1], + Map2 = [0|M2], + NDeps = [V1|MDeps], + expand_tabs(Deps1, Sz1, Deps2, Sz2, M1, M2, MDeps,SortedAtoms) + ; + C == < -> + NDeps = [V1|MDeps], + Map1 = [0|M1], + Map2 = [S1|M2], + NDeps = [V1|MDeps], + expand_tabs(Deps1, Sz1, [V2|Deps2], [S2|Sz2], M1, M2, MDeps,SortedAtoms) + ; + NDeps = [V2|MDeps], + Map1 = [S2|M1], + Map2 = [0|M2], + NDeps = [V2|MDeps], + expand_tabs([V1|Deps1], [S1|Sz1], Deps2, Sz2, M1, M2, MDeps,SortedAtoms) + ). + +compare_var(C,V1,V2,SortedAtoms):- + nth(N1,SortedAtoms,V1), + nth(N2,SortedAtoms,V2),!, + compare(C,N1,N2). + +deputy_atoms([],[]):-!. + +deputy_atoms([H|T],[d(H)|T1]):- + deputy_atoms(T,T1). + +identity_facotrs([],[],[],Graph,Graph):-!. + +identity_facotrs([H|T],[d(H)|TD],[f(Mat,[d(H),H],[2,2])|TF],Graph0,Graph1):- + dgraph_add_edges(Graph0,[d(H)-H],Graph2), + matrix_new(floats, [2,2], [1.0,0.0,0.0,1.0],Mat), + identity_facotrs(T,TD,TF,Graph2,Graph1). + + +find_rules_with_atom(_A,[],[]). + +find_rules_with_atom(A,[(N,Head,_Body)|T],[(N,Head)|R]):- + member(A:_P,Head),!, + find_rules_with_atom(A,T,R). + +find_rules_with_atom(A,[_H|T],R):- + find_rules_with_atom(A,T,R). + +rule_factors([],HetF,HetF,[],Graph,Graph):-!. + +rule_factors([(N,Head,Body)|T],HetF0,HetF1,[f(Mat,Deps,Sizes)|HomF],Graph0,Graph1):- + find_atoms_head(Head,Atoms,Probs), + length(Body,LB), + list2(0,LB,Sizes0), + length(Head,LH), + LH1 is LH-1, + list0(0,LH1,FalseCol0), + append(FalseCol0,[1.0],FalseCol), + build_table(Probs,FalseCol,Body,Table), + append(Sizes0,[LH],Sizes), + matrix_new(floats,Sizes,Table,Mat), + find_atoms_body(Body,BodyAtoms), + append(BodyAtoms,[ch(N)],Deps), + gen_het_factors(Atoms,N,LH,0,HetF0,HetF2), + add_hom_edges_to_graph(BodyAtoms,N,Graph0,Graph2), + add_het_edges_to_graph(Atoms,N,Graph2,Graph3), + rule_factors(T,HetF2,HetF1,HomF,Graph3,Graph1). + + +build_table(Probs,FalseCol,Body,T):-!, + build_col(Body,t,Probs,FalseCol,[],T). + +build_col([],t,Probs,_FalseCol,T0,T1):-!, + append(T0,Probs,T1). + +build_col([],f,_Probs,FalseCol,T0,T1):-!, + append(T0,FalseCol,T1). + +build_col([\+ _H|T],Truth,Probs,FalseCol,T0,T1):-!, + build_col(T,Truth,Probs,FalseCol,T0,T2), + build_col(T,f,Probs,FalseCol,T2,T1). + +build_col([_H|T],Truth,Probs,FalseCol,T0,T1):- + build_col(T,f,Probs,FalseCol,T0,T2), + build_col(T,Truth,Probs,FalseCol,T2,T1). + +add_hom_edges_to_graph([],_N,Graph,Graph):-!. + +add_hom_edges_to_graph([H|T],N,Graph0,Graph1):- + dgraph_add_edges(Graph0,[H-ch(N)],Graph2), + add_hom_edges_to_graph(T,N,Graph2,Graph1). + +add_het_edges_to_graph([''],_N,Graph,Graph):-!. + +add_het_edges_to_graph([H|T],N,Graph0,Graph1):- + dgraph_add_edges(Graph0,[ch(N)-d(H)],Graph2), + add_het_edges_to_graph(T,N,Graph2,Graph1). + +add_edges_to_graph([],_Atoms,Graph,Graph):-!. + +add_edges_to_graph([H|T],Atoms,Graph0,Graph1):- + add_edges_from_atom(Atoms,H,Graph0,Graph2), + add_edges_to_graph(T,Atoms,Graph2,Graph1). + +add_edges_from_atom([''],_At,Graph,Graph):-!. + +add_edges_from_atom([H|T],At,Graph0,Graph1):- + dgraph_add_edges(Graph0,[At-d(H)],Graph2), + add_edges_from_atom(T,At,Graph2,Graph1). + +gen_het_factors([''],_N,_LH,_Pos,HetF,HetF):-!. + +gen_het_factors([H|Atoms],N,LH,Pos,HetF0,[f(Mat,[ch(N),d(H)],[LH,2])|HetF1]):- + gen_het_table(0,LH,Pos,Table), + matrix_new(floats, [LH,2], Table, Mat), + Pos1 is Pos+1, + gen_het_factors(Atoms,N,LH,Pos1,HetF0,HetF1). + +gen_het_table(N,N,_Pos,[]):-!. + +gen_het_table(N0,N,N0,[0.0,1.0|T]):-!, + N1 is N0+1, + gen_het_table(N1,N,N0,T). + +gen_het_table(N0,N,Pos,[1.0,0.0|T]):- + N1 is N0+1, + gen_het_table(N1,N,Pos,T). + + + +get_parents([],_AV,[]). + +get_parents([\+ H|T],AV,[V|T1]):-!, + avl_lookup(H,V,AV), + get_parents(T,AV,T1). + +get_parents([H|T],AV,[V|T1]):-!, + avl_lookup(H,V,AV), + get_parents(T,AV,T1). + +choice_vars([],Tr,Tr,[]). + +choice_vars([(N,_H,_B)|T],Tr0,Tr1,[NV|T1]):- + avl_insert(N,NV,Tr0,Tr2), + choice_vars(T,Tr2,Tr1,T1). + +atom_vars([],Tr,Tr,[]). + +atom_vars([H|T],Tr0,Tr1,[VH|VT]):- + avl_insert(H,VH,Tr0,Tr2), + atom_vars(T,Tr2,Tr1,VT). + +find_ground_atoms([],GA,GA). + +find_ground_atoms([(_N,Head,Body)|T],GA0,GA1):- + find_atoms_head(Head,AtH,_P), + append(GA0,AtH,GA2), + find_atoms_body(Body,AtB), + append(GA2,AtB,GA3), + find_ground_atoms(T,GA3,GA1). + +find_atoms_body([],[]). + +find_atoms_body([\+H|T],[H|T1]):-!, + find_atoms_body(T,T1). + +find_atoms_body([H|T],[H|T1]):- + find_atoms_body(T,T1). + + +find_atoms_head([],[],[]). + +find_atoms_head([H:P|T],[H|TA],[P|TP]):- + find_atoms_head(T,TA,TP). + + +find_deriv(GoalsList,Deriv):- + solve(GoalsList,[],DerivDup), + remove_duplicates(DerivDup,Deriv). +/* duplicate can appear in the C set because two different unistantiated clauses may become the +same clause when instantiated */ + + + +/* solve(GoalsList,CIn,COut) takes a list of goals and an input C set +and returns an output C set +The C set is a list of triple (N,R,S) where +- N is the index of the head atom used, starting from 0 +- R is the index of the non ground rule used, starting from 1 +- S is the substitution of rule R, in the form of a list whose elements + are of the form 'VarName'=value +*/ +solve([],C,C):-!. + +solve([bagof(V,EV^G,L)|T],CIn,COut):-!, + list2and(GL,G), + bagof((V,C),EV^solve(GL,CIn,C),LD), + length(LD,N), + build_initial_graph(N,GrIn), + build_graph(LD,0,GrIn,Gr), + clique(Gr,Clique), + build_Cset(LD,Clique,L,[],C1), + remove_duplicates_eq(C1,C2), + solve(T,C2,COut). + +solve([bagof(V,G,L)|T],CIn,COut):-!, + list2and(GL,G), + bagof((V,C),solve(GL,CIn,C),LD), + length(LD,N), + build_initial_graph(N,GrIn), + build_graph(LD,0,GrIn,Gr), + clique(Gr,Clique), + build_Cset(LD,Clique,L,[],C1), + remove_duplicates_eq(C1,C2), + solve(T,C2,COut). + + +solve([setof(V,EV^G,L)|T],CIn,COut):-!, + list2and(GL,G), + setof((V,C),EV^solve(GL,CIn,C),LD), + length(LD,N), + build_initial_graph(N,GrIn), + build_graph(LD,0,GrIn,Gr), + clique(Gr,Clique), + build_Cset(LD,Clique,L1,[],C1), + remove_duplicates(L1,L), + solve(T,C1,COut). + +solve([setof(V,G,L)|T],CIn,COut):-!, + list2and(GL,G), + setof((V,C),solve(GL,CIn,C),LD), + length(LD,N), + build_initial_graph(N,GrIn), + build_graph(LD,0,GrIn,Gr), + clique(Gr,Clique), + build_Cset(LD,Clique,L1,[],C1), + remove_duplicates(L1,L), + solve(T,C1,COut). + +solve([\+ H |T],CIn,COut):-!, + list2and(HL,H), + (setof(D,find_deriv(HL,D),LDup)-> + rem_dup_lists(LDup,[],L), + choose_clauses(CIn,L,C1), + solve(T,C1,COut) + ; + solve(T,CIn,COut) + ). + +solve([H|T],CIn,COut):- + builtin(H),!, + call(H), + solve(T,CIn,COut). + +solve([H|T],CIn,COut):- + def_rule(H,B), + append(B,T,NG), + solve(NG,CIn,COut). + +solve([H|T],CIn,COut):- + find_rule(H,(R,S,N),B,CIn), + solve_pres(R,S,N,B,T,CIn,COut). + +solve_pres(R,S,N,B,T,CIn,COut):- + member_eq((N,R,S),CIn),!, + append(B,T,NG), + solve(NG,CIn,COut). + +solve_pres(R,S,N,B,T,CIn,COut):- + append(CIn,[(N,R,S)],C1), + append(B,T,NG), + solve(NG,C1,COut). + +build_initial_graph(N,G):- + listN(0,N,Vert), + add_vertices([],Vert,G). + + +build_graph([],_N,G,G). + +build_graph([(_V,C)|T],N,GIn,GOut):- + N1 is N+1, + compatible(C,T,N,N1,GIn,G1), + build_graph(T,N1,G1,GOut). + +compatible(_C,[],_N,_N1,G,G). + +compatible(C,[(_V,H)|T],N,N1,GIn,GOut):- + (compatible(C,H)-> + add_edges(GIn,[N-N1,N1-N],G1) + ; + G1=GIn + ), + N2 is N1 +1, + compatible(C,T,N,N2,G1,GOut). + +compatible([],_C). + +compatible([(N,R,S)|T],C):- + not_present_with_a_different_head(N,R,S,C), + compatible(T,C). + +not_present_with_a_different_head(_N,_R,_S,[]). + +not_present_with_a_different_head(N,R,S,[(N,R,S)|T]):-!, + not_present_with_a_different_head(N,R,S,T). + +not_present_with_a_different_head(N,R,S,[(_N1,R,S1)|T]):- + S\=S1,!, + not_present_with_a_different_head(N,R,S,T). + +not_present_with_a_different_head(N,R,S,[(_N1,R1,_S1)|T]):- + R\=R1, + not_present_with_a_different_head(N,R,S,T). + + + +build_Cset(_LD,[],[],C,C). + +build_Cset(LD,[H|T],[V|L],CIn,COut):- + nth0(H,LD,(V,C)), + append(C,CIn,C1), + build_Cset(LD,T,L,C1,COut). + + +/* find_rule(G,(R,S,N),Body,C) takes a goal G and the current C set and +returns the index R of a disjunctive rule resolving with G together with +the index N of the resolving head, the substitution S and the Body of the +rule */ +find_rule(H,(R,S,N),Body,C):- + rule(R,S,_,Head,Body), + member_head(H,Head,0,N), + not_already_present_with_a_different_head(N,R,S,C). + +find_rule(H,(R,S,Number),Body,C):- + rule(R,S,_,uniform(H:1/_Num,_P,Number),Body), + not_already_present_with_a_different_head(Number,R,S,C). + +not_already_present_with_a_different_head(_N,_R,_S,[]). + +not_already_present_with_a_different_head(N,R,S,[(N1,R,S1)|T]):- + not_different(N,N1,S,S1),!, + not_already_present_with_a_different_head(N,R,S,T). + +not_already_present_with_a_different_head(N,R,S,[(_N1,R1,_S1)|T]):- + R\==R1, + not_already_present_with_a_different_head(N,R,S,T). + +not_different(_N,_N1,S,S1):- + S\=S1,!. + +not_different(N,N1,S,S1):- + N\=N1,!, + dif(S,S1). + +not_different(N,N,S,S). + + +member_head(H,[(H:_P)|_T],N,N). + +member_head(H,[(_H:_P)|T],NIn,NOut):- + N1 is NIn+1, + member_head(H,T,N1,NOut). + +/* choose_clauses(CIn,LC,COut) takes as input the current C set and +the set of C sets for a negative goal and returns a new C set that +excludes all the derivations for the negative goals */ +choose_clauses(C,[],C). + +choose_clauses(CIn,[D|T],COut):- + member((N,R,S),D), + already_present_with_a_different_head(N,R,S,CIn),!, + choose_a_head(N,R,S,CIn,C1), + choose_clauses(C1,T,COut). + + +choose_clauses(CIn,[D|T],COut):- + member((N,R,S),D), + new_head(N,R,S,N1), + \+ already_present(N1,R,S,CIn), + impose_dif_cons(R,S,CIn), + choose_clauses([(N1,R,S)|CIn],T,COut). + +impose_dif_cons(_R,_S,[]):-!. + +impose_dif_cons(R,S,[(_NH,R,SH)|T]):-!, + dif(S,SH), + impose_dif_cons(R,S,T). + +impose_dif_cons(R,S,[_H|T]):- + impose_dif_cons(R,S,T). + +/* instantiation_present_with_the_same_head(N,R,S,C) +takes rule R with substitution S and selected head N and a C set +and asserts dif constraints for all the clauses in C of which RS +is an instantitation and have the same head selected */ +instantiation_present_with_the_same_head(_N,_R,_S,[]). + +instantiation_present_with_the_same_head(N,R,S,[(NH,R,SH)|T]):- + \+ \+ S=SH,!, + dif_head_or_subs(N,R,S,NH,SH,T). + +instantiation_present_with_the_same_head(N,R,S,[_H|T]):- + instantiation_present_with_the_same_head(N,R,S,T). + +dif_head_or_subs(N,R,S,NH,_SH,T):- + dif(N,NH), + instantiation_present_with_the_same_head(N,R,S,T). + +dif_head_or_subs(N,R,S,N,SH,T):- + dif(S,SH), + instantiation_present_with_the_same_head(N,R,S,T). + +/* case 1 of Select: a more general rule is present in C with +a different head, instantiate it */ +choose_a_head(N,R,S,[(NH,R,SH)|T],[(NH,R,SH)|T]):- + S=SH, + dif(N,NH). + +/* case 2 of Select: a more general rule is present in C with +a different head, ensure that they do not generate the same +ground clause */ +choose_a_head(N,R,S,[(NH,R,SH)|T],[(NH,R,S),(NH,R,SH)|T]):- + \+ \+ S=SH, S\==SH, + dif(N,NH), + dif(S,SH). + +choose_a_head(N,R,S,[H|T],[H|T1]):- + choose_a_head(N,R,S,T,T1). + +/* select a head different from N for rule R with +substitution S, return it in N1 */ +new_head(N,R,S,N1):- + rule(R,S,Numbers,Head,_Body), + Head\=uniform(_,_,_),!, + nth0(N, Numbers, _Elem, Rest), + member(N1,Rest). + +new_head(N,R,S,N1):- + rule(R,S,Numbers,uniform(_A:1/Tot,_L,_Number),_Body), + listN(0,Tot,Numbers), + nth0(N, Numbers, _Elem, Rest), + member(N1,Rest). + +already_present_with_a_different_head(N,R,S,[(NH,R,SH)|_T]):- + \+ \+ S=SH,NH \= N. + +already_present_with_a_different_head(N,R,S,[_H|T]):- + already_present_with_a_different_head(N,R,S,T). + + +/* checks that a rule R with head N and selection S is already +present in C (or a generalization of it is in C) */ +already_present(N,R,S,[(N,R,SH)|_T]):- + S=SH. + +already_present(N,R,S,[_H|T]):- + already_present(N,R,S,T). + +/* rem_dup_lists removes the C sets that are a superset of +another C sets further on in the list of C sets */ +/* rem_dup_lists removes the C sets that are a superset of +another C sets further on in the list of C sets */ +rem_dup_lists([],L,L). + +rem_dup_lists([H|T],L0,L):- + (member_subset(H,T);member_subset(H,L0)),!, + rem_dup_lists(T,L0,L). + +rem_dup_lists([H|T],L0,L):- + rem_dup_lists(T,[H|L0],L). + +member_subset(E,[H|_T]):- + subset_my(H,E),!. + +member_subset(E,[_H|T]):- + member_subset(E,T). + + + +/* predicates for building the formula to be converted into a BDD */ + +/* build_formula(LC,Formula,VarIn,VarOut) takes as input a set of C sets +LC and a list of Variables VarIn and returns the formula and a new list +of variables VarOut +Formula is of the form [Term1,...,Termn] +Termi is of the form [Factor1,...,Factorm] +Factorj is of the form (Var,Value) where Var is the index of +the multivalued variable Var and Value is the index of the value +*/ +build_formula([],[],Var,Var). + +build_formula([D|TD],[F|TF],VarIn,VarOut):- + build_term(D,F,VarIn,Var1), + build_formula(TD,TF,Var1,VarOut). + +build_term([],[],Var,Var). + +build_term([(N,R,S)|TC],[[NVar,N]|TF],VarIn,VarOut):- + (nth0_eq(0,NVar,VarIn,(R,S))-> + Var1=VarIn + ; + append(VarIn,[(R,S)],Var1), + length(VarIn,NVar) + ), + build_term(TC,TF,Var1,VarOut). + +/* nth0_eq(PosIn,PosOut,List,El) takes as input a List, +an element El and an initial position PosIn and returns in PosOut +the position in the List that contains an element exactly equal to El +*/ +nth0_eq(N,N,[H|_T],El):- + H==El,!. + +nth0_eq(NIn,NOut,[_H|T],El):- + N1 is NIn+1, + nth0_eq(N1,NOut,T,El). + +/* var2numbers converts a list of couples (Rule,Substitution) into a list +of triples (N,NumberOfHeadsAtoms,ListOfProbabilities), where N is an integer +starting from 0 */ +var2numbers([],_N,[]). + +var2numbers([(R,S)|T],N,[[N,ValNumber,Probs]|TNV]):- + find_probs(R,S,Probs), + length(Probs,ValNumber), + N1 is N+1, + var2numbers(T,N1,TNV). + +find_probs(R,S,Probs):- + rule(R,S,_N,Head,_Body), + get_probs(Head,Probs). + +get_probs(uniform(_A:1/Num,_P,_Number),ListP):- + Prob is 1/Num, + list_el(Num,Prob,ListP). + +get_probs([],[]). + +get_probs([_H:P|T],[P1|T1]):- + P1 is P, + get_probs(T,T1). + +list_el(0,_P,[]):-!. + +list_el(N,P,[P|T]):- + N1 is N-1, + list_el(N1,P,T). + +/* end of predicates for building the formula to be converted into a BDD */list_el(0,_P,[]):-!. + + +/* start of predicates for parsing an input file containing a program */ + +/* p(File) parses the file File.cpl. It can be called more than once without +exiting yap */ +p(File):- + parse(File). + +parse(File):- + atom_concat(File,'.cpl',FilePl), + open(FilePl,read,S), + read_clauses(S,C), + close(S), + retractall(rule(_,_,_,_,_)), + retractall(def_rule(_,_)), + process_clauses(C,1). + +process_clauses([(end_of_file,[])],_N). + +process_clauses([((H:-B),V)|T],N):- + H=uniform(A,P,L),!, + list2and(BL,B), + process_body(BL,V,V1), + remove_vars([P],V1,V2), + append(BL,[length(L,Tot),nth0(Number,L,P)],BL1), + append(V2,['Tot'=Tot],V3), + assertz(rule(N,V3,_NH,uniform(A:1/Tot,L,Number),BL1)), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([((H:-B),V)|T],N):- + H=(_;_),!, + list2or(HL1,H), + process_head(HL1,HL), + list2and(BL,B), + process_body(BL,V,V1), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V1,NH,HL,BL)), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([((H:-B),V)|T],N):- + H=(_:_),!, + list2or(HL1,H), + process_head(HL1,HL), + list2and(BL,B), + process_body(BL,V,V1), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V1,NH,HL,BL)), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([((H:-B),V)|T],N):-!, + process_head([H:1.0],HL), + list2and(BL,B), + process_body(BL,V,V1), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V1,NH,HL,BL)), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([(H,V)|T],N):- + H=(_;_),!, + list2or(HL1,H), + process_head(HL1,HL), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V,NH,HL,[])), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([(H,V)|T],N):- + H=(_:_),!, + list2or(HL1,H), + process_head(HL1,HL), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V,NH,HL,[])), + N1 is N+1, + process_clauses(T,N1). + +process_clauses([(H,V)|T],N):- + process_head([H:1.0],HL), + length(HL,LH), + listN(0,LH,NH), + assertz(rule(N,V,NH,HL,[])), + N1 is N+1, + process_clauses(T,N1). + +/* if the annotation in the head are not ground, the null atom is not added +and the eventual formulas are not evaluated */ + +process_head(HL,NHL):- + (ground_prob(HL)-> + process_head_ground(HL,0.0,NHL) + ; + NHL=HL + ). + +ground_prob([]). + +ground_prob([_H:PH|T]):- + ground(PH), + ground_prob(T). + +process_head_ground([H:PH],P,[H:PH1,'':PNull1]):-!, + PH1 is PH, + PNull is 1.0-P-PH1, + (PNull>=0.0-> + PNull1 =PNull + ; + PNull1=0.0 + ). + +process_head_ground([H:PH|T],P,[H:PH1|NT]):- + PH1 is PH, + P1 is P+PH1, + process_head_ground(T,P1,NT). + +/* setof must have a goal of the form B^G where B is a term containing the existential variables */ +process_body([],V,V). + +process_body([setof(A,B^_G,_L)|T],VIn,VOut):-!, + get_var(A,VA), + get_var(B,VB), + remove_vars(VA,VIn,V1), + remove_vars(VB,V1,V2), + process_body(T,V2,VOut). + +process_body([setof(A,_G,_L)|T],VIn,VOut):-!, + get_var(A,VA), + remove_vars(VA,VIn,V1), + process_body(T,V1,VOut). + +process_body([bagof(A,B^_G,_L)|T],VIn,VOut):-!, + get_var(A,VA), + get_var(B,VB), + remove_vars(VA,VIn,V1), + remove_vars(VB,V1,V2), + process_body(T,V2,VOut). + +process_body([bagof(A,_G,_L)|T],VIn,VOut):-!, + get_var(A,VA), + remove_vars(VA,VIn,V1), + process_body(T,V1,VOut). + +process_body([_H|T],VIn,VOut):-!, + process_body(T,VIn,VOut). + +get_var_list([],[]). + +get_var_list([H|T],[H|T1]):- + var(H),!, + get_var_list(T,T1). + +get_var_list([H|T],VarOut):-!, + get_var(H,Var), + append(Var,T1,VarOut), + get_var_list(T,T1). + +get_var(A,[A]):- + var(A),!. + +get_var(A,V):- + A=..[_F|Args], + get_var_list(Args,V). + +remove_vars([],V,V). + +remove_vars([H|T],VIn,VOut):- + delete_var(H,VIn,V1), + remove_vars(T,V1,VOut). + +delete_var(_H,[],[]). + +delete_var(V,[VN=Var|T],[VN=Var|T1]):- + V\==Var,!, + delete_var(V,T,T1). + +delete_var(_V,[_H|T],T). + +/* predicates for reading in the program clauses */ +read_clauses(S,Clauses):- + (setting(ground_body,true)-> + read_clauses_ground_body(S,Clauses) + ; + read_clauses_exist_body(S,Clauses) + ). + + +read_clauses_ground_body(S,[(Cl,V)|Out]):- + read_term(S,Cl,[variable_names(V)]), + (Cl=end_of_file-> + Out=[] + ; + read_clauses_ground_body(S,Out) + ). + + +read_clauses_exist_body(S,[(Cl,V)|Out]):- + read_term(S,Cl,[variable_names(VN)]), + extract_vars_cl(Cl,VN,V), + (Cl=end_of_file-> + Out=[] + ; + read_clauses_exist_body(S,Out) + ). + + +extract_vars_cl(end_of_file,[]). + +extract_vars_cl(Cl,VN,Couples):- + (Cl=(H:-_B)-> + true + ; + H=Cl + ), + extract_vars(H,[],V), + pair(VN,V,Couples). + + +pair(_VN,[],[]). + +pair([VN= _V|TVN],[V|TV],[VN=V|T]):- + pair(TVN,TV,T). + + +extract_vars(Var,V0,V):- + var(Var),!, + (member_eq(Var,V0)-> + V=V0 + ; + append(V0,[Var],V) + ). + +extract_vars(Term,V0,V):- + Term=..[_F|Args], + extract_vars_list(Args,V0,V). + + +extract_vars_list([],V,V). + +extract_vars_list([Term|T],V0,V):- + extract_vars(Term,V0,V1), + extract_vars_list(T,V1,V). + + +listN(N,N,[]):-!. + +listN(NIn,N,[NIn|T]):- + N1 is NIn+1, + listN(N1,N,T). + +list2(N,N,[]):-!. + +list2(NIn,N,[2|T]):- + N1 is NIn+1, + list2(N1,N,T). + +list0(N,N,[]):-!. + +list0(NIn,N,[0.0|T]):- + N1 is NIn+1, + list0(N1,N,T). + +/* end of predicates for parsing an input file containing a program */ + +/* start of utility predicates */ +list2or([X],X):- + X\=;(_,_),!. + +list2or([H|T],(H ; Ta)):-!, + list2or(T,Ta). + +list2and([X],X):- + X\=(_,_),!. + +list2and([H|T],(H,Ta)):-!, + list2and(T,Ta). + +member_eq(A,[H|_T]):- + A==H,!. + +member_eq(A,[_H|T]):- + member_eq(A,T). + +subset_my([],_). + +subset_my([H|T],L):- + member_eq(H,L), + subset_my(T,L). + +remove_duplicates_eq([],[]). + +remove_duplicates_eq([H|T],T1):- + member_eq(H,T),!, + remove_duplicates_eq(T,T1). + +remove_duplicates_eq([H|T],[H|T1]):- + remove_duplicates_eq(T,T1). + +builtin(_A is _B). +builtin(_A > _B). +builtin(_A < _B). +builtin(_A >= _B). +builtin(_A =< _B). +builtin(_A =:= _B). +builtin(_A =\= _B). +builtin(true). +builtin(false). +builtin(_A = _B). +builtin(_A==_B). +builtin(_A\=_B). +builtin(_A\==_B). +builtin(length(_L,_N)). +builtin(member(_El,_L)). +builtin(average(_L,_Av)). +builtin(max_list(_L,_Max)). +builtin(min_list(_L,_Max)). +builtin(nth0(_,_,_)). +builtin(nth(_,_,_)). +average(L,Av):- + sum_list(L,Sum), + length(L,N), + Av is Sum/N. + +clique(Graph,Clique):- + vertices(Graph,Candidates), + extend_cycle(Graph,Candidates,[],[],Clique). + +extend_cycle(G,[H|T],Not,CS,CSOut):- + neighbours(H, G, Neigh), + intersection(Neigh,T,NewCand), + intersection(Neigh,Not,NewNot), + extend(G,NewCand,NewNot,[H|CS],CSOut). + +extend_cycle(G,[H|T],Not,CS,CSOut):- + extend_cycle(G,T,[H|Not],CS,CSOut). + +extend(_G,[],[],CompSub,CompSub):-!. + +extend(G,Cand,Not,CS,CSOut):- + extend_cycle(G,Cand,Not,CS,CSOut). + +intersection([],_Y,[]). + +intersection([H|T],Y,[H|Z]):- + member(H,Y),!, + intersection(T,Y,Z). + +intersection([_H|T],Y,Z):- + intersection(T,Y,Z). + +/* set(Par,Value) can be used to set the value of a parameter */ +set(Parameter,Value):- + retract(setting(Parameter,_)), + assert(setting(Parameter,Value)). + +/* end of utility predicates */ diff --git a/packages/cplint/semcpl.pl b/packages/cplint/semcpl.pl new file mode 100644 index 000000000..bfe4895a2 --- /dev/null +++ b/packages/cplint/semcpl.pl @@ -0,0 +1,638 @@ +/* + +Program for computing the probability of a query directly according to the +semantics + +Copyright (c) 2007, Fabrizio Riguzzi + + +*/ + +:-module(semcpl,[p/1,s/2,sc/3,build/0,print/0,set/2]). + +:-use_module(library(lists)). +:-dynamic setting/2. +%:-set_prolog_flag(unknown,fail). + +setting(epsilon_parsing,0.00001). +setting(ground_body,false). +/* available values: true, false +if true, both the head and the body of each clause will be grounded, otherwise +only the head is grounded. In the case in which the body contains variables +not appearing in the head, the body represents an existential event */ + +/* sc(Goal,Evidence,Probability) + computes a conditional probability +*/ +sc(G,E,P):- + append(G,E,GE), + s(GE,PGE), + s(E,PE), + (PE\==0-> + P is PGE/PE + ; + P=undefined + ). +/* s(GoalsList,Prob) + computes the probability of a query in the form of a list of literals +*/ +s(GoalsList,Prob):- + findall((State,Prob),node(empty,_,_,State,Prob),LL), + sum_prob(LL,GoalsList,0,Prob). + +/* sum_prob(List,GoalsList,P0,P) + List is a list of couples (State,Prob) where State is an interpretation and +Prob is the associated probability. + GoalsList is a list of goals. + P0/P is an accumulator for the probability + sum_prob computes the probability of GoalsList by summing the probability of every + state where GoalsList is true +*/ +sum_prob([],_GL,P,P):-!. + +sum_prob([(State,Prob)|T],GL,P0,P):- + copy_term(GL,GLC), + (body_true(GLC,State)-> + P1 is P0+Prob + ; + P1 is P0 + ), + sum_prob(T,GL,P1,P). + +/* predicates for build the probabilistic process tree */ +/* build + builds the probabilistic process tree with an empty context +*/ +build:- + build([]). + +/* build(Context) + builds the probabilistic process tree with context Context +*/ +build(Context):- + clauses(Cl), + herbrand_base(HB), + deleteall(HB,Context,HB1), + get_new_atom(A), + assert(root(A)), + build(A,Context,1,Cl,HB1). + +/* build(Parent,State,Prob,Clauses,HB):- + Given a parent node, its State, its probability, the list of ground + clauses Clauses and the Herbrand Base HB, it builds the tree below Parent. + The tree is stored in the database in the form of facts of the form + node(Node,Parent,State,r(Head,Body),Prob). + Parent is the parent of Node, State is the interpretation associated to + Node, r(Head,Body) is the clause associated to Node and Prob is its Probability. + The real root of the tree has a dummy parent P for which the fact root(P) is + true that is used to access the tree +*/ +build(Parent,State,Prob,Clauses,HB):- + get_new_atom(Node), + compute_three_valued(State,Clauses,HB,[],Unknowns), + choose_clause(Clauses,State,Unknowns,RemainingClauses,Clause), + (Clause=empty-> + (RemainingClauses=[]-> + assert(node(empty,Node,Parent,State,Prob)) + ; + format("Invalid program.~nInterpretation=~p.~nUnknowns atoms=~p.~nClauses=~p~n",[State,Unknowns,RemainingClauses]) + ) + ; + Clause=r(Head,Body), + assert(node(r(Head,Body),Node,Parent,State,Prob)), + new_states(Node,Head,State,Prob,RemainingClauses,Unknowns) + ). +/* choose_clause(Clauses,Trues,Unknowns,RemainingClauses,Clause) + selects a clause whose body is true in the three valued interpretation + represented by Trues and Unknowns. The selected clause is returned in Clause + and the remaining clauses in RemainingClauses. If no clause has the body + true, it returns empty in Clause. +*/ +choose_clause([],_True,_Unk,[],empty):-!. + +choose_clause([r(Head,Body)|T],True,Unk,RemCl,Clause):- + copy_term(Body,BodyC), + (body_true(BodyC,True,[],Unk)-> + Clause=r(Head,Body), + remove_false(T,True,Unk,RemCl) + ; + (body_false(BodyC,True,[],Unk)-> + RemCl=RemCl0 + ; + RemCl=[r(Head,Body)|RemCl0] + ), + choose_clause(T,True,Unk,RemCl0,Clause) + ). + +remove_false([],_True,_Unk,[]):-!. + +remove_false([r(Head,Body)|T],True,Unk,RemCl):- + copy_term(Body,BodyC), + (body_false(BodyC,True,[],Unk)-> + RemCl=RemCl0 + ; + RemCl=[r(Head,Body)|RemCl0] + ), + remove_false(T,True,Unk,RemCl0). + + +body_true([],_,_,_):-!. + +body_true([\+ H|T],True,False,Unk):- + (\+ ground(H)-> + format("Floundering ~n",[]) + ; + true + ), + \+ member(H,True),\+ member(H,Unk),!, + body_true(T,True,False,Unk). + +body_true([H|T],True,False,Unk):- + H \= (\+ _A), + member(H,True), + body_true(T,True,False,Unk). + +body_true([H|T],True,False,Unk):- + builtin(H), + call(H), + body_true(T,True,False,Unk). + +body_true([],_):-!. + +body_true([\+ H|T],True):- + \+ member(H,True),!, + body_true(T,True). + +body_true([H|T],True):- + member(H,True),!, + body_true(T,True). + + +body_undef([\+ H|T],True,False,Unk):- + member(H,False),!, + body_undef(T,True,False,Unk). + +body_undef([\+ H|T],True,False,Unk):- + \+ member(H,True),\+ member(H,Unk),!, + body_undef(T,True,False,Unk). + +body_undef([\+ H|T],True,False,Unk):- + member(H,Unk),!, + \+ body_false(T,True,False,Unk). + +body_undef([H|T],True,False,Unk):- + member(H,True),!, + body_undef(T,True,False,Unk). + +body_undef([H|T],True,False,Unk):- + member(H,Unk),!, + \+ body_false(T,True,False,Unk). + +/* compute_three_valued(State,Clauses,False,Unknowns0,Unknowns) + computes the three valued interpretation associated with State +*/ +compute_three_valued(State,Clauses,False,Unknowns0,Unknowns):- + choose_clause_three_val(Clauses,State,False,Unknowns0,RemainingClauses,Clause), + (Clause=empty-> + Unknowns=Unknowns0 + ; + Clause=r(Head,_Body), + new_int(Head,False,False1,Unknowns0,Unknowns1), + compute_three_valued(State,RemainingClauses,False1,Unknowns1,Unknowns) + ). +/* choose_clause_three_val(Clauses,Trues,False,Unknowns,RemainingClauses,Clause) + selects a clause whose body is not false in the three valued interpretation + represented by Trues, False and Unknowns. The selected clause is returned in Clause + and the remaining clauses in RemainingClauses. If no clause has the body + true, it returns empty in Clause. +*/ +choose_clause_three_val([],_True,_False,_Unk,_,empty):-!. + +choose_clause_three_val([r(Head,Body)|T],True,False,Unk,RemCl,Clause):- + (\+ body_false(Body,True,False,Unk)-> + Clause=r(Head,Body), + RemCl=T + ; + RemCl=[r(Head,Body)|RemCl0], + choose_clause_three_val(T,True,False,Unk,RemCl0,Clause) + ). + +body_false([\+ H|_T],True,_False,_Unk):- + (\+ ground(H)-> + format("Floundering ~n",[]) + ; + true + ), + member(H,True),!. + +body_false([\+ H|T],True,False,Unk):- + builtin(H), + (call(H)-> + true + ; + body_false(T,True,False,Unk) + ). + +body_false([\+ _H|T],True,False,Unk):-!, + body_false(T,True,False,Unk). + +body_false([H|T],True,False,Unk):- + builtin(H), + call(H),!, + body_false(T,True,False,Unk). + +body_false([H|_T],_True,_False,_Unk):- + builtin(H), + \+ call(H),!. + +body_false([H|T],True,False,Unk):- + findall(H,(member(H,True);member(H,Unk)),LH),!, + body_false_list(LH,H,T,True,False,Unk). + + +body_false_list([],_,_,_,_,_):-!. + +body_false_list([H|T],A,Body,True,False,Unk):- + copy_term((A,Body),(AC,BodyC)), + AC=H, + body_false(BodyC,True,False,Unk), + body_false_list(T,A,Body,True,False,Unk). + + +/* new_int(Head,False0,False,Unk0,Unk) + computes a new three valued interpretation from False0/Unk0 by moving the atoms + in the head from False to Unk +*/ +new_int([],False,False,Unk,Unk):-!. + +new_int([H:_P|T],False0,False,Unk0,Unk):- + (member(H,False0)-> + delete(False0,H,False1), + append(Unk0,[H],Unk1) + ; + False1=False0, + Unk1=Unk0 + ), + new_int(T,False1,False,Unk1,Unk). + + + +/* new_states(Node,Head,State,Prob,Clauses,HB) + computest the tree below Node, where Head is the head of the clause + associated to Node, Prob is the probability of Node, Clauses is the list + of ground clauses yet to be associated to a node and HB is the Herbrand Base. +*/ +new_states(_,[],_,_,_,_):-!. + + +new_states(Node,[H:P|T],State,Prob,Clauses,HB):- + Prob1 is P*Prob, + (member(H,State)-> + NewState=State + ; + append(State,[H],NewState) + ), + build(Node,NewState,Prob1,Clauses,HB), + new_states(Node,T,State,Prob,Clauses,HB). + +/* get_new_atom(Atom) + returns a new Atom of the form nNumber +*/ +get_new_atom(Atom):- + retract(new_number(N)), + N1 is N+1, + assert(new_number(N1)), + number_atom(N,NA), + atom_concat('n',NA,Atom). + +/* predicates for printing the probabilistic process tree */ +print:- + root(Root), + print_children(Root,""). + +print_children(Parent,Tab):- + findall((Node,State,Clause,Prob),node(Clause,Node,Parent,State,Prob),LC), + print_list(LC,Tab). + +print_list([],_Tab):-!. + +print_list([(Node,State0,Clause,Prob)|T],Tab):- + delete(State0,'',State), + (Clause=empty-> % leaf + format("~s~p ~f~n",[Tab,State,Prob]) + ; + format("~s~p ~p ~f~n",[Tab,State,Clause,Prob]), + append(Tab,"| ",Tab1), + print_children(Node,Tab1) + ), + print_list(T,Tab). + + + + +/* predicate for parsing the program file */ +p(File):- + parse(File), + build. + +parse(File):- + retractall(root(_)), + retractall(clauses(_)), + retractall(herbrand_base(_)), + retractall(node(_,_,_,_,_)), + retractall(new_number(_)), + assert(new_number(0)), + atom_concat(File,'.cpl',FilePl), + open(FilePl,read,S), + read_clauses(S,C), + close(S), + atom_concat(File,'.uni',FileUni), + reconsult(FileUni), + process_clauses(C,ClausesVar), + instantiate(ClausesVar,[],Clauses), + assert(clauses(Clauses)), + build_herbrand_base(HB), + assert(herbrand_base(HB)). + + +build_herbrand_base(HB):- + findall(A,mode(A),LA), + inst_list(LA,[],HB). + +/* inst_list(Atoms,HB0,HB) + enlarges the Herbrand Base by instantiating the atoms in Atoms +*/ +inst_list([],HB,HB):-!. + +inst_list([H|T],HB0,HB):- + functor(H,F,Args), + functor(A,F,Args), + findall(A,instantiate_atom_modes(A),LA), + append(HB0,LA,HB1), + inst_list(T,HB1,HB). + +/* instantiate(Clauses,C0,C) + returns in C the set of clauses obtained by grounding Clauses +*/ +instantiate([],C,C). + +instantiate([r(_V,H,B)|T],CIn,COut):- + findall(r(H,BOut),instantiate_clause_modes(H,B,BOut),L), + append(CIn,L,C1), + instantiate(T,C1,COut). + + +instantiate_clause_modes(H,B,BOut):- + instantiate_head_modes(H), + instantiate_body_modes(B,BOut). + + +instantiate_head_modes([]):-!. + +instantiate_head_modes([H:_P|T]):- + instantiate_atom_modes(H), + instantiate_head_modes(T). + + +instantiate_body_modes(BL,BL):- + setting(ground_body,false),!. + +instantiate_body_modes(BL0,BL):- + instantiate_list_modes(BL0,BL). + + +instantiate_list_modes([],[]). + +instantiate_list_modes([H|T0],T):- + builtin(H),!, + call(H), + instantiate_list_modes(T0,T). + +instantiate_list_modes([\+ H|T0],T):- + builtin(H),!, + \+ call(H), + instantiate_list_modes(T0,T). + +instantiate_list_modes([\+ H|T0],[\+ H|T]):-!, + instantiate_atom_modes(H), + instantiate_list_modes(T0,T). + +instantiate_list_modes([H|T0],[H|T]):- + instantiate_atom_modes(H), + instantiate_list_modes(T0,T). + + +instantiate_atom_modes(''):-!. + +instantiate_atom_modes(A):- + functor(A,F,NArgs), + functor(TA,F,NArgs), + A=..[F|Args], + mode(TA), + TA=..[F|Types], + instantiate_args_modes(Args,Types). + + +instantiate_args_modes([],[]):-!. + +instantiate_args_modes([H|T],[TH|TT]):- + type(TH,Constants), + member(H,Constants), + instantiate_args_modes(T,TT). + + +/* process_clauses(Terms,Clauses) + processes Terms to produce Clauses + Terms is a list contatining elements of the form + ((H:-B),V) + Clauses is a list containing elements of the form + r(V,HL,BL) + where HL is the list of disjuncts in H and BL is the list + of literals in B +*/ +process_clauses([(end_of_file,[])],[]). + +process_clauses([((H:-B),V)|T],[r(V,HL,BL)|T1]):- + H=(_;_),!, + list2or(HL1,H), + list2and(BL,B), + process_head(HL1,0,HL), + process_clauses(T,T1). + +process_clauses([((H:-B),V)|T],[r(V,HL,BL)|T1]):- + H=(_:_),!, + list2or(HL1,H), + process_head(HL1,0,HL), + list2and(BL,B), + process_clauses(T,T1). + +process_clauses([((H:-B),V)|T],[r(V,[H:1],BL)|T1]):-!, + list2and(BL,B), + process_clauses(T,T1). + +process_clauses([(H,V)|T],[r(V,HL,[])|T1]):- + H=(_;_),!, + list2or(HL1,H), + process_head(HL1,0,HL), + process_clauses(T,T1). + +process_clauses([(H,V)|T],[r(V,HL,[])|T1]):- + H=(_:_),!, + list2or(HL1,H), + process_head(HL1,0,HL), + process_clauses(T,T1). + +process_clauses([(H,V)|T],[r(V,[H:1],[])|T1]):- + process_clauses(T,T1). + +process_head([H:PH],P,[H:PH1|Null]):- + PH1 is PH, + PNull is 1-P-PH1, + setting(epsilon_parsing,Eps), + EpsNeg is - Eps, + PNull > EpsNeg, + (PNull>Eps-> + Null=['':PNull] + ; + Null=[] + ). + +process_head([H:PH|T],P,[H:PH1|NT]):- + PH1 is PH, + P1 is P+PH1, + process_head(T,P1,NT). + +/* read_clauses(S,Clauses) + read Clauses from stream S +*/ +read_clauses(S,Clauses):- + (setting(ground_body,true)-> + read_clauses_ground_body(S,Clauses) + ; + read_clauses_exist_body(S,Clauses) + ). + +read_clauses_ground_body(S,[(Cl,V)|Out]):- + read_term(S,Cl,[variable_names(V)]), + (Cl=end_of_file-> + Out=[] + ; + read_clauses_ground_body(S,Out) + ). + + +read_clauses_exist_body(S,[(Cl,V)|Out]):- + read_term(S,Cl,[variable_names(VN)]), + extract_vars_cl(Cl,VN,V), + (Cl=end_of_file-> + Out=[] + ; + read_clauses_exist_body(S,Out) + ). + +/* extract_vars_cl(Clause,VariableNames,Couples) + extract from Clause couples of the form VariableName=Variable +*/ +extract_vars_cl(end_of_file,[]). + +extract_vars_cl(Cl,VN,Couples):- + (Cl=(H:-_B)-> + true + ; + H=Cl + ), + extract_vars(H,[],V), + pair(VN,V,Couples). + +extract_vars(Var,V0,V):- + var(Var),!, + (member_eq(Var,V0)-> + V=V0 + ; + append(V0,[Var],V) + ). + +extract_vars(Term,V0,V):- + Term=..[_F|Args], + extract_vars_list(Args,V0,V). + +extract_vars_list([],V,V). + +extract_vars_list([Term|T],V0,V):- + extract_vars(Term,V0,V1), + extract_vars_list(T,V1,V). + +pair(_VN,[],[]). + +pair([VN= _V|TVN],[V|TV],[VN=V|T]):- + pair(TVN,TV,T). + +/* auxiliary predicates */ +list2or([X],X):- + X\=;(_,_),!. + +list2or([H|T],(H ; Ta)):-!, + list2or(T,Ta). + + +list2and([],true):-!. + +list2and([X],X):- + X\=(_,_),!. + +list2and([H|T],(H,Ta)):-!, + list2and(T,Ta). + +builtin(_A is _B). +builtin(_A > _B). +builtin(_A < _B). +builtin(_A >= _B). +builtin(_A =< _B). +builtin(_A =:= _B). +builtin(_A =\= _B). +builtin(true). +builtin(false). +builtin(_A = _B). +builtin(_A==_B). +builtin(_A\=_B). +builtin(_A\==_B). + +bg(member(_El,_L)). +bg(average(_L,_Av)). +bg(max_list(_L,_Max)). +bg(min_list(_L,_Max)). + +average(L,Av):- + sum_list(L,Sum), + length(L,N), + Av is Sum/N. + +assert_all([]):-!. + +assert_all([(:- G)|T]):-!, + call(G), + assert_all(T). + +assert_all([H|T]):-!, + assertz((H)), + assert_all(T). + +assert_all(C):- + assertz((C)). + +deleteall(L,[],L). + +deleteall(L,[H|T],LOut):- + delete(L,H,L1), + deleteall(L1,T,LOut). + +member_eq(A,[H|_T]):- + A==H. + +member_eq(A,[_H|T]):- + member_eq(A,T). + +/* set(Par,Value) can be used to set the value of a parameter */ +set(Parameter,Value):- + retract(setting(Parameter,_)), + assert(setting(Parameter,Value)). diff --git a/packages/cplint/semlpad.pl b/packages/cplint/semlpad.pl new file mode 100644 index 000000000..18b4a7403 --- /dev/null +++ b/packages/cplint/semlpad.pl @@ -0,0 +1,529 @@ +/* + LPAD and CP-Logic reasoning suite + File semlpad.pl + Program for building the semantics of an LPAD + Queries are answered by using SLG in every instance + Copyright (c) 2007, Fabrizio Riguzzi +*/ + +:-module(semlpad,[p/1,s/2,sc/3,set/2]). +:-use_module(library(lists)). +:-dynamic setting/2. +:-set_prolog_flag(unknown,fail). +:- dynamic new_number/1. + +:-[library(slg)]. +:-retract('slg$default'(_D)),assert('slg$default'(tabled)). + +setting(epsilon,0.00001). +%setting(ground_body,true). +setting(ground_body,false). +/* available values: true, false +if true, both the head and the body of each clause will be grounded, otherwise +only the head is grounded. In the case in which the body contains variables +not appearing in the head, the body represents an existential event */ + +%setting(grounding,variables). +setting(grounding,modes). +/* available values: variables, modes +if set to variables, the universe facts from the .uni file are used +if set to modes, the mode and type declaration from the .uni file are used +*/ + +setting(verbose,false). + +new_number(0). +/* sc(Goal,Evidence,Probability) + computes a conditional probability +*/ +sc(Goals,Evidence,Prob):- + s(Evidence,ProbE), + append(Goals,Evidence,GE), + s(GE,ProbGE), + Prob is ProbGE/ProbE. + +/* s(GoalsList,Prob) + computes the probability of a query in the form of a list of literals +*/ +s(GoalsList,Prob):- + program_names(L), + convert_to_goal(GoalsList,Goal,L), + run_query(L,Goal,0,Prob). + +run_query([],_G,P,P). + +run_query([Prog|T],Goal,PIn,POut):- + elab_conj(Prog,Goal,Goal1), + slg(Goal1),!, + prob(Prog,P), + P1 is PIn+P, + run_query(T,Goal,P1,POut). + +run_query([_Prog|T],Goal,PIn,POut):- + run_query(T,Goal,PIn,POut). + + +convert_to_goal([Goal],Goal,_Pr):-!. + +convert_to_goal(GoalsList,Head,Pr):- + get_new_atom(Atom), + extract_vars(GoalsList,[],V), + Head=..[Atom|V], + list2and(GoalsList,Body), + elab_conj(Prog,Head,HeadP), + elab_conj(Prog,Body,BodyP), + do_term_expansion((HeadP:-BodyP),LC), + assert_in_all_prog(LC,Prog,Pr). + + +get_new_atom(Atom):- + retract(new_number(N)), + N1 is N+1, + assert(new_number(N1)), + number_atom(N,NA), + atom_concat('$call',NA,Atom). + + +assert_in_all_prog(_LC,_Prog,[]). + +assert_in_all_prog(LC,Prog,[PrH|PrT]):- + copy_term((LC,Prog),(LC1,Prog1)), + Prog1=PrH, + assert_all(LC1), + assert_in_all_prog(LC,Prog,PrT). + +/* predicate for parsing the program file */ +p(File):- + clean_db, + atom_concat(File,'.cpl',FilePl), + open(FilePl,read,S), + read_clauses(S,C), + close(S), + atom_concat(File,'.uni',FileUni), + reconsult(FileUni), + process_clauses(C,ClausesVar), + instantiate(ClausesVar,[],Clauses), + assert(program(1)), + assert(program_names([])), + create_programs(Clauses). + +clean_db:- + findall((P/A),(mode(Atom),functor(Atom,P,A0),A is A0+1),L), + findall((P/A),(mode(Atom),functor(Atom,P0,A0),A is A0+2, + name(P0,Pl), + name(P,[115,108,103,36|Pl]) % 'slg$' + ),Lslg), + abolish_all(L), + abolish_all(Lslg), + abolish(program/1), + abolish(program_names/1), + abolish(prob/2). + + +abolish_all([]). + +abolish_all([(P/A)|T]):- + abolish(P/A), + abolish_all(T). + +/* create_programs(Clauses) + create the instances of the ground LPAD composed by Clauses + Each instance is identified by an atom of the form P where is an + increasing number. An extra argument is added to each atom in the clauses to represent + the identifier of the instance. +*/ +create_programs(Clauses):- + create_single_program(Clauses,1,Program), + retract(program(N)), + number_codes(N,NC), + atom_codes(NA,NC), + atom_concat(p,NA,Name), + N1 is N+1, + assert(program(N1)), + (setting(verbose,true)-> + format("Writing instance ~d~n",[N]) + ; + true + ), + write_program(Name,Program), + retract(program_names(L)), + append(L,[Name],L1), + assert(program_names(L1)), + fail. + +create_programs(_). + +write_program(Name,[(prob(P):-true)]):-!, + elab_conj(Name,prob(P),Pr), + assertz(Pr). + + +write_program(Name,[(H:-B)|T]):- + elab_conj(Name,H,H1), + elab_conj(Name,B,B1), + do_term_expansion((H1:-B1),LC), + assert_all(LC), + write_program(Name,T). + +/* elab_conj(Name,Conj0,Conj) + adds the extra argument Name to the conjunction Conj0 resulting in Conj +*/ +elab_conj(_Name,true,true):-!. + +elab_conj(Name,\+(B),\+(B1)):-!, + elab_conj(Name,B,B1). + +elab_conj(Name,(BL,Rest),(BL1,Rest1)):-!, + elab_conj(Name,BL,BL1), + elab_conj(Name,Rest,Rest1). + +elab_conj(Name,bagof(V,EV^G,L),bagof(V,EV^GL,L)):-!, + elab_conj(Name,G,GL). + +elab_conj(Name,bagof(V,G,L),bagof(V,GL,L)):-!, + elab_conj(Name,G,GL). + +elab_conj(Name,setof(V,EV^G,L),setof(V,EV^GL,L)):-!, + elab_conj(Name,G,GL). + +elab_conj(Name,setof(V,G,L),setof(V,GL,L)):-!, + elab_conj(Name,G,GL). + +elab_conj(Name,findall(V,G,L),findall(V,GL,L)):-!, + elab_conj(Name,G,GL). + +elab_conj(_Name,A,A):- + bg(A),!. + +elab_conj(_Name,A,A):- + builtin(A),!. + +elab_conj(Name,Lit,Lit1):- + Lit\=(_,_), + Lit=..[Pred|Args], + Lit1=..[Pred,Name|Args]. + + +create_single_program([],P,[(prob(P):-true)]). + +create_single_program([r(H,B)|T],PIn,[(HA:-B)|T1]):- + member((HA:P),H), + P1 is PIn*P, + create_single_program(T,P1,T1). + +/* predicates for producing the ground instances of program clauses */ + +/* instantiate(Clauses,C0,C) + returns in C the set of clauses obtained by grounding Clauses +*/ +instantiate([],C,C). + +instantiate([r(_V,[H:1],B)|T],CIn,COut):-!, + append(CIn,[r([H:1],B)],C1), + instantiate(T,C1,COut). + +instantiate([r(V,H,B)|T],CIn,COut):- + (setting(grounding,variables)-> + findall(r(H,BOut),instantiate_clause_variables(V,H,B,BOut),L) + ; + findall(r(H,BOut),instantiate_clause_modes(H,B,BOut),L) + ), + append(CIn,L,C1), + instantiate(T,C1,COut). + + +instantiate_clause_modes(H,B,BOut):- + instantiate_head_modes(H), + list2and(BL,B), + instantiate_body_modes(BL,BLOut), + list2and(BLOut,BOut). + + +instantiate_head_modes([]):-!. + +instantiate_head_modes([H:_P|T]):- + instantiate_atom_modes(H), + instantiate_head_modes(T). + + +instantiate_body_modes(BL,BL):- + setting(ground_body,false),!. + +instantiate_body_modes(BL0,BL):- + instantiate_list_modes(BL0,BL). + + +instantiate_list_modes([],[]). + +instantiate_list_modes([H|T0],T):- + builtin(H),!, + call(H), + instantiate_list_modes(T0,T). + +instantiate_list_modes([\+ H|T0],T):- + builtin(H),!, + \+ call(H), + instantiate_list_modes(T0,T). + +instantiate_list_modes([\+ H|T0],[\+ H|T]):-!, + instantiate_atom_modes(H), + instantiate_list_modes(T0,T). + +instantiate_list_modes([H|T0],[H|T]):- + instantiate_atom_modes(H), + instantiate_list_modes(T0,T). + + +instantiate_atom_modes(''):-!. + +instantiate_atom_modes(A):- + functor(A,F,NArgs), + functor(TA,F,NArgs), + A=..[F|Args], + mode(TA), + TA=..[F|Types], + instantiate_args_modes(Args,Types). + + +instantiate_args_modes([],[]):-!. + +instantiate_args_modes([H|T],[TH|TT]):- + type(TH,Constants), + member(H,Constants), + instantiate_args_modes(T,TT). + + +instantiate_clause_variables([],_H,B,BOut):- + list2and(BL,B), + (setting(ground_body,true)-> + check_body(BL,BLOut) + ; + BLOut=BL + ), + list2and(BLOut,BOut). + +instantiate_clause_variables([VarName=Var|T],H,BIn,BOut):- + universe(VarNames,U), + member(VarName,VarNames), + member(Var,U), + instantiate_clause_variables(T,H,BIn,BOut). + +instantiate_clause_variables([VarName=_Var|T],H,BIn,BOut):- + \+ varName_present_variables(VarName),!, + instantiate_clause_variables(T,H,BIn,BOut). + + +varName_present_variables(VarName):- + universe(VarNames,_U), member(VarName,VarNames). + +/* check_body(Body0,Body) + removes the true builtin literals from Body0. Fails if there is a false builtin literal. +*/ +check_body([],[]). + +check_body([H|T],TOut):- + builtin(H),!, + call(H), + check_body(T,TOut). + +check_body([H|T],[H|TOut]):- + check_body(T,TOut). + + +/* predicates for processing the clauses read from the file */ +/* process_clauses(Terms,Clauses) + processes Terms to produce Clauses + Terms is a list contatining elements of the form + ((H:-B),V) + Clauses is a list containing elements of the form + r(V,HL,BL) + where HL is the list of disjuncts in H and BL is the list + of literals in B +*/ +process_clauses([(end_of_file,[])],[]). + +process_clauses([((H:-B),V)|T],[r(V,HL,B)|T1]):- + H=(_;_),!, + list2or(HL1,H), + process_head(HL1,0,HL), + process_clauses(T,T1). + +process_clauses([((H:-B),V)|T],[r(V,HL,B)|T1]):- + H=(_:_),!, + list2or(HL1,H), + process_head(HL1,0,HL), + process_clauses(T,T1). + +process_clauses([((H:-B),V)|T],[r(V,[H:1],B)|T1]):-!, + process_clauses(T,T1). + +process_clauses([(H,V)|T],[r(V,HL,true)|T1]):- + H=(_;_),!, + list2or(HL1,H), + process_head(HL1,0,HL), + process_clauses(T,T1). + +process_clauses([(H,V)|T],[r(V,HL,true)|T1]):- + H=(_:_),!, + list2or(HL1,H), + process_head(HL1,0,HL), + process_clauses(T,T1). + +process_clauses([(H,V)|T],[r(V,[H:1],true)|T1]):- + process_clauses(T,T1). + +process_head([H:PH],P,[H:PH1|Null]):- + PH1 is PH, + PNull is 1-P-PH1, + setting(epsilon,Eps), + EpsNeg is - Eps, + PNull > EpsNeg, + (PNull>Eps-> + Null=['':PNull] + ; + Null=[] + ). + +process_head([H:PH|T],P,[H:PH1|NT]):- + PH1 is PH, + P1 is P+PH1, + process_head(T,P1,NT). + +/* predicates for reading in the program clauses */ +/* read_clauses(S,Clauses) + read Clauses from stream S +*/ +read_clauses(S,Clauses):- + (setting(ground_body,true)-> + read_clauses_ground_body(S,Clauses) + ; + read_clauses_exist_body(S,Clauses) + ). + + +read_clauses_ground_body(S,[(Cl,V)|Out]):- + read_term(S,Cl,[variable_names(V)]), + (Cl=end_of_file-> + Out=[] + ; + read_clauses_ground_body(S,Out) + ). + + +read_clauses_exist_body(S,[(Cl,V)|Out]):- + read_term(S,Cl,[variable_names(VN)]), + extract_vars_cl(Cl,VN,V), + (Cl=end_of_file-> + Out=[] + ; + read_clauses_exist_body(S,Out) + ). + + +/* extract_vars_cl(Clause,VariableNames,Couples) + extract from Clause couples of the form VariableName=Variable +*/ +extract_vars_cl(end_of_file,[]). + +extract_vars_cl(Cl,VN,Couples):- + (Cl=(H:-_B)-> + true + ; + H=Cl + ), + extract_vars(H,[],V), + pair(VN,V,Couples). + + +pair(_VN,[],[]). + +pair([VN= _V|TVN],[V|TV],[VN=V|T]):- + pair(TVN,TV,T). + + +extract_vars(Var,V0,V):- + var(Var),!, + (member_eq(Var,V0)-> + V=V0 + ; + append(V0,[Var],V) + ). + +extract_vars(Term,V0,V):- + Term=..[_F|Args], + extract_vars_list(Args,V0,V). + + +extract_vars_list([],V,V). + +extract_vars_list([Term|T],V0,V):- + extract_vars(Term,V0,V1), + extract_vars_list(T,V1,V). + + +/* auxiliary predicates */ +list2or([X],X):- + X\=;(_,_),!. + +list2or([H|T],(H ; Ta)):-!, + list2or(T,Ta). + + +list2and([],true):-!. + +list2and([X],X):- + X\=(_,_),!. + +list2and([H|T],(H,Ta)):-!, + list2and(T,Ta). + + +builtin(_A is _B). +builtin(_A > _B). +builtin(_A < _B). +builtin(_A >= _B). +builtin(_A =< _B). +builtin(_A =:= _B). +builtin(_A =\= _B). +builtin(true). +builtin(false). +builtin(_A = _B). +builtin(_A==_B). +builtin(_A\=_B). +builtin(_A\==_B). + + +bg(member(_El,_L)). +bg(average(_L,_Av)). +bg(max_list(_L,_Max)). +bg(min_list(_L,_Max)). + + +average(L,Av):- + sum_list(L,Sum), + length(L,N), + Av is Sum/N. + +assert_all([]):-!. + +assert_all([(:- G)|T]):-!, + call(G), + assert_all(T). + +assert_all([H|T]):-!, + assertz((H)), + assert_all(T). + +assert_all(C):- + assertz((C)). + +member_eq(A,[H|_T]):- + A==H,!. + +member_eq(A,[_H|T]):- + member_eq(A,T). + +/* set(Par,Value) can be used to set the value of a parameter */ +set(Parameter,Value):- + retract(setting(Parameter,_)), + assert(setting(Parameter,Value)). diff --git a/packages/cplint/semlpadsld.pl b/packages/cplint/semlpadsld.pl new file mode 100644 index 000000000..8e59ff16b --- /dev/null +++ b/packages/cplint/semlpadsld.pl @@ -0,0 +1,468 @@ +/* + LPAD and CP-Logic reasoning suite + File semlpadsld.pl + Program for building the semantics of an LPAD + Queries are answered by using Prolog in every instance + Copyright (c) 2007, Fabrizio Riguzzi +*/ + +:-module(semlpadsld,[p/1,s/2,sc/3,set/2]). +:-use_module(library(lists)). +:-dynamic setting/2. +:-set_prolog_flag(unknown,fail). + + +setting(epsilon,0.00001). +setting(ground_body,false). +/* available values: true, false +if true, both the head and the body of each clause will be grounded, otherwise +only the head is grounded. In the case in which the body contains variables +not appearing in the head, the body represents an existential event */ + +setting(grounding,modes). +/* available values: variables, modes +if set to variables, the universe facts from the .uni file are used +if set to modes, the mode and type declaration from the .uni file are used +*/ + +setting(verbose,false). + + +sc(Goals,Evidence,Prob):- + s(Evidence,ProbE), + append(Goals,Evidence,GE), + s(GE,ProbGE), + Prob is ProbGE/ProbE. + +s(GoalsList,Prob):- + program_names(L), + list2and(GoalsList,Goals), + run_query(L,Goals,0,Prob). + +run_query([],_G,P,P). + +run_query([Prog|T],Goal,PIn,POut):- + elab_conj(Prog,Goal,Goal1), + call(Goal1), + prob(Prog,P), + P1 is PIn+P, + run_query(T,Goal,P1,POut). + +run_query([Prog|T],Goal,PIn,POut):- + elab_conj(Prog,Goal,Goal1), + \+ call(Goal1), + run_query(T,Goal,PIn,POut). + +/* predicate for parsing the program file */ +p(File):- + clean_db, + atom_concat(File,'.cpl',FilePl), + open(FilePl,read,S), + read_clauses(S,C), + close(S), + atom_concat(File,'.uni',FileUni), + reconsult(FileUni), + process_clauses(C,ClausesVar), + instantiate(ClausesVar,[],Clauses), + assert(program(1)), + assert(program_names([])), + create_programs(Clauses). + +clean_db:- + findall((P/A),(mode(Atom),functor(Atom,P,A0),A is A0+1),L), + abolish_all(L), + abolish(program/1), + abolish(program_names/1), + abolish(prob/2). + +abolish_all([]). + +abolish_all([(P/A)|T]):- + abolish(P/A), + abolish_all(T). + +/* create_programs(Clauses) + create the instances of the ground LPAD composed by Clauses + Each instance is identified by an atom of the form P where is an + increasing number. An extra argument is added to each atom in the clauses to represent + the identifier of the instance. +*/ +create_programs(Clauses):- + create_single_program(Clauses,1,Program), + retract(program(N)), + number_codes(N,NC), + atom_codes(NA,NC), + atom_concat(p,NA,Name), + N1 is N+1, + assert(program(N1)), + (setting(verbose,true)-> + format("Writing instance ~d~n",[N]) + ; + true + ), + write_program(Name,Program), + retract(program_names(L)), + append(L,[Name],L1), + assert(program_names(L1)), + fail. + +create_programs(_). + + +write_program(_Name,[]). + +write_program(Name,[(H:-B)|T]):- + elab_conj(Name,H,H1), + elab_conj(Name,B,B1), + assertz((H1:-B1)), + write_program(Name,T). + +/* elab_conj(Name,Conj0,Conj) + adds the extra argument Name to the conjunction Conj0 resulting in Conj +*/ +elab_conj(_Name,true,true):-!. + +elab_conj(Name,\+(B),\+(B1)):-!, + elab_conj(Name,B,B1). + +elab_conj(Name,(BL,Rest),(BL1,Rest1)):-!, + elab_conj(Name,BL,BL1), + elab_conj(Name,Rest,Rest1). + +elab_conj(Name,bagof(V,EV^G,L),bagof(V,EV^GL,L)):-!, + elab_conj(Name,G,GL). + +elab_conj(Name,bagof(V,G,L),bagof(V,GL,L)):-!, + elab_conj(Name,G,GL). + +elab_conj(Name,setof(V,EV^G,L),setof(V,EV^GL,L)):-!, + elab_conj(Name,G,GL). + +elab_conj(Name,setof(V,G,L),setof(V,GL,L)):-!, + elab_conj(Name,G,GL). + +elab_conj(Name,findall(V,G,L),findall(V,GL,L)):-!, + elab_conj(Name,G,GL). + +elab_conj(_Name,A,A):- + bg(A),!. + +elab_conj(_Name,A,A):- + builtin(A),!. + +elab_conj(Name,Lit,Lit1):- + Lit\=(_,_), + Lit=..[Pred|Args], + Lit1=..[Pred,Name|Args]. + + +create_single_program([],P,[(prob(P):-true)]). + +create_single_program([r(H,B)|T],PIn,[(HA:-B)|T1]):- + member((HA:P),H), + P1 is PIn*P, + create_single_program(T,P1,T1). + +/* predicates for producing the ground instances of program clauses */ + +/* instantiate(Clauses,C0,C) + returns in C the set of clauses obtained by grounding Clauses +*/ +instantiate([],C,C). + +instantiate([r(_V,[H:1],B)|T],CIn,COut):-!, + append(CIn,[r([H:1],B)],C1), + instantiate(T,C1,COut). + +instantiate([r(V,H,B)|T],CIn,COut):- + (setting(grounding,variables)-> + findall(r(H,BOut),instantiate_clause_variables(V,H,B,BOut),L) + ; + findall(r(H,BOut),instantiate_clause_modes(H,B,BOut),L) + ), + append(CIn,L,C1), + instantiate(T,C1,COut). + + +instantiate_clause_modes(H,B,BOut):- + instantiate_head_modes(H), + list2and(BL,B), + instantiate_body_modes(BL,BLOut), + list2and(BLOut,BOut). + + +instantiate_head_modes([]):-!. + +instantiate_head_modes([H:_P|T]):- + instantiate_atom_modes(H), + instantiate_head_modes(T). + + +instantiate_body_modes(BL,BL):- + setting(ground_body,false),!. + +instantiate_body_modes(BL0,BL):- + instantiate_list_modes(BL0,BL). + + +instantiate_list_modes([],[]). + +instantiate_list_modes([H|T0],T):- + builtin(H),!, + call(H), + instantiate_list_modes(T0,T). + +instantiate_list_modes([\+ H|T0],T):- + builtin(H),!, + \+ call(H), + instantiate_list_modes(T0,T). + +instantiate_list_modes([\+ H|T0],[\+ H|T]):-!, + instantiate_atom_modes(H), + instantiate_list_modes(T0,T). + +instantiate_list_modes([H|T0],[H|T]):- + instantiate_atom_modes(H), + instantiate_list_modes(T0,T). + + +instantiate_atom_modes(''):-!. + +instantiate_atom_modes(A):- + functor(A,F,NArgs), + functor(TA,F,NArgs), + A=..[F|Args], + mode(TA), + TA=..[F|Types], + instantiate_args_modes(Args,Types). + + +instantiate_args_modes([],[]):-!. + +instantiate_args_modes([H|T],[TH|TT]):- + type(TH,Constants), + member(H,Constants), + instantiate_args_modes(T,TT). + + +instantiate_clause_variables([],_H,B,BOut):- + list2and(BL,B), + (setting(ground_body,true)-> + check_body(BL,BLOut) + ; + BLOut=BL + ), + list2and(BLOut,BOut). + +instantiate_clause_variables([VarName=Var|T],H,BIn,BOut):- + universe(VarNames,U), + member(VarName,VarNames), + member(Var,U), + instantiate_clause_variables(T,H,BIn,BOut). + +instantiate_clause_variables([VarName=_Var|T],H,BIn,BOut):- + \+ varName_present_variables(VarName),!, + instantiate_clause_variables(T,H,BIn,BOut). + + +varName_present_variables(VarName):- + universe(VarNames,_U), member(VarName,VarNames). + +/* check_body(Body0,Body) + removes the true builtin literals from Body0. Fails if there is a false builtin literal. +*/ +check_body([],[]). + +check_body([H|T],TOut):- + builtin(H),!, + call(H), + check_body(T,TOut). + +check_body([H|T],[H|TOut]):- + check_body(T,TOut). + + +/* predicates for processing the clauses read from the file */ +/* process_clauses(Terms,Clauses) + processes Terms to produce Clauses + Terms is a list contatining elements of the form + ((H:-B),V) + Clauses is a list containing elements of the form + r(V,HL,BL) + where HL is the list of disjuncts in H and BL is the list + of literals in B +*/ +process_clauses([(end_of_file,[])],[]). + +process_clauses([((H:-B),V)|T],[r(V,HL,B)|T1]):- + H=(_;_),!, + list2or(HL1,H), + process_head(HL1,0,HL), + process_clauses(T,T1). + +process_clauses([((H:-B),V)|T],[r(V,HL,B)|T1]):- + H=(_:_),!, + list2or(HL1,H), + process_head(HL1,0,HL), + process_clauses(T,T1). + +process_clauses([((H:-B),V)|T],[r(V,[H:1],B)|T1]):-!, + process_clauses(T,T1). + +process_clauses([(H,V)|T],[r(V,HL,true)|T1]):- + H=(_;_),!, + list2or(HL1,H), + process_head(HL1,0,HL), + process_clauses(T,T1). + +process_clauses([(H,V)|T],[r(V,HL,true)|T1]):- + H=(_:_),!, + list2or(HL1,H), + process_head(HL1,0,HL), + process_clauses(T,T1). + +process_clauses([(H,V)|T],[r(V,[H:1],true)|T1]):- + process_clauses(T,T1). + +process_head([H:PH],P,[H:PH1|Null]):- + PH1 is PH, + PNull is 1-P-PH1, + setting(epsilon,Eps), + EpsNeg is - Eps, + PNull > EpsNeg, + (PNull>Eps-> + Null=['':PNull] + ; + Null=[] + ). + +process_head([H:PH|T],P,[H:PH1|NT]):- + PH1 is PH, + P1 is P+PH1, + process_head(T,P1,NT). + + +/* predicates for reading in the program clauses */ +/* read_clauses(S,Clauses) + read Clauses from stream S +*/ +read_clauses(S,Clauses):- + (setting(ground_body,true)-> + read_clauses_ground_body(S,Clauses) + ; + read_clauses_exist_body(S,Clauses) + ). + + +read_clauses_ground_body(S,[(Cl,V)|Out]):- + read_term(S,Cl,[variable_names(V)]), + (Cl=end_of_file-> + Out=[] + ; + read_clauses_ground_body(S,Out) + ). + + +read_clauses_exist_body(S,[(Cl,V)|Out]):- + read_term(S,Cl,[variable_names(VN)]), + extract_vars_cl(Cl,VN,V), + (Cl=end_of_file-> + Out=[] + ; + read_clauses_exist_body(S,Out) + ). + + +/* extract_vars_cl(Clause,VariableNames,Couples) + extract from Clause couples of the form VariableName=Variable +*/ +extract_vars_cl(end_of_file,[]). + +extract_vars_cl(Cl,VN,Couples):- + (Cl=(H:-_B)-> + true + ; + H=Cl + ), + extract_vars(H,[],V), + pair(VN,V,Couples). + + +pair(_VN,[],[]). + +pair([VN= _V|TVN],[V|TV],[VN=V|T]):- + pair(TVN,TV,T). + + +extract_vars(Var,V0,V):- + var(Var),!, + (member_eq(Var,V0)-> + V=V0 + ; + append(V0,[Var],V) + ). + +extract_vars(Term,V0,V):- + Term=..[_F|Args], + extract_vars_list(Args,V0,V). + + +extract_vars_list([],V,V). + +extract_vars_list([Term|T],V0,V):- + extract_vars(Term,V0,V1), + extract_vars_list(T,V1,V). + +member_eq(A,[H|_T]):- + A==H,!. + +member_eq(A,[_H|T]):- + member_eq(A,T). + +/* auxiliary predicates */ +list2or([X],X):- + X\=;(_,_),!. + +list2or([H|T],(H ; Ta)):-!, + list2or(T,Ta). + + +list2and([],true):-!. + +list2and([X],X):- + X\=(_,_),!. + +list2and([H|T],(H,Ta)):-!, + list2and(T,Ta). + + +builtin(_A is _B). +builtin(_A > _B). +builtin(_A < _B). +builtin(_A >= _B). +builtin(_A =< _B). +builtin(_A =:= _B). +builtin(_A =\= _B). +builtin(true). +builtin(false). +builtin(_A = _B). +builtin(_A==_B). +builtin(_A\=_B). +builtin(_A\==_B). + + +bg(member(_El,_L)). +bg(average(_L,_Av)). +bg(max_list(_L,_Max)). +bg(min_list(_L,_Max)). + + +average(L,Av):- + sum_list(L,Sum), + length(L,N), + Av is Sum/N. + +/* set(Par,Value) can be used to set the value of a parameter */ +set(Parameter,Value):- + retract(setting(Parameter,_)), + assert(setting(Parameter,Value)). diff --git a/packages/cplint/slg.pl b/packages/cplint/slg.pl new file mode 100644 index 000000000..1ccf75983 --- /dev/null +++ b/packages/cplint/slg.pl @@ -0,0 +1,2158 @@ +/***************************************************************************/ +/* */ +/* The SLG System */ +/* Authors: Weidong Chen and David Scott Warren */ +/* Copyright (C) 1993 Southern Methodist University */ +/* 1993 SUNY at Stony Brook */ +/* See file COPYRIGHT_SLG for copying policies and disclaimer. */ +/* */ +/***************************************************************************/ + +/*========================================================================== + File : slg.pl + Last Modification : November 14, 2007 by Fabrizio Riguzzi +===========================================================================*/ + +/* ----------- beginning of system dependent features --------------------- + To run the SLG system under a version of Prolog other than Quintus, + comment out the following Quintus-specific code, and include the code + for the Prolog you are running. +*/ + +% Quintus +/* Begin Quintus specific code */ +% :- use_module(library(basics)). +% :- dynamic 'slg$prolog'/1, 'slg$tab'/2. +% :- dynamic slg_expanding/0. +% :- dynamic wfs_trace/0. +/* End Quintus specific code */ + +% Sicstus +/* Begin Sicstus specific code */ + append([],L,L). + append([X|L1],L2,[X|L3]) :- append(L1,L2,L3). + + member(X,[X|_]). + member(X,[_|L]) :- member(X,L). + + memberchk(X,[X|_]) :- !. + memberchk(X,[_|L]) :- memberchk(X,L). + + :- dynamic 'slg$prolog'/1, 'slg$tab'/2. + :- dynamic slg_expanding/0. + :- dynamic wfs_trace/0. +/* End Sicstus specific code */ + +% XSB +/* Begin XSB specific code */ +/* To compile this under xsb, you must allocate more than the default stack + space when running xsb. E.g. use % xsb -m 2000 +*/ +%:- import member/2, memberchk/2, append/3, ground/1 from basics. +%:- import numbervars/3 from num_vars. + +%:- dynamic slg_expanding/0. +%:- dynamic 'slg$prolog'/1, 'slg$tab'/2. +%:- dynamic wfs_trace/0. +/* End XSB specific code */ + +/* -------------- end of system dependent features ----------------------- */ + +/* -------------- beginning of slg_load routines ------------------------- + An input file may contain three kinds of directives (in addition to + regular Prolog clauses and commands): + + a) :- default(prolog). + :- default(tabled). + All predicates defined from now on are prolog (tabled) predicates + unless specified otherwise later. + b) :- tabled pred_name/arity. + pred_name/arity is a tabled predicate. A comma separated list + is also acceptable. + + c) :- prolog pred_name/arity. + pred_name/arity is a prolog predicate. A comma separated list + is also acceptable. + + Besides Prolog clauses, we allow general clauses where the body is a + universal disjunction of literals. Such clauses are specified in the form + Head <-- Body. + (Maybe <-- can be viewed as "All".) The head must be an atom of a tabled + predicate and the body should be a disjunction of literals (separated by ';') + and should not contain cut. The head must be ground whenever it is called. + All variables in the body that do not occur in the head are universally + quantified. + + There is NO support for module facilities. In particular, ALL TABLED + PREDICATES SHOULD BE DEFINED IN MODULE 'user'. +*/ + +:- op(1200,xfx,<--). +:- op(1150,fx,[(tabled),(prolog),(default)]). +:- op(900,xfx,<-). + +:- assert('slg$tabled'(0,0)), retractall('slg$tabled'(_,_)). +:- assert('slg$default'((prolog))). + +do_term_expansion(end_of_file,_) :- !, + retractall('slg$default'(_)), + assert('slg$default'((prolog))), + retractall('slg$prolog'(_)), + retractall('slg$tab'(_,_)), + fail. +do_term_expansion((:-Com),Clauses) :- !, + expand_command(Com,Clauses). +do_term_expansion((H-->B),NewClause) :- !, + \+ slg_expanding, + assert(slg_expanding), + expand_term((H-->B),Clause), + retractall(slg_expanding), + do_term_expansion(Clause,NewClause). +do_term_expansion((Head <-- Body),Clauses) :- !, + functor(Head,P,A), + Pred = P/A, + ( 'slg$tab'(P,A) -> + convert_univ_clause(Head,Body,Clauses) + ; 'slg$prolog'(Pred) -> + write('Error: Prolog predicate '), write(Pred), + write(' in clauses with universal disjunction.'),nl, + write(' Clause ignored: '), write((Head <-- Body)), nl, + Clauses = [] + ; 'slg$default'(Default), + ( Default == (prolog) -> + write('Error: Prolog predicate '), write(Pred), + write(' in clauses with universal disjunction.'),nl, + write(' Clause ignored: '), write((Head <-- Body)), nl, + Clauses = [] + ; assert('slg$tab'(P,A)), + retractall('slg$tabled'(P,A)), + assert('slg$tabled'(P,A)), + functor(NewHead,P,A), + Clauses = [(:- retractall('slg$tabled'(P,A)), assert('slg$tabled'(P,A))), + (NewHead :- slg(NewHead))|RestClauses], + convert_univ_clause(Head,Body,RestClauses) + ) + ). +do_term_expansion(Clause,Clauses) :- + ( Clause = (Head :- Body) -> true; Head = Clause, Body = true ), + functor(Head,P,A), + Pred = P/A, + ( 'slg$tab'(P,A) -> + convert_tabled_clause(Head,Body,Clauses) + ; 'slg$prolog'(Pred) -> + Clauses = Clause + ; 'slg$default'(Default), + ( Default == (prolog) -> + Clauses = Clause + ; ( 'slg$tab'(P,A) -> + convert_tabled_clause(Head,Body,Clauses) + ; assert('slg$tab'(P,A)), + retractall('slg$tabled'(P,A)), + assert('slg$tabled'(P,A)), + functor(NewHead,P,A), + Clauses = [(:- retractall('slg$tabled'(P,A)), assert('slg$tabled'(P,A))), + (NewHead :- slg(NewHead))|RestClauses], + convert_tabled_clause(Head,Body,RestClauses) + ) + ) + ). +expand_command(tabled(Preds),Clauses) :- + expand_command_table(Preds,Clauses,[]). +expand_command(prolog(Preds),Clauses) :- + expand_command_prolog(Preds,Clauses,[]). +expand_command(multifile(Preds),(:-multifile(NewPreds))) :- + add_table_preds(Preds,NewPreds,[]). +expand_command(dynamic(Preds),(:-dynamic(NewPreds))) :- + add_table_preds(Preds,NewPreds,[]). +expand_command(default(D),[]) :- + ( (D == (prolog); D == (tabled)) -> + retractall('slg$default'(_)), + assert('slg$default'(D)) + ; write('Warning: illegal default '), + write(D), + write(' ignored.'), + nl + ). + +expand_command_table((Pred,Preds),Clauses0,Clauses) :- !, + expand_command_table_one(Pred,Clauses0,Clauses1), + expand_command_table(Preds,Clauses1,Clauses). +expand_command_table(Pred,Clauses0,Clauses) :- + expand_command_table_one(Pred,Clauses0,Clauses). + +expand_command_table_one(Pspec,Clauses0,Clauses) :- + ( Pspec = P/A -> true; P = Pspec, A = 0 ), + Pred = P/A, + functor(H,P,A), + ( ( predicate_property(H,built_in); slg_built_in(H) ) -> + write('ERROR: Cannot table built_in '), + write(Pred), nl, + Clauses0 = Clauses + ; 'slg$prolog'(Pred) -> + write('ERROR: '), + write(Pred), + write(' assumed to be a Prolog predicate'), + nl, + tab(7), + write('But later declared a tabled predicate.'), + nl, + Clauses0 = Clauses + ; 'slg$tab'(P,A) -> + Clauses0 = Clauses + ; assert('slg$tab'(P,A)), + retractall('slg$tabled'(P,A)), + assert('slg$tabled'(P,A)), + Clauses0 = [(:- retractall('slg$tabled'(P,A)), assert('slg$tabled'(P,A))), + (H :- slg(H))|Clauses] + ). + +expand_command_prolog((Pred,Preds),Clauses0,Clauses) :- !, + expand_command_prolog_one(Pred,Clauses0,Clauses1), + expand_command_prolog(Preds,Clauses1,Clauses). +expand_command_prolog(Pred,Clauses0,Clauses) :- + expand_command_prolog_one(Pred,Clauses0,Clauses). + +expand_command_prolog_one(Pspec,Clauses0,Clauses) :- + ( Pspec = P/A -> true; P = Pspec, A = 0 ), + Pred = P/A, + ( 'slg$tab'(P,A) -> + write('ERROR: '), + write(Pred), + write(' assumed to be a tabled predicate'), + nl, + tab(7), + write('But later declared a Prolog predicate.'), + nl, + Clauses0 = Clauses + ; retractall('slg$tab'(P,A)), + retractall('slg$tabled'(P,A)), + ( 'slg$prolog'(Pred) -> + true + ; assert('slg$prolog'(Pred)) + ), + Clauses0 = [(:- retractall('slg$tabled'(P,A)))|Clauses] + ). + +add_table_preds(Preds,NewPreds0,NewPreds) :- + ( Preds == [] -> + NewPreds0 = NewPreds + ; Preds = [P|Ps] -> + add_table_preds(P,NewPreds0,NewPreds1), + add_table_preds(Ps,NewPreds1,NewPreds) + ; Preds = (P,Ps) -> + add_table_preds(P,NewPreds0,NewPreds1), + add_table_preds(Ps,NewPreds1,NewPreds) + ; ( Preds = P/A -> true; P = Preds, A = 0 ), + ( 'slg$tab'(P,A) -> + name(P,Pl), + name(NewP,[115,108,103,36|Pl]), % 'slg$' + NewA is A+1, + NewPreds0 = [P/A,NewP/NewA|NewPreds] + ; NewPreds0 = [P/A|NewPreds] + ) + ). + +convert_tabled_clause(Head,Body,Clauses0) :- + conj_to_list(Body,Blist), + extract_guard(Blist,Guard,[],Nbody,Clauses0,Clauses), + list_to_conj(Guard,Gconj), + new_slg_head(Head,Nbody,NewHead), + ( Gconj == true -> + Clauses = [NewHead] + ; Clauses = [(NewHead :- Gconj)] + ). + +convert_univ_clause(Head,Body,Clauses) :- + disj_to_list(Body,Blist), + new_slg_head(Head,all(Blist),NewHead), + Clauses = [(NewHead :- ( ground0(Head) -> + true + ; write('Error: Non-ground call '), + write(Head), + write(' in a clause with universal disjunction.'), + nl + ))]. + +ground0(X) :- ground(X). + +conj_to_list(Term,List) :- + conj_to_list(Term,List,[]). +conj_to_list(Term,List0,List) :- + ( Term = (T1,T2) -> + conj_to_list(T1,List0,List1), + conj_to_list(T2,List1,List) + ; Term == true -> + List0 = List + ; List0 = [Term|List] + ). + +disj_to_list(Term,List) :- + disj_to_list(Term,List,[]). +disj_to_list(Term,List0,List) :- + ( Term = (T1;T2) -> + disj_to_list(T1,List0,List1), + disj_to_list(T2,List1,List) + ; Term == true -> + List0 = List + ; List0 = [Term|List] + ). + +extract_guard([],G,G,[],Cls,Cls). +extract_guard([Lit|List],G0,G,Rest,Cls0,Cls) :- + ( Lit = (\+N) -> + Nlit = N + ; Nlit = Lit + ), + ( ( predicate_property(Nlit,built_in); slg_built_in(Nlit) ) -> + G0 = [Lit|G1], + extract_guard(List,G1,G,Rest,Cls0,Cls) + ; functor(Nlit,P,A), + Pred = P/A, + ( 'slg$tab'(P,A) -> + G0 = G, + Rest = [Lit|List], + Cls0 = Cls + ; 'slg$prolog'(Pred) -> + G0 = [Lit|G1], + extract_guard(List,G1,G,Rest,Cls0,Cls) + ; 'slg$default'((prolog)) -> + G0 = [Lit|G1], + assert('slg$prolog'(Pred)), + Cls0 = [(:- 'slg$prolog'(Pred) -> true; assert('slg$prolog'(Pred)))|Cls1], + extract_guard(List,G1,G,Rest,Cls1,Cls) + ; 'slg$default'((tabled)) -> + G0 = G, + Rest = [Lit|List], + assert('slg$tab'(P,A)), + retractall('slg$tabled'(P,A)), + assert('slg$tabled'(P,A)), + functor(Head,P,A), + Cls0 = [(:- retractall('slg$tabled'(P,A)), assert('slg$tabled'(P,A))), + (Head :- slg(Head))|Cls] + ) + ). + +list_to_conj([],true). +list_to_conj([Lit|List],G0) :- + ( List == [] -> + G0 = Lit + ; G0 = (Lit,G), + list_to_conj(List,G) + ). + +new_slg_head(Head,Body,NewHead) :- + functor(Head,P,A), + name(P,Pl), + name(Npred,[115,108,103,36|Pl]), % 'slg$' + Narity is A+1, + functor(NewHead,Npred,Narity), + arg(Narity,NewHead,Body), + put_in_args(0,A,Head,NewHead). + +put_in_args(A,A,_,_). +put_in_args(A0,A,Head,NewHead) :- + A0 < A, + A1 is A0+1, + arg(A1,Head,Arg), + arg(A1,NewHead,Arg), + put_in_args(A1,A,Head,NewHead). + +slg_built_in(slg(_)). +slg_built_in(_<-_). +slg_built_in(slgall(_,_)). +slg_built_in(slgall(_,_,_,_)). +slg_built_in(emptytable(_)). +slg_built_in(st(_,_)). +slg_built_in(stnot(_,_)). +slg_built_in(stall(_,_,_)). +slg_built_in(stall(_,_,_,_,_)). +slg_built_in(stselect(_,_,_,_)). +slg_built_in(stselect(_,_,_,_,_,_)). +slg_built_in(xtrace). +slg_built_in(xnotrace). + +/* ----------------- end of slg_load routines --------------------------- */ + +/* SLG tracing: + xtrace: turns SLG trace on, which prints out tables at various + points + xnotrace: turns off SLG trace +*/ +xtrace :- + ( wfs_trace -> + true + ; assert(wfs_trace) + ). +xnotrace :- + ( wfs_trace -> + retractall(wfs_trace) + ; true + ). + +/* isprolog(Call): Call is a Prolog subgoal */ +isprolog(Call) :- + functor(Call,P,A), + \+ 'slg$tabled'(P,A). + +/* slg(Call): + It returns all true answers of Call under the well-founded semantics + one by one. +*/ +slg(Call) :- + ( isprolog(Call) -> + call(Call) + ; oldt(Call,Tab), + ground(Call,Ggoal), + find(Tab,Ggoal,Ent), + ent_to_anss(Ent,Anss), + member_anss(d(Call,[]),Anss) + ). + +/* Call<-Cons: + It returns all true or undefined answers of Call one by one. In + case of a true answer, Cons = []. For an undefined answer, + Cons is a list of delayed literals. +*/ +Call<-Cons :- + ( isprolog(Call) -> + call(Call), + Cons = [] + ; oldt(Call,Tab), + ground(Call,Ggoal), + find(Tab,Ggoal,Ent), + ent_to_anss(Ent,Anss), + member_anss(d(Call,Cons),Anss) + ). + +/* emptytable(EmptTab): creates an initial empty stable. +*/ +emptytable(0:[]). + +/* slgall(Call,Anss): + slgall(Call,Anss,N0-Tab0,N-Tab): + If Call is a prolog call, findall is used, and Tab = Tab0; + If Call is an atom of a tabled predicate, SLG evaluation + is carried out. +*/ +slgall(Call,Anss) :- + slgall(Call,Anss,0:[],_). +slgall(Call,Anss,N0:Tab0,N:Tab) :- + ( isprolog(Call) -> + findall(Call,Call,Anss), + N = N0, Tab = Tab0 + ; ground(Call,Ggoal), + ( find(Tab0,Ggoal,Ent) -> + ent_to_anss(Ent,Answers), + Tab = Tab0 + ; new_init_call(Call,Ggoal,Ent,[],S1,1,Dfn1), + add_tab_ent(Ggoal,Ent,Tab0,Tab1), + oldt(Call,Ggoal,Tab1,Tab,S1,_S,Dfn1,_Dfn,maxint-maxint,_Dep,N0:[],N:_TP), + find(Tab,Ggoal,NewEnt), + ent_to_anss(NewEnt,Answers) + ), + ansstree_to_list(Answers,Anss,[]) + ). + +/* st(Call,PSM): + stnot(Call,PSM): + It finds a stable model in which Call must be true (false). + Call must be ground. +*/ +st(Call,PSM) :- + st_true_false(Call,true,PSM). +stnot(Call,PSM) :- + st_true_false(Call,false,PSM). + +st_true_false(Call,Val,PSM) :- + ( isprolog(Call) -> + PSM = [], + call(Call) + ; ground(Call) -> + wfs_newcall(Call,[],Tab1,0,_), + find(Tab1,Call,Ent), + ent_to_anss(Ent,Anss), + ( succeeded(Anss) -> + ( Val == true -> + PSM = [] + ; fail + ) + ; failed(Anss) -> + ( Val == false -> + PSM = [] + ; fail + ) + ; assume_one(Call,Val,Tab1,Tab2,[],Abd1,A0,A1), + collect_unds(Anss,A1,A), + st(A0,A,Tab2,Tab3,Abd1,Abd,[],DAbd,[],_Plits), + final_check(Abd,Tab3,_Tab,DAbd,PSM) + ) + ; write('Error: non-ground call '), + write(Call), + write(' in st/2.'), + nl, + fail + ). + +/* stall(Call,Anss,PSM): + stall(Call,Anss,PSM,Tab0,Tab): + It computes a partial stable model PSM and collects all + answers of Call in that model. +*/ +stall(Call,Anss,PSM) :- + stall(Call,Anss,PSM,0:[],_). + +stall(Call,Anss,PSM,N0:Tab0,N:Tab) :- + ( isprolog(Call) -> + findall(Call,Call,Anss), + PSM = [], N = N0, Tab = Tab0 + ; ground(Call,Ggoal), + ( find(Tab0,Ggoal,Ent) -> + Tab1 = Tab0, N = N0 + ; wfs_newcall(Call,Tab0,Tab1,N0,N), + find(Tab1,Ggoal,Ent) + ), + ent_to_delay(Ent,Delay), + ( Delay == false -> + Fent = Ent, PSM = [], Tab = Tab1 + ; ent_to_anss(Ent,Anss0), + collect_unds(Anss0,A0,A), + st(A0,A,Tab1,Tab2,[],Abd,[],DAbd,[],_Plits), + final_check(Abd,Tab2,Tab,DAbd,PSM), + find(Tab,Ggoal,Fent) + ), + ent_to_anss(Fent,Anss1), + ansstree_to_list(Anss1,Anss,[]) + ). + +/* stselect(Call,PSM0,Anss,PSM): + stselect(Call,PSM0,Anss,PSM,N0:Tab0,N:Tab): + It computes a partial stable model PSM in which all ground + literals in PSM0 are true, and returns all answers of Call + in the partial stable model. Call must be an atom of a tabled + or stable predicate. +*/ +stselect(Call,PSM0,Anss,PSM) :- + stselect(Call,PSM0,Anss,PSM,0:[],_). + +stselect(Call,PSM0,Anss,PSM,N0:Tab0,N:Tab) :- + ( isprolog(Call) -> + write('Error: Prolog predicate '), + write(Call), + write('stselect.'), + fail + ; wfsoldt(Call,PSM0,Ent,Tab0,Tab1,N0,N), + ent_to_delay(Ent,Delay), + assume_list(PSM0,true,Tab1,Tab2,[],Abd0,A0,A1), + ( Delay == false -> + A1 = A2 + ; ent_to_anss(Ent,Anss0), + collect_unds(Anss0,A1,A2) + ), + st(A0,A2,Tab2,Tab3,Abd0,Abd,[],DAbd,[],_Plits), + final_check(Abd,Tab3,Tab,DAbd,PSM), + ground(Call,Ggoal), + find(Tab,Ggoal,Fent), + ent_to_anss(Fent,Anss1), + ansstree_to_list(Anss1,Anss,[]) + ). + +wfsoldt(Call,PSM0,Ent,Tab0,Tab,N0,N) :- + ground(Call,Ggoal), + ( find(Tab0,Ggoal,Ent) -> + Tab1 = Tab0, N1 = N0 + ; wfs_newcall(Call,Tab0,Tab1,N0,N1), + find(Tab1,Ggoal,Ent) + ), + wfsoldt_ground(PSM0,Tab1,Tab,N1,N). + +wfsoldt_ground([],Tab,Tab,N,N). +wfsoldt_ground([A|PSM],Tab0,Tab,N0,N) :- + ( ground(A) -> + true + ; write('Error: non-ground assumption in stable model selection: '), + write(A), nl, fail + ), + ( A = (\+G) -> + true + ; A = G + ), + ( isprolog(G) -> + Tab1 = Tab0, N1 = N0, + call(A) + ; find(Tab0,G,_) -> + Tab1 = Tab0, N1 = N0 + ; wfs_newcall(G,Tab0,Tab1,N0,N1) + ), + wfsoldt_ground(PSM,Tab1,Tab,N1,N). + +wfs_newcall(Call,Tab0,Tab,N0,N) :- + new_init_call(Call,Ggoal,Ent0,[],S1,1,Dfn1), + add_tab_ent(Ggoal,Ent0,Tab0,Tab1), + oldt(Call,Ggoal,Tab1,Tab,S1,_S,Dfn1,_Dfn,maxint-maxint,_Dep,N0:[],N:_TP). + +/* collect_unds(Anss,A0,A): + collects all delayed literals in answers Anss in a open-ended difference + list A0/A. These delayed literals are assumed either false or true in the + stable model computation. +*/ +collect_unds([],A,A). +collect_unds(l(_GH,Lanss),A1,A) :- + collect_unds_lanss(Lanss,A1,A). +collect_unds(n2(T1,_,T2),A1,A) :- + collect_unds(T1,A1,A2), + collect_unds(T2,A2,A). +collect_unds(n3(T1,_,T2,_,T3),A1,A) :- + collect_unds(T1,A1,A2), + collect_unds(T2,A2,A3), + collect_unds(T3,A3,A). + +collect_unds_lanss([],A,A). +collect_unds_lanss([d(_,D)|Lanss],A1,A) :- + collect_unds_list(D,A1,A2), + collect_unds_lanss(Lanss,A2,A). + +collect_unds_list([],A,A). +collect_unds_list([Lit|D],[Lit|A1],A) :- + collect_unds_list(D,A1,A). + +/* st(A0,A,Tab0,Tab,Abd0,Abd,DAbd0,DAbd,Plits0,Plits): + A0/A is an open-ended difference list containing a list of + delayed literals. st tries for each delayed literal to + assume that it is true or false and checks to see if + it leads to a partial stable model. Propagation of assumed + truth values is carried out as much as possible. It will + fail if the relevant program contains p :- \+p. + + Abd0/Abd is an accumulator for a table of assumed truth + values. They are checked against the table Tab0/Tab for + consistency later in check_consistency. DAbd0/DAbd is an + accumulator for truth values of undefined literals that + are derived from assumed truth values of other literals. + Plits0/Plits is an accumulator for avoiding positive + infinite loops in processing positive delayed literals. +*/ +st(A0,A,Tab0,Tab,Abd0,Abd,DAbd0,DAbd,Plits0,Plits) :- + ( % empty difference list + A0 == A -> + Tab = Tab0, Abd = Abd0, DAbd = DAbd0, Plits = Plits0 + ; A0 = [Lit|A1], + ( % non-ground negative literals + Lit = (Ggoal - (\+GH)) -> + write('Error: cannot handle non-ground negative literals: '), + write(\+GH), nl, fail + ; % positive undefined literal + Lit = Ggoal-GH -> + ( % encountered before + find(Plits0,Lit,_) -> + st(A1,A,Tab0,Tab,Abd0,Abd,DAbd0,DAbd,Plits0,Plits) + ; % otherwise, process undefined literals it depends upon + addkey(Plits0,Lit,_,Plits1), + find(Tab0,Ggoal,Ent), + ent_to_anss(Ent,Anss), + find(Anss,GH,Lanss), + collect_unds_lanss(Lanss,A,NewA), + st(A1,NewA,Tab0,Tab,Abd0,Abd,DAbd0,DAbd,Plits1,Plits) + ) + ; % negative undefined literal + Lit = (\+G) -> + ( % has been assumed or derived to be true or false + ( find(Abd0,G,_Val); find(DAbd0,G,_) ) -> + st(A1,A,Tab0,Tab,Abd0,Abd,DAbd0,DAbd,Plits0,Plits) + ; find(Tab0,G,Gent), + ent_to_anss(Gent,Ganss), + ( % found to be false already + failed(Ganss) -> + addkey(DAbd0,G,false,DAbd1), + st(A1,A,Tab0,Tab,Abd0,Abd,DAbd1,DAbd,Plits0,Plits) + ; % found to be true already + succeeded(Ganss) -> + addkey(DAbd0,G,true,DAbd1), + st(A1,A,Tab0,Tab,Abd0,Abd,DAbd1,DAbd,Plits0,Plits) + ; % create a choice point + addkey(Abd0,G,Val,Abd1), + ( Ganss = l(G,[d(G,Ds)]), memberchk(\+G,Ds) -> + Val = false + ; ( Val = false; Val = true ) + ), + propagate_forward(G,Val,Tab0,Tab1,Abd1), + A = [G-G|NewA], % make sure delayed literals of G are checked + propagate_backward(G,Val,Ganss,Tab1,Tab2,Abd1,Abd2,NewA,NNA), + st(A1,NNA,Tab2,Tab,Abd2,Abd,DAbd0,DAbd,Plits0,Plits) + ) + ) + ) + ). + +/* propagate_forward(G,Val,Tab0,Tab,Abd): + G has been assumed to be Val, and this information is propagated + using simplification or forward chaining links as much as + possible. +*/ +propagate_forward(G,Val,Tab0,Tab,Abd) :- + updatevs(Tab0,G,Ent0,Ent,Tab1), + Ent0 = e(Nodes,ANegs,Anss,Delay,Comp,Gdfn,Slist0), + Ent = e(Nodes,ANegs,Anss,Delay,Comp,Gdfn,Slist), + extract_known_by_abd(Slist0,Val,[],Slist,[],Klist), + simplify(Klist,Tab1,Tab,Abd). + +/* The forward chaining is such that negative literals can fail + or succeed by assumption, and positive literals can fail + by assumption, but cannot succeed by assumption. + This avoids the construction of supported models that are + not stable. +*/ +extract_known_by_abd([],_,Slist,Slist,Klist,Klist). +extract_known_by_abd([Link|Links],Val,Slist0,Slist,Klist0,Klist) :- + ( Link = (_ : (\+ _)) -> + ( Val == false -> + Slist1 = Slist0, + Klist1 = [succ-Link|Klist0] + ; Val == true -> + Slist1 = Slist0, + Klist1 = [fail-Link|Klist0] + ; Slist1 = [Link|Slist0], + Klist1 = Klist0 + ) + ; % Link = (_ : _-GH) -> + ( Val = false -> + Slist1 = Slist0, + Klist1 = [fail-Link|Klist0] + ; % Val = true -> + Slist1 = [Link|Slist0], + Klist1 = Klist0 + ) + ), + extract_known_by_abd(Links,Val,Slist1,Slist,Klist1,Klist). + +/* propagate_backward(G,Val,Ganss,Tab0,Tab,Abd0,Abd,A,NewA): + It tried to propagate the Val of G backward through answers + if possible. If G is assumed to be true, and G has only one + answer clause, then all literals in the body of the answer + clause must be true. If G is assumed to be false, then all + literals in answer clauses of G that have a single literal + are assumed to be false too. Otherwise, it is no-op. +*/ +propagate_backward(G,Val,Ganss,Tab0,Tab,Abd0,Abd,A,NewA) :- + ( Ganss = l(G,Lanss) -> + ( Val == true, Lanss = [d(G,Ds)] -> + assume_list(Ds,true,Tab0,Tab,Abd0,Abd,A,NewA) + ; Val == false, findall(Lit,member(d(G,[Lit]),Lanss),Ds) -> + assume_list(Ds,false,Tab0,Tab,Abd0,Abd,A,NewA) + ; Tab = Tab0, Abd = Abd0, A = NewA + ) + ; Tab = Tab0, Abd = Abd0, A = NewA + ). + +assume_list([],_Val,Tab,Tab,Abd,Abd,A,A). +assume_list([Lit|Lits],Val,Tab0,Tab,Abd0,Abd,A0,A) :- + assume_one(Lit,Val,Tab0,Tab1,Abd0,Abd1,A0,A1), + assume_list(Lits,Val,Tab1,Tab,Abd1,Abd,A1,A). + +/* assume_one(Lit,Val,Tab0,Tab,Abd0,Abd,A0,A): + Due to back propagation, Lit is assumed to be Val. + However, this assumption is carried out only if + Lit is a delayed literal of a ground call or most + general call. +*/ +assume_one(Ggoal-GH,_Val,Tab0,Tab,Abd0,Abd,A0,A) :- + Ggoal \== GH, + !, + Tab = Tab0, Abd = Abd0, A = A0. +assume_one(Lit,Val,Tab0,Tab,Abd0,Abd,A0,A) :- + ( Lit = G-G -> + GVal = Val + ; Lit = (\+G) -> + ( Val == true -> GVal = false; GVal = true ) + ; Lit = G -> + GVal = Val + ), + ( find(Abd0,G,V) -> % already assumed + ( V == GVal -> + Tab = Tab0, Abd = Abd0, A = A0 + ; fail + ) + ; find(Tab0,G,Gent), + ent_to_anss(Gent,Ganss), + ( failed(Ganss) -> % already known + ( GVal == true -> + fail + ; Tab = Tab0, Abd = Abd0, A = A0 + ) + ; succeeded(Ganss) -> % already known + ( GVal == false -> + fail + ; Tab = Tab0, Abd = Abd0, A = A0 + ) + ; addkey(Abd0,G,GVal,Abd1), % otherwise, propagate + propagate_forward(G,GVal,Tab0,Tab1,Abd1), + A0 = [G-G|A1], + propagate_backward(G,Ganss,GVal,Tab1,Tab,Abd1,Abd,A1,A) + ) + ). + +final_check(Abd,Tab0,Tab,DAbd,Alist) :- + check_consistency(Abd,Tab0,Tab,Alist0,Alist1), + add_dabd(DAbd,Alist1,[]), + sort(Alist0,Sorted), + listval_to_listlit(Sorted,Alist). + +listval_to_listlit([],[]). +listval_to_listlit([Val|Vlist],[Lit|Llist]) :- + val_to_lit(Val,Lit), + listval_to_listlit(Vlist,Llist). + +val_to_lit(G-true,G). +val_to_lit(G-false,\+G). + +/* check_consistency(Abd,Tab0,Tab,Alist0,Alist): + A proposition may be assumed to be true, but no true answer + is derived at the end, which is inconsistency. A proposition + may be assumed to be false, but has a true answer. The latter + case is checked when the true answer is derived. Here Abd + indicates the assumed truth values, and answers in Tab0 + indicate the derived values by a fixpoint computation of + forward chaining. + + Also at the end of a fixpoint computation, a subgoal may + have only delayed answers with positive literals. These + have to be deleted in order for Tab0/Tab to be used + correctly later. +*/ +check_consistency([],Tab,Tab,Alist,Alist). +check_consistency(l(G,Val),Tab0,Tab,Alist0,Alist) :- + updatevs(Tab0,G,Ent0,Ent,Tab), + Ent0 = e(Nodes,ANegs,Anss0,_Delay,Comp,Dfn,Slist), + Ent = e(Nodes,ANegs,Anss,false,Comp,Dfn,Slist), + ( Val == true -> + succeeded(Anss0), + Anss = l(G,[d(G,[])]), % delete answers with positive delays + Alist0 = [G-Val|Alist] + ; % Val == false -> + Anss = [], + Alist0 = [G-Val|Alist] + ). +check_consistency(n2(T1,_,T2),Tab0,Tab,Alist0,Alist) :- + check_consistency(T1,Tab0,Tab1,Alist0,Alist1), + check_consistency(T2,Tab1,Tab,Alist1,Alist). +check_consistency(n3(T1,_,T2,_,T3),Tab0,Tab,Alist0,Alist) :- + check_consistency(T1,Tab0,Tab1,Alist0,Alist1), + check_consistency(T2,Tab1,Tab2,Alist1,Alist2), + check_consistency(T3,Tab2,Tab,Alist2,Alist). + +add_dabd([],Alist,Alist). +add_dabd(l(G,Val),[G-Val|Alist],Alist). +add_dabd(n2(T1,_,T2),Alist0,Alist) :- + add_dabd(T1,Alist0,Alist1), + add_dabd(T2,Alist1,Alist). +add_dabd(n3(T1,_,T2,_,T3),Alist0,Alist) :- + add_dabd(T1,Alist0,Alist1), + add_dabd(T2,Alist1,Alist2), + add_dabd(T3,Alist2,Alist). + +/* oldt(QueryAtom,Table): top level call for SLG resolution. + It returns a table consisting of answers for each relevant + subgoal. For stable predicates, it basically extract the + relevant set of ground clauses by solving Prolog predicates + and other well-founded predicates. +*/ +oldt(Call,Tab) :- + new_init_call(Call,Ggoal,Ent,[],S1,1,Dfn1), + add_tab_ent(Ggoal,Ent,[],Tab1), + oldt(Call,Ggoal,Tab1,Tab,S1,_S,Dfn1,_Dfn,maxint-maxint,_Dep,0:[],_TP), + ( wfs_trace -> + nl, write('Final '), display_table(Tab), nl + ; true + ). + +/* oldt(Call,Ggoal,Tab0,Tab,Stack0,Stack,DFN0,DFN,Dep0,Dep,TP0,TP) + explores the initial set of edges, i.e., all the + program clauses for Call. Ggoal is of the form + Gcall-Gdfn, where Gcall is numbervar of Call and Gdfn + is the depth-first number of Gcall. Tab0/Tab,Stack0/Stack, + DFN0/DFN, and Dep0/Dep are accumulators for the table, + the stack of subgoals, the DFN counter, and the dependencies. + TP0/TP is the accumulator for newly created clauses during + the processing of general clauss with universal disjunctions + in the body. These clauses are created in order to guarantee + polynomial data complexity in processing clauses with + universal disjuntions in the body of a clause. The newly + created propositions are represented by numbers. +*/ +oldt(Call,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + ( number(Call) -> + TP0 = (_ : Tcl), + find(Tcl,Call,Clause), + edge_oldt(Clause,Ggoal,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1) + ; findall(rule(d(Call,[]),Body), + (new_slg_head(Call,Body,NewHead),call(NewHead)), + Frames), + map_oldt(Frames,Ggoal,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1) + ), + comp_tab_ent(Ggoal,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP). + +map_oldt([],_Ggoal,Tab,Tab,S,S,Dfn,Dfn,Dep,Dep,TP,TP). +map_oldt([Clause|Frames],Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + edge_oldt(Clause,Ggoal,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1), + map_oldt(Frames,Ggoal,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP). + +/* edge_oldt(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + Clause may be one of the following forms: + rule(d(H,Dlist),Blist) + rule(d(H,all(Dlist)),all(Blist)) + where the second form is for general clauses with a universal + disjunction of literals in the body. Dlist is a list of delayed + literals, and Blist is the list of literals to be solved. + Clause represents a directed edge from Ggoal to the left most + subgoal in Blist. +*/ +edge_oldt(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + Clause = rule(Ans,B), + ( B == [] -> + ans_edge(Ans,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + ; B = [Lit|_] -> + ( Lit = (\+N) -> + neg_edge(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + ; pos_edge(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + ) + ; B = all(Bl) -> + ( Bl == [] -> + ans_edge(Ans,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + ; Bl = [Lit|_], + ( Lit = (\+N) -> + aneg_edge(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + ; apos_edge(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + ) + ) + ). + +ans_edge(Ans,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + ( add_ans(Tab0,Ggoal,Ans,Nodes,Mode,Tab1) -> + ( Mode = new_head -> + returned_ans(Ans,Ggoal,RAns), + map_nodes(Nodes,RAns,Tab1,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + ; Mode = no_new_head -> + Tab = Tab1, S = S0, Dfn = Dfn0, Dep = Dep0, TP = TP0 + ) + ; Tab = Tab0, S = S0, Dfn = Dfn0, Dep = Dep0, TP = TP0 + ). + +neg_edge(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + Clause = rule(_,[\+N|_]), + ( ground(N) -> true + ; write('Flounder: '), write(\+N), nl, fail + ), + Node = (Ggoal:Clause), + Ngoal = N, % N is already ground + ( isprolog(N) -> % if N is a Prolog predicate + ( call(N) -> % then just call + Tab = Tab0, S = S0, Dfn = Dfn0, Dep = Dep0, TP = TP0 + ; apply_subst(Node,d(\+ N,[]),Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + ) + ; ( find(Tab0,Ngoal,Nent) -> + Tab2 = Tab0, S2 = S0, Dfn2 = Dfn0, Dep1 = Dep0, TP1 = TP0 + ; new_init_call(N,Ngoal,Ent,S0,S1,Dfn0,Dfn1), + add_tab_ent(Ngoal,Ent,Tab0,Tab1), + oldt(N,Ngoal,Tab1,Tab2,S1,S2,Dfn1,Dfn2,maxint-maxint,Ndep,TP0,TP1), + compute_mins(Dep0,Ndep,pos,Dep1), + find(Tab2,Ngoal,Nent) + ), + ent_to_comp(Nent,Ncomp), + ent_to_anss(Nent,Nanss), + ( succeeded(Nanss) -> + Tab = Tab2, S = S2, Dfn = Dfn2, Dep = Dep1, TP = TP1 + ; failed(Nanss), Ncomp == true -> + apply_subst(Node,d(\+N,[]),Tab2,Tab,S2,S,Dfn2,Dfn,Dep1,Dep,TP1,TP) + ; apply_subst(Node,d(\+N,[\+N]),Tab2,Tab,S2,S,Dfn2,Dfn,Dep1,Dep,TP1,TP) + ) + ). + +pos_edge(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + Clause = rule(_H,[N|_B]), + Node = (Ggoal:Clause), + ground(N,Ngoal), + ( isprolog(N) -> + findall(d(N,[]),call(N),Nanss), + map_anss_list(Nanss,Node,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + ; ( find(Tab0,Ngoal,Nent) -> + ent_to_comp(Nent,Ncomp), + ent_to_anss(Nent,Nanss), + ( Ncomp \== true -> + update_lookup_mins(Ggoal,Node,Ngoal,pos,Tab0,Tab1,Dep0,Dep1), + map_anss(Nanss,Node,Ngoal,Tab1,Tab,S0,S,Dfn0,Dfn,Dep1,Dep,TP0,TP) + ; % N is completed. + map_anss(Nanss,Node,Ngoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + ) + ; % otherwise N is new + new_pos_call(Ngoal,Node,Ent,S0,S1,Dfn0,Dfn1), + add_tab_ent(Ngoal,Ent,Tab0,Tab1), + oldt(N,Ngoal,Tab1,Tab2,S1,S,Dfn1,Dfn,maxint-maxint,Ndep,TP0,TP), + update_solution_mins(Ggoal,Ngoal,pos,Tab2,Tab,Ndep,Dep0,Dep) + ) + ). + +aneg_edge(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + Clause = rule(_H,all([\+N|_B])), + Node = (Ggoal:Clause), + ground(N,Ngoal), + ( isprolog(N) -> + findall(d(N,[]),call(N),Nanss), + return_to_disj_list(Nanss,Node,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + ; ( find(Tab0,Ngoal,Nent) -> + ent_to_comp(Nent,Ncomp), + ent_to_anss(Nent,Nanss), + ( Ncomp \== true -> + update_lookup_mins(Ggoal,Node,Ngoal,aneg,Tab0,Tab,Dep0,Dep), + S = S0, Dfn = Dfn0, TP = TP0 + ; % N is completed. + return_to_disj(Nanss,Node,Ngoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + ) + ; % otherwise N is new + new_aneg_call(Ngoal,Node,Ent,S0,S1,Dfn0,Dfn1), + add_tab_ent(Ngoal,Ent,Tab0,Tab1), + oldt(N,Ngoal,Tab1,Tab2,S1,S,Dfn1,Dfn,maxint-maxint,Ndep,TP0,TP), + update_solution_mins(Ggoal,Ngoal,pos,Tab2,Tab,Ndep,Dep0,Dep) + ) + ). + +apos_edge(Clause,Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + Clause = rule(d(H,D),all([N|B])), + ( ground(N) -> true + ; write('Flounder in a universal disjunction: '), + write(N), + nl, + fail + ), + pos_edge(rule(d(H,[]),[N]),Ggoal,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1), + edge_oldt(rule(d(H,D),all(B)),Ggoal,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP). + +apply_subst(Ggoal:Cl,d(An,Vr),Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + copy_term(Cl,rule(d(Ac,Vc),Body)), + ( Body = [Call|NBody] -> + Call = An, + append(Vr,Vc,Vn) + ; Body = all([Call|Calls]), + % Call = An, % An is the numbervar-ed version of Call. + ( Vc == [] -> + Vn = all(Vr) + ; Vc = all(Vc0), + append(Vr,Vc0,Vn0), + Vn = all(Vn0) + ), + NBody = all(Calls) + ), + edge_oldt(rule(d(Ac,Vn),NBody),Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP). + +/* map_nodes(Nodes,Ans,....): + return Ans to each of the waiting nodes in Nodes, where a node + is of the form Ggoal:Clause. +*/ +map_nodes([],_Ans,Tab,Tab,S,S,Dfn,Dfn,Dep,Dep,TP,TP). +map_nodes([Node|Nodes],Ans,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + apply_subst(Node,Ans,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1), + map_nodes(Nodes,Ans,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP). + +map_anss([],_Node,_Ngoal,Tab,Tab,S,S,Dfn,Dfn,Dep,Dep,TP,TP). +map_anss(l(_GH,Lanss),Node,Ngoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + ( Lanss == [] -> + Tab = Tab0, S = S0, Dfn = Dfn0, Dep = Dep0, TP = TP0 + ; Lanss = [Ans|_], + returned_ans(Ans,Ngoal,RAns), + apply_subst(Node,RAns,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + ). +map_anss(n2(T1,_,T2),Node,Ngoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + map_anss(T1,Node,Ngoal,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1), + map_anss(T2,Node,Ngoal,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP). +map_anss(n3(T1,_,T2,_,T3),Node,Ngoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + map_anss(T1,Node,Ngoal,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1), + map_anss(T2,Node,Ngoal,Tab1,Tab2,S1,S2,Dfn1,Dfn2,Dep1,Dep2,TP1,TP2), + map_anss(T3,Node,Ngoal,Tab2,Tab,S2,S,Dfn2,Dfn,Dep2,Dep,TP2,TP). + +map_anss_list([],_Node,Tab,Tab,S,S,Dfn,Dfn,Dep,Dep,TP,TP). +map_anss_list([Ans|Lanss],Node,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + apply_subst(Node,Ans,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1), + map_anss_list(Lanss,Node,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP). + +/* return_to_disj(Nanss,Node,Ngoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + Nanss: an answer table for Ngoal + Node: is of the form (Ggoal:Clause), where Clause is of the form + rule(d(H,D),all([\+N|B])) + It carries out resolution of each answer with Clause, and constructs + a new clause rule(Head,NBody), where the body is basically a + conjunction of all the resolvents. If a resolvent is a disjunction + or a non-ground literal, a new proposition is created (which is + actually represented by a number), which has a clause whose body + is the resolvent. +*/ +return_to_disj(Nanss,Node,Ngoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + Node = (Ggoal : Clause), + Clause = rule(Head,all(Body)), + TP0 = (N0 : Tcl0), + negative_return_all(Nanss,Body,Ngoal,NBody,[],N0,N,Tcl0,Tcl), + TP1 = (N : Tcl), + edge_oldt(rule(Head,NBody),Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP1,TP). + +negative_return_all([],_Body,_Ngoal,NBody,NBody,N,N,Tcl,Tcl). +negative_return_all(l(_GH,Lanss),Body,Ngoal,NBody0,NBody,N0,N,Tcl0,Tcl) :- + ( Lanss == [] -> + NBody0 = NBody, N = N0, Tcl = Tcl0 + ; Lanss = [Ans|_], + negative_return_one(Ans,Body,Ngoal,NBody0,NBody,N0,N,Tcl0,Tcl) + ). +negative_return_all(n2(T1,_,T2),Body,Ngoal,NBody0,NBody,N0,N,Tcl0,Tcl) :- + negative_return_all(T1,Body,Ngoal,NBody0,NBody1,N0,N1,Tcl0,Tcl1), + negative_return_all(T2,Body,Ngoal,NBody1,NBody,N1,N,Tcl1,Tcl). +negative_return_all(n3(T1,_,T2,_,T3),Body,Ngoal,NBody0,NBody,N0,N,Tcl0,Tcl) :- + negative_return_all(T1,Body,Ngoal,NBody0,NBody1,N0,N1,Tcl0,Tcl1), + negative_return_all(T2,Body,Ngoal,NBody1,NBody2,N1,N2,Tcl1,Tcl2), + negative_return_all(T3,Body,Ngoal,NBody2,NBody,N2,N,Tcl2,Tcl). + +negative_return_one(d(H,Tv),Body,Ngoal,NBody0,NBody,N0,N,Tcl0,Tcl) :- + copy_term(Body,[\+Call|Bs]), + H = Call, + ( Tv == [] -> % no delay + ( (Bs = [Lit], ground(Lit)) -> % resovlent is a ground literal + NBody0 = [Lit|NBody], + N = N0, Tcl = Tcl0 + ; Lit = N0, % otherwise, replace it with a number + N is N0+1, + NBody0 = [Lit|NBody], + Clause = rule(d(Lit,[]),all(Bs)), + add_tab_ent(Lit,Clause,Tcl0,Tcl) + ) + ; ( ground(H) -> % if there is delay, always replace with number + NewTv = [\+H] + ; ground(H,GH), + NewTv = [Ngoal - (\+GH)] + ), + Lit = N0, + N is N0+1, + NBody0 = [Lit|NBody], + Clause = rule(d(Lit,all(NewTv)),all(Bs)), + add_tab_ent(Lit,Clause,Tcl0,Tcl) + ). + +return_to_disj_list(Lanss,Node,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + Node = (Ggoal : Clause), + Clause = rule(Head,all(Body)), + TP0 = (N0 : Tcl0), + negative_return_list(Lanss,Body,NBody,[],N0,N,Tcl0,Tcl), + TP1 = (N : Tcl), + edge_oldt(rule(Head,NBody),Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP1,TP). + +negative_return_list([],_Body,NBody,NBody,N,N,Tcl,Tcl). +negative_return_list([d(H,[])|Lanss],Body,NBody0,NBody,N0,N,Tcl0,Tcl) :- + copy_term(Body,[\+Call|Bs]), + H = Call, + ( Bs = [Lit], ground(Lit) -> + NBody0 = [Lit|NBody1], + N1 = N0, Tcl1 = Tcl0 + ; Lit = N0, + N1 is N0+1, + NBody0 = [Lit|NBody1], + Clause = rule(d(Lit,[]),all(Bs)), + add_tab_ent(Lit,Clause,Tcl0,Tcl1) + ), + negative_return_list(Lanss,Body,NBody1,NBody,N1,N,Tcl1,Tcl). + +/* comp_tab_ent(Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) + check if Ggoal and subgoals on top of it on the stack are + completely evaluated. +*/ +comp_tab_ent(Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + ( Dep0 == maxint-maxint -> + process_pos_scc(Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep,TP0,TP) + ; update_mins(Ggoal,Dep0,pos,Tab0,Tab1,Gdfn,Gdep), + Gdep = Gpmin-Gnmin, + ( Gdfn @=< Gpmin, Gnmin == maxint -> + process_pos_scc(Ggoal,Tab1,Tab,S0,S,Dfn0,Dfn,Dep,TP0,TP) + ; Gdfn @=< Gpmin, Gdfn @=< Gnmin -> + process_neg_scc(Ggoal,Tab1,Tab,S0,S,Dfn0,Dfn,Dep,TP0,TP) + ; Tab = Tab1, S0 = S, Dfn = Dfn0, Dep = Gdep, TP = TP0 + ) + ). + +process_pos_scc(Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep,TP0,TP) :- + ( wfs_trace -> + write('Stack: '), nl, display_stack(S0,Tab0), + write('Completed call found: '), write(Ggoal), nl, + display_table(Tab0), + write('Completing calls ......'), nl, nl + ; true + ), + pop_subgoals(Ggoal,S0,S1,[],Scc), + complete_comp(Scc,Tab0,Tab1,Alist,[]), + return_aneg_nodes(Alist,Tab1,Tab,S1,S,Dfn0,Dfn,maxint-maxint,Dep,TP0,TP). + +/* pop_subgoals(Ggoal,S0,S,Scc0,Scc) + pop off the stack subgoals up to and including Ggoal +*/ +pop_subgoals(Ggoal,S0,S,Scc0,Scc) :- + S0 = [Sent|S1], + ( Ggoal == Sent -> + S = S1, + Scc = [Sent|Scc0] + ; pop_subgoals(Ggoal,S1,S,[Sent|Scc0],Scc) + ). + +/* complete_comp(Scc,Tab0,Tab,Alist0,Alist): + process the list Scc of subgoals that are + completely evaluated. +*/ +complete_comp([],Tab,Tab,Alist,Alist). +complete_comp([Ggoal|Scc],Tab0,Tab,Alist0,Alist) :- + complete_one(Ggoal,Tab0,Tab1,Alist0,Alist1), + complete_comp(Scc,Tab1,Tab,Alist1,Alist). + +/* complete_one(Ggoal,Tab0,Tab,Alist0,Alist) + process one subgoal that has been completely + evaluated: + 1. set its Nodes and Negs to [] and Comp to true; + 2. simplify its answers and set up links + for further simplification later; + 3. use the truth value of Ggoal to simplify + answers of other complete subgoals (possibly + including itself). + 4. set Alist0/Alist: a list of negation nodes with + universal disjunctions with associated answers + for the selected negative literal. +*/ +complete_one(Ggoal,Tab0,Tab,Alist0,Alist) :- + updatevs(Tab0,Ggoal,Ent0,Ent,Tab1), + Ent0 = e(_Nodes,ANegs,Anss0,Delay,_Comp,Gdfn,Slist0), + Ent = e([],[],Anss,Delay,true,Gdfn,Slist), + ( Delay == true -> + reduce_ans(Anss0,Anss,Tab0), + setup_simp_links(Anss,Ggoal,Slist0,Slist1,Tab1,Tab2) + ; % Delay == false + Anss = Anss0, + Tab2 = Tab1, + Slist1 = Slist0 + ), + extract_known(Ggoal,Anss,Slist1,Slist,Klist), + simplify(Klist,Tab2,Tab,[]), + ( ANegs == [] -> + Alist0 = Alist + ; Alist0 = [(Anss,Ggoal)-ANegs|Alist] + ). + +setup_simp_links([],_,Slist,Slist,Tab,Tab). +setup_simp_links(l(GH,Lanss),Ggoal,Slist0,Slist,Tab0,Tab) :- + setup_simp_links_list(Lanss,Ggoal-GH,Ggoal,Slist0,Slist,Tab0,Tab). +setup_simp_links(n2(T1,_,T2),Ggoal,Slist0,Slist,Tab0,Tab) :- + setup_simp_links(T1,Ggoal,Slist0,Slist1,Tab0,Tab1), + setup_simp_links(T2,Ggoal,Slist1,Slist,Tab1,Tab). +setup_simp_links(n3(T1,_,T2,_,T3),Ggoal,Slist0,Slist,Tab0,Tab) :- + setup_simp_links(T1,Ggoal,Slist0,Slist1,Tab0,Tab1), + setup_simp_links(T2,Ggoal,Slist1,Slist2,Tab1,Tab2), + setup_simp_links(T3,Ggoal,Slist2,Slist,Tab2,Tab). + +/* setup_simp_link_list(Lanss,Ggoal-GH,Ggoal,Slist0,Slist,Tab0,Tab) + Ggoal-GH is to tell what portion of answers of Ggoal can be + simplified. +*/ +setup_simp_links_list([],_,_,Slist,Slist,Tab,Tab). +setup_simp_links_list([d(_,D)|Anss],GHead,Ggoal,Slist0,Slist,Tab0,Tab) :- + ( D = all(Ds) -> + true + ; Ds = D + ), + links_from_one_delay(Ds,GHead,Ggoal,Slist0,Slist1,Tab0,Tab1), + setup_simp_links_list(Anss,GHead,Ggoal,Slist1,Slist,Tab1,Tab). + +/* A link ((Ggoal-GH):Lit) in an entry for Ngoal means that + the literal Lit in an answer with head GH in Ggoal can + be potentially simplified if we know answers for Ngoal. +*/ +links_from_one_delay([],_,_,Slist,Slist,Tab,Tab). +links_from_one_delay([D|Ds],GHead,Ggoal,Slist0,Slist,Tab0,Tab) :- + ( D = (\+ Ngoal) -> + ( Ggoal == Ngoal -> + Tab1 = Tab0, + Slist1 = [GHead:D|Slist0] + ; add_link_to_ent(Tab0,Ngoal,GHead:D,Tab1), + Slist1 = Slist0 + ) + ; D = (Ngoal-_) -> + ( Ggoal == Ngoal -> + Slist1 = [GHead:D|Slist0], + Tab1 = Tab0 + ; Slist1 = Slist0, + add_link_to_ent(Tab0,Ngoal,GHead:D,Tab1) + ) + ), + links_from_one_delay(Ds,GHead,Ggoal,Slist1,Slist,Tab1,Tab). + +/* extract_known(Ggoal,Anss,Links,Slist,Klist): + Given Ggoal and its answers Anss, and its + simplification Links, it partitioned Links + into Slist and Klist of links, where Klist + is a list of links that are known to be either + true or false. + + Klist is either of the form Val-Links, or a + list of the form Val-Link. In case of non-ground + calls, the corresponding portion of Anss has to + be searched. +*/ +extract_known(Ggoal,Anss,Links,Slist,Klist) :- + ( failed(Anss) -> + Klist = fail-Links, + Slist = [] + ; Anss = l(GH,Lanss) -> + ( Ggoal == GH -> % Ground or most general call + ( memberchk(d(_,[]),Lanss) -> + Klist = succ-Links, + Slist = [] + ; Klist = [], + Slist = Links + ) + ; % non-ground call + extract_known_anss(Links,Anss,[],Slist,[],Klist) + ) + ; % non-ground call + extract_known_anss(Links,Anss,[],Slist,[],Klist) + ). + +extract_known_anss([],_,Slist,Slist,Klist,Klist). +extract_known_anss([Link|Links],Anss,Slist0,Slist,Klist0,Klist) :- + Link = (_:Lit), + extract_lit_val(Lit,Anss,true,Val), + ( Val == undefined -> + Slist1 = [Link|Slist0], + Klist1 = Klist0 + ; Slist1 = Slist0, + Klist1 = [Val-Link|Klist0] + ), + extract_known_anss(Links,Anss,Slist1,Slist,Klist1,Klist). + +/* extract_lit_val(Lit,Anss,Comp,Val): + extract the truth value of Lit according to Anss and Comp. + In case of a non-ground calls, the corresponding portion + of Anss has to be searched. +*/ +extract_lit_val(Lit,Anss,Comp,Val) :- + ( Lit = (\+ _) -> + ( succeeded(Anss) -> + Val = fail + ; failed(Anss), Comp == true -> + Val = succ + ; Val = undefined + ) + ; Lit = (_ - (\+GH)) -> + ( find(Anss,GH,Lanss) -> + ( (\+ \+ memberchk(d(GH,[]),Lanss)) -> + Val = fail + ; Lanss == [], Comp == true -> + Val = succ + ; Val = undefined + ) + ; ( Comp == true -> + Val = succ + ; Val = undefined + ) + ) + ; Lit = (_-GH) -> + ( find(Anss,GH,Lanss) -> + ( (\+ \+ memberchk(d(GH,[]),Lanss)) -> + Val = succ + ; Lanss == [], Comp == true -> + Val = fail + ; Val = undefined + ) + ; ( Comp == true -> + Val = fail + ; Val = undefined + ) + ) + ). + +/* simplify(KnownLinks,Tab0,Tab,Abd): + Given a list of KnownLinks, Tab0 and Abd, + it tries to simplify answers according to + KnownLinks. When a subgoal is found to be + true or false according to answers, + consistency with assumed truth values in Abd + is checked. +*/ +simplify([],Tab,Tab,_Abd). +simplify([Val-Link|Klist],Tab0,Tab,Abd) :- + simplify_one(Val,Link,Tab0,Tab1,Abd), + simplify(Klist,Tab1,Tab,Abd). +simplify(Val-Links,Tab0,Tab,Abd) :- + simplify_list(Links,Val,Tab0,Tab,Abd). + +simplify_list([],_,Tab,Tab,_Abd). +simplify_list([Link|Links],Val,Tab0,Tab,Abd) :- + Link = (_ : Lit), + ( ( Lit = (\+_); Lit = (_ - (\+_)) ) -> + ( Val = fail -> LVal = succ; LVal = fail ) + ; LVal = Val + ), + simplify_one(LVal,Link,Tab0,Tab1,Abd), + simplify_list(Links,Val,Tab1,Tab,Abd). + +simplify_one(Val,Link,Tab0,Tab,Abd) :- + Link = ((Ngoal - GH) : Lit), + updatevs(Tab0,Ngoal,Ent0,Ent,Tab1), + Ent0 = e(Nodes,ANegs,Anss0,Delay,Comp,Dfn,Slist0), + Ent = e(Nodes,ANegs,Anss,Delay,Comp,Dfn,Slist), + ( updatevs(Anss0,GH,Lanss0,Lanss,Anss) -> + simplify_anss(Lanss0,Val,Lit,[],Lanss,C), + ( C == true -> + ( find(Abd,GH,Aval) -> + ( Aval == true, Lanss == [] -> % deduced result inconsistent with assumption + fail + ; Aval == false, memberchk( d(_ , []), Lanss) -> + fail + ; true + ) + ; true + ), + extract_known(Ngoal,Anss,Slist0,Slist,Klist), + simplify(Klist,Tab1,Tab,Abd) + ; Tab = Tab0 + ) + ; Tab = Tab0 + ). + +/* simplify_anss(List,Val,Lit,Lanss0,Lanss,C): + Given a List of answers, Val of Lit, it + simplifies the List and construct a new list + Lanss0/Lanss of answers. C is unified with true + if some simplification is carried out. + + As soon as a true answer is detected, all + other answers with the same head are deleted. +*/ +simplify_anss([],_,_,Anss,Anss,_). +simplify_anss([Ans|Rest],Val,Lit,Anss0,Anss,C) :- + ( simplified_ans(Ans,Val,Lit,NewAns,C) -> + ( NewAns = d(_,[]) -> + Anss = [NewAns] + ; Anss1 = [NewAns|Anss0], + simplify_anss(Rest,Val,Lit,Anss1,Anss,C) + ) + ; C = true, + simplify_anss(Rest,Val,Lit,Anss0,Anss,C) + ). + +simplified_ans(Ans,Val,Lit,NewAns,C) :- + Ans = d(H,Ds), + ( Ds == [] -> + NewAns = Ans + ; Ds = all(Dlist) -> + ( Val == fail -> + delete_lit(Dlist,Lit,NewDlist,[],C), + ( NewDlist == [] -> + fail + ; NewAns = d(H,all(NewDlist)) + ) + ; % Val == succ -> + ( memberchk(Lit,Dlist) -> + NewAns = d(H,[]), + C = true + ; NewAns = Ans + ) + ) + ; % Ds is a conjunction + ( Val == fail -> + ( memberchk(Lit,Ds) -> + fail + ; NewAns = Ans + ) + ; % Val == succ -> + delete_lit(Ds,Lit,NewDs,[],C), + NewAns = d(H,NewDs) + ) + ). + +/* delete_lit(Delays,Lit,Ds0,Ds,C): + deletes Lit from Delays. Delays is + a list of delayed literals and it + is guaranteed to have no duplicates. +*/ +delete_lit([],_,Ds,Ds,_). +delete_lit([D|Rest],Lit,Ds0,Ds,C) :- + ( D == Lit -> + Ds0 = Rest, + C = true + ; Ds0 = [D|Ds1], + delete_lit(Rest,Lit,Ds1,Ds,C) + ). + +% return answers to negative nodes within universal disjunctions +return_aneg_nodes([],Tab,Tab,S,S,Dfn,Dfn,Dep,Dep,TP,TP). +return_aneg_nodes([(Anss,Ngoal)-ANegs|Alist],Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + map_anegs(ANegs,Anss,Ngoal,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1), + return_aneg_nodes(Alist,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP). + +map_anegs([],_Anss,_Ngoal,Tab,Tab,S,S,Dfn,Dfn,Dep,Dep,TP,TP). +map_anegs([Node|ANegs],Anss,Ngoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + return_to_disj(Anss,Node,Ngoal,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1), + map_anegs(ANegs,Anss,Ngoal,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP). + +/* process a component of subgoals that may be involved in + negative loops. +*/ +process_neg_scc(Ggoal,Tab0,Tab,S0,S,Dfn0,Dfn,Dep,TP0,TP) :- + ( wfs_trace -> + write('Stack: '), nl, display_stack(S0,Tab0), + write('Possible negative loop: '), write(Ggoal), nl, + display_table(Tab0) + ; true + ), + extract_subgoals(Ggoal,S0,Scc,[]), + reset_nmin(Scc,Tab0,Tab1,Ds,[]), + ( wfs_trace -> + write('Delaying: '), display_dlist(Ds) + ; true + ), + delay_and_cont(Ds,Tab1,Tab2,S0,S1,Dfn0,Dfn1,maxint-maxint,Dep1,TP0,TP1), + recomp_scc(Scc,Tab2,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP). + +/* extract_subgoals(Ggoal,S0,Scc0,Scc) + extract subgoals that may be involved in negative loops, + but leave the stack of subgoals intact. +*/ +extract_subgoals(Ggoal,[Sent|S],[Sent|Scc0],Scc) :- + ( Ggoal == Sent -> + Scc0 = Scc + ; extract_subgoals(Ggoal,S,Scc0,Scc) + ). + +/* reset_nmin(Scc,Tab0,Tab,Dnodes0,Dnodes) + reset NegLink and collect all waiting nodes that need to be + delayed. Dnodes0/Dnodes is a difference list. +*/ +reset_nmin([],Tab,Tab,Ds,Ds). +reset_nmin([Ggoal|Scc],Tab0,Tab,Ds0,Ds) :- + get_and_reset_negs(Tab0,Ggoal,ANegs,Tab1), + ( ANegs == [] -> + Ds0 = Ds1 + ; Ds0 = [Ggoal-ANegs|Ds1] + ), + reset_nmin(Scc,Tab1,Tab,Ds1,Ds). + +delay_and_cont([],Tab,Tab,S,S,Dfn,Dfn,Dep,Dep,TP,TP). +delay_and_cont([Ggoal-Negs|Dnodes],Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + map_nodes(Negs,d(\+Ggoal,[\+Ggoal]),Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1), + delay_and_cont(Dnodes,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP). + +recomp_scc([],Tab,Tab,S,S,Dfn,Dfn,Dep,Dep,TP,TP). +recomp_scc([Ggoal|Scc],Tab0,Tab,S0,S,Dfn0,Dfn,Dep0,Dep,TP0,TP) :- + comp_tab_ent(Ggoal,Tab0,Tab1,S0,S1,Dfn0,Dfn1,Dep0,Dep1,TP0,TP1), + recomp_scc(Scc,Tab1,Tab,S1,S,Dfn1,Dfn,Dep1,Dep,TP1,TP). + +/* routines for incremental update of dependency information +*/ + +/* update_mins(Ggoal,Dep,Sign,Tab0,Tab,Gdfn,Gdep) + update the PosLink and NegLink of Ggoal according to + Dep and Sign +*/ +update_mins(Ggoal,Dep,Sign,Tab0,Tab,Gdfn,Gdep) :- + Ent0 = e(Nodes,ANegs,Anss,Delay,Comp,Gdfn:Gdep0,Slist), + Ent = e(Nodes,ANegs,Anss,Delay,Comp,Gdfn:Gdep,Slist), + updatevs(Tab0,Ggoal,Ent0,Ent,Tab), + compute_mins(Gdep0,Dep,Sign,Gdep). + +/* update_lookup_mins(Ggoal,Node,Ngoal,Sign,Tab0,Tab,Dep0,Dep) + There is a lookup edge (Node) from Ggoal to Ngoal + with Sign. It adds Node to the corresponding waiting list + in Ngoal and then update the dependencies of Ggoal. +*/ +update_lookup_mins(Ggoal,Node,Ngoal,Sign,Tab0,Tab,Dep0,Dep) :- + updatevs(Tab0,Ngoal,Ent0,Ent,Tab1), + ( Sign == pos -> + pos_to_newent(Ent0,Ent,Node) + ; Sign == aneg -> + aneg_to_newent(Ent0,Ent,Node) + ), + Ent0 = e(_,_,_,_,_,_Ndfn:Ndep,_), + compute_mins(Dep0,Ndep,Sign,Dep), + update_mins(Ggoal,Ndep,Sign,Tab1,Tab,_,_). + +/* update_solution_mins(Ggoal,Ngoal,Sign,Tab0,Tab,Ndep,Dep0,Dep) + There is an edge with Sign from Ggoal to Ngoal, where Ngoal is + a new subgoal. Ndep is the final dependency information of + Ngoal. Dep0/Dep is for the most recent enclosing new call. + This predicate is called after Ngoal is solved. +*/ +update_solution_mins(Ggoal,Ngoal,Sign,Tab0,Tab,Ndep,Dep0,Dep) :- + find(Tab0,Ngoal,Nent), + ent_to_comp(Nent,Ncomp), + ( Ncomp == true -> + ( Ndep == maxint-maxint -> + Tab = Tab0, Dep = Dep0 + ; update_mins(Ggoal,Ndep,pos,Tab0,Tab,_,_), + compute_mins(Dep0,Ndep,pos,Dep) + ) + ; update_mins(Ggoal,Ndep,Sign,Tab0,Tab,_,_), + compute_mins(Dep0,Ndep,Sign,Dep) + ). + +compute_mins(Gpmin-Gnmin,Npmin-Nnmin,Sign,Newpmin-Newnmin) :- + ( Sign == pos -> + min(Gpmin,Npmin,Newpmin), + min(Gnmin,Nnmin,Newnmin) + ; % (Sign == neg; Sign == aneg) -> + Newpmin=Gpmin, + min(Gnmin,Npmin,Imin), + min(Imin,Nnmin,Newnmin) + ). + +min(X,Y,M) :- ( X @< Y -> M=X; M=Y ). + +%%%%%%%%%%%%%%% Local table manipulation predicates %%%%%%%%%% + +/* Table Entry Structure: + For each Call, its table entry is identified with its number-vared + version -- Ggoal. Its value is a term of the form + + e(Nodes,ANegs,Anss,Delay,Comp,Dfn:Dep,Slist) + + where + Nodes: positive suspension list + ANegs: negative suspension list (for universal disjunction clauss) + Anss: another table. + Delay: whether Anss contains any answer with delay + Comp: whether Call is completely evaluated or not + Dfn: depth-first number of Gcall + Dep: (PosLink-NegLink) --- dependency information + Slist: a list of nodes whose answers may be simplified + if the truth value of Ggoal is known. Each element of Slist + is of the form (Ngoal-GH):Literal. + Stack Entry Structure: + Ggoal +*/ + +/* routines for accessing individual fields of an entry +*/ +ent_to_nodes(e(Nodes,_,_,_,_,_,_),Nodes). +ent_to_anegs(e(_,ANegs,_,_,_,_,_),ANegs). +ent_to_anss(e(_,_,Anss,_,_,_,_),Anss). +ent_to_delay(e(_,_,_,Delay,_,_,_),Delay). +ent_to_comp(e(_,_,_,_,Comp,_,_),Comp). +ent_to_dfn(e(_,_,_,_,_,Dfn,_),Dfn). +ent_to_slist(e(_,_,_,_,_,_,Slist),Slist). + +get_and_reset_negs(Tab0,Ggoal,ANegs,Tab) :- + Ent0 = e(Nodes,ANegs,Anss,Delay,Comp,Gdfn: (Gpmin - _),Slist), + Ent = e(Nodes,[],Anss,Delay,Comp,Gdfn:Gpmin-maxint,Slist), + updatevs(Tab0,Ggoal,Ent0,Ent,Tab). + +/* adding a new table entry +*/ +add_tab_ent(Ggoal,Ent,Tab0,Tab) :- + addkey(Tab0,Ggoal,Ent,Tab). + +/* The following three routines are for creating + new calls +*/ +/* a new call with empty suspensions +*/ +new_init_call(Call,Ggoal,Ent,S0,S,Dfn0,Dfn) :- + ground(Call,Ggoal), + S = [Ggoal|S0], + Dfn is Dfn0+1, + Ent = e([],[],[],false,false,Dfn0:Dfn0-maxint,[]). + +/* a new call with an initial negative suspension from + inside a universal disjunction +*/ +new_aneg_call(Ngoal,Neg,Ent,S0,S,Dfn0,Dfn) :- + S = [Ngoal|S0], + Dfn is Dfn0+1, + Ent = e([],[Neg],[],false,false,Dfn0:Dfn0-maxint,[]). + +/* a new call with an initial positive suspension +*/ +new_pos_call(Ngoal,Node,Ent,S0,S,Dfn0,Dfn) :- + S = [Ngoal|S0], + Dfn is Dfn0+1, + Ent = e([Node],[],[],false,false,Dfn0:Dfn0-maxint,[]). + +/* routines for adding more information to a + table entry. +*/ +aneg_to_newent(Ent0,Ent,ANeg) :- + Ent0 = e(Nodes,ANegs,Anss,Delay,Comp,Dfn,Slist), + Ent = e(Nodes,[ANeg|ANegs],Anss,Delay,Comp,Dfn,Slist). + +pos_to_newent(Ent0,Ent,Node) :- + Ent0 = e(Nodes,ANegs,Anss,Delay,Comp,Dfn,Slist), + Ent = e([Node|Nodes],ANegs,Anss,Delay,Comp,Dfn,Slist). + +add_link_to_ent(Tab0,Ggoal,Link,Tab) :- + updatevs(Tab0,Ggoal,Ent0,Ent,Tab), + link_to_newent(Ent0,Ent,Link). + +link_to_newent(Ent0,Ent,Link) :- + Ent0 = e(Nodes,ANegs,Anss,Delay,Comp,Dfn,Slist), + Ent = e(Nodes,ANegs,Anss,Delay,Comp,Dfn,[Link|Slist]). + +/* routines for manipulating answers */ +ansstree_to_list([],L,L). +ansstree_to_list(l(_GH,Lanss),L0,L) :- + attach(Lanss,L0,L). +ansstree_to_list(n2(T1,_M,T2),L0,L) :- + ansstree_to_list(T1,L0,L1), + ansstree_to_list(T2,L1,L). +ansstree_to_list(n3(T1,_M2,T2,_M3,T3),L0,L) :- + ansstree_to_list(T1,L0,L1), + ansstree_to_list(T2,L1,L2), + ansstree_to_list(T3,L2,L). + +attach([],L,L). +attach([d(H,B)|R],[X|L0],L) :- + ( B == [] -> + X = H + ; X = (H <- B) + ), + attach(R,L0,L). + +member_anss(Ans,Anss) :- + member_anss_1(Anss,Ans). + +member_anss_1(l(_,Lanss),Ans) :- + member(Ans,Lanss). +member_anss_1(n2(T1,_,T2),Ans) :- + ( member_anss_1(T1,Ans) + ; member_anss_1(T2,Ans) + ). +member_anss_1(n3(T1,_,T2,_,T3),Ans) :- + ( member_anss_1(T1,Ans) + ; member_anss_1(T2,Ans) + ; member_anss_1(T3,Ans) + ). + +/* failed(Anss): Anss is empty */ +failed([]). +failed(l(_,[])). + +/* succeeded(Anss): Anss contains a single definite answer */ +succeeded(l(_,Lanss)) :- + memberchk(d(_,[]),Lanss). + +/* add_ans(Tab0,Goal,Ans,Nodes,Mode,Tab): + If Ans is not subsumed by any existing answer then + Ans is added to Anss(Goal); + If some existing answer also has head H then + Mode = no_new_head + else + Mode = new_head + else + fail. +*/ +add_ans(Tab0,Ggoal,Ans,Nodes,Mode,Tab) :- + updatevs(Tab0,Ggoal,Ent0,Ent,Tab), + Ans = d(H,Ds), + ( Ds == [] -> + new_ans_ent(Ent0,Ent,Ans,Nodes,Mode) + ; setof(X,member(X,Ds),NewDs), + new_ans_ent(Ent0,Ent,d(H,NewDs),Nodes,Mode) + ). + +new_ans_ent(Ent0,Ent,Ans,Nodes,Mode) :- + Ent0 = e(Nodes,ANegs,Anss0,Delay0,Comp,Dfn,Slist), + Ent = e(Nodes,ANegs,Anss,Delay,Comp,Dfn,Slist), + Ans = d(H,D), + ground(H,GH), + ( updatevs(Anss0,GH,Lanss0,Lanss,Anss) -> + ( D == [] -> + \+(memberchk(d(_,[]),Lanss0)), + Lanss = [Ans] + ; not_subsumed_ans(Ans,Lanss0), + Lanss = [Ans|Lanss0] + ), + Mode = no_new_head + ; addkey(Anss0,GH,[Ans],Anss), + Mode = new_head + ), + ( D == [] -> + Delay = Delay0 + ; Delay = true + ). + +/* returned_ans(Ans,Ggoal,RAns): + determines whether SLG resolution or SLG factoring should + be applied. +*/ +returned_ans(d(H,Tv),Ggoal,d(H,NewTv)) :- + ( Tv = [] -> + NewTv = [] + ; ground(H,GH), + NewTv = [Ggoal-GH] + ). + +% reduce a list of answers, by reducing delay list, and by subsumption +reduce_ans(Anss0,Anss,Tab) :- + reduce_completed_ans(Anss0,Anss,Tab). + +% simplify all the delay lists in a list of answers. +reduce_completed_ans([],[],_Tab). +reduce_completed_ans(l(GH,Lanss0),l(GH,Lanss),Tab) :- + reduce_completed_anslist(Lanss0,[],Lanss,Tab). +reduce_completed_ans(n2(T1,M,T2),n2(NT1,M,NT2),Tab) :- + reduce_completed_ans(T1,NT1,Tab), + reduce_completed_ans(T2,NT2,Tab). +reduce_completed_ans(n3(T1,M2,T2,M3,T3),n3(NT1,M2,NT2,M3,NT3),Tab) :- + reduce_completed_ans(T1,NT1,Tab), + reduce_completed_ans(T2,NT2,Tab), + reduce_completed_ans(T3,NT3,Tab). + +reduce_completed_anslist([],Lanss,Lanss,_Tab). +reduce_completed_anslist([d(G,D0)|List],Lanss0,Lanss,Tab) :- + ( D0 = all(Dlist1) -> + ( filter_delays(Dlist1,[],Dlist,disj,V,Tab) -> + ( V == true -> % true answer + Lanss = [d(G,[])] + ; Dlist == [] -> % false answer, ignore + reduce_completed_anslist(List,Lanss0,Lanss,Tab) + ; reduce_completed_anslist(List,[d(G,all(Dlist))|Lanss0],Lanss,Tab) + ) + ; reduce_completed_anslist(List,Lanss0,Lanss,Tab) + ) + ; ( filter_delays(D0,[],D,conj,_V,Tab) -> + ( D == [] -> + Lanss = [d(G,[])] + ; reduce_completed_anslist(List,[d(G,D)|Lanss0],Lanss,Tab) + ) + ; reduce_completed_anslist(List,Lanss0,Lanss,Tab) + ) + ). + +% simplify a delay list by the completed table: delete true negations, +% fail if a false one. +filter_delays([],Fds,Fds,_DC,_V,_Tab). +filter_delays([Lit|Ds],Fds0,Fds,DC,V,Tab) :- + lit_to_call(Lit,Gcall), + find(Tab,Gcall,Gent), + ent_to_comp(Gent,Gcomp), + ent_to_anss(Gent,Ganss), + extract_lit_val(Lit,Ganss,Gcomp,Val), + ( Val == succ -> + ( DC == conj -> + filter_delays(Ds,Fds0,Fds,DC,V,Tab) + ; DC == disj -> + V = true + ) + ; Val == fail -> + ( DC == conj -> + fail + ; DC == disj -> + filter_delays(Ds,Fds0,Fds,DC,V,Tab) + ) + ; % Val == undefined + filter_delays(Ds,[Lit|Fds0],Fds,DC,V,Tab) + ). + +lit_to_call(\+G,G). +lit_to_call(Gcall-_,Gcall). + +not_subsumed_ans(Ans,Lanss0) :- + \+ + ( numbervars(Ans,0,_), + subsumed_ans1(Ans,Lanss0) + ). + +% succeed if answer is subsumed by any in list1 or 2. +subsumed_ans(Tv,List1,List2) :- + \+ + (numbervars(Tv,0,_), + \+ subsumed_ans1(Tv,List1), + \+ subsumed_ans1(Tv,List2) + ). + +% check if a delay is subsumed one of the element in the list +subsumed_ans1(d(T,V),List) :- + member(d(T,V1),List), + ( V1 == [] + ; V = all(LV), V1 = all(LV1) -> + subset(LV,LV1) + ; subset(V1,V) + ). + +/****************** auxiliary routines *******************/ +% variantchk/2 finds a variant in a list of atoms. +variantchk(G,[G1|_]) :- variant(G,G1), !. +variantchk(G,[_|L]) :- variantchk(G,L). + +variant(A, B) :- + A == B + -> true + ; subsumes_chk(A, B), + subsumes_chk(B, A), + A = B. +/* +subsumes_chk(General, Specific) :- + \+ ( numbervars(Specific, 0, _), + \+ General = Specific + ). +*/ +ground(O,C) :- ground(O) -> C = O ; copy_term(O,C), numbervars(C,0,_). + +subset([],_). +subset([E|L1],L2) :- memberchk(E,L2), subset(L1,L2). + +reverse([],R,R). +reverse([Goal|Scc],R0,R) :- reverse(Scc,[Goal|R0],R). + +/***************** routines for debugging *******************/ + +% Debugging help: pretty-prints strongly connected components and local table. +display_stack(Stack,Tab) :- + reverse(Stack,[],Rstack), + display_st(Rstack,Tab). +display_st([],_Tab). +display_st([Ggoal|Scc],Tab) :- + find(Tab,Ggoal,Ent), + ent_to_dfn(Ent,Dfn:Pmin-Nmin), + tab(2), + write(Ggoal-Dfn), + write(': '), + write('Pmin='), + write(Pmin), + write('; '), + write('Nmin='), + write(Nmin), + write('; '), + nl, + display_st(Scc,Tab). + +display_dlist([]) :- nl,nl. +display_dlist([Ngoal-_|Dlist]) :- + write(\+ Ngoal), + write('; '), + display_dlist(Dlist). + +display_table(Tab) :- + write('Table: '), + nl, + write_tab(Tab). + +display_final(Tab) :- + write(' Final Set of Answers: '), + nl, + display_final1(Tab). +display_final1([]). +display_final1(l(_,e(_,_,Anss,_,_,_,_))) :- + write_anss(Anss). +display_final1(n2(X,_,Y)) :- + display_final1(X), + display_final1(Y). +display_final1(n3(X,_,Y,_,Z)) :- + display_final1(X), + display_final1(Y), + display_final1(Z). + +write_tab([]). +write_tab(l(G,e(Nodes,ANegs,Anss,_,Comp,Dfn:_,_))) :- + write(' Entry: '), + write(G-Dfn), + write(': '), + ( Comp == true -> + write('Complete!') + ; write('Incomplete!') + ), + nl, + ( Anss == [] -> + true + ; write(' Anss: '), + nl, + write_anss(Anss) + ), + ( ( Comp == true; Nodes == []) -> + true + ; write(' Nodes: '), + write(Nodes), + nl + ), + ( ( Comp == true; ANegs == []) -> + true + ; write(' ANegs: '), + write(ANegs), + nl + ). +write_tab(n2(X,_,Y)) :- + write_tab(X), + write_tab(Y). +write_tab(n3(X,_,Y,_,Z)) :- + write_tab(X), + write_tab(Y), + write_tab(Z). + +write_anss([]). +write_anss(l(_,Lanss)) :- + write_anss_list(Lanss). +write_anss(n2(T1,_,T2)) :- + write_anss(T1), + write_anss(T2). +write_anss(n3(T1,_,T2,_,T3)) :- + write_anss(T1), + write_anss(T2), + write_anss(T3). + +write_anss_list([]). +write_anss_list([Ans|Anss]) :- + write_ans(Ans), + write_anss_list(Anss). + +write_ans(d(H,Ds)) :- + write(' '), + write(H), + ( Ds == [] -> + true + ; write(' :- '), + ( Ds = all([D|Ds1]) -> + ( D = (_-GH) -> + write(GH) + ; write(D) + ), + write_delay(Ds1,'; ') + ; Ds = [D|Ds1], + ( D = (_-GH) -> + write(GH) + ; write(D) + ), + write_delay(Ds1,', ') + ) + ), + write('.'), + nl. +write_delay([],_). +write_delay([D|Ds1],Sep) :- + write(Sep), + ( D = (_Gcall-GH) -> + write(GH) + ; write(D) + ), + write_delay(Ds1,Sep). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +/* +This is a set of routines that supports indexed tables. Tables +are sets of key-value_list pairs. With each key is associated a list +of values. It uses 2-3 trees for the index (modified by D.S. Warren +from Ivan Bratko: ``Prolog Programming for Artificial +Intelligence'', Addison Wesley, 1986). Operations are: + +Keys must be ground! (so numbervar them) + +addkey(Tree,Key,V,Tree1) adds a new Key with value V, returning + new Tree1. Fails if the key is already there. + +find(Tree,Key,V) finds the entry with Key and returns associated + values in V. + +updatevs(Tree,Key,OldV,NewV,Tree1) replaces value of entry with key + Key and value OldV with NewV. +*/ + + +addkey(Tree,X,V,Tree1) :- + ins2(Tree,X,V,Trees), + cmb0(Trees,Tree1). +addkey([],X,V,l(X,V)). + + +find(l(X,V),Xs,V) :- X == Xs. +find(n2(T1,M,T2),X,V) :- + M @=< X + -> find(T2,X,V) + ; find(T1,X,V). +find(n3(T1,M2,T2,M3,T3),X,V) :- + M2 @=< X + -> (M3 @=< X + -> find(T3,X,V) + ; find(T2,X,V) + ) + ; find(T1,X,V). + + +% updatevs(Tab0,X,Ov,Nv,Tab) updates Tab0 to Tab, by replacing +% Ov of entry with key X by Nv. +/* +updatevs(Tab0,X,Ov,Nv,Tab) :- + updatevs(Tab0,X,Ov,Nv), + Tab = Tab0. + +updatevs(Tab,X,Ov,Nv) :- + ( Tab = l(Xs,Ov), Xs == X -> + setarg(2,Tab,Nv) + ; Tab = n2(T1,M,T2) -> + ( M @=< X -> + updatevs(T2,X,Ov,Nv) + ; updatevs(T1,X,Ov,Nv) + ) + ; Tab = n3(T1,M2,T2,M3,T3) -> + ( M2 @=< X -> + ( M3 @=< X -> + updatevs(T3,X,Ov,Nv) + ; updatevs(T2,X,Ov,Nv) + ) + ; updatevs(T1,X,Ov,Nv) + ) + ). +*/ + +updatevs(l(X,Ov),Xs,Ov,Nv,l(X,Nv)) :- X == Xs. +updatevs(n2(T1,M,T2),X,Ov,Nv,n2(NT1,M,NT2)) :- + M @=< X + -> NT1=T1, updatevs(T2,X,Ov,Nv,NT2) + ; NT2=T2, updatevs(T1,X,Ov,Nv,NT1). +updatevs(n3(T1,M2,T2,M3,T3),X,Ov,Nv,n3(NT1,M2,NT2,M3,NT3)) :- + M2 @=< X + -> (M3 @=< X + -> NT2=T2, NT1=T1, updatevs(T3,X,Ov,Nv,NT3) + ; NT1=T1, NT3=T3, updatevs(T2,X,Ov,Nv,NT2) + ) + ; NT2=T2, NT3=T3, updatevs(T1,X,Ov,Nv,NT1). + +ins2(n2(T1,M,T2),X,V,Tree) :- + M @=< X + -> ins2(T2,X,V,Tree1), + cmb2(Tree1,T1,M,Tree) + ; ins2(T1,X,V,Tree1), + cmb1(Tree1,M,T2,Tree). +ins2(n3(T1,M2,T2,M3,T3),X,V,Tree) :- + M2 @=< X + -> (M3 @=< X + -> ins2(T3,X,V,Tree1), + cmb4(Tree1,T1,M2,T2,M3,Tree) + ; ins2(T2,X,V,Tree1), + cmb5(Tree1,T1,M2,M3,T3,Tree) + ) + ; ins2(T1,X,V,Tree1), + cmb3(Tree1,M2,T2,M3,T3,Tree). +ins2(l(A,V),X,Vn,Tree) :- + A @=< X + -> (X @=< A + -> fail + ; Tree = t(l(A,V),X,l(X,Vn)) + ) + ; Tree = t(l(X,Vn),A,l(A,V)). + +cmb0(t(Tree),Tree). +cmb0(t(T1,M,T2),n2(T1,M,T2)). + +cmb1(t(NT1),M,T2,t(n2(NT1,M,T2))). +cmb1(t(NT1a,Mb,NT1b),M,T2,t(n3(NT1a,Mb,NT1b,M,T2))). + +cmb2(t(NT2),T1,M,t(n2(T1,M,NT2))). +cmb2(t(NT2a,Mb,NT2b),T1,M,t(n3(T1,M,NT2a,Mb,NT2b))). + +cmb3(t(NT1),M2,T2,M3,T3,t(n3(NT1,M2,T2,M3,T3))). +cmb3(t(NT1a,Mb,NT1b),M2,T2,M3,T3,t(n2(NT1a,Mb,NT1b),M2,n2(T2,M3,T3))). + +cmb4(t(NT3),T1,M2,T2,M3,t(n3(T1,M2,T2,M3,NT3))). +cmb4(t(NT3a,Mb,NT3b),T1,M2,T2,M3,t(n2(T1,M2,T2),M3,n2(NT3a,Mb,NT3b))). + +cmb5(t(NT2),T1,M2,M3,T3,t(n3(T1,M2,NT2,M3,T3))). +cmb5(t(NT2a,Mb,NT2b),T1,M2,M3,T3,t(n2(T1,M2,NT2a),Mb,n2(NT2b,M3,T3))). + +start_slg:- assertz(( + term_expansion(X,Y) :- !, + do_term_expansion(X,Y) + )). + diff --git a/packages/cplint/testcpl.pl b/packages/cplint/testcpl.pl new file mode 100644 index 000000000..ed840be4f --- /dev/null +++ b/packages/cplint/testcpl.pl @@ -0,0 +1,124 @@ +/* + LPAD and CP-Logic reasoning suite + Copyright (c) 2007, Fabrizio Riguzzi + +Test file for cpld.pl + +Use +:-t. +to execute the test + +*/ + +:-use_module(library(cpl)). + +epsilon(0.000001). + +close_to(V,T):- + epsilon(E), + TLow is T-E, + THigh is T+E, + TLow=PL-1e-7,P==PL-1e-10,P==PL-1e-7,P==PL-1e-10,P==PL-1e-7,P==PL-1e-10,P=