示例#1
0
文件: msearch.c 项目: axelrod9/ladr
static
int search(int max_constrained, int depth)
{
  int id;
  BOOL go;
  int rc = check_time_memory();
  if (rc != SEARCH_GO_NO_MODELS)
    return rc;
  else {
    id = select_cell(max_constrained);
    if (id == -1) {
      rc = possible_model();
      return rc;
    }
    else {
      int i, last;  /* we'll do 0 .. last */
      int x = Cells[id].max_index;
      max_constrained = MAX(max_constrained, x);
      Mstats.selections++;

      if (flag(Opt->trace)) {
	printf("select: ");
	p_model(FALSE);
	/* p_possible_values(); */
      }

      if (Cells[id].symbol->type == RELATION)
	last = 1;
      else if (flag(Opt->lnh))
	last = MIN(max_constrained+1, Domain_size-1);
      else
	last = Domain_size-1;

      for (i = 0, go = TRUE; i <= last && go; i++) {
	Estack stk;
	Mstats.assignments++;

	if (flag(Opt->trace)) {
	  printf("assign: ");
	  fwrite_term(stdout, Cells[id].eterm);
	  printf("=%d (%d) depth=%d\n", i, last, depth);
	}

	stk = assign_and_propagate(id, Domain[i]);

	if (stk != NULL) {
	  /* no contradiction found during propagation, so we recurse */
	  rc = search(MAX(max_constrained, i), depth+1);
	  /* undo assign_and_propagate changes */
	  restore_from_stack(stk);
	  if (rc == SEARCH_GO_MODELS)
	    go = mace4_skolem_check(id);
	  else
	    go = (rc == SEARCH_GO_NO_MODELS);
	}
      }
      return rc;
    }
  }
}  /* search */
示例#2
0
文件: msearch.c 项目: axelrod9/ladr
static
int possible_model(void)
{
  if (flag(Opt->arithmetic)) {
    if (!check_with_arithmetic(Ground_clauses))
      return SEARCH_GO_NO_MODELS;
  }
  else if (!check_that_ground_clauses_are_true())
    fatal_error("possible_model, bad model found");

  {
    static int next_message = 1;
    Total_models++;
    Mstats.current_models++;

    if (flag(Opt->return_models)) {
      Term modelterm = interp_term();
      Interp model = compile_interp(modelterm, FALSE);
      zap_term(modelterm);
      Models = plist_append(Models, model);
    }

    if (flag(Opt->print_models))
      print_model_standard(stdout, TRUE);
    else if (flag(Opt->print_models_tabular))
      p_model(FALSE);
    else if (next_message == Total_models) {
      printf("\nModel %d has been found.\n", Total_models);
      next_message *= 10;
    }
    fflush(stdout);
    if (parm(Opt->max_models) != -1 && Total_models >= parm(Opt->max_models))
      return SEARCH_MAX_MODELS;
    else
      return SEARCH_GO_MODELS;
  }
}  /* possible_model */
    void TestSteadyStateRunnerConverges(void) throw(Exception)
    {
#ifdef CHASTE_CVODE
        //////////// DEFINE PARAMETERS ///////////////
        // Get the frequency
        double hertz = 1.0;

        ///////// END DEFINE PARAMETERS ////////////////////////

        // Setup a CVODE model that has empty solver and stimulus
        boost::shared_ptr<RegularStimulus> p_stimulus;
        boost::shared_ptr<AbstractIvpOdeSolver> p_solver;
        boost::shared_ptr<AbstractCvodeCell> p_model(new CellShannon2004FromCellMLCvode(p_solver, p_stimulus));

        // Get it to use the default stimulus from CellML
        boost::shared_ptr<RegularStimulus> p_reg_stim = p_model->UseCellMLDefaultStimulus();

        { // Test that the steady state analysis throws a nice error if we try to run it with a non-RegularStimulus

            boost::shared_ptr<ZeroStimulus> p_stim(new ZeroStimulus());
            p_model->SetStimulusFunction(p_stim);

            SteadyStateRunner bad_steady_runner(p_model);
            TS_ASSERT_THROWS_THIS(bad_steady_runner.RunToSteadyState(),
                                  "Steady State approximations only work for models with RegularStimulus objects.");

            // Reset to a sensible stimulus function.
            p_model->SetStimulusFunction(p_reg_stim);
        }

        p_reg_stim->SetPeriod(1000.0/hertz);

        // Note that increasing the strictness of the tolerances here (default is 1e-5, 1e-7)
        // actually leads to a faster convergence to steady state, as a model solved in
        // a sloppy way might never actually get close to its true limit cycle!
        p_model->SetTolerances(1e-6,1e-8);

        /**
         * STEADY STATE PACING EXPERIMENT
         */
        /*
         * HOW_TO_TAG Cardiac/Cell Models
         * Get a cardiac cell model to (roughly) a steady state, given a regular stimulus, using the `SteadyStateRunner` class.
         */
        SteadyStateRunner steady_runner(p_model);

        bool result;

        // Here we don't reach steady state by max num paces
        steady_runner.SetMaxNumPaces(1u);
        result = steady_runner.RunToSteadyState();

        TS_ASSERT_EQUALS(result,false);

        // Here we do reach the steady state OK.
        steady_runner.SetMaxNumPaces(10000u);
        result = steady_runner.RunToSteadyState();

        TS_ASSERT_EQUALS(result,true);
        // Your mileage may vary. 32-bit machine, default build gives 520 evaluations, 484 on recent 64-bit CVODE.
        TS_ASSERT_LESS_THAN(steady_runner.GetNumEvaluations(),550u);

        // For coverage
        TS_ASSERT_THROWS_THIS(steady_runner.SetMaxNumPaces(0u),
                "Please set a maximum number of paces that is positive");
#else
        std::cout << "CVODE must be enabled for the steady state runner to work." << std::endl;
#endif //_CHASTE_CVODE
    }
示例#4
0
boost::shared_ptr<AbstractCvodeCell> CellMLLoader::LoadCvodeCell(void)
{
    AbstractCardiacCellInterface* p_loaded_cell = LoadCellMLFile(true);
    boost::shared_ptr<AbstractCvodeCell> p_model(dynamic_cast<AbstractCvodeCell*>(p_loaded_cell));
    return p_model;
}
    void TestShannonSimulation()
    {
/* CVODE is still an optional Chaste dependency, but it is highly recommended for
 * working with single cell simulations. This tutorial code will only run if CVODE is installed and enabled
 * (see InstallCvode and ChasteGuides/HostconfigSystem). */
#ifdef CHASTE_CVODE
        /*
         * == Defining a CVODE model ==
         *
         * Setup a CVODE model that has empty solver and stimulus
         * This is necessary to initialise the cell model.
         *
         * If you want to define your own stimulus without using the default one,
         * you can define it here instead of giving it an empty stimulus:
         *
         * {{{boost::shared_ptr<RegularStimulus> p_stimulus(new RegularStimulus(-25.5,2.0,50.0,500));}}}
         *
         * the parameters are magnitude, duration, period, and start time of stimulus.
         */
        boost::shared_ptr<RegularStimulus> p_stimulus;
        boost::shared_ptr<AbstractIvpOdeSolver> p_solver;
        boost::shared_ptr<AbstractCvodeCell> p_model(new CellShannon2004FromCellMLCvode(p_solver, p_stimulus));

        /*
         * Once the model is set up we can tell it to use the the default stimulus from CellML,
         * (if one has been labelled, you get an exception if not), and return it.
         *
         * NB. You could automatically check whether one is available with:
         *
         * {{{p_model->HasCellMLDefaultStimulus()}}}
         *
         */
        boost::shared_ptr<RegularStimulus> p_regular_stim = p_model->UseCellMLDefaultStimulus();

        /*
         * Now you can modify certain parameters of the stimulus function, such as the period
         */
        p_regular_stim->SetPeriod(1000.0);


        /*
         * == Numerical Considerations ==
         *
         * Cardiac cell models can be pretty tricky to deal with, as they are very stiff and sometimes full
         * of singularities.
         *
         * One of the first things you want to ensure is that the maximum timestep CVODE can take is less
         * than or equal to the duration of the stimulus. Otherwise CVODE could evaluate the right-hand side
         * before and after the stimulus, and never see it (giving you a cell that never does anything).
         * This can be done using something like:
         *
         * {{{double max_timestep = p_regular_stim->GetDuration();}}}
         *
         * instead of the declaration of `max_timestep` below. In this tutorial we want an answer that is
         * refined in time to give an accurate upstroke velocity. So we make the maximum timestep even
         * smaller, to match the printing timestep. A rough rule of thumb would be to use the smaller of
         * stimulus duration and printing time step as your CVODE maximum timestep. But note CVODE will still
         * give sensible answers if printing timestep is less than maximum timestep, it might just decide
         * to interpolate the output instead of evaluate it directly, if it thinks it will be
         * accurate enough to meet your tolerances.
         *
         *
         * A common error from CVODE is '''TOO_MUCH_WORK''', this means CVODE tried to exceed the maximum number of
         * internal time steps it is allowed to do. You can try using the method `SetMaxSteps` to change
         * the default (500) to a larger value, with a command like:
         *
         * {{{p_model->SetMaxSteps(1e5);}}}
         *
         * We have found that 1e5 should be enough for a single pace of all models we've tried so far,
         * but if you were running for a long time (e.g. 1000 paces in one Solve call) you would need to increase this.
         *
         * Another common error from CVODE is:
         * '''the error test failed repeatedly or with |h| = hmin.'''
         *
         * Since we don't change hmin (and it defaults to a very small value), this generally means the
         * ODE system has got to a situation where refining the timestep is not helping the convergence.
         *
         * This generally indicates that you are hitting some sort of singularity, or divide by zero, in
         * the model. Unfortunately cardiac models are full of these, they can sometimes be manually edited out
         * by changing the cellML file, for instance using [http://en.wikipedia.org/wiki/L%27H%C3%B4pital%27s_rule L'Hopital's rule].
         *
         * In this case, one other thing you can try is to change the absolute and relative
         * tolerances of the CVODE solver, the default being (1e-5,1e-7), although it isn't clear whether
         * refining sometimes makes things worse, as CVODE goes to look for trouble in areas with steep gradients.
         *
         * {{{p_model->SetTolerances(1e-6,1e-8);}}}
         *
         * By default we use an analytic Jacobian for CVODE cells (where available - see [wiki:ChasteGuides/CodeGenerationFromCellML]
         * for instructions on how to provide one using Maple). In some cases (the Hund-Rudy model particularly being one) the
         * analytic Jacobian contains effectively divide-by-zero entries, even at resting potential. If you observe
         * CVODE errors when trying to run simulations, it can be worth switching off the analytic Jacobian and resorting
         * to a numerical approximation (as happens by default if no analytic Jacobian is available). This can be done with the
         * following command:
         *
         * {{{p_model->ForceUseOfNumericalJacobian();}}}
         *
         */

        /*
         * == Changing Parameters in the Cell Model ==
         *
         * You can also change any parameters that are labelled in the cell model.
         *
         * Instructions for annotating parameters can be found at [wiki:ChasteGuides/CodeGenerationFromCellML]
         *
         * Here we show how to change the parameter dictating the maximal conductance of the IKs current.
         * Note this call actually leaves it unchanged from the default,
         * you can experiment with changing it and examine the impact on APD.
         */
        p_model->SetParameter("membrane_slow_delayed_rectifier_potassium_current_conductance", 0.07);

        /*
         * == Running model to steady state ==
         *
         * Now we run the model to steady state.
         * You can detect for steady state alternans by giving it true as a second parameter
         * {{{SteadyStateRunner steady_runner(p_model, true);}}}
         *
         * You may change the number of maximum paces the runner takes. The default is 1e5.
         */
        SteadyStateRunner steady_runner(p_model);
        steady_runner.SetMaxNumPaces(100u);
        bool result;
        result = steady_runner.RunToSteadyState();

        /*
         * Check that the model has NOT reached steady state
         * (this model needs more than 100 paces to reach steady state).
         *
         */
        TS_ASSERT_EQUALS(result,false);

        /*
         * == Getting detail for paces of interest ==
         *
         * Now we solve for the number of paces we are interested in.
         *
         * The absolute values of start time and end time are typically only relevant for the stimulus, in general
         * nothing else on the right-hand side of the equations uses time directly.
         *
         * i.e. if you have a `RegularStimulus` of period 1000ms then you would get exactly the same results
         * calling Solve(0,1000,...) twice, as you would calling Solve(0,1000,...) and Solve(1000,2000,...).
         *
         * Single cell results can be very sensitive to the sampling time step, because of the steepness of the upstroke.
         *
         * For example, try changing the line below to 1 ms. The upstroke velocity that is detected will change
         * from 339 mV/ms to around 95 mV/ms. APD calculations will only ever be accurate to sampling timestep
         * for the same reason.
         */
        double max_timestep = 0.1;
        p_model->SetMaxTimestep(max_timestep);

        double sampling_timestep = max_timestep;
        double start_time = 0.0;
        double end_time = 1000.0;
        OdeSolution solution = p_model->Compute(start_time, end_time, sampling_timestep);

        /*
         * `p_model` retains the state variables at the end of `Solve`, if you call `Solve` again the state
         * variables will evolve from their new state, not the original initial conditions.
         *
         * Write the data out to a file.
         */
        solution.WriteToFile("TestCvodeCells","Shannon2004Cvode","ms");

        /*
         * == Calculating APD and Upstroke Velocity ==
         *
         * Calculate APD and upstroke velocity using {{{CellProperties}}}
         */
        unsigned voltage_index = p_model->GetSystemInformation()->GetStateVariableIndex("membrane_voltage");
        std::vector<double> voltages = solution.GetVariableAtIndex(voltage_index);
        CellProperties cell_props(voltages, solution.rGetTimes());

        double apd = cell_props.GetLastActionPotentialDuration(90);
        double upstroke_velocity = cell_props.GetLastMaxUpstrokeVelocity();
        /*
         * Here we just check that the values are equal to the ones we expect,
         * with appropriate precision to pass on different versions of CVODE.
         */
        TS_ASSERT_DELTA(apd, 212.41, 1e-2);
        TS_ASSERT_DELTA(upstroke_velocity, 338, 1.25);

        /* CVODE is still an optional dependency for Chaste.
         * If CVODE is not installed this tutorial will
         * not do anything, but we can at least alert the user to this.*/
#else
        std::cout << "Cvode is not enabled.\n";
#endif
    }
示例#6
0
文件: msearch.c 项目: axelrod9/ladr
static
int mace4n(Plist clauses, int order)
{
  Plist p, g;
  int i, rc;
  Mstate initial_state = get_mstate();

  Variable_style save_style = variable_style();
  set_variable_style(INTEGER_STYLE);

  if (Max_domain_element_in_input >= order) {
    if (flag(Opt->arithmetic)) {
      if (!ok_for_arithmetic(clauses, order))
	return SEARCH_DOMAIN_OUT_OF_RANGE;
    }
    else
      return SEARCH_DOMAIN_OUT_OF_RANGE;
  }

  Domain_size = order;

  init_for_domain_size();

  built_in_assignments();  /* Fill out equality table (and maybe others). */

  special_assignments();  /* assignments determined by options */

  /* Instantiate clauses over the domain.  This also
     (1) makes any domain element constants into real domain elements,
     (2) applies OR, NOT, and EQ simplification, and
     (3) does unit propagation (which pushes events onto initial_state->stack).
     Do the units first, then the 2-clauses, then the rest. */

  for (p = clauses; initial_state->ok && p != NULL; p = p->next)
    if (number_of_literals(p->v) < 2)
      generate_ground_clauses(p->v, initial_state);

  for (p = clauses; initial_state->ok && p != NULL; p = p->next)
    if (number_of_literals(p->v) == 2)
      generate_ground_clauses(p->v, initial_state);

  for (p = clauses; initial_state->ok && p != NULL; p = p->next)
    if (number_of_literals(p->v) > 2)
      generate_ground_clauses(p->v, initial_state);

  /* The preceding calls push propagation events onto initial_state->stack.
     We won't have to undo those initial events during the search,
     but we can undo them after the search.
  */

  if (flag(Opt->verbose)) {
    printf("\nInitial partial model:\n");
    p_model(FALSE);
    fflush(stdout);
  }

  /* Here we go! */

  if (initial_state->ok)
    rc = search(Max_domain_element_in_input, 0);
  else
    rc = SEARCH_GO_NO_MODELS;  /* contradiction in initial state */

  /* Free all of the memory associated with the current domain size. */

  restore_from_stack(initial_state->stack);
  free_mstate(initial_state);

  if (flag(Opt->negprop))
    free_negprop_index();

  free(Ordered_cells);
  Ordered_cells = NULL;

  for (i = 0; i < Number_of_cells; i++) {
    zap_mterm(Cells[i].eterm);
    free(Cells[i].possible);
  }
  free(Cells);
  Cells = NULL;

  for (i = 0; i < Domain_size; i++)
    zap_term(Domain[i]);
  free(Domain);
  Domain = NULL;

  for (g = Ground_clauses; g != NULL; g = g->next)
    zap_mclause(g->v);
  zap_plist(Ground_clauses);
  Ground_clauses = NULL;

  set_variable_style(save_style);
  return rc;
}  /* mace4n */