static ssize_t scribe_do_read(struct file *file, char __user *buf, ssize_t len, loff_t *ppos) { struct scribe_ps *scribe = current->scribe; int force_block = 0; ssize_t ret; if (!is_scribed(scribe)) return do_read(file, buf, len, ppos, force_block); if (is_kernel_copy()) goto out; if (!should_scribe_data(scribe)) goto out; scribe_need_syscall_ret(scribe); if (is_replaying(scribe)) { len = scribe->orig_ret; if (len <= 0) return len; force_block = 1; } if (is_deterministic(file)) goto out; scribe_data_non_det(); if (is_recording(scribe)) goto out; return scribe_emul_copy_to_user(scribe, buf, len); out: scribe->in_read_write = true; ret = do_read(file, buf, len, ppos, force_block); scribe->in_read_write = false; return ret; }
fm<Label>& fm<Label>::subset() { fm<Label> m; int i; int j; int k; int no_states; state s1; state s2; set<state> target; set<state> temp2; set<Label> alphabet; inst<Label> t; fm<Label> temp; // if already deterministic, do nothing if (is_deterministic()) return *this; // sort if necessary arcs.sort(); // remove unreachable states reachable_fm(); reverse(); reachable_fm(); reverse(); // collect the alphabet labels(alphabet); // add start subset to the list list<set<state> > sub; sub += start_states; s1 = 0; m.start_states += s1; // if some start state is also a final state, add // the new start state to the list of final states temp2.intersect(final_states, start_states); if (temp2.size() > 0) m.final_states += s1; // for each existing set in the subset list, // find a new reachable subset no_states = 1; for (i=0; i<no_states; ++i) { for (j=0; j<alphabet.size(); ++j) { target.clear(); for (k=0; k<sub[i].size(); ++k) { select(alphabet[j], sub[i][k], SOURCE, temp); target += temp.sinks(temp2); } if (target.size() == 0) continue; // create states for an instruction s1 = i; if ((k = sub.member(target)) < 0) { sub += target; s2 = no_states++; temp2.intersect(final_states, target); if (temp2.size() > 0) m.final_states += s2; } else s2 = k; t.assign(s1, alphabet[j], s2); m.arcs += t; } } *this = m; return *this; }
static ssize_t scribe_do_readv_writev(int type, struct file *file, const struct iovec __user * uvector, unsigned long nr_segs, loff_t *pos) { struct scribe_ps *scribe = current->scribe; struct iovec iovstack[UIO_FASTIOV]; struct iovec *iov = iovstack; int force_block = 0; ssize_t ret, len = 0; if (!is_scribed(scribe)) return do_readv_writev(type, file, uvector, nr_segs, 0, pos, force_block); if (is_kernel_copy()) goto out; if (!should_scribe_data(scribe)) goto out; scribe_need_syscall_ret(scribe); if (is_replaying(scribe)) { len = scribe->orig_ret; if (len <= 0) { rw_copy_check_uvector(type, uvector, nr_segs, ARRAY_SIZE(iovstack), iovstack, &iov); ret = len; goto free; } force_block = 1; } if (type == READ) { if (is_deterministic(file)) goto out; scribe_data_non_det(); if (is_recording(scribe)) goto out; rw_copy_check_uvector(type, uvector, nr_segs, ARRAY_SIZE(iovstack), iovstack, &iov); ret = __do_loop_readv_writev(file, iov, nr_segs, len, pos, io_scribe_emul_copy_to_user); goto free; } out: scribe->in_read_write = true; ret = do_readv_writev(type, file, uvector, nr_segs, len, pos, force_block); scribe->in_read_write = false; free: if (iov != iovstack) kfree(iov); return ret; }
int mealy<Input, Output>::deterministic_execution(const string<Input>& wd, string<Output>& results, const int verbose) const { int i; set<state> end; mealy<Input, Output> bunch; set<state> current; Input r; // check that machine is deterministic if (!is_deterministic()) { cerr << "cannot execute nondeterministic mealy machine"; return -1; } // begin with start states current = this->start_states[0]; // do for all characters for (i=0; i<wd.size(); ++i) { r = wd[i]; // get the target set select(r, current[0], SOURCE, bunch); // if there are no states, return if (bunch.size() == 0) { if (verbose) cout << "no states acccessible on " << r << "\n"; return 0; } // else, target set is the new start set bunch.sinks(current); if (verbose) cout << "on " << r << " take instructions\n" << bunch; // output corresponding symbol results += bunch[0].get_label().get_right(); } // exhausted the string; now test for a final state in the set end.intersect(this->final_states, current); if (end.size() != 0) { if (verbose) cout << "terminate on final states " << end << "\n"; return 1; } else return 0; }